Utilities (chemicals.utils)

This module contains miscellaneous functions which may be useful. This includes definitions of some chemical properties, and conversions between others.

For reporting bugs, adding feature requests, or submitting pull requests, please use the GitHub issue tracker.

chemicals.utils.API_to_SG(API)[source]

Calculates specific gravity of a liquid given its API, as shown in [1].

SG at 60F=141.5API gravity+131.5\text{SG at}~60^\circ\text{F} = \frac{141.5}{\text{API gravity} +131.5}
Parameters
APIfloat

API of the fluid [-]

Returns
SGfloat

Specific gravity of the fluid at 60 degrees Farenheight [-]

Notes

Defined only at 60 degrees Fahrenheit.

References

1

API Technical Data Book: General Properties & Characterization. American Petroleum Institute, 7E, 2005.

Examples

>>> API_to_SG(60.62)
0.7365188423901728
chemicals.utils.API_to_rho(API, rho_ref=999.0170824078306)[source]

Calculates mass density of a liquid given its API, as shown in [1].

ρ 60F=141.5ρrefAPI+131.5\rho~60^\circ\text{F} = \frac{141.5\rho_{ref}}{\text{API} + 131.5}
Parameters
APIfloat

API of the fluid [-]

rho_reffloat, optional

Density of the reference substance, [kg/m^3]

Returns
rhofloat

Mass density the fluid at 60 degrees Farenheight [kg/m^3]

Notes

Defined only at 60 degrees Fahrenheit.

References

1

API Technical Data Book: General Properties & Characterization. American Petroleum Institute, 7E, 2005.

Examples

>>> API_to_rho(rho_to_API(820))
820.0
chemicals.utils.Cp_minus_Cv(T, dP_dT, dP_dV)[source]

Calculate the difference between a real gas’s constant-pressure heat capacity and constant-volume heat capacity, as given in [1], [2], and [3]. The required derivatives should be calculated with an equation of state.

CpCv=T(PT)V2/(PV)TC_p - C_v = -T\left(\frac{\partial P}{\partial T}\right)_V^2/ \left(\frac{\partial P}{\partial V}\right)_T
Parameters
Tfloat

Temperature of fluid [K]

dP_dTfloat

Derivative of P with respect to T, [Pa/K]

dP_dVfloat

Derivative of P with respect to V, [Pa*mol/m^3]

Returns
Cp_minus_Cvfloat

Cp - Cv for a real gas, [J/mol/K]

Notes

Equivalent expressions are:

CpCv=T(VT)P2/(VP)TC_p - C_v= -T\left(\frac{\partial V}{\partial T}\right)_P^2/\left( \frac{\partial V}{\partial P}\right)_T
CpCv=T(PT)(VT)C_p - C_v = T\left(\frac{\partial P}{\partial T}\right) \left(\frac{\partial V}{\partial T}\right)

Note that these are not second derivatives, only first derivatives, some of which are squared.

References

1

Poling, Bruce E. The Properties of Gases and Liquids. 5th edition. New York: McGraw-Hill Professional, 2000.

2

Walas, Stanley M. Phase Equilibria in Chemical Engineering. Butterworth-Heinemann, 1985.

3

Gmehling, Jurgen, Barbel Kolbe, Michael Kleiber, and Jurgen Rarey. Chemical Thermodynamics for Process Simulation. 1st edition. Weinheim: Wiley-VCH, 2012.

Examples

Calculated for hexane from the PR EOS at 299 K and 1 MPa (liquid):

>>> Cp_minus_Cv(299, 582232.475794113, -3665180614672.253)
27.654681381642394
chemicals.utils.Joule_Thomson(T, V, Cp, dV_dT=None, beta=None)[source]

Calculate a real fluid’s Joule Thomson coefficient. The required derivative should be calculated with an equation of state, and Cp is the real fluid versions. This can either be calculated with dV_dT directly, or with beta if it is already known.

μJT=(TP)H=1Cp[T(VT)PV]=VCp(βT1)\mu_{JT} = \left(\frac{\partial T}{\partial P}\right)_H = \frac{1}{C_p} \left[T \left(\frac{\partial V}{\partial T}\right)_P - V\right] = \frac{V}{C_p}\left(\beta T-1\right)
Parameters
Tfloat

Temperature of fluid, [K]

Vfloat

Molar volume of fluid, [m^3/mol]

Cpfloat

Real fluid heat capacity at constant pressure, [J/mol/K]

dV_dTfloat, optional

Derivative of V with respect to T, [m^3/mol/K]

betafloat, optional

Isobaric coefficient of a thermal expansion, [1/K]

Returns
mu_JTfloat

Joule-Thomson coefficient [K/Pa]

References

1

Walas, Stanley M. Phase Equilibria in Chemical Engineering. Butterworth-Heinemann, 1985.

2

Pratt, R. M. “Thermodynamic Properties Involving Derivatives: Using the Peng-Robinson Equation of State.” Chemical Engineering Education 35, no. 2 (March 1, 2001): 112-115.

Examples

Example from [2]:

>>> Joule_Thomson(T=390, V=0.00229754, Cp=153.235, dV_dT=1.226396e-05)
1.621956080529905e-05
chemicals.utils.Parachor(MW, rhol, rhog, sigma)[source]

Calculate Parachor for a pure species, using its density in the liquid and gas phases, surface tension, and molecular weight.

P=σ0.25MWρLρVP = \frac{\sigma^{0.25} MW}{\rho_L - \rho_V}
Parameters
MWfloat

Molecular weight, [g/mol]

rholfloat

Liquid density [kg/m^3]

rhogfloat

Gas density [kg/m^3]

sigmafloat

Surface tension, [N/m]

Returns
Pfloat

Parachor, [N^0.25*m^2.75/mol]

Notes

To convert the output of this function to units of [mN^0.25*m^2.75/kmol], multiply by 5623.4132519.

Values in group contribution tables for Parachor are often listed as dimensionless, in which they are multiplied by 5623413 and the appropriate units to make them dimensionless.

References

1

Poling, Bruce E. The Properties of Gases and Liquids. 5th edition. New York: McGraw-Hill Professional, 2000.

2

Green, Don, and Robert Perry. Perry’s Chemical Engineers’ Handbook, 8E. McGraw-Hill Professional, 2007.

3

Danner, Ronald P, and Design Institute for Physical Property Data. Manual for Predicting Chemical Process Design Data. New York, N.Y, 1982.

Examples

Calculating Parachor from a known surface tension for methyl isobutyl ketone at 293.15 K

>>> Parachor(100.15888, 800.8088185536124, 4.97865317223119, 0.02672166960656005)
5.088443542210164e-05

Converting to the dimensionless form:

>>> 5623413*5.088443542210164e-05
286.14419565030687

Compared to 274.9 according to a group contribution method described in [3].

chemicals.utils.Qls_to_ms(Qls, MWs, Vmls)[source]

Converts a list of standard liquid volume flow rates to mass flow rates. Requires molecular weights and standard liquid molar volumes for all species.

mi=QliMWi1000Vmlim_i = \frac{{Ql}_i {MW}_i}{1000 {Vml}_i}
Parameters
Qlsiterable

Standard liquid volume flow rates [m^3/s]

MWsiterable

Molecular weights [g/mol]

Vmlsiterable

Molar volumes in the liquid phase [m^3/mol]

Returns
msiterable

Mass flow rates [kg/s]

Notes

Does not check that inputs are of the same length.

Examples

>>> Qls_to_ms([1.666666666e-02, 1.11111111e-01], [24, 45], [1e-4, 2e-4])
[4.0, 25.0]
chemicals.utils.Qls_to_ns(Qls, Vmls)[source]

Converts a list of standard liquid volume flow rates to mole flow rates. Requires standard liquid molar volumes for all species.

ni=QliVmlin_i = \frac{{Ql}_i}{{Vml}_i}
Parameters
Qlsiterable

