Sie sind auf Seite 1von 51

1. IEC (* 1 configuration, 1 resource *) 1.1. Configuration 1: Config1 (* This is the Config 1 *) 1. Resource 1: DOWN_DYNAGRAPH (* Clculo de dinagrama de fondo *) 1.1.

Description and Properties


Resources 1 * Target: QNX-Target * Resource Network parameters: HSD ValidityTime = 0 ETCP TimeOut = 10000

1.2. Resource content


Variable Groups From_DYNVAL Control For_DYNSUB Programs Calc_Downhole Calculos_Sarta (* Clculo de valores asociados a sarta de cabillas *) Functions Get_CDS (* Lectura de CDS (simulada o real) *) Interpolation PublicaResult (* Escribir archivo de texto con cartas dinagrficas *) Analisis_Goodman Real2String BHD_Calculation String2Real Public_dynas Function blocks PID_ST_1 (* user modifiable, for use in ST programs *) VIRGO_STATUS (* expose system variables to OPC *)

1.4. Variables
THT (* Temperatura en Cabezal de pozo *) Type: REAL

Virgo Workbench /01/20 P_PILOTO_OROCU onfiguration, 1 resou 1/51

Attribute: Free Direction: Memory existe_pozo (* Arreglo que indica si existe pozo (con fines de agilizar procesamiento) *) Dimension: [1..4] Type: BOOL Attribute: Free Direction: Memory Retain: YES refresc_conf (* Bit para controlar ejecucin de clculos de sartas de cabillas *) Type: BOOL Attribute: Free Direction: Memory Init. value: TRUE BBB Type: REAL Attribute: Free Direction: Memory IAA (* Contador de uso general *) Type: DINT Attribute: Free Direction: Memory div_por_cero (* Sealizacin de divisin por cero *) Type: BOOL Attribute: Free Direction: Memory Init. value: TRUE Counter_3 Group: For_DYNSUB Type: DINT Attribute: Free Direction: Memory CC Type: REAL Attribute: Free Direction: Memory Wf (* Peso del fluido sobre la bomba [Lbs] *) Type: REAL Attribute: Free

Virgo Workbench /01/20 P_PILOTO_OROCU onfiguration, 1 resou 2/51

Direction: Memory Retain: YES public_pointnum Group: For_DYNSUB Type: DINT Attribute: Free Direction: Memory PRG_SECS Type: REAL Attribute: Free Direction: Memory K (* Contador de uso general *) Type: DINT Attribute: Free Direction: Memory

FIRST_TIME (* Bandera para controlar clculos de cabillas, densidad fluido e init. consts. Slo 1 vez *) Type: BOOL Attribute: Free Direction: Memory Init. value: FALSE F Type: REAL Attribute: Free Direction: Memory

CCC Type: REAL Attribute: Free Direction: Memory Pmax (* Posicin mxima barra pulida (longitud de carrera) *) Dimension: [1..4] Type: REAL Attribute: Free Direction: Memory Retain: YES PIP (* Pump Intake Pressure( presin de entrada a la bomba) [psi] *) Type: REAL Attribute: Free Direction: Memory

Virgo Workbench /01/20 P_PILOTO_OROCU onfiguration, 1 resou 3/51

Type: REAL Attribute: Free Direction: Memory

DD Type: REAL Attribute: Free Direction: Memory Calc_Vel (* Arreglo para propagar data de velocidad *) Dimension: [0..10][0..255] Type: REAL Attribute: Free Direction: Memory public_CDS Dimension: [0..1][1..255] Group: For_DYNSUB Type: REAL Attribute: Free Direction: Memory Num_Sect (* Nmero de secciones de sarta de cabillas *) Dimension: [1..4] Type: DINT Attribute: Free Direction: Memory Retain: YES LLL Type: DINT Attribute: Free Direction: Memory lee_texto Group: Control Type: BOOL Attribute: Free Direction: Memory DownDyn (* Arreglo que contiene carta dinagrfica de fondo (contiene posicin[0,i] y carga[i,0]) *) Dimension: [1..4][0..1][1..255] Type: REAL Attribute: Free Direction: Memory Delta_TT

Virgo Workbench /01/20 P_PILOTO_OROCU onfiguration, 1 resou 4/51

(* Tiempo de muestreo para interpolacin *) Type: REAL Attribute: Free Direction: Memory DDD Type: REAL Attribute: Free Direction: Memory Cpmax (* Valor mximo de cuentas (pos) en ciclo de bombeo despus de procedimiento de ajuste de campo *) Dimension: [1..4] Type: REAL Attribute: Free Direction: Memory Retain: YES Xa Type: REAL Attribute: Free Direction: Memory U Type: REAL Attribute: Free Direction: Memory

simul_on_off (* Control modo simul. o utilizacin driver dynamod para CDS *) Dimension: [1..4] Group: Control Type: BOOL Attribute: Free Direction: Memory Init. value: FALSE POS_A Type: REAL Attribute: Free Direction: Memory pointnum_min (* Nmero mnimo de puntos que componen la carta dinagrfica *) Dimension: [1..4] Type: DINT Attribute: Free Direction: Memory Retain: YES KK

Virgo Workbench /01/20 P_PILOTO_OROCU onfiguration, 1 resou 5/51

(* Contador de uso general *) Type: DINT Attribute: Free Direction: Memory Delta_x (* Intervalo de propagacin *) Type: REAL Attribute: Free Direction: Memory Cpmin (* Valor mnimo de cuentas (pos) en ciclo de bombeo despus de procedimiento de ajuste de campo *) Dimension: [1..4] Type: REAL Attribute: Free Direction: Memory Retain: YES cds_ui_max_load (* valor mximo de carga UI de CDS *) Type: REAL Attribute: Free Direction: Memory BHD_Calc (* Booleano que permite realziar adquisicin de CDS y convertir a UI sin calcular la CDF *) Dimension: [1..4] Group: Control Type: BOOL Attribute: Free Direction: Memory Retain: YES Xc Type: REAL Attribute: Free Direction: Memory UU Type: REAL Attribute: Free Direction: Memory POS_B Type: REAL Attribute: Free Direction: Memory pointnum_max (* Nmero mximo de puntos que componen la carta dinagrfica *)

Virgo Workbench /01/20 P_PILOTO_OROCU onfiguration, 1 resou 6/51

Dimension: [1..4] Type: DINT Attribute: Free Direction: Memory Retain: YES Lmax (* Valor mximo de carga posible (valor mximo de calibracin de CC) *) Dimension: [1..4] Type: REAL Attribute: Free Direction: Memory Retain: YES KKK (* Contador de uso general *) Type: DINT Attribute: Free Direction: Memory cds_ui_min_load (* valor mnimo de carga UI de CDS *) Type: REAL Attribute: Free Direction: Memory aux_conv_ui (* Booleano auxiliar para sealizar problema en conversin a UI *) Type: BOOL Attribute: Free Direction: Memory Init. value: TRUE Pos_s (* Arreglo para propagar data de posicin a interpolar *) Dimension: [0..510] Type: REAL Attribute: Free Direction: Memory min_pos Type: REAL Attribute: Free Direction: Memory LC (* Contador de uso general *) Type: DINT Attribute: Free Direction: Memory

Virgo Workbench /01/20 P_PILOTO_OROCU onfiguration, 1 resou 7/51

fluid_dens (* [Lb/cu in] *) Dimension: [1..4] Type: REAL Attribute: Free Direction: Memory Existe_CDF Group: For_DYNSUB Type: BOOL Attribute: Free Direction: Memory Init. value: FALSE Ef_Weight (* Peso efectivo de la sarta *) Dimension: [1..4] Type: REAL Attribute: Free Direction: Memory DIFF Type: REAL Attribute: Free Direction: Memory Clmax (* Valor mximo posible de cuentas a obtener a carga mxima *) Dimension: [1..4] Type: REAL Attribute: Free Direction: Memory Retain: YES cds_cad_hora (* hora CDS CAD *) Type: DINT Attribute: Free Direction: Memory water_dens Dimension: [1..4] Type: REAL Attribute: Free Direction: Memory tendencias_p Type: STRING(8) Attribute: Free Direction: Memory Init. value: 'presion'

Virgo Workbench /01/20 P_PILOTO_OROCU onfiguration, 1 resou 8/51

Str_s (* Arreglo para propagar data de tensin (stress) a interpolar *) Dimension: [0..510] Type: REAL Attribute: Free Direction: Memory Rod (* Arreglo de estructuras para data de cabilla *) Dimension: [1..4][1..10] Type: ROD_SECTION Attribute: Free Direction: Memory Retain: YES Public_hora Group: For_DYNSUB Type: DINT Attribute: Free Direction: Memory LM (* Contador de uso general *) Type: DINT Attribute: Free Direction: Memory interpolation_dummy Type: BOOL Attribute: Free Direction: Memory Interpolation_counter (* Contador de veces que se interpola *) Type: BOOL Attribute: Free Direction: Memory cds_cad_min (* hora CDS CAD *) Type: DINT Attribute: Free Direction: Memory AA Type: REAL Attribute: Free Direction: Memory Vel_s

Virgo Workbench /01/20 P_PILOTO_OROCU onfiguration, 1 resou 9/51

(* Arreglo para propagar data de velocidad a interpolar *) Dimension: [0..510] Type: REAL Attribute: Free Direction: Memory VarBool1 Group: For_DYNSUB Type: BOOL Attribute: Free Direction: Memory tendencias_t Type: STRING(8) Attribute: Free Direction: Memory Init. value: 'temp' Temp (* variable temporal para uso general *) Type: REAL Attribute: Free Direction: Memory public_dynas_dummy (* booleano dummy para funcin de publicacin de CDS y CDF en pgina web *) Type: BOOL Attribute: Free Direction: Memory Public_ano Group: For_DYNSUB Type: DINT Attribute: Free Direction: Memory netdas_in Type: Attribute: Free Direction: Memory IC (* Contador de uso general *) Type: DINT Attribute: Free Direction: Memory cds_cad_seg (* hora CDS CAD *) Type: DINT Attribute: Free

Virgo Workbench /01/20 P_PILOTO_OROCU onfiguration, 1 resou 10/51

Direction: Memory AAA Type: REAL Attribute: Free Direction: Memory VarReal1 Group: For_DYNSUB Type: REAL Attribute: Free Direction: Memory Temp_Weight (* Variable temporal para clculo de peso de secciones remanentes de cabilla *) Type: REAL Attribute: Free Direction: Memory RunDynValvulas Group: From_DYNVAL Type: BOOL Attribute: Free Direction: Memory Init. value: FALSE RodVol (* Volumen de la sarta *) Dimension: [1..4] Type: REAL Attribute: Free Direction: Memory Public_mes Group: For_DYNSUB Type: DINT Attribute: Free Direction: Memory pointnum (* Nmero de puntos que componen la carta dinagrfica *) Dimension: [1..4] Type: DINT Attribute: Free Direction: Memory netdas_out Type: Attribute: Free Direction: Memory

