Source code for realgas.critical_constants

from chem_util.chem_constants import gas_constant as R
from chem_util.math import percent_difference

from . import os, ROOT_DIR


[docs]class CriticalConstants: """ Get critical constants of a compound If critical constants are not passed in, reads from DIPPR table :param dippr_no: dippr_no of compound by DIPPR table, defaults to None :type dippr_no: str, optional :param compound_name: name of chemical compound, defaults to None :type compound_name: str, optional :param cas_number: CAS registry number for chemical compound, defaults to None :type cas_number: str, optional :param MW: molecular weight in g/mol :param T_c: critical temperature [K] :param P_c: critical pressure [Pa] :param V_c: critical molar volume [m^3/mol] :param Z_c: critical compressibility factor [dimensionless] :param w: accentric factor [dimensionless] :param tol: tolerance for percent difference in Zc calulcated and tabulated, set to 0.5 :type tol: float, hard-coded """ def __init__(self, dippr_no: str = None, compound_name: str = None, cas_number: str = None, MW: float = None, P_c: float = None, V_c: float = None, Z_c: float = None, T_c: float = None, w: float = None): file = os.path.join(ROOT_DIR, 'critical_constants.csv') my_header = [ 'Cmpd. no.', 'Name', 'Formula', 'CAS no.', 'Mol. wt. [g/mol]', 'Tc [K]', 'Pc [MPa]', 'Vc [m3/kmol]', 'Zc', 'Acentric factor' ] self.dippr_no = dippr_no self.compound_name = compound_name self.cas_number = cas_number self.MW = MW self.P_c = P_c self.V_c = V_c self.Z_c = Z_c self.T_c = T_c self.w = w self.tol = 0.5 if self.MW is None and self.P_c is None and self.V_c is None and self.Z_c is None and self.T_c is None and self.w is None: # if havent input critical compounds, get from DIPPR table found_compound = False with open(file, 'r') as f: header = next(f).rstrip('\n').split(',') assert header == my_header, 'Wrong header!' for line in f: vals = line.rstrip('\n').split(',') if vals[0] == self.dippr_no or vals[1] == self.compound_name or vals[3] == self.cas_number: assert not found_compound, 'Input compound found twice in table!' found_compound = True # found (self.dippr_no, self.compound_name, self.formula, self.cas_number, *floating_point_vals) = vals self.MW, self.T_c, self.P_c, self.V_c, self.Z_c, self.w = map(float, floating_point_vals) self.P_c = 1e6 * self.P_c self.V_c = self.V_c / 1000. assert found_compound, 'No compound was found in table! for {}, {}, {}'.format(self.dippr_no, self.compound_name, self.cas_number) assert self.Z_c_percent_difference() < self.tol, 'Critical compressibility inconsistency!' else: # make dummy class from DIPPR table, test that custom parameters are at least close to DIPPR dippr_cls = CriticalConstants(compound_name=self.compound_name) assert abs(percent_difference(self.Z_c, dippr_cls.Z_c)) < 50., 'Percent difference too high for Z_c' assert abs(percent_difference(self.V_c, dippr_cls.V_c)) < 50., 'Percent difference too high for V_c' assert abs(percent_difference(self.P_c, dippr_cls.P_c)) < 50., 'Percent difference too high for P_c' assert abs(percent_difference(self.T_c, dippr_cls.T_c)) < 50., 'Percent difference too high for T_c' assert abs(percent_difference(self.w, dippr_cls.w)) < 50., 'Percent difference too high for w' assert abs(percent_difference(self.MW, dippr_cls.MW)) < 0.01, 'Percent difference too high for MW' assert (self.compound_name is not None and self.cas_number is not None and self.MW is not None and self.P_c is not None and self.V_c is not None and self.Z_c is not None and self.w is not None and self.T_c is not None), 'Inconsistent input, need to input all values'
[docs] def calc_Z_c(self): """Calculate critical compressibility, for comparison to tabulated value""" return self.P_c * self.V_c / R / self.T_c
[docs] def Z_c_percent_difference(self): """calculate percent difference between Z_c calculated and tabulated""" return percent_difference(self.calc_Z_c(), self.Z_c)