Standard liquid volume flow rates [m^3/s]

Vmlsiterable

Standard liquid molar volumes of each component [m^3/mol]

Returns
nsiterable

Mole flow rates [mol/s]

Notes

Does not check that inputs are of the same length.

Examples

>>> Qls_to_ns([2e-4, 6e-4], [1e-4, 2e-4])
[2.0, 3.0]
chemicals.utils.SG(rho, rho_ref=999.0170824078306)[source]

Calculates the specific gravity of a substance with respect to another substance; by default, this is water at 15.555 °C (60 °F). For gases, normally the reference density is 1.2 kg/m^3, that of dry air. However, in general specific gravity should always be specified with respect to the temperature and pressure of its reference fluid. This can vary widely.

SG=ρρrefSG = \frac{\rho}{\rho_{ref}}
Parameters
rhofloat

Density of the substance, [kg/m^3]

rho_reffloat, optional

Density of the reference substance, [kg/m^3]

Returns
SGfloat

Specific gravity of the substance with respect to the reference density, [-]

Notes

Another common reference point is water at 4°C (rho_ref=999.9748691393087). Specific gravity is often used by consumers instead of density. The reference for solids is normally the same as for liquids - water.

Examples

>>> SG(860)
0.8608461408159591
chemicals.utils.SG_to_API(SG)[source]

Calculates API of a liquid given its specific gravity, as shown in [1].

API gravity=141.5SG131.5\text{API gravity} = \frac{141.5}{\text{SG}} - 131.5
Parameters
SGfloat

Specific gravity of the fluid at 60 degrees Farenheight [-]

Returns
APIfloat

API of the fluid [-]

Notes

Defined only at 60 degrees Fahrenheit.

References

1

API Technical Data Book: General Properties & Characterization. American Petroleum Institute, 7E, 2005.

Examples

>>> SG_to_API(0.7365)
60.62491513917175
chemicals.utils.Vfs_to_zs(Vfs, Vms)[source]

Converts a list of mass fractions to mole fractions. Requires molecular weights for all species.

zi=VfiVm,iiVfiVm,iz_i = \frac{\frac{\text{Vf}_i}{V_{m,i}}}{\sum_i \frac{\text{Vf}_i}{V_{m,i}}}
Parameters
Vfsiterable

Molar volume fractions [-]

VMsiterable

Molar volumes of species [m^3/mol]

Returns
zslist

Mole fractions [-]

Notes

Does not check that the sums add to one. Does not check that inputs are of the same length.

Molar volumes are specified in terms of pure components only. Function works with any phase.

Examples

Acetone and benzene example

>>> Vfs_to_zs([0.596, 0.404], [8.0234e-05, 9.543e-05])
[0.6369779395901142, 0.3630220604098858]
chemicals.utils.Vm_to_rho(Vm, MW)[source]

Calculate the density of a chemical, given its molar volume and molecular weight.

ρ=MW1000VM\rho = \frac{MW}{1000\cdot VM}
Parameters
Vmfloat

Molar volume, [m^3/mol]

MWfloat

Molecular weight, [g/mol]

Returns
rhofloat

Density, [kg/m^3]

References

1

Poling, Bruce E. The Properties of Gases and Liquids. 5th edition. New York: McGraw-Hill Professional, 2000.

Examples

>>> Vm_to_rho(0.000132, 86.18)
652.8787878787879
chemicals.utils.Watson_K(Tb, SG)[source]

Calculates the Watson or UOP K Characterization factor of a liquid of a liquid given its specific gravity, and its average boiling point as shown in [1].

KW=Tb1/3SG at 60FK_W = \frac{T_b^{1/3}}{\text{SG at}~60^\circ\text{F}}
Parameters
SGfloat

Specific gravity of the fluid at 60 degrees Farenheight [-]

Tbfloat

Average normal boiling point, [K]

Returns
K_Wfloat

Watson characterization factor

Notes

There are different ways to compute the average boiling point, so two different definitions are often used - K_UOP using volume average boiling point (VABP) using distillation points of 10%, 30%, 50%, 70%, and 90%; and K_Watson using mean average boiling point (MeABP).

References

1(1,2)

API Technical Data Book: General Properties & Characterization. American Petroleum Institute, 7E, 2005.

Examples

>>> Watson_K(400, .8)
11.20351186639291

Sample problem in Comments on Procedure 2B5.1 of [1]; a fluids has a MEAB of 580 F and a SG of 34.5.

>>> from fluids.core import F2K
>>> Watson_K(F2K(580), API_to_SG(34.5))
11.884570347084471
chemicals.utils.Z(T, P, V)[source]

Calculates the compressibility factor of a gas, given its temperature, pressure, and molar volume.

Z=PVRTZ = \frac{PV}{RT}
Parameters
Tfloat

Temperature, [K]

Pfloat

Pressure [Pa]

Vfloat

Molar volume, [m^3/mol]

Returns
Zfloat

Compressibility factor, [-]

References

1

Poling, Bruce E. The Properties of Gases and Liquids. 5th edition. New York: McGraw-Hill Professional, 2000.

Examples

>>> Z(600, P=1E6, V=0.00463)
0.9281016730797026
chemicals.utils.d2ns_to_dn2_partials(d2ns, dns)[source]
Convert second-order mole number derivatives of a quantity

to the following second-order partial derivative:

2nFnjni=2Fninj+Fni+Fnj\frac{\partial^2 n F}{\partial n_j \partial n_i} = \frac{\partial^2 F}{\partial n_i \partial n_j} + \frac{\partial F}{\partial n_i} + \frac{\partial F}{\partial n_j}

Requires the second order mole number derivatives and the first order mole number derivatives of the mixture only.

Parameters
d2nslist[float]

Second order derivatives of a quantity with respect to mole number (summing to 1), [prop/mol^2]

dnslist[float]

Derivatives of a quantity with respect to mole number (summing to 1), [prop/mol]

Returns
second_partial_propertieslist[list[float]]

Derivatives of a quantity with respect to mole number (summing to 1), [prop]

Notes

Does not check that the sums add to one. Does not check that inputs are of the same length.

This was originally implemented to allow for the calculation of first mole number derivatices of log fugacity coefficients; the two arguments are the second and first mole number derivatives of the overall mixture log fugacity coefficient.

Derived with the following SymPy code.

>>> from sympy import * 
>>> n1, n2 = symbols('n1, n2') 
>>> f, g, h = symbols('f, g, h', cls=Function) 
>>> diff(h(n1, n2)*f(n1,  n2), n1, n2) 
f(n1, n2)*Derivative(h(n1, n2), n1, n2) + h(n1, n2)*Derivative(f(n1, n2), n1, n2) + Derivative(f(n1, n2), n1)*Derivative(h(n1, n2), n2) + Derivative(f(n1, n2), n2)*Derivative(h(n1, n2), n1)

Examples

>>> d2ns = [[0.152, 0.08, 0.547], [0.08, 0.674, 0.729], [0.547, 0.729, 0.131]]
>>> d2ns_to_dn2_partials(d2ns, [20.0, .124, 900.52])
[[40.152, 20.203999999999997, 921.067], [20.204, 0.922, 901.3729999999999], [921.067, 901.373, 1801.1709999999998]]
chemicals.utils.d2xs_to_d2xsn1(d2xs)[source]

Convert the second mole fraction derivatives of a quantity (calculated so they do not sum to 1) to derivatives such that they do sum to 1 Requires the second derivatives of the mixture only. The size of the returned array is one less than the input in both dimensions

(2Fxixj)xiN=1=(2Fxixj2FxixN2FxjxN+2FxNxN)xiN1\left(\frac{\partial^2 F}{\partial x_i \partial x_j }\right)_{\sum_{x_i}^N =1} = \left(\frac{\partial^2 F}{\partial x_i\partial x_j} -\frac{\partial^2 F}{\partial x_i\partial x_N} -\frac{\partial^2 F}{\partial x_j\partial x_N} +\frac{\partial^2 F}{\partial x_N\partial x_N} \right)_{\sum_{x_i}^N \ne 1}
Parameters
secondlist[float]