Virgo Workbench /01/20 P_PILOTO_OROCU onfiguration, 1 resou 11/51

ILL (* Contador de uso general *) Type: DINT Attribute: Free Direction: Memory IJK (* Contador mtodo MCH *) Type: DINT Attribute: Free Direction: Memory cds_cad_dia (* hora CDS CAD *) Type: DINT Attribute: Free Direction: Memory BB Type: REAL Attribute: Free Direction: Memory VarReal2 Group: For_DYNSUB Type: REAL Attribute: Free Direction: Memory Temp_Vol (* Variable temporal para clculod e volumen secciones cabilla remanentes *) Type: REAL Attribute: Free Direction: Memory SurfaceDyn (* Arreglo que contiene carta dinagrfica de superficie (contiene posicin y carga) *) Dimension: [1..4][0..1][1..255] Type: REAL Attribute: Free Direction: Memory RodLen (* Volumen de la sarta *) Dimension: [1..4] Type: REAL Attribute: Free Direction: Memory Public_dia Group: For_DYNSUB

Virgo Workbench /01/20 P_PILOTO_OROCU onfiguration, 1 resou 12/51

Type: DINT Attribute: Free Direction: Memory Pozo_var (* Variable con datos del pozo *) Dimension: [1..4] Type: POZO Attribute: Free Direction: Memory Retain: YES netdas_var (* 0 -> Pos, 1-> Load *) Dimension: [0..1] Type: NETDAS Attribute: Free Direction: Memory IA (* Contador de uso general *) Type: DINT Attribute: Free Direction: Memory i (* Contador de uso general *) Type: DINT Attribute: Free Direction: Memory

crude_dens Dimension: [1..4] Type: REAL Attribute: Free Direction: Memory Counter_1 Group: For_DYNSUB Type: DINT Attribute: Free Direction: Memory cds_cad_mes (* hora CDS CAD *) Type: DINT Attribute: Free Direction: Memory BHD_Calculation_Dummy (* dummy para ejecutar funcin de clculo de BHD *)

Virgo Workbench /01/20 P_PILOTO_OROCU onfiguration, 1 resou 13/51

Type: BOOL Attribute: Free Direction: Memory VarReal3 Group: For_DYNSUB Type: REAL Attribute: Free Direction: Memory Temp_Buoy (* Variable temporal para calcular flotabilidad de secciones remanentes de cabilla *) Type: REAL Attribute: Free Direction: Memory run (* Control de ejecucin. Suiche indicador de calibracin e inicializacin realizada *) Group: Control Type: BOOL Attribute: Free Direction: Memory Init. value: FALSE RodWeight (* Volumen de la sarta *) Dimension: [1..4] Type: REAL Attribute: Free Direction: Memory Public_min Group: For_DYNSUB Type: DINT Attribute: Free Direction: Memory pozo_indice (* ndice de pozo a procesar *) Type: DINT Attribute: Free Direction: Memory Init. value: 1 j (* Contador de uso general *) Type: DINT Attribute: Free Direction: Memory

Goodman_dummy

Virgo Workbench /01/20 P_PILOTO_OROCU onfiguration, 1 resou 14/51

(* dummy para llamar funcin de anlisis de Goodman *) Type: DINT Attribute: Free Direction: Memory Counter_2 Group: For_DYNSUB Type: DINT Attribute: Free Direction: Memory cds_cad_ano (* hora CDS CAD *) Type: DINT Attribute: Free Direction: Memory Calc_Pos (* Arreglo para propagar data de posicin *) Dimension: [0..10][0..255] Type: REAL Attribute: Free Direction: Memory VarString1 Group: For_DYNSUB Type: STRING(255) Attribute: Free Direction: Memory Temp_ef_Weight (* Variable temporal para calcular peso efectivo secciones remanentes de cabilla *) Type: REAL Attribute: Free Direction: Memory T_Stroke (* Tiempo de duracin de stroke del balancn (en segundos) *) Dimension: [1..4] Type: REAL Attribute: Free Direction: Memory Retain: YES Public_seg Group: For_DYNSUB Type: DINT Attribute: Free Direction: Memory Porc_Carga_SF

Virgo Workbench /01/20 P_PILOTO_OROCU onfiguration, 1 resou 15/51

(* Porcentaje de carga por cada seccin (1..10) segn factor de servicio (1->H2S..6->H2O) *) Dimension: [1..4][0..9][1..6] Type: REAL Attribute: Free Direction: Memory netdas_input Type: NETDAS Attribute: Free Direction: Memory Get_CDS_dummy (* dummy para llamar a la funcin Get_CDS *) Type: BOOL Attribute: Free Direction: Memory dir_pozo (* Variable que contiene direccin de inicio de data de pozo a procesar (leer o escribir) *) Type: DINT Attribute: Free Direction: Memory Calc_Strain (* Arreglo para propagar data de esfuerzo *) Dimension: [0..10][0..255] Type: REAL Attribute: Free Direction: Memory Buoyancy (* Volumen de la sarta *) Dimension: [1..4] Type: REAL Attribute: Free Direction: Memory VarString2 Group: For_DYNSUB Type: STRING(255) Attribute: Free Direction: Memory Rod_Stretch (* Volumen de la sarta *) Dimension: [1..4] Type: REAL Attribute: Free Direction: Memory Esfuerzos

Virgo Workbench /01/20 P_PILOTO_OROCU onfiguration, 1 resou 16/51

(* Arreglo que contendr esfuerzos mnimos y mximos en tope de cada seccin *) Dimension: [1..4][0..9] Type: Esfuerzo Attribute: Free Direction: Memory cds_ui_max_pos (* valor mximo de posicin UI de CDS *) Type: REAL Attribute: Free Direction: Memory cds_ui_min_pos (* valor mnimo de posicin UI de CDS *) Type: REAL Attribute: Free Direction: Memory

1.5. Detailed binding


Produced variables Pozo_var produced to Pozo_var (DYNSUB) Pozo_var (* Variable con datos del pozo *) Type: POZO Pozo_var (* Variable con datos del pozo... se utiliza para Binding desde recurso down_dynagraph *) Type: POZO Ef_Weight produced to Ef_Weight (DYNSUB) Ef_Weight (* Peso efectivo de la sarta *) Type: REAL Ef_Weight (* Peso efectivo de la sarta *) Type: REAL Esfuerzos produced to CopyOfEsfuerzos (DYNSUB) Esfuerzos (* Arreglo que contendr esfuerzos mnimos y mximos en tope de cada seccin *) Type: Esfuerzo CopyOfEsfuerzos (* Arreglo que contendr esfuerzos mnimos y mximos en tope de cada seccin *) Type: Esfuerzo Num_Sect produced to CopyOfNum_Sect (DYNSUB) Num_Sect (* Nmero de secciones de sarta de cabillas *) Type: DINT CopyOfNum_Sect (* Nmero de secciones de sarta de cabillas *) Type: DINT Porc_Carga_SF produced to CopyOfPorc_Carga_SF (DYNSUB) Porc_Carga_SF (* Porcentaje de carga por cada seccin (1..10) segn factor de servicio (1->H2S..6->H2O) *) Type: REAL

Virgo Workbench /01/20 P_PILOTO_OROCU onfiguration, 1 resou 17/51

CopyOfPorc_Carga_SF (1->H2S..6->H2O) *) Type: REAL

