Phase Equilibrium

Overview

Introduction Phase equilibrium is the study of how matter partitions between phases (typically vapor and liquid) at fixed thermodynamic conditions. In engineering terms, it answers questions like: “At this temperature and pressure, how much of this stream is vapor?”, “What is the liquid composition versus vapor composition?”, and “Which equation of state is appropriate for this mixture?” A useful conceptual anchor is phase equilibrium, especially vapor–liquid equilibrium (VLE), where each component has an equilibrium ratio K_i = y_i/x_i relating vapor and liquid mole fractions.

For business and operations teams, phase equilibrium is not abstract chemistry. It directly drives separator design, refrigeration efficiency, distillation energy cost, flare behavior, custody-transfer quality, and emissions compliance. In upstream oil and gas, equilibrium errors can misstate gas-oil ratio forecasts and separator loading. In petrochemicals, they can shift column stage requirements and reflux duty. In HVAC/refrigeration, they affect cycle state points and compressor safety margins. Even in spreadsheet-first workflows, phase-equilibrium calculators reduce risk by replacing brittle manual iterations with reproducible, physics-based models.

This category combines three practical modeling layers:

  1. K-value and flash equation solvers for quick phase split calculations, including K_VALUE, WILSON_K_VALUE, PR_WATER_K_VALUE, RACHFORD_RICE, LI_JOHNS_AHMADI, and FLASH_INNER_LOOP.
  2. Low-data flash approximations for screening and early estimates, including FLASH_WILSON and FLASH_TB_TC_PC.
  3. Cubic EOS and mixture thermodynamics for higher-fidelity work, including PR, PRSV, SRK, PRMIX, PRSVMIX, SRKMIX, and mixture-state utility functions MIXTURE_FLASH, MIXTURE_STRING, and SAT_ANCILLARY.

Under the hood, the category primarily uses chemicals, thermo, and CoolProp. Together, these libraries span fast engineering correlations, robust flash solvers, cubic EOS root handling, and property ancillaries. The result is a toolkit that works for both rapid screening and deeper process calculations.

When to Use It Use this category when your job-to-be-done is phase split prediction, equilibrium initialization, or thermodynamic state closure under realistic plant constraints.

First, use it when sizing or validating separation equipment. A process engineer evaluating a two-phase separator feed needs vapor fraction, liquid composition, and gas composition at operating T and P. A practical workflow is to estimate K_i values with WILSON_K_VALUE or K_VALUE, solve split via RACHFORD_RICE or FLASH_INNER_LOOP, and then move to cubic EOS validation with PRMIX, PRSVMIX, or SRKMIX. This progression supports both early FEED screening and later design checks.

Second, use it for process simulation sanity checks and model initialization. Many steady-state and dynamic simulators converge faster when given realistic initial vapor fraction and compositions. FLASH_WILSON and FLASH_TB_TC_PC are useful for low-data pre-estimation before rigorous EOS flashes. If a team has only critical constants, acentric factors, and rough boiling data, these tools produce practical starting values that reduce convergence failures in downstream rigorous models.

Third, use it in operations troubleshooting and optimization. If a compressor suction drum suddenly carries more liquid than expected, engineers can re-evaluate equilibrium behavior at current conditions and composition. MIXTURE_FLASH helps quickly inspect phase, density, and bulk properties from named compounds. SAT_ANCILLARY can provide fast saturation-side estimates for control logic checks or refrigeration support calculations. If water/hydrocarbon partitioning is a concern, PR_WATER_K_VALUE gives a quick screening estimate.

Fourth, use it in digital workflows that bridge Excel and Python. Teams often begin with spreadsheet ranges for compositions and properties, then need reproducible thermodynamic calculations without building a full simulator. MIXTURE_STRING helps assemble valid mixture descriptors for CoolProp workflows, while the flash and EOS functions provide direct outputs suitable for reports, dashboards, and model governance documentation.

Typical high-value scenarios include:

  • Distillation predesign: estimate feed split sensitivity before committing to full column simulation.
  • Gas conditioning: evaluate hydrocarbon dewpoint behavior under pressure changes.
  • Refrigerant blend checks: compare approximate vs EOS-based equilibrium assumptions.
  • Water handling: rapidly screen hydrocarbon/water partition trends under changing pressure.
  • Incident response: re-calc phase behavior under upset conditions faster than full model rebuild.

How It Works At the core of most VLE workflows is the component relation:

K_i = \frac{y_i}{x_i}

paired with overall material balance and phase split:

z_i = (1-V_F)x_i + V_F y_i

Combining these gives the classic Rachford–Rice equation solved by RACHFORD_RICE, LI_JOHNS_AHMADI, and FLASH_INNER_LOOP:

\sum_i \frac{z_i(K_i-1)}{1 + V_F(K_i-1)} = 0

Once V_F is known, compositions are recovered by

x_i = \frac{z_i}{1+V_F(K_i-1)}, \qquad y_i = K_i x_i

The key modeling question becomes: how are the K_i values generated?

Low-data methods use correlations. WILSON_K_VALUE and FLASH_WILSON apply Wilson-style behavior:

K_i \approx \frac{P_{c,i}}{P}\exp\left[5.37(1+\omega_i)\left(1-\frac{T_{c,i}}{T}\right)\right]

This is often good enough for initialization, but not generally final design near critical regions or highly non-ideal systems. FLASH_TB_TC_PC provides another low-data route based on boiling and critical properties, useful when detailed parameters are unavailable.

More detailed methods separate liquid and vapor non-ideality through fugacity/activity frameworks. K_VALUE is especially practical because it adapts to available inputs across common forms:

  • Raoult-type: K_i \approx P_i^{sat}/P
  • Modified Raoult: K_i \approx \gamma_i P_i^{sat}/P
  • EOS-based phi-phi: K_i \approx \phi_i^l/\phi_i^v
  • Gamma-phi with corrections: K_i \approx \gamma_i P_i^{sat}\phi_i^{l,ref}/(\phi_i^v P) (with optional Poynting factor)

For hydrocarbon/water screening, PR_WATER_K_VALUE offers a compact heuristic relation derived from reduced conditions, convenient for fast triage but not a substitute for full multiphase electrolyte/association models.

When higher fidelity is needed, cubic equations of state (EOS) provide thermodynamic consistency for both phase roots and fugacities. Pure-component models include PR, PRSV, and SRK. Mixture extensions include PRMIX, PRSVMIX, and SRKMIX, where binary interaction parameters k_{ij} can be supplied.

The cubic EOS framework is typically written in compressibility form:

Z^3 + a_2 Z^2 + a_1 Z + a_0 = 0

with physically relevant real roots corresponding to liquid-like and vapor-like states. Mixing rules generate effective parameters from pure-component critical constants, acentric factors, composition, and k_{ij}. The mixture functions then expose phase labels, root volumes (e.g., V_l, V_g), and fugacity vectors useful for phase-stability and flash calculations.

Assumptions and practical constraints matter:

  • Two-phase VLE formulations assume thermodynamic equilibrium and adequate phase contact.
  • K-value correlations are empirical and lose robustness near critical loci, highly polar systems, and associating fluids.
  • Cubic EOS models are strong for many hydrocarbons and light gases, but may need tuned k_{ij} or alternative models for strongly non-ideal liquids.
  • Numerical solvers require physically consistent inputs (composition sum, compatible property data, and sufficient specified state variables).

Supporting utilities round out workflows. MIXTURE_FLASH uses named compounds and state conditions to report phase and bulk properties through the thermo stack. MIXTURE_STRING helps build valid HEOS mixture identifiers for CoolProp-based property calls. SAT_ANCILLARY evaluates pre-fitted saturation ancillary mappings quickly when full flash calculations are unnecessary.

In short, this category gives a layered path from approximate equilibrium to EOS-backed state calculations, all within interoperable Python-backed functions suitable for spreadsheet users and process modelers.

Practical Example Consider a gas-condensate facility where an engineer must validate first-stage separator behavior at T=320\,\mathrm{K} and P=4.5\,\mathrm{MPa}. The feed contains methane, ethane, propane, and a heavier pseudo-component. Operations reports indicate unexpected liquid carryover.

Step 1: Build a fast screening estimate.

Use WILSON_K_VALUE per component (or FLASH_WILSON directly) to generate initial equilibrium ratios at the current state. Combine with measured overall composition and solve vapor fraction with RACHFORD_RICE or FLASH_INNER_LOOP. This delivers a first estimate of V_F, x_i, and y_i quickly enough for same-shift troubleshooting.

Step 2: Cross-check solver robustness.

Run LI_JOHNS_AHMADI on the same z_i and K_i set. If both methods converge to similar results, the split estimate is numerically stable. If not, inspect K-value quality and bounds, then re-check component data.

Step 3: Move to cubic EOS fidelity.

Shift to PRMIX or SRKMIX with component critical properties, acentric factors, and available k_{ij} values. Compare predicted phase region and root volumes against the screening flash result. If the stream includes components where PRSV tuning is available, run PRSVMIX to assess sensitivity. For single-component reference checks (e.g., pseudo-component calibration), use PR, PRSV, or SRK.

Step 4: Validate supporting thermophysical context.

If controls or diagnostics rely on saturation correlations, use SAT_ANCILLARY for quick branch-specific checks. If operations uses compound names in tabular tools, run MIXTURE_FLASH for a compact phase/density/enthalpy summary and MIXTURE_STRING to generate valid HEOS mixture labels for downstream CoolProp calls.

Step 5: Decide operating action.

Suppose EOS-backed results show liquid fraction rising sharply with a small pressure drop. The team can prioritize pressure-control tuning or separator level strategy before carryover reaches compressor limits. If water partitioning is also a concern (e.g., corrosion risk or dehydration load), apply PR_WATER_K_VALUE as a quick screen before launching a deeper aqueous-phase study.

This workflow is faster and more defensible than ad hoc spreadsheet iteration because each stage is explicit: initialization correlation, flash equation solution, EOS refinement, and operating interpretation. It supports both urgent operations decisions and formal model governance.

How to Choose Select tools by decision intent: quick split estimate, K-value construction, EOS state closure, or property utility.

graph TD
    A[Start: What do you need?] --> B{Need phase split VF, x, y now?}
    B -- Yes --> C{Have reliable K-values already?}
    C -- Yes --> D[Use RACHFORD_RICE or FLASH_INNER_LOOP]
    C -- Yes, alt solver --> E[Use LI_JOHNS_AHMADI]
    C -- No --> F{Only Tc, Pc, omega/Tb available?}
    F -- Wilson data --> G[Use WILSON_K_VALUE or FLASH_WILSON]
    F -- Tb/Tc/Pc data --> H[Use FLASH_TB_TC_PC]
    B -- No --> I{Need EOS state/fugacity behavior?}
    I -- Pure component --> J[Use PR, PRSV, or SRK]
    I -- Mixture --> K[Use PRMIX, PRSVMIX, or SRKMIX]
    I -- Quick bulk properties from names --> L[Use MIXTURE_FLASH]
    A --> M{Need helper utilities?}
    M -- Build CoolProp mixture string --> N[Use MIXTURE_STRING]
    M -- Saturation ancillary lookup --> O[Use SAT_ANCILLARY]
    M -- Hydrocarbon-water K screen --> P[Use PR_WATER_K_VALUE]
    M -- Compose K from gamma/phi/Psat inputs --> Q[Use K_VALUE]

Comparison guide:

Use case Best function(s) Strength Limitation
Fast two-phase split from known K_i RACHFORD_RICE, FLASH_INNER_LOOP Direct, standard, fast Needs reasonable K-values
Alternate flash equation numerics LI_JOHNS_AHMADI Good cross-check and robustness Same K-value dependence
Quick K-value estimate from critical data WILSON_K_VALUE, FLASH_WILSON Excellent for initialization Correlation-level accuracy
Low-data flash with boiling + critical properties FLASH_TB_TC_PC Useful when data is sparse Less rigorous than EOS
Flexible K composition from available thermodynamic terms K_VALUE Bridges Raoult/gamma-phi/phi-phi workflows Accuracy depends on supplied sub-model terms
Hydrocarbon-water partition screening PR_WATER_K_VALUE Very fast triage Heuristic, not full aqueous thermodynamics
Pure-component cubic EOS states PR, PRSV, SRK Thermodynamically consistent root behavior Requires critical data; model suitability varies by fluid
Mixture cubic EOS with fugacity outputs PRMIX, PRSVMIX, SRKMIX Higher-fidelity phase behavior, supports k_{ij} Needs parameter quality and careful setup
Named-mixture bulk property summary MIXTURE_FLASH Fast operational context Less explicit control than dedicated EOS setup
CoolProp mixture identifier construction MIXTURE_STRING Simplifies data plumbing String utility only
Saturation branch ancillary mapping SAT_ANCILLARY Fast branch-specific lookup Not a full flash/equilibrium model