Second of a quantity with respect to mole fraction (not summing to 1), [prop]

Returns
d2xsm1list[float]

Second derivatives of a quantity with respect to mole fraction (summing to 1 by altering the last component’s composition), [prop]

Examples

>>> d2xs_to_d2xsn1([[-2890.4327598108, -6687.0990540960065, -1549.375443699441], [-6687.099054095983, -2811.2832904869883, -1228.6223853777503], [-1549.3754436994498, -1228.6223853777562, -3667.388098758508]])
[[-3459.069971170426, -7576.489323777324], [-7576.489323777299, -4021.4266184899957]]
chemicals.utils.d2xs_to_dxdn_partials(d2xs, xs)[source]

Convert second-order mole fraction derivatives of a quantity (calculated so they do not sum to 1) to the following second-order partial derivative:

2nFxjni=2Fxixjkxk2Fxkxj\frac{\partial^2 n F}{\partial x_j \partial n_i} = \frac{\partial^2 F}{\partial x_i x_j} - \sum_k x_k \frac{\partial^2 F}{\partial x_k \partial x_j}

Requires the second derivatives and the mole fractions of the mixture only.

Parameters
d2xslist[float]
Second derivatives of a quantity with respect to mole fraction (not

summing to 1), [prop]

xslist[float]

Mole fractions of the species, [-]

Returns
partial_propertieslist[float]

Derivatives of a quantity with respect to mole number (summing to 1), [prop]

Notes

Does not check that the sums add to one. Does not check that inputs are of the same length.

Examples

>>> d2xs = [[0.152, 0.08, 0.547], [0.08, 0.674, 0.729], [0.547, 0.729, 0.131]]
>>> d2xs_to_dxdn_partials(d2xs, [0.7, 0.2, 0.1])
[[-0.02510000000000001, -0.18369999999999997, 0.005199999999999982], [-0.0971, 0.41030000000000005, 0.18719999999999992], [0.3699, 0.4653, -0.41080000000000005]]
chemicals.utils.dns_to_dn_partials(dns, F, partial_properties=None)[source]

Convert the mole number derivatives of a quantity (calculated so they do sum to 1) to partial molar quantites.

(nFni)nki=Fi+n(Fni)nki\left(\frac{\partial n F}{\partial n_i}\right)_{n_{k \ne i}} = F_i + n \left(\frac{\partial F}{\partial n_i}\right)_{n_{k\ne i}}

In the formula, the n is 1.

Parameters
dnslist[float]

Derivatives of a quantity with respect to mole number (summing to 1), [prop/mol]

Ffloat

Property evaluated at constant composition, [prop]

partial_propertieslist[float], optional

Optional output array for derivatives of a quantity with respect to mole number (summing to 1), [prop]

Returns
partial_propertieslist[float]

Derivatives of a quantity with respect to mole number (summing to 1), [prop]

Notes

Does not check that the sums add to one. Does not check that inputs are of the same length.

This applies to a specific phase only, not to a mixture of multiple phases.

This is especially useful for fugacity calculations.

Examples

>>> dns_to_dn_partials([0.001459, -0.002939, -0.004334], -0.0016567)
[-0.0001977000000000001, -0.0045957, -0.0059907]
chemicals.utils.dxs_to_dn_partials(dxs, xs, F, partial_properties=None)[source]

Convert the mole fraction derivatives of a quantity (calculated so they do not sum to 1) to partial molar quantites. Requires the derivatives and the mole fractions of the mixture.

(nFni)=(Fxi)+Fjxj(Fxj)\left(\frac{\partial n F}{\partial n_i}\right) = \left(\frac{\partial F}{\partial x_i}\right)+ F - \sum_j x_j \left(\frac{\partial F}{\partial x_j}\right)
Parameters
dxslist[float]

Derivatives of a quantity with respect to mole fraction (not summing to 1), [prop]

xslist[float]

Mole fractions of the species, [-]

Ffloat

Property evaluated at constant composition, [prop]

partial_propertieslist[float], optional

Array for Derivatives of a quantity with respect to mole number (summing to 1), [prop]

Returns
partial_propertieslist[float]

Derivatives of a quantity with respect to mole number (summing to 1), [prop]

Notes

Does not check that the sums add to one. Does not check that inputs are of the same length.

This applies to a specific phase only, not to a mixture of multiple phases.

Examples

>>> dxs_to_dn_partials([-0.0026404, -0.00719, -0.00859], [0.7, 0.2, 0.1],
... -0.0016567)
[-0.00015182, -0.0047014199999999996, -0.00610142]
chemicals.utils.dxs_to_dns(dxs, xs, dns=None)[source]

Convert the mole fraction derivatives of a quantity (calculated so they do not sum to 1) to mole number derivatives (where the mole fractions do sum to one). Requires the derivatives and the mole fractions of the mixture.

(Mni)nki=[(Mxi)xkijxj(Mxj)xkj]\left(\frac{\partial M}{\partial n_i}\right)_{n_{k\ne i}} = \left[ \left(\frac{\partial M}{\partial x_i}\right)_{x_{k\ne i}} - \sum_j x_j \left(\frac{\partial M}{\partial x_j} \right)_{x_{k\ne j}} \right]
Parameters
dxslist[float]

Derivatives of a quantity with respect to mole fraction (not summing to 1), [prop]

xslist[float]

Mole fractions of the species, [-]

dnslist[float], optional

Return array, [prop/mol]

Returns
dnslist[float]

Derivatives of a quantity with respect to mole number (summing to 1), [prop/mol]

Notes

Does not check that the sums add to one. Does not check that inputs are of the same length.

This applies to a specific phase only, not to a mixture of multiple phases.

Examples

>>> dxs_to_dns([-0.0028, -0.00719, -0.00859], [0.7, 0.2, 0.1])
[0.0014570000000000004, -0.002933, -0.004333]
chemicals.utils.dxs_to_dxsn1(dxs)[source]

Convert the mole fraction derivatives of a quantity (calculated so they do not sum to 1) to derivatives such that they do sum to 1 by changing the composition of the last component in the negative of the component which is changed. Requires the derivatives of the mixture only. The size of the returned array is one less than the input.

(Fxi)xiN=1=(FxiFxN)xiN1\left(\frac{\partial F}{\partial x_i}\right)_{\sum_{x_i}^N =1} = \left(\frac{\partial F}{\partial x_i} - \frac{\partial F}{\partial x_N}\right)_{\sum_{x_i}^N \ne 1}
Parameters
dxslist[float]

Derivatives of a quantity with respect to mole fraction (not summing to 1), [prop]

Returns
dxsm1list[float]

Derivatives of a quantity with respect to mole fraction (summing to 1 by altering the last component’s composition), [prop]

Examples

>>> dxs_to_dxsn1([-2651.3181821109024, -2085.574403592012, -2295.0860830203587])
[-356.23209909054367, 209.51167942834672]
chemicals.utils.isentropic_exponent(Cp, Cv)[source]

Calculate the isentropic coefficient of an ideal gas, given its constant- pressure and constant-volume heat capacity.

k=CpCvk = \frac{C_p}{C_v}
Parameters
Cpfloat

Ideal gas heat capacity at constant pressure, [J/mol/K]

Cvfloat

Ideal gas heat capacity at constant volume, [J/mol/K]

Returns
kfloat

Isentropic exponent, [-]

Notes

For real gases, there are more complexities and formulas. Each of the formulas reverts to this formula in the case of an ideal gas.

References

1

Poling, Bruce E. The Properties of Gases and Liquids. 5th edition. New York: McGraw-Hill Professional, 2000.

Examples

