Permeabilidades Relativas LET en Python: Aceite–Agua y Gas–Aceite

Dos conjuntos de curvas kr y el efecto de los parámetros L, E y T

Yacimientos
Petrofísica
Python
Calcula curvas de permeabilidad relativa LET para aceite–agua y gas–aceite en Python. Define saturaciones límite, valores de extremo y parámetros de forma, y explora su efecto con un ejemplo paso a paso.
Autor/a
Fecha de publicación

3 de octubre de 2026

Dos conjuntos de curvas de permeabilidad relativa

La permeabilidad relativa describe la capacidad de una fase para fluir en presencia de otras, respecto de una permeabilidad de referencia. Se expresa como una razón adimensional:

\[ k_{r\alpha}=\frac{k_{\mathrm{efectiva},\alpha}}{k_{\mathrm{referencia}}} \]

En este ejemplo construiremos curvas LET para aceite–agua y gas–aceite. Definiremos sus extremos, calcularemos kr en Python y veremos cómo cambia la forma de las curvas al variar sus parámetros.

Usaremos parámetros ilustrativos, elegidos para practicar. No representan mediciones de laboratorio ni un ajuste para una roca específica. Todas las saturaciones se introducen como fracción, entre 0 y 1.

Visita el canal @rigopetrodata

Tutoriales de R, Python y Excel para ingeniería petrolera

Ver canal

La función LET

Lomeland, Ebeltoft y Thomas presentaron la correlación en A New Versatile Relative Permeability Correlation, SCA2005-32. La formulación emplea tres parámetros empíricos de forma por curva, además de las saturaciones límite y el valor de extremo.

Podemos escribir la función normalizada como:

\[ F(s;L,E,T)=\frac{s^L}{s^L+E(1-s)^T},\qquad 0\leq s\leq1 \]

En el ejemplo elegimos L, E y T positivos. Así, F(0) = 0 y F(1) = 1. Al multiplicar F por el valor de extremo, obtenemos la curva kr de la fase correspondiente.

Los parámetros tienen efectos relacionados: L controla principalmente la parte baja, T la parte alta y E desplaza la transición. Son parámetros de ajuste, no propiedades que se midan directamente como la porosidad. Al final veremos su efecto variando uno a la vez.

1. Preparar Python

Necesitamos NumPy, pandas y Matplotlib. Si hace falta instalarlos, ejecuta pip install numpy pandas matplotlib en la terminal. Ejecuta los fragmentos en orden dentro de la misma sesión o cuaderno.

Ver código
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

def let(s, L, E, T):
    return s**L / (s**L + E * (1 - s)**T)

Evaluaremos la función únicamente dentro del intervalo normalizado [0, 1]. Para usar otros datos, revisa primero que las saturaciones pertenezcan al intervalo de cada sistema.

2. Sistema aceite–agua

Consideramos un desplazamiento con saturación de agua creciente. No hay gas, de modo que So = 1 − Sw. Distinguimos Sorw, el aceite residual al desplazamiento con agua.

La saturación normalizada es:

\[ S_{wn}=\frac{S_w-S_{wi}}{1-S_{wi}-S_{orw}} \]

Y las curvas se calculan mediante:

\[ k_{rw}=k_{rw}^{\mathrm{fin}}F(S_{wn};L_w,E_w,T_w) \]

\[ k_{row}=k_{row}^{\mathrm{ini}}F(1-S_{wn};L_{ow},E_{ow},T_{ow}) \]

Usamos krow para identificar la permeabilidad relativa del aceite en el sistema aceite–agua. Los superíndices ini y fin indican los extremos de este desplazamiento.

Parámetro Valor del ejemplo
Agua inicial, Swi 0.20
Aceite residual al agua, Sorw 0.25
krw final, a Sw = 1 − Sorw 0.35
krow inicial, a Sw = Swi 0.80
Lw, Ew, Tw 2.0, 3.0, 2.0
Low, Eow, Tow 2.0, 1.5, 2.0

El intervalo de Sw va de 0.20 a 0.75. Su amplitud es 0.55, por lo que el denominador de la normalización es positivo.

