Core Module

yaeos Python API core module.

ArModel and GeModel abstract classes definition. Also, the implementation of the models’ thermoprops methods.

adjust_root_kind(number_of_phases, kinds_x=None, kind_w=None)[source]

Convert the the kinds of each phase to the corresponding value.

The C interface of yaeos expects the kinds of each phase to be defined as integer values, so this function converts the kinds of each phase to the corresponding integer value. If the kind is not specified, it defaults to “stable” for all phases.

Parameters:
  • number_of_phases (int) – Number of phases in the system, besides de reference phase

  • kinds_x (list, optional) – Kinds of the phases in the system, by default None

  • kind_w (str, optional) – Kind of the test phase, by default None

Returns:

kinds_x_outlist

List of kinds for each phase in the system

kind_w_outstr

Kind of the test phase

Return type:

tuple

class GeModel[source]

Bases: ABC

Excess Gibbs (Ge) model abstract class.

ln_gamma(moles, temperature: float, dt: bool = False, dn: bool = False) ndarray | tuple[ndarray, dict][source]

Calculate natural logarithm of activity coefficients.

Calculate \(\ln \gamma_i(n,T)\) vector.

Parameters:
  • moles (array_like) – Moles number vector [mol]

  • temperature (float) – Temperature [K]

Returns:

\(ln \gamma_i(n,T)\) vector

Return type:

np.ndarray

Example

import numpy as np

from yaeos import NRTL

a = np.array([[0, 0.3], [0.3, 0]])
b = np.array([[0, 0.4], [0.4, 0]])
c = np.array([[0, 0.5], [0.5, 0]])

nrtl = NRTL(a, b, c)

# Evaluating ln_gamma only
print(nrtl.ln_gamma([5.0, 5.6], 300.0))

# Asking for derivatives

print(nrtl.ln_gamma([5.0, 5.6], 300.0, dt=True, dn=True))
excess_gibbs(moles, temperature: float, dt: bool = False, dt2: bool = False, dn: bool = False, dtn: bool = False, dn2: bool = False) ndarray | tuple[ndarray, dict][source]

Calculate excess Gibbs energy [bar L].

Parameters:
  • moles (array_like) – Moles number vector [mol]

  • temperature (float) – Temperature [K]

  • dt (bool, optional) – Calculate temperature derivative, by default False

  • dt2 (bool, optional) – Calculate temperature second derivative, by default False

  • dn (bool, optional) – Calculate moles derivative, by default False

  • dtn (bool, optional) – Calculate cross temperature and moles derivative, by default False

  • dn2 (bool, optional) – Calculate moles second derivative, by default False

Returns:

Excess Gibbs energy or tuple with excess Gibbs energy and derivatives dictionary if any derivative is asked [bar L]

Return type:

Union[np.ndarray, tuple[np.ndarray, dict]]

Example

from yaeos import UNIFACVLE

# Ethanol - water system
groups = [{1: 2, 2: 1, 14: 1}, {16: 1}]

model = UNIFACVLE(groups)