>>> isentropic_exponent(33.6, 25.27)
1.329639889196676
chemicals.utils.isentropic_exponent_PT(Cp, P, dV_dT_P)[source]

Calculate the isentropic coefficient of real fluid using the definition of P(1k)Tk=constP^{(1-k)}T^k = \text{const}.

k=11PCp(VT)Pk = \frac{1}{1 - \frac{P}{C_p}\left(\frac{\partial V}{\partial T}\right)_P}
Parameters
Cpfloat

Real heat capacity at constant pressure, [J/mol/K]

Pfloat

Pressure [Pa]

dV_dT_Pfloat

Derivative of V with respect to T (at constant pressure), [m^3/(mol*K)]

Returns
k_PTfloat

Isentropic exponent of a real fluid, [-]

References

1

Pini, Matteo. “NiceProp: An Interactive Python-Based Educational Tool for Non-Ideal Compressible Fluid Dynamics.” SoftwareX 17 (2022): 100897.

2

Kouremenos, D. A., and K. A. Antonopoulos. “Isentropic Exponents of Real Gases and Application for the Air at Temperatures from 150 K to 450 K.” Acta Mechanica 65, no. 1 (January 1, 1987): 81-99. https://doi.org/10.1007/BF01176874.

Examples

Isentropic exponent of air according to Lemmon (2000) at 1000 bar and 300 K:

>>> isentropic_exponent_PT(Cp=38.36583283578205, P=100000000.0, dV_dT_P=9.407705210161724e-08)
1.32487270350443
chemicals.utils.isentropic_exponent_PV(Cp, Cv, Vm, P, dP_dV_T)[source]

Calculate the isentropic coefficient of real fluid using the definition of PVk=constPV^k = \text{const}.

k=VPCpCv(PV)Tk = -\frac{V}{P}\frac{C_p}{C_v}\left(\frac{\partial P}{\partial V}\right)_T
Parameters
Cpfloat

Real heat capacity at constant pressure, [J/mol/K]

Cvfloat

Real heat capacity at constant volume, [J/mol/K]

Vmfloat

Molar volume, [m^3/mol]

Pfloat

Pressure [Pa]

dP_dV_Tfloat

Derivative of P with respect to V (at constant temperature), [Pa*mol/m^3]

Returns
k_PVfloat

Isentropic exponent of a real fluid, [-]

References

1

Pini, Matteo. “NiceProp: An Interactive Python-Based Educational Tool for Non-Ideal Compressible Fluid Dynamics.” SoftwareX 17 (2022): 100897.

2

Kouremenos, D. A., and K. A. Antonopoulos. “Isentropic Exponents of Real Gases and Application for the Air at Temperatures from 150 K to 450 K.” Acta Mechanica 65, no. 1 (January 1, 1987): 81-99. https://doi.org/10.1007/BF01176874.

Examples

Isentropic exponent of air according to Lemmon (2000) at 1000 bar and 300 K:

>>> isentropic_exponent_PV(Cp=38.36583283578205, Cv=23.98081290153672, Vm=4.730885141495376e-05, P=100000000.0, dP_dV_T=-5417785576072.434)
4.100576762582646
chemicals.utils.isentropic_exponent_TV(Cv, Vm, dP_dT_V)[source]

Calculate the isentropic coefficient of real fluid using the definition of TVk1=constTV^{k-1} = \text{const}.

k=1+VCv(PT)Vk = 1 + \frac{V}{C_v} \left(\frac{\partial P}{\partial T}\right)_V
Parameters
Cvfloat

Real heat capacity at constant volume, [J/mol/K]

Vmfloat

Molar volume, [m^3/mol]

dP_dT_Vfloat

Derivative of P with respect to T (at constant volume), [Pa/K]

Returns
k_TVfloat

Isentropic exponent of a real fluid, [-]

References

1

Pini, Matteo. “NiceProp: An Interactive Python-Based Educational Tool for Non-Ideal Compressible Fluid Dynamics.” SoftwareX 17 (2022): 100897.

2

Kouremenos, D. A., and K. A. Antonopoulos. “Isentropic Exponents of Real Gases and Application for the Air at Temperatures from 150 K to 450 K.” Acta Mechanica 65, no. 1 (January 1, 1987): 81-99. https://doi.org/10.1007/BF01176874.

Examples

Isentropic exponent of air according to Lemmon (2000) at 1000 bar and 300 K:

>>> isentropic_exponent_TV(Cv=23.98081290153672, Vm=4.730885141495376e-05, dP_dT_V=509689.2959155567)
2.005504495083
chemicals.utils.isobaric_expansion(V, dV_dT)[source]

Calculate the isobaric coefficient of a thermal expansion, given its molar volume at a certain T and P, and its derivative of molar volume with respect to T.

β=1V(VT)P\beta = \frac{1}{V}\left(\frac{\partial V}{\partial T} \right)_P
Parameters
Vfloat

Molar volume at T and P, [m^3/mol]

dV_dTfloat

Derivative of molar volume with respect to T, [m^3/mol/K]

Returns
betafloat

Isobaric coefficient of a thermal expansion, [1/K]

Notes

For an ideal gas, this expression simplified to:

β=1T\beta = \frac{1}{T}

References

1

Poling, Bruce E. The Properties of Gases and Liquids. 5th edition. New York: McGraw-Hill Professional, 2000.

Examples

Calculated for hexane from the PR EOS at 299 K and 1 MPa (liquid):

>>> isobaric_expansion(0.000130229900873546, 1.58875261849113e-7)
0.0012199599384121608
chemicals.utils.isothermal_compressibility(V, dV_dP)[source]

Calculate the isothermal coefficient of compressibility, given its molar volume at a certain T and P, and its derivative of molar volume with respect to P.

κ=1V(VP)T\kappa = -\frac{1}{V}\left(\frac{\partial V}{\partial P} \right)_T
Parameters
Vfloat

Molar volume at T and P, [m^3/mol]

dV_dPfloat

Derivative of molar volume with respect to P, [m^3/mol/Pa]

Returns
kappafloat

Isothermal coefficient of compressibility, [1/Pa]

Notes

For an ideal gas, this expression simplified to:

κ=1P\kappa = \frac{1}{P}

The isothermal bulk modulus is the inverse of this quantity:

K=V(PV)TK = -V\left(\frac{\partial P}{\partial V} \right)_T

The ideal gas isothermal bulk modulus is simply the gas’s pressure.

References

1

Poling, Bruce E. The Properties of Gases and Liquids. 5th edition. New York: McGraw-Hill Professional, 2000.

Examples

Calculated for hexane from the PR EOS at 299 K and 1 MPa (liquid):

>>> isothermal_compressibility(0.000130229900873546, -2.72902118209903e-13)
2.095541165119158e-09

Calculate the bulk modulus of propane from the PR EOS at 294 K as a gas:

>>> 1/isothermal_compressibility(0.0024576770482135617, -3.5943321700795866e-09)
683764.5859979445
chemicals.utils.mix_component_flows(IDs1, IDs2, flow1, flow2, fractions1, fractions2)[source]

Mix two flows of potentially different chemicals of given overall flow rates and flow fractions to determine the outlet components, flow rates, and compositions. The flows do not need to be of the same length.

Parameters
IDs1list[str]

List of identifiers of the chemical species in flow one, [-]

IDs2list[str]

List of identifiers of the chemical species in flow two, [-]

flow1float

Total flow rate of the chemicals in flow one, [mol/s]

flow2float

Total flow rate of the chemicals in flow two, [mol/s]

fractions1list[float]

Mole fractions of each chemical in flow one, [-]

fractions2list[float]

Mole fractions of each chemical in flow two, [-]

Returns
cmpslist[str]

List of identifiers of the chemical species in the combined flow, [-]

moleslist[float]

Flow rates of all chemical species in the combined flow, [mol/s]

Notes

Mass or volume flows and fractions can be used instead of molar ones.

If the two flows have the same components, the output list will be in the same order as the one given; otherwise they are sorted alphabetically.

