Skip to content
Chemical Engineering

chemical-engineering-ai999x

Material and energy balances, reactor design, separations (distillation, absorption, extraction), transport phenomena, process control and reservoir and petroleum basics.

91capabilities
10topics
91formulas typeset
8worked examples below
1.0.0version
About this model

What Chemical Engineering does

Chemical Engineering (chemical-engineering-ai999x) is an offline Python package for chemical engineering. It covers material and energy balances, reactor design, separations (distillation, absorption, extraction), transport phenomena, process control and reservoir and petroleum basics.

It has 91 capabilities — 91 computational procedures — in 10 topics, the largest being Separations, Reactor design, Process control, Property estimation, Energy balances and Material balances. Ask a question in words with ask(), or call a capability by name with typed inputs with solve(). Every answer carries its value and unit, the steps that produced it and the formula in LaTeX.

When a question is not determined — a value is missing, an input is out of range, or the request is outside the package — it says so and names what it needs, instead of guessing. It runs on an ordinary CPU without a network connection (Python >=3.10), and the same question always gets the same answer.

Install

pip install chemical-engineering-ai999x
hf download AI999X/chemical-engineering-ai999x --local-dir chemical-engineering-ai999x

What it covers

Energy balances7Adiabatic flame temperature (complete combustion, NASA polynomials) · Adiabatic reactor outlet temperature · Batch cooling (or heating) with a non-isothermal coolant in a coil …Fluid transport2Net positive suction head available · Pump total head and powerMaterial balances7Blending: feed flows that make a product of given composition · Combustion with excess air: air requirement and flue-gas composition · Filling or draining well-mixed tank (variable volume) …Petroleum engineering4Exponential decline curve: rate and cumulative production · Gas-well deliverability from a back-pressure test (Rawlins-Schellhardt) · Harmonic decline curve: rate and cumulative production …Process control8Closed-loop stability of a P-controlled process (closed-loop poles) · Discrete PID controller output for an error history · First-order-plus-dead-time process: response to a step …Property estimation8Gas compressibility from the virial equation (Pitzer-Abbott correlation) · Heat of vaporisation at another temperature (Watson) · Heat of vaporisation at the normal boiling point (Riedel) …Reactor design20Batch reactor conversion after a time (first order) · Batch reactor conversion after a time (second order) · Batch reactor time for a conversion (first order) …Reservoir engineering6Gas initially in place from the p/z plot · Oil in place and gas-cap size from the material balance (Havlena-Odeh, gas cap) · Oil initially in place from the material balance (Havlena-Odeh straight line) …Separations22Absorber with N equilibrium stages (Kremser) · Activity coefficients from the NRTL equation · Activity coefficients from the UNIQUAC equation …Transport7Constant-pressure cake filtration: filtrate volume after a time · Diffusion of A through stagnant B (Stefan film) · Equimolar counterdiffusion flux …
Try it

Worked examples

Each question below was put to chemical-engineering-ai999x and the answer shown is the one it returned, with the steps it took.

Reactor designm.ask(…)

First-order CSTR volume: v0 = 36 m^3/h, k = 0.06 1/min, X = 90%

V = 90 m^3
tau = 9000 s
Show the steps
  1. CSTR volume for a conversion (first order)
    V = \frac{v_0\,X}{k(1-X)}
    with v0 = 36 m^3/h, k = 0.06 1/min, X = 0.9
    → V = 90 m^3, tau = 9000 s
Material balancesm.ask(…)

Combustion flue gas: fuel = CH4, excess_air = 20%

O2_theoretical = 2
air = 11.42857143
n_CO2 = 1
n_H2O = 2
n_SO2 = 0
n_O2 = 0.4
Show the steps
  1. Combustion with excess air: air requirement and flue-gas composition
    n_{O_2,th} = x + \tfrac{y}{4} + v - \tfrac{z}{2},\quad n_{air} = \frac{(1+e)\,n_{O_2,th}}{0.21}
    with fuel = CH4, excess_air = 0.2
    → O2_theoretical = 2, air = 11.42857143, n_CO2 = 1, n_H2O = 2, n_SO2 = 0, n_O2 = 0.4, n_N2 = 9.028571429, y_CO2_dry = 0.09589041096, y_O2_dry = 0.03835616438, y_H2O_wet = 0.1609195402, AFR_mass = 20.55283933
Separationsm.ask(…)

Bubble-point temperature: x = [0.4, 0.6], ant = [[6.90565, 1211.033, 220.79], [6.95464, 1344.8, 219.482]], units = mmHg_degC, base = log10, P = 1 atm