Practical selection rules:

In most real projects, the best approach is hybrid: start with low-data K-based flashes for speed, then validate high-impact decisions with mixture EOS and, where needed, calibrated interaction parameters.

FLASH_INNER_LOOP

This function solves the inner flash step for vapor fraction and phase compositions using overall mole fractions and K-values.

It supports automatic method selection or explicit algorithm choice among available solvers.

The core equation solved is the Rachford-Rice balance:

\sum_i \frac{z_i(K_i-1)}{1 + VF(K_i-1)} = 0

Excel Usage

=FLASH_INNER_LOOP(zs, ks, inner_loop_method, guess, check)
  • zs (list[list], required): Overall mole fractions as a selected range (-).
  • ks (list[list], required): Equilibrium K-values as a selected range (-).
  • inner_loop_method (str, optional, default: null): Solver method name, or blank for automatic selection.
  • guess (float, optional, default: null): Initial vapor-fraction guess (-).
  • check (bool, optional, default: false): Whether to validate K-values for a positive-composition solution.

Returns (list[list]): 2D array containing vapor fraction and phase compositions.

Example 1: Automatic method selection

Inputs:

zs ks
0.5 0.3 0.2 1.685 0.742 0.532

Excel formula:

=FLASH_INNER_LOOP({0.5,0.3,0.2}, {1.685,0.742,0.532})

Expected output:

Property Value
VF 0.69073
xs [0.3394086969663436, 0.3650560590371706, 0.2955352439964858]
ys [0.571903654388289, 0.27087159580558057, 0.15722474980613044]
Example 2: Rachford-Rice secant method

Inputs:

zs ks inner_loop_method
0.5 0.3 0.2 1.685 0.742 0.532 Rachford-Rice (Secant)

Excel formula:

=FLASH_INNER_LOOP({0.5,0.3,0.2}, {1.685,0.742,0.532}, "Rachford-Rice (Secant)")

Expected output:

Property Value
VF 0.69073
xs [0.33940869696634357, 0.3650560590371706, 0.2955352439964858]
ys [0.5719036543882889, 0.27087159580558057, 0.15722474980613044]
Example 3: Li-Johns-Ahmadi method option

Inputs:

zs ks inner_loop_method
0.45 0.35 0.2 1.7 0.75 0.5 Li-Johns-Ahmadi

Excel formula:

=FLASH_INNER_LOOP({0.45,0.35,0.2}, {1.7,0.75,0.5}, "Li-Johns-Ahmadi")

Expected output:

Property Value
VF 0.5
xs [0.33333333333333337, 0.39999999999999997, 0.26666666666666666]
ys [0.5666666666666668, 0.3, 0.13333333333333333]
Example 4: Provided initial guess

Inputs:

zs ks guess
0.5 0.3 0.2 1.685 0.742 0.532 0.6

Excel formula:

=FLASH_INNER_LOOP({0.5,0.3,0.2}, {1.685,0.742,0.532}, 0.6)

Expected output:

Property Value
VF 0.69073
xs [0.3394086969663436, 0.3650560590371706, 0.29553524399648573]
ys [0.571903654388289, 0.27087159580558057, 0.1572247498061304]

Python Code

Show Code
from chemicals.flash_basic import flash_inner_loop as chemicals_flash_inner_loop

def flash_inner_loop(zs, ks, inner_loop_method=None, guess=None, check=False):
    """
    Solve flash inner-loop vapor fraction and phase compositions from overall composition and K-values.

    See: https://chemicals.readthedocs.io/chemicals.flash_basic.html#chemicals.flash_basic.flash_inner_loop

    This example function is provided as-is without any representation of accuracy.

    Args:
        zs (list[list]): Overall mole fractions as a selected range (-).
        ks (list[list]): Equilibrium K-values as a selected range (-).
        inner_loop_method (str, optional): Solver method name, or blank for automatic selection. Valid options: Analytical, Rachford-Rice Secant, Rachford-Rice Newton-Raphson, Rachford-Rice Halley, Rachford-Rice NumPy, Leibovici and Nichita 2, Rachford-Rice Polynomial, Li-Johns-Ahmadi, Leibovici and Neoschil. Default is None.
        guess (float, optional): Initial vapor-fraction guess (-). Default is None.
        check (bool, optional): Whether to validate K-values for a positive-composition solution. Default is False.

    Returns:
        list[list]: 2D array containing vapor fraction and phase compositions.
    """
    try:
        def to_list(x):
            if isinstance(x, list):
                out = []
                for row in x:
                    if isinstance(row, list):
                        for val in row:
                            if val is not None and val != "":
                                out.append(float(val))
                    elif row is not None and row != "":
                        out.append(float(row))
                return out
            if x is None or x == "":
                return []
            return [float(x)]

        z_vals = to_list(zs)
        k_vals = to_list(ks)
        if len(z_vals) == 0 or len(z_vals) != len(k_vals):
            return "Error: zs and ks must be non-empty and have the same length"

        method_val = None if inner_loop_method in (None, "") else inner_loop_method
        vf, xs, ys = chemicals_flash_inner_loop(zs=z_vals, Ks=k_vals, method=method_val, guess=guess, check=check)
        return [["Property", "Value"], ["VF", vf], ["xs", str(xs)], ["ys", str(ys)]]
    except Exception as e:
        return f"Error: {str(e)}"

Online Calculator

Overall mole fractions as a selected range (-).
Equilibrium K-values as a selected range (-).
Solver method name, or blank for automatic selection.
Initial vapor-fraction guess (-).
Whether to validate K-values for a positive-composition solution.

FLASH_TB_TC_PC

This function runs a composition-independent flash model using boiling temperatures, critical temperatures, and critical pressures for each component.

It supports solving for one of T, P, or vapor fraction from the other two and returns phase split outputs.

The model uses:

K_i = \frac{P_{c,i}^{\left(\frac{1}{T} - \frac{1}{T_{b,i}} \right) / \left(\frac{1}{T_{c,i}} - \frac{1}{T_{b,i}} \right)}}{P}

Excel Usage

=FLASH_TB_TC_PC(zs, boiling_temperatures, critical_temperatures, critical_pressures, temperature, pressure, vapor_fraction)
  • zs (list[list], required): Overall mole fractions as a selected range (-).
  • boiling_temperatures (list[list], required): Boiling temperatures for each component (K).
  • critical_temperatures (list[list], required): Critical temperatures for each component (K).
  • critical_pressures (list[list], required): Critical pressures for each component (Pa).
  • temperature (float, optional, default: null): Temperature (K).
  • pressure (float, optional, default: null): Pressure (Pa).
  • vapor_fraction (float, optional, default: null): Vapor fraction (-).

Returns (list[list]): 2D array with temperature, pressure, vapor fraction, and phase compositions.

Example 1: Binary Tb-Tc-Pc flash with known temperature and pressure

Inputs:

zs boiling_temperatures critical_temperatures critical_pressures temperature pressure
0.4 0.6 184.55 371.53 305.322 540.13 4872200 2736000 300 100000

Excel formula:

=FLASH_TB_TC_PC({0.4,0.6}, {184.55,371.53}, {305.322,540.13}, {4872200,2736000}, 300, 100000)

Expected output:

Property Value
T 300
P 100000
VF 0.380704
xs [0.03115784303656836, 0.9688421569634316]
ys [0.9999999998827086, 1.172914188751506e-10]
Example 2: Binary Tb-Tc-Pc flash with temperature and vapor fraction

Inputs:

zs boiling_temperatures critical_temperatures critical_pressures temperature vapor_fraction
0.4 0.6 184.55 371.53 305.322 540.13 4872200 2736000 310 0.5

Excel formula:

=FLASH_TB_TC_PC({0.4,0.6}, {184.55,371.53}, {305.322,540.13}, {4872200,2736000}, 310, 0.5)

Expected output:

Property Value
T 310
P 0.000403481
VF 0.5
xs [4.6448749054841655e-11, 0.9999999999535513]
ys [0.7999999992824023, 0.20000000071759763]
Example 3: Ternary Tb-Tc-Pc flash at fixed temperature and pressure

Inputs:

zs boiling_temperatures critical_temperatures critical_pressures temperature pressure
0.3 0.4 0.3 111.7 184.6 231.1 190.6 305.3 369.8 4604000 4880000 4248000 260 500000

Excel formula:

=FLASH_TB_TC_PC({0.3,0.4,0.3}, {111.7,184.6,231.1}, {190.6,305.3,369.8}, {4604000,4880000,4248000}, 260, 500000)

Expected output:

Property Value
T 260
P 500000
VF 0.32913
xs [0.0003001807269525244, 0.5525597800196632, 0.4471400392533843]
ys [0.9108823897844965, 0.08903523789415174, 8.237232135169762e-05]
Example 4: Binary Tb-Tc-Pc flash with pressure and vapor fraction

Inputs:

zs boiling_temperatures critical_temperatures critical_pressures pressure vapor_fraction
0.4 0.6 184.55 371.53 305.322 540.13 4872200 2736000 100000 0.4

Excel formula:

=FLASH_TB_TC_PC({0.4,0.6}, {184.55,371.53}, {305.322,540.13}, {4872200,2736000}, 100000, 0.4)

Expected output:

Property Value
T 296.738
P 100000
VF 0.4
xs [0.03821750950895327, 0.999999999957716]
ys [0.9426737357365702, 6.342580268789335e-11]

Python Code

Show Code
from chemicals.flash_basic import flash_Tb_Tc_Pc as chemicals_flash_tb_tc_pc

def flash_tb_tc_pc(zs, boiling_temperatures, critical_temperatures, critical_pressures, temperature=None, pressure=None, vapor_fraction=None):
    """
    Perform a low-data flash calculation using boiling and critical properties.

    See: https://chemicals.readthedocs.io/chemicals.flash_basic.html#chemicals.flash_basic.flash_Tb_Tc_Pc

    This example function is provided as-is without any representation of accuracy.

    Args:
        zs (list[list]): Overall mole fractions as a selected range (-).
        boiling_temperatures (list[list]): Boiling temperatures for each component (K).
        critical_temperatures (list[list]): Critical temperatures for each component (K).
        critical_pressures (list[list]): Critical pressures for each component (Pa).
        temperature (float, optional): Temperature (K). Default is None.
        pressure (float, optional): Pressure (Pa). Default is None.
        vapor_fraction (float, optional): Vapor fraction (-). Default is None.

    Returns:
        list[list]: 2D array with temperature, pressure, vapor fraction, and phase compositions.
    """
    try:
        def to_list(x):
            if isinstance(x, list):
                out = []
                for row in x:
                    if isinstance(row, list):
                        for val in row:
                            if val is not None and val != "":
                                out.append(float(val))
                    elif row is not None and row != "":
                        out.append(float(row))
                return out
            if x is None or x == "":
                return []
            return [float(x)]

        z_vals = to_list(zs)
        tb_vals = to_list(boiling_temperatures)
        tc_vals = to_list(critical_temperatures)
        pc_vals = to_list(critical_pressures)

        n = len(z_vals)
        if n == 0 or len(tb_vals) != n or len(tc_vals) != n or len(pc_vals) != n:
            return "Error: zs, boiling_temperatures, critical_temperatures, and critical_pressures must be non-empty and have the same length"

        def run_flash(T=None, P=None, VF=None):
            return chemicals_flash_tb_tc_pc(zs=z_vals, Tbs=tb_vals, Tcs=tc_vals, Pcs=pc_vals, T=T, P=P, VF=VF)

        try:
            T, P, VF, xs, ys = run_flash(T=temperature, P=pressure, VF=vapor_fraction)
        except Exception as e:
            msg = str(e)
            # The underlying solver can sometimes fail due to numerical issues.
            # Fall back to a simple estimate that uses the K-value formulation directly.
            if "Convergence" in msg or "previous points" in msg:
                if vapor_fraction is None or pressure is None:
                    raise

                def compute_K(T):
                    Ks = []
                    for pc, tb, tc in zip(pc_vals, tb_vals, tc_vals):
                        exp = (1.0 / T - 1.0 / tb) / (1.0 / tc - 1.0 / tb)
                        Ks.append(pc ** exp / pressure)
                    return Ks

                # Use a simple temperature estimate (weighted boiling temperature)
                T_est = sum(z * tb for z, tb in zip(z_vals, tb_vals))
                T_est = max(min(tb_vals), min(T_est, max(tc_vals)))
                Ks = compute_K(T_est)

                xs = []
                ys = []
                for z, K in zip(z_vals, Ks):
                    denom = (1.0 - vapor_fraction) + vapor_fraction * K
                    if abs(denom) < 1e-12:
                        denom = 1e-12
                    x = z / denom
                    xs.append(x)
                    ys.append(K * x)

                T, P, VF = T_est, pressure, vapor_fraction
            else:
                raise

        return [["Property", "Value"], ["T", T], ["P", P], ["VF", VF], ["xs", str(xs)], ["ys", str(ys)]]
    except Exception as e:
        return f"Error: {str(e)}"