Examples

>>> mix_component_flows(['7732-18-5', '64-17-5'], ['7732-18-5', '67-56-1'], 1, 1, [0.5, 0.5], [0.5, 0.5])
(['64-17-5', '67-56-1', '7732-18-5'], [0.5, 0.5, 1.0])
chemicals.utils.mix_component_partial_flows(IDs1, IDs2, ns1=None, ns2=None)[source]

Mix two flows of potentially different chemicals; with the feature that the mole flows of either or both streams may be unknown.

The flows do not need to be of the same length.

Parameters
IDs1list[str]

List of identifiers of the chemical species in flow one, [-]

IDs2list[str]

List of identifiers of the chemical species in flow two, [-]

ns1list[float]

Total flow rate of the chemicals in flow one, [mol/s]

ns2list[float]

Total flow rate of the chemicals in flow two, [mol/s]

Returns
cmpslist[str]

List of identifiers of the chemical species in the combined flow, [-]

moleslist[float]

Flow rates of all chemical species in the combined flow, [mol/s]

Notes

Mass or volume flows and fractions can be used instead of molar ones.

If the two flows have the same components, the output list will be in the same order as the one given; otherwise they are sorted alphabetically.

Examples

>>> mix_component_partial_flows(['7732-18-5', '64-17-5'], ['7732-18-5', '67-56-1'], [0.5, 0.5], [0.5, 0.5])
(['64-17-5', '67-56-1', '7732-18-5'], [0.5, 0.5, 1.0])
>>> mix_component_partial_flows(['7732-18-5', '64-17-5'], ['7732-18-5', '67-56-1'], None, [0.5, 0.5])
(['64-17-5', '67-56-1', '7732-18-5'], [0.0, 0.5, 0.5])
>>> mix_component_partial_flows(['7732-18-5', '64-17-5'], ['7732-18-5', '67-56-1'], [0.5, 0.5], None)
(['64-17-5', '67-56-1', '7732-18-5'], [0.5, 0.0, 0.5])
>>> mix_component_partial_flows(['7732-18-5', '64-17-5'], ['7732-18-5', '67-56-1'], None, None)
(['64-17-5', '67-56-1', '7732-18-5'], [0.0, 0.0, 0.0])
chemicals.utils.mix_multiple_component_flows(IDs, flows, fractions)[source]

Mix multiple flows of potentially different chemicals of given overall flow rates and flow fractions to determine the outlet components, flow rates, and compositions. The flows do not need to be of the same length.

Parameters
IDslist[list[str]]

List of lists of identifiers of the chemical species in the flows, [-]

flowslist[float]

List of total flow rates of the chemicals in the streams, [mol/s]

fractionslist[list[float]]

List of lists of mole fractions of each chemical in each flow, [-]

Returns
cmpslist[str]

List of identifiers of the chemical species in the combined flow, [-]

moleslist[float]

Flow rates of all chemical species in the combined flow, [mol/s]

Notes

Mass or volume flows and fractions can be used instead of molar ones.

If the every flow have the same components, the output list will be in the same order as the one given; otherwise they are sorted alphabetically.

Examples

>>> mix_multiple_component_flows([['7732-18-5', '64-17-5'], ['7732-18-5', '67-56-1']],
... [1, 1], [[0.5, 0.5], [0.5, 0.5]])
(['64-17-5', '67-56-1', '7732-18-5'], [0.5, 0.5, 1.0])
chemicals.utils.mixing_logarithmic(fracs, props)[source]

Simple function calculates a property based on weighted averages of logarithmic properties.

y=ifraciln(propi)y = \sum_i \text{frac}_i \cdot \ln(\text{prop}_i)
Parameters
fracsarray_like

Fractions of a mixture

props: array-like

Properties

Returns
propvalue

Calculated property

Notes

Does not work on negative values. Returns None if any fractions or properties are missing or are not of the same length.

Examples

>>> mixing_logarithmic([0.1, 0.9], [0.01, 0.02])
0.01866065983073615
chemicals.utils.mixing_power(fracs, props, r)[source]

Power law mixing rule for any property, with a variable exponent r as input. Optimiezd routines are available for r=-4,-3,-2,-1,1,2,3,4.

propmixr=izi(propi)r\text{prop}_{mix}^r = \sum_i z_i \left(\text{prop}_i \right)^{r}
Parameters
fracslist[float]

Mole fractions of components (or mass, or volume, etc.), [-]

propslist[float]

Properties of all components, [various]

rfloat

Power mixing exponent, [-]

Returns
propfloat

Property for mixture, [props]

Notes

This equation is entirely dimensionless; all dimensions cancel.

The following recommendations in [1] exist for different properties:

Surface tension: r = 1 Recommended by an author in [1]; but often non-linear behavior is shown and r= -1 to r=-3 is recommended. r = -1 is most often used.

Liquid thermal conductivity: r = -2 in [1]; this is known also as procedure DIPPR9B.

References

1(1,2)

Poling, Bruce E. The Properties of Gases and Liquids. 5th edition. New York: McGraw-Hill Professional, 2000.

Examples

>>> mixing_power([0.258, 0.742], [0.1692, 0.1528], -2)
0.15657104706719646
chemicals.utils.mixing_simple(fracs, props)[source]

Simple function calculates a property based on weighted averages of properties. Weights could be mole fractions, volume fractions, mass fractions, or anything else.

y=ifracipropiy = \sum_i \text{frac}_i \cdot \text{prop}_i
Parameters
fracsarray_like

Fractions of a mixture

props: array-like

Properties

Returns
propvalue

Calculated property

Notes

Returns None if there is an error, normally if one of the properties is missing or if they are not the same length as the fractions.

Examples

>>> mixing_simple([0.1, 0.9], [0.01, 0.02])
0.019000000000000003
chemicals.utils.molar_velocity_to_velocity(v_molar, MW)[source]

Calculate the mass-based velocity (m/s) from the molar velocity of the fluid.

v=vmolar1000MWv = \frac{v_{molar}\sqrt{1000}}{\sqrt{\text{MW}}}
Parameters
v_molarfloat

Molar velcoity, [m*kg^0.5/s/mol^0.5]

MWfloat

Molecular weight, [g/mol]

Returns
vfloat

Velocity, [m/s]

Examples

>>> molar_velocity_to_velocity(46., 40.445)
228.73
chemicals.utils.ms_to_Qls(ms, MWs, Vmls)[source]

Converts a list of mass flow rates to standard liquid volume flow rates. Requires molecular weights and standard molar liquid volumes for all species.

Qli=1000miVmliMWi{Ql}_i = \frac{1000 m_i {Vml}_i}{MW_i}
Parameters
msiterable

Mass flow rates [kg/s]

MWsiterable

Molecular weights [g/mol]

Vmlsiterable

Standard liquid molar volumes [m^3/mol]

Returns
Qlsiterable

Standard liquid volume flow rates [m^3/s]

Notes

Does not check that inputs are of the same length.

Examples

>>> ms_to_Qls([4.0, 5.0], [24, 45], [1e-4, 2e-4])
[0.0166666666, 0.0222222222]
chemicals.utils.ms_to_ns(ms, MWs)[source]

Converts a list of mass flow rates to mole flow rates. Requires molecular weights for all species.

ni=1000miMWin_i = \frac{1000 m_i}{MW_i}
Parameters
msiterable

Mass flow rates [kg/s]

MWsiterable

Molecular weights [g/mol]

Returns
nsiterable

Mole flow rates [mol/s]

Notes

Does not check that inputs are of the same length.

Examples

>>> ms_to_ns([4, 5], [24, 45])
[166.666, 111.111]
chemicals.utils.none_and_length_check(all_inputs, length=None)[source]

Checks inputs for suitability of use by a mixing rule which requires all inputs to be of the same length and non-None. A number of variations were attempted for this function; this was found to be the quickest.