Ver código
Swi, Sorw = 0.20, 0.25
krw_fin, krow_ini = 0.35, 0.80
Lw, Ew, Tw = 2.0, 3.0, 2.0
Low, Eow, Tow = 2.0, 1.5, 2.0

Sw = np.linspace(Swi, 1 - Sorw, 101)
Swn = (Sw - Swi) / (1 - Swi - Sorw)

krw = krw_fin * let(Swn, Lw, Ew, Tw)
krow = krow_ini * let(1 - Swn, Low, Eow, Tow)

agua_aceite = pd.DataFrame({"Sw": Sw, "krw": krw, "krow": krow})
agua_aceite.iloc[[0, 50, 100]].round(4)
Sw krw krow
0 0.200 0.0000 0.80
50 0.475 0.0875 0.32
100 0.750 0.3500 0.00

En Sw = 0.20, krw = 0 y krow = 0.80. Al llegar a Sw = 0.75, krw = 0.35 y krow = 0. Estos valores son los extremos que fijamos, no resultados de un ajuste automático.

3. Graficar krw y krow

Ver código
plt.figure(figsize=(8, 4.5))
plt.plot(Sw, krw, label="Agua: krw")
plt.plot(Sw, krow, label="Aceite: krow")
plt.xlabel("Saturación de agua, Sw (fracción)")
plt.ylabel("Permeabilidad relativa, kr")
plt.ylim(0, 1)
plt.grid(alpha=0.3)
plt.legend()
plt.tight_layout()
plt.show()
Figura 1: Curvas LET ilustrativas para agua y aceite, con saturación de agua creciente.

La curva del agua aumenta y la del aceite disminuye. El cruce de ambas significa igualdad de kr, pero no necesariamente igualdad de movilidad: la movilidad de cada fase depende también de su viscosidad, mediante kr/μ.

🛒
Propiedades De Los Fluidos Del Yacimiento

Disponible en Mercado Libre

Ver oferta →

4. Sistema gas–aceite

Ahora consideramos un desplazamiento con saturación de gas creciente y agua inmóvil fija en Swi = 0.20. En este conjunto So = 1 − Swi − Sg. El aceite residual al gas, Sorg, puede diferir del aceite residual al agua.

Para este ejemplo tomamos saturación crítica de gas Sgc = 0. La normalización es:

\[ S_{gn}=\frac{S_g}{1-S_{wi}-S_{org}} \]

Las curvas correspondientes son:

\[ k_{rg}=k_{rg}^{\mathrm{fin}}F(S_{gn};L_g,E_g,T_g) \]

\[ k_{rog}=k_{rog}^{\mathrm{ini}}F(1-S_{gn};L_{og},E_{og},T_{og}) \]

krog identifica al aceite en el sistema gas–aceite. Esta normalización corresponde al caso sin umbral positivo de movilidad del gas. Si se necesita Sgc > 0, se debe definir cómo comienza el flujo del gas y ajustar los intervalos de las curvas.

Parámetro Valor del ejemplo
Agua inmóvil, Swi 0.20
Aceite residual al gas, Sorg 0.15
krg final, a Sg = 1 − Swi − Sorg 0.85
krog inicial, a Sg = 0 0.80
Lg, Eg, Tg 1.5, 1.0, 2.0
Log, Eog, Tog 3.0, 2.0, 1.5

Sg varía de 0 a 0.65. En el extremo final, Sg + Swi + Sorg = 1. Conservamos el mismo kr inicial de aceite en ambos conjuntos, correspondiente al estado inicial con Swi = 0.20 y sin gas, usando una misma permeabilidad de referencia.

Ver código
Sorg = 0.15
krg_fin, krog_ini = 0.85, 0.80
Lg, Eg, Tg = 1.5, 1.0, 2.0
Log, Eog, Tog = 3.0, 2.0, 1.5

Sg = np.linspace(0, 1 - Swi - Sorg, 101)
Sgn = Sg / (1 - Swi - Sorg)

krg = krg_fin * let(Sgn, Lg, Eg, Tg)
krog = krog_ini * let(1 - Sgn, Log, Eog, Tog)

