Вы находитесь на странице: 1из 40

Aplicación a la Simulación Numérica de

Yacimientos Petroleros
Antonio Carrillo Ledesma

1 Planteamiento del Problema


Consideremos la siguiente ecuación diferencial de flujo compresible bidimnsional
(r, z) hacia un pozo:
µ ¶ ∙ µ ¶¸ µ ¶
1 ∂ ∂p ∂ ∂p ∂p ∂ φ
rλ + λ −γ = (1)
r ∂r ∂r ∂z ∂z ∂z ∂t B

para rw < r < re ; 0 < D < H; t > 0, con condiciones


³ iniciales
´ p(r, z, 0) = p0 en
∂p qw ¯
¯
rw < r < re ; 0 < D < H y condiciones de frontera r ∂r = − 2πhλ rw y j=9,10,11
,
rw
si pwf > pwf,min
³ en ´t > 0 entonces
³ p(r´w , z, t) = pwf,min a partir de que
∂p ∂p ∂p
pwf = pwf,min y r ∂r = 0 y ∂z − γ ∂z = 0 para r = rw , r = re y D = 0 y
re
k
D = H, t > 0 y donde λ = μB .

2 Ecuaciones que Sirven de Base al Simulador


Expresando (1) en diferencias finitas centrales en espacio y regresivas en tiempo
tenemos
½ µ ¶ ∙ µ ¶¸ µ ¶¾n+1
∂ ∂p ∂ ∂p ∂D ∂ φ
2 2 rλ + λ −γ = (2)
∂r ∂r ∂z ∂z ∂z ∂t B i,j
³ ´
∂p
si hacemos u = rλ ∂r , entonces podemos expresar

½ ¾n+1
∂u un+1 n+1
i+1/2,j − ui−1/2,j
≈ 2 2
∂r2 i,j ri+1/2,j − ri−1/2,j
(µ µ ¶¶ µ µ ¶¶ )n+1
1 ∂p ∂p
= rλ − rλ
∆ri2 ∂r i+1/2,j ∂r i−1/2,j
½ ¾n+1
1 (pi+1,j − pi,j ) (pi,j − pi−1,j )
= (rλ)i+1/2,j − (rλ)i−1/2,j
∆ri2 ri+1/2,j ri−1/2,j
factorizando
(µ ¶ µ ¶ )n+1
1 rλ rλ
(pi+1,j − pi,j ) − (pi,j − pi−1,j ) (3)
∆ri2 r i+1/2,j r i−1/2,j

1
de forma similar
∙ µ ¶¸n+1 (µ ¶
∂ ∂p ∂D 1 λ ³ ´
λ −γ ' pi,j+1 − pi,j − (γ∆D)i,j+1/2 −
∂z ∂z ∂z i,j ∆zj ∆z i,j+1/2

µ ¶ )
rλ ³ ´ n+1
pi,j − pi,j−1 − (γ∆D)i,j−1/2 (4)
r i,j−1/2

y la aproximación del término de acumulación es


½ µ ¶¾n+1 "µ ¶ µ ¶n #
n+1
∂ φ 1 φ φ
= − (5)
∂t B i,j ∆t B i,j B i,j

ahora sustituyendo (3), (4) y (5) en (2), donde además A ³ = 2πr∆zj y multipli- ´
2 2
cando por el volumen de roca de la celda i, j, Vri,j = π∆zj ri+1/2,j − ri−1/2,j ,
entonces podemos reescribir la expresión (2) como
"µ ¶ µ ¶ #n+1
Aλ Aλ
(pi+1,j − pi,j ) − (pi,j − pi−1,j ) +
∆r i+1/2,j ∆r i−1/2,j
"µ ¶
Aλ ³ ´
pi,j+1 − pi,j − (γ∆D)i,j+1/2 − (6)
∆z i,j+1/2

µ ¶ # "µ ¶ µ ¶n #
Aλ ³ ´ n+1 V φ
n+1
φ
ri,j
pi,j − pi,j−1 − (γ∆D)i,j−1/2 = − .
r i,j−1/2 ∆t B i,j B i,j

Usando el concepto de transmisibilidad, definida como


µ ¶ µ ¶
Aλ Aλ
T ri±1/2,j = y T zi,j±1/2 =
∆r i±1/2,j ∆z i,j±1/2

entonces tenemos que (6) se escribe como


n+1
T ri+1/2,j [pi+1,j − pi,j ]n+1 − T ri−1/2,j
n+1
[pi,j − pi−1,j ]n+1 +
h in+1
n+1
T zi,j+1/2 pi,j+1 − pi,j − (γ∆D)i,j+1/2 − (7)
"µ ¶ µ ¶n #
h in+1 V φ
n+1
φ
n+1 ri,j
T zi,j−1/2 pi,j − pi,j−1 − (γ∆D)i,j−1/2 = −
∆t B i,j B i,j
donde ³ ´
2 2
Vri,j = π ri+1/2 − ri−1/2 ∆zj
£ ¡ ¢¤
φn+1 = φn 1 + Cr pn+1 − pn i,j

2
µ ¶ µ ¶
n+1 Aλ n+1 Aλ
T ri+1/2,j = y T ri−1/2,j = (8)
∆r i+1/2,j ∆r i−1/2,j
µ ¶ µ ¶
n+1 Aλ n+1 Aλ
T zi,j+1/2 = y T zi,j−1/2 =
∆z i,j+1/2 ∆z i,j−1/2

considerando
⎡ ⎤ ⎡ ⎤
r2 + ri2 r2 + r2
ri+1/2 = ³ r2 ´ ⎦ , ri−1/2
⎣ i+1 = ⎣ i ³ 2i−1´⎦
r
ln i+1
ri2
ln r2i
i−1

y ∆zj = 12 (zj + zj+1 ), podemos desarrollar la expresión (8) y obtenemos que la


transmisibilidad queda definida como
à 2 !µ ¶
n+1
r i+1/2 ∆z j k
T ri+1/2,j = 4π 2 (9)
ri+1 − ri2 μB i+1/2,j
à 2 !µ ¶
n+1
ri−1/2 ∆zj k
T ri−1/2,j = 4π
ri2 − ri−1
2 μB i−1/2,j
à 2 2
!µ ¶
n+1
ri+1/2 − ri−1/2 k
T zi,j+1/2 = π
∆zj+1/2 μB i,j+1/2
à 2 2
! µ ¶
n+1
ri+1/2 − ri−1/2 k
T zi,j−1/2 = π .
∆zj−1/2 μB i,j−1/2

Tomando en cuenta el sentido del flujo en i + 1/2, j se tiene que

∆Φ = pi+1,j − pi,j si ≥ 0 el flujo es de i −→ i + 1


∆Φ = pi+1,j − pi,j si < 0 el flujo es de i + 1 −→ i

entonces µ ¶ ½
1 (1/μB)i+1,j si ∆Φi+1/2,j ≥ 0
=
μB i+1/2,j (1/μB)i,j si ∆Φi+1/2,j < 0
en i − 1/2, j, se tiene que

∆Φ = pi,j − pi−1,j si ≥ 0 el flujo es de i −→ i − 1


∆Φ = pi,j − pi−1,j si < 0 el flujo es de i − 1 −→ i

entonces µ ¶ ½
1 (1/μB)i−1,j si ∆Φi−1/2,j ≥ 0
=
μB i−1/2,j (1/μB)i,j si ∆Φi−1/2,j < 0.

Desarrollando la porosidad tenemos


£ ¡ ¢¤
φn+1 = φn 1 + Cr pn+1 − pn

3
1 dφ
donde Cr = φ dp , entonces integrando
Z p Z φ µ ¶
φ
Crdp = d ln φ =⇒ Cr (p − pref ) = ln
pref φref φref

de donde se tiene que φ = φref eCr(p−pref ) , así tenemos que