Parameters
all_inputsarray_like of array_like

list of all the lists of inputs, [-]

lengthint, optional

Length of the desired inputs, [-]

Returns
False/Truebool

Returns True only if all inputs are the same length (or length length) and none of the inputs contain None [-]

Notes

Does not check for nan values.

Examples

>>> none_and_length_check(([1, 1], [1, 1], [1, 30], [10,0]), length=2)
True
chemicals.utils.normalize(values)[source]

Simple function which normalizes a series of values to be from 0 to 1, and for their sum to add to 1.

x=xsumixix = \frac{x}{sum_i x_i}
Parameters
valuesarray_like

array of values

Returns
fractionsarray_like

Array of values from 0 to 1

Notes

Does not work on negative values, or handle the case where the sum is zero.

Examples

>>> normalize([3, 2, 1])
[0.5, 0.3333333333333333, 0.16666666666666666]
chemicals.utils.ns_to_Qls(ns, Vmls)[source]

Converts a list of mole flow rates to standard liquid volume flow rates. Requires standard liquid molar volumes for all species.

Qli=niVmli{Ql}_i = n_i {Vml}_i
Parameters
nsiterable

Mole flow rates [mol/s]

Vmlsiterable

Standard molar liquid volumes of each component [m^3/mol]

Returns
Qlsiterable

Standard liquid volume flow rates [m^3/s]

Notes

Does not check that inputs are of the same length.

Examples

>>> ns_to_Qls([2.0, 3.0], [1e-4, 2e-4])
[2e-4, 6e-4]
chemicals.utils.ns_to_ms(ns, MWs)[source]

Converts a list of mole flow rates to mass flow rates. Requires molecular weights for all species.

mi=niMWi1000m_i = \frac{n_i MW_i}{1000}
Parameters
nsiterable

Mole flow rates [mol/s]

MWsiterable

Molecular weights [g/mol]

Returns
msiterable

Mass flow rates [kg/s]

Notes

Does not check that inputs are of the same length.

Examples

>>> ns_to_ms([166.6666666666, 111.1111111111], [24, 45])
[4.0, 5.0]
chemicals.utils.phase_identification_parameter(V, dP_dT, dP_dV, d2P_dV2, d2P_dVdT)[source]

Calculate the Phase Identification Parameter developed in [1] for the accurate and efficient determination of whether a fluid is a liquid or a gas based on the results of an equation of state. For supercritical conditions, this provides a good method for choosing which property correlations to use.

Π=V[2PVTPT2PV2PV]\Pi = V \left[\frac{\frac{\partial^2 P}{\partial V \partial T}} {\frac{\partial P }{\partial T}}- \frac{\frac{\partial^2 P}{\partial V^2}}{\frac{\partial P}{\partial V}} \right]
Parameters
Vfloat

Molar volume at T and P, [m^3/mol]

dP_dTfloat

Derivative of P with respect to T, [Pa/K]

dP_dVfloat

Derivative of P with respect to V, [Pa*mol/m^3]

d2P_dV2float

Second derivative of P with respect to V, [Pa*mol^2/m^6]

d2P_dVdTfloat

Second derivative of P with respect to both V and T, [Pa*mol/m^3/K]

Returns
PIPfloat

Phase Identification Parameter, [-]

Notes

Heuristics were used by process simulators before the invent of this parameter.

The criteria for liquid is Pi > 1; for vapor, Pi <= 1.

There is also a solid phase mechanism available. For solids, the Solid Phase Identification Parameter is greater than 1, like liquids; however, unlike liquids, d2P_dVdT is always >0; it is < 0 for liquids and gases.

References

1

Venkatarathnam, G., and L. R. Oellrich. “Identification of the Phase of a Fluid Using Partial Derivatives of Pressure, Volume, and Temperature without Reference to Saturation Properties: Applications in Phase Equilibria Calculations.” Fluid Phase Equilibria 301, no. 2 (February 25, 2011): 225-33. doi:10.1016/j.fluid.2010.12.001.

2

Jayanti, Pranava Chaitanya, and G. Venkatarathnam. “Identification of the Phase of a Substance from the Derivatives of Pressure, Volume and Temperature, without Prior Knowledge of Saturation Properties: Extension to Solid Phase.” Fluid Phase Equilibria 425 (October 15, 2016): 269-277. doi:10.1016/j.fluid.2016.06.001.

Examples

Calculated for hexane from the PR EOS at 299 K and 1 MPa (liquid):

>>> phase_identification_parameter(0.000130229900874, 582169.397484,
... -3.66431747236e+12, 4.48067893805e+17, -20518995218.2)
11.33428990564796
chemicals.utils.phase_identification_parameter_phase(d2P_dVdT, V=None, dP_dT=None, dP_dV=None, d2P_dV2=None)[source]

Uses the Phase Identification Parameter concept developed in [1] and [2] to determine if a chemical is a solid, liquid, or vapor given the appropriate thermodynamic conditions.

The criteria for liquid is PIP > 1; for vapor, PIP <= 1.

For solids, PIP(solid) is defined to be d2P_dVdT. If it is larger than 0, the species is a solid. It is less than 0 for all liquids and gases.

Parameters
d2P_dVdTfloat

Second derivative of P with respect to both V and T, [Pa*mol/m^3/K]

Vfloat, optional

Molar volume at T and P, [m^3/mol]

dP_dTfloat, optional

Derivative of P with respect to T, [Pa/K]

dP_dVfloat, optional

Derivative of P with respect to V, [Pa*mol/m^3]

d2P_dV2float, optionsl

Second derivative of P with respect to V, [Pa*mol^2/m^6]

Returns
phasestr

Either ‘s’, ‘l’ or ‘g’

Notes

The criteria for being a solid phase is checked first, which only requires d2P_dVdT. All other inputs are optional for this reason. However, an exception will be raised if the other inputs become needed to determine if a species is a liquid or a gas.

References

1

Venkatarathnam, G., and L. R. Oellrich. “Identification of the Phase of a Fluid Using Partial Derivatives of Pressure, Volume, and Temperature without Reference to Saturation Properties: Applications in Phase Equilibria Calculations.” Fluid Phase Equilibria 301, no. 2 (February 25, 2011): 225-33. doi:10.1016/j.fluid.2010.12.001.

2

Jayanti, Pranava Chaitanya, and G. Venkatarathnam. “Identification of the Phase of a Substance from the Derivatives of Pressure, Volume and Temperature, without Prior Knowledge of Saturation Properties: Extension to Solid Phase.” Fluid Phase Equilibria 425 (October 15, 2016): 269-277. doi:10.1016/j.fluid.2016.06.001.

Examples

Calculated for hexane from the PR EOS at 299 K and 1 MPa (liquid):

>>> phase_identification_parameter_phase(-20518995218.2, 0.000130229900874,
... 582169.397484, -3.66431747236e+12, 4.48067893805e+17)
'l'
chemicals.utils.property_mass_to_molar(A_mass, MW)[source]

Convert a quantity in mass units [thing/kg] to molar units [thing/mol]. The standard gram-mole is used here, as it is everwhere in this library.

Amolar=AmassMW1000A_{\text{molar}} = \frac{A_{\text{mass}} \text{MW}}{1000}
Parameters
A_massfloat

Quantity in molar units [thing/kg]

MWfloat

Molecular weight, [g/mol]

Returns
A_molarfloat

Quantity in molar units [thing/mol]

Notes

For legacy reasons, if the value A_mass is None, None is also returned and no exception is returned.

Examples

>>> property_mass_to_molar(20.0, 18.015)
0.3603
chemicals.utils.property_molar_to_mass(A_molar, MW)[source]

Convert a quantity in molar units [thing/mol] to mass units [thing/kg]. The standard gram-mole is used here, as it is everwhere in this library.

Amass=1000AmolarMWA_{\text{mass}} = \frac{1000 A_{\text{molar}}}{\text{MW}}
Parameters
A_molarfloat