T = 368.2916947 K
y = [0.6218490537, 0.3781509463]
Show the steps
  1. Bubble-point temperature (Raoult's law)
    \sum_i x_i P_i^{sat}(T_{bubble}) = P
    with x = [0.4, 0.6], ant = [6.90565 1211.03 220.79; 6.95464 1344.8 219.482], units = mmHg_degC, base = log10, P = 1 atm
    → T = 368.2916947 K, y = [0.6218490537, 0.3781509463] K
Reservoir engineeringm.ask(…)

Radial Darcy flow: k = 100 md, h = 30 ft, mu = 1.5 cP, pe = 3000 psi, pw = 2500 psi, re = 1000 ft, rw = 0.3 ft

q = 0.001606511475 m^3/s
PI = 4.660095801e-10 m^3/(s*Pa)
Show the steps
  1. Steady radial flow of oil to a well (Darcy) and productivity index
    q = \frac{2\pi kh\,(p_e - p_w)}{\mu\left(\ln\frac{r_e}{r_w} + S\right)}
    with k = 9.869233e-14 m^2, h = 30 ft, mu = 0.0015 (Pa*s), pe = 20684271.88 Pa, pw = 17236893.23 Pa, re = 1000 ft, rw = 0.3 ft
    → q = 0.001606511475 m^3/s, PI = 4.660095801e-10 m^3/(s*Pa)
Separationsm.solve(…)
m.solve("chemeng_mccabe_thiele_stages", alpha=2.5, zF=0.5, xD=0.95, q=1, xB=0.05, R=2)
N = 11
Rmin = 1.1
Show the steps
  1. McCabe-Thiele number of theoretical stages (binary)
    y_{n+1} = \frac{R}{R+1}x_n + \frac{x_D}{R+1},\quad x_n = \frac{y_n}{\alpha - (\alpha-1)y_n}
    with alpha = 2.5, zF = 0.5, xD = 0.95, q = 1, xB = 0.05, R = 2
    → N = 11, Rmin = 1.1
Energy balancesm.ask(…)

Adiabatic flame temperature: fuel = CH4, excess_air = 0.0, T_in = 300.0 K

T_ad = 2326.321765 K
Show the steps
  1. Adiabatic flame temperature (complete combustion, NASA polynomials)
    \sum_{p} n_p\,h_p(T_{ad}) = \sum_{r} n_r\,h_r(T_{in}),\quad \frac{h}{RT} = a_1 + \frac{a_2T}{2} + \frac{a_3T^2}{3} + \frac{a_4T^3}{4} + \frac{a_5T^4}{5} + \frac{a_6}{T}
    with fuel = CH4, excess_air = 0, T_in = 300 K
    → T_ad = 2326.321765 K
Fluid transportm.ask(…)

NPSH available: p_s = 101325.0 Pa, p_v = 2339.0 Pa, rho = 998.0 kg/m^3, z_s = 2.0 m, h_f = 0.5 m

NPSHa = 11.61399089 m
pressure_head = 10.35298049 m
vapour_head = 0.2389896014 m
Show the steps
  1. Net positive suction head available
    NPSH_a = \frac{p_s - p_v}{\rho g} + z_s - h_f
    with p_s = 101325 Pa, p_v = 2339 Pa, rho = 998 kg/m^3, z_s = 2 m, h_f = 0.5 m
    → NPSHa = 11.61399089 m, pressure_head = 10.35298049 m, vapour_head = 0.2389896014 m
Petroleum engineeringm.ask(…)

Exponential decline: qi = 0.0018401307283333335 m^3/s, Di = 9.506426344208685e-09 1/s, t = 63115200.0 s

q = 0.001009885156 m^3/s
Np = 87335.19228 m^3
Show the steps
  1. Exponential decline curve: rate and cumulative production
    q = q_ie^{-D_it},\quad N_p = \frac{q_i - q}{D_i}
    with qi = 0.001840130728 m^3/s, Di = 9.506426344e-09 1/s, t = 63115200 s
    → q = 0.001009885156 m^3/s, Np = 87335.19228 m^3
Use it

From Python or the command line

Every snippet was run as shown; the output under it is what it printed.

import chemical_engineering_ai999x as m

a = m.ask("First-order CSTR volume: v0 = 36 m^3/h, k = 0.06 1/min, X = 90%")
print(a.outcome)
print(a.values)
for step in a.steps:
    print(step["name"])
Output
SOLVED
{'V': 90.0, 'tau': 9000.0}
CSTR volume for a conversion (first order)
Figures

Computed, not drawn by hand

Every value in these figures was computed by the package, each point a run of solve(); in a notebook, plot() and plot_relation() draw a capability's curves the same way.

Boiling-point diagram: bubble and dew curves of a binary mixture

\sum_i x_i P_i^{sat}(T_{bubble}) = P
Boiling-point diagram: bubble and dew curves of a binary mixtureBoiling-point diagram of an ideal binary mixture at P = 101325 Pa (Raoult's law with the Antoine constants [[6.90565, 1211.033, 220.79], [6.95464, 1344.8, 219.482]], mmHg and °C): bubble and dew temperatures computed by the package at 40 compositions each; between them (shaded) liquid and vapour coexist. The tie line joins a liquid with x₁ = 0.4 to its vapour y₁ = 0.621849; marked: x₁ = 0.4, T = 368.292 K.00.250.50.751360370380368.292 Kliquid + vapour (two phases)bubble point (liquid x₁)dew point (vapour y₁)tie linex₁, y₁ — mole fraction of the lighter componentT — temperature [K]
Boiling-point diagram of an ideal binary mixture at P = 101325 Pa (Raoult's law with the Antoine constants [[6.90565, 1211.033, 220.79], [6.95464, 1344.8, 219.482]], mmHg and °C): bubble and dew temperatures computed by the package at 40 compositions each; between them (shaded) liquid and vapour coexist. The tie line joins a liquid with x₁ = 0.4 to its vapour y₁ = 0.621849; marked: x₁ = 0.4, T = 368.292 K.

Reactor conversion: CSTR, CSTRs in series, PFR

X = \frac{k\tau}{1 + k\tau},\ \tau = V/v_0
Reactor conversion: CSTR, CSTRs in series, PFRConversion of a first-order reaction (k = 0.001 1/s, feed 0.01 m³/s) against total volume for one CSTR, three equal CSTRs in series and a plug-flow reactor, each computed by the package at 60 volumes. At V = 20 m³ the PFR reaches X = 0.864665; marked: V = 20 m³, X = 0.666667 (CSTR).02040600.250.50.7510.666667plug flow (PFR)3 equal CSTRs in seriesone CSTRV — total reactor volume [m³]X — conversion
Conversion of a first-order reaction (k = 0.001 1/s, feed 0.01 m³/s) against total volume for one CSTR, three equal CSTRs in series and a plug-flow reactor, each computed by the package at 60 volumes. At V = 20 m³ the PFR reaches X = 0.864665; marked: V = 20 m³, X = 0.666667 (CSTR).

Production decline: exponential, hyperbolic, harmonic

q = \frac{q_i}{(1 + bD_it)^{1/b}},\quad N_p = \frac{q_i^b}{(1-b)D_i}\left(q_i^{1-b} - q^{1-b}\right)
Production decline: exponential, hyperbolic, harmonicWell production rate against time for three decline laws from the same initial rate qi = 158.987 m³/day, each computed by the package at 81 times over 10 years. After 10 years: exponential (Di = 0.3 per year) 7.91551 m³/day; hyperbolic, b = 0.5 (Di = 0.5 per year) 12.9786 m³/day; harmonic (Di = 0.4 per year) 31.7975 m³/day.0246810050100150exponentialhyperbolic, b = 0.5harmonict — time [years]q — rate [m³/day]
Well production rate against time for three decline laws from the same initial rate qi = 158.987 m³/day, each computed by the package at 81 times over 10 years. After 10 years: exponential (Di = 0.3 per year) 7.91551 m³/day; hyperbolic, b = 0.5 (Di = 0.5 per year) 12.9786 m³/day; harmonic (Di = 0.4 per year) 31.7975 m³/day.

Flash separation: feed, liquid and vapour compositions

\sum_i \frac{z_i (K_i - 1)}{1 + \frac{V}{F}(K_i - 1)} = 0
Flash separation: feed, liquid and vapour compositionsIsothermal flash of a 3-component feed z = [0.5, 0.3, 0.2] with equilibrium ratios K = [1.685, 0.742, 0.532]: the package solves the Rachford–Rice equation for a vapour fraction of 0.69073 and returns the liquid x = [0.339409, 0.365056, 0.295535] and vapour y = [0.571904, 0.270872, 0.157225] compositions (bars).00.20.40.61: K = 1.6852: K = 0.7423: K = 0.532feed zliquid x (0.30927 of the feed)vapour y (0.69073 of the feed)componentmole fraction
Isothermal flash of a 3-component feed z = [0.5, 0.3, 0.2] with equilibrium ratios K = [1.685, 0.742, 0.532]: the package solves the Rachford–Rice equation for a vapour fraction of 0.69073 and returns the liquid x = [0.339409, 0.365056, 0.295535] and vapour y = [0.571904, 0.270872, 0.157225] compositions (bars).

Conversion table: tanks in series against total volume

X = 1 - (1 + k\tau_i)^{-N}
Conversion tableConversion of a first-order reaction (k = 0.001 1/s, feed 0.01 m³/s) in N equal CSTRs in series (rows, N = 1 to 5) sharing a total volume of 5, 10, 20, 40, 80 m³ (columns), each cell computed by the package. More tanks approach plug flow: a PFR of the same volumes gives 0.393469, 0.632121, 0.864665, 0.981684, 0.999665.0.3330.50.6670.80.8890.360.5560.750.8890.960.370.5780.7840.9210.980.3760.590.8020.9380.9880.3790.5980.8140.9470.992conversion X · rows N = 1 → 5 tanks · columns V = 5 → 80 m³
Conversion of a first-order reaction (k = 0.001 1/s, feed 0.01 m³/s) in N equal CSTRs in series (rows, N = 1 to 5) sharing a total volume of 5, 10, 20, 40, 80 m³ (columns), each cell computed by the package. More tanks approach plug flow: a PFR of the same volumes gives 0.393469, 0.632121, 0.864665, 0.981684, 0.999665.
Formulas

The mathematics inside

12 of its 91 formulas; every one is in the capability browser below.

Combustion with excess air: air requirement and flue-gas composition
n_{O_2,th} = x + \tfrac{y}{4} + v - \tfrac{z}{2},\quad n_{air} = \frac{(1+e)\,n_{O_2,th}}{0.21}
Bubble-point temperature (Raoult's law)
\sum_i x_i P_i^{sat}(T_{bubble}) = P
Steady radial flow of oil to a well (Darcy) and productivity index
q = \frac{2\pi kh\,(p_e - p_w)}{\mu\left(\ln\frac{r_e}{r_w} + S\right)}
McCabe-Thiele number of theoretical stages (binary)
y_{n+1} = \frac{R}{R+1}x_n + \frac{x_D}{R+1},\quad x_n = \frac{y_n}{\alpha - (\alpha-1)y_n}
Adiabatic flame temperature (complete combustion, NASA polynomials)
\sum_{p} n_p\,h_p(T_{ad}) = \sum_{r} n_r\,h_r(T_{in}),\quad \frac{h}{RT} = a_1 + \frac{a_2T}{2} + \frac{a_3T^2}{3} + \frac{a_4T^3}{4} + \frac{a_5T^4}{5} + \frac{a_6}{T}
Net positive suction head available
NPSH_a = \frac{p_s - p_v}{\rho g} + z_s - h_f
Exponential decline curve: rate and cumulative production
q = q_ie^{-D_it},\quad N_p = \frac{q_i - q}{D_i}
Adiabatic reactor outlet temperature
\sum_i n_{i0}\!\int_{T_{in}}^{T_{ref}}\!c_{p,i}dT + \xi\,\Delta H_r(T_{ref}) + \sum_i n_i\!\int_{T_{ref}}^{T_{out}}\!c_{p,i}dT = 0
Pump total head and power
H = \frac{p_2 - p_1}{\rho g} + (z_2 - z_1) + \frac{v_2^2 - v_1^2}{2g},\quad P = \rho g Q H
Blending: feed flows that make a product of given composition
\sum_i F_i\,w_{ij} = P\,p_j \quad (j = 1..n)
Gas-well deliverability from a back-pressure test (Rawlins-Schellhardt)
q = C\left(\bar p_r^2 - p_{wf}^2\right)^n,\quad AOF = C\,\bar p_r^{2n}
Capabilities

Every capability, with an example

Search by name, formula, input or topic. Each capability opens to show what it takes, what it returns, when it applies, and a question it answered.

91 capabilities

Energy balances 7

Adiabatic flame temperature (complete combustion, NASA polynomials)chemeng_adiabatic_flame_temperature

Adiabatic flame temperature of a gaseous fuel burned with excess dry air at constant pressure, complete combustion without dissociation, from NASA 7-coefficient polynomials (GRI-Mech 3.0 data).

\sum_{p} n_p\,h_p(T_{ad}) = \sum_{r} n_r\,h_r(T_{in}),\quad \frac{h}{RT} = a_1 + \frac{a_2T}{2} + \frac{a_3T^2}{3} + \frac{a_4T^3}{4} + \frac{a_5T^4}{5} + \frac{a_6}{T}

Inputs

  • fuel fuel: CH4, C2H6, C3H8, H2, CO, C2H4, C2H2, CH3OH choice
  • excess_air excess air as a fraction of theoretical (0 = stoichiometric)
  • T_in temperature of the fuel and air entering [K]

Returns

  • T_ad adiabatic flame temperature [K]

Applies when

  • complete combustion to CO2 and H2O vapour, no dissociation
  • 300 K <= T_in <= 1000 K
  • result <= 3500 K

Example

m.ask("Adiabatic flame temperature: fuel = CH4, excess_air = 0.0, T_in = 300.0 K")
→ T_ad = 2326.32 K
Adiabatic reactor outlet temperaturechemeng_adiabatic_reactor_temperature

Outlet temperature of an adiabatic reactor from the feed, the conversion of the limiting reactant, the heat of reaction at a reference temperature and polynomial heat capacities.

\sum_i n_{i0}\!\int_{T_{in}}^{T_{ref}}\!c_{p,i}dT + \xi\,\Delta H_r(T_{ref}) + \sum_i n_i\!\int_{T_{ref}}^{T_{out}}\!c_{p,i}dT = 0

Inputs

  • n0 feed amounts of each species, mol (or mol/s) on one basis vector
  • nu stoichiometric coefficients, negative for reactants vector
  • cp heat-capacity coefficients, one row (a, b, c, d) per species; cp = a + bT + cT^2 + dT^3 in J/(mol K) matrix
  • dH heat of reaction at T_ref, per mole of extent [J/mol]
  • T_ref reference temperature of dH [K]
  • T_in feed temperature [K]
  • key number of the limiting reactant in the species list (1 = first) integer
  • X conversion of the limiting reactant

Returns

  • T_out adiabatic outlet temperature [K]

Applies when

  • adiabatic, no shaft work, no phase change
  • outlet between 200 and 3200 K

Example

m.ask("Adiabatic reactor temperature: n0 = [1.0, 2.0, 0.0], nu = [-1.0, -1.0, 1.0], cp = [[30.0, 0.01], [29.0, 0.004], [45.0, 0.02]], dH = -60000.0 J/mol, T_ref = 298.15 K, T_in = 400.0 K, key = 1, X = 0.8")
→ T_out = 932.348 K
Batch cooling (or heating) with a non-isothermal coolant in a coilchemeng_batch_coil_cooling

Temperature of a well-stirred batch after time t when a coolant (or heating liquid) flows once through a coil and leaves warmer (Kern's batch cooling).

T = t_{in} + (T_0 - t_{in})\exp\!\left[-\frac{W c_{p,c}\,(1 - e^{-UA/(W c_{p,c})})\,t}{M c_p}\right]

Inputs

  • M mass of liquid in the tank [kg]
  • cp specific heat of the batch liquid [J/(kg*K)]
  • W coolant mass flow [kg/s]
  • cp_c specific heat of the coolant [J/(kg*K)]
  • t_in coolant inlet temperature [K]
  • UA overall heat-transfer coefficient times coil area [W/K]
  • T0 initial batch temperature [K]
  • t time [s]

Returns

  • T batch temperature at time t [K]

Applies when

  • well-stirred batch
  • constant UA, cp and coolant flow

Example

m.ask("Batch coil cooling: M = 5000.0 kg, cp = 2500.0 J/(kg*K), W = 2.0 kg/s, cp_c = 4180.0 J/(kg*K), t_in = 288.15 K, UA = 3000.0 W/K, T0 = 393.15 K, t = 7200.0 s")
→ T = 312.732 K
Batch heating of a stirred tank: temperature after a timechemeng_batch_heating_temperature

Temperature of a well-stirred batch heated or cooled by a medium at constant temperature (condensing steam, boiling refrigerant) after time t.

T = T_s - (T_s - T_0)\,e^{-UA\,t/(m c_p)}

Inputs

  • m mass of liquid in the tank [kg]
  • cp specific heat of the liquid [J/(kg*K)]
  • UA overall heat-transfer coefficient times area of the coil or jacket [W/K]
  • T_s temperature of the heating or cooling medium (constant, e.g. condensing steam) [K]
  • T0 initial liquid temperature [K]
  • t heating time [s]

Returns

  • T liquid temperature at time t [K]

Applies when

  • well stirred
  • constant UA and cp
  • medium at constant temperature

Example

m.ask("Batch heating temperature: m = 1000.0 kg, cp = 4180.0 J/(kg*K), UA = 2000.0 W/K, T_s = 393.15 K, T0 = 293.15 K, t = 3600.0 s")
→ T = 375.288 K
Batch heating of a stirred tank: time to reach a temperaturechemeng_batch_heating_time

Time for a well-stirred batch heated or cooled by a medium at constant temperature to reach a stated temperature.

t = \frac{m c_p}{UA}\ln\frac{T_s - T_0}{T_s - T}

Inputs

  • m mass of liquid in the tank [kg]
  • cp specific heat of the liquid [J/(kg*K)]
  • UA overall heat-transfer coefficient times area of the coil or jacket [W/K]
  • T_s temperature of the heating or cooling medium (constant, e.g. condensing steam) [K]
  • T0 initial liquid temperature [K]
  • T temperature to reach [K]

Returns

  • t time needed [s]

Applies when

  • T between T0 and T_s
  • well stirred
  • constant UA and cp

Example

m.ask("Batch heating time: m = 1000.0 kg, cp = 4180.0 J/(kg*K), UA = 2000.0 W/K, T_s = 393.15 K, T0 = 293.15 K, T = 353.15 K")
→ t = 1915.05 s
Heat of reaction at another temperature (Kirchhoff)chemeng_reaction_enthalpy_at_temperature

The heat of reaction at T from its value at T0 and the polynomial heat capacities of the species (Kirchhoff's law).

\Delta H_r(T) = \Delta H_r(T_0) + \int_{T_0}^{T}\sum_i \nu_i c_{p,i}\,dT

Inputs

  • nu stoichiometric coefficients, negative for reactants and positive for products vector
  • cp heat-capacity coefficients, one row (a, b, c, d) per species in the order of nu; cp = a + bT + cT^2 + dT^3 in J/(mol K) matrix
  • dH0 heat of reaction at T0, per mole of extent [J/mol]
  • T0 temperature of the known heat of reaction [K]
  • T temperature wanted [K]

Returns

  • dH heat of reaction at T, per mole of extent [J/mol]

Applies when

  • no phase change of any species between T0 and T

Example

m.ask("Heat of reaction at temperature: nu = [-1.0, -3.0, 2.0], cp = [[27.27, 0.004927, 0.0, 0.0], [27.01, 0.003509, 0.0, 0.0], [24.62, 0.03753, -7.1e-06, 0.0]], dH0 = -92220.0 J/mol, T0 = 298.15 K, T = 700.0 K")
→ dH = -105497 J/mol
Sensible heat with a polynomial heat capacitychemeng_sensible_heat_cp_polynomial

Heat needed to take n moles from T1 to T2 when cp = a + bT + cT^2 + dT^3 (J/(mol K), T in K), and the mean heat capacity over the range.

Q = n\int_{T_1}^{T_2}(a + bT + cT^2 + dT^3)\,dT

Inputs

  • n amount of substance [mol]
  • a cp coefficient a, J/(mol K)
  • b cp coefficient b, J/(mol K^2)
  • c cp coefficient c, J/(mol K^3) (default 0) optional
  • d cp coefficient d, J/(mol K^4) (default 0) optional
  • T1 initial temperature [K]
  • T2 final temperature [K]

Returns

  • Q heat added (negative when cooled) [J]
  • cp_mean mean heat capacity between T1 and T2 [J/(mol*K)]

Applies when

  • no phase change between T1 and T2
  • T in kelvin inside the polynomial

Example

m.ask("Sensible heat with polynomial cp: n = 10.0 mol, a = 29.0, b = 0.002, c = 0.0, d = 0.0, T1 = 300.0 K, T2 = 500.0 K")
→ Q = 59600 J, cp_mean = 29.8 J/(mol*K)

Fluid transport 2

Net positive suction head availablechemeng_npsh_available

The net positive suction head available at a pump inlet, NPSHa = (p_s - p_v)/(rho g) + z_s - h_f, from the pressure on the liquid surface, the vapour pressure, the static head and the suction-line loss; with the required NPSH, the margin.

NPSH_a = \frac{p_s - p_v}{\rho g} + z_s - h_f

Inputs

  • p_s absolute pressure on the suction liquid surface [Pa]
  • p_v vapour pressure of the liquid at the pumping temperature [Pa]
  • rho liquid density [kg/m^3]
  • z_s liquid surface above the pump inlet (negative for a suction lift) [m]
  • h_f friction head loss in the suction line [m]
  • NPSHr required NPSH of the pump (optional) [m] optional

Returns

  • NPSHa NPSH available [m]
  • pressure_head p_s/(rho g) [m]
  • vapour_head p_v/(rho g) [m]
  • margin NPSHa - NPSHr (with NPSHr) [m]

Applies when

  • absolute pressures
  • h_f >= 0

Example

m.ask("NPSH available: p_s = 101325.0 Pa, p_v = 2339.0 Pa, rho = 998.0 kg/m^3, z_s = 2.0 m, h_f = 0.5 m")
→ NPSHa = 11.614 m, pressure_head = 10.353 m, vapour_head = 0.23899 m
Pump total head and powerchemeng_pump_head

The total head a pump adds between its suction and discharge, H = (p2 - p1)/(rho g) + (z2 - z1) + (v2^2 - v1^2)/(2g), with the hydraulic power rho g Q H and the shaft power for an efficiency.

H = \frac{p_2 - p_1}{\rho g} + (z_2 - z_1) + \frac{v_2^2 - v_1^2}{2g},\quad P = \rho g Q H

Inputs

  • p1 suction pressure (absolute) [Pa]
  • p2 discharge pressure (absolute) [Pa]
  • rho liquid density [kg/m^3]
  • dz elevation of the discharge gauge above the suction gauge (default 0) [m] optional
  • v1 suction velocity (default 0) [m/s] optional
  • v2 discharge velocity (default 0) [m/s] optional
  • Q volumetric flow (optional, for the power) [m^3/s] optional
  • eta pump efficiency (optional, with Q) optional

Returns

  • H total head [m]
  • dp_equivalent head as a pressure rho g H [Pa]
  • P_hydraulic hydraulic power rho g Q H [W]
  • P_shaft shaft power rho g Q H/eta [W]

Applies when

  • absolute pressures
  • incompressible liquid
  • H > 0

Example

m.ask("Pump total head: p1 = 100000.0 Pa, p2 = 400000.0 Pa, rho = 1000.0 kg/m^3")
→ H = 30.5915 m, dp_equivalent = 300000 Pa

Material balances 7

Blending: feed flows that make a product of given compositionchemeng_blending_flows

The mass flow of each feed stream needed to make a product of stated flow and composition, from the component balances (as many feeds as components).

\sum_i F_i\,w_{ij} = P\,p_j \quad (j = 1..n)

Inputs

  • W mass fractions of the feed streams: one row per feed stream, one column per component (rows sum to 1) matrix
  • p mass fractions of the product, one per component (sum to 1) vector
  • P product mass flow [kg/s]

Returns

  • F1 flow of the first feed stream [kg/s]
  • F flow of every feed stream, in kg/s, in the order of the rows of W

Applies when

  • as many feed streams as components (2 to 6)
  • each composition sums to 1
  • the product lies within the reach of the feeds (no negative flow)

Example

m.ask("Blending feed flows: W = [[0.9, 0.1], [0.2, 0.8]], p = [0.5, 0.5], P = 100.0 kg/s")
→ F1 = 42.8571 kg/s, F = [42.8571428571, 57.1428571429]
Combustion with excess air: air requirement and flue-gas compositionchemeng_combustion_flue_gas

Theoretical oxygen, air supplied, flue-gas moles and wet and dry compositions, and the air-fuel mass ratio for complete combustion of a fuel with excess dry air (21 % O2, 79 % N2).

n_{O_2,th} = x + \tfrac{y}{4} + v - \tfrac{z}{2},\quad n_{air} = \frac{(1+e)\,n_{O_2,th}}{0.21}

Inputs

  • fuel molecular formula of the fuel (C, H, O, N and S), e.g. CH4, C3H8, C2H5OH text
  • excess_air excess air as a fraction of the theoretical air (20% = 0.2)

Returns

  • O2_theoretical theoretical O2, mol per mol fuel
  • air air supplied, mol per mol fuel
  • n_CO2 CO2 in the flue gas, mol per mol fuel
  • n_H2O H2O, mol per mol fuel
  • n_SO2 SO2, mol per mol fuel
  • n_O2 O2, mol per mol fuel
  • n_N2 N2, mol per mol fuel
  • y_CO2_dry CO2 mole fraction, dry basis
  • y_O2_dry O2 mole fraction, dry basis
  • y_H2O_wet H2O mole fraction, wet basis
  • AFR_mass air-fuel ratio, kg air per kg fuel

Applies when

  • complete combustion to CO2, H2O and SO2; fuel N leaves as N2
  • dry air 21 % O2 / 79 % N2
  • 0 <= excess air <= 500 %

Example

m.ask("Combustion flue gas: fuel = CH4, excess_air = 0.2")
→ O2_theoretical = 2, air = 11.4286, n_CO2 = 1, n_H2O = 2, n_SO2 = 0, n_O2 = 0.4, n_N2 = 9.02857, y_CO2_dry = 0.0958904, y_O2_dry = 0.0383562, y_H2O_wet = 0.16092, AFR_mass = 20.5528
Filling or draining well-mixed tank (variable volume)chemeng_variable_volume_tank

Volume and concentration of a well-mixed tank whose inflow and outflow differ, at time t.

C = C_{in} - (C_{in} - C_0)\left(\frac{V_0}{V}\right)^{q_{in}/(q_{in}-q_{out})},\ V = V_0 + (q_{in}-q_{out})t

Inputs

  • V0 liquid volume at t = 0 [m^3]
  • q_in volumetric inflow [m^3/s]
  • q_out volumetric outflow [m^3/s]
  • C_in inlet concentration [mol/m^3]
  • C0 concentration in the tank at t = 0 [mol/m^3]
  • t time [s]

Returns

  • V liquid volume at time t [m^3]
  • C concentration at time t [mol/m^3]

Applies when

  • V0 > 0, q_in > 0
  • the tank does not empty before t
  • perfect mixing

Example

m.ask("Variable-volume tank: V0 = 1.0 m^3, q_in = 0.002 m^3/s, q_out = 0.001 m^3/s, C_in = 1000.0 mol/m^3, C0 = 0.0 mol/m^3, t = 1000.0 s")
→ V = 2 m^3, C = 750 mol/m^3
Mass fractions to mole fractions and mean molar masschemeng_mass_to_mole_fractions

Mole fractions of a mixture and its mean molar mass from the mass fractions and the molar masses of the components.

z_i = \frac{w_i/M_i}{\sum_j w_j/M_j},\quad \bar M = \sum_i z_iM_i

Inputs

  • w mass fractions (sum to 1) vector
  • MW molar masses of the components, g/mol vector

Returns

  • z mole fractions
  • MW_mean mean molar mass of the mixture [kg/mol]

Applies when

  • fractions sum to 1
  • positive molar masses

Example

m.ask("Mass to mole fractions: w = [0.5, 0.5], MW = [32.042, 18.015]")
→ z = [0.359889725713, 0.640110274287], MW_mean = 0.0230632 kg/mol
Reactor with recycle and purgechemeng_recycle_purge

Steady-state flows of a reactor A -> B with complete product separation, recycle of unreacted A and inert, and a purge that removes a fraction of the recycle stream to stop the inert accumulating.

A_{in} = \frac{F_0 z_A}{1 - (1-f)(1-X)},\quad I_{in} = \frac{F_0(1-z_A)}{f}

Inputs

  • F0 fresh feed flow (reactant A plus inert) [mol/s]
  • zA mole fraction of A in the fresh feed (the rest is inert)
  • X single-pass conversion of A in the reactor
  • f purge fraction: the fraction of the separator overhead (unreacted A + inert) that is purged

Returns

  • R recycle flow [mol/s]
  • P purge flow [mol/s]
  • reactor_feed combined reactor feed flow [mol/s]
  • X_overall overall conversion of A (fresh feed to product)
  • product production rate of B [mol/s]
  • y_inert mole fraction of inert in the recycle and purge

Applies when

  • 0 < zA <= 1
  • 0 < X < 1
  • 0 < f < 1
  • A -> B one to one; the separator removes all B

Example

m.ask("Recycle and purge balance: F0 = 100.0 mol/s, zA = 0.98, X = 0.25, f = 0.1")
→ R = 221.538 mol/s, P = 24.6154 mol/s, reactor_feed = 321.538 mol/s, X_overall = 0.769231, product = 75.3846 mol/s, y_inert = 0.08125
Two-product separator balance (binary distillation column)chemeng_binary_separator_balance

Distillate and bottoms flows of a binary separator from the feed flow and the three compositions, with the recoveries of the light component in the distillate and of the heavy component in the bottoms.

D = F\,\frac{z_F - x_B}{x_D - x_B},\quad B = F - D

Inputs

  • F feed molar flow [mol/s]
  • zF mole fraction of the light component in the feed
  • xD mole fraction of the light component in the distillate (top product)
  • xB mole fraction of the light component in the bottoms

Returns

  • D distillate flow [mol/s]
  • B bottoms flow [mol/s]
  • recovery_D fraction of the light component recovered in the distillate
  • recovery_B fraction of the heavy component recovered in the bottoms

Applies when

  • xB < zF < xD
  • steady state, no reaction

Example

m.ask("Two-product separator balance: F = 100.0 mol/s, zF = 0.4, xD = 0.95, xB = 0.05")
→ D = 38.8889 mol/s, B = 61.1111 mol/s, recovery_D = 0.923611, recovery_B = 0.967593
Unsteady well-mixed tank (concentration change)chemeng_unsteady_mixing_tank

Concentration in a constant-volume well-mixed tank at time t after the inlet concentration changes (inflow equals outflow).

C(t) = C_{in} + (C_0 - C_{in})\,e^{-q t/V}

Inputs

  • V liquid volume of the tank [m^3]
  • q volumetric flow in and out [m^3/s]
  • C_in inlet concentration [mol/m^3]
  • C0 concentration in the tank at t = 0 [mol/m^3]
  • t time [s]

Returns

  • C concentration in the tank (and outlet) at time t [mol/m^3]

Applies when

  • V > 0, q > 0
  • perfect mixing
  • constant volume (inflow = outflow)

Example

m.ask("Unsteady mixing tank: V = 10.0 m^3, q = 0.01 m^3/s, C_in = 500.0 mol/m^3, C0 = 0.0 mol/m^3, t = 1000.0 s")
→ C = 316.06 mol/m^3

Petroleum engineering 4

Exponential decline curve: rate and cumulative productionchemeng_exponential_decline

Production rate and cumulative production at time t of a well in exponential (constant-percentage) decline (Arps b = 0).

q = q_ie^{-D_it},\quad N_p = \frac{q_i - q}{D_i}

Inputs

  • qi initial rate (bbl/day and STB/day are converted here) [m^3/s]
  • Di initial nominal decline rate, e.g. 0.3 1/yr [1/s]
  • t time since the start of the decline [s]

Returns

  • q rate at time t [m^3/s]
  • Np cumulative production to time t [m^3]

Applies when

  • boundary-dominated flow, constant operating conditions

Example

m.ask("Exponential decline: qi = 0.0018401307283333335 m^3/s, Di = 9.506426344208685e-09 1/s, t = 63115200.0 s")
→ q = 0.00100989 m^3/s, Np = 87335.2 m^3
Gas-well deliverability from a back-pressure test (Rawlins-Schellhardt)chemeng_gas_well_backpressure

Exponent n, coefficient C and absolute open flow of a gas well from multi-rate test data fitted to q = C (pr^2 - pwf^2)^n.

q = C\left(\bar p_r^2 - p_{wf}^2\right)^n,\quad AOF = C\,\bar p_r^{2n}

Inputs

  • q test gas rates, in q_unit vector
  • pwf flowing bottom-hole pressures at those rates, in p_unit vector
  • q_unit unit of the rates: m3_per_day or Mscf_per_day choice
  • p_unit unit of the flowing pressures choice
  • pr average reservoir (shut-in) pressure [Pa]

Returns

  • n back-pressure exponent
  • log10_C log10 of the coefficient C, with q in m^3/s and pressures in Pa
  • AOF absolute open flow (rate at pwf = 0) [m^3/s]

Applies when

  • stabilised flow at every rate
  • 0.3 < n < 1.5

Example

m.ask("Gas well back-pressure test: q = [4288.0, 9265.0, 15552.0, 20177.0], pwf = [403.1, 394.0, 378.5, 362.6], q_unit = Mscf_per_day, p_unit = psi, pr = 2814439.927071325 Pa")
→ n = 0.727757, log10_C = -8.06553, AOF = 20.9729 m^3/s
Harmonic decline curve: rate and cumulative productionchemeng_harmonic_decline

Production rate and cumulative production at time t of a well in harmonic decline (Arps b = 1).

q = \frac{q_i}{1 + D_it},\quad N_p = \frac{q_i}{D_i}\ln\frac{q_i}{q}

Inputs

  • qi initial rate (bbl/day and STB/day are converted here) [m^3/s]
  • Di initial nominal decline rate, e.g. 0.3 1/yr [1/s]
  • t time since the start of the decline [s]

Returns

  • q rate at time t [m^3/s]
  • Np cumulative production to time t [m^3]

Applies when

  • boundary-dominated flow

Example

m.ask("Harmonic decline: qi = 0.0018401307283333335 m^3/s, Di = 1.2675235125611581e-08 1/s, t = 94672800.0 s")
→ q = 0.000836423 m^3/s, Np = 114465 m^3
Hyperbolic decline curve: rate and cumulative productionchemeng_hyperbolic_decline

Production rate and cumulative production at time t of a well in hyperbolic decline with Arps exponent 0 < b < 1.

q = \frac{q_i}{(1 + bD_it)^{1/b}},\quad N_p = \frac{q_i^b}{(1-b)D_i}\left(q_i^{1-b} - q^{1-b}\right)

Inputs

  • qi initial rate (bbl/day and STB/day are converted here) [m^3/s]
  • Di initial nominal decline rate, e.g. 0.3 1/yr [1/s]
  • b Arps decline exponent (0 < b < 1)
  • t time since the start of the decline [s]

Returns

  • q rate at time t [m^3/s]
  • Np cumulative production to time t [m^3]

Applies when

  • 0 < b < 1
  • boundary-dominated flow

Example

m.ask("Hyperbolic decline: qi = 0.0018401307283333335 m^3/s, Di = 1.5844043907014474e-08 1/s, b = 0.5, t = 94672800.0 s")
→ q = 0.000600859 m^3/s, Np = 99548.8 m^3

Process control 8

Closed-loop stability of a P-controlled process (closed-loop poles)chemeng_closed_loop_stability

Whether a feedback loop with a proportional controller Kc around a process G(s) = num(s)/den(s) is stable: the largest real part of the closed-loop poles and how many lie in the right half-plane.

1 + K_cG(s) = 0 \iff \mathrm{den}(s) + K_c\,\mathrm{num}(s) = 0

Inputs

  • num numerator coefficients of G(s), highest power of s first vector
  • den denominator coefficients of G(s), highest power of s first vector
  • Kc controller gain

Returns

  • max_real largest real part of the closed-loop poles, 1/(time unit of the coefficients)
  • n_rhp number of closed-loop poles in the right half-plane
  • stable stable or unstable (text)

Applies when

  • proper process
  • no pole on the imaginary axis or nearly repeated poles (refused)

Example

m.ask("Closed-loop stability: num = [1.0], den = [1.0, 3.0, 3.0, 1.0], Kc = 10.0")
→ max_real = 0.0772173, n_rhp = 2, stable = unstable
Discrete PID controller output for an error historychemeng_pid_controller_output

Output of a digital position-form PID controller at each sample for a stated history of errors (rectangular integration, derivative on the error, loop at rest before the first sample).

u_k = \bar u + K_c\left[e_k + \frac{\Delta t}{\tau_I}\sum_{j=1}^{k} e_j + \frac{\tau_D}{\Delta t}(e_k - e_{k-1})\right]

Inputs

  • Kc controller gain
  • tauI integral (reset) time [s]
  • tauD derivative time (0 for PI) [s]
  • dt sampling interval [s]
  • e error samples e_1 ... e_n (set point minus measurement) vector
  • bias controller output bias (output when the error has always been zero)

Returns

  • u_last controller output at the last sample
  • u controller output at every sample

Applies when

  • position form, e_0 = 0 before the first sample
  • rectangular integration including the current sample

Example

m.ask("PID controller output: Kc = 2.0, tauI = 10.0 s, tauD = 1.0 s, dt = 1.0 s, e = [1.0, 0.8, 0.5, 0.3], bias = 50.0")
→ u_last = 50.72, u = [54.2, 51.56, 50.86, 50.72]
First-order-plus-dead-time process: response to a stepchemeng_fopdt_step_response

Deviation of the output of a first-order process with dead time at time t after a step of size M in its input.

y(t) = KM\left(1 - e^{-(t-\theta)/\tau}\right)\,u(t-\theta)

Inputs

  • K process gain (output change per unit input change)
  • tau process time constant [s]
  • theta dead time [s]
  • M size of the input step (deviation)
  • t time after the step [s]

Returns

  • y output deviation at time t (in the output's units)

Applies when

  • the process starts at steady state
  • linear first-order dynamics with dead time

Example

m.ask("FOPDT step response: K = 2.0, tau = 300.0 s, theta = 60.0 s, M = 5.0, t = 360.0 s")
→ y = 6.32121
Frequency response of first-order lags in series (amplitude ratio and phase)chemeng_lag_frequency_response

Amplitude ratio and phase angle of a process made of one to three first-order lags in series, at angular frequency w.

AR = \frac{K}{\prod_i\sqrt{1 + \omega^2\tau_i^2}},\quad \varphi = -\sum_i \arctan(\omega\tau_i)

Inputs

  • K process gain
  • taus time constants of the lags, in t_unit vector
  • t_unit unit of the time constants choice
  • w angular frequency of the input sinusoid [rad/s]

Returns

  • AR amplitude ratio (output amplitude per input amplitude)
  • phase_deg phase angle in degrees (negative: lag)

Applies when

  • K > 0
  • linear lags without dead time

Example

m.ask("Lag frequency response: K = 2.0, taus = [10.0], t_unit = s, w = 0.1 rad/s")
→ AR = 1.41421, phase_deg = -45
Gain and phase margins of a PI loop around lags in serieschemeng_pi_loop_margins

Gain margin, phase margin and the two crossover frequencies of a loop with a PI controller and a process of three to five first-order lags.

GM = \frac{1}{|L(j\omega_{pc})|},\quad PM = 180^\circ + \arg L(j\omega_{gc})

Inputs

  • Kc controller gain
  • tauI integral time [s]
  • K process gain
  • taus time constants of the lags, in t_unit (the integral time is converted to this unit too) vector
  • t_unit unit of the time constants choice

Returns

  • GM gain margin (ratio)
  • PM_deg phase margin, degrees
  • w_pc phase-crossover frequency (phase -180 degrees) [rad/s]
  • w_gc gain-crossover frequency (|L| = 1) [rad/s]

Applies when

  • one phase crossover (refused otherwise)
  • Kc K > 0

Example

m.ask("PI loop margins: Kc = 1.0, tauI = 5.0 s, K = 2.0, taus = [1.0, 1.0, 1.0], t_unit = min")
→ GM = 3.22094, PM_deg = 51.0531, w_pc = 0.02625 rad/s, w_gc = 0.0131317 rad/s
Process gain and time constant from step-test data (least squares)chemeng_first_order_step_fit

Gain and time constant of a first-order process (dead time known) fitted by least squares to the recorded response of a step test.

\min_{K,\tau}\sum_k\left[y_k - KM\left(1 - e^{-(t_k-\theta)/\tau}\right)\right]^2

Inputs

  • t sample times from the moment of the step, in t_unit vector
  • y output deviations at those times vector
  • t_unit unit of the times choice
  • M size of the input step
  • theta dead time (known) [s]

Returns

  • K process gain
  • tau time constant [s]

Applies when

  • step from steady state
  • first-order response after the dead time
  • a unique interior least-squares minimum

Example

m.ask("First-order step test fit: t = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 8.0, 10.0, 12.0, 15.0, 20.0], y = [0.0, 0.0, 1.7, 3.1, 4.3, 5.2, 6.0, 7.1, 7.9, 8.4, 8.8, 9.1], t_unit = min, M = 5.0, theta = 60.0 s")
→ K = 1.86707, tau = 292.778 s
Proportional control: steady-state offset after a set-point stepchemeng_p_control_offset

Steady-state output (as a fraction of a set-point step) and the offset of a P-only feedback loop around a process of first-order lags in series, after checking the loop is stable.

\text{offset} = \frac{1}{1 + K_cK}

Inputs

  • Kc controller gain
  • K process gain
  • taus time constants of the first-order lags in series, in t_unit vector
  • t_unit unit of the time constants choice

Returns

  • y_ss final output change per unit set-point change
  • offset steady-state offset per unit set-point change

Applies when

  • Kc K > 0
  • the closed loop is stable (checked by the Routh array)

Example

m.ask("P-only control offset: Kc = 2.0, K = 1.5, taus = [5.0, 2.0], t_unit = min")
→ y_ss = 0.75, offset = 0.25
Ziegler-Nichols closed-loop tuning of lags in serieschemeng_ziegler_nichols_tuning

Ultimate gain and period of a process of first-order lags in series, and the Ziegler-Nichols closed-loop settings of a P, PI or PID controller.

\sum_i\arctan(\omega_u\tau_i) = \pi,\quad K_u = \frac{1}{|G(j\omega_u)|},\quad P_u = \frac{2\pi}{\omega_u}

Inputs

  • K process gain
  • taus time constants of the lags (three or more), in t_unit vector
  • t_unit unit of the time constants choice
  • controller controller type: P, PI or PID choice

Returns

  • Ku ultimate gain
  • Pu ultimate period [s]
  • Kc controller gain
  • tauI integral time (PI, PID) [s]
  • tauD derivative time (PID) [s]

Applies when

  • three or more lags (a finite ultimate gain)
  • K > 0

Example

m.ask("Ziegler-Nichols tuning: K = 2.0, taus = [1.0, 1.0, 1.0], t_unit = min, controller = PID")
→ Ku = 4, Pu = 217.656 s, Kc = 2.4, tauI = 108.828 s, tauD = 27.207 s

Property estimation 8

Gas compressibility from the virial equation (Pitzer-Abbott correlation)chemeng_virial_compressibility

Second virial coefficient from the Abbott (Pitzer) correlation and the compressibility factor Z = 1 + BP/(RT) of a gas at moderate pressure.

\frac{BP_c}{RT_c} = 0.083 - \frac{0.422}{T_r^{1.6}} + \omega\left(0.139 - \frac{0.172}{T_r^{4.2}}\right),\quad Z = 1 + \frac{BP}{RT}

Inputs

  • T temperature [K]
  • P pressure [Pa]
  • Tc critical temperature [K]
  • Pc critical pressure [Pa]
  • omega acentric factor

Returns

  • B second virial coefficient [m^3/mol]
  • Z compressibility factor

Applies when

  • moderate pressure (truncated virial equation)
  • non-polar or slightly polar gas

Example

m.ask("Virial compressibility: T = 510.0 K, P = 2500000.0 Pa, Tc = 425.1 K, Pc = 3796000.0 Pa, omega = 0.2")
→ B = -0.000205361 m^3/mol, Z = 0.878925
Heat of vaporisation at another temperature (Watson)chemeng_watson_heat_of_vaporization

Heat of vaporisation at T from a known value at T_ref and the critical temperature (Watson's correlation, exponent 0.38).

\Delta H_v(T) = \Delta H_v(T_{ref})\left(\frac{1 - T_r}{1 - T_{r,ref}}\right)^{0.38}

Inputs

  • T temperature wanted [K]
  • T_ref temperature of the known value [K]
  • Hvap_ref heat of vaporisation at T_ref [J/mol]
  • Tc critical temperature [K]

Returns

  • Hvap heat of vaporisation at T [J/mol]

Applies when

  • T, T_ref < Tc

Example

m.ask("Watson heat of vaporization: T = 298.15 K, T_ref = 373.15 K, Hvap_ref = 40656.0 J/mol, Tc = 647.1 K")
→ Hvap = 44571.7 J/mol
Heat of vaporisation at the normal boiling point (Riedel)chemeng_riedel_heat_of_vaporization

Heat of vaporisation at the normal boiling point from the boiling point and critical constants (Riedel's equation, Pc in bar).

\Delta H_{vb} = 1.093\,R\,T_b\,\frac{\ln P_c - 1.013}{0.930 - T_{br}}

Inputs

  • Tb normal boiling point [K]
  • Tc critical temperature [K]
  • Pc critical pressure [Pa]

Returns

  • Hvap_b heat of vaporisation at the normal boiling point [J/mol]

Applies when

  • Tb well below Tc

Example

m.ask("Riedel heat of vaporization: Tb = 294.0 K, Tc = 466.0 K, Pc = 5550000.0 Pa")
→ Hvap_b = 26828.6 J/mol
Heat of vaporisation from the acentric factor (Pitzer)chemeng_pitzer_heat_of_vaporization

Heat of vaporisation at T from the critical temperature and acentric factor (Pitzer's corresponding-states correlation as fitted by Carruth and Kobayashi).

\frac{\Delta H_v}{RT_c} = 7.08(1-T_r)^{0.354} + 10.95\,\omega(1-T_r)^{0.456}

Inputs

  • T temperature [K]
  • Tc critical temperature [K]
  • omega acentric factor

Returns

  • Hvap heat of vaporisation [J/mol]

Applies when

  • 0.6 < Tr < 1 (fit range)

Example

m.ask("Pitzer heat of vaporization: T = 452.0 K, Tc = 645.6 K, omega = 0.35")
→ Hvap = 36691 J/mol
Peng-Robinson equation of state: compressibility and fugacity coefficientchemeng_peng_robinson

Compressibility factors (vapour and liquid roots) and fugacity coefficients of a pure substance at T and P from the Peng-Robinson equation of state.

Z^3 - (1-B)Z^2 + (A - 3B^2 - 2B)Z - (AB - B^2 - B^3) = 0

Inputs

  • Tc critical temperature [K]
  • Pc critical pressure [Pa]
  • omega acentric factor
  • T temperature [K]
  • P pressure [Pa]

Returns

  • Z_vapour compressibility factor of the vapour-like (largest) root
  • Z_liquid compressibility factor of the liquid-like (smallest) root
  • phi_vapour fugacity coefficient on the vapour root
  • phi_liquid fugacity coefficient on the liquid root
  • n_roots number of real roots above the covolume (1 or 3)

Applies when

  • pure substance
  • not too close to the critical point or a spinodal (a double root is refused)
  • one real root: both roots reported equal

Example

m.ask("Peng-Robinson: Tc = 507.6 K, Pc = 3025000.0 Pa, omega = 0.2975, T = 400.0 K, P = 1000000.0 Pa")
→ Z_vapour = 0.644021, Z_liquid = 0.0469282, phi_vapour = 0.746232, phi_liquid = 0.421597, n_roots = 3
Saturated liquid molar volume (Rackett)chemeng_rackett_liquid_volume

Molar volume of a saturated liquid from the critical constants and the critical compressibility factor (Rackett equation).

V_s = \frac{RT_c}{P_c}Z_c^{\,1 + (1-T_r)^{2/7}}

Inputs

  • T temperature [K]
  • Tc critical temperature [K]
  • Pc critical pressure [Pa]
  • Zc critical compressibility factor

Returns

  • Vm saturated liquid molar volume [m^3/mol]

Applies when

  • T < Tc

Example

m.ask("Rackett liquid volume: T = 272.03889 K, Tc = 369.83 K, Pc = 4248000.0 Pa, Zc = 0.2763")
→ Vm = 8.29923e-05 m^3/mol
Soave-Redlich-Kwong equation of state: compressibility and fugacity coefficientchemeng_srk

Compressibility factors (vapour and liquid roots) and fugacity coefficients of a pure substance at T and P from the Soave-Redlich-Kwong equation of state.

Z^3 - Z^2 + (A - B - B^2)Z - AB = 0

Inputs

  • Tc critical temperature [K]
  • Pc critical pressure [Pa]
  • omega acentric factor
  • T temperature [K]
  • P pressure [Pa]

Returns

  • Z_vapour compressibility factor of the vapour-like (largest) root
  • Z_liquid compressibility factor of the liquid-like (smallest) root
  • phi_vapour fugacity coefficient on the vapour root
  • phi_liquid fugacity coefficient on the liquid root
  • n_roots number of real roots above the covolume (1 or 3)

Applies when

  • pure substance
  • not too close to the critical point or a spinodal
  • one real root: both roots reported equal

Example

m.ask("Soave-Redlich-Kwong: Tc = 507.6 K, Pc = 3025000.0 Pa, omega = 0.2975, T = 400.0 K, P = 1000000.0 Pa")
→ Z_vapour = 0.65891, Z_liquid = 0.0532184, phi_vapour = 0.757696, phi_liquid = 0.430644, n_roots = 3
Vapour pressure by the Lee-Kesler correlationchemeng_lee_kesler_vapour_pressure

Vapour pressure of a pure substance from its critical constants and acentric factor (Lee-Kesler corresponding-states correlation).

\ln\frac{P^{sat}}{P_c} = f^{(0)}(T_r) + \omega f^{(1)}(T_r)

Inputs

  • T temperature [K]
  • Tc critical temperature [K]
  • Pc critical pressure [Pa]
  • omega acentric factor

Returns

  • Psat vapour pressure [Pa]

Applies when

  • T < Tc
  • non-polar or slightly polar substances

Example

m.ask("Lee-Kesler vapour pressure: T = 400.0 K, Tc = 568.7 K, Pc = 2490000.0 Pa, omega = 0.399")
→ Psat = 104829 Pa

Reactor design 20

Batch reactor conversion after a time (first order)chemeng_batch_conversion_first_order

Conversion reached in an isothermal batch reactor after time t for a first-order reaction.

X = 1 - e^{-kt}

Inputs

  • k first-order rate constant [1/s]
  • t reaction time [s]

Returns

  • X conversion of A

Applies when

  • isothermal, constant volume, -r_A = k C_A

Example

m.ask("First-order batch reactor conversion: k = 0.001 1/s, t = 1000.0 s")
→ X = 0.632121
Batch reactor conversion after a time (second order)chemeng_batch_conversion_second_order

Conversion and concentration reached in an isothermal batch reactor after time t when -r_A = k C_A^2.

X = \frac{k C_{A0} t}{1 + k C_{A0} t}

Inputs

  • k second-order rate constant (-r_A = k C_A^2) [m^3/(mol*s)]
  • CA0 feed (initial) concentration of A [mol/m^3]
  • t reaction time [s]

Returns

  • X conversion of A
  • CA concentration of A at time t [mol/m^3]

Applies when

  • isothermal, constant volume

Example

m.ask("Second-order batch reactor conversion: k = 0.0001 m^3/(mol*s), CA0 = 1000.0 mol/m^3, t = 40.0 s")
→ X = 0.8, CA = 200 mol/m^3
Batch reactor time for a conversion (first order)chemeng_batch_time_first_order

Reaction time an isothermal batch reactor needs to reach conversion X for a first-order reaction.

t = \frac{1}{k}\ln\frac{1}{1-X}

Inputs

  • k first-order rate constant [1/s]
  • X conversion of A wanted

Returns

  • t reaction time [s]

Applies when

  • 0 <= X < 1
  • isothermal, constant volume, -r_A = k C_A

Example

m.ask("First-order batch reactor time: k = 0.001 1/s, X = 0.9")
→ t = 2302.59 s
Batch reactor time for a conversion (second order)chemeng_batch_time_second_order

Reaction time an isothermal batch reactor needs to reach conversion X when -r_A = k C_A^2.

t = \frac{X}{k\,C_{A0}(1-X)}

Inputs

  • k second-order rate constant (-r_A = k C_A^2) [m^3/(mol*s)]
  • CA0 feed (initial) concentration of A [mol/m^3]
  • X conversion of A wanted

Returns

  • t reaction time [s]

Applies when

  • 0 <= X < 1
  • isothermal, constant volume

Example

m.ask("Second-order batch reactor time: k = 0.0001 m^3/(mol*s), CA0 = 1000.0 mol/m^3, X = 0.8")
→ t = 40 s
CSTR conversion for a volume (first order)chemeng_cstr_conversion_first_order

Steady-state conversion of a CSTR of volume V for a first-order liquid-phase reaction.

X = \frac{k\tau}{1 + k\tau},\ \tau = V/v_0

Inputs

  • v0 volumetric feed flow [m^3/s]
  • V reactor volume [m^3]
  • k first-order rate constant [1/s]

Returns

  • X conversion of A

Applies when

  • steady state, perfect mixing, constant density, -r_A = k C_A

Example

m.ask("First-order CSTR conversion: v0 = 0.01 m^3/s, V = 20.0 m^3, k = 0.001 1/s")
→ X = 0.666667
CSTR conversion for a volume (second order)chemeng_cstr_conversion_second_order

Steady-state conversion and exit concentration of a CSTR of volume V when -r_A = k C_A^2.

\frac{C_A}{C_{A0}} = \frac{2}{1 + \sqrt{1 + 4\,k\tau C_{A0}}}

Inputs

  • v0 volumetric feed flow [m^3/s]
  • V reactor volume [m^3]
  • k second-order rate constant (-r_A = k C_A^2) [m^3/(mol*s)]
  • CA0 feed (initial) concentration of A [mol/m^3]

Returns

  • X conversion of A
  • CA exit concentration of A [mol/m^3]

Applies when

  • steady state, perfect mixing, constant density

Example

m.ask("Second-order CSTR conversion: v0 = 0.01 m^3/s, V = 2.0 m^3, k = 1e-05 m^3/(mol*s), CA0 = 1000.0 mol/m^3")
→ X = 0.5, CA = 500 mol/m^3
CSTR volume for a conversion (first order)chemeng_cstr_volume_first_order

Volume and space time of a CSTR that reaches conversion X for a first-order liquid-phase reaction.

V = \frac{v_0\,X}{k(1-X)}

Inputs

  • v0 volumetric feed flow [m^3/s]
  • k first-order rate constant [1/s]
  • X conversion of A wanted

Returns

  • V reactor volume [m^3]
  • tau space time V/v0 [s]

Applies when

  • 0 <= X < 1
  • steady state, perfect mixing, constant density, -r_A = k C_A

Example

m.ask("First-order CSTR volume: v0 = 0.01 m^3/s, k = 0.001 1/s, X = 0.9")
→ V = 90 m^3, tau = 9000 s
CSTR volume for a conversion (second order)chemeng_cstr_volume_second_order

Volume and space time of a CSTR that reaches conversion X when -r_A = k C_A^2 (liquid phase, constant density).

V = \frac{v_0 X}{k C_{A0}(1 - X)^2}

Inputs

  • v0 volumetric feed flow [m^3/s]
  • k second-order rate constant (-r_A = k C_A^2) [m^3/(mol*s)]
  • CA0 feed (initial) concentration of A [mol/m^3]
  • X conversion of A wanted

Returns

  • V reactor volume [m^3]
  • tau space time V/v0 [s]

Applies when

  • 0 <= X < 1
  • steady state, perfect mixing, constant density, -r_A = k C_A^2

Example

m.ask("Second-order CSTR volume: v0 = 0.01 m^3/s, k = 1e-05 m^3/(mol*s), CA0 = 1000.0 mol/m^3, X = 0.8")
→ V = 20 m^3, tau = 2000 s
Equal CSTRs in series: conversion (first order)chemeng_cstrs_in_series_first_order

Conversion leaving N equal CSTRs in series, each of volume V, for a first-order liquid-phase reaction.

X = 1 - (1 + k\tau_i)^{-N}

Inputs

  • v0 volumetric feed flow [m^3/s]
  • V volume of EACH tank [m^3]
  • k first-order rate constant [1/s]
  • N number of equal tanks in series integer

Returns

  • X overall conversion of A

Applies when

  • equal tanks
  • steady state, perfect mixing in each tank, constant density

Example

m.ask("First-order CSTRs in series: v0 = 0.01 m^3/s, V = 5.0 m^3, k = 0.001 1/s, N = 3")
→ X = 0.703704
Equal CSTRs in series: conversion (second order)chemeng_cstrs_in_series_second_order

Conversion leaving N equal CSTRs in series, each of volume V, when -r_A = k C_A^2.

C_i = \frac{2C_{i-1}}{1 + \sqrt{1 + 4k\tau_i C_{i-1}}}

Inputs

  • v0 volumetric feed flow [m^3/s]
  • V volume of EACH tank [m^3]
  • k second-order rate constant (-r_A = k C_A^2) [m^3/(mol*s)]
  • CA0 feed (initial) concentration of A [mol/m^3]
  • N number of equal tanks in series integer

Returns

  • X overall conversion of A
  • CA exit concentration of A [mol/m^3]

Applies when

  • equal tanks
  • steady state, perfect mixing, constant density

Example

m.ask("Second-order CSTRs in series: v0 = 0.01 m^3/s, V = 1.0 m^3, k = 1e-05 m^3/(mol*s), CA0 = 1000.0 mol/m^3, N = 3")
→ X = 0.674359, CA = 325.641 mol/m^3
Gas-phase PFR volume with volume change (first order)chemeng_pfr_gas_volume_first_order

Volume of an isothermal, isobaric gas-phase plug-flow reactor for conversion X of a first-order reaction whose mole number changes (factor eps).

V = \frac{F_{A0}}{kC_{A0}}\left[(1+\varepsilon)\ln\frac{1}{1-X} - \varepsilon X\right]

Inputs

  • FA0 molar feed flow of A [mol/s]
  • CA0 concentration of A at the inlet [mol/m^3]
  • k first-order rate constant [1/s]
  • eps volume-change factor eps = y_A0 * (change in moles per mole of A); e.g. A -> 2B with pure A: eps = 1
  • X conversion of A wanted

Returns

  • V reactor volume [m^3]

Applies when

  • isothermal, isobaric ideal gas
  • eps > -1
  • 0 <= X < 1

Example

m.ask("First-order gas-phase PFR volume: FA0 = 10.0 mol/s, CA0 = 40.0 mol/m^3, k = 0.05 1/s, eps = 1.0, X = 0.8")
→ V = 12.0944 m^3
Gas-phase PFR volume with volume change (second order)chemeng_pfr_gas_volume_second_order

Volume of an isothermal, isobaric gas-phase plug-flow reactor for conversion X when -r_A = k C_A^2 and the mole number changes (factor eps).

V = \frac{F_{A0}}{kC_{A0}^2}\left[2\varepsilon(1+\varepsilon)\ln(1-X) + \varepsilon^2X + \frac{(1+\varepsilon)^2X}{1-X}\right]

Inputs

  • FA0 molar feed flow of A [mol/s]
  • CA0 concentration of A at the inlet [mol/m^3]
  • k second-order rate constant (-r_A = k C_A^2) [m^3/(mol*s)]
  • eps volume-change factor eps = y_A0 * (change in moles per mole of A); e.g. A -> 2B with pure A: eps = 1
  • X conversion of A wanted

Returns

  • V reactor volume [m^3]

Applies when

  • isothermal, isobaric ideal gas
  • eps > -1
  • 0 <= X < 1

Example

m.ask("Second-order gas-phase PFR volume: FA0 = 10.0 mol/s, CA0 = 40.0 mol/m^3, k = 0.001 m^3/(mol*s), eps = 1.0, X = 0.8")
→ V = 64.7641 m^3
PFR conversion for a volume (first order, liquid)chemeng_pfr_conversion_first_order

Conversion at the exit of an isothermal plug-flow reactor of volume V for a first-order constant-density reaction.

X = 1 - e^{-k\tau}

Inputs

  • v0 volumetric feed flow [m^3/s]
  • V reactor volume [m^3]
  • k first-order rate constant [1/s]

Returns

  • X conversion of A

Applies when

  • plug flow, isothermal, constant density

Example

m.ask("First-order PFR conversion: v0 = 0.01 m^3/s, V = 20.0 m^3, k = 0.001 1/s")
→ X = 0.864665
PFR conversion for a volume (second order, liquid)chemeng_pfr_conversion_second_order

Exit conversion and concentration of an isothermal plug-flow reactor of volume V when -r_A = k C_A^2 (constant density).

X = \frac{k\tau C_{A0}}{1 + k\tau C_{A0}}

Inputs

  • v0 volumetric feed flow [m^3/s]
  • V reactor volume [m^3]
  • k second-order rate constant (-r_A = k C_A^2) [m^3/(mol*s)]
  • CA0 feed (initial) concentration of A [mol/m^3]

Returns

  • X conversion of A
  • CA exit concentration of A [mol/m^3]

Applies when

  • plug flow, isothermal, constant density

Example

m.ask("Second-order PFR conversion: v0 = 0.01 m^3/s, V = 2.0 m^3, k = 1e-05 m^3/(mol*s), CA0 = 1000.0 mol/m^3")
→ X = 0.666667, CA = 333.333 mol/m^3
PFR volume for a conversion (first order, liquid)chemeng_pfr_volume_first_order

Volume of an isothermal plug-flow reactor that reaches conversion X for a first-order constant-density reaction.

V = \frac{v_0}{k}\ln\frac{1}{1-X}

Inputs

  • v0 volumetric feed flow [m^3/s]
  • k first-order rate constant [1/s]
  • X conversion of A wanted

Returns

  • V reactor volume [m^3]

Applies when

  • 0 <= X < 1
  • plug flow, isothermal, constant density

Example

m.ask("First-order PFR volume: v0 = 0.01 m^3/s, k = 0.001 1/s, X = 0.9")
→ V = 23.0259 m^3
PFR volume for a conversion (second order, liquid)chemeng_pfr_volume_second_order

Volume of an isothermal plug-flow reactor that reaches conversion X when -r_A = k C_A^2 (constant density).

V = \frac{v_0}{k C_{A0}}\,\frac{X}{1-X}

Inputs

  • v0 volumetric feed flow [m^3/s]
  • k second-order rate constant (-r_A = k C_A^2) [m^3/(mol*s)]
  • CA0 feed (initial) concentration of A [mol/m^3]
  • X conversion of A wanted

Returns

  • V reactor volume [m^3]

Applies when

  • 0 <= X < 1
  • plug flow, isothermal, constant density

Example

m.ask("Second-order PFR volume: v0 = 0.01 m^3/s, k = 1e-05 m^3/(mol*s), CA0 = 1000.0 mol/m^3, X = 0.8")
→ V = 4 m^3
Plug-flow reactor with recycle: conversion (first order)chemeng_recycle_reactor_first_order

Overall conversion of a plug-flow reactor with recycle ratio R (recycled flow / product flow) for a first-order constant-density reaction.

\frac{k\tau}{R+1} = \ln\frac{1 + R(1-X)}{(R+1)(1-X)}

Inputs

  • v0 fresh volumetric feed flow [m^3/s]
  • V reactor volume [m^3]
  • k first-order rate constant [1/s]
  • R recycle ratio: recycled flow divided by the flow leaving the system

Returns

  • X overall conversion of A

Applies when

  • R >= 0 (R = 0 is a plain PFR; large R approaches a CSTR)
  • isothermal, constant density

Example

m.ask("Recycle reactor conversion: v0 = 0.01 m^3/s, V = 20.0 m^3, k = 0.001 1/s, R = 2.0")
→ X = 0.7398
Residence-time distribution: mean, variance and tanks-in-series number from tracer datachemeng_rtd_moments

Mean residence time, variance and the equivalent number of tanks in series from a pulse-tracer response C(t) (trapezoidal rule, uneven spacing allowed).

\bar t = \frac{\int t\,C\,dt}{\int C\,dt},\quad \sigma^2 = \frac{\int (t-\bar t)^2 C\,dt}{\int C\,dt}

Inputs

  • t sample times, in the unit t_unit vector
  • C tracer concentrations at those times (any unit) vector
  • t_unit unit of the times: s, min or h choice

Returns

  • t_mean mean residence time [s]
  • variance variance of the RTD [s^2]
  • N_tanks equivalent number of equal tanks in series, t_mean^2/variance

Applies when

  • pulse tracer, closed vessel
  • times increasing, concentrations >= 0

Example

m.ask("RTD moments: t = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 12.0, 14.0], C = [0.0, 1.0, 5.0, 8.0, 10.0, 8.0, 6.0, 4.0, 3.0, 2.2, 1.5, 0.6, 0.0], t_unit = min")
→ t_mean = 307.641 s, variance = 21424.3 s^2, N_tanks = 4.41753
Reversible first-order reaction A <-> B in a batch reactorchemeng_reversible_first_order_batch

Concentrations and conversion after time t, and the equilibrium conversion, for A <-> B with first-order forward and reverse steps.

C_A = C_{Ae} + (C_{A0} - C_{Ae})e^{-(k_1+k_2)t},\ C_{Ae} = \frac{k_2(C_{A0}+C_{B0})}{k_1+k_2}

Inputs

  • k1 forward rate constant (A -> B) [1/s]
  • k2 reverse rate constant (B -> A) [1/s]
  • CA0 feed (initial) concentration of A [mol/m^3]
  • CB0 initial concentration of B [mol/m^3]
  • t reaction time [s]

Returns

  • CA concentration of A at t [mol/m^3]
  • CB concentration of B at t [mol/m^3]
  • X conversion of A at t
  • X_eq equilibrium conversion of A

Applies when

  • isothermal, constant volume

Example

m.ask("Reversible first-order batch reaction: k1 = 0.002 1/s, k2 = 0.001 1/s, CA0 = 1000.0 mol/m^3, CB0 = 0.0 mol/m^3, t = 300.0 s")
→ CA = 604.38 mol/m^3, CB = 395.62 mol/m^3, X = 0.39562, X_eq = 0.666667
Series reactions A -> B -> C: maximum of the intermediate (batch or PFR)chemeng_series_reaction_maximum

Time (or plug-flow space time) at which the intermediate B of first-order series reactions A -> B -> C peaks, starting from pure A, and the concentrations there.

t_{max} = \frac{\ln(k_2/k_1)}{k_2 - k_1},\quad C_{B,max} = C_{A0}\left(\frac{k_1}{k_2}\right)^{k_2/(k_2-k_1)}

Inputs

  • k1 rate constant of A -> B [1/s]
  • k2 rate constant of B -> C [1/s]
  • CA0 feed (initial) concentration of A [mol/m^3]

Returns

  • t_max time (or space time) of the maximum of B [s]
  • CB_max maximum concentration of B [mol/m^3]
  • CA concentration of A at the maximum [mol/m^3]
  • CC concentration of C at the maximum [mol/m^3]

Applies when

  • starting from pure A (no B or C)
  • isothermal, constant volume, first-order steps

Example

m.ask("Series reaction maximum: k1 = 0.002 1/s, k2 = 0.001 1/s, CA0 = 1000.0 mol/m^3")
→ t_max = 693.147 s, CB_max = 500 mol/m^3, CA = 250 mol/m^3, CC = 250 mol/m^3

Reservoir engineering 6

Gas initially in place from the p/z plotchemeng_gas_pz_material_balance

Original gas in place of a volumetric gas reservoir from the straight line of p/z against cumulative gas production.

\frac{p}{z} = \frac{p_i}{z_i}\left(1 - \frac{G_p}{G}\right)

Inputs

  • p average reservoir pressures, in p_unit vector
  • z gas deviation factors at those pressures vector
  • Gp cumulative gas production at standard conditions, in gp_unit vector
  • p_unit unit of the pressures choice
  • gp_unit unit of Gp: m3, MMscf or Bscf choice

Returns

  • G original gas in place at standard conditions [m^3]
  • pz_initial p/z extrapolated to no production [Pa]

Applies when

  • volumetric (no water drive) gas reservoir
  • p/z falls with production

Example

m.ask("Gas p/z material balance: p = [3200.0, 2925.0, 2525.0, 2125.0], z = [0.85, 0.84, 0.83, 0.82], Gp = [0.0, 15.0, 35.0, 55.0], p_unit = psi, gp_unit = Bscf")
→ G = 4.99351e+09 m^3, pz_initial = 2.60849e+07 Pa
Oil in place and gas-cap size from the material balance (Havlena-Odeh, gas cap)chemeng_havlena_odeh_gas_cap

Oil initially in place and the gas-cap ratio m from the straight line F/Eo = N + N m Eg/Eo of successive surveys (no water influx).

\frac{F}{E_o} = N + Nm\,\frac{E_g}{E_o}

Inputs

  • F underground withdrawals, in v_unit at reservoir conditions vector
  • Eo oil and dissolved-gas expansion per unit of oil in place vector
  • Eg gas-cap expansion term per unit of oil in place vector
  • v_unit unit of F: m3 or bbl choice

Returns

  • N oil initially in place (stock-tank volume) [m^3]
  • m ratio of initial gas-cap to oil-zone reservoir volume

Applies when

  • no water influx
  • consistent units

Example

m.ask("Havlena-Odeh gas cap: F = [5000000.0, 9300000.0, 14300000.0, 19500000.0], Eo = [0.01, 0.018, 0.027, 0.036], Eg = [0.025, 0.05, 0.08, 0.11], v_unit = bbl")
→ N = 5.05983e+07 m^3, m = 0.226683
Oil initially in place from the material balance (Havlena-Odeh straight line)chemeng_havlena_odeh_oil_in_place

Stock-tank oil initially in place from the underground withdrawal F and the total expansion term Et of successive pressure surveys (no water influx), by the straight line F = N Et through the origin.

F = N\,E_t,\quad N = \frac{\sum F E_t}{\sum E_t^2}

Inputs

  • F underground withdrawals at each survey, in v_unit at reservoir conditions vector
  • Et total expansion per unit of oil in place at each survey (reservoir volume per stock-tank volume) vector
  • v_unit unit of F: m3 or bbl choice

Returns

  • N oil initially in place (stock-tank volume) [m^3]

Applies when

  • volumetric reservoir (no water influx)
  • F and Et on one consistent basis

Example

m.ask("Havlena-Odeh oil in place: F = [580700.0, 1600000.0, 2800000.0, 4100000.0], Et = [0.0101, 0.0278, 0.0485, 0.0712], v_unit = bbl")
→ N = 9.1612e+06 m^3
Pressure build-up test: Horner analysis for permeability and extrapolated pressurechemeng_horner_buildup

Permeability and the extrapolated pressure p* from the semilog straight line of shut-in pressure against the Horner time ratio (tp + dt)/dt.

p_{ws} = p^* - m\log_{10}\frac{t_p + \Delta t}{\Delta t},\quad k = \frac{q\mu\ln 10}{4\pi mh}

Inputs

  • dt shut-in times, in t_unit vector
  • pws shut-in bottom-hole pressures, in p_unit vector
  • t_unit unit of the shut-in times choice
  • p_unit unit of the pressures choice
  • tp producing time before shut-in [s]
  • q flow rate before shut-in at reservoir conditions [m^3/s]
  • mu fluid viscosity [Pa*s]
  • h net pay thickness [m]

Returns

  • m semilog slope, pressure change per log cycle [Pa]
  • k permeability [m^2]
  • p_star extrapolated pressure p* at (tp + dt)/dt = 1 [Pa]

Applies when

  • infinite-acting radial flow on the straight line
  • the points given lie on the semilog straight line

Example

m.ask("Horner build-up analysis: dt = [2.0, 4.0, 8.0, 16.0, 24.0], pws = [2960.0, 3015.0, 3069.0, 3122.0, 3150.0], t_unit = h, p_unit = psi, tp = 1800000.0 s, q = 0.0005520392185 m^3/s, mu = 0.0008 Pa*s, h = 6.096 m")
→ m = 1.23929e+06 Pa, k = 1.07115e-14 m^2, p_star = 2.3388e+07 Pa
Steady radial flow of oil to a well (Darcy) and productivity indexchemeng_radial_darcy_flow

Steady-state reservoir flow rate into a vertical well from a circular drainage area, with an optional skin factor, and the productivity index.

q = \frac{2\pi kh\,(p_e - p_w)}{\mu\left(\ln\frac{r_e}{r_w} + S\right)}

Inputs

  • k permeability (md is converted here) [m^2]
  • h net pay thickness [m]
  • mu fluid viscosity (cP is converted here) [Pa*s]
  • pe pressure at the drainage radius [Pa]
  • pw flowing bottom-hole pressure [Pa]
  • re drainage radius [m]
  • rw wellbore radius [m]
  • S skin factor (default 0: undamaged well) optional

Returns

  • q flow rate at reservoir conditions [m^3/s]
  • PI productivity index q/(pe - pw) [m^3/(s*Pa)]

Applies when

  • steady state, single-phase incompressible flow
  • re > rw, pe > pw

Example

m.ask("Radial Darcy flow: k = 9.869233e-14 m^2, h = 9.144 m, mu = 0.0015 Pa*s, pe = 20684271.879505083 Pa, pw = 17236893.232920904 Pa, re = 304.8 m, rw = 0.09144000000000001 m")
→ q = 0.00160651 m^3/s, PI = 4.6601e-10 m^3/(s*Pa)
Transient drawdown around a well (line-source solution)chemeng_line_source_drawdown

Pressure drop and pressure at radius r and time t after a well starts producing at a constant rate in an infinite reservoir (line-source, exponential-integral solution).

\Delta p = \frac{q\mu}{4\pi kh}\,E_1\!\left(\frac{\phi\mu c_t r^2}{4kt}\right)

Inputs

  • q flow rate at reservoir conditions [m^3/s]
  • mu fluid viscosity [Pa*s]
  • k permeability [m^2]
  • h net pay thickness [m]
  • phi porosity (fraction)
  • ct total compressibility (1/psi is converted here) [1/Pa]
  • r radius from the well [m]
  • t time since production started [s]
  • pi initial reservoir pressure [Pa]

Returns

  • dp pressure drop at r and t [Pa]
  • p pressure at r and t [Pa]

Applies when

  • infinite-acting, homogeneous, slightly compressible fluid
  • constant rate from t = 0

Example

m.ask("Line-source drawdown: q = 0.001 m^3/s, mu = 0.001 Pa*s, k = 1e-13 m^2, h = 10.0 m, phi = 0.2, ct = 1e-09 1/Pa, r = 0.1 m, t = 3600.0 s, pi = 30000000.0 Pa")
→ dp = 1.02733e+06 Pa, p = 2.89727e+07 Pa

Separations 22

Absorber with N equilibrium stages (Kremser)chemeng_kremser_absorber

Solute mole fraction in the gas leaving a countercurrent absorber of N ideal stages, and the fraction of solute absorbed, for dilute gas with linear equilibrium y = m x.

\frac{y_{in} - y_{out}}{y_{in} - m x_{in}} = \frac{A^{N+1} - A}{A^{N+1} - 1}

Inputs

  • N number of ideal stages integer
  • A absorption factor A = L/(m V)
  • m slope of the equilibrium line y = m x
  • y_in solute mole fraction in the entering gas
  • x_in solute mole fraction in the entering liquid (solvent)

Returns

  • y_out solute mole fraction in the leaving gas
  • recovery fraction of the entering solute absorbed

Applies when

  • dilute, constant L and V, linear equilibrium
  • y_in > m x_in

Example

m.ask("Kremser absorber: N = 5, A = 1.4, m = 2.0, y_in = 0.05, x_in = 0.0")
→ y_out = 0.003063, recovery = 0.93874
Activity coefficients from the NRTL equationchemeng_nrtl_activity_coefficients

Activity coefficients and excess Gibbs energy of a liquid mixture from NRTL interaction parameters tau_ij and non-randomness parameters alpha_ij.

\ln\gamma_i = \frac{\sum_j x_j\tau_{ji}G_{ji}}{\sum_k x_k G_{ki}} + \sum_j \frac{x_jG_{ij}}{\sum_k x_kG_{kj}}\left(\tau_{ij} - \frac{\sum_m x_m\tau_{mj}G_{mj}}{\sum_k x_kG_{kj}}\right)

Inputs

  • x liquid mole fractions vector
  • tau NRTL parameters tau_ij (dimensionless, tau_ii = 0) at the temperature of interest matrix
  • alpha non-randomness parameters alpha_ij (symmetric, alpha_ii = 0) matrix

Returns

  • gamma1 activity coefficient of component 1
  • gamma activity coefficients of every component
  • GE_RT excess Gibbs energy over RT

Applies when

  • tau_ii = 0, alpha_ii = 0
  • all mole fractions positive

Example

m.ask("NRTL activity coefficients: x = [0.3, 0.7], tau = [[0.0, 0.8], [1.2, 0.0]], alpha = [[0.0, 0.3], [0.3, 0.0]]")
→ gamma1 = 2.25346, gamma = [2.25346353086, 1.18777953647], GE_RT = 0.3642
Activity coefficients from the UNIQUAC equationchemeng_uniquac_activity_coefficients

Activity coefficients of a liquid mixture from UNIQUAC volume and area parameters r, q and interaction parameters tau_ij (coordination number 10).

\ln\gamma_i = \ln\frac{\Phi_i}{x_i} + \frac{z}{2}q_i\ln\frac{\theta_i}{\Phi_i} + l_i - \frac{\Phi_i}{x_i}\sum_j x_jl_j + q_i\Big[1 - \ln\sum_j\theta_j\tau_{ji} - \sum_j\frac{\theta_j\tau_{ij}}{\sum_k\theta_k\tau_{kj}}\Big]

Inputs

  • x liquid mole fractions vector
  • r UNIQUAC volume parameters r_i vector
  • q UNIQUAC area parameters q_i vector
  • tau UNIQUAC parameters tau_ij = exp(-a_ij/T) at the temperature of interest (tau_ii = 1) matrix

Returns

  • gamma1 activity coefficient of component 1
  • gamma activity coefficients of every component

Applies when

  • tau_ii = 1, tau_ij > 0
  • all mole fractions positive
  • coordination number z = 10

Example

m.ask("UNIQUAC activity coefficients: x = [0.3, 0.7], r = [2.1055, 0.92], q = [1.972, 1.4], tau = [[1.0, 0.9], [1.1, 1.0]]")
→ gamma1 = 1.29869, gamma = [1.29868568479, 1.10358464339]
Activity coefficients from the Wilson equationchemeng_wilson_activity_coefficients

Activity coefficients of every component and the excess Gibbs energy of a liquid mixture from Wilson parameters Lambda_ij.

\ln\gamma_i = 1 - \ln\Big(\sum_j x_j\Lambda_{ij}\Big) - \sum_k \frac{x_k\Lambda_{ki}}{\sum_j x_j\Lambda_{kj}}

Inputs

  • x liquid mole fractions vector
  • Lam Wilson parameters Lambda_ij (dimensionless, Lambda_ii = 1) at the temperature of interest matrix

Returns

  • gamma1 activity coefficient of component 1
  • gamma activity coefficients of every component
  • GE_RT excess Gibbs energy over RT

Applies when

  • Lambda_ii = 1, Lambda_ij > 0
  • all mole fractions positive

Example

m.ask("Wilson activity coefficients: x = [0.3, 0.7], Lam = [[1.0, 0.5], [1.5, 1.0]]")
→ gamma1 = 1.05781, gamma = [1.05781025716, 1.02099043889], GE_RT = 0.0314015
Boiling (saturation) temperature from the Antoine equationchemeng_antoine_boiling_temperature

Temperature at which a pure liquid boils at pressure P, from Antoine coefficients written in a stated convention.

T^{sat} = \frac{B}{A - \log_{10} P} - C

Inputs

  • A Antoine coefficient A
  • B Antoine coefficient B
  • C Antoine coefficient C
  • units units the Antoine coefficients are written for: pressure_temperature, e.g. mmHg_degC (P in mmHg, T in degC) or kPa_K choice
  • base logarithm of the Antoine equation: log10 or ln choice
  • P pressure [Pa]

Returns

  • Tsat saturation temperature [K]

Applies when

  • the convention (units, base) is stated
  • P within the fitted range

Example

m.ask("Antoine boiling temperature: A = 8.07131, B = 1730.63, C = 233.426, units = mmHg_degC, base = log10, P = 101325.0 Pa")
→ Tsat = 373.147 K
Bubble-point pressure (Raoult's law)chemeng_raoult_bubble_pressure

Pressure at which a liquid of composition x starts to boil at temperature T, and the composition of the first bubble, for an ideal solution (Raoult's law, Antoine vapour pressures).

P_{bubble} = \sum_i x_i P_i^{sat}(T)

Inputs

  • x liquid mole fractions vector
  • ant Antoine coefficients, one row (A, B, C) per component, in the stated convention matrix
  • units units the Antoine coefficients are written for: pressure_temperature, e.g. mmHg_degC (P in mmHg, T in degC) or kPa_K choice
  • base logarithm of the Antoine equation: log10 or ln choice
  • T temperature [K]

Returns

  • P bubble-point pressure [Pa]
  • y vapour mole fractions of the first bubble

Applies when

  • ideal liquid and ideal gas (Raoult's law)
  • fractions sum to 1

Example

m.ask("Bubble-point pressure: ant = [[6.90565, 1211.033, 220.79], [6.95464, 1344.8, 219.482]], units = mmHg_degC, base = log10, x = [0.4, 0.6], T = 368.15 K")
→ P = 100906 Pa, y = [0.621960532969, 0.378039467031]
Bubble-point pressure by the modified Raoult's law (activity coefficients)chemeng_modified_raoult_bubble_pressure

The bubble-point pressure P = sum x_i gamma_i P_i^sat of a non-ideal liquid with stated activity coefficients and vapour pressures (low pressure, ideal vapour), and the vapour composition y_i = x_i gamma_i P_i^sat/P.

P = \sum_i x_i\gamma_i P_i^{sat},\quad y_i = \frac{x_i\gamma_i P_i^{sat}}{P}

Inputs

  • x liquid mole fractions (sum to 1) vector
  • gamma activity coefficient of each component at this composition vector
  • Psat vapour pressure of each pure component at the temperature, in the unit p_unit vector
  • p_unit unit of the vapour pressures: Pa, kPa, MPa, bar, atm or psi choice

Returns

  • P bubble-point pressure [Pa]
  • y1 vapour mole fraction of the first component
  • y vapour mole fractions, in the order of x

Applies when

  • low pressure (ideal vapour, Poynting factor 1)
  • activity coefficients stated for this liquid composition and temperature

Example

m.ask("Modified Raoult bubble pressure: x = [0.4, 0.6], gamma = [1.8, 1.2], Psat = [55.0, 30.0], p_unit = kPa")
→ P = 61200 Pa, y1 = 0.647059, y = [0.647058823529, 0.352941176471]
Bubble-point temperature (Raoult's law)chemeng_raoult_bubble_temperature

Temperature at which a liquid of composition x starts to boil at pressure P, and the first-bubble composition (Raoult's law, Antoine vapour pressures; iterative).

\sum_i x_i P_i^{sat}(T_{bubble}) = P

Inputs

  • x liquid mole fractions vector
  • ant Antoine coefficients, one row (A, B, C) per component, in the stated convention matrix
  • units units the Antoine coefficients are written for: pressure_temperature, e.g. mmHg_degC (P in mmHg, T in degC) or kPa_K choice
  • base logarithm of the Antoine equation: log10 or ln choice
  • P pressure [Pa]

Returns

  • T bubble-point temperature [K]
  • y vapour mole fractions of the first bubble

Applies when

  • ideal liquid and ideal gas
  • fractions sum to 1

Example

m.ask("Bubble-point temperature: ant = [[6.90565, 1211.033, 220.79], [6.95464, 1344.8, 219.482]], units = mmHg_degC, base = log10, x = [0.4, 0.6], P = 101325.0 Pa")
→ T = 368.292 K, y = [0.62184905372, 0.37815094628]
Countercurrent liquid-liquid extraction (N stages, immiscible solvents)chemeng_countercurrent_extraction

Raffinate and extract solute ratios and the fraction extracted for N ideal countercurrent stages with immiscible carrier and solvent and a constant distribution ratio Y = K X (solute-free mass-ratio basis).

\frac{X_F - X_N}{X_F - Y_S/K} = \frac{E^{N+1} - E}{E^{N+1} - 1},\ E = \frac{KS}{F}

Inputs

  • F solute-free carrier flow in the feed [kg/s]
  • S solute-free solvent flow [kg/s]
  • K distribution ratio Y = K X (mass ratios)
  • N number of ideal stages integer
  • XF solute ratio in the feed, kg solute per kg carrier
  • YS solute ratio in the entering solvent, kg solute per kg solvent

Returns

  • XN solute ratio in the final raffinate
  • Y1 solute ratio in the final extract
  • recovery fraction of the solute extracted

Applies when

  • immiscible carrier and solvent, constant K
  • XF > YS/K

Example

m.ask("Countercurrent extraction: F = 100.0 kg/s, S = 80.0 kg/s, K = 1.5, N = 4, XF = 0.1, YS = 0.0")
→ XN = 0.013438, Y1 = 0.108203, recovery = 0.86562
Crosscurrent (multiple-contact) extraction with fresh solventchemeng_crosscurrent_extraction

Raffinate solute ratio after N ideal stages, each fed with the same amount of fresh solvent, for immiscible solvents and a constant distribution ratio.

X_N = \frac{X_F}{(1 + KS/F)^N}

Inputs

  • F solute-free carrier flow (or mass) in the feed [kg/s]
  • S solute-free solvent flow (or mass) added to EACH stage [kg/s]
  • K distribution ratio Y = K X (mass ratios)
  • N number of stages integer
  • XF solute ratio in the feed, kg solute per kg carrier

Returns

  • XN solute ratio in the final raffinate
  • recovery fraction of the solute extracted

Applies when

  • immiscible carrier and solvent, constant K
  • fresh (solute-free) solvent to every stage

Example

m.ask("Crosscurrent extraction: F = 100.0 kg/s, S = 20.0 kg/s, K = 1.5, N = 4, XF = 0.1")
→ XN = 0.0350128, recovery = 0.649872
Dew-point pressure (Raoult's law)chemeng_raoult_dew_pressure

Pressure at which a vapour of composition y starts to condense at temperature T, and the composition of the first drop (Raoult's law, Antoine vapour pressures).

\frac{1}{P_{dew}} = \sum_i \frac{y_i}{P_i^{sat}(T)}

Inputs

  • y vapour mole fractions vector
  • ant Antoine coefficients, one row (A, B, C) per component, in the stated convention matrix
  • units units the Antoine coefficients are written for: pressure_temperature, e.g. mmHg_degC (P in mmHg, T in degC) or kPa_K choice
  • base logarithm of the Antoine equation: log10 or ln choice
  • T temperature [K]

Returns

  • P dew-point pressure [Pa]
  • x liquid mole fractions of the first drop

Applies when

  • ideal liquid and ideal gas
  • fractions sum to 1

Example

m.ask("Dew-point pressure: ant = [[6.90565, 1211.033, 220.79], [6.95464, 1344.8, 219.482]], units = mmHg_degC, base = log10, y = [0.4, 0.6], T = 368.15 K")
→ P = 83426 Pa, x = [0.212686334545, 0.787313665455]
Dew-point temperature (Raoult's law)chemeng_raoult_dew_temperature

Temperature at which a vapour of composition y starts to condense at pressure P, and the first-drop composition (Raoult's law, Antoine vapour pressures; iterative).

\sum_i \frac{y_i P}{P_i^{sat}(T_{dew})} = 1

Inputs

  • y vapour mole fractions vector
  • ant Antoine coefficients, one row (A, B, C) per component, in the stated convention matrix
  • units units the Antoine coefficients are written for: pressure_temperature, e.g. mmHg_degC (P in mmHg, T in degC) or kPa_K choice
  • base logarithm of the Antoine equation: log10 or ln choice
  • P pressure [Pa]

Returns

  • T dew-point temperature [K]
  • x liquid mole fractions of the first drop

Applies when

  • ideal liquid and ideal gas
  • fractions sum to 1

Example

m.ask("Dew-point temperature: ant = [[6.90565, 1211.033, 220.79], [6.95464, 1344.8, 219.482]], units = mmHg_degC, base = log10, y = [0.4, 0.6], P = 101325.0 Pa")
→ T = 374.635 K, x = [0.216267034105, 0.783732965895]
Flash with Wilson K-values (hydrocarbon mixtures)chemeng_wilson_k_flash

Vapour fraction and phase compositions of a hydrocarbon feed at T and P with K-values estimated by Wilson's correlation from critical constants and acentric factors.

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

Inputs

  • z feed mole fractions vector
  • Tc critical temperatures, K vector
  • Pc critical pressures, in the unit p_unit vector
  • omega acentric factors vector
  • p_unit unit of the critical pressures: Pa, kPa, MPa, bar, atm or psi choice
  • T flash temperature [K]
  • P flash pressure [Pa]

Returns

  • VF vapour fraction V/F
  • x liquid mole fractions
  • y vapour mole fractions
  • K Wilson K-values

Applies when

  • two-phase at the Wilson K-values
  • some K-value differs from 1 by more than 1 %
  • Wilson's correlation suits light hydrocarbons at low to moderate pressure

Example

m.ask("Wilson K-value flash: z = [0.3, 0.4, 0.3], Tc = [190.564, 369.83, 507.6], Pc = [45.99, 42.48, 30.25], omega = [0.011, 0.152, 0.3], p_unit = bar, T = 300.0 K, P = 2000000.0 Pa")
→ VF = 0.362332, x = [0.0449443371671, 0.487795919806, 0.467259743027], y = [0.748872564861, 0.245487924989, 0.00563951014995], K = [16.6622229198, 0.503259488285, 0.0120693259672]
Isothermal flash of an ideal mixture (Raoult's law)chemeng_raoult_isothermal_flash

Vapour fraction and phase compositions of a feed flashed at temperature T and pressure P, with Raoult's-law K-values from Antoine vapour pressures.

K_i = \frac{P_i^{sat}(T)}{P},\quad \sum_i \frac{z_i (K_i - 1)}{1 + \frac{V}{F}(K_i - 1)} = 0

Inputs

  • z feed mole fractions vector
  • ant Antoine coefficients, one row (A, B, C) per component, in the stated convention matrix
  • units units the Antoine coefficients are written for: pressure_temperature, e.g. mmHg_degC (P in mmHg, T in degC) or kPa_K choice
  • base logarithm of the Antoine equation: log10 or ln choice
  • T flash temperature [K]
  • P flash pressure [Pa]

Returns

  • VF vapour fraction V/F
  • x liquid mole fractions
  • y vapour mole fractions

Applies when

  • P between the dew- and bubble-point pressures at T (two phases)
  • ideal liquid and gas
  • some K-value differs from 1 by more than 1 %

Example

m.ask("Raoult isothermal flash: ant = [[6.90565, 1211.033, 220.79], [6.95464, 1344.8, 219.482]], units = mmHg_degC, base = log10, z = [0.5, 0.5], T = 368.15 K, P = 101325.0 Pa")
→ VF = 0.430535, x = [0.404485322459, 0.595514677541], y = [0.626336606294, 0.373663393706]
Isothermal flash with given K-values (Rachford-Rice)chemeng_rachford_rice_flash

Vapour fraction and the liquid and vapour compositions of a feed flashed at conditions where the K-values are known.

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

Inputs

  • z feed mole fractions vector
  • K equilibrium ratios K_i = y_i/x_i vector

Returns

  • VF vapour fraction V/F
  • x liquid mole fractions
  • y vapour mole fractions

Applies when

  • two-phase: sum z K > 1 and sum z/K > 1
  • K-values independent of composition
  • some K-value differs from 1 by more than 1 % (well-conditioned)

Example

m.ask("Rachford-Rice flash: z = [0.5, 0.3, 0.2], K = [1.685, 0.742, 0.532]")
→ VF = 0.69073, x = [0.339408696966, 0.365056059037, 0.295535243996], y = [0.571903654388, 0.270871595806, 0.157224749806]
McCabe-Thiele number of theoretical stages (binary)chemeng_mccabe_thiele_stages

Number of theoretical stages (the partial reboiler counted as one) of a binary column at reflux ratio R, by stepping between the operating lines and a constant-alpha equilibrium curve, with the feed switched at the intersection of the operating lines.

y_{n+1} = \frac{R}{R+1}x_n + \frac{x_D}{R+1},\quad x_n = \frac{y_n}{\alpha - (\alpha-1)y_n}

Inputs

  • alpha relative volatility of the light component (constant)
  • zF mole fraction of the light component in the feed
  • xD mole fraction of the light component in the distillate
  • q feed quality q: 1 saturated liquid, 0 saturated vapour, > 1 subcooled, < 0 superheated
  • xB mole fraction of the light component in the bottoms
  • R reflux ratio L/D

Returns

  • N theoretical stages including the partial reboiler
  • Rmin minimum reflux ratio

Applies when

  • binary, constant alpha, constant molar overflow, total condenser
  • R > R_min
  • 0 < xB < zF < xD < 1

Example

m.ask("McCabe-Thiele stages: alpha = 2.5, zF = 0.5, xD = 0.95, q = 1.0, xB = 0.05, R = 2.0")
→ N = 11, Rmin = 1.1
Minimum number of stages at total reflux (Fenske)chemeng_fenske_minimum_stages

The minimum number of equilibrium stages of a binary distillation at total reflux by the Fenske equation (constant relative volatility), counting the partial reboiler as a stage.

N_{min} = \frac{\ln\left[\frac{x_D}{1 - x_D}\,\frac{1 - x_B}{x_B}\right]}{\ln\alpha}

Inputs

  • alpha relative volatility of the light component (constant)
  • xD mole fraction of the light component in the distillate
  • xB mole fraction of the light component in the bottoms

Returns

  • Nmin minimum number of equilibrium stages (partial reboiler included)
  • Nmin_trays minimum number of trays (Nmin - 1, the reboiler excluded)

Applies when

  • binary, constant alpha
  • 0 < xB < xD < 1
  • total reflux, total condenser

Example

m.ask("Fenske minimum stages: alpha = 2.5, xD = 0.95, xB = 0.05")
→ Nmin = 6.42687, Nmin_trays = 5.42687
Minimum reflux of a multicomponent column (Underwood)chemeng_multicomponent_underwood

The minimum reflux ratio of a multicomponent distillation with constant relative volatilities by Underwood's equations: the root theta between the key volatilities of sum alpha_i z_i/(alpha_i - theta) = 1 - q, then R_min + 1 = sum alpha_i x_D,i/(alpha_i - theta).

\sum_i \frac{\alpha_i z_i}{\alpha_i - \theta} = 1 - q,\quad R_{min} + 1 = \sum_i \frac{\alpha_i x_{D,i}}{\alpha_i - \theta}

Inputs

  • alpha relative volatility of each component (any common reference, constant) vector
  • z feed mole fractions (sum to 1) vector
  • xD distillate mole fractions at minimum reflux (sum to 1) vector
  • q feed quality q (1 saturated liquid, 0 saturated vapour)
  • lk light key: its position in the lists (1 = first) integer
  • hk heavy key: its position in the lists integer

Returns

  • theta Underwood root between the key volatilities
  • Rmin minimum reflux ratio L/D

Applies when

  • constant relative volatilities and molar overflow
  • adjacent keys (no component between them in volatility)
  • the distillate composition at minimum reflux is stated

Example

m.ask("Multicomponent minimum reflux: alpha = [2.5, 1.0, 0.5], z = [0.4, 0.3, 0.3], xD = [0.9, 0.1, 0.0], q = 1.0, lk = 1, hk = 2")
→ theta = 1.40263, Rmin = 0.802
Minimum reflux ratio of a binary column (Underwood)chemeng_binary_minimum_reflux

Minimum reflux ratio of a binary distillation with constant relative volatility, for any feed condition q (Underwood's equations).

\sum_i \frac{\alpha_i z_{F,i}}{\alpha_i - \theta} = 1 - q,\quad R_{min} + 1 = \sum_i \frac{\alpha_i x_{D,i}}{\alpha_i - \theta}

Inputs

  • alpha relative volatility of the light component (constant)
  • zF mole fraction of the light component in the feed
  • xD mole fraction of the light component in the distillate
  • q feed quality q: 1 saturated liquid, 0 saturated vapour, > 1 subcooled, < 0 superheated

Returns

  • Rmin minimum reflux ratio L/D

Applies when

  • binary, constant alpha, constant molar overflow
  • 0 < zF < xD < 1

Example

m.ask("Minimum reflux ratio: alpha = 2.5, zF = 0.5, xD = 0.95, q = 1.0")
→ Rmin = 1.1
Packed absorber: number of transfer units and height (Colburn)chemeng_absorber_transfer_units

Number of overall gas-phase transfer units and packed height of a dilute countercurrent absorber with linear equilibrium (Colburn's equation).

N_{OG} = \frac{\ln\!\left[\left(1-\frac{1}{A}\right)\frac{y_1 - m x_2}{y_2 - m x_2} + \frac{1}{A}\right]}{1 - 1/A}

Inputs

  • y1 solute mole fraction in the gas entering (bottom)
  • y2 solute mole fraction in the gas leaving (top)
  • x2 solute mole fraction in the liquid entering (top)
  • m slope of the equilibrium line y = m x
  • A absorption factor A = L/(m V)
  • HOG height of an overall gas-phase transfer unit [m]

Returns

  • NOG number of overall gas-phase transfer units
  • Z packed height [m]

Applies when

  • dilute, constant L and V, linear equilibrium
  • y1 > y2 > m x2
  • no pinch

Example

m.ask("Absorber transfer units: y1 = 0.02, y2 = 0.001, x2 = 0.0, m = 1.2, A = 1.5, HOG = 0.6 m")
→ NOG = 5.97729, Z = 3.58637 m
Stripper with N equilibrium stages (Kremser)chemeng_kremser_stripper

Solute mole fraction in the liquid leaving a countercurrent stripper of N ideal stages, and the fraction stripped, for dilute liquid with linear equilibrium y = m x.

\frac{x_{in} - x_{out}}{x_{in} - y_{in}/m} = \frac{S^{N+1} - S}{S^{N+1} - 1}

Inputs

  • N number of ideal stages integer
  • S stripping factor S = m V/L
  • m slope of the equilibrium line y = m x
  • x_in solute mole fraction in the entering liquid
  • y_in solute mole fraction in the entering stripping gas

Returns

  • x_out solute mole fraction in the leaving liquid
  • recovery fraction of the entering solute stripped

Applies when

  • dilute, constant L and V, linear equilibrium
  • x_in > y_in/m

Example

m.ask("Kremser stripper: N = 6, S = 1.5, m = 3.0, x_in = 0.01, y_in = 0.0")
→ x_out = 0.000310831, recovery = 0.968917
Vapour pressure from the Antoine equationchemeng_antoine_vapour_pressure

Vapour pressure of a pure liquid at temperature T from Antoine coefficients written in a stated convention (logarithm and units).

\log_{10} P^{sat} = A - \frac{B}{T + C}

Inputs

  • A Antoine coefficient A
  • B Antoine coefficient B
  • C Antoine coefficient C
  • units units the Antoine coefficients are written for: pressure_temperature, e.g. mmHg_degC (P in mmHg, T in degC) or kPa_K choice
  • base logarithm of the Antoine equation: log10 or ln choice
  • T temperature [K]

Returns

  • Psat vapour pressure [Pa]

Applies when

  • the convention (units, base) is stated
  • T within the range the coefficients were fitted for

Example

m.ask("Antoine vapour pressure: A = 8.07131, B = 1730.63, C = 233.426, units = mmHg_degC, base = log10, T = 373.15 K")
→ Psat = 101337 Pa

Transport 7

Constant-pressure cake filtration: filtrate volume after a timechemeng_cake_filtration_volume

Volume of filtrate collected after time t in constant-pressure cake filtration (Ruth equation with cake and medium resistances).

t = \frac{\mu\alpha c}{2A^2\Delta P}V^2 + \frac{\mu R_m}{A\,\Delta P}V

Inputs

  • A filter area [m^2]
  • dP pressure difference across cake and medium [Pa]
  • mu filtrate viscosity [Pa*s]
  • alpha specific cake resistance [m/kg]
  • c mass of dry cake deposited per volume of filtrate [kg/m^3]
  • Rm filter medium resistance [1/m]
  • t filtration time [s]

Returns

  • V filtrate volume collected [m^3]

Applies when

  • constant pressure, incompressible cake
  • Rm > 0

Example

m.ask("Cake filtration volume: A = 1.0 m^2, dP = 100000.0 Pa, mu = 0.001 Pa*s, alpha = 100000000000.0 m/kg, c = 20.0 kg/m^3, Rm = 10000000000.0 1/m, t = 600.0 s")
→ V = 0.24 m^3
Diffusion of A through stagnant B (Stefan film)chemeng_stefan_diffusion_flux

Steady molar flux of A diffusing through a stagnant film of non-diffusing B in an ideal gas (evaporation, absorption through an inert).

N_A = \frac{cD_{AB}}{L}\ln\frac{1 - y_{A2}}{1 - y_{A1}},\quad c = \frac{P}{RT}

Inputs

  • D diffusivity of A in B [m^2/s]
  • P total pressure [Pa]
  • T temperature [K]
  • L film thickness (diffusion path length) [m]
  • yA1 mole fraction of A at the start of the path
  • yA2 mole fraction of A at the end of the path

Returns

  • NA molar flux of A [mol/(m^2*s)]

Applies when

  • steady state, ideal gas, constant D
  • B stagnant (no net flux of B)

Example

m.ask("Stefan diffusion flux: D = 2.6e-05 m^2/s, P = 101325.0 Pa, T = 298.15 K, L = 0.1 m, yA1 = 0.0313, yA2 = 0.0")
→ NA = 0.00033795 mol/(m^2*s)
Equimolar counterdiffusion fluxchemeng_equimolar_counterdiffusion

The molar flux of A through a film of thickness L in equimolar counterdiffusion (N_B = -N_A, ideal gas): N_A = c D (y_A1 - y_A2)/L with c = P/(R T).

N_A = \frac{P}{RT}\,\frac{D_{AB}\,(y_{A1} - y_{A2})}{L}

Inputs

  • D diffusivity of A in B [m^2/s]
  • P total pressure [Pa]
  • T temperature [K]
  • L film (path) thickness [m]
  • yA1 mole fraction of A at z = 0
  • yA2 mole fraction of A at z = L

Returns

  • NA molar flux of A [mol/(m^2*s)]
  • NB molar flux of B (= -N_A) [mol/(m^2*s)]

Applies when

  • steady state, ideal gas, constant D
  • equimolar counterdiffusion (N_B = -N_A)
  • yA1 > yA2

Example

m.ask("Equimolar counterdiffusion flux: D = 2.3e-05 m^2/s, P = 101325.0 Pa, T = 298.15 K, L = 0.1 m, yA1 = 0.2, yA2 = 0.05")
→ NA = 0.00141015 mol/(m^2*s), NB = -0.00141015 mol/(m^2*s)
Mass-transfer coefficient from a stated Sherwood correlationchemeng_mass_transfer_coefficient

The convective mass-transfer coefficient k_c = Sh D/L from the Reynolds and Schmidt numbers by a stated correlation: a sphere (Ranz-Marshall), a flat plate in laminar flow (average) or turbulent flow in a pipe (Linton-Sherwood).

Sh = \frac{k_c L}{D},\quad Sh = 2 + 0.6\,Re^{1/2}Sc^{1/3}\ \text{(sphere)}

Inputs

  • geometry correlation: sphere (Ranz-Marshall), flat_plate (laminar, average) or pipe (Linton-Sherwood, turbulent) choice
  • u fluid velocity [m/s]
  • L characteristic length: sphere or pipe diameter, plate length [m]
  • D diffusivity of the solute in the fluid [m^2/s]
  • rho fluid density [kg/m^3]
  • mu fluid viscosity [Pa*s]

Returns

  • Re Reynolds number rho u L/mu
  • Sc Schmidt number mu/(rho D)
  • Sh Sherwood number
  • kc mass-transfer coefficient Sh D/L [m/s]

Applies when

  • within each correlation's stated range of Re and Sc
  • dilute solute

Example

m.ask("Mass-transfer coefficient: geometry = sphere, u = 0.1 m/s, L = 0.001 m, D = 5e-09 m^2/s, rho = 1000.0 kg/m^3, mu = 0.001 Pa*s")
→ Re = 100, Sc = 200, Sh = 37.0882, kc = 0.000185441 m/s
Packed-bed pressure drop (Carman correlation)chemeng_carman_pressure_drop

Pressure drop through a packed bed from Carman's correlation of the bed friction factor (180/Re' + 2.87/Re'^0.1 form).

f_p = \frac{\left(180 + 2.871\left(\frac{Re}{1-\varepsilon}\right)^{0.9}\right)(1-\varepsilon)^2}{\varepsilon^3 Re},\quad \Delta P = \frac{f_p\,\rho v_s^2 L}{d_p}

Inputs

  • dp particle diameter [m]
  • eps bed voidage (porosity)
  • vs superficial velocity [m/s]
  • rho fluid density [kg/m^3]
  • mu fluid viscosity [Pa*s]
  • L bed depth [m]

Returns

  • dP pressure drop across the bed [Pa]

Applies when

  • 0 < eps < 1
  • incompressible flow

Example

m.ask("Carman pressure drop: dp = 0.0008 m, eps = 0.4, vs = 0.05 m/s, rho = 1000.0 kg/m^3, mu = 0.001 Pa*s, L = 1.0 m")
→ dP = 134368 Pa
Packed-bed pressure drop (Ergun equation)chemeng_ergun_pressure_drop

Pressure drop of a fluid flowing through a packed bed of spheres from the particle size, voidage, superficial velocity and fluid properties (Ergun equation).

\frac{\Delta P}{L} = \frac{150\,\mu(1-\varepsilon)^2 v_s}{\varepsilon^3 d_p^2} + \frac{1.75\,(1-\varepsilon)\rho v_s^2}{\varepsilon^3 d_p}

Inputs

  • dp particle diameter [m]
  • eps bed voidage (porosity)
  • vs superficial velocity [m/s]
  • rho fluid density [kg/m^3]
  • mu fluid viscosity [Pa*s]
  • L bed depth [m]

Returns

  • dP pressure drop across the bed [Pa]

Applies when

  • 0 < eps < 1
  • incompressible flow (or small pressure drop for a gas)
  • spherical or equivalent particles

Example

m.ask("Ergun pressure drop: dp = 0.0008 m, eps = 0.4, vs = 0.05 m/s, rho = 1000.0 kg/m^3, mu = 0.001 Pa*s, L = 1.0 m")
→ dP = 117188 Pa
Specific cake and medium resistance from constant-pressure filtration datachemeng_filtration_constants_fit

Specific cake resistance and filter-medium resistance from a constant-pressure filtration test (times and filtrate volumes), by the straight line of t/V against V.

\frac{t}{V} = \frac{\mu\alpha c}{2A^2\Delta P}V + \frac{\mu R_m}{A\Delta P}

Inputs

  • t times at which the filtrate volumes were read, in t_unit vector
  • V cumulative filtrate volumes, in v_unit vector
  • t_unit unit of the times choice
  • v_unit unit of the volumes choice
  • A filter area [m^2]
  • dP constant pressure difference [Pa]
  • mu filtrate viscosity [Pa*s]
  • c dry cake mass per volume of filtrate [kg/m^3]

Returns

  • alpha specific cake resistance [m/kg]
  • Rm filter medium resistance [1/m]
  • slope slope of t/V against V, s/m^6
  • intercept intercept of t/V against V, s/m^3

Applies when

  • constant pressure, incompressible cake
  • a positive slope and intercept

Example

m.ask("Filtration constants fit: t = [17.3, 41.3, 72.0, 108.3, 152.1, 201.7], V = [0.5, 1.0, 1.5, 2.0, 2.5, 3.0], t_unit = s, v_unit = L, A = 0.0439 m^2, dP = 338000.0 Pa, mu = 0.000895 Pa*s, c = 23.47 kg/m^3")
→ alpha = 8.07822e+11 m/kg, Rm = 4.67973e+11 1/m, slope = 1.3025e+07, intercept = 28226.9
Questions

Frequently asked

What does chemical-engineering-ai999x do?

Chemical Engineering answers questions in chemical engineering: material and energy balances, reactor design, separations (distillation, absorption, extraction), transport phenomena, process control and reservoir and petroleum basics. Each answer gives the value with its unit, the steps and the formula in LaTeX.

How do I install chemical-engineering-ai999x?

With pip: pip install chemical-engineering-ai999x. The same files are on Hugging Face (hf download AI999X/chemical-engineering-ai999x --local-dir chemical-engineering-ai999x) and GitHub.

Does it run offline?

Yes. It is a Python package that runs on an ordinary CPU without a network connection (Python >=3.10); no GPU and no API key are needed.

How many capabilities does chemical-engineering-ai999x have?

91 capabilities in 10 topics, including Separations, Reactor design, Process control, Property estimation, Energy balances.

Which field and tasks does it cover?

Field: Engineering. Tasks: Question Answering, Sentence Similarity, Feature Extraction.

What does an answer look like?

Asked "First-order CSTR volume: v0 = 36 m^3/h, k = 0.06 1/min, X = 90%", it answers: V = 90 m^3, tau = 9000 s.

What happens when a question cannot be answered?

It says so and names what is missing or out of range, instead of guessing a number.

More from AI999X

Explore every model.