n+1
−pn )
φn+1 = φn eCr(p

con esta expresión desarrollamos


"µ ¶ µ ¶n # " ¡ ¢ #
Vri,j φ
n+1
φ Vri,j φni,j 1 + Cr pn+1 − pn 1
− = − n
∆t B i,j B i,j ∆t B n+1 B
i,j

derivandola con respecto a pi,j tenemos


∙ ¸ " ¡ ¡ ¢¢ #
d 1 + Cr (p − pn ) BCr 1 + Cr pn+1 − pn dB
= − . (10)
dpi,j B i,j B2 B2 dp
i,j

Ahora, partiendo de (7) acoplaremos las condiciones de frontera que son im-
permeables, para i = 1, j = 1, 2, 3, ..., J; i = I, J = 1, 2, 3, ..., J, i = 1, 2, 3..., I, j =
1 y i = 1, 2, 3, ..., I, j = J excepto para i = 1, j = 9, 10, 11 que son celdas abiertas
al flujo.
Si
j = 1 → α1 = 0
i = 1 → α2 = 0
i = I → α3 = 0
j = J → α4 = 0
en caso contrario α1 = α2 = α3 = α4 = 1 en
n+1 n+1 n+1 n+1
α3 T ri+1/2,j [pi+1,j − pi,j ] − α2 T ri−1/2,j [pi,j − pi−1,j ] +
h in+1
n+1
α4 T zi,j+1/2 pi,j+1 − pi,j − (γ∆D)i,j+1/2 − (11)
"µ ¶ µ ¶n #
h in+1 V φ
n+1
φ
n+1 r
α1 T zi,j−1/2 pi,j − pi,j−1 − (γ∆D)i,j−1/2 = i,j −
∆t B i,j B i,j
Para las celdas abiertas al flujo i = 1, j = 9, 10, 11, tenemos
n+1
T ri+1/2,j [pi+1,j − pi,j ]n+1 − qi,j
n+1
+
h in+1
n+1
T zi,j+1/2 pi,j+1 − pi,j − (γ∆D)i,j+1/2 − (12)
"µ ¶ µ ¶n #
h in+1 V φ
n+1
φ
n+1 ri,j
T zi,j−1/2 pi,j − pi,j−1 − (γ∆D)i,j−1/2 = −
∆t B i,j B i,j

4
donde " #
n+1
n+1
T r1,j
qi,j = P11 qon+1 i = 1, j = 9, 10, 11
j=9 T 1,j

Ahora debemos de expresar la función de residuos, la cual queda definida


como

Fi (pi,j−1 , pi−1,j , pi,j , pi+1,j , pi,j+1 )n+1 = T ri+1/2,j


n+1
[pi+1,j − pi,j ]n+1 −

n+1 n+1
T ri−1/2,j [pi,j − pi−1,j ] +
h in+1
n+1
T zi,j+1/2 pi,j+1 − pi,j − (γ∆D)i,j+1/2 − (13)
h in+1
n+1
T zi,j−1/2 pi,j − pi,j−1 − (γ∆D)i,j−1/2 −
"µ ¶ µ ¶n #
n+1
Vri,j φ φ
− =0
∆t B i,j B i,j
para i = 1, 2, 3, ..., I, j = 1, 2, 3, ..., J y n = 0, 1, 2, ... Expandiendo (13) mediante
una serie de Taylor truncada alrededor del nivel de iteración (ν), de la que sólo
se conservan los terminos de menor orden tenemos
µ ¶(ν)
n+1 (ν) ∂Fi,j (ν+1)
Fi,j (pi,j−1 , pi−1,j , pi,j , pi+1,j , pi,j+1 ) ≈ Fi,j + δpi,j−1 +
∂pi,j−1
µ ¶(ν) µ ¶(ν)
∂Fi,j (ν+1) ∂Fi,j (ν+1)
δpi−1,j + δpi,j +
∂pi−1,j ∂pi,j
µ ¶(ν) µ ¶(ν)
∂Fi,j (ν+1) ∂Fi,j (ν+1)
δpi+1,j + δpi,j+1 = 0
∂pi+1,j ∂pi,j+1
por lo tanto
µ ¶(ν) µ ¶(ν) µ ¶(ν)
∂Fi,j (ν+1) ∂Fi,j (ν+1) ∂Fi,j (ν+1)
δpi,j−1 + δpi−1,j + δpi,j +
∂pi,j−1 ∂pi−1,j ∂pi,j
µ ¶(ν) µ ¶(ν)
∂Fi,j (ν+1) ∂Fi,j (ν+1) (ν)
δpi+1,j + δpi,j+1 = −Fi,j (14)
∂pi+1,j ∂pi,j+1
donde
(ν+1) (ν+1) (ν)
δpi,j = pi,j − pi,j .

5
Realizando las derivadas parciales de (14) obtenemos

µ ¶
∂Fi ∂T ri+1/2,j
= ai,j = −T ri+1/2,j + [pi+1,j − pi,j ] −
∂pi,j ∂pi,j
∂T ri−1/2,j
T ri−1/2,j − [pi,j − pi−1,j ] −
∂pi,j
∙ ¸
∂γ i,j+1/2
T zi,j+1/2 1 + ∆Di,j+1/2 +
∂pi,j
h i ∂T z
i,j+1/2
pi,j+1 − pi,j − (γ∆D)i,j+1/2 −
∂pi,j
∙ ¸
∂γ i,j−1/2
T zi,j−1/2 1 − ∆Di,j−1/2 −
∂pi,j
h i ∂T z
i,j−1/2
pi,j − pi,j−1 − (γ∆D)i,j−1/2 −
∂pi,j
µ ¶
V ri,j ∂ φ
∆t ∂pi,j B
µ ¶
∂Fi ∂T ri+1/2,j
= bi,j = T ri+1/2,j + [pi+1,j − pi,j ]
∂pi+1,j ∂pi+1,j
µ ¶
∂Fi ∂T ri−1/2,j
= ci,j = T ri−1/2,j − [pi,j − pi−1,j ] (15)
∂pi−1,j ∂pi−1,j

µ ¶ ∙ ¸
∂Fi ∂γ i,j+1/2
= ei,j = T zi,j+1/2 1 − ∆Di,j+1/2 +
∂pi,j+1 ∂pi,j+1
h i ∂T z
i+1/2,j
pi,j+1 − pi,j − (γ∆D)i,j+1/2
∂pi,j+1

µ ¶ ∙ ¸
∂Fi ∂γ i,j−1/2
= fi,j = T zi,j−1/2 1 + ∆Di,j−1/2 −
∂pi,j−1 ∂pi,j−1
h i ∂T z
i−1/2,j
pi,j − pi,j−1 − (γ∆D)i,j−1/2
∂pi,j−1

6
¡ A ¢³ k ´
Para calcular ∂T
∂p en forma generica a partir de T = ∆r μB obtenemos
∂T
¡A¢ ∂ ³ 1 ´ ∂
³ ´
1
∂p = ∆r k ∂p μB , primeramente calculamos ∂p μB de donde se obtiene
³ ´
µ ¶ d μB dμ
∂ 1 dp P μ dB
dp + B dp
= 2 = 2
∂p μB (μB) (μB)
µ ¶
1 1 dB 1 dμ
= − +
μB B dp μ dp
∂T ri+1/2,j ∂T ri−1/2,j ∂T zi,j+1/2 ∂T zi,j−1/2 ∂T ri+1/2,j
pero como se debe de calcular ∂pi,j , ∂pi,j , ∂pi,j , ∂pi,j , ∂pi+1,j ,
∂T ri−1/2,j ∂T zi,j+1/2 ∂T zi,j−1/2
∂pi−1,j , ∂pi,j+1 y ∂pi,j−1 entonces tenemos
µ ¶
∂T ri+1/2,j 1 dB 1 dμ
= −T ri+1/2,j +
∂pi,j B dpi,j μ dpi,j i+1/2,j
µ ¶
∂T ri−1/2,j 1 dB 1 dμ
= −T ri−1/2,j +
∂pi,j B dpi,j μ dpi,j i−1/2,j
µ ¶
∂T zi,j+1/2 1 dB 1 dμ
= −T zi,j+1/2 +
∂pi,j B dpi,j μ dpi,j i,j+1/2
µ ¶
∂T zi,j−1/2 1 dB 1 dμ
= −T zi,j−1/2 + (16)
∂pi,j B dpi,j μ dpi,j i,j−1/2
µ ¶
∂T ri+1/2,j 1 dB 1 dμ
= −T ri+1/2,j +
∂pi+1,j B dpi+1,j μ dpi+1,j i+1/2,j
µ ¶
∂T ri−1/2,j 1 dB 1 dμ
= −T ri−1/2,j +
∂pi−1,j B dpi−1,j μ dpi−1,j i−1/2,j
µ ¶
∂T zi,j+1/2 1 dB 1 dμ
= −T zi,j+1/2 +
∂pi,j+1 B dpi,j+1 μ dpi,j+1 i,j+1/2
µ ¶
∂T zi,j−1/2 1 dB 1 dμ
= −T zi,j−1/2 + .
∂pi,j−1 B dpi,j−1 μ dpi,j−1 i,j−1/2

7
Sustituyendo (10) y (16) en (15), tenemos para cada i, j

µ ¶
∂Fi
= ai,j = −T ri+1/2,j − T ri−1/2,j − (17)
∂pi,j
µ ¶
1 dB 1 dμ
T ri+1/2,j [pi+1,j − pi,j ] + +
B dpi,j μ dpi,j i+1/2,j
µ ¶
1 dB 1 dμ
T ri−1/2,j [pi,j − pi−1,j ] + −
B dpi,j μ dpi,j i−1/2,j
∙ ¸
∂γ i,j+1/2
T zi,j+1/2 1 + ∆Di,j+1/2 −
∂pi,j
h i µ 1 dB 1 dμ

T zi,j+1/2 pi,j+1 − pi,j − (γ∆D)i,j+1/2 + −
B dpi,j μ dpi,j i,j+1/2
∙ ¸
∂γ i,j−1/2
T zi,j−1/2 1 − ∆Di,j−1/2 +
∂pi,j
h i µ 1 dB 1 dμ

T zi,j−1/2 pi,j − pi,j−1 − (γ∆D)i,j−1/2 + −
B dpi,j μ dpi,j i,j−1/2
" ¡ ¡ ¢¢ #
V ri,j BCr 1 + Cr pn+1 − pn dB

∆t B2 B2 dp
i,j
µ ¶ µ ¶
∂Fi 1 dB 1 dμ
= bi,j = T ri+1/2,j −T ri+1/2,j [pi+1,j − pi,j ] +
∂pi+1,j B dpi+1,j μ dpi+1,j i+1/2,j
µ ¶ µ ¶
∂Fi 1 dB 1 dμ
= ci,j = T ri−1/2,j +T ri−1/2,j [pi,j − pi−1,j ] +
∂pi−1,j B dpi−1,j μ dpi−1,j i−1/2,j

µ ¶ ∙ ¸
∂Fi ∂γ i,j+1/2
= ei,j = T zi,j+1/2 1 − ∆Di,j+1/2 −
∂pi,j+1 ∂pi,j+1
h i µ 1 dB 1 dμ

T zi,j+1/2 pi,j+1 − pi,j − (γ∆D)i,j+1/2 +
B dpi,j+1 μ dpi,j+1 i,j+1/2

µ ¶ ∙ ¸
∂Fi ∂γ i,j−1/2
= fi,j = T zi,j−1/2 1 + ∆Di,j−1/2 +
∂pi,j−1 ∂pi,j−1
h i µ 1 dB 1 dμ

T zi,j−1/2 pi,j − pi,j−1 − (γ∆D)i,j−1/2 +
B dpi,j−1 μ dpi,j−1 i,j−1/2

ρg ∂γ i,j+1/2 ∂γ i,j−1/2
Definimos a γ como γ = gc entonces se tiene que ∂pi,j = ∂pi,j =
∂γ i,j+1/2 ∂γ i,j−1/2
∂pi,j+1 = ∂pi,j−1 = 0, por ser ρ constante.

8
3 Estructura del Programa de Cómputo
A partir de las ecuaciones (17) se construyen los algoritmos para controlar los
dos problemas de condiciones iniciales dados, en cada una de las formulaciones
de los métodos generales de linealización Totalmente Implícita, Simi-Implícita
Linelizada y Linealización Directa, primeramente se trabaja con la formulación
general Totalmente Implícita.

El primer problema (gasto constante y presión variable) se resuelve generando


la matriz jacobiana donde se considera frontera impermeable para i = 1 y
j = 1, 2, ..., 8, 12, 13, ..., J, i = I y j = 1, 2, 3, ..., J, j = 1 y i = 1, 2, 3, ..., I y
j = J y i = 1, 2, 3, ..., I. Las celdas i = 1 y j = 9, 10, 11 se consideran celdas
productoras.
Acoplando las condiciones iniciales (dependiente del ∆D) y de frontera a
(17) se genera la matriz [J]ν y tomando (13) se genera el vector F (ν) , para
generar el sistema [J]ν δp(ν+1) = −F (ν) . Usando el algoritmo para matrices
dispersas NSPIV se calculan las presiones en la iteración ν¯ + 1 por ¯ medio de
(ν+1) (ν) (ν+1) ¯ (ν+1) ¯
pi,j = pi,j + δpi,j y se verifica la convergencia usando ¯δpi,j ¯ < εp . Si es
menor que la tolerancia dada se actualiza la presión y se incrementa el tiempo,
para nuevamente llenar las matrices [J]ν y F (ν) y continuar con el ciclo hasta
alcanzar la presión de fondo igual a pwf,min .

El segundo problema (presión constante y gasto variable) se resuelve generando


la matriz jacobiana donde se considera frontera impermeable para i = 0 y
j = 1, 2, ..., 8, 12, 13, ..., J, i = I y j = 1, 2, 3, ..., J, j = 1 y i = 1, 2, 3, ..., I y
j = J y i = 1, 2, 3, ..., I. Las celdas i = 1 y j = 9, 10, 11 se consideran celdas
productoras.
Acoplando las condiciones iniciales y de frontera a (17) se genera la ma-
triz [J]ν y tomando (13) se genera el vector F (ν) , para generar el sistema
[J]ν δp(ν+1) = −F (ν) . Usando el algoritmo para matrices dispersas NSPIV se
(ν+1) (ν) (ν+1)
calcula el gasto en la iteración ν + 1 por medio de qwi,i = qwi,i + δqi,i y
¯ ¯
¯ (ν+1) ¯
se verifica la convergencia usando ¯δqi,j ¯ < εp . Si es menor que la tolerancia
dada se actualiza el gasto y se incrementa el tiempo, para nuevamente llenar las
matrices [J]ν y F (ν) y continuar con el ciclo hasta alcanzar gasto igual a qw,min .

Partiendo de la formulación Totalmente Implícita, se resuelve la formulación


de Simi-implícita Linelizada, en donde se toma la salida de la primera iteración
del método NR de la formulación Totalmente Implícita.

Del mismo modo, partiendo de la formulación Totalmente Implícita, se re-


suelve la formulación de Linealización Directa, usando la aproximación T n+1 ≈
T n en la cual la derivada de la transmisibilidad es cero, simplificando no-
tablemete las ecuaciones.

9
4 Resultados Obtenidos
Los resultados que se generan para una malla de 20 x 19, una tolerancia de
1e-1 (para el algoritmo de N-R), con una distribucón de presion inicial (sólo
se muestran los primeros 8 valores para que puedan ser visualizados en una
página):

+ 1 9 8 .2 3 6 0 0 0 + 1 9 8 .2 3 6 0 0 0 + 1 9 8 .2 3 6 0 0 0 + 1 9 8 .2 3 6 0 0 0 + 1 9 8 .2 3 6 0 0 0 + 1 9 8 .2 3 6 0 0 0 + 1 9 8 .2 3 6 0 0 0 + 1 9 8 .2 3 6 0 0 0

+ 1 9 8 .4 3 2 0 0 0 + 1 9 8 .4 3 2 0 0 0 + 1 9 8 .4 3 2 0 0 0 + 1 9 8 .4 3 2 0 0 0 + 1 9 8 .4 3 2 0 0 0 + 1 9 8 .4 3 2 0 0 0 + 1 9 8 .4 3 2 0 0 0 + 1 9 8 .4 3 2 0 0 0

+ 1 9 8 .6 2 8 0 0 0 + 1 9 8 .6 2 8 0 0 0 + 1 9 8 .6 2 8 0 0 0 + 1 9 8 .6 2 8 0 0 0 + 1 9 8 .6 2 8 0 0 0 + 1 9 8 .6 2 8 0 0 0 + 1 9 8 .6 2 8 0 0 0 + 1 9 8 .6 2 8 0 0 0

+ 1 9 8 .8 2 4 0 0 0 + 1 9 8 .8 2 4 0 0 0 + 1 9 8 .8 2 4 0 0 0 + 1 9 8 .8 2 4 0 0 0 + 1 9 8 .8 2 4 0 0 0 + 1 9 8 .8 2 4 0 0 0 + 1 9 8 .8 2 4 0 0 0 + 1 9 8 .8 2 4 0 0 0

+ 1 9 9 .0 2 0 0 0 0 + 1 9 9 .0 2 0 0 0 0 + 1 9 9 .0 2 0 0 0 0 + 1 9 9 .0 2 0 0 0 0 + 1 9 9 .0 2 0 0 0 0 + 1 9 9 .0 2 0 0 0 0 + 1 9 9 .0 2 0 0 0 0 + 1 9 9 .0 2 0 0 0 0

+ 1 9 9 .2 1 6 0 0 0 + 1 9 9 .2 1 6 0 0 0 + 1 9 9 .2 1 6 0 0 0 + 1 9 9 .2 1 6 0 0 0 + 1 9 9 .2 1 6 0 0 0 + 1 9 9 .2 1 6 0 0 0 + 1 9 9 .2 1 6 0 0 0 + 1 9 9 .2 1 6 0 0 0

+ 1 9 9 .4 1 2 0 0 0 + 1 9 9 .4 1 2 0 0 0 + 1 9 9 .4 1 2 0 0 0 + 1 9 9 .4 1 2 0 0 0 + 1 9 9 .4 1 2 0 0 0 + 1 9 9 .4 1 2 0 0 0 + 1 9 9 .4 1 2 0 0 0 + 1 9 9 .4 1 2 0 0 0

+ 1 9 9 .6 0 8 0 0 0 + 1 9 9 .6 0 8 0 0 0 + 1 9 9 .6 0 8 0 0 0 + 1 9 9 .6 0 8 0 0 0 + 1 9 9 .6 0 8 0 0 0 + 1 9 9 .6 0 8 0 0 0 + 1 9 9 .6 0 8 0 0 0 + 1 9 9 .6 0 8 0 0 0

+ 1 9 9 .8 0 4 0 0 0 + 1 9 9 .8 0 4 0 0 0 + 1 9 9 .8 0 4 0 0 0 + 1 9 9 .8 0 4 0 0 0 + 1 9 9 .8 0 4 0 0 0 + 1 9 9 .8 0 4 0 0 0 + 1 9 9 .8 0 4 0 0 0 + 1 9 9 .8 0 4 0 0 0

+ 2 0 0 .0 0 0 0 0 0 + 2 0 0 .0 0 0 0 0 0 + 2 0 0 .0 0 0 0 0 0 + 2 0 0 .0 0 0 0 0 0 + 2 0 0 .0 0 0 0 0 0 + 2 0 0 .0 0 0 0 0 0 + 2 0 0 .0 0 0 0 0 0 + 2 0 0 .0 0 0 0 0 0

+ 2 0 0 .1 9 6 0 0 0 + 2 0 0 .1 9 6 0 0 0 + 2 0 0 .1 9 6 0 0 0 + 2 0 0 .1 9 6 0 0 0 + 2 0 0 .1 9 6 0 0 0 + 2 0 0 .1 9 6 0 0 0 + 2 0 0 .1 9 6 0 0 0 + 2 0 0 .1 9 6 0 0 0

+ 2 0 0 .3 9 2 0 0 0 + 2 0 0 .3 9 2 0 0 0 + 2 0 0 .3 9 2 0 0 0 + 2 0 0 .3 9 2 0 0 0 + 2 0 0 .3 9 2 0 0 0 + 2 0 0 .3 9 2 0 0 0 + 2 0 0 .3 9 2 0 0 0 + 2 0 0 .3 9 2 0 0 0

+ 2 0 0 .5 8 8 0 0 0 + 2 0 0 .5 8 8 0 0 0 + 2 0 0 .5 8 8 0 0 0 + 2 0 0 .5 8 8 0 0 0 + 2 0 0 .5 8 8 0 0 0 + 2 0 0 .5 8 8 0 0 0 + 2 0 0 .5 8 8 0 0 0 + 2 0 0 .5 8 8 0 0 0

+ 2 0 0 .7 8 4 0 0 0 + 2 0 0 .7 8 4 0 0 0 + 2 0 0 .7 8 4 0 0 0 + 2 0 0 .7 8 4 0 0 0 + 2 0 0 .7 8 4 0 0 0 + 2 0 0 .7 8 4 0 0 0 + 2 0 0 .7 8 4 0 0 0 + 2 0 0 .7 8 4 0 0 0

+ 2 0 0 .9 8 0 0 0 0 + 2 0 0 .9 8 0 0 0 0 + 2 0 0 .9 8 0 0 0 0 + 2 0 0 .9 8 0 0 0 0 + 2 0 0 .9 8 0 0 0 0 + 2 0 0 .9 8 0 0 0 0 + 2 0 0 .9 8 0 0 0 0 + 2 0 0 .9 8 0 0 0 0

+ 2 0 1 .1 7 6 0 0 0 + 2 0 1 .1 7 6 0 0 0 + 2 0 1 .1 7 6 0 0 0 + 2 0 1 .1 7 6 0 0 0 + 2 0 1 .1 7 6 0 0 0 + 2 0 1 .1 7 6 0 0 0 + 2 0 1 .1 7 6 0 0 0 + 2 0 1 .1 7 6 0 0 0

+ 2 0 1 .3 7 2 0 0 0 + 2 0 1 .3 7 2 0 0 0 + 2 0 1 .3 7 2 0 0 0 + 2 0 1 .3 7 2 0 0 0 + 2 0 1 .3 7 2 0 0 0 + 2 0 1 .3 7 2 0 0 0 + 2 0 1 .3 7 2 0 0 0 + 2 0 1 .3 7 2 0 0 0

+ 2 0 1 .5 6 8 0 0 0 + 2 0 1 .5 6 8 0 0 0 + 2 0 1 .5 6 8 0 0 0 + 2 0 1 .5 6 8 0 0 0 + 2 0 1 .5 6 8 0 0 0 + 2 0 1 .5 6 8 0 0 0 + 2 0 1 .5 6 8 0 0 0 + 2 0 1 .5 6 8 0 0 0

+ 2 0 1 .7 6 4 0 0 0 + 2 0 1 .7 6 4 0 0 0 + 2 0 1 .7 6 4 0 0 0 + 2 0 1 .7 6 4 0 0 0 + 2 0 1 .7 6 4 0 0 0 + 2 0 1 .7 6 4 0 0 0 + 2 0 1 .7 6 4 0 0 0 + 2 0 1 .7 6 4 0 0 0

Para los esquemas de los métodos generales de linealización Totalmente Im-


plícita, Simi-Implícita Linelizada y Linealización Directa se muestran a contin-
uación las matrices de presiones y el tiempo para alcanzar la presión pwf,min ,
así como el tiempo en que el gasto es igal a qw,min .

10
Para el esquema Totalmente Implícito se muestran a continuación la distribu-
ción de presiones al tiempo 29.5334 días cuando se alcanza la presión pwf,min
(el efecto del pozo sobre la frontera exterior del yacimiento no se aprecia):

+ 1 9 8 .2 3 6 0 0 0 + 1 9 8 .2 3 6 0 0 0 + 1 9 8 .2 3 6 0 0 0 + 1 9 8 .2 3 6 0 0 0 + 1 9 8 .2 3 6 0 0 0 + 1 9 8 .2 3 6 0 0 0 + 1 9 8 .2 3 6 0 0 0 + 1 9 8 .2 3 6 0 0 0

+ 1 9 8 .4 3 2 0 0 0 + 1 9 8 .4 3 2 0 0 0 + 1 9 8 .4 3 2 0 0 0 + 1 9 8 .4 3 2 0 0 0 + 1 9 8 .4 3 2 0 0 0 + 1 9 8 .4 3 2 0 0 0 + 1 9 8 .4 3 2 0 0 0 + 1 9 8 .4 3 2 0 0 0

+ 1 9 8 .6 2 8 0 0 0 + 1 9 8 .6 2 8 0 0 0 + 1 9 8 .6 2 8 0 0 0 + 1 9 8 .6 2 8 0 0 0 + 1 9 8 .6 2 8 0 0 0 + 1 9 8 .6 2 8 0 0 0 + 1 9 8 .6 2 8 0 0 0 + 1 9 8 .6 2 8 0 0 0

+ 1 9 8 .8 2 4 0 0 0 + 1 9 8 .8 2 4 0 0 0 + 1 9 8 .8 2 4 0 0 0 + 1 9 8 .8 2 4 0 0 0 + 1 9 8 .8 2 4 0 0 0 + 1 9 8 .8 2 4 0 0 0 + 1 9 8 .8 2 4 0 0 0 + 1 9 8 .8 2 4 0 0 0

+ 1 9 9 .0 2 0 0 0 0 + 1 9 9 .0 2 0 0 0 0 + 1 9 9 .0 2 0 0 0 0 + 1 9 9 .0 2 0 0 0 0 + 1 9 9 .0 2 0 0 0 0 + 1 9 9 .0 2 0 0 0 0 + 1 9 9 .0 2 0 0 0 0 + 1 9 9 .0 2 0 0 0 0

+ 1 9 9 .2 1 6 0 0 0 + 1 9 9 .2 1 6 0 0 0 + 1 9 9 .2 1 6 0 0 0 + 1 9 9 .2 1 6 0 0 0 + 1 9 9 .2 1 6 0 0 0 + 1 9 9 .2 1 6 0 0 0 + 1 9 9 .2 1 6 0 0 0 + 1 9 9 .2 1 6 0 0 0

+ 1 9 9 .4 1 1 9 7 5 + 1 9 9 .4 1 1 9 9 6 + 1 9 9 .4 1 2 0 0 0 + 1 9 9 .4 1 2 0 0 0 + 1 9 9 .4 1 2 0 0 0 + 1 9 9 .4 1 2 0 0 0 + 1 9 9 .4 1 2 0 0 0 + 1 9 9 .4 1 2 0 0 0

+ 1 9 9 .5 4 9 7 8 4 + 1 9 9 .5 9 8 6 5 3 + 1 9 9 .6 0 7 5 9 6 + 1 9 9 .6 0 7 9 9 5 + 1 9 9 .6 0 8 0 0 0 + 1 9 9 .6 0 8 0 0 0 + 1 9 9 .6 0 8 0 0 0 + 1 9 9 .6 0 8 0 0 0

+ 9 9 .8 1 8 1 2 7 + 1 8 6 .1 9 2 0 6 9 + 1 9 9 .2 0 9 3 4 1 + 1 9 9 .7 9 5 4 7 4 + 1 9 9 .8 0 3 9 5 8 + 1 9 9 .8 0 4 0 0 0 + 1 9 9 .8 0 4 0 0 0 + 1 9 9 .8 0 4 0 0 0

+ 9 9 .9 8 5 9 2 0 + 1 8 6 .3 8 7 1 8 0 + 1 9 9 .4 0 6 8 9 5 + 1 9 9 .9 9 1 8 8 3 + 1 9 9 .9 9 9 9 6 2 + 2 0 0 .0 0 0 0 0 0 + 2 0 0 .0 0 0 0 0 0 + 2 0 0 .0 0 0 0 0 0

+ 1 0 0 .3 1 4 9 4 9 + 1 8 6 .6 1 2 4 2 3 + 1 9 9 .6 1 2 1 3 8 + 2 0 0 .1 8 8 0 8 6 + 2 0 0 .1 9 5 9 6 3 + 2 0 0 .1 9 6 0 0 0 + 2 0 0 .1 9 6 0 0 0 + 2 0 0 .1 9 6 0 0 0

+ 2 0 0 .3 3 2 7 4 7 + 2 0 0 .3 8 2 9 5 7 + 2 0 0 .3 9 1 6 2 7 + 2 0 0 .3 9 1 9 9 5 + 2 0 0 .3 9 2 0 0 0 + 2 0 0 .3 9 2 0 0 0 + 2 0 0 .3 9 2 0 0 0 + 2 0 0 .3 9 2 0 0 0

+ 2 0 0 .5 8 7 9 7 6 + 2 0 0 .5 8 7 9 9 6 + 2 0 0 .5 8 8 0 0 0 + 2 0 0 .5 8 8 0 0 0 + 2 0 0 .5 8 8 0 0 0 + 2 0 0 .5 8 8 0 0 0 + 2 0 0 .5 8 8 0 0 0 + 2 0 0 .5 8 8 0 0 0

+ 2 0 0 .7 8 4 0 0 0 + 2 0 0 .7 8 4 0 0 0 + 2 0 0 .7 8 4 0 0 0 + 2 0 0 .7 8 4 0 0 0 + 2 0 0 .7 8 4 0 0 0 + 2 0 0 .7 8 4 0 0 0 + 2 0 0 .7 8 4 0 0 0 + 2 0 0 .7 8 4 0 0 0

+ 2 0 0 .9 8 0 0 0 0 + 2 0 0 .9 8 0 0 0 0 + 2 0 0 .9 8 0 0 0 0 + 2 0 0 .9 8 0 0 0 0 + 2 0 0 .9 8 0 0 0 0 + 2 0 0 .9 8 0 0 0 0 + 2 0 0 .9 8 0 0 0 0 + 2 0 0 .9 8 0 0 0 0

+ 2 0 1 .1 7 6 0 0 0 + 2 0 1 .1 7 6 0 0 0 + 2 0 1 .1 7 6 0 0 0 + 2 0 1 .1 7 6 0 0 0 + 2 0 1 .1 7 6 0 0 0 + 2 0 1 .1 7 6 0 0 0 + 2 0 1 .1 7 6 0 0 0 + 2 0 1 .1 7 6 0 0 0

+ 2 0 1 .3 7 2 0 0 0 + 2 0 1 .3 7 2 0 0 0 + 2 0 1 .3 7 2 0 0 0 + 2 0 1 .3 7 2 0 0 0 + 2 0 1 .3 7 2 0 0 0 + 2 0 1 .3 7 2 0 0 0 + 2 0 1 .3 7 2 0 0 0 + 2 0 1 .3 7 2 0 0 0

+ 2 0 1 .5 6 8 0 0 0 + 2 0 1 .5 6 8 0 0 0 + 2 0 1 .5 6 8 0 0 0 + 2 0 1 .5 6 8 0 0 0 + 2 0 1 .5 6 8 0 0 0 + 2 0 1 .5 6 8 0 0 0 + 2 0 1 .5 6 8 0 0 0 + 2 0 1 .5 6 8 0 0 0

+ 2 0 1 .7 6 4 0 0 0 + 2 0 1 .7 6 4 0 0 0 + 2 0 1 .7 6 4 0 0 0 + 2 0 1 .7 6 4 0 0 0 + 2 0 1 .7 6 4 0 0 0 + 2 0 1 .7 6 4 0 0 0 + 2 0 1 .7 6 4 0 0 0 + 2 0 1 .7 6 4 0 0 0

Cuyo tiempo para alcanzar qw,min es de 45.3444 días.

11
Para el esquema Semi-Implícito Linealizado se muestran a continuación la
distribución de presiones al tiempo 31.0323 días cuando se alcanza la presión
pwf,min (el efecto del pozo sobre la frontera exterior del yacimiento no se aprecia):

+ 1 9 8 .2 3 6 0 0 0 + 1 9 8 .2 3 6 0 0 0 + 1 9 8 .2 3 6 0 0 0 + 1 9 8 .2 3 6 0 0 0 + 1 9 8 .2 3 6 0 0 0 + 1 9 8 .2 3 6 0 0 0 + 1 9 8 .2 3 6 0 0 0 + 1 9 8 .2 3 6 0 0 0

+ 1 9 8 .4 3 2 0 0 0 + 1 9 8 .4 3 2 0 0 0 + 1 9 8 .4 3 2 0 0 0 + 1 9 8 .4 3 2 0 0 0 + 1 9 8 .4 3 2 0 0 0 + 1 9 8 .4 3 2 0 0 0 + 1 9 8 .4 3 2 0 0 0 + 1 9 8 .4 3 2 0 0 0

+ 1 9 8 .6 2 8 0 0 0 + 1 9 8 .6 2 8 0 0 0 + 1 9 8 .6 2 8 0 0 0 + 1 9 8 .6 2 8 0 0 0 + 1 9 8 .6 2 8 0 0 0 + 1 9 8 .6 2 8 0 0 0 + 1 9 8 .6 2 8 0 0 0 + 1 9 8 .6 2 8 0 0 0

+ 1 9 8 .8 2 4 0 0 0 + 1 9 8 .8 2 4 0 0 0 + 1 9 8 .8 2 4 0 0 0 + 1 9 8 .8 2 4 0 0 0 + 1 9 8 .8 2 4 0 0 0 + 1 9 8 .8 2 4 0 0 0 + 1 9 8 .8 2 4 0 0 0 + 1 9 8 .8 2 4 0 0 0

+ 1 9 9 .0 2 0 0 0 0 + 1 9 9 .0 2 0 0 0 0 + 1 9 9 .0 2 0 0 0 0 + 1 9 9 .0 2 0 0 0 0 + 1 9 9 .0 2 0 0 0 0 + 1 9 9 .0 2 0 0 0 0 + 1 9 9 .0 2 0 0 0 0 + 1 9 9 .0 2 0 0 0 0

+ 1 9 9 .2 1 6 0 0 0 + 1 9 9 .2 1 6 0 0 0 + 1 9 9 .2 1 6 0 0 0 + 1 9 9 .2 1 6 0 0 0 + 1 9 9 .2 1 6 0 0 0 + 1 9 9 .2 1 6 0 0 0 + 1 9 9 .2 1 6 0 0 0 + 1 9 9 .2 1 6 0 0 0

+ 1 9 9 .4 1 1 9 0 3 + 1 9 9 .4 1 1 9 6 6 + 1 9 9 .4 1 1 9 9 5 + 1 9 9 .4 1 2 0 0 0 + 1 9 9 .4 1 2 0 0 0 + 1 9 9 .4 1 2 0 0 0 + 1 9 9 .4 1 2 0 0 0 + 1 9 9 .4 1 2 0 0 0

+ 1 9 9 .4 9 5 5 3 2 + 1 9 9 .5 7 3 5 6 8 + 1 9 9 .6 0 3 7 9 8 + 1 9 9 .6 0 7 7 9 2 + 1 9 9 .6 0 7 9 9 6 + 1 9 9 .6 0 8 0 0 0 + 1 9 9 .6 0 8 0 0 0 + 1 9 9 .6 0 8 0 0 0

+ 8 3 .2 9 1 2 6 3 + 1 7 4 .6 8 0 6 1 4 + 1 9 7 .3 1 2 6 2 0 + 1 9 9 .6 9 5 2 1 8 + 1 9 9 .8 0 1 9 5 7 + 1 9 9 .8 0 3 9 8 4 + 1 9 9 .8 0 4 0 0 0 + 1 9 9 .8 0 4 0 0 0

+ 8 7 .6 2 9 1 5 5 + 1 7 5 .6 6 2 6 4 5 + 1 9 7 .5 8 2 8 6 5 + 1 9 9 .8 9 8 3 9 1 + 1 9 9 .9 9 8 1 6 8 + 1 9 9 .9 9 9 9 8 6 + 2 0 0 .0 0 0 0 0 0 + 2 0 0 .0 0 0 0 0 0

+ 8 7 .9 5 8 0 1 2 + 1 7 5 .9 1 1 5 2 8 + 1 9 7 .7 9 8 5 5 8 + 2 0 0 .0 9 5 5 0 6 + 2 0 0 .1 9 4 1 9 1 + 2 0 0 .1 9 5 9 8 6 + 2 0 0 .1 9 6 0 0 0 + 2 0 0 .1 9 6 0 0 0

+ 2 0 0 .2 8 2 5 0 6 + 2 0 0 .3 5 9 4 0 0 + 2 0 0 .3 8 8 1 4 4 + 2 0 0 .3 9 1 8 1 6 + 2 0 0 .3 9 1 9 9 6 + 2 0 0 .3 9 2 0 0 0 + 2 0 0 .3 9 2 0 0 0 + 2 0 0 .3 9 2 0 0 0

+ 2 0 0 .5 8 7 9 0 9 + 2 0 0 .5 8 7 9 6 8 + 2 0 0 .5 8 7 9 9 6 + 2 0 0 .5 8 8 0 0 0 + 2 0 0 .5 8 8 0 0 0 + 2 0 0 .5 8 8 0 0 0 + 2 0 0 .5 8 8 0 0 0 + 2 0 0 .5 8 8 0 0 0

+ 2 0 0 .7 8 4 0 0 0 + 2 0 0 .7 8 4 0 0 0 + 2 0 0 .7 8 4 0 0 0 + 2 0 0 .7 8 4 0 0 0 + 2 0 0 .7 8 4 0 0 0 + 2 0 0 .7 8 4 0 0 0 + 2 0 0 .7 8 4 0 0 0 + 2 0 0 .7 8 4 0 0 0

+ 2 0 0 .9 8 0 0 0 0 + 2 0 0 .9 8 0 0 0 0 + 2 0 0 .9 8 0 0 0 0 + 2 0 0 .9 8 0 0 0 0 + 2 0 0 .9 8 0 0 0 0 + 2 0 0 .9 8 0 0 0 0 + 2 0 0 .9 8 0 0 0 0 + 2 0 0 .9 8 0 0 0 0

+ 2 0 1 .1 7 6 0 0 0 + 2 0 1 .1 7 6 0 0 0 + 2 0 1 .1 7 6 0 0 0 + 2 0 1 .1 7 6 0 0 0 + 2 0 1 .1 7 6 0 0 0 + 2 0 1 .1 7 6 0 0 0 + 2 0 1 .1 7 6 0 0 0 + 2 0 1 .1 7 6 0 0 0

+ 2 0 1 .3 7 2 0 0 0 + 2 0 1 .3 7 2 0 0 0 + 2 0 1 .3 7 2 0 0 0 + 2 0 1 .3 7 2 0 0 0 + 2 0 1 .3 7 2 0 0 0 + 2 0 1 .3 7 2 0 0 0 + 2 0 1 .3 7 2 0 0 0 + 2 0 1 .3 7 2 0 0 0

+ 2 0 1 .5 6 8 0 0 0 + 2 0 1 .5 6 8 0 0 0 + 2 0 1 .5 6 8 0 0 0 + 2 0 1 .5 6 8 0 0 0 + 2 0 1 .5 6 8 0 0 0 + 2 0 1 .5 6 8 0 0 0 + 2 0 1 .5 6 8 0 0 0 + 2 0 1 .5 6 8 0 0 0

+ 2 0 1 .7 6 4 0 0 0 + 2 0 1 .7 6 4 0 0 0 + 2 0 1 .7 6 4 0 0 0 + 2 0 1 .7 6 4 0 0 0 + 2 0 1 .7 6 4 0 0 0 + 2 0 1 .7 6 4 0 0 0 + 2 0 1 .7 6 4 0 0 0 + 2 0 1 .7 6 4 0 0 0

Cuyo tiempo para alcanzar qw,min es de 45.8989 días.

12
Para el esquema Linealización Directa se muestran a continuación la distribu-
ción de presiones al tiempo 31.4563 días cuando se alcanza la presión pwf,min (el
efecto del pozo sobre la frontera exterior del yacimiento no se aprecia):
+ 1 9 8 .2 3 6 0 0 0 + 1 9 8 .2 3 6 0 0 0 + 1 9 8 .2 3 6 0 0 0 + 1 9 8 .2 3 6 0 0 0 + 1 9 8 .2 3 6 0 0 0 + 1 9 8 .2 3 6 0 0 0 + 1 9 8 .2 3 6 0 0 0 + 1 9 8 .2 3 6 0 0 0

+ 1 9 8 .4 3 2 0 0 0 + 1 9 8 .4 3 2 0 0 0 + 1 9 8 .4 3 2 0 0 0 + 1 9 8 .4 3 2 0 0 0 + 1 9 8 .4 3 2 0 0 0 + 1 9 8 .4 3 2 0 0 0 + 1 9 8 .4 3 2 0 0 0 + 1 9 8 .4 3 2 0 0 0

+ 1 9 8 .6 2 8 0 0 0 + 1 9 8 .6 2 8 0 0 0 + 1 9 8 .6 2 8 0 0 0 + 1 9 8 .6 2 8 0 0 0 + 1 9 8 .6 2 8 0 0 0 + 1 9 8 .6 2 8 0 0 0 + 1 9 8 .6 2 8 0 0 0 + 1 9 8 .6 2 8 0 0 0

+ 1 9 8 .8 2 4 0 0 0 + 1 9 8 .8 2 4 0 0 0 + 1 9 8 .8 2 4 0 0 0 + 1 9 8 .8 2 4 0 0 0 + 1 9 8 .8 2 4 0 0 0 + 1 9 8 .8 2 4 0 0 0 + 1 9 8 .8 2 4 0 0 0 + 1 9 8 .8 2 4 0 0 0

+ 1 9 9 .0 2 0 0 0 0 + 1 9 9 .0 2 0 0 0 0 + 1 9 9 .0 2 0 0 0 0 + 1 9 9 .0 2 0 0 0 0 + 1 9 9 .0 2 0 0 0 0 + 1 9 9 .0 2 0 0 0 0 + 1 9 9 .0 2 0 0 0 0 + 1 9 9 .0 2 0 0 0 0

+ 1 9 9 .2 1 6 0 0 0 + 1 9 9 .2 1 6 0 0 0 + 1 9 9 .2 1 6 0 0 0 + 1 9 9 .2 1 6 0 0 0 + 1 9 9 .2 1 6 0 0 0 + 1 9 9 .2 1 6 0 0 0 + 1 9 9 .2 1 6 0 0 0 + 1 9 9 .2 1 6 0 0 0

+ 1 9 9 .4 1 1 9 7 5 + 1 9 9 .4 1 1 9 9 6 + 1 9 9 .4 1 2 0 0 0 + 1 9 9 .4 1 2 0 0 0 + 1 9 9 .4 1 2 0 0 0 + 1 9 9 .4 1 2 0 0 0 + 1 9 9 .4 1 2 0 0 0 + 1 9 9 .4 1 2 0 0 0

+ 1 9 9 .5 4 9 7 8 3 + 1 9 9 .5 9 8 6 5 3 + 1 9 9 .6 0 7 5 9 6 + 1 9 9 .6 0 7 9 9 5 + 1 9 9 .6 0 8 0 0 0 + 1 9 9 .6 0 8 0 0 0 + 1 9 9 .6 0 8 0 0 0 + 1 9 9 .6 0 8 0 0 0

+ 9 9 .8 0 9 7 7 9 + 1 8 6 .1 9 1 7 9 7 + 1 9 9 .2 0 9 3 3 4 + 1 9 9 .7 9 5 4 7 4 + 1 9 9 .8 0 3 9 5 8 + 1 9 9 .8 0 4 0 0 0 + 1 9 9 .8 0 4 0 0 0 + 1 9 9 .8 0 4 0 0 0

+ 9 9 .9 7 7 5 6 8 + 1 8 6 .3 8 6 9 0 8 + 1 9 9 .4 0 6 8 8 8 + 1 9 9 .9 9 1 8 8 3 + 1 9 9 .9 9 9 9 6 2 + 2 0 0 .0 0 0 0 0 0 + 2 0 0 .0 0 0 0 0 0 + 2 0 0 .0 0 0 0 0 0

+ 1 0 0 .3 0 6 6 2 5 + 1 8 6 .6 1 2 1 5 3 + 1 9 9 .6 1 2 1 3 1 + 2 0 0 .1 8 8 0 8 6 + 2 0 0 .1 9 5 9 6 3 + 2 0 0 .1 9 6 0 0 0 + 2 0 0 .1 9 6 0 0 0 + 2 0 0 .1 9 6 0 0 0

+ 2 0 0 .3 3 2 7 4 6 + 2 0 0 .3 8 2 9 5 6 + 2 0 0 .3 9 1 6 2 7 + 2 0 0 .3 9 1 9 9 5 + 2 0 0 .3 9 2 0 0 0 + 2 0 0 .3 9 2 0 0 0 + 2 0 0 .3 9 2 0 0 0 + 2 0 0 .3 9 2 0 0 0

+ 2 0 0 .5 8 7 9 7 6 + 2 0 0 .5 8 7 9 9 6 + 2 0 0 .5 8 8 0 0 0 + 2 0 0 .5 8 8 0 0 0 + 2 0 0 .5 8 8 0 0 0 + 2 0 0 .5 8 8 0 0 0 + 2 0 0 .5 8 8 0 0 0 + 2 0 0 .5 8 8 0 0 0

+ 2 0 0 .7 8 4 0 0 0 + 2 0 0 .7 8 4 0 0 0 + 2 0 0 .7 8 4 0 0 0 + 2 0 0 .7 8 4 0 0 0 + 2 0 0 .7 8 4 0 0 0 + 2 0 0 .7 8 4 0 0 0 + 2 0 0 .7 8 4 0 0 0 + 2 0 0 .7 8 4 0 0 0

+ 2 0 0 .9 8 0 0 0 0 + 2 0 0 .9 8 0 0 0 0 + 2 0 0 .9 8 0 0 0 0 + 2 0 0 .9 8 0 0 0 0 + 2 0 0 .9 8 0 0 0 0 + 2 0 0 .9 8 0 0 0 0 + 2 0 0 .9 8 0 0 0 0 + 2 0 0 .9 8 0 0 0 0

+ 2 0 1 .1 7 6 0 0 0 + 2 0 1 .1 7 6 0 0 0 + 2 0 1 .1 7 6 0 0 0 + 2 0 1 .1 7 6 0 0 0 + 2 0 1 .1 7 6 0 0 0 + 2 0 1 .1 7 6 0 0 0 + 2 0 1 .1 7 6 0 0 0 + 2 0 1 .1 7 6 0 0 0

+ 2 0 1 .3 7 2 0 0 0 + 2 0 1 .3 7 2 0 0 0 + 2 0 1 .3 7 2 0 0 0 + 2 0 1 .3 7 2 0 0 0 + 2 0 1 .3 7 2 0 0 0 + 2 0 1 .3 7 2 0 0 0 + 2 0 1 .3 7 2 0 0 0 + 2 0 1 .3 7 2 0 0 0

+ 2 0 1 .5 6 8 0 0 0 + 2 0 1 .5 6 8 0 0 0 + 2 0 1 .5 6 8 0 0 0 + 2 0 1 .5 6 8 0 0 0 + 2 0 1 .5 6 8 0 0 0 + 2 0 1 .5 6 8 0 0 0 + 2 0 1 .5 6 8 0 0 0 + 2 0 1 .5 6 8 0 0 0

+ 2 0 1 .7 6 4 0 0 0 + 2 0 1 .7 6 4 0 0 0 + 2 0 1 .7 6 4 0 0 0 + 2 0 1 .7 6 4 0 0 0 + 2 0 1 .7 6 4 0 0 0 + 2 0 1 .7 6 4 0 0 0 + 2 0 1 .7 6 4 0 0 0 + 2 0 1 .7 6 4 0 0 0

Cuyo tiempo para alcanzar qw,min es de 46.3322 días.

5 Programa de Cómputo
El programa de cómputo esta dividido en 4 objetos, uno para manipular las
matrices y vectores, otro para la interpolar valores numéricos, otro para generar
las mallas y otro para resolver el sistema linea Ax = b pentadiagonal por el
algoritmo para matrices dispersas NSPIV (también es posible usar cualquier
rutina tipo Gauss Siedel o Jacobi). Además de el programa propiamente dicho
que se encarga del cálculo de las formulaciones Totalmente Implícita, Simi-
implícita Linelizada y Linealización Directa. los cuales a continuación se anexan.

13
Definiciones Básicas Definiciones.hpp:
#ifndef __DEFINICIONES_HPP__
#define __DEFINICIONES_HPP__

#define __Double__

#ifdef __Double__
// Define ldouble como long double
typedef double ldouble;
#else
// Define ldouble como double
typedef long double ldouble;
#endif

struct Dimension_Ventana {
ldouble Xi;
ldouble Xf;
ldouble Yi;
ldouble Yf;
ldouble Zi;
ldouble Zf;
};

struct Definicion_Ventana {
int Xi;
int Xf;
int Yi;
int Yf;
};

struct C_2D {
ldouble X;
ldouble Y;
};

struct C_3D {
ldouble x;
ldouble y;
ldouble z;
};

// Coordenadas triples en formato entero


struct C_3I {
int x;
int y;
int z;
};

// Coordenadas dobles en formato entero


struct C_2I {
int x;
int y;
};

// Manejo de colores
#ifndef __PROGRAMACION_BORLAND__
typedef int TColor;
#else
extern TColor Colores_16[];
#endif

// Numeros complejos
#include <complex>
typedef std::complex <ldouble> cdouble;

#endif
Interpolador Lineal Interpolador.hpp:
// Clase para hacer interpolaciones lineales
// Antonio Carrillo Ledesma

#ifndef __Interpolador__
#define __Interpolador__

#include "Definiciones.hpp"

class Interpolador
{

private:
ldouble *X;
ldouble *FX;
int N_elementos;

public:

// Constructor de la clase
Interpolador(ldouble *x, ldouble *fx, int i)
{
X = x;
FX = fx;
N_elementos = i;
}

// Calcula la interpolación correspondiente al valor xi


ldouble Calcula(ldouble xi);

// Calcula la interpolación inversa correspondiente al valor fxi


ldouble CalculaInverso(ldouble fxi);

// Calcula la derivada del correspondiente valor xi


ldouble Derivada(ldouble xi);

};

#endif

Interpolador Lineal Interpolador.cpp:


#include <stdio.h>
#include "Interpolador.hpp"

// Cálcula la interpolación correspondiente al valor xi


ldouble Interpolador::Calcula(ldouble xi)
{
ldouble y = 0.0;
if (X[0] < X[N_elementos-1])
{
if (xi >= X[0] && xi <= X[N_elementos-1])
{
int i;
for(i = 0; i < N_elementos ; i++)
{
if (xi >= X[i] && xi <= X[i+1])
{
y = FX[i] * ((xi - X[i+1]) / (X[i] - X[i+1])) + FX[i+1] * ((xi - X[i]) / (X[i+1] - X[i]));
return y;
}
}
} else printf ("Valor solicitado fuera de rango (ascendente Calcula) %lf ",xi);
} else {
if (xi <= X[0] && xi >= X[N_elementos-1])
{
int i;
for(i = 0; i < N_elementos ; i++)
{
if (xi <= X[i] && xi >= X[i+1])
{
y = FX[i] * ((xi - X[i+1]) / (X[i] - X[i+1])) + FX[i+1] * ((xi - X[i]) / (X[i+1] - X[i]));
return y;
}
}
} else printf ("Valor solicitado fuera de rango (descendente Calcula) %lf ",xi);
}
return y;
}

// Cálcula la interpolación inversa correspondiente al valor fxi


ldouble Interpolador::CalculaInverso(ldouble fxi)
{
ldouble y = 0.0;
if (FX[0] < FX[N_elementos-1])
{
if (fxi >= FX[0] && fxi <= FX[N_elementos-1])
{
int i;
for(i = 0; i < N_elementos ; i++)
{
if (fxi >= FX[i] && fxi <= FX[i+1])
{
y = X[i] * ((fxi - FX[i+1]) / (FX[i] - FX[i+1])) + X[i+1] * ((fxi - FX[i]) / (FX[i+1] - FX[i]));
return y;
}
}
} else printf ("Valor solicitado fuera de rango (ascendente Inverso) %lf ",fxi);
} else {
if (fxi <= FX[0] && fxi >= FX[N_elementos-1])
{
int i;
for(i = 0; i < N_elementos ; i++)
{
if (fxi <= FX[i] && fxi >= FX[i+1])
{
y = X[i] * ((fxi - FX[i+1]) / (FX[i] - FX[i+1])) + X[i+1] * ((fxi - FX[i]) / (FX[i+1] - FX[i]));
return y;
}
}

} else printf ("Valor solicitado fuera de rango (descendente Inverso) %lf ",fxi);
}
return y;
}

// Calcula la derivada del correspondiente valor xi


ldouble Interpolador::Derivada(ldouble xi)
{
ldouble y = 0.0;
if (X[0] < X[N_elementos-1])
{
if (xi >= X[0] && xi <= X[N_elementos-1])
{
int i;
for(i = 0; i < N_elementos ; i++)
{

if (xi >= X[i] && xi <= X[i+1])


{
y = (FX[i+1] - FX[i]) / (X[i+1] - X[i]);
//y = FX[i] * ((xi - X[i+1]) / (X[i] - X[i+1])) + FX[i+1] * ((xi - X[i]) / (X[i+1] - X[i]));
return y;
}
}
} else printf ("Valor solicitado fuera de rango (ascendente Derivada) %lf ",xi);
} else {
if (xi <= X[0] && xi >= X[N_elementos-1])
{
int i;
for(i = 0; i < N_elementos ; i++)
{
if (xi <= X[i] && xi >= X[i+1])
{
y = (FX[i] - FX[i+1]) / (X[i] - X[i+1]);
//y = FX[i] * ((xi - X[i+1]) / (X[i] - X[i+1])) + FX[i+1] * ((xi - X[i]) / (X[i+1] - X[i]));
return y;
}
}
} else printf ("Valor solicitado fuera de rango (descendente Derivada) %lf ",xi);
}
return y;
}

Malla Radial Cilíndrica Malla_RC.hpp:


#ifndef __Malla_RC__
#define __Malla_RC__

#include "Definiciones.hpp"
#include "BMV.hpp"

#define NODOS_DISTRIBUIDOS 0
#define BLOQUES_CENTRADOS 1

class Malla_RC
{

private:
ldouble *FR;
ldouble *ND;
ldouble RE;
ldouble RW;
BMV bmv;
int N_elementos;
int Tipo_malla;

// Calcula los nodos y las fronteras


void Calcula(void);

public:

// Constructor de la clase
Malla_RC(ldouble rw, ldouble re, int n, int tp)
{
N_elementos = n;
Tipo_malla = tp;
RE = re;
RW = rw;
FR = bmv.SolicitaMemoria(N_elementos+1);
ND = bmv.SolicitaMemoria(N_elementos);
Calcula();
}

// Destructor de la clase
~Malla_RC()
{
bmv.LiberaMemoria(FR,N_elementos+1);
bmv.LiberaMemoria(ND,N_elementos);
}

// Regresa el valor de las fronteras del nodo i (i=1,2,..., N_elementos)


void Frontera(int i, ldouble &f1, ldouble &f2);

// Regresa el valor del nodo i (i=1,2,..., N_elementos)


void Nodo(int i, ldouble &nd);

// Regresa el valor de la frontera anterior, nodo y frontera siguiente del nodo i (i=1,2,..., N_elementos)
void Nodo(int i, ldouble &f1, ldouble &nd, ldouble &f2);

// Visualiza la malla
void Visualiza(void);

};

#endif

Malla Radial Cilíndrica Malla_RC.cpp:


#include <stdio.h>
#include <math.h>
#include "Malla_RC.hpp"

// Calcula los nodos y las fronteras


void Malla_RC::Calcula(void)
{
ldouble alfa;
int i;
if (Tipo_malla == NODOS_DISTRIBUIDOS)
{
alfa = pow(RE / RW,1.0/(ldouble)(N_elementos-1));
ND[0] = RW;
// Calculo de nodos
for (i = 0; i < N_elementos-1; i++) ND[i+1] = alfa * ND[i];
ND[N_elementos-1] = RE;
// Calculo de fronteras
for (i = 0; i < N_elementos-1; i++) FR[i+1] = (ND[i+1] - ND[i]) / log(ND[i+1] / ND[i]);
} else {
alfa = pow(RE / RW,1.0/(ldouble) N_elementos);
// Calculo de nodos
ND[0] = (alfa / (alfa - 1.0)) * log(alfa) * RW;
for (i = 0; i < N_elementos-1; i++) ND[i+1] = alfa * ND[i];
// Calculo de fronteras
FR[0] = RW;
for (i = 0; i < N_elementos-1; i++) FR[i+1] = (ND[i+1] - ND[i]) / log(ND[i+1] / ND[i]);
FR[N_elementos] = RE;
}
}

// Regresa el valor de las fronteras del nodo i (i=1,2,..., N_elementos)


void Malla_RC::Frontera(int i, ldouble &f1, ldouble &f2)
{
if (i >= 1 && i <= N_elementos) f1 = FR[i-1], f2 = FR[i];
}

// Regresa el valor del nodo i (i=1,2,..., N_elementos)


void Malla_RC::Nodo(int i, ldouble &nd)
{
if (i >= 1 && i <= N_elementos) nd = ND[i-1];
}

// Regresa el valor de la frontera anterior, nodo y frontera siguiente del nodo i (i=1,2,..., N_elementos)
void Malla_RC::Nodo(int i, ldouble &f1, ldouble &nd, ldouble &f2)
{
if (i >= 1 && i <= N_elementos)
{
f1 = FR[i-1];
nd = ND[i-1];
f2 = FR[i];
}
}

// Visualiza la malla
void Malla_RC::Visualiza(void)
{
for (int i = 0; i < N_elementos; i++)
{
printf("%lf %lf %lf\n",FR[i], ND[i], FR[i+1]);
}
printf("\n");
}

Malla 1D Malla1D.hpp:
#ifndef __Malla1D__
#define __Malla1D__

#include "Definiciones.hpp"
#include "BMV.hpp"

#define NODOS_DISTRIBUIDOS 0
#define BLOQUES_CENTRADOS 1

class Malla1D
{

private:
ldouble *FR;
ldouble *ND;
ldouble A;
ldouble B;
BMV bmv;
int N_elementos;
int Tipo_malla;

// Calcula los nodos y las fronteras


void Calcula(void);

public:

// Constructor de la clase
Malla1D(ldouble a, ldouble b, int n, int tp)
{
N_elementos = n;
Tipo_malla = tp;
A = a;
B = b;
FR = bmv.SolicitaMemoria(N_elementos+1);
ND = bmv.SolicitaMemoria(N_elementos);
Calcula();
}

// Destructor de la clase
~Malla1D()
{
bmv.LiberaMemoria(FR,N_elementos+1);
bmv.LiberaMemoria(ND,N_elementos);
}

// Regresa el valor de las fronteras del nodo i (i=1,2,..., N_elementos)


void Frontera(int i, ldouble &f1, ldouble &f2);

// Regresa el valor del nodo i (i=1,2,..., N_elementos)


void Nodo(int i, ldouble &nd);
// Regresa el valor de la frontera anterior, nodo y frontera siguiente del nodo i (i=1,2,..., N_elementos)
void Nodo(int i, ldouble &f1, ldouble &nd, ldouble &f2);

// Visualiza la malla
void Visualiza(void);

};

#endif

Malla 1D Malla1D.cpp:
#include <stdio.h>
#include "Malla1D.hpp"

// Calcula los nodos y las fronteras


void Malla1D::Calcula(void)
{
ldouble alfa = (B - A) / (ldouble) N_elementos;
int i;
if (Tipo_malla == NODOS_DISTRIBUIDOS)
{
ND[0] = A;
// Calculo de nodos
for (i = 0; i < N_elementos-1; i++) ND[i+1] = A + alfa * (i+1);
ND[N_elementos-1] = B;
// Calculo de fronteras
for (i = 0; i < N_elementos-1; i++) FR[i+1] = ND[i] + (ND[i+1] - ND[i]) / 2.0;
} else {
// Calculo de fronteras
FR[0] = A;
for (i = 0; i < N_elementos-1; i++) FR[i+1] = A + alfa * (i+1);
FR[N_elementos] = B;
// Calculo de nodos
for (i = 0; i < N_elementos; i++) ND[i] = FR[i] + (FR[i+1] - FR[i]) /2.0;
}
}

// Regresa el valor de las fronteras del nodo i (i=1,2,..., N_elementos)


void Malla1D::Frontera(int i, ldouble &f1, ldouble &f2)
{
if (i >= 1 && i <= N_elementos) f1 = FR[i-1], f2 = FR[i];
}

// Regresa el valor del nodo i (i=1,2,..., N_elementos)


void Malla1D::Nodo(int i, ldouble &nd)
{
if (i >= 1 && i <= N_elementos) nd = ND[i-1];
}

// Regresa el valor de la frontera anterior, nodo y frontera siguiente del nodo i (i=1,2,..., N_elementos)
void Malla1D::Nodo(int i, ldouble &f1, ldouble &nd, ldouble &f2)
{
if (i >= 1 && i <= N_elementos)
{
f1 = FR[i-1];
nd = ND[i-1];
f2 = FR[i];
}
}

// Visualiza la malla
void Malla1D::Visualiza(void)
{
for (int i = 0; i < N_elementos; i++)
{
printf("%lf %lf %lf\n",FR[i], ND[i], FR[i+1]);
}
printf("\n");
}

Código Principal main.cpp:


#include "Interpolador.hpp"
#include "Malla_RC.hpp"
#include "Malla1D.hpp"
#include "Resuelve_Axb.hpp"
#include <stdio.h>

//#define TodosNodos
//#define AZIZ
#define ITR 5

ldouble PC[] = {1.033,24.99,74.98,124.98,174.96,199.96,249.95,299.94,349.93,393.65};


ldouble B0[] = {1.5828,1.5827,1.5778,1.5680,1.5545,1.5469,1.5308,1.5144,1.4991,1.4874};
ldouble U0[] = {0.3982,0.4118,0.4383,0.4621,0.4832,0.4927,0.5098,0.5242,0.5359,0.5440};

ldouble DPo = 200.0;


ldouble DRw = 0.1;
ldouble DRe = 500.0;
ldouble DQw = 750.0;
ldouble DQwm = 50.0;
ldouble DK = 30.0/1000.0;
ldouble DF = 0.12;
ldouble DR = 0.7448*0.1;
ldouble DH = 50.0;
ldouble DPwfm = 100.0;
ldouble DCr = 7e-5;

int DI = 20; // 20
int DZ = 19; // 19
ldouble DE = 1e-1;
ldouble Dit = 1e-12;

ldouble rtiM, rtim, ztiM, ztim, dvi, vi;


ldouble **P, **xP;

// Interpolador para Bo
Interpolador Bo(PC,B0,10);
// Interpolador para Uo
Interpolador Uo(PC,U0,10);
// Definicion de la malla radial logaritmica con bloques centrados
Malla_RC mr(DRw,DRe,DI,BLOQUES_CENTRADOS);
Malla1D mz(0.0,DH,DZ,BLOQUES_CENTRADOS);

// Trasmicibilidad
void TrM(int i, int j)
{

rtiM = 0;
if (i >= DI-1) return;

ldouble rf1, rf2, rn, zf1, zf2, zn, n, p;


if (i < (DI - 1)) {
if ((xP[j][i+1] - xP[j][i]) >= 0.0) p = xP[j][i+1];
else p = xP[j][i];
} else p = xP[j][DI-1];

ldouble rmbM = DK / (Uo.Calcula(p) * Bo.Calcula(p));

mr.Nodo(i+1,rf1,rn,rf2);
mz.Nodo(j+1,zf1,zn,zf2);
mr.Nodo(i+2,n);
#ifdef AZIZ
rtiM = 4.0 * M_PI * (((rf2*rf2)*(zf2-zf1))/(n*n-rn*rn)) * rmbM * 8.364;
#else
rtiM = 2.0 * M_PI * rf2 * (zf2-zf1) / (rf2 - rf1) * rmbM * 8.364;
#endif
}

void Trm(int i, int j)


{
rtim = 0;
if (i <= 0) return;

ldouble rf1, rf2, rn, zf1, zf2, zn, n, p;


if (i > 0) {
if ((xP[j][i] - xP[j][i-1]) >= 0.0) p = xP[j][i-1];
else p = xP[j][i];
} else p = xP[j][0];

ldouble rmbm = DK / (Uo.Calcula(p) * Bo.Calcula(p));

mr.Nodo(i+1,rf1,rn,rf2);
mz.Nodo(j+1,zf1,zn,zf2);
mr.Nodo(i,n);
#ifdef AZIZ
rtim = 4.0 * M_PI * (((rf1*rf1)*(zf2-zf1))/(rn*rn-n*n)) * rmbm * 8.364;
#else
rtim = 2.0 * M_PI * rf1 * (zf2-zf1) / (rf2 - rf1) * rmbm * 8.364;
#endif
}

void TzM(int i, int j)


{
ztiM = 0;
if (j >= DZ-1) return;

ldouble rf1, rf2, rn, zf1, zf2, zn, n, p;


mr.Nodo(i+1,rf1,rn,rf2);
mz.Nodo(j+1,zf1,zn,zf2);
mz.Nodo(j+2,n);

if (j < (DZ - 1)) {


if ((xP[j+1][i] - xP[j][i] - (DR*(DH/(ldouble)DZ))) >= 0.0) p = xP[j+1][i];
else p = xP[j][i];
} else p = xP[DZ-1][i];

ldouble zmbM = DK / (Uo.Calcula(p) * Bo.Calcula(p));


#ifdef AZIZ
ztiM = M_PI * ((rf2*rf2-rf1*rf1)/(n-zn)) * zmbM * 8.364;
#else
ztiM = M_PI * ((rf2-rf1)/(n-zn)) * zmbM * 8.364;
#endif
}

void Tzm(int i, int j)


{
ztim = 0;
if (j <= 0) return;

ldouble rf1, rf2, rn, zf1, zf2, zn, n, p;


mr.Nodo(i+1,rf1,rn,rf2);
mz.Nodo(j+1,zf1,zn,zf2);
mz.Nodo(j,n);

if (j > 0) {
if ((xP[j][i] - xP[j-1][i] - (DR*(DH/(ldouble)DZ))) >= 0.0) p = xP[j-1][i];
else p = xP[j][i];
} else p = xP[j][0];

ldouble zmbm = DK / (Uo.Calcula(p) * Bo.Calcula(p));


#ifdef AZIZ
ztim = M_PI * ((rf2*rf2-rf1*rf1)/(zn-n)) * zmbm * 8.364;
#else
ztim = M_PI * ((rf2-rf1)/(zn-n)) * zmbm * 8.364;
#endif
}

///////////////////////////////////////////////////////////////////////////////////////////////////

// Trasmicibilidad
void LDTrM(int i, int j)
{

rtiM = 0;
if (i >= DI-1) return;

ldouble rf1, rf2, rn, zf1, zf2, zn, n, p;


if (i < (DI - 1)) {
if ((P[j][i+1] - P[j][i]) >= 0.0) p = P[j][i+1];
else p = P[j][i];
} else p = P[j][DI-1];

ldouble rmbM = DK / (Uo.Calcula(p) * Bo.Calcula(p));

mr.Nodo(i+1,rf1,rn,rf2);
mz.Nodo(j+1,zf1,zn,zf2);
mr.Nodo(i+2,n);
#ifdef AZIZ
rtiM = 4.0 * M_PI * (((rf2*rf2)*(zf2-zf1))/(n*n-rn*rn)) * rmbM * 8.364;
#else
rtiM = 2.0 * M_PI * rf2 * (zf2-zf1) / (rf2 - rf1) * rmbM * 8.364;
#endif
}

void LDTrm(int i, int j)


{
rtim = 0;
if (i <= 0) return;

ldouble rf1, rf2, rn, zf1, zf2, zn, n, p;


if (i > 0) {
if ((P[j][i] - P[j][i-1]) >= 0.0) p = P[j][i-1];
else p = P[j][i];
} else p = P[j][0];

ldouble rmbm = DK / (Uo.Calcula(p) * Bo.Calcula(p));

mr.Nodo(i+1,rf1,rn,rf2);
mz.Nodo(j+1,zf1,zn,zf2);
mr.Nodo(i,n);
#ifdef AZIZ
rtim = 4.0 * M_PI * (((rf1*rf1)*(zf2-zf1))/(rn*rn-n*n)) * rmbm * 8.364;
#else
rtim = 2.0 * M_PI * rf1 * (zf2-zf1) / (rf2 - rf1) * rmbm * 8.364;
#endif
}

void LDTzM(int i, int j)


{
ztiM = 0;
if (j >= DZ-1) return;

ldouble rf1, rf2, rn, zf1, zf2, zn, n, p;


mr.Nodo(i+1,rf1,rn,rf2);
mz.Nodo(j+1,zf1,zn,zf2);
mz.Nodo(j+2,n);
if (j < (DZ - 1)) {
if ((P[j+1][i] - P[j][i] - (DR*(DH/(ldouble)DZ))) >= 0.0) p = P[j+1][i];
else p = P[j][i];
} else p = P[DZ-1][i];

ldouble zmbM = DK / (Uo.Calcula(p) * Bo.Calcula(p));


#ifdef AZIZ
ztiM = M_PI * ((rf2*rf2-rf1*rf1)/(n-zn)) * zmbM * 8.364;
#else
ztiM = M_PI * ((rf2-rf1)/(n-zn)) * zmbM * 8.364;
#endif
}

void LDTzm(int i, int j)


{
ztim = 0;
if (j <= 0) return;

ldouble rf1, rf2, rn, zf1, zf2, zn, n, p;


mr.Nodo(i+1,rf1,rn,rf2);
mz.Nodo(j+1,zf1,zn,zf2);
mz.Nodo(j,n);

if (j > 0) {
if ((P[j][i] - P[j-1][i] - (DR*(DH/(ldouble)DZ))) >= 0.0) p = P[j-1][i];
else p = P[j][i];
} else p = P[j][0];

ldouble zmbm = DK / (Uo.Calcula(p) * Bo.Calcula(p));


#ifdef AZIZ
ztim = M_PI * ((rf2*rf2-rf1*rf1)/(zn-n)) * zmbm * 8.364;
#else
ztim = M_PI * ((rf2-rf1)/(zn-n)) * zmbm * 8.364;
#endif
}

///////////////////////////////////////////////////////////////////////////////////////////////////

void Dvi(int i, int j)


{
ldouble f1,f2;
mr.Frontera(i+1,f1,f2);

dvi = ((M_PI * (f2 * f2 - f1 * f1) * (DH/(ldouble)DZ)) / Dit) * ((Bo.Calcula(xP[j][i]) * DCr / (Bo.Calcula(xP[j][i]) *


Bo.Calcula(xP[j][i]))) - (((1.0 + DCr * (xP[j][i] - P[j][i])) / (Bo.Calcula(xP[j][i]) * Bo.Calcula(xP[j][i])))*
Bo.Derivada(xP[j][i])));
}

void Vi(int i, int j)


{
ldouble f1,f2;
mr.Frontera(i+1,f1,f2);

vi = (((M_PI * (f2 * f2 - f1 * f1) * (DH/(ldouble)DZ)) * DF) / Dit) * (((1.0 + DCr * (xP[j][i] - P[j][i]))/Bo.Calcula(xP[j][i]))-
(1.0/Bo.Calcula(P[j][i])));
}

int main(void)
{
printf ("\n\nMalla Radial Cilíndrica\n");
mr.Visualiza();

printf ("\n\nMalla en Z\n");


mz.Visualiza();

BMV m;
Resuelve_Axb rs;
ldouble **A, **AA, *x, *b, **Re;
if (!(A = m.SolicitaMemoria(DI*DZ,DI*DZ))) return 1; // Solicita memoria para la matriz A
if (!(AA = m.SolicitaMemoria(DI*DZ,DI*DZ))) return 1; // Solicita memoria para la matriz AA
if (!(b = m.SolicitaMemoria(DI*DZ))) return 1; // Solicita la memoria para el vector b
if (!(x = m.SolicitaMemoria(DI*DZ))) return 1; // Solicita la memoria para el vector x
if (!(P = m.SolicitaMemoria(DZ,DI))) return 1; // Solicita la memoria para el vector p
if (!(xP = m.SolicitaMemoria(DZ,DI))) return 1; // Solicita la memoria para el vector xp

ldouble t, pwf=DPo, qw;


ldouble dij, diMj, dijM, a1, a2, a3, a4, xa, zf1, zf2, zn , xQw;
int i, j, k, sw, xsw, sv;

////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////

printf ("\n\nEsquema Totalmente Implicito\nI = %d, J = %d, Tol=%e\n\n",DI,DZ,DE);


// Condiciones iniciales
for (j = 0; j < DZ; j++)
{
a1 = DH / DZ;
a2 = (DH/DZ) / 2.0;
for (i = 0; i < DI; i++) P[j][i] = DPo + DR *(j*a1+a2 - DH/2.0 );
}
printf("Distribución de Presión inicial\n");
printf("Matriz de Presiones\n");
m.Visualiza(P,DZ,DI,0);
t = 0.0;
xQw = DQw;

do
{
// Presion aproximada
for (j = 0; j < DZ; j++)
{
for (i = 0; i < DI; i++) xP[j][i] = P[j][i];
}
sw = 0, xsw = 1;
while (xsw)
{
xsw = 0;
// Genera A
// Celdas interiores de la discretizacion
for (j = 0; j < DZ; j++)
{
mz.Nodo(j+1,zf1,zn,zf2);
for (i = 0; i < DI; i++)
{
TrM(i,j);
Trm(i,j);
TzM(i,j);
Tzm(i,j);
Dvi(i,j);

diMj = dijM = 0.0;


dij= (1.0 / Bo.Calcula(xP[j][i])) * Bo.Derivada(xP[j][i]) + (1.0 / Uo.Calcula(xP[j][i])) * Uo.Derivada(xP[j][i]);
if (i <= DI-2) diMj = (1.0 / Bo.Calcula(xP[j][i+1])) * Bo.Derivada(xP[j][i+1]) + (1.0 / Uo.Calcula(xP[j][i+1])) *
Uo.Derivada(xP[j][i+1]);
if (j <= DZ-2) dijM = (1.0 / Bo.Calcula(xP[j+1][i])) * Bo.Derivada(xP[j+1][i]) + (1.0 / Uo.Calcula(xP[j+1][i])) *
Uo.Derivada(xP[j+1][i]);

// f
if (j > 0) A[i+DI*j][i+DI*(j-1)] = ztim + ztim * (xP[j][i] - xP[j-1][i] - (DR*(DH/(ldouble)DZ))) * dij;
// c
if (i > 0) A[i+DI*j][i+DI*j-1] = rtim + rtim * (xP[j][i] - xP[j][i-1]) * dij;
// a
a1 = a2 = a3 = a4 = 0.0;
if (i < DI-1) a1 = rtiM * (xP[j][i+1] - xP[j][i]) * diMj;
// Celdas abiertas a produccion
#ifndef TodosNodos
if (i == 0 && (j == 8 || j == 9 || j == 10))
{
for (xa = 0.0,k = 8; k < 11; k++)
{
TrM(i,k);
xa += rtiM;
}
TrM(i,j);
a2 = (rtiM / xa) * (-xQw * 8.364) * dij;
}
#else
if (i == 0)
{
for (xa = 0.0,k = 0; k < DZ; k++)
{
TrM(i,k);
xa += rtiM;
}
TrM(i,j);
a2 = (rtiM / xa) * (-xQw * 8.364) * dij;
}
#endif
if (i > 0) a2 = rtim * (xP[j][i] - xP[j][i-1]) * dij;
if (j < DZ-1) a3 = ztiM * (xP[j+1][i] - xP[j][i] - (DR*(DH/(ldouble)DZ))) * dij;
if (j > 0) a4 = ztim * (xP[j][i] - xP[j-1][i] - (DR*(DH/(ldouble)DZ))) * dij;
A[i+DI*j][i+DI*j] = -rtiM - rtim - a1 + a2 - ztiM - a3 - ztim + a4 - dvi;
// b
if (i < DI-1) A[i+DI*j][i+DI*j+1] = rtiM - rtiM * (xP[j][i+1] - xP[j][i]) * diMj;
// e
if (j < DZ-1) A[i+DI*j][i+DI*(j+1)] = ztiM - ztiM * (xP[j+1][i] - xP[j][i] - (DR*(DH/(ldouble)DZ))) * dijM;
}
}

// Genera b
for (j = 0; j < DZ; j++)
{
mz.Nodo(j+1,zf1,zn,zf2);
for (i = 0; i < DI; i++)
{
TrM(i,j);
Trm(i,j);
TzM(i,j);
Tzm(i,j);
Vi(i,j);

a1 = a2 = a3 = a4 = 0.0;
if (i < DI-1) a1 = rtiM * (xP[j][i+1] - xP[j][i]);
if (i > 0) a2 = rtim * (xP[j][i] - xP[j][i-1]);
if (j < DZ-1) a3 = ztiM * (xP[j+1][i] - xP[j][i] - (DR*(DH/(ldouble)DZ)));
if (j > 0) a4 = ztim * (xP[j][i] - xP[j-1][i] - (DR*(DH/(ldouble)DZ)));
// Celdas abiertas a produccion
#ifndef TodosNodos
if (i == 0 && (j == 8 || j == 9 || j == 10))
{
for (xa = 0.0,k = 8; k < 11; k++)
{
TrM(i,k);
xa += rtiM;
}
TrM(i,j);
a2 = (rtiM / xa) * (xQw * 8.364);
}
#else
if (i == 0)
{
for (xa = 0.0,k = 0; k < DZ; k++)
{
TrM(i,k);
xa += rtiM;
}
TrM(i,j);
a2 = (rtiM / xa) * (xQw * 8.364);
}
#endif
b[i+DI*j] = -(a1 - a2 + a3 - a4 - vi);
}
}

// Resolver Ax=b
rs.Resuelve(A,x,b,DI*DZ,ITR);

// Revisar aproximación
for (i = 0; i < DI*DZ; i++)
{
if (fabs(x[i]) > DE) xsw = 1;
}
// Actualiza las presiones calculadas
for (j = 0; j < DZ; j++)
{
for (i = 0; i < DI; i++) xP[j][i] = P[j][i] + x[j*DI+i];
}
sw++;
if (sw >= 5) break;
}

// Actualizar las presiones


if (sw < 5) {
sv = 0;
if (P[0][DI-1] >= (DPo-1e-6) && xP[0][DI-1] <= (DPo-1e-6)) sv = 1;
for (j = 0; j < DZ; j++)
{
for (i = 0; i < DI; i++) P[j][i] = xP[j][i];
}
t += Dit;
if (sw <= 2) Dit *= 2.0;
if (Dit > 15.0) Dit = 15.0;
// Calculo de presion de fondo
#ifndef TodosNodos
pwf = P[9][0];
#else
pwf = P[0][0];
#endif
if (pwf < 100.0 ) sv = 1;
if (sv)
{
printf("Tiempo %2.18e, incremento %2.18e\n",t,Dit);
printf("Presion fondo poso %2.18f\n",pwf);
printf("Matriz de Presiones\n");
m.Visualiza(xP,DZ,DI,0);
}
} else Dit /= 2.0;
} while (pwf > DPwfm);

////////////////////////////////////////////////////////////////////////////////////

// Presion aproximada
for (j = 0; j < DZ; j++)
{
for (i = 0; i < DI; i++) xP[j][i] = P[j][i];
}
Dit = 1e-12;
do
{
qw = xQw;
sw = 0, xsw = 1;
while (xsw)
{
xsw = 0;
// Genera A
// Celdas interiores de la discretizacion
for (j = 0; j < DZ; j++)
{
mz.Nodo(j+1,zf1,zn,zf2);
for (i = 0; i < DI; i++)
{
TrM(i,j);
Trm(i,j);
TzM(i,j);
Tzm(i,j);
Dvi(i,j);

diMj = dijM = 0.0;


dij= (1.0 / Bo.Calcula(xP[j][i])) * Bo.Derivada(xP[j][i]) + (1.0 / Uo.Calcula(xP[j][i])) * Uo.Derivada(xP[j][i]);
if (i <= DI-2) diMj = (1.0 / Bo.Calcula(xP[j][i+1])) * Bo.Derivada(xP[j][i+1]) + (1.0 / Uo.Calcula(xP[j][i+1])) *
Uo.Derivada(xP[j][i+1]);
if (j <= DZ-2) dijM = (1.0 / Bo.Calcula(xP[j+1][i])) * Bo.Derivada(xP[j+1][i]) + (1.0 / Uo.Calcula(xP[j+1][i])) *
Uo.Derivada(xP[j+1][i]);

// f
if (j > 0) A[i+DI*j][i+DI*(j-1)] = ztim + ztim * (xP[j][i] - xP[j-1][i] - (DR*(DH/(ldouble)DZ))) * dij;
// c
if (i > 0) A[i+DI*j][i+DI*j-1] = rtim + rtim * (xP[j][i] - xP[j][i-1]) * dij;
// a
a1 = a2 = a3 = a4 = 0.0;
if (i < DI-1) a1 = rtiM * (xP[j][i+1] - xP[j][i]) * diMj;
// Celdas abiertas a produccion
#ifndef TodosNodos
if (i == 0 && (j == 8 || j == 9 || j == 10))
{
for (xa = 0.0,k = 8; k < 11; k++)
{
TrM(i,k);
xa += rtiM;
}
TrM(i,j);
a2 = (rtiM / xa) * (-xQw * 8.364) * dij;
}
#else
if (i == 0)
{
for (xa = 0.0,k = 0; k < DZ; k++)
{
TrM(i,k);
xa += rtiM;
}
TrM(i,j);
a2 = (rtiM / xa) * (-xQw * 8.364) * dij;
}
#endif
if (i > 0) a2 = rtim * (xP[j][i] - xP[j][i-1]) * dij;
if (j < DZ-1) a3 = ztiM * (xP[j+1][i] - xP[j][i] - (DR*(DH/(ldouble)DZ))) * dij;
if (j > 0) a4 = ztim * (xP[j][i] - xP[j-1][i] - (DR*(DH/(ldouble)DZ))) * dij;
A[i+DI*j][i+DI*j] = -rtiM - rtim - a1 + a2 - ztiM - a3 - ztim + a4 - dvi;
// b
if (i < DI-1) A[i+DI*j][i+DI*j+1] = rtiM - rtiM * (xP[j][i+1] - xP[j][i]) * diMj;
// e
if (j < DZ-1) A[i+DI*j][i+DI*(j+1)] = ztiM - ztiM * (xP[j+1][i] - xP[j][i] - (DR*(DH/(ldouble)DZ))) * dijM;
}
}

// Genera b
for (j = 0; j < DZ; j++)
{
mz.Nodo(j+1,zf1,zn,zf2);
for (i = 0; i < DI; i++)
{
TrM(i,j);
Trm(i,j);
TzM(i,j);
Tzm(i,j);
Vi(i,j);

a1 = a2 = a3 = a4 = 0.0;
if (i < DI-1) a1 = rtiM * (xP[j][i+1] - xP[j][i]);
if (i > 0) a2 = rtim * (xP[j][i] - xP[j][i-1]);
if (j < DZ-1) a3 = ztiM * (xP[j+1][i] - xP[j][i] - (DR*(DH/(ldouble)DZ)));
if (j > 0) a4 = ztim * (xP[j][i] - xP[j-1][i] - (DR*(DH/(ldouble)DZ)));
// Celdas abiertas a produccion
#ifndef TodosNodos
if (i == 0 && (j == 8 || j == 9 || j == 10))
{
for (xa = 0.0,k = 8; k < 11; k++)
{
TrM(i,k);
xa += rtiM;
}
TrM(i,j);
a2 = (rtiM / xa) * (xQw * 8.364);
}
#else
if (i == 0)
{
for (xa = 0.0,k = 0; k < DZ; k++)
{
TrM(i,k);
xa += rtiM;
}
TrM(i,j);
a2 = (rtiM / xa) * (xQw * 8.364);
}
#endif
b[i+DI*j] = -(a1 - a2 + a3 - a4 - vi);
}
}

// Resolver Ax=b
rs.Resuelve(A,x,b,DI*DZ,ITR);

// Revisar aproximación
for (i = 0; i < DI*DZ; i++)
{
if (fabs(x[i]) > DE) xsw = 1;
}
// Actualiza las presiones calculadas
#ifndef TodosNodos
qw = xQw - fabs(x[9*DI]);
#else
qw = xQw - fabs(x[0]);
#endif
sw++;
if (sw >= 5) break;
}

// Actualizar las presiones


if (sw < 5) {
if (xQw == qw) qw -= 1e-10;
xQw = qw;
t += Dit;
if (sw <= 2) Dit *= 2.0;
if (Dit > 15.0) Dit = 15.0;
} else Dit /= 2.0;
} while (xQw > DQwm);
printf("\nTiempo %2.18e, incremento %2.18e\n",t,Dit);
printf("Gasto %2.18f\n",xQw);

////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////

printf ("\n\nEsquema Semi-Implícito Linealizado\nI = %d, J = %d, Tol=%e\n\n",DI,DZ,DE);


// Condiciones iniciales
for (j = 0; j < DZ; j++)
{
a1 = DH / DZ;
a2 = (DH/DZ) / 2.0;
for (i = 0; i < DI; i++) P[j][i] = DPo + DR *(j*a1+a2 - DH/2.0 );
}
t = 0.0;
Dit = 1e-12;
xQw = DQw;

do
{
// Presion aproximada
for (j = 0; j < DZ; j++)
{
for (i = 0; i < DI; i++) xP[j][i] = P[j][i];
}
sw = 0, xsw = 1;
while (xsw)
{
xsw = 0;
// Genera A
// Celdas interiores de la discretizacion
for (j = 0; j < DZ; j++)
{
mz.Nodo(j+1,zf1,zn,zf2);
for (i = 0; i < DI; i++)
{
TrM(i,j);
Trm(i,j);
TzM(i,j);
Tzm(i,j);
Dvi(i,j);

diMj = dijM = 0.0;


dij= (1.0 / Bo.Calcula(xP[j][i])) * Bo.Derivada(xP[j][i]) + (1.0 / Uo.Calcula(xP[j][i])) * Uo.Derivada(xP[j][i]);
if (i <= DI-2) diMj = (1.0 / Bo.Calcula(xP[j][i+1])) * Bo.Derivada(xP[j][i+1]) + (1.0 / Uo.Calcula(xP[j][i+1])) *
Uo.Derivada(xP[j][i+1]);
if (j <= DZ-2) dijM = (1.0 / Bo.Calcula(xP[j+1][i])) * Bo.Derivada(xP[j+1][i]) + (1.0 / Uo.Calcula(xP[j+1][i])) *
Uo.Derivada(xP[j+1][i]);

// f
if (j > 0) A[i+DI*j][i+DI*(j-1)] = ztim + ztim * (xP[j][i] - xP[j-1][i] - (DR*(DH/(ldouble)DZ))) * dij;
// c
if (i > 0) A[i+DI*j][i+DI*j-1] = rtim + rtim * (xP[j][i] - xP[j][i-1]) * dij;
// a
a1 = a2 = a3 = a4 = 0.0;
if (i < DI-1) a1 = rtiM * (xP[j][i+1] - xP[j][i]) * diMj;
// Celdas abiertas a produccion
#ifndef TodosNodos
if (i == 0 && (j == 8 || j == 9 || j == 10))
{
for (xa = 0.0,k = 8; k < 11; k++)
{
TrM(i,k);
xa += rtiM;
}
TrM(i,j);
a2 = (rtiM / xa) * (-xQw * 8.364) * dij;
}
#else
if (i == 0)
{
for (xa = 0.0,k = 0; k < DZ; k++)
{
TrM(i,k);
xa += rtiM;
}
TrM(i,j);
a2 = (rtiM / xa) * (-xQw * 8.364) * dij;
}
#endif
if (i > 0) a2 = rtim * (xP[j][i] - xP[j][i-1]) * dij;
if (j < DZ-1) a3 = ztiM * (xP[j+1][i] - xP[j][i] - (DR*(DH/(ldouble)DZ))) * dij;
if (j > 0) a4 = ztim * (xP[j][i] - xP[j-1][i] - (DR*(DH/(ldouble)DZ))) * dij;
A[i+DI*j][i+DI*j] = -rtiM - rtim - a1 + a2 - ztiM - a3 - ztim + a4 - dvi;
// b
if (i < DI-1) A[i+DI*j][i+DI*j+1] = rtiM - rtiM * (xP[j][i+1] - xP[j][i]) * diMj;
// e
if (j < DZ-1) A[i+DI*j][i+DI*(j+1)] = ztiM - ztiM * (xP[j+1][i] - xP[j][i] - (DR*(DH/(ldouble)DZ))) * dijM;
}
}

// Genera b
for (j = 0; j < DZ; j++)
{
mz.Nodo(j+1,zf1,zn,zf2);
for (i = 0; i < DI; i++)
{
TrM(i,j);
Trm(i,j);
TzM(i,j);
Tzm(i,j);
Vi(i,j);

a1 = a2 = a3 = a4 = 0.0;
if (i < DI-1) a1 = rtiM * (xP[j][i+1] - xP[j][i]);
if (i > 0) a2 = rtim * (xP[j][i] - xP[j][i-1]);
if (j < DZ-1) a3 = ztiM * (xP[j+1][i] - xP[j][i] - (DR*(DH/(ldouble)DZ)));
if (j > 0) a4 = ztim * (xP[j][i] - xP[j-1][i] - (DR*(DH/(ldouble)DZ)));
// Celdas abiertas a produccion
#ifndef TodosNodos
if (i == 0 && (j == 8 || j == 9 || j == 10))
{
for (xa = 0.0,k = 8; k < 11; k++)
{
TrM(i,k);
xa += rtiM;
}
TrM(i,j);
a2 = (rtiM / xa) * (xQw * 8.364);
}
#else
if (i == 0)
{
for (xa = 0.0,k = 0; k < DZ; k++)
{
TrM(i,k);
xa += rtiM;
}
TrM(i,j);
a2 = (rtiM / xa) * (xQw * 8.364);
}
#endif
b[i+DI*j] = -(a1 - a2 + a3 - a4 - vi);
}
}

// Resolver Ax=b
rs.Resuelve(A,x,b,DI*DZ,ITR);

// Revisar aproximación
for (i = 0; i < DI*DZ; i++)
{
if (fabs(x[i]) > DE) xsw = 1;
}
// Actualiza las presiones calculadas
for (j = 0; j < DZ; j++)
{
for (i = 0; i < DI; i++) xP[j][i] = P[j][i] + x[j*DI+i];
}
sw++;
if (sw >= 5) break;
xsw = 0;
}

// Actualizar las presiones


if (sw < 5) {
sv = 0;
if (P[0][DI-1] >= (DPo-1e-6) && xP[0][DI-1] <= (DPo-1e-6)) sv = 1;
for (j = 0; j < DZ; j++)
{
for (i = 0; i < DI; i++) P[j][i] = xP[j][i];
}
t += Dit;
if (sw <= 2) Dit *= 2.0;
if (Dit > 15.0) Dit = 15.0;
// Calculo de presion de fondo
#ifndef TodosNodos
pwf = P[9][0];
#else
pwf = P[0][0];
#endif
if (pwf < 100.0 ) sv = 1;
if (sv)
{
printf("Tiempo %2.18e, incremento %2.18e\n",t,Dit);
printf("Presion fondo poso %2.18f\n",pwf);
printf("Matriz de Presiones\n");
m.Visualiza(xP,DZ,DI,0);
}
} else Dit /= 2.0;
} while (pwf > DPwfm);

////////////////////////////////////////////////////////////////////////////////////

// Presion aproximada
for (j = 0; j < DZ; j++)
{
for (i = 0; i < DI; i++) xP[j][i] = P[j][i];
}
Dit = 1e-12;
do
{
qw = xQw;
sw = 0, xsw = 1;
while (xsw)
{
xsw = 0;
// Genera A
// Celdas interiores de la discretizacion
for (j = 0; j < DZ; j++)
{
mz.Nodo(j+1,zf1,zn,zf2);
for (i = 0; i < DI; i++)
{
TrM(i,j);
Trm(i,j);
TzM(i,j);
Tzm(i,j);
Dvi(i,j);

diMj = dijM = 0.0;


dij= (1.0 / Bo.Calcula(xP[j][i])) * Bo.Derivada(xP[j][i]) + (1.0 / Uo.Calcula(xP[j][i])) * Uo.Derivada(xP[j][i]);
if (i <= DI-2) diMj = (1.0 / Bo.Calcula(xP[j][i+1])) * Bo.Derivada(xP[j][i+1]) + (1.0 / Uo.Calcula(xP[j][i+1])) *
Uo.Derivada(xP[j][i+1]);
if (j <= DZ-2) dijM = (1.0 / Bo.Calcula(xP[j+1][i])) * Bo.Derivada(xP[j+1][i]) + (1.0 / Uo.Calcula(xP[j+1][i])) *
Uo.Derivada(xP[j+1][i]);

// f
if (j > 0) A[i+DI*j][i+DI*(j-1)] = ztim + ztim * (xP[j][i] - xP[j-1][i] - (DR*(DH/(ldouble)DZ))) * dij;
// c
if (i > 0) A[i+DI*j][i+DI*j-1] = rtim + rtim * (xP[j][i] - xP[j][i-1]) * dij;
// a
a1 = a2 = a3 = a4 = 0.0;
if (i < DI-1) a1 = rtiM * (xP[j][i+1] - xP[j][i]) * diMj;
// Celdas abiertas a produccion
#ifndef TodosNodos
if (i == 0 && (j == 8 || j == 9 || j == 10))
{
for (xa = 0.0,k = 8; k < 11; k++)
{
TrM(i,k);
xa += rtiM;
}
TrM(i,j);
a2 = (rtiM / xa) * (-xQw * 8.364) * dij;
}
#else
if (i == 0)
{
for (xa = 0.0,k = 0; k < DZ; k++)
{
TrM(i,k);
xa += rtiM;
}
TrM(i,j);
a2 = (rtiM / xa) * (-xQw * 8.364) * dij;
}
#endif
if (i > 0) a2 = rtim * (xP[j][i] - xP[j][i-1]) * dij;
if (j < DZ-1) a3 = ztiM * (xP[j+1][i] - xP[j][i] - (DR*(DH/(ldouble)DZ))) * dij;
if (j > 0) a4 = ztim * (xP[j][i] - xP[j-1][i] - (DR*(DH/(ldouble)DZ))) * dij;
A[i+DI*j][i+DI*j] = -rtiM - rtim - a1 + a2 - ztiM - a3 - ztim + a4 - dvi;
// b
if (i < DI-1) A[i+DI*j][i+DI*j+1] = rtiM - rtiM * (xP[j][i+1] - xP[j][i]) * diMj;
// e
if (j < DZ-1) A[i+DI*j][i+DI*(j+1)] = ztiM - ztiM * (xP[j+1][i] - xP[j][i] - (DR*(DH/(ldouble)DZ))) * dijM;
}
}

// Genera b
for (j = 0; j < DZ; j++)
{
mz.Nodo(j+1,zf1,zn,zf2);
for (i = 0; i < DI; i++)
{
TrM(i,j);
Trm(i,j);
TzM(i,j);
Tzm(i,j);
Vi(i,j);

a1 = a2 = a3 = a4 = 0.0;
if (i < DI-1) a1 = rtiM * (xP[j][i+1] - xP[j][i]);
if (i > 0) a2 = rtim * (xP[j][i] - xP[j][i-1]);
if (j < DZ-1) a3 = ztiM * (xP[j+1][i] - xP[j][i] - (DR*(DH/(ldouble)DZ)));
if (j > 0) a4 = ztim * (xP[j][i] - xP[j-1][i] - (DR*(DH/(ldouble)DZ)));
// Celdas abiertas a produccion
#ifndef TodosNodos
if (i == 0 && (j == 8 || j == 9 || j == 10))
{
for (xa = 0.0,k = 8; k < 11; k++)
{
TrM(i,k);
xa += rtiM;
}
TrM(i,j);
a2 = (rtiM / xa) * (xQw * 8.364);
}
#else
if (i == 0)
{
for (xa = 0.0,k = 0; k < DZ; k++)
{
TrM(i,k);
xa += rtiM;
}
TrM(i,j);
a2 = (rtiM / xa) * (xQw * 8.364);
}
#endif
b[i+DI*j] = -(a1 - a2 + a3 - a4 - vi);
}
}

// Resolver Ax=b
rs.Resuelve(A,x,b,DI*DZ,ITR);

// Revisar aproximación
for (i = 0; i < DI*DZ; i++)
{
if (fabs(x[i]) > DE) xsw = 1;
}
// Actualiza las presiones calculadas
#ifndef TodosNodos
qw = xQw - fabs(x[9*DI]);
#else
qw = xQw - fabs(x[0]);
#endif
sw++;
if (sw >= 5) break;
}

// Actualizar las presiones


if (sw < 5) {
if (xQw == qw) qw -= 1e-10;
xQw = qw;
t += Dit;
if (sw <= 2) Dit *= 2.0;
if (Dit > 15.0) Dit = 15.0;
} else Dit /= 2.0;
} while (xQw > DQwm);
printf("\nTiempo %2.18e, incremento %2.18e\n",t,Dit);
printf("Gasto %2.18f\n",xQw);
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////

printf ("\n\nEsquema Linealización Directa\nI = %d, J = %d, Tol=%e\n\n",DI,DZ,DE);


// Condiciones iniciales
for (j = 0; j < DZ; j++)
{
a1 = DH / DZ;
a2 = (DH/DZ) / 2.0;
for (i = 0; i < DI; i++) P[j][i] = DPo + DR *(j*a1+a2 - DH/2.0 );
}
t = 0.0;
Dit = 1e-12;
xQw = DQw;

do
{
// Presion aproximada
for (j = 0; j < DZ; j++)
{
for (i = 0; i < DI; i++) xP[j][i] = P[j][i];
}
sw = 0, xsw = 1;
while (xsw)
{
xsw = 0;
// Genera A
// Celdas interiores de la discretizacion
for (j = 0; j < DZ; j++)
{
mz.Nodo(j+1,zf1,zn,zf2);
for (i = 0; i < DI; i++)
{
LDTrM(i,j);
LDTrm(i,j);
LDTzM(i,j);
LDTzm(i,j);
Dvi(i,j);

dij = diMj = dijM = 0.0;


//dij= (1.0 / Bo.Calcula(xP[j][i])) * Bo.Derivada(xP[j][i]) + (1.0 / Uo.Calcula(xP[j][i])) * Uo.Derivada(xP[j][i]);
//if (i <= DI-2) diMj = (1.0 / Bo.Calcula(xP[j][i+1])) * Bo.Derivada(xP[j][i+1]) + (1.0 / Uo.Calcula(xP[j][i+1])) *
Uo.Derivada(xP[j][i+1]);
//if (j <= DZ-2) dijM = (1.0 / Bo.Calcula(xP[j+1][i])) * Bo.Derivada(xP[j+1][i]) + (1.0 / Uo.Calcula(xP[j+1][i])) *
Uo.Derivada(xP[j+1][i]);

// f
if (j > 0) A[i+DI*j][i+DI*(j-1)] = ztim + ztim * (xP[j][i] - xP[j-1][i] - (DR*(DH/(ldouble)DZ))) * dij;
// c
if (i > 0) A[i+DI*j][i+DI*j-1] = rtim + rtim * (xP[j][i] - xP[j][i-1]) * dij;
// a
a1 = a2 = a3 = a4 = 0.0;
if (i < DI-1) a1 = rtiM * (xP[j][i+1] - xP[j][i]) * diMj;
// Celdas abiertas a produccion
#ifndef TodosNodos
if (i == 0 && (j == 8 || j == 9 || j == 10))
{
for (xa = 0.0,k = 8; k < 11; k++)
{
LDTrM(i,k);
xa += rtiM;
}
LDTrM(i,j);
a2 = (rtiM / xa) * (-xQw * 8.364) * dij;
}
#else
if (i == 0)
{
for (xa = 0.0,k = 0; k < DZ; k++)
{
LDTrM(i,k);
xa += rtiM;
}
LDTrM(i,j);
a2 = (rtiM / xa) * (-xQw * 8.364) * dij;
}
#endif
if (i > 0) a2 = rtim * (xP[j][i] - xP[j][i-1]) * dij;
if (j < DZ-1) a3 = ztiM * (xP[j+1][i] - xP[j][i] - (DR*(DH/(ldouble)DZ))) * dij;
if (j > 0) a4 = ztim * (xP[j][i] - xP[j-1][i] - (DR*(DH/(ldouble)DZ))) * dij;
A[i+DI*j][i+DI*j] = -rtiM - rtim - a1 + a2 - ztiM - a3 - ztim + a4 - dvi;
// b
if (i < DI-1) A[i+DI*j][i+DI*j+1] = rtiM - rtiM * (xP[j][i+1] - xP[j][i]) * diMj;
// e
if (j < DZ-1) A[i+DI*j][i+DI*(j+1)] = ztiM - ztiM * (xP[j+1][i] - xP[j][i] - (DR*(DH/(ldouble)DZ))) * dijM;
}
}

// Genera b
for (j = 0; j < DZ; j++)
{
mz.Nodo(j+1,zf1,zn,zf2);
for (i = 0; i < DI; i++)
{
LDTrM(i,j);
LDTrm(i,j);
LDTzM(i,j);
LDTzm(i,j);
Vi(i,j);

a1 = a2 = a3 = a4 = 0.0;
if (i < DI-1) a1 = rtiM * (xP[j][i+1] - xP[j][i]);
if (i > 0) a2 = rtim * (xP[j][i] - xP[j][i-1]);
if (j < DZ-1) a3 = ztiM * (xP[j+1][i] - xP[j][i] - (DR*(DH/(ldouble)DZ)));
if (j > 0) a4 = ztim * (xP[j][i] - xP[j-1][i] - (DR*(DH/(ldouble)DZ)));
// Celdas abiertas a produccion
#ifndef TodosNodos
if (i == 0 && (j == 8 || j == 9 || j == 10))
{
for (xa = 0.0,k = 8; k < 11; k++)
{
LDTrM(i,k);
xa += rtiM;
}
LDTrM(i,j);
a2 = (rtiM / xa) * (xQw * 8.364);
}
#else
if (i == 0)
{
for (xa = 0.0,k = 0; k < DZ; k++)
{
LDTrM(i,k);
xa += rtiM;
}
LDTrM(i,j);
a2 = (rtiM / xa) * (xQw * 8.364);
}
#endif
b[i+DI*j] = -(a1 - a2 + a3 - a4 - vi);
}
}

// Resolver Ax=b
rs.Resuelve(A,x,b,DI*DZ,ITR);

// Revisar aproximación
for (i = 0; i < DI*DZ; i++)
{
if (fabs(x[i]) > DE) xsw = 1;
}
// Actualiza las presiones calculadas
for (j = 0; j < DZ; j++)
{
for (i = 0; i < DI; i++) xP[j][i] = P[j][i] + x[j*DI+i];
}
sw++;
if (sw >= 5) break;
}

// Actualizar las presiones


if (sw < 5) {
sv = 0;
if (P[0][DI-1] >= (DPo-1e-6) && xP[0][DI-1] <= (DPo-1e-6)) sv = 1;
for (j = 0; j < DZ; j++)
{
for (i = 0; i < DI; i++) P[j][i] = xP[j][i];
}
t += Dit;
if (sw <= 2) Dit *= 2.0;
if (Dit > 15.0) Dit = 15.0;
// Calculo de presion de fondo
#ifndef TodosNodos
pwf = P[9][0];
#else
pwf = P[0][0];
#endif
if (pwf < 100.0 ) sv = 1;
if (sv)
{
printf("Tiempo %2.18e, incremento %2.18e\n",t,Dit);
printf("Presion fondo poso %2.18f\n",pwf);
printf("Matriz de Presiones\n");
m.Visualiza(xP,DZ,DI,0);
}
} else Dit /= 2.0;
} while (pwf > DPwfm);

////////////////////////////////////////////////////////////////////////////////////

// Presion aproximada
for (j = 0; j < DZ; j++)
{
for (i = 0; i < DI; i++) xP[j][i] = P[j][i];
}
Dit = 1e-12;
do
{
qw = xQw;
sw = 0, xsw = 1;
while (xsw)
{
xsw = 0;
// Genera A
// Celdas interiores de la discretizacion
for (j = 0; j < DZ; j++)
{
mz.Nodo(j+1,zf1,zn,zf2);
for (i = 0; i < DI; i++)
{
LDTrM(i,j);
LDTrm(i,j);
LDTzM(i,j);
LDTzm(i,j);
Dvi(i,j);

dij = diMj = dijM = 0.0;


//dij= (1.0 / Bo.Calcula(xP[j][i])) * Bo.Derivada(xP[j][i]) + (1.0 / Uo.Calcula(xP[j][i])) * Uo.Derivada(xP[j][i]);
//if (i <= DI-2) diMj = (1.0 / Bo.Calcula(xP[j][i+1])) * Bo.Derivada(xP[j][i+1]) + (1.0 / Uo.Calcula(xP[j][i+1])) *
Uo.Derivada(xP[j][i+1]);
//if (j <= DZ-2) dijM = (1.0 / Bo.Calcula(xP[j+1][i])) * Bo.Derivada(xP[j+1][i]) + (1.0 / Uo.Calcula(xP[j+1][i])) *
Uo.Derivada(xP[j+1][i]);

// f
if (j > 0) A[i+DI*j][i+DI*(j-1)] = ztim + ztim * (xP[j][i] - xP[j-1][i] - (DR*(DH/(ldouble)DZ))) * dij;
// c
if (i > 0) A[i+DI*j][i+DI*j-1] = rtim + rtim * (xP[j][i] - xP[j][i-1]) * dij;
// a
a1 = a2 = a3 = a4 = 0.0;
if (i < DI-1) a1 = rtiM * (xP[j][i+1] - xP[j][i]) * diMj;
// Celdas abiertas a produccion
#ifndef TodosNodos
if (i == 0 && (j == 8 || j == 9 || j == 10))
{
for (xa = 0.0,k = 8; k < 11; k++)
{
LDTrM(i,k);
xa += rtiM;
}
LDTrM(i,j);
a2 = (rtiM / xa) * (-xQw * 8.364) * dij;
}
#else
if (i == 0)
{
for (xa = 0.0,k = 0; k < DZ; k++)
{
LDTrM(i,k);
xa += rtiM;
}
LDTrM(i,j);
a2 = (rtiM / xa) * (-xQw * 8.364) * dij;
}
#endif
if (i > 0) a2 = rtim * (xP[j][i] - xP[j][i-1]) * dij;
if (j < DZ-1) a3 = ztiM * (xP[j+1][i] - xP[j][i] - (DR*(DH/(ldouble)DZ))) * dij;
if (j > 0) a4 = ztim * (xP[j][i] - xP[j-1][i] - (DR*(DH/(ldouble)DZ))) * dij;
A[i+DI*j][i+DI*j] = -rtiM - rtim - a1 + a2 - ztiM - a3 - ztim + a4 - dvi;
// b
if (i < DI-1) A[i+DI*j][i+DI*j+1] = rtiM - rtiM * (xP[j][i+1] - xP[j][i]) * diMj;
// e
if (j < DZ-1) A[i+DI*j][i+DI*(j+1)] = ztiM - ztiM * (xP[j+1][i] - xP[j][i] - (DR*(DH/(ldouble)DZ))) * dijM;
}
}

// Genera b
for (j = 0; j < DZ; j++)
{
mz.Nodo(j+1,zf1,zn,zf2);
for (i = 0; i < DI; i++)
{
LDTrM(i,j);
LDTrm(i,j);
LDTzM(i,j);
LDTzm(i,j);
Vi(i,j);

a1 = a2 = a3 = a4 = 0.0;
if (i < DI-1) a1 = rtiM * (xP[j][i+1] - xP[j][i]);
if (i > 0) a2 = rtim * (xP[j][i] - xP[j][i-1]);
if (j < DZ-1) a3 = ztiM * (xP[j+1][i] - xP[j][i] - (DR*(DH/(ldouble)DZ)));
if (j > 0) a4 = ztim * (xP[j][i] - xP[j-1][i] - (DR*(DH/(ldouble)DZ)));
// Celdas abiertas a produccion
#ifndef TodosNodos
if (i == 0 && (j == 8 || j == 9 || j == 10))
{
for (xa = 0.0,k = 8; k < 11; k++)
{
LDTrM(i,k);
xa += rtiM;
}
LDTrM(i,j);
a2 = (rtiM / xa) * (xQw * 8.364);
}
#else
if (i == 0)
{
for (xa = 0.0,k = 0; k < DZ; k++)
{
LDTrM(i,k);
xa += rtiM;
}
LDTrM(i,j);
a2 = (rtiM / xa) * (xQw * 8.364);
}
#endif
b[i+DI*j] = -(a1 - a2 + a3 - a4 - vi);
}
}

// Resolver Ax=b
rs.Resuelve(A,x,b,DI*DZ,ITR);

// Revisar aproximación
for (i = 0; i < DI*DZ; i++)
{
if (fabs(x[i]) > DE) xsw = 1;
}
// Actualiza las presiones calculadas
#ifndef TodosNodos
qw = xQw - fabs(x[9*DI]);
#else
qw = xQw - fabs(x[0]);
#endif
sw++;
if (sw >= 5) break;
}

// Actualizar las presiones


if (sw < 5) {
if (xQw == qw) qw -= 1e-10;
xQw = qw;
t += Dit;
if (sw <= 2) Dit *= 2.0;
if (Dit > 15.0) Dit = 15.0;
} else Dit /= 2.0;
} while (xQw > DQwm);
printf("\nTiempo %2.18e, incremento %2.18e\n",t,Dit);
printf("Gasto %2.18f\n",xQw);

////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////

// Libera la memoria
m.LiberaMemoria(A,DI*DZ,DI*DZ);
m.LiberaMemoria(AA,DI*DZ,DI*DZ);
m.LiberaMemoria(b,DI*DZ);
m.LiberaMemoria(x,DI*DZ);
m.LiberaMemoria(P,DZ,DI);
m.LiberaMemoria(xP,DZ,DI);

return 0;
}

Вам также может понравиться