gas_aceite = pd.DataFrame({"Sg": Sg, "krg": krg, "krog": krog})
gas_aceite.iloc[[0, 50, 100]].round(4)
Sg krg krog
0 0.000 0.0000 0.8000
50 0.325 0.4979 0.1202
100 0.650 0.8500 0.0000

5. Graficar krg y krog

Ver código
plt.figure(figsize=(8, 4.5))
plt.plot(Sg, krg, label="Gas: krg")
plt.plot(Sg, krog, label="Aceite: krog")
plt.xlabel("Saturación de gas, Sg (fracción)")
plt.ylabel("Permeabilidad relativa, kr")
plt.ylim(0, 1)
plt.grid(alpha=0.3)
plt.legend()
plt.tight_layout()
plt.show()
Figura 2: Curvas LET ilustrativas para gas y aceite, con agua inmóvil y Sgc = 0.

En Sg = 0 obtenemos krg = 0 y krog = 0.80. En Sg = 0.65, krg = 0.85 y krog = 0. La diferencia entre este gráfico y el anterior proviene tanto de sus saturaciones límite como de los valores de extremo y parámetros de forma.

Estos son dos conjuntos bifásicos. Para describir agua, aceite y gas móviles simultáneamente se necesita un modelo de tres fases. Tampoco incluimos ciclos de histéresis en este ejemplo.

6. ¿Cómo influyen L, E y T?

Para separar los efectos, utilizaremos una curva normalizada con extremo igual a 1 y parámetros base L = 2, E = 1 y T = 2. En cada panel cambiaremos un solo parámetro, dejando los otros dos fijos.

Ver código
s = np.linspace(0, 1, 101)
base = {"L": 2.0, "E": 1.0, "T": 2.0}
variaciones = {"L": [1, 2, 4], "E": [0.5, 1, 3], "T": [1, 2, 4]}

fig, axes = plt.subplots(1, 3, figsize=(12, 4), sharey=True)
for ax, (nombre, valores) in zip(axes, variaciones.items()):
    for valor in valores:
        parametros = base.copy()
        parametros[nombre] = valor
        ax.plot(s, let(s, **parametros), label=f"{nombre} = {valor}")
    ax.set_xlabel("Saturación normalizada, s")
    ax.set_title(f"Variación de {nombre}")
    ax.grid(alpha=0.3)
    ax.legend()

axes[0].set_ylabel("kr normalizada")
plt.tight_layout()
plt.show()
Figura 3: Sensibilidad de la función LET normalizada, variando un parámetro a la vez.

Para la función creciente F(s), a una saturación interior fija y con los demás parámetros constantes:

  • Aumentar L reduce F(s), retrasando su crecimiento.
  • Aumentar E también reduce F(s) y desplaza la transición hacia saturaciones mayores.
  • Aumentar T eleva F(s), haciendo que se acerque antes al extremo superior.

Los extremos permanecen en 0 y 1. En las curvas de aceite el argumento es 1 − Swn o 1 − Sgn, por lo que debemos tener en cuenta esa inversión al interpretar el eje de saturación de agua o gas.

Qué revisar al construir un conjunto kr

Antes de cambiar L, E y T, define el proceso de desplazamiento, las saturaciones límite y los valores de extremo. Verifica también que todas las permeabilidades relativas utilicen una base de referencia coherente.

En estos ejemplos, las curvas quedan entre cero y su extremo y cambian de forma monótona. Las kr no tienen que sumar uno: cada fase tiene su propia relación entre saturación y capacidad de flujo.

Para representar una roca real, los parámetros deben calibrarse con información SCAL y con el proceso de desplazamiento correspondiente. Los valores de este post permiten aprender el cálculo y explorar la forma de las curvas.

Referencia

Lomeland, F., Ebeltoft, E. y Thomas, W. H. (2005). A New Versatile Relative Permeability Correlation. SCA2005-32. International Symposium of the Society of Core Analysts, Toronto, Canadá, 21–25 de agosto. Consultar el artículo. Ecuaciones bifásicas en los apéndices A y B.