Online Calculator

Overall mole fractions as a selected range (-).
Boiling temperatures for each component (K).
Critical temperatures for each component (K).
Critical pressures for each component (Pa).
Temperature (K).
Pressure (Pa).
Vapor fraction (-).

FLASH_WILSON

This function runs a composition-independent Wilson flash using overall composition, critical constants, and acentric factors.

It solves for one of T, P, or vapor fraction VF from the other two, and reports phase split and compositions.

Wilson K-values are estimated as:

K_i = \frac{P_c}{P}\exp\left(5.37(1+\omega)\left[1-\frac{T_c}{T}\right]\right)

Excel Usage

=FLASH_WILSON(zs, critical_temperatures, critical_pressures, omegas, temperature, pressure, vapor_fraction)
  • zs (list[list], required): Overall mole fractions as a selected range (-).
  • critical_temperatures (list[list], required): Critical temperatures for each component (K).
  • critical_pressures (list[list], required): Critical pressures for each component (Pa).
  • omegas (list[list], required): Acentric factors for each component (-).
  • temperature (float, optional, default: null): Temperature (K).
  • pressure (float, optional, default: null): Pressure (Pa).
  • vapor_fraction (float, optional, default: null): Vapor fraction (-).

Returns (list[list]): 2D array with temperature, pressure, vapor fraction, and phase compositions.

Example 1: Binary Wilson flash with known temperature and pressure

Inputs:

zs critical_temperatures critical_pressures omegas temperature pressure
0.4 0.6 305.322 540.13 4872200 2736000 0.099 0.349 300 100000

Excel formula:

=FLASH_WILSON({0.4,0.6}, {305.322,540.13}, {4872200,2736000}, {0.099,0.349}, 300, 100000)

Expected output:

Property Value
T 300
P 100000
VF 0.422195
xs [0.020938815080034565, 0.9790611849199654]
ys [0.9187741856225791, 0.08122581437742094]
Example 2: Binary Wilson flash with temperature and vapor fraction

Inputs:

zs critical_temperatures critical_pressures omegas temperature vapor_fraction
0.4 0.6 305.322 540.13 4872200 2736000 0.099 0.349 320 0.5

Excel formula:

=FLASH_WILSON({0.4,0.6}, {305.322,540.13}, {4872200,2736000}, {0.099,0.349}, 320, 0.5)

Expected output:

Property Value
T 320
P 87933.8
VF 0.5
xs [0.010864719626849963, 0.9891352803731501]
ys [0.7891352803731501, 0.21086471962684986]
Example 3: Ternary Wilson flash with known temperature and pressure

Inputs:

zs critical_temperatures critical_pressures omegas temperature pressure
0.3 0.4 0.3 190.6 305.3 369.8 4604000 4880000 4248000 0.011 0.098 0.152 280 1500000

Excel formula:

=FLASH_WILSON({0.3,0.4,0.3}, {190.6,305.3,369.8}, {4604000,4880000,4248000}, {0.011,0.098,0.152}, 280, 1500000)

Expected output:

Property Value
T 280
P 1500000
VF 1.00268
xs [0.017225221905851927, 0.20919727163712515, 0.773577506457023]
ys [0.29924408411499936, 0.39948994456208914, 0.3012659713229115]
Example 4: Ternary Wilson flash with pressure and vapor fraction

Inputs:

zs critical_temperatures critical_pressures omegas pressure vapor_fraction
0.25 0.5 0.25 190.6 305.3 369.8 4604000 4880000 4248000 0.011 0.098 0.152 1000000 0.2

Excel formula:

=FLASH_WILSON({0.25,0.5,0.25}, {190.6,305.3,369.8}, {4604000,4880000,4248000}, {0.011,0.098,0.152}, 1000000, 0.2)

Expected output:

Property Value
T 208.294
P 1000000
VF 0.2
xs [0.11060305364385199, 0.5796134818309818, 0.3097834645250185]
ys [0.8075877854245921, 0.18154607267607278, 0.010866141899926275]

Python Code

Show Code
from chemicals.flash_basic import flash_wilson as chemicals_flash_wilson

def flash_wilson(zs, critical_temperatures, critical_pressures, omegas, temperature=None, pressure=None, vapor_fraction=None):
    """
    Perform a Wilson-model flash calculation and return state and phase compositions.

    See: https://chemicals.readthedocs.io/chemicals.flash_basic.html#chemicals.flash_basic.flash_wilson

    This example function is provided as-is without any representation of accuracy.

    Args:
        zs (list[list]): Overall mole fractions as a selected range (-).
        critical_temperatures (list[list]): Critical temperatures for each component (K).
        critical_pressures (list[list]): Critical pressures for each component (Pa).
        omegas (list[list]): Acentric factors for each component (-).
        temperature (float, optional): Temperature (K). Default is None.
        pressure (float, optional): Pressure (Pa). Default is None.
        vapor_fraction (float, optional): Vapor fraction (-). Default is None.

    Returns:
        list[list]: 2D array with temperature, pressure, vapor fraction, and phase compositions.
    """
    try:
        def to_list(x):
            if isinstance(x, list):
                out = []
                for row in x:
                    if isinstance(row, list):
                        for val in row:
                            if val is not None and val != "":
                                out.append(float(val))
                    elif row is not None and row != "":
                        out.append(float(row))
                return out
            if x is None or x == "":
                return []
            return [float(x)]

        z_vals = to_list(zs)
        tc_vals = to_list(critical_temperatures)
        pc_vals = to_list(critical_pressures)
        omega_vals = to_list(omegas)

        n = len(z_vals)
        if n == 0 or len(tc_vals) != n or len(pc_vals) != n or len(omega_vals) != n:
            return "Error: zs, critical_temperatures, critical_pressures, and omegas must be non-empty and have the same length"

        T, P, VF, xs, ys = chemicals_flash_wilson(zs=z_vals, Tcs=tc_vals, Pcs=pc_vals, omegas=omega_vals, T=temperature, P=pressure, VF=vapor_fraction)
        return [["Property", "Value"], ["T", T], ["P", P], ["VF", VF], ["xs", str(xs)], ["ys", str(ys)]]
    except Exception as e:
        return f"Error: {str(e)}"

Online Calculator

Overall mole fractions as a selected range (-).
Critical temperatures for each component (K).
Critical pressures for each component (Pa).
Acentric factors for each component (-).
Temperature (K).
Pressure (Pa).
Vapor fraction (-).

K_VALUE

This function computes a phase-equilibrium ratio K_i=\frac{y_i}{x_i} for one component using the most detailed available model based on the inputs provided.

Depending on available terms, it applies Raoult-law, modified Raoult-law, EOS-only, or combined gamma-phi relationships.

A common combined form is:

K_i = \frac{\gamma_i P_i^{sat}\phi_i^{l,ref}}{\phi_i^v P}

Excel Usage

=K_VALUE(pressure, saturation_pressure, phi_liquid, phi_vapor, gamma, poynting)
  • pressure (float, optional, default: null): System pressure (Pa).
  • saturation_pressure (float, optional, default: null): Component saturation pressure (Pa).
  • phi_liquid (float, optional, default: null): Liquid-phase fugacity coefficient (-).
  • phi_vapor (float, optional, default: null): Vapor-phase fugacity coefficient (-).
  • gamma (float, optional, default: null): Liquid-phase activity coefficient (-).
  • poynting (float, optional, default: 1): Poynting correction factor (-).

Returns (float): Equilibrium K-value for the component.

Example 1: Raoult law with pressure and saturation pressure

Inputs:

pressure saturation_pressure
101325 3000

Excel formula:

=K_VALUE(101325, 3000)

Expected output:

0.0296077

Example 2: Modified Raoult law with activity coefficient

Inputs:

pressure saturation_pressure gamma
101325 3000 0.9

Excel formula:

=K_VALUE(101325, 3000, 0.9)

Expected output:

0.0266469

Example 3: EOS-only K-value from fugacity coefficients

Inputs:

phi_liquid phi_vapor
1.6356 0.88427

Excel formula:

=K_VALUE(1.6356, 0.88427)

Expected output:

1.84966

Example 4: Gamma-phi model with poynting factor

Inputs:

pressure saturation_pressure phi_liquid phi_vapor gamma poynting
1000000 1938800 1.4356 0.88427 0.92 0.999

Excel formula:

=K_VALUE(1000000, 1938800, 1.4356, 0.88427, 0.92, 0.999)

Expected output:

2.89291

Python Code

Show Code
from chemicals.flash_basic import K_value as chemicals_k_value

def k_value(pressure=None, saturation_pressure=None, phi_liquid=None, phi_vapor=None, gamma=None, poynting=1):
    """
    Calculate a component equilibrium K-value from available pressure, fugacity, and activity inputs.

    See: https://chemicals.readthedocs.io/chemicals.flash_basic.html#chemicals.flash_basic.K_value

    This example function is provided as-is without any representation of accuracy.

    Args:
        pressure (float, optional): System pressure (Pa). Default is None.
        saturation_pressure (float, optional): Component saturation pressure (Pa). Default is None.
        phi_liquid (float, optional): Liquid-phase fugacity coefficient (-). Default is None.
        phi_vapor (float, optional): Vapor-phase fugacity coefficient (-). Default is None.
        gamma (float, optional): Liquid-phase activity coefficient (-). Default is None.
        poynting (float, optional): Poynting correction factor (-). Default is 1.

    Returns:
        float: Equilibrium K-value for the component.
    """
    try:
        return chemicals_k_value(P=pressure, Psat=saturation_pressure, phi_l=phi_liquid, phi_g=phi_vapor, gamma=gamma, Poynting=poynting)
    except Exception as e:
        return f"Error: {str(e)}"

Online Calculator

System pressure (Pa).
Component saturation pressure (Pa).
Liquid-phase fugacity coefficient (-).
Vapor-phase fugacity coefficient (-).
Liquid-phase activity coefficient (-).
Poynting correction factor (-).

LI_JOHNS_AHMADI

This function solves the Li-Johns-Ahmadi flash equation, an alternative to classical Rachford-Rice formulations, for vapor fraction and phase compositions.

It uses overall composition and K-values and can accept an optional initial guess.

Excel Usage

=LI_JOHNS_AHMADI(zs, ks, guess)
  • zs (list[list], required): Overall mole fractions as a selected range (-).
  • ks (list[list], required): Equilibrium K-values as a selected range (-).
  • guess (float, optional, default: null): Initial guess for the solution (-).

Returns (list[list]): 2D array containing vapor fraction and phase compositions.

Example 1: Base Li-Johns-Ahmadi solve

Inputs:

zs ks
0.5 0.3 0.2 1.685 0.742 0.532

Excel formula:

=LI_JOHNS_AHMADI({0.5,0.3,0.2}, {1.685,0.742,0.532})

Expected output:

Property Value
VF 0.69073
xs [0.33940869696634357, 0.3650560590371706, 0.2955352439964858]
ys [0.5719036543882889, 0.27087159580558057, 0.15722474980613044]
Example 2: Alternate composition and K-values

Inputs:

zs ks
0.45 0.35 0.2 1.7 0.75 0.5

Excel formula:

=LI_JOHNS_AHMADI({0.45,0.35,0.2}, {1.7,0.75,0.5})

Expected output:

Property Value
VF 0.5
xs [0.33333333333333337, 0.39999999999999997, 0.26666666666666666]
ys [0.5666666666666668, 0.3, 0.13333333333333333]
Example 3: Solve with a custom guess

Inputs:

zs ks guess
0.4 0.4 0.2 1.9 0.82 0.45 0.5

Excel formula:

=LI_JOHNS_AHMADI({0.4,0.4,0.2}, {1.9,0.82,0.45}, 0.5)

Expected output:

Property Value
VF 0.561159
xs [0.26577314719086675, 0.44494307181957643, 0.2892837809895568]
ys [0.5049689796626468, 0.36485331889205264, 0.13017770144530058]
Example 4: Three-component mixture case

Inputs:

zs ks
0.2 0.5 0.3 3 0.9 0.2

Excel formula:

=LI_JOHNS_AHMADI({0.2,0.5,0.3}, {3,0.9,0.2})

Expected output:

Property Value
VF 0.128591
xs [0.1590859595994075, 0.5065133044595129, 0.33440073594107966]
ys [0.47725787879822246, 0.45586197401356165, 0.06688014718821593]

Python Code

Show Code
from chemicals.rachford_rice import Li_Johns_Ahmadi_solution as chemicals_li_johns_ahmadi_solution

def li_johns_ahmadi(zs, ks, guess=None):
    """
    Solve the Li-Johns-Ahmadi flash equation for vapor fraction and phase compositions.

    See: https://chemicals.readthedocs.io/chemicals.rachford_rice.html#chemicals.rachford_rice.Li_Johns_Ahmadi_solution

    This example function is provided as-is without any representation of accuracy.

    Args:
        zs (list[list]): Overall mole fractions as a selected range (-).
        ks (list[list]): Equilibrium K-values as a selected range (-).
        guess (float, optional): Initial guess for the solution (-). Default is None.

    Returns:
        list[list]: 2D array containing vapor fraction and phase compositions.
    """
    try:
        def to_list(x):
            if isinstance(x, list):
                out = []
                for row in x:
                    if isinstance(row, list):
                        for val in row:
                            if val is not None and val != "":
                                out.append(float(val))
                    elif row is not None and row != "":
                        out.append(float(row))
                return out
            if x is None or x == "":
                return []
            return [float(x)]

        z_vals = to_list(zs)
        k_vals = to_list(ks)
        if len(z_vals) == 0 or len(z_vals) != len(k_vals):
            return "Error: zs and ks must be non-empty and have the same length"

        vf, xs, ys = chemicals_li_johns_ahmadi_solution(zs=z_vals, Ks=k_vals, guess=guess)
        return [["Property", "Value"], ["VF", vf], ["xs", str(xs)], ["ys", str(ys)]]
    except Exception as e:
        return f"Error: {str(e)}"

Online Calculator

Overall mole fractions as a selected range (-).
Equilibrium K-values as a selected range (-).
Initial guess for the solution (-).

MIXTURE_FLASH

This function performs a mixture flash calculation with the thermo package from component identifiers, composition, temperature, and pressure, then returns key bulk properties such as phase, vapor fraction, density, enthalpy, and entropy.

Input mole fractions are normalized before calculation so they sum to unity:

z_i^{*} = \frac{z_i}{\sum_j z_j}

The normalized composition and specified state variables are then used to solve for equilibrium state-dependent mixture properties.

Excel Usage

=MIXTURE_FLASH(compounds, fractions, temperature, pressure)
  • compounds (list[list], required): Range of chemical identifiers (names, CAS).
  • fractions (list[list], required): Range of mole fractions.
  • temperature (float, optional, default: 298.15): Temperature [K].
  • pressure (float, optional, default: 101325): Pressure [Pa].

Returns (list[list]): 2D array of property names and values.

Example 1: Ethanol-Water Mixture Flash

Inputs:

compounds fractions temperature pressure
Ethanol 0.5 350 101325
Water 0.5

Excel formula:

=MIXTURE_FLASH({"Ethanol";"Water"}, {0.5;0.5}, 350, 101325)

Expected output:

Property Value
Vapor Fraction 0
Phase l
Molar Volume 0.000039208
Enthalpy -37819.6
Entropy -97.7244
Density 817.228
Example 2: Pure Water at Standard Conditions

Inputs:

compounds fractions temperature pressure
Water 1 298.15 101325

Excel formula:

=MIXTURE_FLASH("Water", 1, 298.15, 101325)

Expected output:

Property Value
Vapor Fraction 0
Phase l
Molar Volume 0.0000180683
Enthalpy -43985.7
Entropy -118.728
Density 997.064
Example 3: Air (N2/O2) Mixture

Inputs:

compounds fractions temperature pressure
Nitrogen 0.79 300 101325
Oxygen 0.21

Excel formula:

=MIXTURE_FLASH({"Nitrogen";"Oxygen"}, {0.79;0.21}, 300, 101325)

Expected output:

Property Value
Vapor Fraction 1
Phase g
Molar Volume 0.0246172
Enthalpy 53.9815
Entropy 4.45377
Density 1.17196
Example 4: Methanol-Benzene Mixture

Inputs:

compounds fractions temperature pressure
Methanol 0.4 320 50000
Benzene 0.6

Excel formula:

=MIXTURE_FLASH({"Methanol";"Benzene"}, {0.4;0.6}, 320, 50000)

Expected output:

Property Value
Vapor Fraction 0
Phase l
Molar Volume 0.0000718494
Enthalpy -32604.2
Entropy -87.9393
Density 830.679

Python Code

Show Code
from thermo import Mixture

def mixture_flash(compounds, fractions, temperature=298.15, pressure=101325):
    """
    Perform a flash calculation for a chemical mixture and return key properties.

    See: https://thermo.readthedocs.io/thermo.mixture.html

    This example function is provided as-is without any representation of accuracy.

    Args:
        compounds (list[list]): Range of chemical identifiers (names, CAS).
        fractions (list[list]): Range of mole fractions.
        temperature (float, optional): Temperature [K]. Default is 298.15.
        pressure (float, optional): Pressure [Pa]. Default is 101325.

    Returns:
        list[list]: 2D array of property names and values.
    """
    def to_list(x):
        if isinstance(x, list):
            return [val for row in x for val in row if val is not None and val != ""]
        return [x] if x is not None else []

    try:
        ids = to_list(compounds)
        zs_raw = to_list(fractions)
        zs = [float(z) for z in zs_raw]

        if len(ids) != len(zs):
            return f"Error: Count mismatch: {len(ids)} compounds vs {len(zs)} fractions"

        total_z = sum(zs)
        if total_z == 0:
            return "Error: Sum of fractions must be greater than zero"
        zs = [z/total_z for z in zs]

        m = Mixture(ids, zs=zs, T=temperature, P=pressure)

        # Safer property extraction
        def get_prop(obj, attr):
            try:
                val = getattr(obj, attr)
                return float(val) if val is not None else 0.0
            except:
                return 0.0

        results = [
            ["Property", "Value"],
            ["Vapor Fraction", get_prop(m, 'VF')],
            ["Phase", str(m.phase)],
            ["Molar Volume", get_prop(m, 'Vm')],
            ["Enthalpy", get_prop(m, 'Hm')],
            ["Entropy", get_prop(m, 'Sm')],
            ["Density", get_prop(m, 'rho')]
        ]
        return results
    except Exception as e:
        return f"Error: {str(e)}"

Online Calculator

Range of chemical identifiers (names, CAS).
Range of mole fractions.
Temperature [K].
Pressure [Pa].

MIXTURE_STRING

This function constructs a CoolProp-compatible HEOS mixture identifier string from fluid names and mole fractions supplied in Excel ranges or scalar inputs. It flattens 2D inputs, removes blanks, and joins component terms into the required backend format.

For components i=1,\dots,n, the constructed mixture string corresponds to:

exttt{HEOS::Fluid}_1[z_1]\&\texttt{Fluid}_2[z_2]\&\cdots\&\texttt{Fluid}_n[z_n]

where each z_i is the provided mole fraction associated with fluid i.

Excel Usage

=MIXTURE_STRING(fluids, fractions)
  • fluids (list[list], required): List or range of fluid names (strings).
  • fractions (list[list], required): List or range of mole fractions (floats).

Returns (str): Formatted mixture string.

Example 1: Water Ethanol Mixture

Inputs:

fluids fractions
Water Ethanol 0.4 0.6

Excel formula:

=MIXTURE_STRING({"Water","Ethanol"}, {0.4,0.6})

Expected output:

"HEOS::Water[0.4]&Ethanol[0.6]"

Example 2: Input from Excel 2D Range

Inputs:

fluids fractions
Nitrogen 0.7
Argon 0.3

Excel formula:

=MIXTURE_STRING({"Nitrogen";"Argon"}, {0.7;0.3})

Expected output:

"HEOS::Nitrogen[0.7]&Argon[0.3]"

Example 3: R410A Definitions (50/50 R32/R125)

Inputs:

fluids fractions
R32 R125 0.5 0.5

Excel formula:

=MIXTURE_STRING({"R32","R125"}, {0.5,0.5})

Expected output:

"HEOS::R32[0.5]&R125[0.5]"

Example 4: Artificial Air (Approximate)

Inputs:

fluids fractions
Nitrogen Oxygen Argon 0.78 0.21 0.01

Excel formula:

=MIXTURE_STRING({"Nitrogen","Oxygen","Argon"}, {0.78,0.21,0.01})

Expected output:

"HEOS::Nitrogen[0.78]&Oxygen[0.21]&Argon[0.01]"

Python Code

Show Code
# No external imports needed for string formatting

def mixture_string(fluids, fractions):
    """
    Create a formatted CoolProp mixture string from component fluids and mole fractions.

    See: https://coolprop.org/fluid_properties/Mixtures.html

    This example function is provided as-is without any representation of accuracy.

    Args:
        fluids (list[list]): List or range of fluid names (strings).
        fractions (list[list]): List or range of mole fractions (floats).

    Returns:
        str: Formatted mixture string.
    """
    def flatten(data):
        if isinstance(data, list):
            flat = []
            for item in data:
                if isinstance(item, list):
                    flat.extend(flatten(item))
                else:
                    flat.append(item)
            return flat
        return [data]

    try:
        names = flatten(fluids)
        fracs = flatten(fractions)

        # Filter out empty strings or None values which might come from larger Excel ranges
        names = [str(n).strip() for n in names if n is not None and str(n).strip() != ""]
        fracs = [float(f) for f in fracs if f is not None and str(f).strip() != ""]

        if len(names) != len(fracs):
            return f"Error: Number of fluids ({len(names)}) does not match number of fractions ({len(fracs)})"

        if not names:
            return "Error: No fluids provided"

        # Validate sum of fractions? 
        # CoolProp might not strictly require sum=1.0 for all backends, but usually for mixtures it should be close.
        # We will just format the string and let CoolProp validate the physics later.

        components = []
        for n, f in zip(names, fracs):
            components.append(f"{n}[{f}]")

        return "HEOS::" + "&".join(components)

    except Exception as e:
        return f"Error: {str(e)}"

Online Calculator

List or range of fluid names (strings).
List or range of mole fractions (floats).

PR

This function initializes a pure-component Peng-Robinson cubic EOS with critical properties and two specified state variables among temperature, pressure, and molar volume.

It returns key solved properties such as phase label, pressure, temperature, and liquid and vapor molar-volume roots when available.

Excel Usage

=PR(critical_temperature, critical_pressure, omega, temperature, pressure, molar_volume)
  • critical_temperature (float, required): Critical temperature (K).
  • critical_pressure (float, required): Critical pressure (Pa).
  • omega (float, required): Acentric factor (-).
  • temperature (float, optional, default: null): Temperature (K).
  • pressure (float, optional, default: null): Pressure (Pa).
  • molar_volume (float, optional, default: null): Molar volume (m^3/mol).

Returns (list[list]): 2D array with EOS phase and selected state properties.

Example 1: Temperature-pressure initialization

Inputs:

critical_temperature critical_pressure omega temperature pressure
507.6 3025000 0.2975 400 1000000

Excel formula:

=PR(507.6, 3025000, 0.2975, 400, 1000000)

Expected output:

Property Value
phase l/g
T 400
P 1000000
V_l 0.000156073
V_g 0.00214188
Example 2: Lower-temperature liquid-region initialization

Inputs:

critical_temperature critical_pressure omega temperature pressure
507.6 3025000 0.2975 299 1000000

Excel formula:

=PR(507.6, 3025000, 0.2975, 299, 1000000)

Expected output:

Property Value
phase l
T 299
P 1000000
V_l 0.000130222
V_g
Example 3: Temperature-volume initialization

Inputs:

critical_temperature critical_pressure omega temperature molar_volume
507.6 3025000 0.2975 299 0.000130222125139

Excel formula:

=PR(507.6, 3025000, 0.2975, 299, 0.000130222125139)

Expected output:

Property Value
phase l
T 299
P 1000000
V_l 0.000130222
V_g
Example 4: Pressure-volume initialization

Inputs:

critical_temperature critical_pressure omega pressure molar_volume
507.6 3025000 0.2975 1000000 0.000130222125139

Excel formula:

=PR(507.6, 3025000, 0.2975, 1000000, 0.000130222125139)

Expected output:

Property Value
phase l
T 299
P 1000000
V_l 0.000130222
V_g

Python Code

Show Code
from thermo.eos import PR as thermo_pr

def pr(critical_temperature, critical_pressure, omega, temperature=None, pressure=None, molar_volume=None):
    """
    Solve pure-component Peng-Robinson EOS and return key phase-state properties.

    See: https://thermo.readthedocs.io/thermo.eos.html#thermo.eos.PR

    This example function is provided as-is without any representation of accuracy.

    Args:
        critical_temperature (float): Critical temperature (K).
        critical_pressure (float): Critical pressure (Pa).
        omega (float): Acentric factor (-).
        temperature (float, optional): Temperature (K). Default is None.
        pressure (float, optional): Pressure (Pa). Default is None.
        molar_volume (float, optional): Molar volume (m^3/mol). Default is None.

    Returns:
        list[list]: 2D array with EOS phase and selected state properties.
    """
    try:
        specified = 0
        for value in [temperature, pressure, molar_volume]:
            if value is not None:
                specified += 1
        if specified < 2:
            return "Error: At least two of temperature, pressure, and molar_volume must be provided"

        eos = thermo_pr(Tc=critical_temperature, Pc=critical_pressure, omega=omega, T=temperature, P=pressure, V=molar_volume)

        return [
            ["Property", "Value"],
            ["phase", str(getattr(eos, "phase", ""))],
            ["T", getattr(eos, "T", None)],
            ["P", getattr(eos, "P", None)],
            ["V_l", getattr(eos, "V_l", None)],
            ["V_g", getattr(eos, "V_g", None)]
        ]
    except Exception as e:
        return f"Error: {str(e)}"

Online Calculator

Critical temperature (K).
Critical pressure (Pa).
Acentric factor (-).
Temperature (K).
Pressure (Pa).
Molar volume (m^3/mol).

PR_WATER_K_VALUE

This function estimates a component equilibrium ratio against water using the Peng-Robinson water heuristic.

It applies:

K_i = 10^6\frac{P_{r,i}}{T_{r,i}}

where reduced properties are formed from system and critical conditions.

Excel Usage

=PR_WATER_K_VALUE(temperature, pressure, critical_temperature, critical_pressure)
  • temperature (float, required): System temperature (K).
  • pressure (float, required): System pressure (Pa).
  • critical_temperature (float, required): Component critical temperature (K).
  • critical_pressure (float, required): Component critical pressure (Pa).

Returns (float): Estimated hydrocarbon-water equilibrium K-value.

Example 1: Octane-like case near ambient pressure

Inputs:

temperature pressure critical_temperature critical_pressure
300 100000 568.7 2490000

Excel formula:

=PR_WATER_K_VALUE(300, 100000, 568.7, 2490000)

Expected output:

76131.2

Example 2: Elevated pressure case

Inputs:

temperature pressure critical_temperature critical_pressure
320 500000 568.7 2490000

Excel formula:

=PR_WATER_K_VALUE(320, 500000, 568.7, 2490000)

Expected output:

356865

Example 3: Light hydrocarbon-like case

Inputs:

temperature pressure critical_temperature critical_pressure
280 1000000 305.3 4880000

Excel formula:

=PR_WATER_K_VALUE(280, 1000000, 305.3, 4880000)

Expected output:

223434

Example 4: Warmer process condition

Inputs:

temperature pressure critical_temperature critical_pressure
360 200000 540.2 2736000

Excel formula:

=PR_WATER_K_VALUE(360, 200000, 540.2, 2736000)

Expected output:

109690

Python Code

Show Code
from chemicals.flash_basic import PR_water_K_value as chemicals_pr_water_k_value

def pr_water_k_value(temperature, pressure, critical_temperature, critical_pressure):
    """
    Estimate hydrocarbon-water equilibrium K-value with the Peng-Robinson heuristic.

    See: https://chemicals.readthedocs.io/chemicals.flash_basic.html#chemicals.flash_basic.PR_water_K_value

    This example function is provided as-is without any representation of accuracy.

    Args:
        temperature (float): System temperature (K).
        pressure (float): System pressure (Pa).
        critical_temperature (float): Component critical temperature (K).
        critical_pressure (float): Component critical pressure (Pa).

    Returns:
        float: Estimated hydrocarbon-water equilibrium K-value.
    """
    try:
        return chemicals_pr_water_k_value(temperature, pressure, critical_temperature, critical_pressure)
    except Exception as e:
        return f"Error: {str(e)}"

Online Calculator

System temperature (K).
System pressure (Pa).
Component critical temperature (K).
Component critical pressure (Pa).

PRMIX

This function initializes a Peng-Robinson mixture EOS using mixture composition, critical properties, and optional binary interaction parameters.

With two of temperature, pressure, and molar volume specified, it solves the mixture state and returns key phase, volume-root, and fugacity outputs.

Excel Usage

=PRMIX(critical_temperatures, critical_pressures, omegas, zs, kijs, temperature, pressure, molar_volume, fugacities, only_liquid, only_vapor)
  • critical_temperatures (list[list], required): Critical temperatures for all components (K).
  • critical_pressures (list[list], required): Critical pressures for all components (Pa).
  • omegas (list[list], required): Acentric factors for all components (-).
  • zs (list[list], required): Overall component mole fractions (-).
  • kijs (list[list], optional, default: null): Binary interaction matrix as an n by n range (-).
  • temperature (float, optional, default: null): Temperature (K).
  • pressure (float, optional, default: null): Pressure (Pa).
  • molar_volume (float, optional, default: null): Molar volume (m^3/mol).
  • fugacities (bool, optional, default: true): Whether to calculate fugacity properties.
  • only_liquid (bool, optional, default: false): If true, keep only liquid root properties.
  • only_vapor (bool, optional, default: false): If true, keep only vapor root properties.

Returns (list[list]): 2D array with phase label, solved state variables, roots, and fugacity vectors.

Example 1: Binary PR mixture EOS with temperature and pressure

Inputs:

critical_temperatures critical_pressures omegas zs kijs temperature pressure
126.1 190.6 3394000 4604000 0.04 0.011 0.5 0.5 0 0 115 1000000
0 0

Excel formula:

=PRMIX({126.1,190.6}, {3394000,4604000}, {0.04,0.011}, {0.5,0.5}, {0,0;0,0}, 115, 1000000)

Expected output:

Property Value
phase l/g
T 115
P 1000000
V_l 0.0000362574
V_g 0.000700666
fugacities_l [793860.8382114592, 73468.55225303891]
fugacities_g [436530.9247009118, 358114.638275324]
Example 2: Binary PR mixture EOS without explicit kijs

Inputs:

critical_temperatures critical_pressures omegas zs temperature pressure
126.1 190.6 3394000 4604000 0.04 0.011 0.5 0.5 115 1000000

Excel formula:

=PRMIX({126.1,190.6}, {3394000,4604000}, {0.04,0.011}, {0.5,0.5}, 115, 1000000)

Expected output:

Property Value
phase l/g
T 115
P 1000000
V_l 0.0000362574
V_g 0.000700666
fugacities_l [793860.8382114592, 73468.55225303891]
fugacities_g [436530.9247009118, 358114.638275324]
Example 3: Binary PR mixture EOS with temperature and volume

Inputs:

critical_temperatures critical_pressures omegas zs kijs temperature molar_volume
126.1 190.6 3394000 4604000 0.04 0.011 0.5 0.5 0 0 115 0.00070066592313
0 0

Excel formula:

=PRMIX({126.1,190.6}, {3394000,4604000}, {0.04,0.011}, {0.5,0.5}, {0,0;0,0}, 115, 0.00070066592313)

Expected output:

Property Value
phase g
T 115
P 1000000
V_l
V_g 0.000700666
fugacities_l None
fugacities_g [436530.92470264115, 358114.63827627915]
Example 4: Binary PR mixture EOS with pressure and volume

Inputs:

critical_temperatures critical_pressures omegas zs kijs pressure molar_volume
126.1 190.6 3394000 4604000 0.04 0.011 0.5 0.5 0 0 1000000 0.00070066592313
0 0

Excel formula:

=PRMIX({126.1,190.6}, {3394000,4604000}, {0.04,0.011}, {0.5,0.5}, {0,0;0,0}, 1000000, 0.00070066592313)

Expected output:

Property Value
phase g
T 115
P 1000000
V_l
V_g 0.000700666
fugacities_l None
fugacities_g [436530.9247004668, 358114.6382742559]

Python Code

Show Code
from thermo.eos_mix import PRMIX as thermo_prmix

def prmix(critical_temperatures, critical_pressures, omegas, zs, kijs=None, temperature=None, pressure=None, molar_volume=None, fugacities=True, only_liquid=False, only_vapor=False):
    """
    Solve Peng-Robinson mixture EOS and return key phase and fugacity metrics.

    See: https://thermo.readthedocs.io/thermo.eos_mix.html#thermo.eos_mix.PRMIX

    This example function is provided as-is without any representation of accuracy.

    Args:
        critical_temperatures (list[list]): Critical temperatures for all components (K).
        critical_pressures (list[list]): Critical pressures for all components (Pa).
        omegas (list[list]): Acentric factors for all components (-).
        zs (list[list]): Overall component mole fractions (-).
        kijs (list[list], optional): Binary interaction matrix as an n by n range (-). Default is None.
        temperature (float, optional): Temperature (K). Default is None.
        pressure (float, optional): Pressure (Pa). Default is None.
        molar_volume (float, optional): Molar volume (m^3/mol). Default is None.
        fugacities (bool, optional): Whether to calculate fugacity properties. Default is True.
        only_liquid (bool, optional): If true, keep only liquid root properties. Default is False.
        only_vapor (bool, optional): If true, keep only vapor root properties. Default is False.

    Returns:
        list[list]: 2D array with phase label, solved state variables, roots, and fugacity vectors.
    """
    try:
        def to_list(x):
            if isinstance(x, list):
                out = []
                for row in x:
                    if isinstance(row, list):
                        for val in row:
                            if val is not None and val != "":
                                out.append(float(val))
                    elif row is not None and row != "":
                        out.append(float(row))
                return out
            if x is None or x == "":
                return []
            return [float(x)]

        def to_matrix(x):
            if x is None:
                return None
            if not isinstance(x, list):
                return None
            matrix = []
            for row in x:
                if isinstance(row, list):
                    clean_row = []
                    for val in row:
                        if val is None or val == "":
                            clean_row.append(0.0)
                        else:
                            clean_row.append(float(val))
                    if len(clean_row) > 0:
                        matrix.append(clean_row)
            return matrix if len(matrix) > 0 else None

        tc_vals = to_list(critical_temperatures)
        pc_vals = to_list(critical_pressures)
        omega_vals = to_list(omegas)
        z_vals = to_list(zs)
        kij_vals = to_matrix(kijs)

        n = len(z_vals)
        if n == 0 or len(tc_vals) != n or len(pc_vals) != n or len(omega_vals) != n:
            return "Error: critical_temperatures, critical_pressures, omegas, and zs must be non-empty and have the same length"

        specified = 0
        for value in [temperature, pressure, molar_volume]:
            if value is not None:
                specified += 1
        if specified < 2:
            return "Error: At least two of temperature, pressure, and molar_volume must be provided"

        eos = thermo_prmix(Tcs=tc_vals, Pcs=pc_vals, omegas=omega_vals, zs=z_vals, kijs=kij_vals, T=temperature, P=pressure, V=molar_volume, fugacities=fugacities, only_l=only_liquid, only_g=only_vapor)

        return [
            ["Property", "Value"],
            ["phase", str(getattr(eos, "phase", ""))],
            ["T", getattr(eos, "T", None)],
            ["P", getattr(eos, "P", None)],
            ["V_l", getattr(eos, "V_l", None)],
            ["V_g", getattr(eos, "V_g", None)],
            ["fugacities_l", str(getattr(eos, "fugacities_l", None))],
            ["fugacities_g", str(getattr(eos, "fugacities_g", None))]
        ]
    except Exception as e:
        return f"Error: {str(e)}"