(* Porcentaje de carga por cada seccin (1..10) segn factor de servicio

Rod produced to CopyOfRod (DYNSUB) Rod (* Arreglo de estructuras para data de cabilla *) Type: ROD_SECTION CopyOfRod (* Arreglo de estructuras para data de cabilla *) Type: ROD_SECTION Existe_CDF produced to Existe_CDF (DYNSUB) Existe_CDF Type: BOOL Existe_CDF Type: BOOL

1.6. PID_ST_1 (* user modifiable, for use in ST programs *) 1.6.1. Description


An ST-languate PID function block supplied with Virgo 2000 for use with the PID fadeplate. It differs from previous versions in that the formula has been adapted to allow for a variable scan period and for tunable parameters. Bumpless control is obtained by calculating the control output, cv, recursively. When the controller is switched from manual to auto, the process does not bump as it would with the traditional algorithm. Another advantage is that elimination of the summation eliminates the danger of windup, a condition in which the controller saturates its integral term when for some reason an error signal persists. The case of Ki = 0 is known as PD control. While the calculating formula shown above is theoretically valid for PD control, it's non-stationary behavior can be surprising. When you switch from PID to PD control, any accumulated effect of the integration remains as a constant. Most operators expect that in PD control the original constant should be used rather than the integration constant from the PID formula.

1.6.2. Source
IF not init_flag then (* i.e., if first scan *) setpoint Kp Ki Kd internal_cv run_mode := setpoint_init ; := Kp_init ; := Ki_init ; := Kd_init ; := cv_init ; := mode_init ;

Virgo Workbench /01/20 P_PILOTO_OROCU onfiguration, 1 resou 18/51

error internal_cv init_flag c END_IF;

:= setpoint - process_value ; := Kp * ( setpoint - process_value )+ cv_init ; := True; := 0.0 ;

IF NOT enable_manual_setpoint_entry THEN (* read setpoint input *) setpoint := setpoint_init ; END_IF; tunable := tunable_init ; (* repeat every cycle so that this cannot be modified from HMI *) error := setpoint - process_value ; period := any_to_real ( __SYSVA_TCYCYCTIME ) / 1000.0 ; c_last := c ; IF period < 0.001 then c := 0.0 ; ELSE c := Kd / period * ( process_value - pv_last) ; END_IF ; IF not run_mode then (*use manual control *) (*do nothing - manual control means that internal_cv will be updated from HMI;*) ELSIF Ki = 0.0 then (*use std method to calculate PD control *) internal_cv := Kp * ( setpoint - process_value ) + cv_init - c ; ELSE (*use Delta V method to calculate PID control *) delta_cv := 0.5 * period * ( Ki * error + Ki_last * error_last) + Kp * error - Kp_last * error_last - c + c_last ; internal_cv := internal_cv + delta_cv ; END_IF ; IF internal_cv > cv_max THEN internal_cv := cv_max; END_IF; IF internal_cv < cv_min THEN internal_cv := cv_min; END_IF; control_value error_last pv_last Ki_last Kp_last := internal_cv ; := error ; := process_value ; := Ki ; := Kp ;

1.6.3. Local Variables + Parameters


process_value Type: REAL (* quantity to be controlled *)

Virgo Workbench /01/20 P_PILOTO_OROCU onfiguration, 1 resou 19/51

Alias: pv Direction: setpoint_init (* target process value *) Type: REAL Alias: sp Direction: Kp_init (* proportional gain, normally positive, use negative for reverse acting PID *) Type: REAL Alias: Kp Direction: Ki_init (* integral gain, normally positive, use negative for reverse acting PID *) Type: REAL Alias: Ki Direction: Kd_init (* derivative gain, normally positive, use negative for reverse acting PID *) Type: REAL Alias: Kd Direction: cv_init (* integration constant, used as intital value for cv *) Type: REAL Alias: cvin Direction: mode_init (* 1=auto, 0 = manual *) Type: BOOL Alias: mode Direction: setpoint_max Type: REAL Alias: spmx Direction: setpoint_min Type: REAL Alias: spmn Direction: (* max value for setpoint *)

(* min value for setpoint *)

Kp_max (* max value for Kp *) Type: REAL Alias: Kpmx Direction: Kp_min (* min value for KP *) Type: REAL Alias: Kpmn

Virgo Workbench /01/20 P_PILOTO_OROCU onfiguration, 1 resou 20/51

Direction: Ki_max (* max value for Ki *) Type: REAL Alias: Kimx Direction: Ki_min (* min value for Ki *) Type: REAL Alias: Kimn Direction: Kd_max (* max value for Kd *) Type: REAL Alias: Kdmx Direction: Kd_min (* min value for *) Type: REAL Alias: Kdmn Direction: cv_max (* upper limit on cv *) Type: REAL Alias: cvmx Direction: cv_min (* lower limit on cv *) Type: REAL Alias: cvmn Direction: enable_manual_setpoint_entry (* True means that setpoint can be entered form faceplate, False means that PID can be used in cascade with a variable setpoint *) Type: BOOL Alias: man Direction: tunable_init (* True means gains can be input from HMI faceplate, false means that initial gain will be used *) Type: BOOL Alias: tune Direction: control_value Type: REAL Alias: cv Direction: internal_cv Type: REAL (* this is the controller's output *)

Virgo Workbench /01/20 P_PILOTO_OROCU onfiguration, 1 resou 21/51

Direction: Pgina %u Pginas %u-%u setpoint (* target process value *) Type: REAL Direction: Pgina %u Pginas %u-%u Kp (* proportional gain, normally positive, use negative for reverse acting PID *) Type: REAL Direction: Pgina %u Pginas %u-%u Ki (* integral gain, normally positive, use negative for reverse acting PID *) Type: REAL Direction: Pgina %u Pginas %u-%u Kd (* derivative gain, normally positive, use negative for reverse acting PID *) Type: REAL Direction: Pgina %u Pginas %u-%u error (* error = setpoint - pv *) Type: REAL Direction: Pgina %u Pginas %u-%u error_last (* error from previous iteration *) Type: REAL Direction: Pgina %u Pginas %u-%u period (* update period of PID block in seconds *) Type: REAL Direction: Pgina %u Pginas %u-%u period_last (* update perdiod od PID from previous cycle *) Type: REAL Direction: Pgina %u Pginas %u-%u c (* local variable used in calculating derviative term *) Type: REAL Direction: Pgina %u

Virgo Workbench /01/20 P_PILOTO_OROCU onfiguration, 1 resou 22/51

Type: BOOL Direction: Pgina %u Pginas %u-%u init_flag (* initialzation flag *) Type: BOOL Direction: Pgina %u Pginas %u-%u pv_last (* pv from previous iteration *) Type: REAL Direction: Pgina %u Pginas %u-%u Ki_last (* Ki from previous iteration *) Type: REAL Direction: Pgina %u

1.7. VIRGO_STATUS (* expose system variables to OPC *) 1.7.2. Source

virgo_status_name := __SYSVA_RESNAME ; virgo_status_scan_cnt := __SYSVA_SCANCNT ; virgo_status_cycle_cnt := __SYSVA_CYCLECNT ; virgo_status_period := any_to_dint ( __SYSVA_TCYCYCTIME ) ; virgo_status_calc_time := any_to_dint ( __SYSVA_TCYCURRENT ) ; virgo_status_calc_time_max := any_to_dint ( __SYSVA_TCYMAXIMUM ) virgo_status_overflow := __SYSVA_TCYOVERFLOW ;

1.7.3. Local Variables + Parameters


BOGUS_INPUT Type: BOOL Alias: en Direction: VIRGO_STATUS_NAME Type: STRING(80) Alias: name Direction: (* virgo name *)

VIRGO_STATUS_SCAN_CNT Type: DINT Alias: scan

(* number of scans *)

Virgo Workbench /01/20 P_PILOTO_OROCU onfiguration, 1 resou 23/51

Direction: VIRGO_STATUS_CYCLE_CNT Type: DINT Alias: cyc Direction: Pgina %u Pginas %u-%u VIRGO_STATUS_PERIOD Type: DINT Alias: time Direction: Pgina %u Pginas %u-%u (* number of cycles *)

(* execution period in ms *)

VIRGO_STATUS_CALC_TIME Type: DINT Alias: calc Direction: Pgina %u Pginas %u-%u

(* time spent in calculating last cycle in ms *)

VIRGO_STATUS_CALC_TIME_MAX Type: DINT Alias: max Direction: Pgina %u Pginas %u-%u

(* max time spent in calculating a cycle in ms *)

1.8. Interpolation 1.8.2. Source


Interpolation_counter := not(Interpolation_counter); (* trace de interpolaciones *) (* Se calcula nuevo Delta_T *) IF Rod[num_pozo,IJK].Int_Len >= ignore_len THEN Delta_TT := Rod[num_pozo,IJK].Int_Len / Rod[num_pozo,IJK].Speed; (* Se calculan valores auxiliares de u, du/dx y du/dt primeros elementos... *) pos_s[1] := (1.0 / Pozo_var[num_pozo].delta_t ) * (Calc_Pos[IJK, pointnum[num_pozo]] * Delta_TT + Calc_Pos[IJK, 1] * (Pozo_var[num_pozo].delta_t - Delta_TT)); str_s[1] := (1.0 / Pozo_var[num_pozo].delta_t) * (Calc_strain[IJK, pointnum[num_pozo]] * Delta_TT + Calc_strain[IJK, 1] * (Pozo_var[num_pozo].delta_t - Delta_TT)); vel_s[1] := (1.0 / Pozo_var[num_pozo].delta_t) * (Calc_Vel[IJK, pointnum[num_pozo]] * Delta_TT + Calc_Vel[IJK, 1] * (Pozo_var[num_pozo].delta_t - Delta_TT)); (* ltimos elementos *) LM := pointnum[num_pozo] * 2; pos_s[LM] := (1.0 / Pozo_var[num_pozo].delta_t) * (Calc_Pos[IJK, pointnum[num_pozo]] * (Pozo_var[num_pozo].delta_t - Delta_TT) + Calc_Pos[IJK, 1] * Delta_TT); str_s[LM] := (1.0 / Pozo_var[num_pozo].delta_t) * (Calc_strain[IJK, pointnum[num_pozo]] * (Pozo_var[num_pozo].delta_t - Delta_TT) + Calc_strain[IJK, 1] * Delta_TT); vel_s[LM] := (1.0 / Pozo_var[num_pozo].delta_t) * (Calc_Vel[IJK, pointnum[num_pozo]] *

Virgo Workbench /01/20 P_PILOTO_OROCU onfiguration, 1 resou 24/51

(Pozo_var[num_pozo].delta_t - Delta_TT) + Calc_Vel[IJK, 1] * Delta_TT); LC := LM - 2; IC := 0; FOR K := 2 To LC BY 2 DO IAA := K - 1 - IC; IA := K - IC; pos_s[K] := (1.0 / Pozo_var[num_pozo].delta_t) * (Calc_Pos[IJK, IAA] * (Pozo_var[num_pozo].delta_t Delta_TT) + Calc_Pos[IJK, IA] * Delta_TT); str_s[K] := (1.0 / Pozo_var[num_pozo].delta_t) * (Calc_strain[IJK, IAA] * (Pozo_var[num_pozo].delta_t Delta_TT) + Calc_strain[IJK, IA] * Delta_TT); vel_s[K] := (1.0 / Pozo_var[num_pozo].delta_t) * (Calc_Vel[IJK, IAA] * (Pozo_var[num_pozo].delta_t Delta_TT) + Calc_Vel[IJK, IA] * Delta_TT); pos_s[K + 1] := (1.0 / Pozo_var[num_pozo].delta_t) * (Calc_Pos[IJK, IAA] * Delta_TT + Calc_Pos[IJK, IA] * (Pozo_var[num_pozo].delta_t - Delta_TT)); str_s[K + 1] := (1.0 / Pozo_var[num_pozo].delta_t) * (Calc_strain[IJK, IAA] * Delta_TT + Calc_strain[IJK, IA] * (Pozo_var[num_pozo].delta_t - Delta_TT)); vel_s[K + 1] := (1.0 / Pozo_var[num_pozo].delta_t) * (Calc_Vel[IJK, IAA] * Delta_TT + Calc_Vel[IJK, IA] * (Pozo_var[num_pozo].delta_t - Delta_TT)); IC := IC + 1; END_FOR; AAA := (1.0 / Rod[num_pozo,IJK].Speed) + ((damp * Delta_TT) / (2.0 * Rod[num_pozo,IJK].Speed)); BBB := (1.0 / Rod[num_pozo,IJK].Speed) - ((damp * Delta_TT) / (2.0 * Rod[num_pozo,IJK].Speed)); FOR K := 1 To pointnum[num_pozo] BY 1 DO KK := 2 * K; KKK := KK - 1; CCC := -BBB * vel_s[KKK] + str_s[KKK]; DDD := AAA * vel_s[KK] + str_s[KK]; Calc_Vel[IJK, K] := (DDD - CCC) / (BBB + AAA); Calc_strain[IJK, K] := (AAA * DDD + BBB * CCC) / (BBB + AAA); POS_A := (Rod[num_pozo,IJK].Int_Len / 2.0) * (Calc_strain[IJK, K] + str_s[KK]); POS_A := POS_A + pos_s[KK] - (Delta_TT * (Calc_Vel[IJK, K] + vel_s[KK]) / 2.0); POS_B := (Rod[num_pozo,IJK].Int_Len / 2.0) * (Calc_strain[IJK, K] + str_s[KKK]); POS_B := POS_B + pos_s[KKK] + (Delta_TT * (Calc_Vel[IJK, K] + vel_s[KKK]) / 2.0); Calc_Pos[IJK, K] := (POS_A + POS_B) / 2.0; END_FOR; END_IF; Interpolation := NOT (pepe); (* dummy *)

1.8.3. Local Variables + Parameters


pepe Type: BOOL

Virgo Workbench /01/20 P_PILOTO_OROCU onfiguration, 1 resou 25/51

Direction: num_pozo (* Pozo siendo procesado *) Type: DINT Direction: Interpolation Type: BOOL Direction:

1.9. Calc_Downhole 1.9.2. Source


(* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *) (* CONTROL DE EJECUCION *) (* Si no se ha realizado la inicializacin de valores necesarios para la ejecucin del programa, tales como los valores de produccin, o los parmetros de la sarta de cabillas, el operador tiene la posibilidad de mantener detenida la ejecucin del programa desde la pgina web de configuracin: "dyna_config.html" *) if (run=true) then (* se ejecuta programa si la variable "run" esta TRUE *) if existe_pozo[pozo_indice]= TRUE then (* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *) (* Get_CDS *) (* Lectura de Carta Dinagrfica de Superficie (CDS). *) case pozo_indice of 1: dir_pozo := cds_cad_pozo_1; 2: dir_pozo := cds_cad_pozo_2; 3: dir_pozo := cds_cad_pozo_3; 4: dir_pozo := cds_cad_pozo_4; end_case; Get_CDS_dummy := Get_CDS(Get_CDS_dummy,pozo_indice, dir_pozo); (* fin Get_CDS *) (* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *) (* Clculo de CDF *) if (BHD_Calc[pozo_indice] = TRUE) and (pointnum[pozo_indice] >= pointnum_min[pozo_indice]) and (pointnum[pozo_indice] <= pointnum_max[pozo_indice]) then BHD_Calculation_Dummy := BHD_Calculation(BHD_Calculation_Dummy, pozo_indice); end_if; (* BHD_Calc *) (* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ----

Virgo Workbench /01/20 P_PILOTO_OROCU onfiguration, 1 resou 26/51

- - - - - - - - *)

(* Publicacin en pgina web de CDS y CDF *) case pozo_indice of 1: dir_pozo := cdf_pozo_1; 2: dir_pozo := cdf_pozo_2; 3: dir_pozo := cdf_pozo_3; 4: dir_pozo := cdf_pozo_4; end_case; public_dynas_dummy := Public_dynas(public_dynas_dummy, pozo_indice, dir_pozo); (* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *) end_if; (* existe_pozo[pozo_indice] *) (* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *) (* Determinacin del pozo a procesar en el prximo ciclo *) (* pozo_indice vara cclicamente entre 1 y 4 *) if pozo_indice=4 then pozo_indice:= 1; else (* pozo_indice:= pozo_indice+1; *) pozo_indice:= 1; (* GG20090626 ... se fuerza siempre a 1 para el caso de un solo pozo. Adems "pozo_indice" se inicializa en 1... para la aplicacin del LS-2905 *) end_if; end_if; (* run ... control de ejecucin *)

1.10. Public_dynas 1.10.2. Source


(* publicar CDS en UI en pgina web (* *)

Razonamiento: Si en nmero de puntos est comprendido dentro del rango establecido por pointnum_min y pointnum_maxm, quiere decir que se proces la carta de superficie y se calcul la correspondiente de fondo, por tal razn si la comparacin resulta en nmero de puntos fuera de rango, puede abortarse toda la operacin por completo. *) if (pointnum[pozo_public] >= pointnum_min[pozo_public]) and (pointnum[pozo_public] <=

Virgo Workbench /01/20 P_PILOTO_OROCU onfiguration, 1 resou 27/51

pointnum_max[pozo_public]) then (* Escritura en memoria Net-DAS. PUBLICAR HEADER CDS UI (* Header CDS *) nueva[0].PvDINT := pointnum[pozo_public]; nueva[1].PvDINT :=cds_cad_hora; nueva[2].PvDINT :=cds_cad_min; nueva[3].PvDINT :=cds_cad_seg; nueva[4].PvDINT :=cds_cad_dia; nueva[5].PvDINT :=cds_cad_mes; nueva[6].PvDINT :=cds_cad_ano; (* se escriben mximos y mnimos de CDS en UI *) nueva[8].PvDINT :=any_to_dint(cds_ui_max_pos); nueva[9].PvDINT :=any_to_dint(cds_ui_min_pos); nueva[10].PvDINT :=any_to_dint(cds_ui_max_load); nueva[11].PvDINT :=any_to_dint(cds_ui_min_load); (* escritura en memoria a partir de HREG 41001 *) netdas_out('plc_mem','HREG',direccion-525 ,11,'DINT',nueva); (* canales CDS *) *)

(* Ahora canales CDS *) for i_public := 0 to 1 by 1 do (* comn para todo tipo de cartas.... <125; >125 *) (* Razonamiento: a fines de facilitar inteligibilidad del cdigo, se decide realizar siempre la escritura de 1 bloque de 125 regs. y despus se pregunta si el nmero de puntos es mayor de 125; de ser ste el caso, se escriben los remanentes "pointnum[pozo_public] - 125" *) for j_public := 1 to 125 by 1 do nueva[j_public-1].PvDINT := any_to_dint(SurfaceDyn[pozo_public,i_public,j_public]); end_for; (* j *) netdas_out('plc_mem','HREG',(direccion-500+i_public*250),125,'DINT',nueva); if (pointnum[pozo_public]>125) then (* para cartas con ms de 125 puntos se escribe el resto de los puntos *) for j_public := 1 to (pointnum[pozo_public] -125) by 1 do nueva[j_public-1].PvDINT := any_to_dint(SurfaceDyn[pozo_public,i_public,j_public+125]); end_for; (* j *) netdas_out('plc_mem','HREG',direccion-500+125+(250*i_public),(pointnum[pozo_public] -125),'DINT',nueva); end_if; (* (pointnum[pozo_public]>125) *) end_for; (* i_public *) (* Fin Write_CDS *)

*)

(* Escritura de CDF en memoria Net-DAS *) (* Primero se hallan mximos y mnimos de pos. y carga Para hallar mximos y mnimos de posicin y carga se inicializan las variables correspondientes max pos cdf :=0.0;

Virgo Workbench /01/20 P_PILOTO_OROCU onfiguration, 1 resou 28/51

min_pos_cdf :=0.0; max_carga_cdf :=0.0; min_carga_cdf :=0.0; for i_public := 0 to 1 by 1 do for j_public := 1 to pointnum[pozo_public] by 1 do case i_public of (* "0" significa posicin *) 0: if DownDyn[pozo_public,i_public,j_public] > max_pos_cdf then max_pos_cdf:=DownDyn[pozo_public,i_public,j_public]; end_if; if DownDyn[pozo_public,i_public,j_public] < min_pos_cdf then min_pos_cdf:=DownDyn[pozo_public,i_public,j_public]; end_if; (* "1" significa carga *) 1: if DownDyn[pozo_public,i_public,j_public] > max_carga_cdf then max_carga_cdf:=DownDyn[pozo_public,i_public,j_public]; end_if; if DownDyn[pozo_public,i_public,j_public] < min_carga_cdf then min_carga_cdf:=DownDyn[pozo_public,i_public,j_public]; end_if; end_case; end_for; (* j_public *) end_for; (* i_public *) (* Escritura HEADER CDF *)

nueva[0].PvDINT := pointnum[pozo_public]; nueva[1].PvDINT :=cds_cad_hora; nueva[2].PvDINT :=cds_cad_min; nueva[3].PvDINT :=cds_cad_seg; nueva[4].PvDINT :=cds_cad_dia; nueva[5].PvDINT :=cds_cad_mes; nueva[6].PvDINT :=cds_cad_ano; nueva[7].PvDINT :=any_to_dint(max_pos_cdf) ; nueva[8].PvDINT :=any_to_dint(min_pos_cdf) ; nueva[9].PvDINT :=any_to_dint(max_carga_cdf); nueva[10].PvDINT :=any_to_dint(min_carga_cdf); netdas_out('plc_mem','HREG',direccion ,11,'DINT',nueva); (* Escritura de canales CDF *)

for i_public := 0 to 1 by 1 do (* se escriben primeros 125 regs. *) for j_public := 1 to 125 by 1 do nueva[j_public-1].PvDINT := any_to_dint(DownDyn[pozo_public,i_public,j_public]); end_for; (* j_public *) netdas_out('plc_mem','HREG',direccion+25+(250*i_public),125,'DINT',nueva); (* salida *) (* Cuando la CDF es mayor de 125 puntos *)

Virgo Workbench /01/20 P_PILOTO_OROCU onfiguration, 1 resou 29/51

if (pointnum[pozo_public]>125) then for j_public := 1 to pointnum[pozo_public]-125 by 1 do nueva[j_public-1].PvDINT := any_to_dint(DownDyn[pozo_public,i_public,j_public]); end_for; (* j_public *) netdas_out('plc_mem','HREG',direccion+25+125+(i_public*250),(pointnum[pozo_public]-125),'DINT',nueva); (* salida *) end_if; end_for; (* i_public *) (* fin Write_BHD *) end_if; (* pointnum *) *)

(* Escritura de archivos de texto para pgina de despliegue de CDS/CDF PublicaResult_dummy :=PublicaResult(pozo_public); (* fin *) Public_dynas := NOT(pepe1); (* artificio para utilizar funcin *)

1.10.3. Local Variables + Parameters


i_public (* entero para indexar arreglos *) Type: DINT Attribute: Free Direction: Memory j_public (* entero para indexar arreglos *) Type: DINT Attribute: Free Direction: Memory max_carga_cdf (* valor mximo carga CDF *) Type: REAL Attribute: Free Direction: Memory max_pos_cdf (* valor mximo posicin CDF *) Type: REAL Attribute: Free Direction: Memory

Virgo Workbench /01/20 P_PILOTO_OROCU onfiguration, 1 resou 30/51

min_carga_cdf (* valor mnimo carga CDF *) Type: REAL Attribute: Free Direction: Memory min_pos_cdf (* valor mnimo posicin CDF *) Type: REAL Attribute: Free Direction: Memory nueva Type: NETDAS Attribute: Free Direction: Memory PublicaResult_dummy Type: BOOL Attribute: Free Direction: Memory pepe1 Type: BOOL Direction: pozo_public (* Apuntador del pozo al cual publicarle la CD *) Type: DINT Direction: direccion (* Direccin de memoria de pozo al cual publicar CDs *) Type: DINT Direction: Public_dynas Type: BOOL Direction: (* dummy para llamar a funcin "PublicaResult" *)

1.11. Get_CDS (* Lectura de CDS (simulada o real) *) 1.11.2. Source


if simul_on_off[pozo_CDS]=FALSE then *) (* - Leer carta en cuentas ADC cruda - Convertir CDS a unidades de ingeniera (* MODO usar data real proveniente de driver DynamodTCP

*) (* lectura de header de CDS. Generado por recurso de captura CDS *) netdas_in('plc_mem','HREG', dir_adq,12, 'DINT');

Virgo Workbench /01/20 P_PILOTO_OROCU onfiguration, 1 resou 31/51

netdas_input := netdas_in.Data; pointnum[pozo_CDS] := any_to_dint(netdas_input[0].PvDINT); cds_cad_hora := any_to_dint(netdas_input[1].PvDINT); cds_cad_min := any_to_dint(netdas_input[2].PvDINT); cds_cad_seg := any_to_dint(netdas_input[3].PvDINT); cds_cad_dia := any_to_dint(netdas_input[4].PvDINT); cds_cad_mes := any_to_dint(netdas_input[5].PvDINT); cds_cad_ano := any_to_dint(netdas_input[6].PvDINT); (* mximos y mnimos de posicin y carga... se convierten a UI *) if (cpmax[pozo_CDS] - cpmin[pozo_CDS]) <> 0.0 and Clmax[pozo_CDS] <> 0.0 then cds_ui_max_pos := Pmax[pozo_CDS] * (any_to_real(netdas_input[8].PvDINT) - cpmin[pozo_CDS]) / (cpmax[pozo_CDS] - cpmin[pozo_CDS]); cds_ui_min_pos := Pmax[pozo_CDS] * (any_to_real(netdas_input[9].PvDINT) - cpmin[pozo_CDS]) / (cpmax[pozo_CDS] - cpmin[pozo_CDS]); cds_ui_max_load := any_to_real(netdas_input[10].PvDINT)*Lmax[pozo_CDS]/Clmax[pozo_CDS]; cds_ui_min_load := any_to_real(netdas_input[11].PvDINT)*Lmax[pozo_CDS]/Clmax[pozo_CDS]; else (* como hay posibilidad de divisin por cero, se asignan valores default y se toman acciones... *) (* valores default *) cds_ui_max_pos := 0.0; cds_ui_min_pos := 0.0; cds_ui_max_load := 0.0; cds_ui_min_load := 0.0; (* acciones *) aux_conv_ui := false; (* senalizando falla *) run:= false; (* se detiene ejecucin del programa *) div_por_cero:= false; (* sealizando divisin por cero *) end_if; (* lectura CDS *) if pointnum[pozo_CDS] <> 0 then (* hay datos ???... calcular *) T_Stroke[pozo_CDS] := Pozo_var[pozo_CDS].delta_t * any_to_real(pointnum[pozo_CDS]); (* 20031130 *) (* Leer carta en cuentas crudas del ADC y conversin a Unidades de Ingeniera UI *) if (cpmax[pozo_CDS]-cpmin[pozo_CDS]) <> 0.0 and clmax[pozo_CDS]<>0.0 then for i := 0 to 1 by 1 do (* netdas_in('plc_mem','IREG',dir_adq+(250*i)+25,125,'DINT'); *) netdas_in('plc_mem','HREG',dir_adq+(250*i)+25,125,'DINT'); netdas_input := netdas_in.Data; for j := 1 to 125 by 1 do (* i=0 significa posicin, 1 significa carga. De una vez se hace la conversin a UI *) if i=0 then SurfaceDyn[pozo_CDS,i,j] := Pmax[pozo_CDS] * (any_to_real(netdas_input[j-1].PvDINT) - cpmin[pozo_CDS]) / (cpmax[pozo_CDS] - cpmin[pozo_CDS]); else (* carga*) SurfaceDyn[pozo_CDS,i,j] := any_to_real(netdas_input[j-1].PvDINT)*Lmax[pozo_CDS]/Clmax[pozo_CDS]; end_if; end_for; if pointnum[pozo_CDS]>125 then netdas_in('plc_mem','HREG',dir_adq+125+(250*i)+25,pointnum[pozo_CDS]-125,'DINT');

Virgo Workbench /01/20 P_PILOTO_OROCU onfiguration, 1 resou 32/51

conversin a UI *)

netdas_input := netdas_in.Data; for j := 1 to pointnum[pozo_CDS]-125 by 1 do (* i=0 significa posicin, 1 significa carga. De una vez se hace la

if i=0 then SurfaceDyn[pozo_CDS,i,j+125] := Pmax[pozo_CDS] * (any_to_real(netdas_input[j-1].PvDINT) - cpmin[pozo_CDS]) / (cpmax[pozo_CDS] - cpmin[pozo_CDS]); else (* carga*) SurfaceDyn[pozo_CDS,i,j+125] := any_to_real(netdas_input[j-1].PvDINT)*Lmax[pozo_CDS]/Clmax[pozo_CDS]; end_if; end_for; end_if; end_for; else aux_conv_ui := false; (* senalizando falla *) run:= false; (* se detiene ejecucin del programa *) div_por_cero:= false; (* sealizando divisin por cero *) end_if; end_if; (* pointnum[pozo_CDS] *) end_if; (* fin modo data real *) if simul_on_off[pozo_CDS] = TRUE then (*==============================Cdigo aadido para leer del archivo texto=======================================*) if lee_texto=true then for Counter_1 := 1 to 255 by 1 do SurfaceDyn[pozo_CDS,0,Counter_1]:= 0.0; SurfaceDyn[pozo_CDS,1,Counter_1]:= 0.0; end_for; pointnum[pozo_CDS] := 0; VarString1:= 'NumPtos'; VarBool1:= NetDAS_FSearch('/home/webadmin/htdocs/CDS.txt',VarString1,VarString2 ); IF (VarBool1=TRUE ) THEN VarString2 := DELETE (VarString2, FIND (VarString2 ,';'),1); pointnum[pozo_CDS] := ANY_TO_DINT (LEFT (VarString2,FIND (VarString2 ,';')-1)); IF (pointnum[pozo_CDS] <> 0 ) THEN FOR Counter_1 := 1 to pointnum[pozo_CDS] by 1 DO VarString1 := 'CDS_' + ANY_TO_STRING(Counter_1-1); VarBool1:= NetDAS_FSearch('/home/webadmin/htdocs/CDS.txt',VarString1,VarString2 ); VarString2 := DELETE (VarString2, FIND (VarString2 ,';'),1); for Counter_2 := 0 To 1 by 1 do SurfaceDyn[pozo_CDS,Counter_2,Counter_1]:= String2Real (LEFT (VarString2,FIND (VarString2 ,';')-1)); VarString2 := DELETE (VarString2, FIND (VarString2 ,';'),1); end_for; END_FOR; END_IF;

Virgo Workbench /01/20 P_PILOTO_OROCU onfiguration, 1 resou 33/51

end_if;

END_IF; end_if; lee_texto := false;

(*

para evitar lecturas continuas del mismo archivo

*)

(*===========================================Codigo Original==============================================*) (* MODO SIMULACIN: se lee data de superficie en HREGS: 42000 -> pointnum[pozo_CDS], 42001 -> vector posicion, 42201 -> vector carga *) (* numero de puntos de carta superficie *) (* netdas_in('plc_mem','HREG',cds_ui_pointnum[pozo_CDS],1,'DINT'); netdas_input := netdas_in.Data; pointnum[pozo_CDS] := any_to_dint(netdas_input[0].PvDINT); T_Stroke := Pozo_var[pozo_CDS].delta_t * any_to_real(pointnum[pozo_CDS]); if (pointnum[pozo_CDS] <> 0) then for i:=0 to 1 by 1 do netdas_in('plc_mem','HREG',cds_ui_init+ 256*i,125,'DINT'); netdas_input := netdas_in.Data; IF pointnum[pozo_CDS]<=125 then for j := 1 to pointnum[pozo_CDS] by 1 do SurfaceDyn[pozo_CDS,i,j] := any_to_real(netdas_input[j-1].PvDINT); end_for; else for j := 1 to 125 by 1 do SurfaceDyn[pozo_CDS,i,j] := any_to_real(netdas_input[j-1].PvDINT); end_for; netdas_in('plc_mem','HREG',cds_ui_init+125 + 256*i,pointnum[pozo_CDS]-125,'DINT'); netdas_input := netdas_in.Data; for j := 1 to pointnum[pozo_CDS]-125 by 1 do SurfaceDyn[pozo_CDS,i,j+125] := any_to_real(netdas_input[j-1].PvDINT); end_for; end_if; end_for; end_if; end_if; *) (*=======================Cdigo aadido para determinar los max y min en caso de simulacin=====================*) (* cds_ui_min_load:= SurfaceDyn[pozo_CDS,1,1]; FOR Counter_1 := 1 TO pointnum[pozo_CDS] BY 1 DO IF SurfaceDyn[pozo_CDS,1,Counter_1] < cds_ui_min_load THEN cds_ui_min_load := SurfaceDyn[pozo_CDS,1,Counter_1]; END_IF; END_FOR; cds_ui_max_load:= SurfaceDyn [1,1]; FOR Counter_1 := 1 TO pointnum[pozo_CDS] BY 1 DO

Virgo Workbench /01/20 P_PILOTO_OROCU onfiguration, 1 resou 34/51

IF SurfaceDyn[pozo_CDS,1,Counter_1] > cds_ui_max_load THEN cds_ui_max_load := SurfaceDyn[pozo_CDS,1,Counter_1]; END_IF; END_FOR; end_if; *) (* <>-<>-<>-<>-<>-<> Salida de funcin <>-<>-<>-<>-<>-<> *) Get_CDS:= not(pepe2);

1.11.3. Local Variables + Parameters


pepe2 Type: BOOL Direction: pozo_CDS (* pozo del cual adquirir CDS *) Type: DINT Direction: dir_adq (* Direccin de la cual hacer la lectura de la CDS en cuentas crudas ADC *) Type: DINT Direction: Get_CDS Type: BOOL Direction:

Virgo Workbench /01/20 P_PILOTO_OROCU onfiguration, 1 resou 35/51

1.12. Analisis_Goodman 1.12.2. Source


(* Esta funcin hace el clculo del porcentaje de carga en la seccin de cabillas para factores de servicio comprendidos en el rango: 0.5 <= SF >= 1 *) SF_index :=1; SF:= 0.5; (* valor correspondiente a H2S... peor caso for SF_loop := 1 to 6 by 1 do SA := (Rod[pozo,Seccion+1].T_max/4.0 + 0.5625*Esfuerzos[pozo,Seccion].minimo)*SF; DSA := SA - Esfuerzos[pozo,Seccion].minimo; Porc_Carga_SF [pozo,Seccion,SF_index] := (Esfuerzos[pozo,Seccion].maximo Esfuerzos[pozo,Seccion].minimo) * 100.0 / DSA; SF_index := SF_index+1; SF:= SF+0.1; end_for; Analisis_Goodman:= Seccion; (* artificio para retornar de funcin *)

*)

1.12.3. Local Variables + Parameters


DSA (* Rango de esfuerzo permitido *) Type: REAL Attribute: Free Direction: Memory SA (* Esfuerzo mximo permisible *) Type: REAL Attribute: Free Direction: Memory SF (* "Service Factor" *) Type: REAL Attribute: Free Direction: Memory SF_index (* ndice para loop de clculo. Representa diversos factores de servicio *) Type: DINT

Virgo Workbench /01/20 P_PILOTO_OROCU onfiguration, 1 resou 36/51

Attribute: Free Direction: Memory SF_loop (* variable para ser usada en lazo "For" *) Type: SINT Attribute: Free Direction: Memory Seccion (* Nmero de seccin al la cual se le har el anlisis de esfuerzos corresp. *) Type: DINT Direction: pozo Type: DINT Direction: Analisis_Goodman Type: DINT Direction:

1.13. String2Real 1.13.2. Source


SizeSt:=mlen(VariableString); Int_Part:=left(VariableString,find(VariableString,'.')-1); Dec_Part:=right(VariableString,SizeSt-find(VariableString,'.')); SizeSt:=mlen(Dec_Part); for i:=1 to 7 do if left(Dec_Part,1)='0' then Dec_Part:=right(Dec_Part, SizeSt-i); end_if; end_for; String_Real1:=any_to_real(any_to_dint(Int_Part)); String_Real2:=any_to_real(any_to_dint(Dec_Part))/expt(10.0,SizeSt); if find(VariableString,'-')<>0 then String2Real:=String_Real1-String_Real2; else String2Real:=String_Real1+String_Real2; end_if;

1.13.3. Local Variables + Parameters


Dec_Part Type: STRING(80) Attribute: Free Direction: Memory Int_Part Type: STRING(80)

Virgo Workbench /01/20 P_PILOTO_OROCU onfiguration, 1 resou 37/51

Attribute: Free Direction: Memory SizeSt Type: DINT Attribute: Free Direction: Memory String_Real1 Type: REAL Attribute: Free Direction: Memory String_Real2 Type: REAL Attribute: Free Direction: Memory VariableString Type: STRING(30) Direction: String2Real Type: REAL Direction:

1.14. BHD_Calculation 1.14.2. Source


(* Antes de pasar a ejecutar el MCH (Method of Characteristics) deben realizarse los siguientes clculos: - Invertir (cambiar signo) de data de posicin - Convertir a valores de tensin (strain) valores de carga - A partir de informacin de posicin, calcular vector de velocidades - Se aprovecha el ciclo para encontrar PPRL ... GG030313*) IJK := 0; (* indica que es la seccin "0", es decir, 1.era seccin... *) FOR i := 1 To pointnum[pozo_proc] BY 1 DO (* POSICION: Se pasa data de posicin de superficie pero con cambio de signo. Esto se hace para respetar convencin para MCH.*) Calc_Pos[0, i] := -SurfaceDyn[pozo_proc,0, i]; (* CARGA: Se escribe en arreglo de clculo data dinmica de esfuerzo True Load...*) (* aqu no hay posibilidad de divisin poir cero *) Calc_strain[0,i] := 4.0 * ( SurfaceDyn[pozo_proc,1,i] - Ef_Weight[pozo_proc] ) / ( Rod[pozo_proc,1].Mod_Young * pi * Rod[pozo_proc,1].Diameter * Rod[pozo_proc,1].Diameter); (*==========Aadido Variables insumo de DYNSUB===========*) (* public_CDS[1,i]:= SurfaceDyn[pozo_proc,1, i]; public_CDS[0,i]:= SurfaceDyn[pozo_proc,0, i]; *)

Virgo Workbench /01/20 P_PILOTO_OROCU onfiguration, 1 resou 38/51

(*====================================================*) END_FOR; (*==========Aadido Variables insumo de DYNSUB===========*) (* public_pointnum:= pointnum[pozo_proc]; Public_ano:= cds_cad_ano; Public_mes:= cds_cad_mes; Public_dia:= cds_cad_dia; Public_hora:= cds_cad_hora; Public_min:=cds_cad_min; Public_seg:=cds_cad_seg;

*)

(*====================================================*) (* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *) (* Anlisis de Goodman para tope de 1era. seccin *) Temp:= SurfaceDyn[pozo_proc,1,1] *4.0 / (pi * pow(Rod[pozo_proc,1].Diameter,2.0)); Esfuerzos[pozo_proc,IJK].minimo := Temp; (* inicializacin para buscar mximo y mnimo *) Esfuerzos[pozo_proc,IJK].maximo := Temp; for i := 1 to pointnum[pozo_proc] by 1 do (* se compara valor de punto actual a fines de determinar si ste representa un mnimo o un mximo de carga, de manera de actualizar entonces estos valores en el arreglo "Esfuerzos", los cuales se utilizaran en el anlisis de Goodman correspondiente *) Temp := SurfaceDyn[pozo_proc,1,i]*4.0 / (pi * pow(Rod[pozo_proc,1].Diameter,2.0)); IF Temp < Esfuerzos[pozo_proc,IJK].minimo THEN Esfuerzos[pozo_proc,IJK].minimo := Temp; END_IF; IF Temp > Esfuerzos[pozo_proc,IJK].maximo THEN Esfuerzos[pozo_proc,IJK].maximo := Temp; END_IF; end_for; (* Se hace anlisis de Goodman para tope de primer "Tap" *) Goodman_dummy := Analisis_Goodman(IJK,pozo_proc); (* hacer anlisis de esfuerzos en cabillas. Seccin 0 *) (* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *) (* primer elemento posicin*) Calc_Pos[0, 0] := -(SurfaceDyn[pozo_proc,0, pointnum[pozo_proc]] + SurfaceDyn[pozo_proc,0, 1]) / 2.0; (* promedio *) (* primer elemento tensin*) Calc_strain[0, 0] := (Calc_strain[0,pointnum[pozo_proc]] + Calc_strain[0,1]) / 2.0; (* VELOCIDAD: Se trabajar con valores promedio de velocidad, de modo que se clcula el promedio... *) IF Pozo_var[pozo_proc].delta_t <> 0.0 THEN FOR i := 1 To pointnum[pozo_proc] - 1 BY 1 DO Calc_Vel[0, i] := (Calc_Pos[0, i + 1] - Calc_Pos[0, i - 1]) / (2.0 * Pozo_var[pozo_proc].delta_t ); END_FOR; (* Razonamiento: para evitar las perturbaciones que introducen las condiciones de borde, para los valores 1ero. y

Virgo Workbench /01/20 P_PILOTO_OROCU onfiguration, 1 resou 39/51

ltimo de velocidad, se calcularn promedios de valores cercanos y se asignarn directamente. primer dato... promedio *) Calc_Vel[0, 0] := (Calc_Vel[0, 1] + Calc_Vel[0, pointnum[pozo_proc]-1]) / 2.0; (* ltimo dato... *) Calc_Vel[0, pointnum[pozo_proc]] := ( Calc_Pos[0, pointnum[pozo_proc]] - Calc_Pos[0, pointnum[pozo_proc] - 2] ) / ( 2.0 * Pozo_var[pozo_proc].delta_t ); ELSE run:= FALSE; (* se detiene ejecucin del programa *) div_por_cero:= FALSE; (* sealizando divisin por cero *) END_IF; (* fin Preliminary_Calcs *) (* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *) (* BHD_Calculation *) (* calcular "DELTA_X", es decir: longitud de intervalo de propagacin *) (* calcular nmero de intervalos en los que se debe propagar solucin en la seccin actual: Existen 2 casos: DELTA_X <= long seccin -> propagar sol. en intervalo DELTA_X > long. seccin -> interpolar *) FOR IJK := 1 To Num_Sect[pozo_proc] BY 1 DO (* 1140: *) (* Se calcula intervalo de propagacin Delta_X para seccin *) Delta_x := Pozo_var[pozo_proc].delta_t * Rod[pozo_proc,IJK].Speed / 2.0; PRG_SECS := TRUNC ( Rod[pozo_proc,IJK].Length / Delta_x ); (* Con esta operacin se evala el caso a manejar, es decir, se compara longitud de la seccin con respecto a longitud de intervalo de propagacin *) ILL := 1; (* Se establece longitud de intervalo de interpolacin *) Rod[pozo_proc,IJK].Int_Len := Rod[pozo_proc,IJK].Length - PRG_SECS * Delta_x; (* Clculo de longitud de intervalo de interpolacin *) (* Variables de programa *) AA := ( 4.0 + damp * Pozo_var[pozo_proc].delta_t ) / ( 4.0 * Rod[pozo_proc,IJK].Speed ); (* positive slope *) BB := ( 4.0 - damp * Pozo_var[pozo_proc].delta_t ) / ( 4.0 * Rod[pozo_proc,IJK].Speed ); (* negative slope *) LLL := 0; (* contador para convergencia *) (* Preparar data para nuevo ciclo: *) IF PRG_SECS > 0.0 THEN (* 1330: *) WHILE ILL <= ANY_TO_DINT (PRG_SECS) DO FOR j := 1 To pointnum[pozo_proc] BY 1 DO IF j = pointnum[pozo_proc] THEN (* 20040512 para ltimo ciclo *) (* igualando el ltimo al primero...*) Calc_Pos[IJK - 1, pointnum[pozo_proc] + 1] := Calc_Pos[IJK 1, 1]; Calc_strain[IJK - 1, pointnum[pozo_proc] + 1] := Calc_strain[IJK - 1, 1]; Calc_Vel[IJK - 1, pointnum[pozo_proc] + 1] := Calc_Vel[IJK 1, 1]; END_IF; CC := -BB * Calc_Vel[IJK - 1, j] + Calc_strain[IJK - 1, j]; DD := AA * Calc_Vel[IJK - 1, j + 1] + Calc_strain[IJK - 1, j + 1];

Virgo Workbench /01/20 P_PILOTO_OROCU onfiguration, 1 resou 40/51

"caractersticas" *)

Calc_Vel[IJK, j] := ( DD - CC ) / ( BB + AA ); Calc_strain[IJK, j] := ( AA * DD + BB * CC ) / ( BB + AA ); (* Clculo de las posiciones en prximo punto sobre las dos LLL := 0; (* Se inicializa variable de control de lazo *) WHILE LLL < it_max DO U := ( Delta_x / 2.0 ) * ( Calc_strain[IJK, j] + Calc_strain[IJK U := U - ( Pozo_var[pozo_proc].delta_t / 4.0 ) * ( Calc_Vel[IJK, UU := ( Delta_x / 2.0) * ( Calc_strain[IJK, j] + Calc_strain[IJK UU := UU + ( Pozo_var[pozo_proc].delta_t / 4.0 ) * ( DIFF := U - UU; DIFF := ABS ( DIFF ); IF any_to_sint (DIFF) <= res THEN

1, j + 1] ) + Calc_Pos[IJK - 1, j + 1]; j] + Calc_Vel[IJK - 1, j + 1] ); 1, j] ) + Calc_Pos[IJK - 1, j]; Calc_Vel[IJK, j] + Calc_Vel[IJK - 1, j] );

Convergieron valores de posicin !!! *)

(*

LLL := LLL + 1; F := damp * Pozo_var[pozo_proc].delta_t / ( 4.0 * Rod[pozo_proc,IJK].Speed ) * ( Calc_Vel[IJK, j] + Calc_Vel[IJK - 1, j] ); F := F - Calc_Vel[IJK - 1, j] / Rod[pozo_proc,IJK].Speed + Calc_strain[IJK - 1, j]; G := damp * Pozo_var[pozo_proc].delta_t / ( 4.0 * Rod[pozo_proc,IJK].Speed ) * ( Calc_Vel[IJK, j] + Calc_Vel[IJK - 1, j + 1] ); G := G + Calc_Vel[IJK - 1, j + 1] / Rod[pozo_proc,IJK].Speed + Calc_strain[IJK - 1, j + 1]; Calc_strain[IJK, j] := ( F + G ) / 2.0; Calc_Vel[IJK, j] := Rod[pozo_proc,IJK].Speed * ( G - F ) / 2.0; (* Se verifica si se sobrepasa cantidad definida para nmero de iteraciones. En caso de ser positivo se forza la convergencia al promedio de los dos valores existentes. *) IF LLL = it_max THEN Calc_Pos[IJK, j] := ( U + UU ) / 2.0; (* no convergi... pero se asigna valor anyway *) LLL := it_max * 10; (* dummy para salir de lazo *) END_IF; END_IF; END_WHILE; (* LLL *) END_FOR; (* j *) IF ILL < ANY_TO_DINT (PRG_SECS) THEN (* Propagar todava solucin en seccin actual a filas anteriores *) ILL := ILL + 1; (* se incrementa contador y se pasan valores calculados *) FOR i := 1 To pointnum[pozo_proc] BY 1 DO (* de los arreglos correspondientes. Luego comienzar ciclo nuevamente. *) Calc_Pos [IJK - 1, i] := Calc_Pos[IJK, i]; Calc_strain[IJK - 1, i] := Calc_strain[IJK, i]; Calc_Vel[IJK - 1, i] := Calc_Vel[IJK, i];

ELSE

Calc_Pos[IJK, j] := ( U + UU ) / 2.0; LLL := it_max * 10; (* dummy para salir de lazo *)

Virgo Workbench /01/20 P_PILOTO_OROCU onfiguration, 1 resou 41/51

END_WHILE; (* ILL *) (* PRG_SECS *) FOR i := 1 To pointnum[pozo_proc] BY 1 DO Calc_Pos[IJK, i] := Calc_Pos[IJK - 1, i]; Calc_strain[IJK, i] := Calc_strain[IJK - 1, i]; Calc_Vel[IJK, i] := Calc_Vel[IJK - 1, i]; END_FOR; (* Call Interpolation *) interpolation_dummy := Interpolation(interpolation_dummy, pozo_proc); END_IF; (* PRG_SECS *) IF IJK < Num_Sect[pozo_proc] THEN (* Estableciendo condiciones de continuidad y preparando data para anlisis de los esfuerzos en las cabillas de tope de prxima seccin*) (* Razonamiento: Debe calcularse el peso sumergido de las secciones restantes de cabilla para establecer la carga en este punto *) Temp_Weight := 0.0; (* inicializando condiciones... *) Temp_Vol := 0.0; For i:= IJK to Num_Sect[pozo_proc] by 1 DO Temp_Weight:=Temp_Weight + Rod[pozo_proc,i].Weight; Temp_Vol:= Temp_Vol + Rod[pozo_proc,i].Length * pi * pow(Rod[pozo_proc,i].Diameter,2.0)/4.0; end_for; (* Entonces, el peso de las secciones restantes de cabilla es: *) Temp_Buoy := Temp_Vol * fluid_dens[pozo_proc]; (* fotabilidad de secciones remanentes de cabilla *) Temp_Ef_Weight := Temp_Weight - Temp_Buoy; (* Peso efectivo de secciones remanentes *) Temp:= calc_strain[IJK,1] * (pi * pow(Rod[pozo_proc,IJK+1].Diameter,2.0)/4.0) * Rod[pozo_proc,IJK+1].Mod_Young + Temp_Ef_Weight; (* se empieza por el 1ero.. *) Esfuerzos[pozo_proc,IJK].minimo := Temp; (* inicializacin para buscar mximo y mnimo *) Esfuerzos[pozo_proc,IJK].maximo := Temp; FOR i := 1 To pointnum[pozo_proc] BY 1 DO (* ahora si... estableciendo condiciones de continuidad *) Calc_strain[IJK, i] :=Calc_strain[IJK, i]*Rod[pozo_proc,IJK].Mod_Young*pow(Rod[pozo_proc,IJK].Diameter,2.0) /(Rod[pozo_proc,IJK+1].Mod_Young * pow (Rod[pozo_proc,IJK+1].Diameter,2.0)); (*Temp:= calc_strain[IJK,1] *(pi * pow(Rod[pozo_proc,IJK+1].Diameter,2.0)/4.0) * Rod[pozo_proc,IJK+1].Mod_Young + Temp_Ef_Weight; *) Temp:= calc_strain[IJK,i] * Rod[pozo_proc,IJK+1].Mod_Young + Temp_Ef_Weight; (* Se buscan esfuerzos mximos y mnimos, para despus llamar a rutina de anlisis de Goodman *) (* mnimo *) IF Temp < Esfuerzos[pozo_proc,IJK].minimo THEN Esfuerzos[pozo_proc,IJK].minimo := Temp; END_IF; (* mximo*) IF Temp > Esfuerzos[pozo_proc,IJK].maximo THEN Esfuerzos[pozo_proc,IJK].maximo := Temp; END_IF; END_FOR; (*Se llama funcin que hace anlisis de Goddman sobre datos de seccin *) Goodman_dummy := Analisis_Goodman(IJK,pozo_proc); (* hacer ELSE

Virgo Workbench /01/20 P_PILOTO_OROCU onfiguration, 1 resou 42/51

END_FOR; (* IJK *) (*fin BHD_Calculation *) (* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *) (* Write_BHD *) (* Se determina peso del fluido (Wf), para lo cual se inicializa este valor en cero y se procede a hallarlo en loop de escritura de BHD en memoria Net-DAS *) Wf:= 0.0; FOR i := 1 To pointnum[pozo_proc] BY 1 DO (* ' Posicin: *) DownDyn[pozo_proc,0,i] := -Calc_Pos[IJK - 1, i] + Rod_Stretch[pozo_proc]; (* ' Carga: *) DownDyn[pozo_proc,1,i] := Calc_strain[IJK - 1, i] * Rod[pozo_proc,IJK - 1].Mod_Young * pi * Rod[pozo_proc,IJK - 1].Diameter * Rod[pozo_proc,IJK - 1].Diameter / 4.0; IF DownDyn[pozo_proc,1,i] > Wf THEN Wf := DownDyn[pozo_proc,1,i]; END_IF; END_FOR; (* Se busca el valor mnimo de posicin, para luego restarlo a la totalidad de los valores de posicin

*)

min_pos := DownDyn[pozo_proc,0,1]; (* se inicia mnimo con primer elemento *) FOR i := 1 To pointnum[pozo_proc] BY 1 DO IF DownDyn[pozo_proc,0,i] < min_pos THEN min_pos := DownDyn[pozo_proc,0,i]; END_IF; END_FOR; (* se resta mnimo a valores arreglo posicin esto lo hace Dynasim, pero no J. Chacn *) FOR i := 1 To pointnum[pozo_proc] BY 1 DO DownDyn[pozo_proc,0,i] := DownDyn[pozo_proc,0,i] - min_pos; END_FOR; (*=============Aadido para indicar al recurso DYNSUB que existe una CDF=================*) Existe_CDF:=True; (* end_if; BHD_Calc 20031130 *) (* end_if pointnum[pozo_proc] *)

BHD_Calculation:=not(flag_entrada);

1.14.3. Local Variables + Parameters

Virgo Workbench /01/20 P_PILOTO_OROCU onfiguration, 1 resou 43/51

flag_entrada (* variable que recibe valor de parmetro de entrada *) Type: BOOL Direction: pozo_proc (* ndice de pozo a ser procesado *) Type: DINT Direction: BHD_Calculation Type: BOOL Direction:

1.15. Calculos_Sarta (* Clculo de valores asociados a sarta de cabillas *) 1.15.2. Source


(* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *) (* Get_Rod_Data *) (* - Descripcin del arreglo Rod (estructuras tipo "ROD_SECTION"): Rod.Material = Material de la seccion [0-> acero, 1-> Fibra de vidrio] Rod.Mod_Young = Mdulo de Young del material de la seccin Rod.Length_feet = Longitud de la seccin [feet] Rod.Length = Longitud de la seccin [inch] Rod.Diameter = Dimetro de la seccin [inch] Rod.Int_Len = Long. a interpolar...se calcula durante ejec. MCH Rod.Speed = Velocidad de propagacin en material [inch/sec] Rod.Weight = Peso total de la seccin [Lb] Modif. 20040527: Rod.T_index = ndice para asignar valor apropiado de "Resistencia ala tensin mnima" Rod.T_min = resistencia a la Tensin Mnima *) if (refresc_conf = TRUE) and (run = TRUE) then suiche condiciona ejecucin de toda la rutina; 20051007 se agrega "RUN" (* este

condicin de *) for j:= 1 to numero_pozos by 1 do if existe_pozo[j] = TRUE then (* Se calcula el resto de los valores de la seccin que dependen de la data leda *) FOR i := 1 TO Num_Sect[j] BY 1 DO Rod[j,i].Length := Rod[j,i].Length_feet * 12.0; (* conversin a pulgadas de longitud de seccin *) IF Rod[j,i].Material = 0 THEN (* "0" significa acero *) Rod[j,i].Weight := pi * Rod[j,i].Length * Dens_steel * Rod[j,i].Diameter * Rod[j,i].Diameter / (4.0 * 1728.0); Rod[j,i].Speed := a_steel; Rod[j,i].Mod_Young := EY_steel; ELSE (* "1" significa fiberglass *) Rod[j,i].Weight := pi * Rod[j,i].Length * Dens_fg * Rod[j,i].Diameter *

Virgo Workbench /01/20 P_PILOTO_OROCU onfiguration, 1 resou 44/51

C por defecto

end_case; END_FOR; (* i *) end_if; (* existe_pozo[j] *) end_for; (* j .... numero_pozos *) for j:= 1 to numero_pozos by 1 do if existe_pozo[j] = TRUE then (* fin Get_Rod_Data *) (* Fluid_Density_Calc *) (* Se calcula de densidad del fluido, la cual se va a utilizar para calcular la flotabilidad de la cabilla *) (* calcular BWPD y BOPD *) (* Calcular densidad especfica del agua *) water_dens[j] := C1 * EXPT ( Pozo_var[j].temp_fondo, 2 ) + C2 * Pozo_var[j].temp_fondo + C3; (* water_dens := 1 ' DEBUG *) (* calcular densidad especfica del crudo *) crude_dens[j] := C4 * ( Pozo_var[j].temp_fondo - 60.0 ) + ( C5 / ( C6 + Pozo_var[j].grav_tub ) ) * water_dens[j]; (* Calcular fracciones de agua y crudo *) (* Fraccin de agua *) Xa := (pozo_var[j].prod_fluido*pozo_var[j].c/100.0) / pozo_var[j].prod_fluido; (* Fraccin de crudo *) Xc := 1.0 - Xa; (* Calcular densidad de la mezcla *) fluid_dens[j] := Xa * water_dens[j] + Xc * crude_dens[j]; (* [grs/cc] *) fluid_dens[j] := fluid_dens[j] * gr_cc_a_Lb_cuin; (* [Lb/cu in] *) (* fin Fluid_Density_Calc *) end_if; (* if existe_pozo[j] *) end_for; (* j ... numero_pozos *) (* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *) (* Rod_Calcs *) (* Se deben calcular los siguientes datos de la sarta: volumen total peso total longitud total flotabilidad peso efectivo

*)

Rod[j,i].Speed := a_fg; Rod[j,i].Mod_Young := EY_fg; END_IF; case Rod[j,i].T_index of 1: (* C *) Rod[j,i].T_max := tipo_C; 2: (* D *) Rod[j,i].T_max := tipo_D; 3: (* K *) Rod[j,i].T_max := tipo_K; else Rod[j,i].T_max := tipo_C;

(*

se configura como tipo

Virgo Workbench /01/20 P_PILOTO_OROCU onfiguration, 1 resou 45/51

*)

estiramiento for j:=1 to numero_pozos by 1 do if existe_pozo[j]=TRUE then (* inicializando variables de cabilla*) RodVol[j] := 0.0; RodLen[j] := 0.0; RodWeight[j] := 0.0; FOR i:=1 TO Num_Sect[j] BY 1 DO RodVol[j] := RodVol[j] + pi * POW(Rod[j,i].Diameter, 2.0) * (* Clculo de peso total *) RodWeight[j] := RodWeight[j] + Rod[j,i].Weight; (* Clculo de la longitud total de la sarta *) RodLen[j] := RodLen[j] + Rod[j,i].Length; END_FOR; (* i *) (*Buoyancy := RodVol * fluid_dens; fotabilidad de la cabilla *) Buoyancy[j] := RodVol[j] * (141.5/(131.5+Pozo_var[j].grav_cas))*62.4 /1728.0; (* Ef_Weight := RodWeight - Buoyancy; Peso efectivo *) Ef_Weight[j] := RodWeight[j] +500.0 - Buoyancy[j]; (* Peso Rod_Stretch[j] := 0.0; (* Inicializando antes de entrar a loop de

Rod[j,i].Length/4.0;

(* fotabilidad de la cabilla *) efectivo *) clculo *)

FOR i := 1 TO Num_Sect[j] BY 1 DO Rod_Stretch[j] := Rod_Stretch[j]+32.2*(POW (Rod[j,i].Length/(Rod[j,i].Speed),2.0)*12.0); Rod_Stretch[j] := Rod_Stretch[j]+(4.0*Rod[j,i].Length/(pi*POW(Rod[j,i].Diameter,2.0)*Rod[j,i].Mod_Young)*(Rod[j,i].Weight Buoyancy[j])); END_FOR; (* i *) end_if; (* existe_pozo[..] *) end_for; (* j *) refresc_conf := FALSE; (* se desactiva bit... para rehacer clculos hay activar bit desde pgina de configuracin *) end_if; (* refresc_conf *) (* fin Rod_Calcs *) (* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *)

1.16. PublicaResult (* Escribir archivo de texto con cartas dinagrficas *) 1.16.2. Source
(*========================================Inicio Comentario============================================ Escribe los puntos de la Carta Dinagrfica de Superficie en el archivo ubicado en la ruta '/home/webadmin/htdocs/CD/CDS_nmero de pozo.txt' =========================================Fin Comentario=============================================*)

Virgo Workbench /01/20 P_PILOTO_OROCU onfiguration, 1 resou 46/51

case apuntador_pozo of 1:VarString1 := '/home/webadmin/htdocs/CD/CDS_pozo_1.txt'; 2:VarString1 := '/home/webadmin/htdocs/CD/CDS_pozo_2.txt'; 3:VarString1 := '/home/webadmin/htdocs/CD/CDS_pozo_3.txt'; 4:VarString1 := '/home/webadmin/htdocs/CD/CDS_pozo_4.txt'; end_case; VarString2 := ANY_TO_STRING(cds_cad_dia) + '/' + ANY_TO_STRING(cds_cad_mes) +'/'+ ANY_TO_STRING(cds_cad_ano)+ tab; VarString2 :=VarString2 + ANY_TO_STRING(cds_cad_hora)+':'+ANY_TO_STRING(cds_cad_min)+':'+ANY_TO_STRING(cds_cad_seg)+linefit; VarBool1 := NetDAS_Puts(VarString1, VarString2); VarString2:= 'Campo:' + tab + Pozo_var[apuntador_pozo].Campo + linefit; VarBool1 := NetDAS_LOG(VarString1, VarString2); VarString2:='Pozo:' + tab + Pozo_var[apuntador_pozo].Nombre + linefit; VarBool1 := NetDAS_LOG(VarString1, VarString2); VarString2:= ANY_TO_STRING (Pointnum[apuntador_pozo]) + linefit; VarBool1 := NetDAS_LOG(VarString1, VarString2); FOR Counter_1 := 1 TO Pointnum[apuntador_pozo] BY 1 DO VarString2:= Real2String (SurfaceDyn[apuntador_pozo,0,Counter_1], 2) + ';' + Real2String(SurfaceDyn[apuntador_pozo,1 ,Counter_1], 2) + linefit; VarBool1 := NetDAS_LOG(VarString1, VarString2); END_FOR; (*========================================Inicio Comentario============================================ Escribe los puntos de la Carta Dinagrfica de Fondo en el archivo ubicado en la ruta '/home/webadmin/htdocs/CD/CDF.txt' =========================================Fin Comentario=============================================*) case apuntador_pozo of 1:VarString1 := '/home/webadmin/htdocs/CD/CDF_pozo_1.txt'; 2:VarString1 := '/home/webadmin/htdocs/CD/CDF_pozo_2.txt'; 3:VarString1 := '/home/webadmin/htdocs/CD/CDF_pozo_3.txt'; 4:VarString1 := '/home/webadmin/htdocs/CD/CDF_pozo_4.txt'; end_case; (* ELIMINAR VarString2 := ANY_TO_STRING(Public_dia) + '/' + ANY_TO_STRING(Public_mes) +'/'+ ANY_TO_STRING(Public_ano)+ tab; VarString2 :=VarString2 + ANY_TO_STRING(Public_hora)+':'+ANY_TO_STRING(Public_min)+':'+ANY_TO_STRING(Public_seg)+linefit; VarBool1 := NetDAS_Puts(VarString1, VarString2); *** *) VarString2 := ANY_TO_STRING(cds_cad_dia) + '/' + ANY_TO_STRING(cds_cad_mes) +'/'+

Virgo Workbench /01/20 P_PILOTO_OROCU onfiguration, 1 resou 47/51

ANY_TO_STRING(cds_cad_ano)+ tab; VarString2 :=VarString2 + ANY_TO_STRING(cds_cad_hora)+':'+ANY_TO_STRING(cds_cad_min)+':'+ANY_TO_STRING(cds_cad_seg)+linefit; VarBool1 := NetDAS_Puts(VarString1, VarString2); VarString2:= 'Campo:' + tab + Pozo_var[apuntador_pozo].Campo + linefit; VarBool1 := NetDAS_LOG(VarString1, VarString2); VarString2:='Pozo:' + tab + Pozo_var[apuntador_pozo].Nombre + linefit; VarBool1 := NetDAS_LOG(VarString1, VarString2); VarString2:= ANY_TO_STRING (Pointnum[apuntador_pozo]) + linefit; VarBool1 := NetDAS_LOG(VarString1, VarString2); FOR Counter_1 :=1 TO Pointnum[apuntador_pozo] BY 1 DO VarString2:= Real2String (DownDyn[apuntador_pozo,0,Counter_1], 2) +';'+ Real2String(DownDyn[apuntador_pozo,1 ,Counter_1], 2) + linefit; VarBool1 := NetDAS_LOG(VarString1, VarString2); END_FOR; PublicaResult := VarBool1;

1.16.3. Local Variables + Parameters

Virgo Workbench /01/20 P_PILOTO_OROCU onfiguration, 1 resou 48/51

apuntador_pozo Type: DINT Direction: PublicaResult Type: BOOL Direction:

(* recibe nmero de pozo a publicar resultado *)

1.17. Real2String 1.17.2. Source


(*Pasa una variable tipo real a una tripo string (se toma en cuenta el numero de decimales que indica el usuario)*) (* Version modificada para aceptar valores mayores que 1.0e6 *) if number <>0.0 then (* Primero se detecta el tamao del nmero *) Punto_Decimal :=log(abs(number)); (* Si es un nmero pequeo se procede como la funcion original *) IF Punto_Decimal< -5.0 THEN (* Si el nmero es muy pequeo se forma el string como punto flotante *) Number_String :=any_to_string((abs(number)*expt(10.0,any_to_dint(-Punto_Decimal+5.0)))); real_string :=insert(Number_String,'.',2)+'e'+any_to_string(Punto_Decimal-1.0); if number<0.0 then real2string :='-'+real_string; else real2string:=real_string; end_if; ELSIF (Punto_Decimal< 5.0 AND Punto_decimal>=-5.0) THEN Number_String :=any_to_string(any_to_dint(abs(number)*expt(10.0,n_decimal ))); if Punto_Decimal>=0.0 then real_string :=insert(Number_String,'.',any_to_dint(Punto_Decimal)+2); else for i :=0 to any_to_dint(abs(Punto_Decimal)) do if i=0 then add_string :='0.'; else add_string:=add_string+'0'; end_if; end_for; real_string:=add_string+Number_String; end_if; if number<0.0 then real2string :='-'+real_string; else

Virgo Workbench /01/20 P_PILOTO_OROCU onfiguration, 1 resou 49/51

ELSE

end_if;

real2string:=real_string;

(* Si el nmero es grande se forma el string como punto flotante *)

Number_String :=any_to_string((abs(number)/expt(10.0,any_to_dint(Punto_Decimal-5.0)))); real_string :=insert(Number_String,'.',2)+'e'+any_to_string(Punto_Decimal); if number<0.0 then real2string :='-'+real_string; else real2string:=real_string; end_if; END_IF; else real2string:='0.00'; end_if;

(*

VIEJA...

if number<>0.0 then Number_String :=any_to_string(any_to_dint(abs(number)*expt(10.0,n_decimal))); Punto_Decimal:=log(abs(number)); if Punto_Decimal>=0.0 then real_string:=insert(Number_String,'.',any_to_dint(Punto_Decimal)+2); else for i:=0 to any_to_dint(abs(Punto_Decimal)) do if i=0 then add_string:='0.'; else add_string:=add_string+'0'; end_if; end_for; real_string:=add_string+Number_String; end_if; if number<0.0 then real2string:='-'+real_string; else real2string:=real_string; end_if; else

Virgo Workbench /01/20 P_PILOTO_OROCU onfiguration, 1 resou 50/51

real2string:='0.00'; end_if; (* if number<>0.0 then real2string:=any_to_string(any_to_dint(number*100000.0)/100000) +'.'+ any_to_string(mod(any_to_dint(abs(number*100000.0)),100000)); else real2string:='0.00000'; end_if; * ) *)

1.17.3. Local Variables + Parameters


add_string Type: STRING(20) Attribute: Free Direction: Memory Number_String Type: STRING(50) Attribute: Free Direction: Memory Punto_Decimal Type: REAL Attribute: Free Direction: Memory real_string Type: STRING(50) Attribute: Free Direction: Memory number Type: REAL Direction: n_decimal Type: DINT Direction: Real2String Type: STRING(10) Direction:

Virgo Workbench /01/20 P_PILOTO_OROCU onfiguration, 1 resou 51/51

Das könnte Ihnen auch gefallen