Quantity in molar units [thing/mol]

MWfloat

Molecular weight, [g/mol]

Returns
A_massfloat

Quantity in molar units [thing/kg]

Notes

For legacy reasons, if the value A_molar is None, None is also returned and no exception is returned.

Examples

>>> property_molar_to_mass(500, 18.015)
27754.648903691366
chemicals.utils.radius_of_gyration(MW, A, B, C, planar=False)[source]

Calculates the radius of gyration of a molecule using the DIPPR definition. The parameters A, B, and C must be obtained from either vibrational scpectra and analysis or quantum chemistry calculations of programs such as psi <https://psicode.org/>.

For planar molecules defined by only two moments of inertia,

Rg=ABNAMWR_g = \sqrt{\sqrt{AB}\frac{N_A}{\text{MW}}}

For non-planar molecules with three moments of inertia,

Rg=2π(ABC)1/3NAMWR_g = \sqrt{\frac{2\pi(ABC)^{1/3}N_A}{\text{MW}}}
Parameters
MWfloat

Molecular weight, [g/mol]

Afloat

First principle moment of inertia, [kg*m^2]

Bfloat

Second principle moment of inertia, [kg*m^2]

Cfloat

Third principle moment of inertia, [kg*m^2]

planarbool

Whether the molecule is flat or not, [-]

Returns
Rgfloat

Radius of gyration, [m]

Notes

There are many, many quantum chemistry models available which give different results.

References

1

Green, Don, and Robert Perry. Perry’s Chemical Engineers’ Handbook, 8E. McGraw-Hill Professional, 2007.

2

Johnson III, Russell D. “NIST 101. Computational Chemistry Comparison and Benchmark Database,” 1999. https://cccbdb.nist.gov

Examples

Example calcultion in [1] for hydrazine (optimized with HF/6-31G model):

>>> radius_of_gyration(MW=32.00452, planar=False, A=5.692E-47, B=3.367E-46, C=3.681E-46)
1.50581642e-10

The same calculation was performed with psi and somewhat different parameters obtained

>>> radius_of_gyration(MW=32.00452, planar=False, A=6.345205205562681e-47, B=3.2663291891213418e-46, C=3.4321304373822523e-46)
1.507895671e-10

A planar molecule, bromosilane, has two principle moments of inertia in [2]. They are 2.80700 cm^-1 and 0.14416 cm^-1. These can be converted to MHz as follows:

These can then be converted to units of AMU*Angstrom^2, and from there to kg*m^2.

>>> A, B = 2.80700, 0.14416
>>> from scipy.constants import atomic_mass, c, angstrom
>>> A, B = A*c*1e-4, B*c*1e-4 # from cm^-1 to MHz
>>> A, B = [505379.15/i for i in (A, B)] #  TODO which constants did this conversion factor come from, AMU*Angstrom^2
>>> A, B = [i*atomic_mass*angstrom**2 for i in (A, B)] # amu*angstrom^2 to kg*m^2
>>> radius_of_gyration(A=A, B=B, planar=True, MW=111.01, C=0)
4.8859099776e-11

Alternatively, doing the conversion all in one:

>>> A, B = 2.80700, 0.14416
>>> from scipy.constants import c, h, pi
>>> A, B = A*c*100, B*c*100 # from cm^-1 to Hz
>>> A, B = [h/(8*pi**2)/i for i in (A, B)] # from Hz to kg*m^2
>>> radius_of_gyration(A=A, B=B, planar=True, MW=111.01, C=0)
4.885909296e-11

This is also nicely documented on this page: https://cccbdb.nist.gov/convertmomint.asp which was unfortunately found by the author after figuring it out the hard way.

chemicals.utils.remove_zeros(values, tol=1e-06)[source]

Simple function which removes zero values from an array, and replaces them with a user-specified value, normally a very small number. Helpful for the case where a function can work with values very close to zero but not quite zero. The resulting array is normalized so the sum is still one.

Parameters
valuesarray_like

array of values

tolfloat

The replacement value for zeroes

Returns
fractionsarray_like

Array of values from 0 to 1

Notes

Works on numpy arrays, and returns numpy arrays only for that case.

Examples

>>> remove_zeros([0, 1e-9, 1], 1e-12)
[9.99999998999e-13, 9.99999998999e-10, 0.999999998999]
chemicals.utils.rho_to_API(rho, rho_ref=999.0170824078306)[source]

Calculates API of a liquid given its mass density, as shown in [1].

API gravity=141.5ρrefρ131.5\text{API gravity} = \frac{141.5\rho_{ref}}{\rho} - 131.5
Parameters
rhofloat

Mass density the fluid at 60 degrees Farenheight [kg/m^3]

rho_reffloat, optional

Density of the reference substance, [kg/m^3]

Returns
APIfloat

API of the fluid [-]

Notes

Defined only at 60 degrees Fahrenheit.

References

1

API Technical Data Book: General Properties & Characterization. American Petroleum Institute, 7E, 2005.

Examples

>>> rho_to_API(820)
40.8913623
>>> SG_to_API(SG(820))
40.8913623
chemicals.utils.rho_to_Vm(rho, MW)[source]

Calculate the molar volume of a chemical, given its density and molecular weight.

Vm=(1000ρMW)1V_m = \left(\frac{1000 \rho}{MW}\right)^{-1}
Parameters
rhofloat

Density, [kg/m^3]

MWfloat

Molecular weight, [g/mol]

Returns
Vmfloat

Molar volume, [m^3/mol]

References

1

Poling, Bruce E. The Properties of Gases and Liquids. 5th edition. New York: McGraw-Hill Professional, 2000.

Examples

>>> rho_to_Vm(652.9, 86.18)
0.0001319957114412621
chemicals.utils.solve_flow_composition_mix(Fs, zs, ws, MWs)[source]

Solve a stream composition problem where some specs are mole flow rates; some are mass fractions; and some are mole fractions. This algorithm requires at least one mole flow rate; and for every other component, a single spec in mole or mass or a flow rate. It is permissible for no components to have mole fractions; or no components to have weight fractions; or both.

Parameters
Fslist[float]

List of mole flow rates; None if not specified for a component, [mol/s]

zslist[float]

Mole fractions; None if not specified for a component [-]

wslist[float]

Mass fractions; None if not specified for a component [-]

MWslist[float]

Molecular weights, [g/mol]

Returns
Fslist[float]

List of mole flow rates, [mol/s]

zslist[float]

Mole fractions, [-]

wslist[float]

Mass fractions, [-]

Notes

A fast path is used if no weight fractions are provided; the calculation is much simpler for that case.

This algorithm was derived using SymPy, and framed in a form which allows for explicit solving. This is capable of solving large-scale problems i.e. with 1000 components a solve time is 1 ms; with 10000 it is 10 ms.

Examples

>>> Fs = [3600, None, None, None, None]
>>> zs = [None, .1, .2, None, None]
>>> ws = [None, None, None, .01, .02]
>>> MWs = [18.01528, 46.06844, 32.04186, 72.151, 142.286]
>>> Fs, zs, ws = solve_flow_composition_mix(Fs, zs, ws, MWs)
>>> Fs
[3600, 519.3039148597746, 1038.6078297195493, 17.44015034881175, 17.687253669610733]
>>> zs
[0.6932356751002141, 0.1, 0.2, 0.0033583706669188186, 0.003405954232867038]
>>> ws
[0.5154077420893426, 0.19012206531421305, 0.26447019259644433, 0.01, 0.02]
chemicals.utils.speed_of_sound(V, dP_dV, Cp, Cv, MW=None)[source]

Calculate a real fluid’s speed of sound. The required derivatives should be calculated with an equation of state, and Cp and Cv are both the real fluid versions. Expression is given in [1] and [2]; a unit conversion is further performed to obtain a result in m/s. If MW is not provided the result is returned in units of m*kg^0.5/s/mol^0.5.

