Physical & transport properties¶
Equipment sizing runs on densities, viscosities, conductivities, and surface
tension, not just fugacities. Fugacio carries a curated, differentiable layer of
pure-component correlations, corresponding-states estimators, and
mixture combining rules for exactly these properties, sourced from the open
literature (Poling, Prausnitz & O'Connell, The Properties of Gases and
Liquids, 5th ed.) and cross-checked against CoolProp and chemicals in the
oracle suite.
The design follows the rest of fugacio.thermo: correlation kernels are pure
JAX functions of scalars and arrays (differentiable, jit/vmap-compatible),
and dispatchers accept component names and pick the best available method:
curated DIPPR-form coefficients when the database has them, a
corresponding-states estimate otherwise.
Pure-component correlations¶
The component database bundles fitted DIPPR-form coefficients (forms 100, 101,
102, 105, 106) for vapour pressure, liquid density, heat of vaporization,
liquid heat capacity, gas viscosity, and liquid/gas thermal conductivity, with
validity ranges. The generic kernels are exposed directly (dippr100,
dippr101, dippr102, dippr105, dippr106), and the estimators fill the
gaps:
- Heat of vaporization:
heat_of_vaporization(DIPPR-106 where curated,pitzer_hvapotherwise), pluswatson_hvapfor re-scaling a known value to another temperature. - Liquid heat capacity:
liquid_heat_capacity(DIPPR-100 where curated,rowlinson_bondi_cpfrom the ideal-gas Cp otherwise). - Surface tension:
surface_tensions(Mulero-Cachadiña / DIPPR-106 fits where curated,brock_bird_surface_tensionotherwise).
import jax
from fugacio.thermo import heat_of_vaporization, liquid_heat_capacity
hvap = heat_of_vaporization(["water", "ethanol"], 298.15) # J/mol
cp_l = liquid_heat_capacity(["water", "ethanol"], 298.15) # J/mol/K
# Differentiable in T like everything else:
jax.grad(lambda t: heat_of_vaporization(["water"], t)[0])(298.15)
Liquid & vapour density¶
liquid_molar_volumes/liquid_density: saturated-liquid volumes from curated DIPPR-105 fits, falling back to COSTALD (costald_volume) and Rackett (rackett_volume); mixtures use Amagat averaging (mixture_liquid_volume).vapor_density: mass density from any cubic EOS at(T, P, y).- Volume translation:
peneloux_shift/translated_molar_volumeapply the Péneloux correction to cubic-EOS liquid volumes (zra_estimatesupplies the Rackett compressibility), typically halving raw PR/SRK liquid-density error. tyn_calus_vb: molar volume at the normal boiling point, the input the diffusivity estimators need.
Transport properties¶
Gas phase (dilute, kinetic-theory based):
gas_viscosities: Chung's method (chung_viscosity_gas) with the Neufeld collision integral; mixtures by Wilke (gas_mixture_viscosity).gas_thermal_conductivities: Chung's thermal-conductivity form (chung_thermal_conductivity_gas); mixtures by Wassiljewa / Mason-Saxena (gas_mixture_thermal_conductivity).
Liquid phase (corresponding-states):
liquid_viscosities: Letsou-Stiel (letsou_stiel_viscosity); mixtures by Grunberg-Nissan (liquid_mixture_viscosity).liquid_thermal_conductivities: Sato-Riedel (sato_riedel_thermal_conductivity); mixtures by the DIPPR9H power-law rule (liquid_mixture_thermal_conductivity).mixture_surface_tension: Winterfeld-Scriven-Davis combining rule over the pure-component values.
Binary diffusion coefficients:
gas_diffusivity: Fuller-Schettler-Giddings at(T, P)from tabulated atomic diffusion volumes (diffusion_volume).liquid_diffusivity: Wilke-Chang at infinite dilution, with solvent association factors andtyn_calus_vbfor the solute volume.
import jax.numpy as jnp
from fugacio.thermo import (
gas_diffusivity, liquid_mixture_viscosity, mixture_surface_tension,
)
x = jnp.array([0.5, 0.5])
mu = liquid_mixture_viscosity(["benzene", "toluene"], 298.15, x) # Pa*s
sigma = mixture_surface_tension(["benzene", "toluene"], 298.15, x) # N/m
d_ab = gas_diffusivity("ethanol", "air", 313.15, 101325.0) # m^2/s
Stream-level properties & sizing¶
The fugacio.sim layer evaluates all of these at a stream's own state:
liquid_density, vapor_density, liquid_volumetric_flow,
vapor_volumetric_flow, liquid_viscosity, vapor_viscosity,
liquid_thermal_conductivity, vapor_thermal_conductivity, and
surface_tension each take a Stream. column_diameter_for chains them into
a Souders-Brown column/drum diameter sized from actual stream densities, and
because everything is JAX, the diameter is differentiable with respect to feed
conditions through the flash and the property correlations.
import jax.numpy as jnp
from fugacio.sim import Stream, column_diameter_for, flash_drum, liquid_density
feed = Stream.from_fractions(
("methane", "propane", "n-pentane"),
jnp.array([0.5, 0.3, 0.2]),
flow=100.0, t=320.0, p=20e5,
)
vap, liq = flash_drum(feed, 320.0, 20e5)
rho_l = liquid_density(liq) # kg/m^3 at the drum state
d = column_diameter_for(vap, liq) # Souders-Brown diameter (m)
The copilot exposes the same capability as JSON tools: physical_properties
(densities, viscosities, conductivities, surface tension, Hvap, liquid Cp for a
mixture at T, P) and binary_diffusivity (Fuller + Wilke-Chang).
The ThermoML parameter bank¶
Fugacio bundles isothermal binary VLE datasets in
NIST ThermoML
format and a batch regression driver that fits NRTL parameters to every bundled
dataset (fit_vle_dataset, fit_bundled_samples). The results ship as a
parameter bank, a lookup table of fitted binary interaction parameters
with their fit quality:
from fugacio.thermo import ParameterBank
bank = ParameterBank.bundled()
entry = bank.lookup("ethanol", "water") # orientation-aware
entry.b, entry.alpha # fitted NRTL b_ij (K) and alpha
entry.rms_pct # pressure RMS error of the fit (%)
ParameterBank.lookup handles component-order swaps (transposing the parameter
matrices), and the bank serializes to JSON for regeneration via
scripts/gen_parameter_bank.py.
Validation¶
Every correlation is covered at three levels:
- Unit tests (default CI): literature spot values, pure-component limits
of every mixture rule, gradient and
jitchecks. - Oracle tests (
just oracles): differential testing against CoolProp reference equations of state (densities, viscosities, conductivities, surface tension, Hvap, Cp) andchemicalskernel-for-kernel (identical inputs isolate the implementation, not the method). - ThermoML regression: the parameter bank's fits are checked to reproduce the bundled experimental bubble pressures within their recorded RMS.