Coverage for /home/caleb/Documents/University/CHE3123/thermo/thermo/heat_capacity.py : 29%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
# -*- coding: utf-8 -*- Copyright (C) 2016, Caleb Bell <Caleb.Andrew.Bell@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.'''
'Lastovka_Shaw', 'TRCCp', 'TRCCp_integral', 'heat_capacity_gas_methods', 'HeatCapacityGas', 'Rowlinson_Poling', 'Rowlinson_Bondi', 'Dadgostar_Shaw', 'Zabransky_quasi_polynomial', 'Zabransky_cubic', 'ZABRANSKY_TO_DICT', 'heat_capacity_liquid_methods', 'HeatCapacityLiquid', 'Lastovka_solid', 'Lastovka_solid_integral', 'Lastovka_solid_integral_over_T', 'heat_capacity_solid_methods', 'HeatCapacitySolid', 'Cp_liq_mixture', 'Cp_gas_mixture', 'Cv_gas_mixture']
mixing_simple, property_mass_to_molar) _Laliberte_Heat_Capacity_ParametersDict)
'PolingDatabank.csv'), sep='\t', index_col=0)
'TRC Thermodynamics of Organic Compounds in the Gas State.csv'), sep='\t', index_col=0)
'''Read in a dict of heat capacities of irnorganic and elemental solids. These are in section 2, table 151 in: Green, Don, and Robert Perry. Perry's Chemical Engineers' Handbook, Eighth Edition. McGraw-Hill Professional, 2007.
Formula: Cp(Cal/mol/K) = Const + Lin*T + Quadinv/T^2 + Quadinv*T^2
Phases: c, gls, l, g. ''' Tmax, err) = values "Subphase": _subphase, "Const": Const, "Lin": Lin, "Quadinv": Quadinv, "Quad": Quad, "Tmin": Tmin, "Tmax": Tmax, "Error": err}}) else: "Subphase": _subphase, "Const": Const, "Lin": Lin, "Quadinv": Quadinv, "Quad": Quad, "Tmin": Tmin, "Tmax": Tmax, "Error": err}}
# '''Read in a dict of 2481 thermodynamic property sets of different phases from: # Haynes, W.M., Thomas J. Bruno, and David R. Lide. CRC Handbook of # Chemistry and Physics. [Boca Raton, FL]: CRC press, 2014. # Warning: 11 duplicated chemicals are present and currently clobbered. 'CRC Standard Thermodynamic Properties of Chemical Substances.csv'), sep='\t', index_col=0)
### Heat capacities of gases
r'''Calculate ideal-gas constant-pressure heat capacitiy with the similarity variable concept and method as shown in [1]_.
.. math:: C_p^0 = \left(A_2 + \frac{A_1 - A_2}{1 + \exp(\alpha-A_3/A_4)}\right) + (B_{11} + B_{12}\alpha)\left(-\frac{(C_{11} + C_{12}\alpha)}{T}\right)^2 \frac{\exp(-(C_{11} + C_{12}\alpha)/T)}{[1-\exp(-(C_{11}+C_{12}\alpha)/T)]^2}\\ + (B_{21} + B_{22}\alpha)\left(-\frac{(C_{21} + C_{22}\alpha)}{T}\right)^2 \frac{\exp(-(C_{21} + C_{22}\alpha)/T)}{[1-\exp(-(C_{21}+C_{22}\alpha)/T)]^2}
Parameters ---------- T : float Temperature of gas [K] similarity_variable : float similarity variable as defined in [1]_, [mol/g]
Returns ------- Cpg : float Gas constant-pressure heat capacitiy, [J/kg/K]
Notes ----- Original model is in terms of J/g/K. Note that the model is for predicting mass heat capacity, not molar heat capacity like most other methods!
A1 = 0.58, A2 = 1.25, A3 = 0.17338003, A4 = 0.014, B11 = 0.73917383, B12 = 8.88308889, C11 = 1188.28051, C12 = 1813.04613, B21 = 0.0483019, B22 = 4.35656721, C21 = 2897.01927, C22 = 5987.80407.
Examples -------- >>> Lastovka_Shaw(1000.0, 0.1333) 2467.113309084757
References ---------- .. [1] Lastovka, Vaclav, and John M. Shaw. "Predictive Correlations for Ideal Gas Heat Capacities of Pure Hydrocarbons and Petroleum Fractions." Fluid Phase Equilibria 356 (October 25, 2013): 338-370. doi:10.1016/j.fluid.2013.07.023. ''' a = similarity_variable if cyclic_aliphatic: A1 = -0.1793547 A2 = 3.86944439 first = A1 + A2*a else: A1 = 0.58 A2 = 1.25 A3 = 0.17338003 # 803 instead of 8003 in another paper A4 = 0.014 first = A2 + (A1-A2)/(1+exp((a-A3)/A4)) # One reference says exp((a-A3)/A4) # Personal communication confirms the change
B11 = 0.73917383 B12 = 8.88308889 C11 = 1188.28051 C12 = 1813.04613 B21 = 0.0483019 B22 = 4.35656721 C21 = 2897.01927 C22 = 5987.80407 Cp = first + (B11 + B12*a)*(-(C11+C12*a)/T)**2*exp(-(C11 + C12*a)/T)/(1-exp(-(C11+C12*a)/T))**2 Cp += (B21 + B22*a)*(-(C21+C22*a)/T)**2*exp(-(C21 + C22*a)/T)/(1-exp(-(C21+C22*a)/T))**2 Cp = Cp*1000 # J/g/K to J/kg/K return Cp
r'''Calculates ideal gas heat capacity using the model developed in [1]_.
The ideal gas heat capacity is given by:
.. math:: C_p = R\left(a_0 + (a_1/T^2) \exp(-a_2/T) + a_3 y^2 + (a_4 - a_5/(T-a_7)^2 )y^j \right)
y = \frac{T-a_7}{T+a_6} \text{ for } T > a_7 \text{ otherwise } 0
Parameters ---------- T : float Temperature [K] a1-a7 : float Coefficients
Returns ------- Cp : float Ideal gas heat capacity , [J/mol/K]
Notes ----- j is set to 8. Analytical integrals are available for this expression.
Examples -------- >>> TRCCp(300, 4.0, 7.65E5, 720., 3.565, -0.052, -1.55E6, 52., 201.) 42.06525682312236
References ---------- .. [1] Kabo, G. J., and G. N. Roganov. Thermodynamics of Organic Compounds in the Gas State, Volume II: V. 2. College Station, Tex: CRC Press, 1994. ''' j = 8. if T <= a7: y = 0. else: y = (T - a7)/(T + a6) Cp = R*(a0 + (a1/T**2)*exp(-a2/T) + a3*y**2 + (a4 - a5/(T-a7)**2 )*y**j ) return Cp
r'''Integrates ideal gas heat capacity using the model developed in [1]_. Best used as a delta only.
The difference in enthalpy with respect to 0 K is given by:
.. math:: \frac{H(T) - H^{ref}}{RT} = a_0 + a_1x(a_2)/(a_2T) + I/T + h(T)/T
h(T) = (a_5 + a_7)\left[(2a_3 + 8a_4)\ln(1-y)+ \left\{a_3\left(1 + \frac{1}{1-y}\right) + a_4\left(7 + \frac{1}{1-y}\right)\right\}y + a_4\left\{3y^2 + (5/3)y^3 + y^4 + (3/5)y^5 + (1/3)y^6\right\} + (1/7)\left\{a_4 - \frac{a_5}{(a_6+a_7)^2}\right\}y^7\right]
h(T) = 0 \text{ for } T \le a_7
y = \frac{T-a_7}{T+a_6} \text{ for } T > a_7 \text{ otherwise } 0
Parameters ---------- T : float Temperature [K] a1-a7 : float Coefficients I : float, optional Integral offset
Returns ------- H-H(0) : float Difference in enthalpy from 0 K , [J/mol]
Notes ----- Analytical integral as provided in [1]_ and verified with numerical integration.
Examples -------- >>> TRCCp_integral(298.15, 4.0, 7.65E5, 720., 3.565, -0.052, -1.55E6, 52., ... 201., 1.2) 10802.532600592816
References ---------- .. [1] Kabo, G. J., and G. N. Roganov. Thermodynamics of Organic Compounds in the Gas State, Volume II: V. 2. College Station, Tex: CRC Press, 1994. ''' y = (T - a7)/(T + a6) if T <= a7: h = 0 else: first = a6 + a7 second = (2.*a3 + 8.*a4)*log(1.-y) third = (a3*(1 + 1/(1.-y)) + a4*(7 + 1/(1.-y)))*y fourth = a4*(3*y**2 + 5/3.*y**3 + y**4 + 3/5.*y**5 + 1/3.*y**6) fifth = 1/7.*(a4 - a5/((a6+a7)**2))*y**7 h = first*(second + third + fourth + fifth) return (a0 + a1*exp(-a2/T)/(a2*T) + I/T + h/T)*R*T
POLING_CONST, VDI_TABULAR] '''Holds all methods available for the HeatCapacityGas class, for use in iterating over them.'''
r'''Class for dealing with gas heat capacity as a function of temperature. Consists of two coefficient-based methods, two constant methods, one tabular source, one simple estimator, and the external library CoolProp.
Parameters ---------- CASRN : str, optional The CAS number of the chemical MW : float, optional Molecular weight, [g/mol] similarity_variable : float, optional similarity variable, n_atoms/MW, [mol/g]
Notes ----- A string holding each method's name is assigned to the following variables in this module, intended as the most convenient way to refer to a method. To iterate over all methods, use the list stored in :obj:`heat_capacity_gas_methods`.
**TRCIG**: A rigorous expression derived in [1]_ for modeling gas heat capacity. Coefficients for 1961 chemicals are available. **POLING**: Simple polynomials in [2]_ not suitable for extrapolation. Data is available for 308 chemicals. **COOLPROP**: CoolProp external library; with select fluids from its library. Range is limited to that of the equations of state it uses, as described in [3]_. Very slow. **LASTOVKA_SHAW**: A basic estimation method using the `similarity variable` concept; requires only molecular structure, so is very convenient. See :obj:`Lastovka_Shaw` for details. **CRCSTD**: Constant values tabulated in [4]_ at 298.15 K; data is available for 533 gases. **POLING_CONST**: Constant values in [2]_ at 298.15 K; available for 348 gases. **VDI_TABULAR**: Tabular data up to the critical point available in [5]_. Note that this data is along the saturation curve.
See Also -------- TRCCp Lastovka_Shaw Rowlinson_Poling Rowlinson_Bondi
References ---------- .. [1] Kabo, G. J., and G. N. Roganov. Thermodynamics of Organic Compounds in the Gas State, Volume II: V. 2. College Station, Tex: CRC Press, 1994. .. [2] Poling, Bruce E. The Properties of Gases and Liquids. 5th edition. New York: McGraw-Hill Professional, 2000. .. [3] Bell, Ian H., Jorrit Wronski, Sylvain Quoilin, and Vincent Lemort. "Pure and Pseudo-Pure Fluid Thermophysical Property Evaluation and the Open-Source Thermophysical Property Library CoolProp." Industrial & Engineering Chemistry Research 53, no. 6 (February 12, 2014): 2498-2508. doi:10.1021/ie4033999. http://www.coolprop.org/ .. [4] Haynes, W.M., Thomas J. Bruno, and David R. Lide. CRC Handbook of Chemistry and Physics. [Boca Raton, FL]: CRC press, 2014. .. [5] Gesellschaft, V. D. I., ed. VDI Heat Atlas. 2nd edition. Berlin; New York:: Springer, 2010. ''' '''No interpolation transformation by default.''' '''No interpolation transformation by default.''' '''No interpolation transformation by default.''' '''Allow tabular extrapolation by default; gases are fairly linear in heat capacity at high temperatures even if not low temperatures.'''
'''Heat capacities have a minimum value of 0 at 0 K.''' '''Maximum valid of Heat capacity; arbitrarily set. For fluids very near the critical point, this value can be obscenely high.'''
'''Default rankings of the available methods.'''
self.CASRN = CASRN self.MW = MW self.similarity_variable = similarity_variable
self.Tmin = None '''Minimum temperature at which no method can calculate the surface tension under.''' self.Tmax = None '''Maximum temperature at which no method can calculate the surface tension above.'''
self.tabular_data = {} '''tabular_data, dict: Stored (Ts, properties) for any tabular data; indexed by provided or autogenerated name.''' self.tabular_data_interpolators = {} '''tabular_data_interpolators, dict: Stored (extrapolator, spline) tuples which are interp1d instances for each set of tabular data; indexed by tuple of (name, interpolation_T, interpolation_property, interpolation_property_inv) to ensure that if an interpolation transform is altered, the old interpolator which had been created is no longer used.'''
self.sorted_valid_methods = [] '''sorted_valid_methods, list: Stored methods which were found valid at a specific temperature; set by `T_dependent_property`.''' self.user_methods = [] '''user_methods, list: Stored methods which were specified by the user in a ranked order of preference; set by `T_dependent_property`.'''
self.all_methods = set() '''Set of all methods available for a given CASRN and properties; filled by :obj:`load_all_methods`.'''
self.load_all_methods()
r'''Method which picks out coefficients for the specified chemical from the various dictionaries and DataFrames storing it. All data is stored as attributes. This method also sets :obj:`Tmin`, :obj:`Tmax`, and :obj:`all_methods` as a set of methods for which the data exists for.
Called on initialization only. See the source code for the variables at which the coefficients are stored. The coefficients can safely be altered once the class is initialized. This method can be called again to reset the parameters. ''' methods = [] Tmins, Tmaxs = [], [] if self.CASRN in TRC_gas_data.index: methods.append(TRCIG) _, self.TRCIG_Tmin, self.TRCIG_Tmax, a0, a1, a2, a3, a4, a5, a6, a7, _, _, _ = _TRC_gas_data_values[TRC_gas_data.index.get_loc(self.CASRN)].tolist() self.TRCIG_coefs = [a0, a1, a2, a3, a4, a5, a6, a7] Tmins.append(self.TRCIG_Tmin); Tmaxs.append(self.TRCIG_Tmax) if self.CASRN in Poling_data.index and not np.isnan(Poling_data.at[self.CASRN, 'a0']): _, self.POLING_Tmin, self.POLING_Tmax, a0, a1, a2, a3, a4, Cpg, Cpl = _Poling_data_values[Poling_data.index.get_loc(self.CASRN)].tolist() methods.append(POLING) self.POLING_coefs = [a0, a1, a2, a3, a4] Tmins.append(self.POLING_Tmin); Tmaxs.append(self.POLING_Tmax) if self.CASRN in Poling_data.index and not np.isnan(Poling_data.at[self.CASRN, 'Cpg']): methods.append(POLING_CONST) self.POLING_T = 298.15 self.POLING_constant = float(Poling_data.at[self.CASRN, 'Cpg']) if self.CASRN in CRC_standard_data.index and not np.isnan(CRC_standard_data.at[self.CASRN, 'Cpg']): methods.append(CRCSTD) self.CRCSTD_T = 298.15 self.CRCSTD_constant = float(CRC_standard_data.at[self.CASRN, 'Cpg']) if self.CASRN in _VDISaturationDict: # NOTE: VDI data is for the saturation curve, i.e. at increasing # pressure; it is normally substantially higher than the ideal gas # value methods.append(VDI_TABULAR) Ts, props = VDI_tabular_data(self.CASRN, 'Cp (g)') self.VDI_Tmin = Ts[0] self.VDI_Tmax = Ts[-1] self.tabular_data[VDI_TABULAR] = (Ts, props) Tmins.append(self.VDI_Tmin); Tmaxs.append(self.VDI_Tmax) if has_CoolProp and self.CASRN in coolprop_dict: methods.append(COOLPROP) self.CP_f = coolprop_fluids[self.CASRN] Tmins.append(self.CP_f.Tt); Tmaxs.append(self.CP_f.Tc) if self.MW and self.similarity_variable: methods.append(LASTOVKA_SHAW) self.all_methods = set(methods) if Tmins and Tmaxs: self.Tmin, self.Tmax = min(Tmins), max(Tmaxs)
r'''Method to calculate surface tension of a liquid at temperature `T` with a given method.
This method has no exception handling; see `T_dependent_property` for that.
Parameters ---------- T : float Temperature at which to calculate heat capacity, [K] method : str Method name to use
Returns ------- Cp : float Calculated heat capacity, [J/mol/K] ''' if method == TRCIG: a0, a1, a2, a3, a4, a5, a6, a7 = self.TRCIG_coefs Cp = TRCCp(T, a0, a1, a2, a3, a4, a5, a6, a7) elif method == COOLPROP: Cp = PropsSI('Cp0molar', 'T', T,'P', 101325.0, self.CASRN) elif method == POLING: Cp = R*(self.POLING_coefs[0] + self.POLING_coefs[1]*T + self.POLING_coefs[2]*T**2 + self.POLING_coefs[3]*T**3 + self.POLING_coefs[4]*T**4) elif method == POLING_CONST: Cp = self.POLING_constant elif method == CRCSTD: Cp = self.CRCSTD_constant elif method == LASTOVKA_SHAW: Cp = Lastovka_Shaw(T, self.similarity_variable) Cp = property_mass_to_molar(Cp, self.MW) elif method in self.tabular_data: Cp = self.interpolate(T, method) return Cp
r'''Method to test the validity of a specified method for a given temperature.
'TRC' and 'Poling' both have minimum and maimum temperatures. The constant temperatures in POLING_CONST and CRCSTD are considered valid for 50 degrees around their specified temperatures. :obj:`Lastovka_Shaw` is considered valid for the whole range of temperatures.
It is not guaranteed that a method will work or give an accurate prediction simply because this method considers the method valid.
Parameters ---------- T : float Temperature at which to determine the validity of the method, [K] method : str Name of the method to test
Returns ------- validity : bool Whether or not a specifid method is valid ''' validity = True if method == TRCIG: if T < self.TRCIG_Tmin or T > self.TRCIG_Tmax: validity = False elif method == POLING: if T < self.POLING_Tmin or T > self.POLING_Tmax: validity = False elif method == POLING_CONST: if T > self.POLING_T + 50 or T < self.POLING_T - 50: validity = False elif method == CRCSTD: if T > self.CRCSTD_T + 50 or T < self.CRCSTD_T - 50: validity = False elif method == LASTOVKA_SHAW: pass # Valid everywhere elif method == COOLPROP: if T <= self.CP_f.Tmin or T >= self.CP_f.Tmax: validity = False elif method in self.tabular_data: # if tabular_extrapolation_permitted, good to go without checking if not self.tabular_extrapolation_permitted: Ts, properties = self.tabular_data[method] if T < Ts[0] or T > Ts[-1]: validity = False else: raise Exception('Method not valid') return validity
### Heat capacities of liquids
r'''Calculate liquid constant-pressure heat capacitiy with the [1]_ CSP method.
This equation is not terrible accurate.
The heat capacity of a liquid is given by:
.. math:: \frac{Cp^{L} - Cp^{g}}{R} = 1.586 + \frac{0.49}{1-T_r} + \omega\left[ 4.2775 + \frac{6.3(1-T_r)^{1/3}}{T_r} + \frac{0.4355}{1-T_r}\right]
Parameters ---------- T : float Temperature of fluid [K] Tc : float Critical temperature of fluid [K] omega : float Acentric factor for fluid, [-] Cpgm : float Constant-pressure gas heat capacity, [J/mol/K]
Returns ------- Cplm : float Liquid constant-pressure heat capacitiy, [J/mol/K]
Notes ----- Poling compared 212 substances, and found error at 298K larger than 10% for 18 of them, mostly associating. Of the other 194 compounds, AARD is 2.5%.
Examples -------- >>> Rowlinson_Poling(350.0, 435.5, 0.203, 91.21) 143.80194441498296
References ---------- .. [1] Poling, Bruce E. The Properties of Gases and Liquids. 5th edition. New York: McGraw-Hill Professional, 2000. ''' Tr = T/Tc Cplm = Cpgm+ R*(1.586 + 0.49/(1.-Tr) + omega*(4.2775 + 6.3*(1-Tr)**(1/3.)/Tr + 0.4355/(1.-Tr))) return Cplm
r'''Calculate liquid constant-pressure heat capacitiy with the CSP method shown in [1]_.
The heat capacity of a liquid is given by:
.. math:: \frac{Cp^L - Cp^{ig}}{R} = 1.45 + 0.45(1-T_r)^{-1} + 0.25\omega [17.11 + 25.2(1-T_r)^{1/3}T_r^{-1} + 1.742(1-T_r)^{-1}]
Parameters ---------- T : float Temperature of fluid [K] Tc : float Critical temperature of fluid [K] omega : float Acentric factor for fluid, [-] Cpgm : float Constant-pressure gas heat capacity, [J/mol/K]
Returns ------- Cplm : float Liquid constant-pressure heat capacitiy, [J/mol/K]
Notes ----- Less accurate than `Rowlinson_Poling`.
Examples -------- >>> Rowlinson_Bondi(T=373.28, Tc=535.55, omega=0.323, Cpgm=119.342) 175.39760730048116
References ---------- .. [1] Poling, Bruce E. The Properties of Gases and Liquids. 5th edition. New York: McGraw-Hill Professional, 2000. .. [2] Gesellschaft, V. D. I., ed. VDI Heat Atlas. 2nd edition. Berlin; New York:: Springer, 2010. .. [3] J.S. Rowlinson, Liquids and Liquid Mixtures, 2nd Ed., Butterworth, London (1969). ''' Tr = T/Tc Cplm = Cpgm + R*(1.45 + 0.45/(1.-Tr) + 0.25*omega*(17.11 + 25.2*(1-Tr)**(1/3.)/Tr + 1.742/(1.-Tr))) return Cplm
r'''Calculate liquid constant-pressure heat capacitiy with the similarity variable concept and method as shown in [1]_.
.. math:: C_{p} = 24.5(a_{11}\alpha + a_{12}\alpha^2)+ (a_{21}\alpha + a_{22}\alpha^2)T +(a_{31}\alpha + a_{32}\alpha^2)T^2
Parameters ---------- T : float Temperature of liquid [K] similarity_variable : float similarity variable as defined in [1]_, [mol/g]
Returns ------- Cpl : float Liquid constant-pressure heat capacitiy, [J/kg/K]
Notes ----- Many restrictions on its use.
Original model is in terms of J/g/K. Note that the model is for predicting mass heat capacity, not molar heat capacity like most other methods!
a11 = -0.3416; a12 = 2.2671; a21 = 0.1064; a22 = -0.3874l; a31 = -9.8231E-05; a32 = 4.182E-04
Examples -------- >>> Dadgostar_Shaw(355.6, 0.139) 1802.5291501191516
References ---------- .. [1] Dadgostar, Nafiseh, and John M. Shaw. "A Predictive Correlation for the Constant-Pressure Specific Heat Capacity of Pure and Ill-Defined Liquid Hydrocarbons." Fluid Phase Equilibria 313 (January 15, 2012): 211-226. doi:10.1016/j.fluid.2011.09.015. ''' a11 = -0.3416 a12 = 2.2671 a21 = 0.1064 a22 = -0.3874 a31 = -9.8231E-05 a32 = 4.182E-04
# Didn't seem to improve the comparison; sum of errors on some # points included went from 65.5 to 286. # Author probably used more precision in their calculation. # theta = 151.8675 # constant = 3*R*(theta/T)**2*exp(theta/T)/(exp(theta/T)-1)**2 constant = 24.5
Cp = (constant*(a11*similarity_variable + a12*similarity_variable**2) + (a21*similarity_variable + a22*similarity_variable**2)*T + (a31*similarity_variable + a32*similarity_variable**2)*T**2) Cp = Cp*1000 # J/g/K to J/kg/K return Cp
''' Inputs: Dict entry or []; and the dict type '''
# s for spline, p for quasipolynomial
"Uncertainty" : Uncertainty, "Tmin": Tmin, "Tmax" : Tmax, "a1s" : a1s, "a2s" : a2s, "a3s": a3s, "a4s" : a4s, "a1p" : a1p, "a2p" : a2p, "a3p" : a3p, "a4p" : a4p, "a5p" : a5p, "a6p" : a6p, "Tc" : Tc } # dict[CASRN] = [subdict1, subdict2] where each is sorted
r'''Calculates liquid heat capacity using the model developed in [1]_.
.. math:: \frac{C}{R}=A_1\ln(1-T_r) + \frac{A_2}{1-T_r} + \sum_{j=0}^m A_{j+3} T_r^j
Parameters ---------- T : float Temperature [K] Tc : float Critical temperature of fluid, [K] a1-a6 : float Coefficients
Returns ------- Cp : float Liquid heat capacity, [J/mol/K]
Notes ----- Used only for isobaric heat capacities, not saturation heat capacities. Designed for reasonable extrapolation behavior caused by using the reduced critical temperature. Used by the authors of [1]_ when critical temperature was available for the fluid. Analytical integrals are available for this expression.
Examples -------- >>> Zabransky_quasi_polynomial(330, 591.79, -3.12743, 0.0857315, 13.7282, 1.28971, 6.42297, 4.10989) 165.4728226923247
References ---------- .. [1] Zabransky, M., V. Ruzicka Jr, V. Majer, and Eugene S. Domalski. Heat Capacity of Liquids: Critical Review and Recommended Values. 2 Volume Set. Washington, D.C.: Amer Inst of Physics, 1996. ''' Tr = T/Tc return R*(a1*log(1-Tr) + a2/(1-Tr) + a3 + a4*Tr + a5*Tr**2 + a6*Tr**3)
r'''Calculates liquid heat capacity using the model developed in [1]_.
.. math:: \frac{C}{R}=\sum_{j=0}^3 A_{j+1} \left(\frac{T}{100}\right)^j
Parameters ---------- T : float Temperature [K] a1-a4 : float Coefficients
Returns ------- Cp : float Liquid heat capacity, [J/mol/K]
Notes ----- Most often form used in [1]_. Analytical integrals are available for this expression.
Examples -------- >>> Zabransky_cubic(298.15, 20.9634, -10.1344, 2.8253, -0.256738) 75.31462591538555
References ---------- .. [1] Zabransky, M., V. Ruzicka Jr, V. Majer, and Eugene S. Domalski. Heat Capacity of Liquids: Critical Review and Recommended Values. 2 Volume Set. Washington, D.C.: Amer Inst of Physics, 1996. ''' T = T/100. return R*(a1 + a2*T**1 + a3*T**2 + a4*T**3)
ans = None if len(diclist) == 1: # one entry ans = diclist[0] else: for data in diclist: if T < data["Tmin"]: # multiple entries, under Tmin ans = data break elif T >= data["Tmin"] and T <= data["Tmax"]: # Tmin < T < Tmax ans = data break if not ans: ans = diclist[-1] # last entry; T > Tmax, last case
# if strict: # if T < ans["Tmin"] or T > ans["Tmax"]: # either side error # ans = None return ans
ZABRANSKY_QUASIPOLYNOMIAL: _ZabranskyConstp, ZABRANSKY_SPLINE_C: _ZabranskyIsos, ZABRANSKY_QUASIPOLYNOMIAL_C: _ZabranskyIsop, ZABRANSKY_SPLINE_SAT: _ZabranskySats, ZABRANSKY_QUASIPOLYNOMIAL_SAT: _ZabranskySatp} ZABRANSKY_SPLINE_C, ZABRANSKY_QUASIPOLYNOMIAL_C, ZABRANSKY_SPLINE_SAT, ZABRANSKY_QUASIPOLYNOMIAL_SAT, VDI_TABULAR, ROWLINSON_POLING, ROWLINSON_BONDI, COOLPROP, DADGOSTAR_SHAW, POLING_CONST, CRCSTD] '''Holds all methods available for the HeatCapacityLiquid class, for use in iterating over them.'''
r'''Class for dealing with liquid heat capacity as a function of temperature. Consists of six coefficient-based methods, two constant methods, one tabular source, two CSP methods based on gas heat capacity, one simple estimator, and the external library CoolProp.
Parameters ---------- CASRN : str, optional The CAS number of the chemical MW : float, optional Molecular weight, [g/mol] similarity_variable : float, optional similarity variable, n_atoms/MW, [mol/g] Tc : float, optional Critical temperature, [K] omega : float, optional Acentric factor, [-] Cpgm : float or callable, optional Idea-gas molar heat capacity at T or callable for the same, [J/mol/K]
Notes ----- A string holding each method's name is assigned to the following variables in this module, intended as the most convenient way to refer to a method. To iterate over all methods, use the list stored in :obj:`heat_capacity_gas_methods`.
**ZABRANSKY_SPLINE, ZABRANSKY_QUASIPOLYNOMIAL, ZABRANSKY_SPLINE_C, and ZABRANSKY_QUASIPOLYNOMIAL_C**: Rigorous expressions developed in [1]_ following critical evaluation of the available data. The spline methods use the form described in :obj:`Zabransky_cubic` over short ranges with varying coefficients to obtain a wider range. The quasi-polynomial methods use the form described in :obj:`Zabransky_quasi_polynomial`, more suitable for extrapolation, and over then entire range. Respectively, there is data available for 588, 146, 51, and 26 chemicals. **ZABRANSKY_SPLINE_SAT and ZABRANSKY_QUASIPOLYNOMIAL_SAT**: Rigorous expressions developed in [1]_ following critical evaluation of the available data. The spline method use the form described in :obj:`Zabransky_cubic` over short ranges with varying coefficients to obtain a wider range. The quasi-polynomial method use the form described in :obj:`Zabransky_quasi_polynomial`, more suitable for extrapolation, and over then entire range. Respectively, there is data available for 203, and 16 chemicals. Note that these methods are for the saturation curve! **VDI_TABULAR**: Tabular data up to the critical point available in [5]_. Note that this data is along the saturation curve. **ROWLINSON_POLING**: CSP method described in :obj:`Rowlinson_Poling`. Requires a ideal gas heat capacity value at the same temperature as it is to be calculated. **ROWLINSON_BONDI**: CSP method described in :obj:`Rowlinson_Bondi`. Requires a ideal gas heat capacity value at the same temperature as it is to be calculated. **COOLPROP**: CoolProp external library; with select fluids from its library. Range is limited to that of the equations of state it uses, as described in [3]_. Very slow. **DADGOSTAR_SHAW**: A basic estimation method using the `similarity variable` concept; requires only molecular structure, so is very convenient. See :obj:`Dadgostar_Shaw` for details. **POLING_CONST**: Constant values in [2]_ at 298.15 K; available for 245 liquids. **CRCSTD**: Consta values tabulated in [4]_ at 298.15 K; data is available for 433 liquids.
See Also -------- Zabransky_quasi_polynomial Zabransky_cubic Rowlinson_Poling Rowlinson_Bondi Dadgostar_Shaw
References ---------- .. [1] Zabransky, M., V. Ruzicka Jr, V. Majer, and Eugene S. Domalski. Heat Capacity of Liquids: Critical Review and Recommended Values. 2 Volume Set. Washington, D.C.: Amer Inst of Physics, 1996. .. [2] Poling, Bruce E. The Properties of Gases and Liquids. 5th edition. New York: McGraw-Hill Professional, 2000. .. [3] Bell, Ian H., Jorrit Wronski, Sylvain Quoilin, and Vincent Lemort. "Pure and Pseudo-Pure Fluid Thermophysical Property Evaluation and the Open-Source Thermophysical Property Library CoolProp." Industrial & Engineering Chemistry Research 53, no. 6 (February 12, 2014): 2498-2508. doi:10.1021/ie4033999. http://www.coolprop.org/ .. [4] Haynes, W.M., Thomas J. Bruno, and David R. Lide. CRC Handbook of Chemistry and Physics. [Boca Raton, FL]: CRC press, 2014. .. [5] Gesellschaft, V. D. I., ed. VDI Heat Atlas. 2nd edition. Berlin; New York:: Springer, 2010. ''' '''No interpolation transformation by default.''' '''No interpolation transformation by default.''' '''No interpolation transformation by default.''' '''Disallow tabular extrapolation by default; higher-temeprature behavior is not well predicted by most extrapolation.'''
'''Allow very low heat capacities; arbitrarily set; liquid heat capacity should always be somewhat substantial.''' '''Maximum valid of Heat capacity; arbitrarily set. For fluids very near the critical point, this value can be obscenely high.'''
ZABRANSKY_SPLINE_C, ZABRANSKY_QUASIPOLYNOMIAL_C, ZABRANSKY_SPLINE_SAT, ZABRANSKY_QUASIPOLYNOMIAL_SAT, VDI_TABULAR, ROWLINSON_POLING, ROWLINSON_BONDI, COOLPROP, DADGOSTAR_SHAW, POLING_CONST, CRCSTD] '''Default rankings of the available methods.'''
omega=None, Cpgm=None): self.CASRN = CASRN self.MW = MW self.Tc = Tc self.omega = omega self.Cpgm = Cpgm self.similarity_variable = similarity_variable
self.Tmin = None '''Minimum temperature at which no method can calculate the heat capacity under.''' self.Tmax = None '''Maximum temperature at which no method can calculate the heat capacity above.'''
self.tabular_data = {} '''tabular_data, dict: Stored (Ts, properties) for any tabular data; indexed by provided or autogenerated name.''' self.tabular_data_interpolators = {} '''tabular_data_interpolators, dict: Stored (extrapolator, spline) tuples which are interp1d instances for each set of tabular data; indexed by tuple of (name, interpolation_T, interpolation_property, interpolation_property_inv) to ensure that if an interpolation transform is altered, the old interpolator which had been created is no longer used.'''
self.sorted_valid_methods = [] '''sorted_valid_methods, list: Stored methods which were found valid at a specific temperature; set by `T_dependent_property`.''' self.user_methods = [] '''user_methods, list: Stored methods which were specified by the user in a ranked order of preference; set by `T_dependent_property`.'''
self.all_methods = set() '''Set of all methods available for a given CASRN and properties; filled by :obj:`load_all_methods`.'''
self.load_all_methods()
r'''Method which picks out coefficients for the specified chemical from the various dictionaries and DataFrames storing it. All data is stored as attributes. This method also sets :obj:`Tmin`, :obj:`Tmax`, and :obj:`all_methods` as a set of methods for which the data exists for.
Called on initialization only. See the source code for the variables at which the coefficients are stored. The coefficients can safely be altered once the class is initialized. This method can be called again to reset the parameters. ''' methods = [] Tmins, Tmaxs = [], [] if self.CASRN in _ZabranskyConsts: methods.append(ZABRANSKY_SPLINE) self.ZABRANSKY_SPLINE_data = _ZabranskyConsts[self.CASRN] if self.CASRN in _ZabranskyConstp: methods.append(ZABRANSKY_QUASIPOLYNOMIAL) self.ZABRANSKY_QUASIPOLYNOMIAL_data = _ZabranskyConstp[self.CASRN] if self.CASRN in _ZabranskyIsos: methods.append(ZABRANSKY_SPLINE_C) self.ZABRANSKY_SPLINE_C_data = _ZabranskyIsos[self.CASRN] if self.CASRN in _ZabranskyIsop: methods.append(ZABRANSKY_QUASIPOLYNOMIAL_C) self.ZABRANSKY_QUASIPOLYNOMIAL_C_data = _ZabranskyIsop[self.CASRN] if self.CASRN in Poling_data.index and not np.isnan(Poling_data.at[self.CASRN, 'Cpl']): methods.append(POLING_CONST) self.POLING_T = 298.15 self.POLING_constant = float(Poling_data.at[self.CASRN, 'Cpl']) if self.CASRN in CRC_standard_data.index and not np.isnan(CRC_standard_data.at[self.CASRN, 'Cpl']): methods.append(CRCSTD) self.CRCSTD_T = 298.15 self.CRCSTD_constant = float(CRC_standard_data.at[self.CASRN, 'Cpl']) # Saturation functions if self.CASRN in _ZabranskySats: methods.append(ZABRANSKY_SPLINE_SAT) self.ZABRANSKY_SPLINE_SAT_data = _ZabranskySats[self.CASRN] if self.CASRN in _ZabranskySatp: methods.append(ZABRANSKY_QUASIPOLYNOMIAL_SAT) self.ZABRANSKY_QUASIPOLYNOMIAL_SAT_data = _ZabranskySatp[self.CASRN] if self.CASRN in _VDISaturationDict: # NOTE: VDI data is for the saturation curve, i.e. at increasing # pressure; it is normally substantially higher than the ideal gas # value methods.append(VDI_TABULAR) Ts, props = VDI_tabular_data(self.CASRN, 'Cp (l)') self.VDI_Tmin = Ts[0] self.VDI_Tmax = Ts[-1] self.tabular_data[VDI_TABULAR] = (Ts, props) Tmins.append(self.VDI_Tmin); Tmaxs.append(self.VDI_Tmax) if self.Tc and self.omega: methods.extend([ROWLINSON_POLING, ROWLINSON_BONDI]) if has_CoolProp and self.CASRN in coolprop_dict: methods.append(COOLPROP) self.CP_f = coolprop_fluids[self.CASRN] Tmins.append(self.CP_f.Tt); Tmaxs.append(self.CP_f.Tc) if self.MW and self.similarity_variable: methods.append(DADGOSTAR_SHAW) self.all_methods = set(methods) if Tmins and Tmaxs: # TODO: More Tmin, Tmax ranges self.Tmin, self.Tmax = min(Tmins), max(Tmaxs)
r'''Method to calculate heat capacity of a liquid at temperature `T` with a given method.
This method has no exception handling; see `T_dependent_property` for that.
Parameters ---------- T : float Temperature at which to calculate heat capacity, [K] method : str Name of the method to use
Returns ------- Cp : float Heat capacity of the liquid at T, [J/mol/K] ''' if method == ZABRANSKY_SPLINE: data = _ZabranskyDictChoser(T, self.ZABRANSKY_SPLINE_data) Cp = Zabransky_cubic(T, data["a1s"], data["a2s"], data["a3s"], data["a4s"]) elif method == ZABRANSKY_QUASIPOLYNOMIAL: data = _ZabranskyDictChoser(T, self.ZABRANSKY_QUASIPOLYNOMIAL_data) Cp = Zabransky_quasi_polynomial(T, data["Tc"], data["a1p"], data["a2p"], data["a3p"], data["a4p"], data["a5p"], data["a6p"]) elif method == ZABRANSKY_SPLINE_C: data = _ZabranskyDictChoser(T,self.ZABRANSKY_SPLINE_C_data) Cp = Zabransky_cubic(T, data["a1s"], data["a2s"], data["a3s"], data["a4s"]) elif method == ZABRANSKY_QUASIPOLYNOMIAL_C: data = _ZabranskyDictChoser(T, self.ZABRANSKY_QUASIPOLYNOMIAL_C_data) Cp = Zabransky_quasi_polynomial(T, data["Tc"], data["a1p"], data["a2p"], data["a3p"], data["a4p"], data["a5p"], data["a6p"]) elif method == ZABRANSKY_SPLINE_SAT: data = _ZabranskyDictChoser(T, self.ZABRANSKY_SPLINE_SAT_data) Cp = Zabransky_cubic(T, data["a1s"], data["a2s"], data["a3s"], data["a4s"]) elif method == ZABRANSKY_QUASIPOLYNOMIAL_SAT: data = _ZabranskyDictChoser(T, self.ZABRANSKY_QUASIPOLYNOMIAL_SAT_data) Cp = Zabransky_quasi_polynomial(T, data["Tc"], data["a1p"], data["a2p"], data["a3p"], data["a4p"], data["a5p"], data["a6p"]) elif method == COOLPROP: Cp = CoolProp_T_dependent_property(T, self.CASRN , 'CPMOLAR', 'l') elif method == POLING_CONST: Cp = self.POLING_constant elif method == CRCSTD: Cp = self.CRCSTD_constant elif method == ROWLINSON_POLING: Cpgm = self.Cpgm(T) if hasattr(self.Cpgm, '__call__') else self.Cpgm Cp = Rowlinson_Poling(T, self.Tc, self.omega, Cpgm) elif method == ROWLINSON_BONDI: Cpgm = self.Cpgm(T) if hasattr(self.Cpgm, '__call__') else self.Cpgm Cp = Rowlinson_Bondi(T, self.Tc, self.omega, Cpgm) elif method == DADGOSTAR_SHAW: Cp = Dadgostar_Shaw(T, self.similarity_variable) Cp = property_mass_to_molar(Cp, self.MW) elif method in self.tabular_data: Cp = self.interpolate(T, method) return Cp
r'''Method to check the validity of a method. Follows the given ranges for all coefficient-based methods. For the CSP method :obj:`Rowlinson_Poling`, the model is considered valid for all temperatures. The simple method :obj:`Dadgostar_Shaw` is considered valid for all temperatures. For tabular data, extrapolation outside of the range is used if :obj:`tabular_extrapolation_permitted` is set; if it is, the extrapolation is considered valid for all temperatures.
It is not guaranteed that a method will work or give an accurate prediction simply because this method considers the method valid.
Parameters ---------- T : float Temperature at which to test the method, [K] method : str Name of the method to test
Returns ------- validity : bool Whether or not a method is valid ''' validity = True if method in [ZABRANSKY_SPLINE, ZABRANSKY_QUASIPOLYNOMIAL, ZABRANSKY_SPLINE_C, ZABRANSKY_QUASIPOLYNOMIAL_C, ZABRANSKY_SPLINE_SAT, ZABRANSKY_QUASIPOLYNOMIAL_SAT]: data = _ZabranskyDictChoser(T, ZABRANSKY_TO_DICT[method][self.CASRN]) Tmin, Tmax = data['Tmin'], data['Tmax'] if T < Tmin or T > Tmax: validity = False elif method == COOLPROP: if T <= self.CP_f.Tt or T >= self.CP_f.Tc: validity = False elif method == POLING_CONST: if T > self.POLING_T + 50 or T < self.POLING_T - 50: validity = False elif method == CRCSTD: if T > self.CRCSTD_T + 50 or T < self.CRCSTD_T - 50: validity = False elif method == DADGOSTAR_SHAW: pass # Valid everywhere elif method in [ROWLINSON_POLING, ROWLINSON_BONDI]: pass # No limit here elif method in self.tabular_data: # if tabular_extrapolation_permitted, good to go without checking if not self.tabular_extrapolation_permitted: Ts, properties = self.tabular_data[method] if T < Ts[0] or T > Ts[-1]: validity = False else: raise Exception('Method not valid') return validity
### Solid
r'''Calculate solid constant-pressure heat capacitiy with the similarity variable concept and method as shown in [1]_.
.. math:: C_p = 3(A_1\alpha + A_2\alpha^2)R\left(\frac{\theta}{T}\right)^2 \frac{\exp(\theta/T)}{[\exp(\theta/T)-1]^2} + (C_1\alpha + C_2\alpha^2)T + (D_1\alpha + D_2\alpha^2)T^2
Parameters ---------- T : float Temperature of solid [K] similarity_variable : float similarity variable as defined in [1]_, [mol/g]
Returns ------- Cps : float Solid constant-pressure heat capacitiy, [J/kg/K]
Notes ----- Many restrictions on its use. Trained on data with MW from 12.24 g/mol to 402.4 g/mol, C mass fractions from 61.3% to 95.2%, H mass fractions from 3.73% to 15.2%, N mass fractions from 0 to 15.4%, O mass fractions from 0 to 18.8%, and S mass fractions from 0 to 29.6%. Recommended for organic compounds with low mass fractions of hetero-atoms and especially when molar mass exceeds 200 g/mol. This model does not show and effects of phase transition but should not be used passed the triple point.
Original model is in terms of J/g/K. Note that the model s for predicting mass heat capacity, not molar heat capacity like most other methods!
A1 = 0.013183; A2 = 0.249381; theta = 151.8675; C1 = 0.026526; C2 = -0.024942; D1 = 0.000025; D2 = -0.000123.
Examples -------- >>> Lastovka_solid(300, 0.2139) 1682.063629222013
References ---------- .. [1] Laštovka, Václav, Michal Fulem, Mildred Becerra, and John M. Shaw. "A Similarity Variable for Estimating the Heat Capacity of Solid Organic Compounds: Part II. Application: Heat Capacity Calculation for Ill-Defined Organic Solids." Fluid Phase Equilibria 268, no. 1-2 (June 25, 2008): 134-41. doi:10.1016/j.fluid.2008.03.018. ''' A1 = 0.013183 A2 = 0.249381 theta = 151.8675 C1 = 0.026526 C2 = -0.024942 D1 = 0.000025 D2 = -0.000123
Cp = (3*(A1*similarity_variable + A2*similarity_variable**2)*R*(theta/T )**2*exp(theta/T)/(exp(theta/T)-1)**2 + (C1*similarity_variable + C2*similarity_variable**2)*T + (D1*similarity_variable + D2*similarity_variable**2)*T**2) Cp = Cp*1000 # J/g/K to J/kg/K return Cp
r'''Integrates solid constant-pressure heat capacitiy with the similarity variable concept and method as shown in [1]_.
Uses a explicit form as derived with Sympy.
Parameters ---------- T : float Temperature of solid [K] similarity_variable : float similarity variable as defined in [1]_, [mol/g]
Returns ------- H : float Difference in enthalpy from 0 K, [J/kg]
Notes ----- Original model is in terms of J/g/K. Note that the model is for predicting mass heat capacity, not molar heat capacity like most other methods!
See Also -------- Lastovka_solid
Examples -------- >>> Lastovka_solid_integral(300, 0.2139) 283246.1242170376
References ---------- .. [1] Laštovka, Václav, Michal Fulem, Mildred Becerra, and John M. Shaw. "A Similarity Variable for Estimating the Heat Capacity of Solid Organic Compounds: Part II. Application: Heat Capacity Calculation for Ill-Defined Organic Solids." Fluid Phase Equilibria 268, no. 1-2 (June 25, 2008): 134-41. doi:10.1016/j.fluid.2008.03.018. ''' A1 = 0.013183 A2 = 0.249381 theta = 151.8675 C1 = 0.026526 C2 = -0.024942 D1 = 0.000025 D2 = -0.000123 H = (T**3*(1000*D1*similarity_variable/3. + 1000*D2*similarity_variable**2/3.) + T**2*(500*C1*similarity_variable + 500*C2*similarity_variable**2) + (3000*A1*R*similarity_variable*theta + 3000*A2*R*similarity_variable**2*theta)/(exp(theta/T) - 1)) return H
r'''Integrates over T solid constant-pressure heat capacitiy with the similarity variable concept and method as shown in [1]_.
Uses a explicit form as derived with Sympy.
Parameters ---------- T : float Temperature of solid [K] similarity_variable : float similarity variable as defined in [1]_, [mol/g]
Returns ------- S : float Difference in entropy from 0 K, [J/kg/K]
Notes ----- Original model is in terms of J/g/K. Note that the model is for predicting mass heat capacity, not molar heat capacity like most other methods!
See Also -------- Lastovka_solid
Examples -------- >>> Lastovka_solid_integral_over_T(300, 0.2139) 1947.553552666818
References ---------- .. [1] Laštovka, Václav, Michal Fulem, Mildred Becerra, and John M. Shaw. "A Similarity Variable for Estimating the Heat Capacity of Solid Organic Compounds: Part II. Application: Heat Capacity Calculation for Ill-Defined Organic Solids." Fluid Phase Equilibria 268, no. 1-2 (June 25, 2008): 134-41. doi:10.1016/j.fluid.2008.03.018. ''' A1 = 0.013183 A2 = 0.249381 theta = 151.8675 C1 = 0.026526 C2 = -0.024942 D1 = 0.000025 D2 = -0.000123 S = (-3000*R*similarity_variable*(A1 + A2*similarity_variable)*log(exp(theta/T) - 1) + T**2*(500*D1*similarity_variable + 500*D2*similarity_variable**2) + T*(1000*C1*similarity_variable + 1000*C2*similarity_variable**2) + (3000*A1*R*similarity_variable*theta + 3000*A2*R*similarity_variable**2*theta)/(T*exp(theta/T) - T) + (3000*A1*R*similarity_variable*theta + 3000*A2*R*similarity_variable**2*theta)/T) return S
'''Holds all methods available for the HeatCapacitySolid class, for use in iterating over them.'''
r'''Class for dealing with solid heat capacity as a function of temperature. Consists of one temperature-dependent simple expression, one constant value source, and one simple estimator.
Parameters ---------- similarity_variable : float, optional similarity variable, n_atoms/MW, [mol/g] MW : float, optional Molecular weight, [g/mol] CASRN : str, optional The CAS number of the chemical
Notes ----- A string holding each method's name is assigned to the following variables in this module, intended as the most convenient way to refer to a method. To iterate over all methods, use the list stored in :obj:`heat_capacity_solid_methods`.
**PERRY151**: Simple polynomials with vaious exponents selected for each expression. Coefficients are in units of calories/mol/K. The full expression is:
.. math:: Cp = a + bT + c/T^2 + dT^2
Data is available for 284 solids, from [2]_.
**CRCSTD**: Values tabulated in [1]_ at 298.15 K; data is available for 529 solids. **LASTOVKA_S**: A basic estimation method using the `similarity variable` concept; requires only molecular structure, so is very convenient. See :obj:`Lastovka_solid` for details.
See Also -------- Lastovka_solid
References ---------- .. [1] Haynes, W.M., Thomas J. Bruno, and David R. Lide. CRC Handbook of Chemistry and Physics. [Boca Raton, FL]: CRC press, 2014. .. [2] Green, Don, and Robert Perry. Perry's Chemical Engineers' Handbook, Eighth Edition. McGraw-Hill Professional, 2007. ''' '''No interpolation transformation by default.''' '''No interpolation transformation by default.''' '''No interpolation transformation by default.''' '''Allow tabular extrapolation by default; a theoretical solid phase exists for all chemicals at sufficiently high pressures, although few chemicals could stably exist in those conditions.''' '''Heat capacities have a minimum value of 0 at 0 K.''' '''Maximum value of Heat capacity; arbitrarily set.'''
'''Default rankings of the available methods.'''
self.similarity_variable = similarity_variable self.MW = MW self.CASRN = CASRN
self.Tmin = None '''Minimum temperature at which no method can calculate the heat capacity under.''' self.Tmax = None '''Maximum temperature at which no method can calculate the heat capacity above.'''
self.tabular_data = {} '''tabular_data, dict: Stored (Ts, properties) for any tabular data; indexed by provided or autogenerated name.''' self.tabular_data_interpolators = {} '''tabular_data_interpolators, dict: Stored (extrapolator, spline) tuples which are interp1d instances for each set of tabular data; indexed by tuple of (name, interpolation_T, interpolation_property, interpolation_property_inv) to ensure that if an interpolation transform is altered, the old interpolator which had been created is no longer used.'''
self.sorted_valid_methods = [] '''sorted_valid_methods, list: Stored methods which were found valid at a specific temperature; set by `T_dependent_property`.''' self.user_methods = [] '''user_methods, list: Stored methods which were specified by the user in a ranked order of preference; set by `T_dependent_property`.'''
self.all_methods = set() '''Set of all methods available for a given CASRN and properties; filled by :obj:`load_all_methods`.'''
self.load_all_methods()
r'''Method which picks out coefficients for the specified chemical from the various dictionaries and DataFrames storing it. All data is stored as attributes. This method also sets :obj:`Tmin`, :obj:`Tmax`, and :obj:`all_methods` as a set of methods for which the data exists for.
Called on initialization only. See the source code for the variables at which the coefficients are stored. The coefficients can safely be altered once the class is initialized. This method can be called again to reset the parameters. ''' methods = [] Tmins, Tmaxs = [], [] if self.CASRN and self.CASRN in _PerryI and 'c' in _PerryI[self.CASRN]: self.PERRY151_Tmin = _PerryI[self.CASRN]['c']['Tmin'] if _PerryI[self.CASRN]['c']['Tmin'] else 0 self.PERRY151_Tmax = _PerryI[self.CASRN]['c']['Tmax'] if _PerryI[self.CASRN]['c']['Tmax'] else 2000 self.PERRY151_const = _PerryI[self.CASRN]['c']['Const'] self.PERRY151_lin = _PerryI[self.CASRN]['c']['Lin'] self.PERRY151_quad = _PerryI[self.CASRN]['c']['Quad'] self.PERRY151_quadinv = _PerryI[self.CASRN]['c']['Quadinv'] methods.append(PERRY151) Tmins.append(self.PERRY151_Tmin); Tmaxs.append(self.PERRY151_Tmax) if self.CASRN in CRC_standard_data.index and not np.isnan(CRC_standard_data.at[self.CASRN, 'Cpc']): self.CRCSTD_Cp = float(CRC_standard_data.at[self.CASRN, 'Cpc']) methods.append(CRCSTD) if self.MW and self.similarity_variable: methods.append(LASTOVKA_S) Tmins.append(1.0); Tmaxs.append(10000) # Works above roughly 1 K up to 10K. self.all_methods = set(methods) if Tmins and Tmaxs: self.Tmin, self.Tmax = min(Tmins), max(Tmaxs)
r'''Method to calculate heat capacity of a solid at temperature `T` with a given method.
This method has no exception handling; see `T_dependent_property` for that.
Parameters ---------- T : float Temperature at which to calculate heat capacity, [K] method : str Name of the method to use
Returns ------- Cp : float Heat capacity of the solid at T, [J/mol/K] ''' if method == PERRY151: Cp = (self.PERRY151_const + self.PERRY151_lin*T + self.PERRY151_quadinv/T**2 + self.PERRY151_quad*T**2)*calorie elif method == CRCSTD: Cp = self.CRCSTD_Cp elif method == LASTOVKA_S: Cp = Lastovka_solid(T, self.similarity_variable) Cp = property_mass_to_molar(Cp, self.MW) elif method in self.tabular_data: Cp = self.interpolate(T, method) return Cp
r'''Method to check the validity of a method. Follows the given ranges for all coefficient-based methods. For tabular data, extrapolation outside of the range is used if :obj:`tabular_extrapolation_permitted` is set; if it is, the extrapolation is considered valid for all temperatures. For the :obj:`Lastovka_solid` method, it is considered valid under 10000K.
It is not guaranteed that a method will work or give an accurate prediction simply because this method considers the method valid.
Parameters ---------- T : float Temperature at which to test the method, [K] method : str Name of the method to test
Returns ------- validity : bool Whether or not a method is valid ''' validity = True if method == PERRY151: if T < self.PERRY151_Tmin or T > self.PERRY151_Tmax: validity = False elif method == CRCSTD: if T < 298.15-50 or T > 298.15+50: validity = False elif method == LASTOVKA_S: if T > 10000 or T < 0: validity = False elif method in self.tabular_data: # if tabular_extrapolation_permitted, good to go without checking if not self.tabular_extrapolation_permitted: Ts, properties = self.tabular_data[method] if T < Ts[0] or T > Ts[-1]: validity = False else: raise Exception('Method not valid') return validity
### Mixture heat capacities
def Cp_liq_mixture(zs=None, ws=None, Cps=None, T=None, CASRNs=None, AvailableMethods=False, Method=None): # pragma: no cover '''This function handles the retrival of a mixture's liquid heat capacity.
This API is considered experimental, and is expected to be removed in a future release in favor of a more complete object-oriented interface.
>>> Cp_liq_mixture(ws=[0.6, 0.3, 0.1], Cps=[4180.59, 2532.45, 2268.80]) 3494.969 ''' def list_methods(): methods = [] if CASRNs and len(CASRNs) > 1 and '7732-18-5' in CASRNs and T and ws: wCASRNs = list(CASRNs) wCASRNs.remove('7732-18-5') if all([i in _Laliberte_Heat_Capacity_ParametersDict for i in wCASRNs]): methods.append('Laliberte') if none_and_length_check([Cps]): methods.append('Simple') methods.append('None') return methods if AvailableMethods: return list_methods() if not Method: Method = list_methods()[0] # This is the calculate, given the method section if not none_and_length_check([Cps, ws]): # check same-length inputs # raise Exception('Function inputs are incorrect format') return None if Method == 'Simple': _cp = mixing_simple(ws, Cps) elif Method == 'Laliberte': ws = list(ws) ws.remove(ws[CASRNs.index('7732-18-5')]) wCASRNs = list(CASRNs) wCASRNs.remove('7732-18-5') _cp = Laliberte_heat_capacity(T, ws, wCASRNs) elif Method == 'None': return None else: raise Exception('Failure in in function') return _cp
def Cp_gas_mixture(zs=None, ws=None, Cps=None, CASRNs=None, AvailableMethods=False, Method=None): # pragma: no cover '''This function handles the retrival of a mixture's gas heat capacity.
This API is considered experimental, and is expected to be removed in a future release in favor of a more complete object-oriented interface.
>>> Cp_gas_mixture(ws=[0.6, 0.3, 0.1], Cps=[1864.17, 1375.76, 1654.71]) 1696.701 ''' def list_methods(): methods = [] if none_and_length_check([Cps]): methods.append('Simple') methods.append('None') return methods if AvailableMethods: return list_methods() if not Method: Method = list_methods()[0] # This is the calculate, given the method section if not none_and_length_check([Cps, ws]): # check same-length inputs return None # raise Exception('Function inputs are incorrect format') if Method == 'Simple': _cp = mixing_simple(ws, Cps) elif Method == 'None': return None else: raise Exception('Failure in in function') return _cp
def Cv_gas_mixture(zs=None, ws=None, Cps=None, CASRNs=None, AvailableMethods=False, Method=None): # pragma: no cover '''This function handles the retrival of a mixture's gas constant volume heat capacity.
This API is considered experimental, and is expected to be removed in a future release in favor of a more complete object-oriented interface.
>>> Cv_gas_mixture(ws=[0.6, 0.3, 0.1], Cps=[1402.64, 1116.27, 1558.23]) 1332.2880000000002 ''' def list_methods(): methods = [] if none_and_length_check([Cps]): methods.append('Simple') methods.append('None') return methods if AvailableMethods: return list_methods() if not Method: Method = list_methods()[0] # This is the calculate, given the method section if not none_and_length_check((Cps, ws)): # check same-length inputs return None # raise Exception('Function inputs are incorrect format') if Method == 'Simple': _cp = mixing_simple(ws, Cps) elif Method == 'None': return None else: raise Exception('Failure in in function') return _cp
|