Online Calculator

Critical temperatures for all components (K).
Critical pressures for all components (Pa).
Acentric factors for all components (-).
Overall component mole fractions (-).
Binary interaction matrix as an n by n range (-).
Temperature (K).
Pressure (Pa).
Molar volume (m^3/mol).
Whether to calculate fugacity properties.
If true, keep only liquid root properties.
If true, keep only vapor root properties.

PRSV

This function initializes a pure-component Peng-Robinson-Stryjek-Vera EOS using critical properties and optional fit parameter \kappa_1.

With two of temperature, pressure, and molar volume specified, it solves the state and returns key phase and volume properties.

Excel Usage

=PRSV(critical_temperature, critical_pressure, omega, temperature, pressure, molar_volume, kappa_one)
  • critical_temperature (float, required): Critical temperature (K).
  • critical_pressure (float, required): Critical pressure (Pa).
  • omega (float, required): Acentric factor (-).
  • temperature (float, optional, default: null): Temperature (K).
  • pressure (float, optional, default: null): Pressure (Pa).
  • molar_volume (float, optional, default: null): Molar volume (m^3/mol).
  • kappa_one (float, optional, default: null): PRSV fit parameter kappa1 (-).

Returns (list[list]): 2D array with EOS phase and selected state properties.

Example 1: Temperature-pressure initialization with kappa1

Inputs:

critical_temperature critical_pressure omega temperature pressure kappa_one
507.6 3025000 0.2975 299 1000000 0.05104

Excel formula:

=PRSV(507.6, 3025000, 0.2975, 299, 1000000, 0.05104)

Expected output:

Property Value
phase l
T 299
P 1000000
V_l 0.000130127
V_g
Example 2: Temperature-pressure initialization without kappa1

Inputs:

critical_temperature critical_pressure omega temperature pressure
507.6 3025000 0.2975 320 1000000

Excel formula:

=PRSV(507.6, 3025000, 0.2975, 320, 1000000)

Expected output:

Property Value
phase l
T 320
P 1000000
V_l 0.000133867
V_g
Example 3: Temperature-volume initialization

Inputs:

critical_temperature critical_pressure omega temperature molar_volume kappa_one
507.6 3025000 0.2975 299 0.000130126913554 0.05104

Excel formula:

=PRSV(507.6, 3025000, 0.2975, 299, 0.000130126913554, 0.05104)

Expected output:

Property Value
phase l
T 299
P 1000000
V_l 0.000130127
V_g
Example 4: Pressure-volume initialization

Inputs:

critical_temperature critical_pressure omega pressure molar_volume kappa_one
507.6 3025000 0.2975 1000000 0.000130126913554 0.05104

Excel formula:

=PRSV(507.6, 3025000, 0.2975, 1000000, 0.000130126913554, 0.05104)

Expected output:

Property Value
phase l
T 299
P 1000000
V_l 0.000130127
V_g

Python Code

Show Code
from thermo.eos import PRSV as thermo_prsv

def prsv(critical_temperature, critical_pressure, omega, temperature=None, pressure=None, molar_volume=None, kappa_one=None):
    """
    Solve pure-component PRSV EOS and return key phase-state properties.

    See: https://thermo.readthedocs.io/thermo.eos.html#thermo.eos.PRSV

    This example function is provided as-is without any representation of accuracy.

    Args:
        critical_temperature (float): Critical temperature (K).
        critical_pressure (float): Critical pressure (Pa).
        omega (float): Acentric factor (-).
        temperature (float, optional): Temperature (K). Default is None.
        pressure (float, optional): Pressure (Pa). Default is None.
        molar_volume (float, optional): Molar volume (m^3/mol). Default is None.
        kappa_one (float, optional): PRSV fit parameter kappa1 (-). Default is None.

    Returns:
        list[list]: 2D array with EOS phase and selected state properties.
    """
    try:
        specified = 0
        for value in [temperature, pressure, molar_volume]:
            if value is not None:
                specified += 1
        if specified < 2:
            return "Error: At least two of temperature, pressure, and molar_volume must be provided"

        eos = thermo_prsv(Tc=critical_temperature, Pc=critical_pressure, omega=omega, T=temperature, P=pressure, V=molar_volume, kappa1=kappa_one)

        return [
            ["Property", "Value"],
            ["phase", str(getattr(eos, "phase", ""))],
            ["T", getattr(eos, "T", None)],
            ["P", getattr(eos, "P", None)],
            ["V_l", getattr(eos, "V_l", None)],
            ["V_g", getattr(eos, "V_g", None)]
        ]
    except Exception as e:
        return f"Error: {str(e)}"

Online Calculator

Critical temperature (K).
Critical pressure (Pa).
Acentric factor (-).
Temperature (K).
Pressure (Pa).
Molar volume (m^3/mol).
PRSV fit parameter kappa1 (-).

PRSVMIX

This function initializes a PRSV mixture EOS using composition, critical properties, optional binary interaction parameters, and optional component \kappa_1 values.

With two of temperature, pressure, and molar volume specified, it solves the mixture state and returns key phase, volume-root, and fugacity outputs.

Excel Usage

=PRSVMIX(critical_temperatures, critical_pressures, omegas, zs, kijs, temperature, pressure, molar_volume, kappa_ones, fugacities, only_liquid, only_vapor)
  • critical_temperatures (list[list], required): Critical temperatures for all components (K).
  • critical_pressures (list[list], required): Critical pressures for all components (Pa).
  • omegas (list[list], required): Acentric factors for all components (-).
  • zs (list[list], required): Overall component mole fractions (-).
  • kijs (list[list], optional, default: null): Binary interaction matrix as an n by n range (-).
  • temperature (float, optional, default: null): Temperature (K).
  • pressure (float, optional, default: null): Pressure (Pa).
  • molar_volume (float, optional, default: null): Molar volume (m^3/mol).
  • kappa_ones (list[list], optional, default: null): Optional PRSV kappa1 values by component (-).
  • fugacities (bool, optional, default: true): Whether to calculate fugacity properties.
  • only_liquid (bool, optional, default: false): If true, keep only liquid root properties.
  • only_vapor (bool, optional, default: false): If true, keep only vapor root properties.

Returns (list[list]): 2D array with phase label, solved state variables, roots, and fugacity vectors.

Example 1: Binary PRSV mixture EOS with temperature and pressure

Inputs:

critical_temperatures critical_pressures omegas zs kijs temperature pressure
126.1 190.6 3394000 4604000 0.04 0.011 0.5 0.5 0 0 115 1000000
0 0

Excel formula:

=PRSVMIX({126.1,190.6}, {3394000,4604000}, {0.04,0.011}, {0.5,0.5}, {0,0;0,0}, 115, 1000000)

Expected output:

Property Value
phase l/g
T 115
P 1000000
V_l 0.0000362355
V_g 0.000700242
fugacities_l [794057.5831840492, 72851.22327178437]
fugacities_g [436553.6561835043, 357878.1106688994]
Example 2: Binary PRSV mixture EOS with kappa1 values

Inputs:

critical_temperatures critical_pressures omegas zs kijs temperature pressure kappa_ones
126.1 190.6 3394000 4604000 0.04 0.011 0.5 0.5 0 0 115 1000000 0 0
0 0

Excel formula:

=PRSVMIX({126.1,190.6}, {3394000,4604000}, {0.04,0.011}, {0.5,0.5}, {0,0;0,0}, 115, 1000000, {0,0})

Expected output:

Property Value
phase l/g
T 115
P 1000000
V_l 0.0000362355
V_g 0.000700242
fugacities_l [794057.5831840492, 72851.22327178437]
fugacities_g [436553.6561835043, 357878.1106688994]
Example 3: Binary PRSV mixture EOS with temperature and volume

Inputs:

critical_temperatures critical_pressures omegas zs kijs temperature molar_volume
126.1 190.6 3394000 4604000 0.04 0.011 0.5 0.5 0 0 115 0.0007
0 0

Excel formula:

=PRSVMIX({126.1,190.6}, {3394000,4604000}, {0.04,0.011}, {0.5,0.5}, {0,0;0,0}, 115, 0.0007)

Expected output:

Property Value
phase g
T 115
P 1000230
V_l
V_g 0.0007
fugacities_l None
fugacities_g [436641.52794603555, 357926.50637318793]
Example 4: Binary PRSV mixture EOS with pressure and volume

Inputs:

critical_temperatures critical_pressures omegas zs kijs pressure molar_volume
126.1 190.6 3394000 4604000 0.04 0.011 0.5 0.5 0 0 1000000 0.0007
0 0

Excel formula:

=PRSVMIX({126.1,190.6}, {3394000,4604000}, {0.04,0.011}, {0.5,0.5}, {0,0;0,0}, 1000000, 0.0007)

Expected output:

Property Value
phase g
T 114.983
P 1000000
V_l
V_g 0.0007
fugacities_l None
fugacities_g [436531.1021185319, 357823.7636471351]

Python Code

Show Code
from thermo.eos_mix import PRSVMIX as thermo_prsvmix

def prsvmix(critical_temperatures, critical_pressures, omegas, zs, kijs=None, temperature=None, pressure=None, molar_volume=None, kappa_ones=None, fugacities=True, only_liquid=False, only_vapor=False):
    """
    Solve PRSV mixture EOS and return key phase and fugacity metrics.

    See: https://thermo.readthedocs.io/thermo.eos_mix.html#thermo.eos_mix.PRSVMIX

    This example function is provided as-is without any representation of accuracy.

    Args:
        critical_temperatures (list[list]): Critical temperatures for all components (K).
        critical_pressures (list[list]): Critical pressures for all components (Pa).
        omegas (list[list]): Acentric factors for all components (-).
        zs (list[list]): Overall component mole fractions (-).
        kijs (list[list], optional): Binary interaction matrix as an n by n range (-). Default is None.
        temperature (float, optional): Temperature (K). Default is None.
        pressure (float, optional): Pressure (Pa). Default is None.
        molar_volume (float, optional): Molar volume (m^3/mol). Default is None.
        kappa_ones (list[list], optional): Optional PRSV kappa1 values by component (-). Default is None.
        fugacities (bool, optional): Whether to calculate fugacity properties. Default is True.
        only_liquid (bool, optional): If true, keep only liquid root properties. Default is False.
        only_vapor (bool, optional): If true, keep only vapor root properties. Default is False.

    Returns:
        list[list]: 2D array with phase label, solved state variables, roots, and fugacity vectors.
    """
    try:
        def to_list(x):
            if isinstance(x, list):
                out = []
                for row in x:
                    if isinstance(row, list):
                        for val in row:
                            if val is not None and val != "":
                                out.append(float(val))
                    elif row is not None and row != "":
                        out.append(float(row))
                return out
            if x is None or x == "":
                return []
            return [float(x)]

        def to_matrix(x):
            if x is None:
                return None
            if not isinstance(x, list):
                return None
            matrix = []
            for row in x:
                if isinstance(row, list):
                    clean_row = []
                    for val in row:
                        if val is None or val == "":
                            clean_row.append(0.0)
                        else:
                            clean_row.append(float(val))
                    if len(clean_row) > 0:
                        matrix.append(clean_row)
            return matrix if len(matrix) > 0 else None

        tc_vals = to_list(critical_temperatures)
        pc_vals = to_list(critical_pressures)
        omega_vals = to_list(omegas)
        z_vals = to_list(zs)
        kij_vals = to_matrix(kijs)
        kappa_vals = to_list(kappa_ones)
        if len(kappa_vals) == 0:
            kappa_vals = None

        n = len(z_vals)
        if n == 0 or len(tc_vals) != n or len(pc_vals) != n or len(omega_vals) != n:
            return "Error: critical_temperatures, critical_pressures, omegas, and zs must be non-empty and have the same length"
        if kappa_vals is not None and len(kappa_vals) != n:
            return "Error: kappa_ones must be empty or have one value per component"

        specified = 0
        for value in [temperature, pressure, molar_volume]:
            if value is not None:
                specified += 1
        if specified < 2:
            return "Error: At least two of temperature, pressure, and molar_volume must be provided"

        eos = thermo_prsvmix(Tcs=tc_vals, Pcs=pc_vals, omegas=omega_vals, zs=z_vals, kijs=kij_vals, T=temperature, P=pressure, V=molar_volume, kappa1s=kappa_vals, fugacities=fugacities, only_l=only_liquid, only_g=only_vapor)

        return [
            ["Property", "Value"],
            ["phase", str(getattr(eos, "phase", ""))],
            ["T", getattr(eos, "T", None)],
            ["P", getattr(eos, "P", None)],
            ["V_l", getattr(eos, "V_l", None)],
            ["V_g", getattr(eos, "V_g", None)],
            ["fugacities_l", str(getattr(eos, "fugacities_l", None))],
            ["fugacities_g", str(getattr(eos, "fugacities_g", None))]
        ]
    except Exception as e:
        return f"Error: {str(e)}"

