Source code for openpnm.models.phase.density._funcs

from openpnm.models.phase import _phasedocs
import numpy as np


__all__ = [
    "ideal_gas",
    "water_correlation",
    "liquid_mixture_COSTALD",
    "liquid_pure_COSTALD",
    "mass_to_molar",
]


[docs] @_phasedocs def ideal_gas( phase, P='pore.pressure', T='pore.temperature', MW='param.molecular_weight', ): r""" Uses ideal gas law to calculate the mass density of an ideal gas Parameters ---------- %(phase)s %(T)s %(P)s %(MW)s Returns ------- """ P = phase[P] T = phase[T] try: # If phase is a pure species, it should have molecular weight in params MW = phase[MW] except KeyError: # Otherwise, get the mole weighted average value MW = phase.get_mix_vals(MW) R = 8.314462618 # J/(mol.K) value = P/(R*T)*(MW/1000) # Convert to kg/m3 return value
[docs] @_phasedocs def water_correlation( phase, T='pore.temperature', salinity='pore.salinity', ): r""" Calculates density of pure water or seawater at atmospheric pressure using Eq. (8) given by Sharqawy et. al [1]. Values at temperature higher than the normal boiling temperature are calculated at the saturation pressure. Parameters ---------- %(phase)s %(T)s %(salinity)s Returns ------- Notes ----- ``T`` must be in K, and ``salinity`` in g of salt per kg of phase, or ppt (parts per thousand) VALIDITY: 273 < T < 453 K; 0 < S < 160 g/kg; ACCURACY: 0.1 pct References ---------- [1] Sharqawy M. H., Lienhard J. H., and Zubair, S. M., Desalination and Water Treatment, 2010. """ T = phase[T] if salinity in phase.keys(): S = phase[salinity] else: S = 0 a1 = 9.9992293295E+02 a2 = 2.0341179217E-02 a3 = -6.1624591598E-03 a4 = 2.2614664708E-05 a5 = -4.6570659168E-08 b1 = 8.0200240891E-01 b2 = -2.0005183488E-03 b3 = 1.6771024982E-05 b4 = -3.0600536746E-08 b5 = -1.6132224742E-11 TC = T-273.15 rho_w = a1 + a2*TC + a3*TC**2 + a4*TC**3 + a5*TC**4 d_rho = b1*S + b2*S*TC + b3*S*(TC**2) + b4*S*(TC**3) + b5*(S**2)*(TC**2) rho_sw = rho_w + d_rho value = rho_sw return value
[docs] @_phasedocs def liquid_mixture_COSTALD( phase, T='pore.temperature', MWs='param.molecular_weight.*', Tcs='param.critical_temperature.*', Vcs='param.critical_volume.*', omegas='param.acentric_factor.*', ): r""" Computes the density of a liquid mixture using the COrrospoding STAtes Liquid Density (COSTALD) method. Parameters ---------- %(phase)s %(T)s %(MWs)s %(Tcs)s %(Vcs)s %(omegas)s Returns ------- density : ndarray The density of the liquid mixture in units of kg/m3. Note that ``chemicals.volume.COSTALD`` returns molar volume, so this function converts it to density using the mole fraction weighted molecular weight of the mixture: :math:`MW_{mix} = \Sigma x_i \cdot MW_i`. Notes ----- This is same approach used by ``chemicals.volume.COSTALD_mixture`` and exact numerical correspondance is confirmed. Unlike the ``chemicals`` version, this function is vectorized over the conditions rather than the compositions, since a typical simulation has millions of pores each representing an independent conditions, but a mixture typically only has a few components. """ # Fetch parameters for each pure component Tcs = phase.get_comp_vals(Tcs) Vcs = phase.get_comp_vals(Vcs) omegas = phase.get_comp_vals(omegas) Xs = phase['pore.mole_fraction'] # Compute mixture values omegam = np.vstack([Xs[k]*omegas[k] for k in Xs.keys()]).sum(axis=0) Vm1 = np.vstack([Xs[k]*Vcs[k] for k in Xs.keys()]).sum(axis=0) Vm2 = np.vstack([Xs[k]*(Vcs[k])**(2/3) for k in Xs.keys()]).sum(axis=0) Vm3 = np.vstack([Xs[k]*(Vcs[k])**(1/3) for k in Xs.keys()]).sum(axis=0) Vm = 0.25*(Vm1 + 3*Vm2*Vm3) Tcm = 0.0 for i, ki in enumerate(Xs.keys()): inner = 0.0 for j, kj in enumerate(Xs.keys()): inner += Xs[ki]*Xs[kj]*(Vcs[ki]*Tcs[ki]*Vcs[kj]*Tcs[kj])**0.5 Tcm += inner Tcm = Tcm/Vm # Convert molar volume to normal mass density MWs = phase.get_comp_vals('param.molecular_weight') MWm = np.vstack([Xs[k]*MWs[k] for k in Xs.keys()]).sum(axis=0) T = phase[T] rhoL = liquid_pure_COSTALD( phase=phase, T=T, MW=MWm, Tc=Tcm, Vc=Vm, omega=omegam, ) return rhoL
[docs] @_phasedocs def liquid_pure_COSTALD( phase, T='pore.temperature', Tc='param.critical_temperature', Vc='param.critical_volume', omega='param.acentric_factor', MW='param.molecular_weight', ): r""" Computes the density of a pure liquid using the COrrospoding STAtes Liquid Density (COSTALD) method. Parameters ---------- %(phase)s %(T)s %(Tc)s %(Vc)s %(omega)s %(MW)s Returns ------- """ Vc = phase[Vc] Tc = phase[Tc] omega = phase[omega] T = phase[T] Tr = T/Tc V0 = 1 - 1.52816*(1-Tr)**(1/3) + 1.43907*(1-Tr)**(2/3) - 0.81446*(1-Tr) + \ 0.190454*(1-Tr)**(4/3) V1 = (-0.296123 + 0.386914*Tr - 0.0427258*Tr**2 - 0.0480645*Tr**3)/(Tr - 1.00001) Vs = Vc*V0*(1-omega*V1) MW = phase[MW] rhoL = 1e-3*MW/Vs return rhoL
[docs] @_phasedocs def mass_to_molar( phase, MW='param.molecular_weight', rho='pore.density', ): r""" Calculates the molar density from the molecular weight and mass density Parameters ---------- %(phase)s %(MW)s %(rho)s Returns ------- value : ndarray A numpy ndrray containing molar density values [mol/m3] """ MW = phase[MW]/1000 rho = phase[rho] value = rho/MW return value