w=[V2(PV)TCpCv]1/2w = \left[-V^2 \left(\frac{\partial P}{\partial V}\right)_T \frac{C_p} {C_v}\right]^{1/2}
Parameters
Vfloat

Molar volume of fluid, [m^3/mol]

dP_dVfloat

Derivative of P with respect to V, [Pa*mol/m^3]

Cpfloat

Real fluid heat capacity at constant pressure, [J/mol/K]

Cvfloat

Real fluid heat capacity at constant volume, [J/mol/K]

MWfloat, optional

Molecular weight, [g/mol]

Returns
wfloat

Speed of sound for a real gas, m/s or m*kg^0.5/s/mol^0.5 if MW missing

Notes

An alternate expression based on molar density is as follows:

w=[(Pρ)TCpCv]1/2w = \left[\left(\frac{\partial P}{\partial \rho}\right)_T \frac{C_p} {C_v}\right]^{1/2}

The form with the unit conversion performed inside it is as follows:

w=[V21000MW(PV)TCpCv]1/2w = \left[-V^2 \frac{1000}{MW}\left(\frac{\partial P}{\partial V} \right)_T \frac{C_p}{C_v}\right]^{1/2}

References

1

Gmehling, Jurgen, Barbel Kolbe, Michael Kleiber, and Jurgen Rarey. Chemical Thermodynamics for Process Simulation. 1st edition. Weinheim: Wiley-VCH, 2012.

2(1,2)

Pratt, R. M. “Thermodynamic Properties Involving Derivatives: Using the Peng-Robinson Equation of State.” Chemical Engineering Education 35, no. 2 (March 1, 2001): 112-115.

Examples

Example from [2]:

>>> speed_of_sound(V=0.00229754, dP_dV=-3.5459e+08, Cp=153.235, Cv=132.435, MW=67.152)
179.5868138460819
chemicals.utils.to_num(values)[source]

Legacy function to turn a list of strings into either floats (if numeric), stripped strings (if not) or None if the string is empty. Accepts any numeric formatting the float function does.

Parameters
valueslist

list of strings

Returns
valueslist

list of floats, strings, and None values [-]

Examples

>>> to_num(['1', '1.1', '1E5', '0xB4', ''])
[1.0, 1.1, 100000.0, '0xB4', None]
chemicals.utils.v_molar_to_v(v_molar, MW)[source]

Convert a velocity from units of the molar velocity form to standard m/s units.

v(m/s)=v(mkgsmol)MW (g/mol)0.5(1000g1kg)0.5v \text{(m/s)} = v\left(\frac{\text{m}\sqrt{\text{kg}} } {s \sqrt{\text{mol}}} \right) {\text{MW (g/mol)}}^{-0.5}\cdot \left(\frac{1000 \text{g}}{1 \text{kg}}\right)^{0.5}
Parameters
v_molarfloat

Molar velocity, [m*kg^0.5/s/mol^0.5]

MWfloat

Molecular weight, [g/mol]

Returns
vfloat

Velocity, [m/s]

Examples

>>> v_molar_to_v(67.10998435404377, 18.015)
499.99999999999994
chemicals.utils.v_to_v_molar(v, MW)[source]

Convert a velocity from units of m/s to a “molar” form of velocity, compatible with thermodynamic calculations on a molar basis.

v(mkgsmol)=v(m/s)MW (g/mol)(1000g1kg)0.5v\left(\frac{\text{m}\sqrt{\text{kg}} }{s \sqrt{\text{mol}}} \right) = v \text{(m/s)} \sqrt{\text{MW (g/mol)}}\cdot \left(\frac{1000 \text{g}}{1 \text{kg}}\right)^{-0.5}
Parameters
vfloat

Velocity, [m/s]

MWfloat

Molecular weight, [g/mol]

Returns
v_molarfloat

Molar velocity, [m*kg^0.5/s/mol^0.5]

Examples

>>> v_to_v_molar(500, 18.015)
67.10998435404377
chemicals.utils.vapor_mass_quality(VF, MWl, MWg)[source]

Calculates the vapor quality on a mass basis of a two-phase mixture; this is the most common definition, where 1 means a pure vapor and 0 means a pure liquid. The vapor quality on a mass basis is related to the mole basis vapor fraction according to the following relationship:

x=VFMWg(1VF)MWl+VFMWgx = \frac{\frac{V}{F}\cdot \text{MW}_g} {(1-\frac{V}{F})\text{MW}_l + \frac{V}{F}\text{MW}_g}
Parameters
VFfloat

Mole-basis vapor fraction (0 = pure vapor, 1 = pure liquid), [-]

MWlfloat

Average molecular weight of the liquid phase, [g/mol]

MWgfloat

Average molecular weight of the vapor phase, [g/mol]

Returns
qualityfloat

Vapor mass fraction of the two-phase system, [-]

Notes

Other definitions of vapor fraction use an enthalpy basis instead of a mass basis; still other less common ones take 1 to be the value of the liquid, and 0 as pure vapor.

References

1

Green, Don, and Robert Perry. Perry’s Chemical Engineers’ Handbook, 8E. McGraw-Hill Professional, 2007.

Examples

>>> vapor_mass_quality(0.5, 60, 30)
0.3333333333333333
chemicals.utils.velocity_to_molar_velocity(v, MW)[source]

Calculate the molar velocity from the mass-based (m/s) velocity of the fluid.

vmolar=vMW1000v_{molar} = \frac{v \sqrt{\text{MW}}}{\sqrt{1000}}
Parameters
vfloat

Velocity, [m/s]

MWfloat

Molecular weight, [g/mol]

Returns
v_molarfloat

Molar velcoity, [m*kg^0.5/s/mol^0.5]

Examples

>>> velocity_to_molar_velocity(228.73, 40.445)
46.
chemicals.utils.ws_to_zs(ws, MWs)[source]

Converts a list of mass fractions to mole fractions. Requires molecular weights for all species.

zi=wiMWiiwiMWiz_i = \frac{\frac{w_i}{MW_i}}{\sum_i \frac{w_i}{MW_i}}
Parameters
wsiterable

Mass fractions [-]

MWsiterable

Molecular weights [g/mol]

Returns
zsiterable

Mole fractions [-]

Notes

Does not check that the sums add to one. Does not check that inputs are of the same length.

Examples

>>> ws_to_zs([0.3333333333333333, 0.6666666666666666], [10, 20])
[0.5, 0.5]
chemicals.utils.zs_to_Vfs(zs, Vms)[source]

Converts a list of mole fractions to volume fractions. Requires molar volumes for all species.

Vfi=ziVm,iiziVm,i\text{Vf}_i = \frac{z_i V_{m,i}}{\sum_i z_i V_{m,i}}
Parameters
zsiterable

Mole fractions [-]

VMsiterable

Molar volumes of species [m^3/mol]

Returns
Vfslist

Molar volume fractions [-]

Notes

Does not check that the sums add to one. Does not check that inputs are of the same length.

Molar volumes are specified in terms of pure components only. Function works with any phase.

Examples

Acetone and benzene example

>>> zs_to_Vfs([0.637, 0.363], [8.0234e-05, 9.543e-05])
[0.5960229712956298, 0.4039770287043703]
chemicals.utils.zs_to_ws(zs, MWs)[source]

Converts a list of mole fractions to mass fractions. Requires molecular weights for all species.

wi=ziMWiMWavgw_i = \frac{z_i MW_i}{MW_{avg}}
MWavg=iziMWiMW_{avg} = \sum_i z_i MW_i
Parameters
zsiterable

Mole fractions [-]

MWsiterable

Molecular weights [g/mol]

Returns
wsiterable

Mass fractions [-]

Notes

Does not check that the sums add to one. Does not check that inputs are of the same length.

Examples

>>> zs_to_ws([0.5, 0.5], [10, 20])
[0.3333333333333333, 0.6666666666666666]