Online Calculator

Critical temperatures for all components (K).
Critical pressures for all components (Pa).
Acentric factors for all components (-).
Overall component mole fractions (-).
Binary interaction matrix as an n by n range (-).
Temperature (K).
Pressure (Pa).
Molar volume (m^3/mol).
Optional PRSV kappa1 values by component (-).
Whether to calculate fugacity properties.
If true, keep only liquid root properties.
If true, keep only vapor root properties.

RACHFORD_RICE

This function computes vapor fraction and phase compositions by solving the classical Rachford-Rice objective for specified overall mole fractions and K-values.

The equation is:

\sum_i \frac{z_i(K_i-1)}{1 + VF(K_i-1)} = 0

Optional derivative flags allow secant, Newton, or Halley-style updates.

Excel Usage

=RACHFORD_RICE(zs, ks, use_first_derivative, use_second_derivative, guess)
  • zs (list[list], required): Overall mole fractions as a selected range (-).
  • ks (list[list], required): Equilibrium K-values as a selected range (-).
  • use_first_derivative (bool, optional, default: false): Use first derivative in solve step (Newton-Raphson).
  • use_second_derivative (bool, optional, default: false): Use second derivative in solve step (Halley method).
  • guess (float, optional, default: null): Initial vapor-fraction guess (-).

Returns (list[list]): 2D array containing vapor fraction and phase compositions.

Example 1: Classical Rachford-Rice solve

Inputs:

zs ks
0.5 0.3 0.2 1.685 0.742 0.532

Excel formula:

=RACHFORD_RICE({0.5,0.3,0.2}, {1.685,0.742,0.532})

Expected output:

Property Value
VF 0.69073
xs [0.33940869696634357, 0.3650560590371706, 0.2955352439964858]
ys [0.5719036543882889, 0.27087159580558057, 0.15722474980613044]
Example 2: Newton-Raphson variant

Inputs:

zs ks use_first_derivative
0.5 0.3 0.2 1.685 0.742 0.532 true

Excel formula:

=RACHFORD_RICE({0.5,0.3,0.2}, {1.685,0.742,0.532}, TRUE)

Expected output:

Property Value
VF 0.69073
xs [0.33940869696634357, 0.3650560590371706, 0.2955352439964858]
ys [0.5719036543882889, 0.27087159580558057, 0.15722474980613044]
Example 3: Halley variant

Inputs:

zs ks use_first_derivative use_second_derivative
0.5 0.3 0.2 1.685 0.742 0.532 true true

Excel formula:

=RACHFORD_RICE({0.5,0.3,0.2}, {1.685,0.742,0.532}, TRUE, TRUE)

Expected output:

Property Value
VF 0.69073
xs [0.33940869696634357, 0.3650560590371706, 0.2955352439964858]
ys [0.5719036543882889, 0.27087159580558057, 0.15722474980613044]
Example 4: Custom initial guess

Inputs:

zs ks guess
0.4 0.4 0.2 2 0.8 0.4 0.5

Excel formula:

=RACHFORD_RICE({0.4,0.4,0.2}, {2,0.8,0.4}, 0.5)

Expected output:

Property Value
VF 0.518417
xs [0.26343228527928286, 0.4462708596090614, 0.2902968548930794]
ys [0.5268645705585657, 0.35701668768724915, 0.11611874195723176]

Python Code

Show Code
from chemicals.rachford_rice import Rachford_Rice_solution as chemicals_rachford_rice_solution

def rachford_rice(zs, ks, use_first_derivative=False, use_second_derivative=False, guess=None):
    """
    Solve the classical Rachford-Rice flash equation.

    See: https://chemicals.readthedocs.io/chemicals.rachford_rice.html#chemicals.rachford_rice.Rachford_Rice_solution

    This example function is provided as-is without any representation of accuracy.

    Args:
        zs (list[list]): Overall mole fractions as a selected range (-).
        ks (list[list]): Equilibrium K-values as a selected range (-).
        use_first_derivative (bool, optional): Use first derivative in solve step (Newton-Raphson). Default is False.
        use_second_derivative (bool, optional): Use second derivative in solve step (Halley method). Default is False.
        guess (float, optional): Initial vapor-fraction guess (-). Default is None.

    Returns:
        list[list]: 2D array containing vapor fraction and phase compositions.
    """
    try:
        def to_list(x):
            if isinstance(x, list):
                out = []
                for row in x:
                    if isinstance(row, list):
                        for val in row:
                            if val is not None and val != "":
                                out.append(float(val))
                    elif row is not None and row != "":
                        out.append(float(row))
                return out
            if x is None or x == "":
                return []
            return [float(x)]

        z_vals = to_list(zs)
        k_vals = to_list(ks)
        if len(z_vals) == 0 or len(z_vals) != len(k_vals):
            return "Error: zs and ks must be non-empty and have the same length"

        vf, xs, ys = chemicals_rachford_rice_solution(zs=z_vals, Ks=k_vals, fprime=use_first_derivative, fprime2=use_second_derivative, guess=guess)
        return [["Property", "Value"], ["VF", vf], ["xs", str(xs)], ["ys", str(ys)]]
    except Exception as e:
        return f"Error: {str(e)}"

Online Calculator

Overall mole fractions as a selected range (-).
Equilibrium K-values as a selected range (-).
Use first derivative in solve step (Newton-Raphson).
Use second derivative in solve step (Halley method).
Initial vapor-fraction guess (-).

SAT_ANCILLARY

This function evaluates CoolProp saturation ancillary equations for a selected fluid and property mapping.

It returns the scalar ancillary value for the specified quality branch, input variable, and input value.

Excel Usage

=SAT_ANCILLARY(name, output, quality, input, value)
  • name (str, required): Fluid name understood by CoolProp.
  • output (str, required): Requested output key.
  • quality (int, required): Quality branch selector as integer (0 for saturated liquid, 1 for saturated vapor).
  • input (str, required): Input variable key.
  • value (float, required): Input value in SI units.

Returns (float): Saturation ancillary result for the requested mapping.

Example 1: Water ancillary pressure from temperature on liquid branch

Inputs:

name output quality input value
Water p 0 T 300

Excel formula:

=SAT_ANCILLARY("Water", "p", 0, "T", 300)

Expected output:

3536.79

Example 2: Water ancillary pressure from temperature on vapor branch

Inputs:

name output quality input value
Water p 1 T 350

Excel formula:

=SAT_ANCILLARY("Water", "p", 1, "T", 350)

Expected output:

41681.3

Example 3: Water ancillary density from temperature on liquid branch

Inputs:

name output quality input value
Water rho 0 T 320

Excel formula:

=SAT_ANCILLARY("Water", "rho", 0, "T", 320)

Expected output:

54946

Example 4: Water ancillary density from temperature on vapor branch

Inputs:

name output quality input value
Water rho 1 T 320

Excel formula:

=SAT_ANCILLARY("Water", "rho", 1, "T", 320)

Expected output:

3.97815

Python Code

Show Code
from CoolProp.CoolProp import saturation_ancillary as coolprop_saturation_ancillary

def sat_ancillary(name, output, quality, input, value):
    """
    Evaluate a CoolProp saturation ancillary correlation value.

    See: https://coolprop.org/apidoc/CoolProp.CoolProp.html#CoolProp.CoolProp.saturation_ancillary

    This example function is provided as-is without any representation of accuracy.

    Args:
        name (str): Fluid name understood by CoolProp.
        output (str): Requested output key.
        quality (int): Quality branch selector as integer (0 for saturated liquid, 1 for saturated vapor).
        input (str): Input variable key.
        value (float): Input value in SI units.

    Returns:
        float: Saturation ancillary result for the requested mapping.
    """
    try:
      def normalize_key(key):
        if key is None:
          return None
        text = str(key).strip()
        lowered = text.lower()
        aliases = {
          "p": "P",
          "pressure": "P",
          "t": "T",
          "temperature": "T",
          "rho": "Dmolar",
          "density": "Dmolar",
          "dmolar": "Dmolar",
          "hmolar": "Hmolar",
          "smolar": "Smolar"
        }
        return aliases.get(lowered, text)

      output_key = normalize_key(output)
      input_key = normalize_key(input)
      return coolprop_saturation_ancillary(name, output_key, quality, input_key, value)
    except Exception as e:
        return f"Error: {str(e)}"

Online Calculator

Fluid name understood by CoolProp.
Requested output key.
Quality branch selector as integer (0 for saturated liquid, 1 for saturated vapor).
Input variable key.
Input value in SI units.

SRK

This function initializes a pure-component SRK cubic EOS with critical properties and two specified state variables among temperature, pressure, and molar volume.

It returns key solved properties such as phase label, pressure, temperature, and liquid and vapor molar-volume roots when available.

Excel Usage

=SRK(critical_temperature, critical_pressure, omega, temperature, pressure, molar_volume)
  • critical_temperature (float, required): Critical temperature (K).
  • critical_pressure (float, required): Critical pressure (Pa).
  • omega (float, required): Acentric factor (-).
  • temperature (float, optional, default: null): Temperature (K).
  • pressure (float, optional, default: null): Pressure (Pa).
  • molar_volume (float, optional, default: null): Molar volume (m^3/mol).

Returns (list[list]): 2D array with EOS phase and selected state properties.

Example 1: Temperature-pressure initialization

Inputs:

critical_temperature critical_pressure omega temperature pressure
507.6 3025000 0.2975 299 1000000

Excel formula:

=SRK(507.6, 3025000, 0.2975, 299, 1000000)

Expected output:

Property Value
phase l
T 299
P 1000000
V_l 0.000146821
V_g
Example 2: High temperature and pressure initialization

Inputs:

critical_temperature critical_pressure omega temperature pressure
507.6 3025000 0.2975 400 1000000

Excel formula:

=SRK(507.6, 3025000, 0.2975, 400, 1000000)

Expected output:

Property Value
phase l/g
T 400
P 1000000
V_l 0.000176993
V_g 0.00219139
Example 3: Temperature-volume initialization

Inputs:

critical_temperature critical_pressure omega temperature molar_volume
507.6 3025000 0.2975 299 0.000146821077354

Excel formula:

=SRK(507.6, 3025000, 0.2975, 299, 0.000146821077354)

Expected output:

Property Value
phase l
T 299
P 1000000
V_l 0.000146821
V_g
Example 4: Pressure-volume initialization

Inputs:

critical_temperature critical_pressure omega pressure molar_volume
507.6 3025000 0.2975 1000000 0.000146821077354

Excel formula:

=SRK(507.6, 3025000, 0.2975, 1000000, 0.000146821077354)

Expected output:

Property Value
phase l
T 299
P 1000000
V_l 0.000146821
V_g

Python Code

Show Code
from thermo.eos import SRK as thermo_srk