# Evaluating excess Gibbs energy only
print(model.excess_gibbs(model.excess_gibbs([0.5,0.5], 303.15))

# Asking for derivatives
print(
    model.excess_gibbs(
        [0.5,0.5],
        303.15,
        dt=True,
        dt2=True,
        dn=True,
        dtn=True,
        dn2=True
)
excess_enthalpy(moles, temperature: float, dt: bool = False, dn: bool = False) ndarray | tuple[ndarray, dict][source]

Calculate excess enthalpy [bar L].

Parameters:
  • moles (array_like) – Moles number vector [mol]

  • temperature (float) – Temperature [K]

  • dt (bool, optional) – Calculate temperature derivative, by default False

  • dn (bool, optional) – Calculate moles derivative, by default False

Returns:

Excess enthalpy or tuple with excess enthalpy and derivatives dictionary if any derivative is asked [bar L]

Return type:

Union[np.ndarray, tuple[np.ndarray, dict]]

Example

from yaeos import UNIFACVLE

# Ethanol - water system
groups = [{1: 2, 2: 1, 14: 1}, {16: 1}]

model = UNIFACVLE(groups)

# Evaluating excess enthalpy only
print(model.excess_enthalpy([0.5, 0.5], 303.15))

# Asking for derivatives
print(model.excess_enthalpy([0.5, 0.5], 303.15, dt=True, dn=True))
excess_entropy(moles, temperature: float, dt: bool = False, dn: bool = False) ndarray | tuple[ndarray, dict][source]

Calculate excess entropy [bar L / K].

Parameters:
  • moles (array_like) – Moles number vector [mol]

  • temperature (float) – Temperature [K]

  • dt (bool, optional) – Calculate temperature derivative, by default False

  • dn (bool, optional) – Calculate moles derivative, by default False

Returns:

Excess entropy or tuple with excess entropy and derivatives dictionary if any derivative is asked [bar L / K]

Return type:

Union[np.ndarray, tuple[np.ndarray, dict]]

Example

from yaeos import UNIFACVLE

# Ethanol - water system
groups = [{1: 2, 2: 1, 14: 1}, {16: 1}]

model = UNIFACVLE(groups)

# Evaluating excess entropy only
print(model.excess_entropy([0.5, 0.5], 303.15))

# Asking for derivatives
print(model.excess_entropy([0.5, 0.5], 303.15, dt=True, dn=True))
stability_analysis(z, temperature)[source]

Perform stability analysis.

Find all the possible minima values that the \(tm\) function, defined by Michelsen and Mollerup.

Parameters:
  • z (array_like) – Global mole fractions

  • temperature (float) – Temperature [K]

Returns:

  • dict – Stability analysis result dictionary with keys: - w: value of the test phase that minimizes the \(tm\) function - tm: minimum value of the \(tm\) function.

  • dict – All found minimum values of the \(tm\) function and the corresponding test phase mole fractions. - w: all values of \(w\) that minimize the \(tm\) function - tm: all values found minima of the \(tm\) function

flash_t(z, temperature: float, k0=None) dict[source]

Two-phase split with specification of temperature and pressure.

Parameters:
  • z (array_like) – Global mole fractions

  • temperature (float) – Temperature [K]

  • k0 (array_like, optional) – Initial guess for the split, by default None (will use k_wilson)

Returns:

Flash result dictionary with keys:
  • x: heavy phase mole fractions

  • y: light phase mole fractions

  • Vx: heavy phase volume [L]

  • Vy: light phase volume [L]

  • T: temperature [K]

  • beta: light phase fraction

Return type:

dict

class ArModel[source]

Bases: ABC

Residual Helmholtz (Ar) model abstract class.

lnphi_vt(moles, volume: float, temperature: float, dt: bool = False, dp: bool = False, dn: bool = False) ndarray | tuple[ndarray, dict][source]

Calculate fugacity coefficent given volume and temperature.

Calculate \(ln \phi_i(n,V,T)\) and its derivatives with respect to temperature, pressure and moles number.

Parameters:
  • moles (array_like) – Moles number vector [mol]

  • volume (float) – Volume [L]

  • temperature (float) – Temperature [K]

  • dt (bool, optional) – Calculate temperature derivative, by default False

  • dp (bool, optional) – Calculate pressure derivative, by default False

  • dn (bool, optional) – Calculate moles derivative, by default False

Returns:

\(ln \phi_i(n,V,T)\) vector or tuple with \(ln \phi_i(n,V,T)\) vector and derivatives dictionary if any derivative is asked

Return type:

Union[np.ndarray, tuple[np.ndarray, dict]]

Example

import numpy as np

from yaeos import PengRobinson76

tc = np.array([320.0, 375.0])   # critical temperatures [K]
pc = np.array([45.0, 60.0])     # critical pressures [bar]
w = np.array([0.0123, 0.045])   # acentric factors

model = PengRobinson76(tc, pc, w)

# Evaluating ln_phi only
# will print: [-1.45216274 -2.01044828]

print(model.lnphi_vt([5.0, 5.6], 1.0, 300.0))

# Asking for derivatives
# will print:
# (
# array([-1.45216274, -2.01044828]),
# {'dt': array([0.01400063, 0.01923493]), 'dp': None, 'dn': None}
# )

print(model.lnphi_vt([5.0, 5.6], 1.0, 300.0, dt=True)
lnphi_pt(moles, pressure: float, temperature: float, root: str = 'stable', dt: bool = False, dp: bool = False, dn: bool = False) ndarray | tuple[ndarray, dict][source]

Calculate fugacity coefficent given pressure and temperature.

Calculate \(ln \phi_i(n,P,T)\) and its derivatives with respect to temperature, pressure and moles number.

Parameters:
  • moles (array_like) – Moles number vector [mol]

  • pressure (float) – Pressure [bar]

  • temperature (float) – Temperature [K]

  • root (str, optional) – Volume root, use: “liquid”, “vapor” or “stable”, by default “stable”

  • dt (bool, optional) – Calculate temperature derivative, by default False

  • dp (bool, optional) – Calculate pressure derivative, by default False

  • dn (bool, optional) – Calculate moles derivative, by default False

Returns:

\(ln \phi_i(n,P,T)\) vector or tuple with \(ln \phi_i(n,P,T)\) vector and derivatives dictionary if any derivative is asked

Return type:

Union[np.ndarray, tuple[np.ndarray, dict]]

Example

import numpy as np

from yaeos import PengRobinson76

tc = np.array([320.0, 375.0])   # critical temperatures [K]
pc = np.array([45.0, 60.0])     # critical pressures [bar]
w = np.array([0.0123, 0.045])   # acentric factors

model = PengRobinson76(tc, pc, w)

# Evaluating ln_phi only
# will print: [-0.10288733 -0.11909807]

print(model.lnphi_pt([5.0, 5.6], 10.0, 300.0))

# Asking for derivatives
# will print:
# (
# array([-0.10288733, -0.11909807]),
# {'dt': array([0.00094892, 0.00108809]), 'dp': None, 'dn': None}
# )

print(model.lnphi_pt([5.0, 5.6], 10.0, 300.0, dt=True)
pressure(moles, volume: float, temperature: float, dv: bool = False, dt: bool = False, dn: bool = False) float | tuple[float, dict][source]

Calculate pressure given volume and temperature [bar].

Calculate \(P(n,V,T)\) and its derivatives with respect to volume, temperature and moles number.

Parameters:
  • moles (array_like) – Moles number vector [mol]

  • volume (float) – Volume [L]

  • temperature (float) – Temperature [K]

  • dv (bool, optional) – Calculate volume derivative, by default False

  • dt (bool, optional) – Calculate temperature derivative, by default False

  • dn (bool, optional) – Calculate moles derivative, by default False

Returns:

Pressure or tuple with Presure and derivatives dictionary if any derivative is asked [bar]

Return type:

Union[float, tuple[float, dict]]

Example

import numpy as np

from yaeos import PengRobinson76

tc = np.array([320.0, 375.0])   # critical temperatures [K]
pc = np.array([45.0, 60.0])     # critical pressures [bar]
w = np.array([0.0123, 0.045])   # acentric factors

model = PengRobinson76(tc, pc, w)

# Evaluating pressure only
# will print: 16.011985733846956

print(model.pressure(np.array([5.0, 5.6]), 2.0, 300.0))

# Asking for derivatives
# will print:
# (
# 16.011985733846956,
# {'dv': None, 'dt': np.float64(0.7664672352866752), 'dn': None}
# )

print(model.pressure(np.array([5.0, 5.6]), 2.0, 300.0, dt=True))
volume(moles, pressure: float, temperature: float, root: str = 'stable') float[source]

Calculate volume given pressure and temperature [L].

Parameters:
  • moles (array_like) – Moles number vector [mol]

  • pressure (float) – Pressure [bar]

  • temperature (float) – Temperature [K]

  • root (str, optional) – Volume root, use: “liquid”, “vapor” or “stable”, by default “stable”

Returns:

Volume [L]

Return type:

float

Example

import numpy as np

from yaeos import PengRobinson76

tc = np.array([320.0, 375.0])   # critical temperatures [K]
pc = np.array([45.0, 60.0])     # critical pressures [bar]
w = np.array([0.0123, 0.045])   # acentric factors

model = PengRobinson76(tc, pc, w)

# Evaluating stable root volume
# will print: 23.373902973572587

print(model.volume(np.array([5.0, 5.6]), 10.0, 300.0))

# Liquid root volume (not stable)
# will print: 0.8156388756398074

print(model.volume(np.array([5.0, 5.6]), 10.0, 300.0, "liquid"))
enthalpy_residual_vt(moles, volume: float, temperature: float, dt: bool = False, dv: bool = False, dn: bool = False) float | tuple[float, dict][source]

Calculate residual enthalpy given volume and temperature [bar L].

Parameters:
  • moles (array_like) – Moles number vector [mol]

  • volume (float) – Volume [L]

  • temperature (float) – Temperature [K]

Returns:

Residual enthalpy or tuple with Residual enthalpy and derivatives dictionary if any derivative is asked [bar L]

Return type:

Union[float, tuple[float, dict]]

Example

import numpy as np

from yaeos import PengRobinson76

tc = np.array([320.0, 375.0])   # critical temperatures [K]
pc = np.array([45.0, 60.0])     # critical pressures [bar]
w = np.array([0.0123, 0.045])   # acentric factors

model = PengRobinson76(tc, pc, w)

# Evaluating residual enthalpy only
# will print: -182.50424367123696

print(
    model.enthalpy_residual_vt(np.array([5.0, 5.6]), 10.0, 300.0)
)

# Asking for derivatives
# will print:
# (
# -182.50424367123696,
# {'dt': 0.21542452742588686, 'dv': None, 'dn': None}
# )

print(
    model.enthalpy_residual_vt(
        np.array([5.0, 5.6]),
        10.0,
        300.0,
        dt=True)
    )
)
gibbs_residual_vt(moles, volume: float, temperature: float, dt: bool = False, dv: bool = False, dn: bool = False) float | tuple[float, dict][source]

Calculate residual Gibbs energy at volume and temperature [bar L].

Parameters:
  • moles (array_like) – Moles number vector [mol]

  • volume (float) – Volume [L]

  • temperature (float) – Temperature [K]

Returns:

Residual Gibbs energy or tuple with Residual Gibbs energy and derivatives dictionary if any derivative is asked [bar L]

Return type:

Union[float, tuple[float, dict]]

Example

import numpy as np

from yaeos import PengRobinson76

tc = np.array([320.0, 375.0])   # critical temperatures [K]
pc = np.array([45.0, 60.0])     # critical pressures [bar]
w = np.array([0.0123, 0.045])   # acentric factors

model = PengRobinson76(tc, pc, w)

# Evaluating residual gibbs energy only
# will print: -138.60374582274

print(model.gibbs_residual_vt(np.array([5.0, 5.6]), 10.0, 300.0))

# Asking for derivatives
# will print:
# (
# -138.60374582274,
# {'dt': 0.289312908265414, 'dv': None, 'dn': None}
# )

print(
    model.gibbs_residual_vt(
        np.array([5.0, 5.6]),
        10.0,
        300.0,
        dt=True
    )
)
entropy_residual_vt(moles, volume: float, temperature: float, dt: bool = False, dv: bool = False, dn: bool = False) float | tuple[float, dict][source]

Calculate residual entropy given volume and temperature [bar L / K].

Parameters:
  • moles (array_like) – Moles number vector [mol]

  • volume (float) – Volume [L]

  • temperature (float) – Temperature [K]

Returns:

Residual entropy or tuple with Residual entropy and derivatives dictionary if any derivative is asked [bar L]

Return type:

Union[float, tuple[float, dict]]

Example

import numpy as np

from yaeos import PengRobinson76

tc = np.array([320.0, 375.0])   # critical temperatures [K]
pc = np.array([45.0, 60.0])     # critical pressures [bar]
w = np.array([0.0123, 0.045])   # acentric factors

model = PengRobinson76(tc, pc, w)

# Evaluating residual entropy only
# will print: -0.1463349928283233

print(model.entropy_residual_vt(np.array([5.0, 5.6]), 10.0, 300.0))

# Asking for derivatives
# will print:
# (
# (-0.1463349928283233,
# {'dt': 0.00024148870662932045, 'dv': None, 'dn': None})
# )

print(
    model.entropy_residual_vt(
        np.array([5.0, 5.6]),
        10.0,
        300.0,
        dt=True
    )
)
cv_residual_vt(moles, volume: float, temperature: float) float[source]

Residual isochoric heat capacity given V and T [bar L / K].

Parameters:
  • moles (array_like) – Moles number vector [mol]

  • volume (float) – Volume [L]

  • temperature (float) – Temperature [K]

Returns:

Residual isochoric heat capacity [bar L / K]

Return type:

float

Example


import numpy as np

from yaeos import PengRobinson76

tc = np.array([320.0, 375.0]) # critical temperatures [K] pc = np.array([45.0, 60.0]) # critical pressures [bar] w = np.array([0.0123, 0.045]) # acentric factors

model = PengRobinson76(tc, pc, w)

# Evaluating residual isochoric heat capacity only # will print: 0.07244661198879614

print(model.cv_residual_vt(np.array([5.0, 5.6]), 10.0, 300.0))

cp_residual_vt(moles, volume: float, temperature: float) float[source]

Calculate residual isobaric heat capacity given V and T [bar L / K].

Parameters:
  • moles (array_like) – Moles number vector [mol]

  • volume (float) – Volume [L]

  • temperature (float) – Temperature [K]

Returns:

Residual isochoric heat capacity [bar L / K]

Return type:

float

Example

import numpy as np

from yaeos import PengRobinson76

tc = np.array([320.0, 375.0])   # critical temperatures [K]
pc = np.array([45.0, 60.0])     # critical pressures [bar]
w = np.array([0.0123, 0.045])   # acentric factors

model = PengRobinson76(tc, pc, w)

# Evaluating residual isobaric heat capacity only
# will print: 1.4964025088916886

print(model.cp_residual_vt(np.array([5.0, 5.6]), 10.0, 300.0))
pure_saturation_pressures(component, stop_pressure=0.01, stop_temperature=100)[source]

Calculate pure component saturation pressures [bar].

Calculation starts from the critical point and goes down to the stop pressure or stop temperature.

Parameters:
  • component (int) – Component index (starting from 1)

  • stop_pressure (float, optional) – Stop pressure [bar], by default 0.01

  • stop_temperature (float, optional) – Stop temperature [K], by default 100

Returns:

Pure component saturation points dictionary with keys:
  • T: Temperature [K]

  • P: Pressure [bar]

  • Vx: Liquid Phase Volume [L/mole]

  • Vy: Vapor Phase Volume [L/mole]

Return type:

dict

Example

import numpy as np

from yaeos import PengRobinson76

tc = np.array([320.0, 375.0])
pc = np.array([45.0, 60.0])
w = np.array([0.0123, 0.045])

model = PengRobinson76(tc, pc, w)
flash_pt(z, pressure: float, temperature: float, k0=None) dict[source]

Two-phase split with specification of temperature and pressure.

Parameters:
  • z (array_like) – Global mole fractions

  • pressure (float) – Pressure [bar]

  • temperature (float) – Temperature [K]

  • k0 (array_like, optional) – Initial guess for the split, by default None (will use k_wilson)

Returns:

Flash result dictionary with keys:
  • x: heavy phase mole fractions

  • y: light phase mole fractions

  • Vx: heavy phase volume [L]

  • Vy: light phase volume [L]

  • P: pressure [bar]

  • T: temperature [K]

  • beta: light phase fraction. If beta is -1 flash was not

successful.

Return type:

dict

Example

import numpy as np

from yaeos import PengRobinson76

tc = np.array([369.83, 507.6])       # critical temperatures [K]
pc = np.array([42.48, 30.25])        # critical pressures [bar]
w = np.array([0.152291, 0.301261])   # acentric factors

model = PengRobinson76(tc, pc, w)

# Flash calculation
# will print:
# {
#   'x': array([0.3008742, 0.6991258]),
#   'y': array([0.85437317, 0.14562683]),
#   'Vx': 0.12742569165483714,
#   'Vy': 3.218831515959867,
#   'P': 8.0,
#   'T': 350.0,
#   'beta': 0.35975821044266726
# }

print(model.flash_pt([0.5, 0.5], 8.0, 350.0))
flash_vt(z, volume: float, temperature: float, k0=None) dict[source]

Two-phase split with specification of temperature and volume.

Parameters:
  • z (array_like) – Global mole fractions

  • volume (float) – Molar volume [L/mol]

  • temperature (float) – Temperature [K]

  • k0 (array_like, optional) – Initial guess for the split, by default None (will use k_wilson)

Returns:

Flash result dictionary with keys:
  • x: heavy phase mole fractions

  • y: light phase mole fractions

  • Vx: heavy phase molar volume [L/mol]

  • Vy: light phase molar volume [L/mol]

  • P: pressure [bar]

  • T: temperature [K]

  • beta: light phase fraction. If beta is -1 flash was not

successful.

Return type:

dict

Example

import numpy as np

from yaeos import PengRobinson76

tc = np.array([507.6, 658.0])        # critical temperatures [K]
pc = np.array([30.25, 18.20])        # critical pressures [bar]
w = np.array([0.301261, 0.576385])   # acentric factors

model = PengRobinson76(tc, pc, w)

# Flash calculation
# will print:
# {
#     'x': array([0.26308567, 0.73691433]),
#     'y': array([0.95858707, 0.04141293]),
#     'Vx': 0.2417828483590114,
#     'Vy': 31.706890870110417,
#     'P': 1.0001131874567775,
#     'T': 393.15,
#     'beta': 0.34063818069513246
# }

print(model.flash_vt([0.5, 0.5], 10.96, 393.15))
flash_pt_grid(z, pressures, temperatures, parallel=False) dict[source]

Two-phase split with specification of temperature and pressure grid.

Parameters:
  • z (array_like) – Global mole fractions

  • pressures (array_like) – Pressures grid [bar]

  • temperatures (array_like) – Temperatures grid [K]

  • parallel (bool, optional) – Use parallel processing, by default False

Returns:

Flash grid result dictionary with keys:
  • x: heavy phase mole fractions

  • y: light phase mole fractions

  • Vx: heavy phase volume [L]

  • Vy: light phase volume [L]

  • P: pressure [bar]

  • T: temperature [K]

  • beta: light phase fraction

Return type:

dict

Example

import numpy as np

from yaeos import PengRobinson76

tc = np.array([369.83, 507.6])       # critical temperatures [K]
pc = np.array([42.48, 30.25])        # critical pressures [bar]
w = np.array([0.152291, 0.301261])

temperatures = [350.0, 360.0, 400.0]
pressures = [10, 20, 30]
saturation_pressure(z, temperature: float, kind: str = 'bubble', p0: float = 0, y0=None) dict[source]

Saturation pressure at specified temperature.

Parameters:
  • z (array_like) – Global molar fractions

  • temperature (float) – Temperature [K]

  • kind (str, optional) –

    Kind of saturation point, defaults to “bubble”. Options are
    • ”bubble”

    • ”dew”

    • ”liquid-liquid”

  • p0 (float, optional) – Initial guess for pressure [bar]

  • y0 (array_like, optional) – Initial guess for the incipient phase, by default None (will use k_wilson correlation)

Returns:

Saturation pressure calculation result dictionary with keys:
  • x: heavy phase mole fractions

  • y: light phase mole fractions

  • Vx: heavy phase volume [L]

  • Vy: light phase volume [L]

  • P: pressure [bar]

  • T: temperature [K]

  • beta: light phase fraction

Return type:

dict

Example

import numpy as np

from yaeos import PengRobinson76

tc = np.array([369.83, 507.6])       # critical temperatures [K]
pc = np.array([42.48, 30.25])        # critical pressures [bar]
w = np.array([0.152291, 0.301261])   # acentric factors

model = PengRobinson76(tc, pc, w)

# Saturation pressure calculation
# will print:
# {
# 'x': array([0.5, 0.5]),
# 'y': array([0.9210035 , 0.07899651]),
# 'Vx': 0.11974125553488875,
# 'Vy': 1.849650524323853,
# 'T': 350.0,
# 'P': 12.990142036059941,
# 'beta': 0.0
# }

print(model.saturation_pressure(np.array([0.5, 0.5]), 350.0))
saturation_temperature(z, pressure: float, kind: str = 'bubble', t0: float = 0, y0=None) dict[source]

Saturation temperature at specified pressure.

Parameters:
  • z (array_like) – Global molar fractions

  • pressure (float) – Pressure [bar]

  • kind (str, optional) –

    Kind of saturation point, defaults to “bubble”. Options are
    • ”bubble”

    • ”dew”

    • ”liquid-liquid”

  • t0 (float, optional) – Initial guess for temperature [K]

  • y0 (array_like, optional) – Initial guess for the incipient phase, by default None (will use k_wilson correlation)

Returns:

Saturation temperature calculation result dictionary with keys:
  • x: heavy phase mole fractions

  • y: light phase mole fractions

  • Vx: heavy phase volume [L]

  • Vy: light phase volume [L]

  • P: pressure [bar]

  • T: temperature [K]

  • beta: light phase fraction

Return type:

dict

Example

import numpy as np

from yaeos import PengRobinson76

tc = np.array([369.83, 507.6])       # critical temperatures [K]
pc = np.array([42.48, 30.25])        # critical pressures [bar]
w = np.array([0.152291, 0.301261])   # acentric factors

model = PengRobinson76(tc, pc, w)

# Saturation pressure calculation
# will print:
# {
# 'x': array([0.5, 0.5]),
# 'y': array([0.9210035 , 0.07899651]),
# 'Vx': 0.11974125553488875,
# 'Vy': 1.849650524323853,
# 'T': 350.0,
# 'P': 12.99,
# 'beta': 0.0
# }

print(model.saturation_temperature(np.array([0.5, 0.5]), 12.99))
phase_envelope_pt(z, kind: str = 'bubble', max_points: int = 700, t0: float = 150.0, p0: float = 1.0, w0=None, stop_pressure: float = 2500, ds0: float = 0.001) PTEnvelope[source]

Two phase envelope calculation (PT).

Parameters:
  • z (array_like) – Global mole fractions

  • kind (str, optional) – Kind of saturation point to start the envelope calculation, defaults to “bubble”. Options are - “bubble” - “dew” - “liquid-liquid”

  • max_points (int, optional) – Envelope’s maximum points to calculate (T, P), by default 700

  • t0 (float, optional) – Initial guess for temperature [K] for the saturation point of kind: kind, by default 150.0

  • p0 (float, optional) – Initial guess for pressure [bar] for the saturation point of kind: kind, by default 1.0

  • w0 (array_like, optional) – Initial guess for the incipient phase mole fractions, by default None In the case of bubble and dew line calculations, it will use the k_wilson correlation. In the case of liquid-liquid envelope it will make a search for the first unstable component when decreasing temperature at the given pressure.

  • stop_pressure (float, optional) – Stop on pressures above stop_pressure [bar], by default 2500.0. If the the initial guess pressure is above this value, the calculation will stop immediately.

  • ds0 (float, optional) – Step for the first specified variable, by default 0.001. The specified variable is the temperature for bubble and dew lines, and pressure for liquid-liquid lines. For bubble and dew lines, the step is positive, while for liquid-liquid lines it is negative.

Returns:

PTEnvelope object with the phase envelope information.

Return type:

PTEnvelope

Example

import numpy as np

import matplotlib.pyplot as plt

from yaeos import PengRobinson76

tc = np.array([369.83, 507.6])       # critical temperatures [K]
pc = np.array([42.48, 30.25])        # critical pressures [bar]
w = np.array([0.152291, 0.301261])   # acentric factors

model = PengRobinson76(tc, pc, w)

# Two phase envelope calculation and plot
env = model.phase_envelope_pt(
    np.array([0.5, 0.5]),
    t0=150.0,
    p0=1.0
)

plt.plot(env["T"], env["P"])
plt.scatter(env["Tc"], env["Pc"])
phase_envelope_px(z0, zi, temperature, kind='bubble', max_points=500, p0=10.0, w0=None, a0=0.01, ns0=None, ds0=1e-05) PXEnvelope[source]

Two phase envelope calculation (PX).

Calculation of a phase envelope that starts at a given composition and its related to another composition with some proportion.

Parameters:
  • z0 (array_like) – Initial global mole fractions

  • zi (array_like) – Final global mole fractions

  • temperature (float) – Temperature [K]

  • kind (str, optional) – Kind of saturation point to start the envelope calculation, defaults to “bubble”. Options are - “bubble” - “dew”

  • max_points (int, optional) – Envelope’s maximum points to calculate, by default 500

  • p0 (float, optional) – Initial guess for pressure [bar] for the saturation point of kind: kind, by default 10.0

  • a0 (float, optional) – Initial molar fraction of composition zi, by default 0.001

  • ns0 (int, optional) – Initial specified variable number, by default None. The the first n=len(z) values correspond to the K-values, len(z)+1 is the main phase molar fraction (ussually one) and the last two values are the pressure and alpha.

  • ds0 (float, optional) – Step for the first specified variable, by default 0.01

phase_envelope_tx(z0, zi, pressure, kind='bubble', max_points=300, t0=150.0, a0=0.001, ns0=None, ds0=0.1, w0=None) TXEnvelope[source]

Two phase envelope calculation (TX).

Calculation of a phase envelope that starts at a given composition and its related to another composition with some proportion.

Parameters:
  • z0 (array_like) – Initial global mole fractions

  • zi (array_like) – Final global mole fractions

  • pressure (float) – Pressure [bar]

  • kind (str, optional) – Kind of saturation point to start the envelope calculation, defaults to “bubble”. Options are - “bubble” - “dew”

  • max_points (int, optional) – Envelope’s maximum points to calculate (P, X), by default 300

  • t0 (float, optional) – Initial guess for temperature [K] for the saturation point of kind: kind, by default 150.0

  • a0 (float, optional) – Initial molar fraction of composition zi, by default 0.001

  • ns0 (int, optional) – Initial specified variable number, by default None. The the first n=len(z) values correspond to the K-values, where the last two values are the temperature and alpha.

  • ds0 (float, optional) – Step for a, by default 0.1

  • w0 (array_like, optional) – Initial guess for the incipient phase, by default None (will use k_wilson correlation)

phase_envelope_pt3(z, x0, y0, w0, beta0, t0, p0, specified_variable=None, first_step=None, kinds_x=None, kind_w=None, max_points=1000, stop_pressure=2500) PTEnvelope[source]

Three-phase envelope tracing method.

Calculation of a three-phase envelope that starts with an estimated compositions, pressure, temperature and phase fractions.

Parameters:
  • z (array_like) – Global mole fractions

  • x0 (array_like) – Initial phase x mole fractions

  • y0 (array_like) – Initial phase y mole fractions

  • w0 (array_like) – Initial incipient phase w mole fractions

  • beta0 (float) – Initial phase fraction between x and y

  • t0 (float) – Initial temperature [K]

  • p0 (float) – Initial pressure [bar]

  • specified_variable (int, optional) – Initial specified variable number, by default 2*len(z)+2 (temperature). The the first n=(1,len(z)) values correspond to the K-values between phase x and w, the next n=(len(z)+1, 2*len(z)) are the K-values between phase y and w. The last three values are pressure, temperature and beta.

  • first_step (float, optional) – Step for the specified variable, by default 0.1

  • kinds_x (list, optional) – Kinds of the main phases, by default None (will use “stable”)

  • kind_w (str, optional) – Kind of the reference phase, by default None (will use “stable”)

  • max_points (int, optional) – Maximum number of points to calculate, by default 1000

  • stop_pressure (float, optional) – Stop at pressure above stop_pressure [bar], default 2500

phase_envelope_px3(z0, zi, T, x0, y0, w0, beta0, a0, p0, specified_variable=None, first_step=None, max_points=1000, kinds_x=None, kind_w=None) PXEnvelope[source]

Three-phase envelope tracing method.

Calculation of a three-phase envelope that starts with an estimated compositions, pressure, temperature and phase fractions.

Parameters:
  • z0 (array_like) – Global mole fractions of the original fluid

  • zi (array_like) – Global mole fractions of the other fluid

  • x0 (array_like) – Initial phase x mole fractions

  • y0 (array_like) – Initial phase y mole fractions

  • w0 (array_like) – Initial incipient phase w mole fractions

  • beta0 (float) – Initial phase fraction between x and y

  • a0 (float) – Initial molar fraction of the other fluid

  • p0 (float) – Initial pressure [bar]

  • specified_variable (int, optional) – Initial specified variable number, by default 2*len(z)+2 (temperature). The the first n=(1,len(z)) values correspond to the K-values between phase x and w, the next n=(len(z)+1, 2*len(z)) are the K-values between phase y and w. The last three values are pressure, a and beta.

  • first_step (float, optional) – Step for the specified variable, by default 0.1

  • max_points (int, optional) – Maximum number of points to calculate, by default 1000

  • kinds_x (list, optional) – Kinds of the main phases, by default None (will use “stable”) options can be - “stable”, “liquid”, “vapor”

  • kind_w (str, optional) – Kind of the reference phase, by default None (will use “stable”) options can be - “stable”, “liquid”, “vapor”

phase_envelope_pt_mp(z, x_l0, w0, betas0, p0, t0, ns0, ds0, beta_w=0, kinds_x=None, kind_w=None, max_points=1000, stop_pressure=1000) PTEnvelope[source]

Multi-phase envelope.

phase_envelope_px_mp(z0, zi, t, x_l0, w0, betas0, p0, ns0, ds0, alpha0=0, beta_w=0, max_points=1000, kinds_x=None, kind_w=None) PXEnvelope[source]

Multi-phase PX envelope.

Calculate a phase envelope with a preselected ammount of phases.

Parameters:
  • z0 (float, array_like) – Original Fluid.

  • zi (float, array_like) – Other fluid.

  • t (float) – Temperature [K]

  • x_l0 (float, matrix [number of phases, number of components]) – A matrix where each row is the composition of a main phase. Guess for first point.

  • w0 (flot, array_like) – Composition of the reference (ussually incipient) phase. Guess for first point

  • betas0 (float, array_like) – Molar fraction of each main phase. Guess for first point

  • p0 (float) – Pressure guess for first point [bar]

  • ns0 (int) – Initial variable to specifiy. From 1 to (number_of_phases*number_of_components) corresponds to each composition. From number_of_phases*number_of_components to number_of_phases*number_of_components + number_of_phases corresponds to each beta value of the main phases. The last two posibilities are the pressure and molar relation between the two fluids, respectively.

  • kinds_x (list(str), optional) – List of kinds of main phases, defaults to stable. options are: - “stable” - “liquid” - “vapor”

  • kinds_w (list(str), optional) – Kind of reference phase, defaults to stable. options are: - “stable” - “liquid” - “vapor”

phase_envelope_tx_mp(z0, zi, p, x_l0, w0, betas0, t0, ns0, ds0, alpha0=0, beta_w=0, max_points=1000, kinds_x=None, kind_w=None) TXEnvelope[source]

Multi-phase envelope.

phase_envelope_pt_from_dsp(z, env1: PTEnvelope, env2: PTEnvelope, dbeta0=1e-05, max_points=1000) list[source]

Calculate PT phase envelopes from a DSP.

This method calculates the phase envelope at the intersection of two PT envelopes, env1 and env2.

Parameters:
  • z (array_like) – Global mole fractions

  • env1 (PTEnvelope) – First PT envelope object

  • env2 (PTEnvelope) – Second PT envelope object

  • dbeta0 (float, optional) – initial step for the beta values, by default 1e-5

  • max_points (int, optional) – Maximum number of points to calculate, by default 1000

phase_envelope_px_from_dsp(z0, zi, env1: PXEnvelope, env2: PXEnvelope, dbeta0=1e-05) list[source]

Calculate PX phase envelopes from a DSP.

This method calculates the phase envelope at the intersection of two PX envelopes, env1 and env2. :param z0: Global mole fractions of the original fluid :type z0: array_like :param zi: Global mole fractions of the other fluid :type zi: array_like :param env1: First PX envelope object :type env1: PXEnvelope :param env2: Second PX envelope object :type env2: PXEnvelope :param dbeta0: Initial step for the beta values, by default 1e-5 :type dbeta0: float, optional

Returns:

List of lists of two PXEnvelope objects, one for each intersection point.

Return type:

list

isopleth(z, three_phase=True, dew_start=(500, 0.01), bubble_start=(200, 10), max_points=1000, delta_dew_2ph=0.01, delta_bub_2ph=0.01, delta_dsp_3ph=0.01, stop_pressure=2500)[source]
stability_analysis(z, pressure, temperature)[source]

Perform stability analysis.

Find all the possible minima values that the \(tm\) function, defined by Michelsen and Mollerup.

Parameters:
  • z (array_like) – Global mole fractions

  • pressure (float) – Pressure [bar]

  • temperature (float) – Temperature [K]

Returns:

  • dict – Stability analysis result dictionary with keys: - w: value of the test phase that minimizes the \(tm\) function - tm: minimum value of the \(tm\) function.

  • dict – All found minimum values of the \(tm\) function and the corresponding test phase mole fractions. - w: all values of \(w\) that minimize the \(tm\) function - tm: all values found minima of the \(tm\) function

stability_tm(z, w, pressure, temperature)[source]

Calculate the \(tm\) function.

Calculate the \(tm\) function, defined by Michelsen and Mollerup. If this value is negative, it means that the feed with composition z is unstable.

Parameters:
  • z (array_like) – Global mole fractions

  • w (array_like) – Test Phase mole fractions

  • pressure (float) – Pressure [bar]

  • temperature (float) – Temperature [K]

Returns:

Value of the \(tm\) function

Return type:

float

critical_point(z0, zi=[0, 0], ns=1, s=0, max_iters=100) dict[source]

Critical point calculation.

Calculate the critical point of a mixture. At a given composition.

Parameters:
  • z0 (array_like) – Mole fractions of original fluid

  • zi (array_like) – Mole fractinos of other fluid

  • ns (int) – Number of specification

  • S (float) – Specification value

  • max_iters (int, optional)

Returns:

Critical point calculation result dictionary with keys:
  • Tc: critical temperature [K]

  • Pc: critical pressure [bar]

  • Vc: critical volume [L]

Return type:

dict

critical_line(z0, zi, ns=1, s=1e-05, ds0=0.01, a0=1e-05, v0=0, t0=0, p0=0, stability_analysis=False, max_points=1000, stop_pressure=2500)[source]

Critical Line calculation.

Calculate the critical line between two compositions

Parameters:
  • z0 (array_like) – Initial global mole fractions

  • zi (array_like) – Final global mole fractions

  • ns (int, optional) – Specified variable number, by default 1

  • s (float, optional) – Specified value, by default 1e-5

  • ds0 (float, optional) – Step for molar fraction of composition i

  • a0 (float, optional) – Initial molar fraction of composition i

  • v0 (float, optional) – Initial guess for volume [L/mol]

  • t0 (float, optional) – Initial guess for temperature [K]

  • p0 (float, optional) – Initial guess for pressure [bar]

  • max_points (int, optional) – Maximum number of points to calculate

  • stop_pressure (float, optional) – Stop when reaching this pressure value

critical_line_liquid_liquid(z0=[0, 1], zi=[1, 0], pressure=2000, t0=500)[source]

Find the start of the Liquid-Liquid critical line of a binary.

Parameters:
  • z0 (array_like) – Initial global mole fractions

  • zi (array_like) – Final global mole fractions

  • pressure (float) – Pressure [bar]

  • t0 (float) – Initial guess for temperature [K]