Beruflich Dokumente
Kultur Dokumente
1.4. Variables
THT (* Temperatura en Cabezal de pozo *) Type: REAL
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
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
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
(* 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
(* 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 *)
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
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'
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
(* 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
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
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
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 *)
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
(* 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
(* 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
(* 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
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.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 ;
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 ;
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 *)
Kp_max (* max value for Kp *) Type: REAL Alias: Kpmx Direction: Kp_min (* min value for KP *) Type: REAL Alias: Kpmn
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 *)
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
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
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 ;
(* number of scans *)
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 *)
(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 *)
Direction: num_pozo (* Pozo siendo procesado *) Type: DINT Direction: Interpolation Type: BOOL Direction:
- - - - - - - - *)
(* 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 *)
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] <=
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;
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 *)
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 *)
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" *)
*) (* lectura de header de CDS. Generado por recurso de captura CDS *) netdas_in('plc_mem','HREG', dir_adq,12, 'DINT');
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');
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;
end_if;
(*
*)
(*===========================================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
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);
*)
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:
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:
(*====================================================*) 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
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];
"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
(*
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
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
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);
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:
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 *
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;
(*
*)
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;
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=============================================*)
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) +'/'+
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;
ELSE
end_if;
real2string:=real_string;
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
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; * ) *)