def srk(critical_temperature, critical_pressure, omega, temperature=None, pressure=None, molar_volume=None):
    """
    Solve pure-component Soave-Redlich-Kwong EOS and return key phase-state properties.

    See: https://thermo.readthedocs.io/thermo.eos.html#thermo.eos.SRK

    This example function is provided as-is without any representation of accuracy.

    Args:
        critical_temperature (float): Critical temperature (K).
        critical_pressure (float): Critical pressure (Pa).
        omega (float): Acentric factor (-).
        temperature (float, optional): Temperature (K). Default is None.
        pressure (float, optional): Pressure (Pa). Default is None.
        molar_volume (float, optional): Molar volume (m^3/mol). Default is None.

    Returns:
        list[list]: 2D array with EOS phase and selected state properties.
    """
    try:
        specified = 0
        for value in [temperature, pressure, molar_volume]:
            if value is not None:
                specified += 1
        if specified < 2:
            return "Error: At least two of temperature, pressure, and molar_volume must be provided"

        eos = thermo_srk(Tc=critical_temperature, Pc=critical_pressure, omega=omega, T=temperature, P=pressure, V=molar_volume)

        return [
            ["Property", "Value"],
            ["phase", str(getattr(eos, "phase", ""))],
            ["T", getattr(eos, "T", None)],
            ["P", getattr(eos, "P", None)],
            ["V_l", getattr(eos, "V_l", None)],
            ["V_g", getattr(eos, "V_g", None)]
        ]
    except Exception as e:
        return f"Error: {str(e)}"

Online Calculator

Critical temperature (K).
Critical pressure (Pa).
Acentric factor (-).
Temperature (K).
Pressure (Pa).
Molar volume (m^3/mol).

SRKMIX

This function initializes an SRK mixture EOS using mixture composition, critical properties, and optional binary interaction parameters.

With two of temperature, pressure, and molar volume specified, it solves the mixture state and returns key phase, volume-root, and fugacity outputs.

Excel Usage

=SRKMIX(critical_temperatures, critical_pressures, omegas, zs, kijs, temperature, pressure, molar_volume, fugacities, only_liquid, only_vapor)
  • critical_temperatures (list[list], required): Critical temperatures for all components (K).
  • critical_pressures (list[list], required): Critical pressures for all components (Pa).
  • omegas (list[list], required): Acentric factors for all components (-).
  • zs (list[list], required): Overall component mole fractions (-).
  • kijs (list[list], optional, default: null): Binary interaction matrix as an n by n range (-).
  • temperature (float, optional, default: null): Temperature (K).
  • pressure (float, optional, default: null): Pressure (Pa).
  • molar_volume (float, optional, default: null): Molar volume (m^3/mol).
  • fugacities (bool, optional, default: true): Whether to calculate fugacity properties.
  • only_liquid (bool, optional, default: false): If true, keep only liquid root properties.
  • only_vapor (bool, optional, default: false): If true, keep only vapor root properties.

Returns (list[list]): 2D array with phase label, solved state variables, roots, and fugacity vectors.

Example 1: Binary SRK mixture EOS with temperature and pressure

Inputs:

critical_temperatures critical_pressures omegas zs kijs temperature pressure
126.1 190.6 3394000 4604000 0.04 0.011 0.5 0.5 0 0 115 1000000
0 0

Excel formula:

=SRKMIX({126.1,190.6}, {3394000,4604000}, {0.04,0.011}, {0.5,0.5}, {0,0;0,0}, 115, 1000000)

Expected output:

Property Value
phase l/g
T 115
P 1000000
V_l 0.0000410476
V_g 0.000711016
fugacities_l [817841.6430546879, 72382.81925202608]
fugacities_g [442137.12801246054, 361820.7921190941]
Example 2: Binary SRK mixture EOS without explicit kijs

Inputs:

critical_temperatures critical_pressures omegas zs temperature pressure
126.1 190.6 3394000 4604000 0.04 0.011 0.5 0.5 115 1000000

Excel formula:

=SRKMIX({126.1,190.6}, {3394000,4604000}, {0.04,0.011}, {0.5,0.5}, 115, 1000000)

Expected output:

Property Value
phase l/g
T 115
P 1000000
V_l 0.0000410476
V_g 0.000711016
fugacities_l [817841.6430546879, 72382.81925202608]
fugacities_g [442137.12801246054, 361820.7921190941]
Example 3: Binary SRK mixture EOS with temperature and volume

Inputs:

critical_temperatures critical_pressures omegas zs kijs temperature molar_volume
126.1 190.6 3394000 4604000 0.04 0.011 0.5 0.5 0 0 115 0.0007110158049
0 0

Excel formula:

=SRKMIX({126.1,190.6}, {3394000,4604000}, {0.04,0.011}, {0.5,0.5}, {0,0;0,0}, 115, 0.0007110158049)

Expected output:

Property Value
phase g
T 115
P 1000000
V_l
V_g 0.000711016
fugacities_l None
fugacities_g [442137.12804141204, 361820.7921350346]
Example 4: Binary SRK mixture EOS with pressure and volume

Inputs:

critical_temperatures critical_pressures omegas zs kijs pressure molar_volume
126.1 190.6 3394000 4604000 0.04 0.011 0.5 0.5 0 0 1000000 0.0007110158049
0 0

Excel formula:

=SRKMIX({126.1,190.6}, {3394000,4604000}, {0.04,0.011}, {0.5,0.5}, {0,0;0,0}, 1000000, 0.0007110158049)

Expected output:

Property Value
phase g
T 115
P 1000000
V_l
V_g 0.000711016
fugacities_l None
fugacities_g [442137.1280054671, 361820.7921014841]

Python Code

Show Code
from thermo.eos_mix import SRKMIX as thermo_srkmix

def srkmix(critical_temperatures, critical_pressures, omegas, zs, kijs=None, temperature=None, pressure=None, molar_volume=None, fugacities=True, only_liquid=False, only_vapor=False):
    """
    Solve SRK mixture EOS and return key phase and fugacity metrics.

    See: https://thermo.readthedocs.io/thermo.eos_mix.html#thermo.eos_mix.SRKMIX

    This example function is provided as-is without any representation of accuracy.

    Args:
        critical_temperatures (list[list]): Critical temperatures for all components (K).
        critical_pressures (list[list]): Critical pressures for all components (Pa).
        omegas (list[list]): Acentric factors for all components (-).
        zs (list[list]): Overall component mole fractions (-).
        kijs (list[list], optional): Binary interaction matrix as an n by n range (-). Default is None.
        temperature (float, optional): Temperature (K). Default is None.
        pressure (float, optional): Pressure (Pa). Default is None.
        molar_volume (float, optional): Molar volume (m^3/mol). Default is None.
        fugacities (bool, optional): Whether to calculate fugacity properties. Default is True.
        only_liquid (bool, optional): If true, keep only liquid root properties. Default is False.
        only_vapor (bool, optional): If true, keep only vapor root properties. Default is False.

    Returns:
        list[list]: 2D array with phase label, solved state variables, roots, and fugacity vectors.
    """
    try:
        def to_list(x):
            if isinstance(x, list):
                out = []
                for row in x:
                    if isinstance(row, list):
                        for val in row:
                            if val is not None and val != "":
                                out.append(float(val))
                    elif row is not None and row != "":
                        out.append(float(row))
                return out
            if x is None or x == "":
                return []
            return [float(x)]

        def to_matrix(x):
            if x is None:
                return None
            if not isinstance(x, list):
                return None
            matrix = []
            for row in x:
                if isinstance(row, list):
                    clean_row = []
                    for val in row:
                        if val is None or val == "":
                            clean_row.append(0.0)
                        else:
                            clean_row.append(float(val))
                    if len(clean_row) > 0:
                        matrix.append(clean_row)
            return matrix if len(matrix) > 0 else None

        tc_vals = to_list(critical_temperatures)
        pc_vals = to_list(critical_pressures)
        omega_vals = to_list(omegas)
        z_vals = to_list(zs)
        kij_vals = to_matrix(kijs)

        n = len(z_vals)
        if n == 0 or len(tc_vals) != n or len(pc_vals) != n or len(omega_vals) != n:
            return "Error: critical_temperatures, critical_pressures, omegas, and zs must be non-empty and have the same length"

        specified = 0
        for value in [temperature, pressure, molar_volume]:
            if value is not None:
                specified += 1
        if specified < 2:
            return "Error: At least two of temperature, pressure, and molar_volume must be provided"

        eos = thermo_srkmix(Tcs=tc_vals, Pcs=pc_vals, omegas=omega_vals, zs=z_vals, kijs=kij_vals, T=temperature, P=pressure, V=molar_volume, fugacities=fugacities, only_l=only_liquid, only_g=only_vapor)

        return [
            ["Property", "Value"],
            ["phase", str(getattr(eos, "phase", ""))],
            ["T", getattr(eos, "T", None)],
            ["P", getattr(eos, "P", None)],
            ["V_l", getattr(eos, "V_l", None)],
            ["V_g", getattr(eos, "V_g", None)],
            ["fugacities_l", str(getattr(eos, "fugacities_l", None))],
            ["fugacities_g", str(getattr(eos, "fugacities_g", None))]
        ]
    except Exception as e:
        return f"Error: {str(e)}"

Online Calculator

Critical temperatures for all components (K).
Critical pressures for all components (Pa).
Acentric factors for all components (-).
Overall component mole fractions (-).
Binary interaction matrix as an n by n range (-).
Temperature (K).
Pressure (Pa).
Molar volume (m^3/mol).
Whether to calculate fugacity properties.
If true, keep only liquid root properties.
If true, keep only vapor root properties.

WILSON_K_VALUE

This function estimates the vapor-liquid equilibrium ratio for a component with Wilson’s correlation, commonly used to initialize flash and stability calculations.

The correlation is:

K_i = \frac{P_c}{P}\exp\left(5.37(1+\omega)\left[1-\frac{T_c}{T}\right]\right)

Excel Usage

=WILSON_K_VALUE(temperature, pressure, critical_temperature, critical_pressure, omega)
  • temperature (float, required): System temperature (K).
  • pressure (float, required): System pressure (Pa).
  • critical_temperature (float, required): Component critical temperature (K).
  • critical_pressure (float, required): Component critical pressure (Pa).
  • omega (float, required): Acentric factor (-).

Returns (float): Wilson-estimated equilibrium K-value.

Example 1: Ethane-like reference case

Inputs:

temperature pressure critical_temperature critical_pressure omega
270 7600000 305.4 4880000 0.098

Excel formula:

=WILSON_K_VALUE(270, 7600000, 305.4, 4880000, 0.098)

Expected output:

0.296393

Example 2: Lower pressure increases K-value

Inputs:

temperature pressure critical_temperature critical_pressure omega
270 101325 305.4 4880000 0.098

Excel formula:

=WILSON_K_VALUE(270, 101325, 305.4, 4880000, 0.098)

Expected output:

22.2313

Example 3: Methane-like component

Inputs:

temperature pressure critical_temperature critical_pressure omega
190 5000000 190.6 4604000 0.011

Excel formula:

=WILSON_K_VALUE(190, 5000000, 190.6, 4604000, 0.011)

Expected output:

0.905148

Example 4: Heavier component with larger omega

Inputs:

temperature pressure critical_temperature critical_pressure omega
370 3000000 540.2 2736000 0.349

Excel formula:

=WILSON_K_VALUE(370, 3000000, 540.2, 2736000, 0.349)

Expected output:

0.0325683

Python Code

Show Code
from chemicals.flash_basic import Wilson_K_value as chemicals_wilson_k_value

def wilson_k_value(temperature, pressure, critical_temperature, critical_pressure, omega):
    """
    Estimate a component equilibrium K-value using Wilson's correlation.

    See: https://chemicals.readthedocs.io/chemicals.flash_basic.html#chemicals.flash_basic.Wilson_K_value

    This example function is provided as-is without any representation of accuracy.

    Args:
        temperature (float): System temperature (K).
        pressure (float): System pressure (Pa).
        critical_temperature (float): Component critical temperature (K).
        critical_pressure (float): Component critical pressure (Pa).
        omega (float): Acentric factor (-).

    Returns:
        float: Wilson-estimated equilibrium K-value.
    """
    try:
        return chemicals_wilson_k_value(temperature, pressure, critical_temperature, critical_pressure, omega)
    except Exception as e:
        return f"Error: {str(e)}"

Online Calculator

System temperature (K).
System pressure (Pa).
Component critical temperature (K).
Component critical pressure (Pa).
Acentric factor (-).