def list_methods(): ''' List methods available for calculating a chemical's acentric factor, omega ''' methods = [] if (CASRN in _crit_PSRKR4.index and not np.isnan(_crit_PSRKR4.at[CASRN, 'omega'])): methods.append('PSRK') if (CASRN in _crit_PassutDanner.index and not np.isnan(_crit_PassutDanner.at[CASRN, 'omega'])): methods.append('PD') if (CASRN in _crit_Yaws.index and not np.isnan(_crit_Yaws.at[CASRN, 'omega'])): methods.append('YAWS') Tcrit, Pcrit = Tc(CASRN), Pc(CASRN) if Tcrit and Pcrit: if Tb(CASRN): methods.append('LK') if VaporPressure(CASRN=CASRN).T_dependent_property(Tcrit * 0.7): # TODO: better integration methods.append('DEFINITION') if IgnoreMethods: for Method in IgnoreMethods: if Method in methods: methods.remove(Method) methods.append('NONE') return methods
def list_methods(): methods = [] if CASRN in Staveley_data.index and not np.isnan( Staveley_data.at[CASRN, 'Pt']): methods.append(STAVELEY) if Tt(CASRN) and VaporPressure(CASRN=CASRN).T_dependent_property( T=Tt(CASRN)): methods.append(DEFINITION) methods.append(NONE) return methods
def set_T_sources(self): # Tempearture and Pressure Denepdence # Get and choose initial methods self.VaporPressure = VaporPressure(Tb=self.Tb, Tc=self.Tc, Pc=self.Pc, omega=self.omega, CASRN=self.CAS) self.Psat_298 = self.VaporPressure.T_dependent_property(298.15) self.VolumeLiquid = VolumeLiquid(MW=self.MW, Tb=self.Tb, Tc=self.Tc, Pc=self.Pc, Vc=self.Vc, Zc=self.Zc, omega=self.omega, dipole=self.dipole, Psat=self.VaporPressure.T_dependent_property, CASRN=self.CAS) self.Vml_Tb = self.VolumeLiquid.T_dependent_property(self.Tb) if self.Tb else None self.Vml_Tm = self.VolumeLiquid.T_dependent_property(self.Tm) if self.Tm else None self.Vml_STP = self.VolumeLiquid.T_dependent_property(298.15) # set molecular_diameter; depends on Vml_Tb, Vml_Tm self.molecular_diameter_sources = molecular_diameter(Tc=self.Tc, Pc=self.Pc, Vc=self.Vc, Zc=self.Zc, omega=self.omega, Vm=self.Vml_Tm, Vb=self.Vml_Tb, AvailableMethods=True, CASRN=self.CAS) self.molecular_diameter_source = self.molecular_diameter_sources[0] self.molecular_diameter = molecular_diameter(Tc=self.Tc, Pc=self.Pc, Vc=self.Vc, Zc=self.Zc, omega=self.omega, Vm=self.Vml_Tm, Vb=self.Vml_Tb, Method=self.molecular_diameter_source, CASRN=self.CAS) self.VolumeGas = VolumeGas(MW=self.MW, Tc=self.Tc, Pc=self.Pc, omega=self.omega, dipole=self.dipole, CASRN=self.CAS) self.VolumeSolid = VolumeSolid(CASRN=self.CAS, MW=self.MW, Tt=self.Tt) self.HeatCapacityGas = HeatCapacityGas(CASRN=self.CAS, MW=self.MW, similarity_variable=self.similarity_variable) self.HeatCapacitySolid = HeatCapacitySolid(MW=self.MW, similarity_variable=self.similarity_variable, CASRN=self.CAS) self.HeatCapacityLiquid = HeatCapacityLiquid(CASRN=self.CAS, MW=self.MW, similarity_variable=self.similarity_variable, Tc=self.Tc, omega=self.omega, Cpgm=self.HeatCapacityGas.T_dependent_property) self.EnthalpyVaporization = EnthalpyVaporization(CASRN=self.CAS, Tb=self.Tb, Tc=self.Tc, Pc=self.Pc, omega=self.omega, similarity_variable=self.similarity_variable) self.HvapTbm = self.EnthalpyVaporization.T_dependent_property(self.Tb) if self.Tb else None self.HvapTb = property_molar_to_mass(self.HvapTbm, self.MW) self.Hsub_methods = Hsub(T=self.T, P=self.P, MW=self.MW, AvailableMethods=True, CASRN=self.CAS) self.Hsub_method = self.Hsub_methods[0] self.ViscosityLiquid = ViscosityLiquid(CASRN=self.CAS, MW=self.MW, Tm=self.Tm, Tc=self.Tc, Pc=self.Pc, Vc=self.Vc, omega=self.omega, Psat=self.VaporPressure.T_dependent_property, Vml=self.VolumeLiquid.T_dependent_property) vmg_calc = lambda T : self.VolumeGas.TP_dependent_property(T, 101325) self.ViscosityGas = ViscosityGas(CASRN=self.CAS, MW=self.MW, Tc=self.Tc, Pc=self.Pc, Zc=self.Zc, dipole=self.dipole, Vmg=vmg_calc) self.ThermalConductivityLiquid = ThermalConductivityLiquid(CASRN=self.CAS, MW=self.MW, Tm=self.Tm, Tb=self.Tb, Tc=self.Tc, Pc=self.Pc, omega=self.omega, Hfus=self.Hfusm) cvgm_calc = lambda T : self.HeatCapacityGas.T_dependent_property(T) - R self.ThermalConductivityGas = ThermalConductivityGas(CASRN=self.CAS, MW=self.MW, Tb=self.Tb, Pc=self.Pc, Vc=self.Vc, Zc=self.Zc, omega=self.omega, dipole=self.dipole, Vmg=vmg_calc, Cvgm=cvgm_calc, mug=self.ViscosityGas.T_dependent_property) self.SurfaceTension = SurfaceTension(CASRN=self.CAS, Tb=self.Tb, Tc=self.Tc, Pc=self.Pc, Vc=self.Vc, Zc=self.Zc, omega=self.omega, StielPolar=self.StielPolar) self.Permittivity = Permittivity(CASRN=self.CAS) self.solubility_parameter_methods = solubility_parameter(T=self.T, Hvapm=self.HvapTbm, Vml=self.Vml_STP, AvailableMethods=True, CASRN=self.CAS) self.solubility_parameter_method = self.solubility_parameter_methods[0]
def set_T_sources(self): # Tempearture and Pressure Denepdence # Get and choose initial methods self.VaporPressure = VaporPressure(Tb=self.Tb, Tc=self.Tc, Pc=self.Pc, omega=self.omega, CASRN=self.CAS) self.Psat_298 = self.VaporPressure.T_dependent_property(298.15) self.VolumeLiquid = VolumeLiquid(MW=self.MW, Tb=self.Tb, Tc=self.Tc, Pc=self.Pc, Vc=self.Vc, Zc=self.Zc, omega=self.omega, dipole=self.dipole, Psat=self.Psat, CASRN=self.CAS) if self.Tb: self.Vml_Tb = self.VolumeLiquid.T_dependent_property(self.Tb) else: self.Vml_Tb = None if self.Tm: self.Vml_Tm = self.VolumeLiquid.T_dependent_property(self.Tm) else: self.Vml_Tm = None self.Vml_STP = self.VolumeLiquid.T_dependent_property(298.15) self.VolumeGas = VolumeGas(MW=self.MW, Tc=self.Tc, Pc=self.Pc, omega=self.omega, dipole=self.dipole, CASRN=self.CAS) self.VolumeSolid = VolumeSolid(CASRN=self.CAS, MW=self.MW, Tt=self.Tt) self.HeatCapacitySolid = HeatCapacitySolid(MW=self.MW, similarity_variable=self.similarity_variable, CASRN=self.CAS) self.HeatCapacityLiquid = HeatCapacityLiquid(CASRN=self.CAS, MW=self.MW, similarity_variable=self.similarity_variable, Tc=self.Tc, omega=self.omega, Cpgm=self.Cpgm) self.HeatCapacityGas = HeatCapacityGas(CASRN=self.CAS, MW=self.MW, similarity_variable=self.similarity_variable) self.ViscosityLiquid = ViscosityLiquid(CASRN=self.CAS, MW=self.MW, Tm=self.Tm, Tc=self.Tc, Pc=self.Pc, Vc=self.Vc, omega=self.omega, Psat=self.Psat, Vml=self.Vml) self.ViscosityGas = ViscosityGas(CASRN=self.CAS, MW=self.MW, Tc=self.Tc, Pc=self.Pc, Zc=self.Zc, dipole=self.dipole, Vmg=self.Vmg) self.EnthalpyVaporization = EnthalpyVaporization(CASRN=self.CAS, Tb=self.Tb, Tc=self.Tc, Pc=self.Pc, omega=self.omega, similarity_variable=self.similarity_variable) self.HvapTbm = self.EnthalpyVaporization.T_dependent_property(self.Tb) self.HvapTb = property_molar_to_mass(self.HvapTbm, self.MW) self.Hfus_methods = Hfus(T=self.T, P=self.P, MW=self.MW, AvailableMethods=True, CASRN=self.CAS) self.Hfus_method = self.Hfus_methods[0] self.Hsub_methods = Hsub(T=self.T, P=self.P, MW=self.MW, AvailableMethods=True, CASRN=self.CAS) self.Hsub_method = self.Hsub_methods[0] self.ThermalConductivityLiquid = ThermalConductivityLiquid(CASRN=self.CAS, MW=self.MW, Tm=self.Tm, Tb=self.Tb, Tc=self.Tc, Pc=self.Pc, omega=self.omega, Hfus=self.Hfusm) self.ThermalConductivityGas = ThermalConductivityGas(CASRN=self.CAS, MW=self.MW, Tb=self.Tb, Pc=self.Pc, Vc=self.Vc, Zc=self.Zc, omega=self.omega, dipole=self.dipole, Vmg=self.Vmg, Cvgm=self.Cvgm, mug=self.mug) self.SurfaceTension = SurfaceTension(CASRN=self.CAS, Tb=self.Tb, Tc=self.Tc, Pc=self.Pc, Vc=self.Vc, Zc=self.Zc, omega=self.omega, StielPolar=self.StielPolar) self.Permittivity = Permittivity(CASRN=self.CAS) self.solubility_parameter_methods = solubility_parameter(T=self.T, Hvapm=self.Hvapm, Vml=self.Vml, AvailableMethods=True, CASRN=self.CAS) self.solubility_parameter_method = self.solubility_parameter_methods[0]
def list_methods(): methods = [] if CASRN in _crit_PSRKR4.index and not np.isnan(_crit_PSRKR4.at[CASRN, 'omega']): methods.append('PSRK') if CASRN in _crit_PassutDanner.index and not np.isnan(_crit_PassutDanner.at[CASRN, 'omega']): methods.append('PD') if CASRN in _crit_Yaws.index and not np.isnan(_crit_Yaws.at[CASRN, 'omega']): methods.append('YAWS') Tcrit, Pcrit = Tc(CASRN), Pc(CASRN) if Tcrit and Pcrit: if Tb(CASRN): methods.append('LK') if VaporPressure(CASRN=CASRN).T_dependent_property(Tcrit*0.7): methods.append('DEFINITION') # TODO: better integration if IgnoreMethods: for Method in IgnoreMethods: if Method in methods: methods.remove(Method) methods.append('NONE') return methods
def list_methods(): methods = [] if CASRN in CRC_inorganic_data.index and not np.isnan(CRC_inorganic_data.at[CASRN, 'Tb']): methods.append(CRC_INORG) if CASRN in CRC_organic_data.index and not np.isnan(CRC_organic_data.at[CASRN, 'Tb']): methods.append(CRC_ORG) if CASRN in Yaws_data.index: methods.append(YAWS) if PSAT_DEFINITION not in IgnoreMethods: try: # For some chemicals, vapor pressure range will exclude Tb VaporPressure(CASRN=CASRN).solve_prop(101325.) methods.append(PSAT_DEFINITION) except: # pragma: no cover pass if IgnoreMethods: for Method in IgnoreMethods: if Method in methods: methods.remove(Method) methods.append(NONE) return methods
def omega(CASRN, AvailableMethods=False, Method=None, IgnoreMethods=['LK', 'DEFINITION']): r'''This function handles the retrieval of a chemical's acentric factor, `omega`, or its calculation from correlations or directly through the definition of acentric factor if possible. Requires a known boiling point, critical temperature and pressure for use of the correlations. Requires accurate vapor pressure data for direct calculation. Will automatically select a method to use if no Method is provided; returns None if the data is not available and cannot be calculated. .. math:: \omega \equiv -\log_{10}\left[\lim_{T/T_c=0.7}(P^{sat}/P_c)\right]-1.0 Examples -------- >>> omega(CASRN='64-17-5') 0.635 Parameters ---------- CASRN : string CASRN [-] Returns ------- omega : float Acentric factor of compound methods : list, only returned if AvailableMethods == True List of methods which can be used to obtain omega with the given inputs Other Parameters ---------------- Method : string, optional The method name to use. Accepted methods are 'PSRK', 'PD', 'YAWS', 'LK', and 'DEFINITION'. All valid values are also held in the list omega_methods. AvailableMethods : bool, optional If True, function will determine which methods can be used to obtain omega for the desired chemical, and will return methods instead of omega IgnoreMethods : list, optional A list of methods to ignore in obtaining the full list of methods, useful for for performance reasons and ignoring inaccurate methods Notes ----- A total of five sources are available for this function. They are: * 'PSRK', a compillation of experimental and estimated data published in the Appendix of [15]_, the fourth revision of the PSRK model. * 'PD', an older compillation of data published in (Passut & Danner, 1973) [16]_. * 'YAWS', a large compillation of data from a variety of sources; no data points are sourced in the work of [17]_. * 'LK', a estimation method for hydrocarbons. * 'DEFINITION', based on the definition of omega as presented in [1]_, using vapor pressure data. References ---------- .. [1] Pitzer, K. S., D. Z. Lippmann, R. F. Curl, C. M. Huggins, and D. E. Petersen: The Volumetric and Thermodynamic Properties of Fluids. II. Compressibility Factor, Vapor Pressure and Entropy of Vaporization. J. Am. Chem. Soc., 77: 3433 (1955). .. [2] Horstmann, Sven, Anna Jabłoniec, Jörg Krafczyk, Kai Fischer, and Jürgen Gmehling. "PSRK Group Contribution Equation of State: Comprehensive Revision and Extension IV, Including Critical Constants and Α-Function Parameters for 1000 Components." Fluid Phase Equilibria 227, no. 2 (January 25, 2005): 157-64. doi:10.1016/j.fluid.2004.11.002. .. [3] Passut, Charles A., and Ronald P. Danner. "Acentric Factor. A Valuable Correlating Parameter for the Properties of Hydrocarbons." Industrial & Engineering Chemistry Process Design and Development 12, no. 3 (July 1, 1973): 365-68. doi:10.1021/i260047a026. .. [4] Yaws, Carl L. Thermophysical Properties of Chemicals and Hydrocarbons, Second Edition. Amsterdam Boston: Gulf Professional Publishing, 2014. ''' def list_methods(): ''' List methods available for calculating a chemical's acentric factor, omega ''' methods = [] if (CASRN in _crit_PSRKR4.index and not np.isnan(_crit_PSRKR4.at[CASRN, 'omega'])): methods.append('PSRK') if (CASRN in _crit_PassutDanner.index and not np.isnan(_crit_PassutDanner.at[CASRN, 'omega'])): methods.append('PD') if (CASRN in _crit_Yaws.index and not np.isnan(_crit_Yaws.at[CASRN, 'omega'])): methods.append('YAWS') Tcrit, Pcrit = Tc(CASRN), Pc(CASRN) if Tcrit and Pcrit: if Tb(CASRN): methods.append('LK') if VaporPressure(CASRN=CASRN).T_dependent_property(Tcrit * 0.7): # TODO: better integration methods.append('DEFINITION') if IgnoreMethods: for Method in IgnoreMethods: if Method in methods: methods.remove(Method) 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 Method == 'PSRK': _omega = float(_crit_PSRKR4.at[CASRN, 'omega']) elif Method == 'PD': _omega = float(_crit_PassutDanner.at[CASRN, 'omega']) elif Method == 'YAWS': _omega = float(_crit_Yaws.at[CASRN, 'omega']) elif Method == 'LK': _omega = LK_omega(Tb(CASRN), Tc(CASRN), Pc(CASRN)) elif Method == 'DEFINITION': P = VaporPressure(CASRN=CASRN).T_dependent_property(Tc(CASRN) * 0.7) _omega = -log10(P / Pc(CASRN)) - 1.0 elif Method == 'NONE': _omega = None else: raise Exception('Failure in in function') return _omega
def StielPolar(Tc=None, Pc=None, omega=None, CASRN='', Method=None, AvailableMethods=False): r'''This function handles the calculation of a chemical's Stiel Polar factor, directly through the definition of Stiel-polar factor if possible. Requires Tc, Pc, acentric factor, and a vapor pressure datum at Tr=0.6. Will automatically select a method to use if no Method is provided; returns None if the data is not available and cannot be calculated. .. math:: x = \log P_r|_{T_r=0.6} + 1.70 \omega + 1.552 Parameters ---------- Tc : float Critical temperature of fluid [K] Pc : float Critical pressure of fluid [Pa] omega : float Acentric factor of the fluid [-] CASRN : string CASRN [-] Returns ------- factor : float Stiel polar factor of compound methods : list, only returned if AvailableMethods == True List of methods which can be used to obtain Stiel polar factor with the given inputs Other Parameters ---------------- Method : string, optional The method name to use. Only 'DEFINITION' is accepted so far. All valid values are also held in the list Stiel_polar_methods. AvailableMethods : bool, optional If True, function will determine which methods can be used to obtain Stiel-polar factor for the desired chemical, and will return methods instead of stiel-polar factor Notes ----- Only one source is available for this function. It is: * 'DEFINITION', based on the definition of Stiel Polar Factor presented in [1]_, using vapor pressure data. A few points have also been published in [2]_, which may be used for comparison. Currently this is only used for a surface tension correlation. Examples -------- >>> StielPolar(647.3, 22048321.0, 0.344, CASRN='7732-18-5') 0.024581140348734376 References ---------- .. [1] Halm, Roland L., and Leonard I. Stiel. "A Fourth Parameter for the Vapor Pressure and Entropy of Vaporization of Polar Fluids." AIChE Journal 13, no. 2 (1967): 351-355. doi:10.1002/aic.690130228. .. [2] D, Kukoljac Miloš, and Grozdanić Dušan K. "New Values of the Polarity Factor." Journal of the Serbian Chemical Society 65, no. 12 (January 1, 2000). http://www.shd.org.rs/JSCS/Vol65/No12-Pdf/JSCS12-07.pdf ''' def list_methods(): ''' List methods available for Stiel's polar factor ''' methods = [] if Tc and Pc and omega: methods.append('DEFINITION') methods.append('NONE') return methods if AvailableMethods: return list_methods() if not Method: Method = list_methods()[0] if Method == 'DEFINITION': P = VaporPressure(CASRN=CASRN).T_dependent_property(Tc * 0.6) if not P: factor = None else: Pr = P / Pc factor = log10(Pr) + 1.70 * omega + 1.552 elif Method == 'NONE': factor = None else: raise Exception('Failure in in function') return factor
def Tb(CASRN='', AvailableMethods=False, Method=None, IgnoreMethods=[PSAT_DEFINITION]): r'''This function handles the retrieval of a chemical's boiling point. Lookup is based on CASRNs. Will automatically select a data source to use if no Method is provided; returns None if the data is not available. Prefered sources are 'CRC Physical Constants, organic' for organic chemicals, and 'CRC Physical Constants, inorganic' for inorganic chemicals. Function has data for approximately 13000 chemicals. Parameters ---------- CASRN : string CASRN [-] Returns ------- Tb : float Boiling temperature, [K] methods : list, only returned if AvailableMethods == True List of methods which can be used to obtain Tb with the given inputs Other Parameters ---------------- Method : string, optional A string for the method name to use, as defined by constants in Tb_methods AvailableMethods : bool, optional If True, function will determine which methods can be used to obtain Tb for the desired chemical, and will return methods instead of Tb IgnoreMethods : list, optional A list of methods to ignore in obtaining the full list of methods, useful for for performance reasons and ignoring inaccurate methods Notes ----- A total of four methods are available for this function. They are: * 'CRC_ORG', a compillation of data on organics as published in [1]_. * 'CRC_INORG', a compillation of data on inorganic as published in [1]_. * 'YAWS', a large compillation of data from a variety of sources; no data points are sourced in the work of [2]_. * 'PSAT_DEFINITION', calculation of boiling point from a vapor pressure calculation. This is normally off by a fraction of a degree even in the best cases. Listed in IgnoreMethods by default for performance reasons. Examples -------- >>> Tb('7732-18-5') 373.124 References ---------- .. [1] Haynes, W.M., Thomas J. Bruno, and David R. Lide. CRC Handbook of Chemistry and Physics, 95E. Boca Raton, FL: CRC press, 2014. .. [2] Yaws, Carl L. Thermophysical Properties of Chemicals and Hydrocarbons, Second Edition. Amsterdam Boston: Gulf Professional Publishing, 2014. ''' def list_methods(): methods = [] if CASRN in CRC_inorganic_data.index and not np.isnan(CRC_inorganic_data.at[CASRN, 'Tb']): methods.append(CRC_INORG) if CASRN in CRC_organic_data.index and not np.isnan(CRC_organic_data.at[CASRN, 'Tb']): methods.append(CRC_ORG) if CASRN in Yaws_data.index: methods.append(YAWS) if PSAT_DEFINITION not in IgnoreMethods: try: # For some chemicals, vapor pressure range will exclude Tb VaporPressure(CASRN=CASRN).solve_prop(101325.) methods.append(PSAT_DEFINITION) except: # pragma: no cover pass if IgnoreMethods: for Method in IgnoreMethods: if Method in methods: methods.remove(Method) methods.append(NONE) return methods if AvailableMethods: return list_methods() if not Method: Method = list_methods()[0] if Method == CRC_INORG: _Tb = float(CRC_inorganic_data.at[CASRN, 'Tb']) elif Method == CRC_ORG: _Tb = float(CRC_organic_data.at[CASRN, 'Tb']) elif Method == YAWS: _Tb = float(Yaws_data.at[CASRN, 'Tb']) elif Method == PSAT_DEFINITION: _Tb = VaporPressure(CASRN=CASRN).solve_prop(101325.) elif Method == NONE: return None else: raise Exception('Failure in in function') return _Tb
class Chemical(object): # pragma: no cover '''Class for obtaining properties of chemicals. Considered somewhat stable, but changes to some mthods are expected. Default initialization is for 298.15 K, 1 atm. Goal is for, when a method fails, a warning is printed. ''' def __init__(self, ID, T=298.15, P=101325): self.ID = ID self.P = P self.T = T # Identification self.CAS = CASfromAny(ID) self.PubChem = PubChem(self.CAS) self.MW = MW(self.CAS) self.formula = formula(self.CAS) self.smiles = smiles(self.CAS) self.InChI = InChI(self.CAS) self.InChI_Key = InChI_Key(self.CAS) self.IUPAC_name = IUPAC_name(self.CAS).lower() self.name = name(self.CAS).lower() self.synonyms = [i.lower() for i in synonyms(self.CAS)] self.set_structure() self.set_constant_sources() self.set_constants() self.set_T_sources() self.set_T(self.T) self.set_phase() def set_structure(self): try: self.rdkitmol = Chem.MolFromSmiles(self.smiles) self.rdkitmol_Hs = Chem.AddHs(self.rdkitmol) self.atoms = dict(Counter(atom.GetSymbol() for atom in self.rdkitmol_Hs.GetAtoms())) self.charge = Chem.GetFormalCharge(self.rdkitmol) self.rings = Chem.Descriptors.RingCount(self.rdkitmol) self.atom_fractions = atom_fractions(self.atoms) self.mass_fractions = mass_fractions(self.atoms, self.MW) self.similarity_variable = similarity_variable(self.atoms, self.MW) self.Hill = atoms_to_Hill(self.atoms) except: self.rdkitmol = None self.rdkitmol_Hs = None self.charge = None self.rings = None self.atoms = simple_formula_parser(self.formula) self.atom_fractions = atom_fractions(self.atoms) self.mass_fractions = mass_fractions(self.atoms, self.MW) self.similarity_variable = similarity_variable(self.atoms, self.MW) self.Hill = atoms_to_Hill(self.atoms) def draw_2d(self): try: return Draw.MolToImage(self.rdkitmol) except: return 'Rdkit required' def draw_3d(self): try: import py3Dmol AllChem.EmbedMultipleConfs(self.rdkitmol_Hs) mb = Chem.MolToMolBlock(self.rdkitmol_Hs) p = py3Dmol.view(width=300,height=300) p.addModel(mb,'sdf') p.setStyle({'stick':{}}) # Styles: stick, line, cross, sphere p.zoomTo() p.show() return p except: return 'py3Dmol and rdkit required' def set_constant_sources(self): self.Tm_sources = Tm(CASRN=self.CAS, AvailableMethods=True) self.Tm_source = self.Tm_sources[0] self.Tb_sources = Tb(CASRN=self.CAS, AvailableMethods=True) self.Tb_source = self.Tb_sources[0] # Critical Point self.Tc_methods = Tc(self.CAS, AvailableMethods=True) self.Tc_method = self.Tc_methods[0] self.Pc_methods = Pc(self.CAS, AvailableMethods=True) self.Pc_method = self.Pc_methods[0] self.Vc_methods = Vc(self.CAS, AvailableMethods=True) self.Vc_method = self.Vc_methods[0] self.omega_methods = omega(CASRN=self.CAS, AvailableMethods=True) self.omega_method = self.omega_methods[0] # Triple point self.Tt_sources = Tt(self.CAS, AvailableMethods=True) self.Tt_source = self.Tt_sources[0] self.Pt_sources = Pt(self.CAS, AvailableMethods=True) self.Pt_source = self.Pt_sources[0] # Enthalpy self.Hfus_methods = Hfus(T=self.T, P=self.P, MW=self.MW, AvailableMethods=True, CASRN=self.CAS) self.Hfus_method = self.Hfus_methods[0] # Fire Safety Limits self.Tflash_sources = Tflash(self.CAS, AvailableMethods=True) self.Tflash_source = self.Tflash_sources[0] self.Tautoignition_sources = Tautoignition(self.CAS, AvailableMethods=True) self.Tautoignition_source = self.Tautoignition_sources[0] # Chemical Exposure Limits self.TWA_sources = TWA(self.CAS, AvailableMethods=True) self.TWA_source = self.TWA_sources[0] self.STEL_sources = STEL(self.CAS, AvailableMethods=True) self.STEL_source = self.STEL_sources[0] self.Ceiling_sources = Ceiling(self.CAS, AvailableMethods=True) self.Ceiling_source = self.Ceiling_sources[0] self.Skin_sources = Skin(self.CAS, AvailableMethods=True) self.Skin_source = self.Skin_sources[0] self.Carcinogen_sources = Carcinogen(self.CAS, AvailableMethods=True) self.Carcinogen_source = self.Carcinogen_sources[0] # Chemistry - currently molar self.Hf_sources = Hf(CASRN=self.CAS, AvailableMethods=True) self.Hf_source = self.Hf_sources[0] # Misc self.dipole_sources = dipole(CASRN=self.CAS, AvailableMethods=True) self.dipole_source = self.dipole_sources[0] # Environmental self.GWP_sources = GWP(CASRN=self.CAS, AvailableMethods=True) self.GWP_source = self.GWP_sources[0] self.ODP_sources = ODP(CASRN=self.CAS, AvailableMethods=True) self.ODP_source = self.ODP_sources[0] self.logP_sources = logP(CASRN=self.CAS, AvailableMethods=True) self.logP_source = self.logP_sources[0] # Legal self.legal_status_sources = legal_status(CASRN=self.CAS, AvailableMethods=True) self.legal_status_source = self.legal_status_sources[0] self.economic_status_sources = economic_status(CASRN=self.CAS, AvailableMethods=True) self.economic_status_source = self.economic_status_sources[0] # Analytical self.RI_sources = refractive_index(CASRN=self.CAS, AvailableMethods=True) self.RI_source = self.RI_sources[0] self.conductivity_sources = conductivity(CASRN=self.CAS, AvailableMethods=True) self.conductivity_source = self.conductivity_sources[0] def set_constants(self): self.Tm = Tm(self.CAS, Method=self.Tm_source) self.Tb = Tb(self.CAS, Method=self.Tb_source) # Critical Point self.Tc = Tc(self.CAS, Method=self.Tc_method) self.Pc = Pc(self.CAS, Method=self.Pc_method) self.Vc = Vc(self.CAS, Method=self.Vc_method) self.omega = omega(self.CAS, Method=self.omega_method) self.StielPolar_methods = StielPolar(Tc=self.Tc, Pc=self.Pc, omega=self.omega, CASRN=self.CAS, AvailableMethods=True) self.StielPolar_method = self.StielPolar_methods[0] self.StielPolar = StielPolar(Tc=self.Tc, Pc=self.Pc, omega=self.omega, CASRN=self.CAS, Method=self.StielPolar_method) self.Zc = Z(self.Tc, self.Pc, self.Vc) if all((self.Tc, self.Pc, self.Vc)) else None self.rhoC = Vm_to_rho(self.Vc, self.MW) if self.Vc else None self.rhoCm = 1./self.Vc if self.Vc else None # Triple point self.Pt = Pt(self.CAS, Method=self.Pt_source) self.Tt = Tt(self.CAS, Method=self.Tt_source) # Enthalpy self.Hfus = Hfus(T=self.T, P=self.P, MW=self.MW, Method=self.Hfus_method, CASRN=self.CAS) self.Hfusm = property_mass_to_molar(self.Hfus, self.MW) if self.Hfus else None # Chemistry self.Hf = Hf(CASRN=self.CAS, Method=self.Hf_source) self.Hc = Hcombustion(atoms=self.atoms, Hf=self.Hf) # Fire Safety Limits self.Tflash = Tflash(self.CAS, Method=self.Tflash_source) self.Tautoignition = Tautoignition(self.CAS, Method=self.Tautoignition_source) self.LFL_sources = LFL(atoms=self.atoms, Hc=self.Hc, CASRN=self.CAS, AvailableMethods=True) self.LFL_source = self.LFL_sources[0] self.UFL_sources = UFL(atoms=self.atoms, Hc=self.Hc, CASRN=self.CAS, AvailableMethods=True) self.UFL_source = self.UFL_sources[0] self.LFL = LFL(atoms=self.atoms, Hc=self.Hc, CASRN=self.CAS, Method=self.LFL_source) self.UFL = UFL(atoms=self.atoms, Hc=self.Hc, CASRN=self.CAS, Method=self.UFL_source) # Chemical Exposure Limits self.TWA = TWA(self.CAS, Method=self.TWA_source) self.STEL = STEL(self.CAS, Method=self.STEL_source) self.Ceiling = Ceiling(self.CAS, Method=self.Ceiling_source) self.Skin = Skin(self.CAS, Method=self.Skin_source) self.Carcinogen = Carcinogen(self.CAS, Method=self.Carcinogen_source) # Misc self.dipole = dipole(self.CAS, Method=self.dipole_source) # Units of Debye self.Stockmayer_sources = Stockmayer(Tc=self.Tc, Zc=self.Zc, omega=self.omega, AvailableMethods=True, CASRN=self.CAS) self.Stockmayer_source = self.Stockmayer_sources[0] self.Stockmayer = Stockmayer(Tm=self.Tm, Tb=self.Tb, Tc=self.Tc, Zc=self.Zc, omega=self.omega, Method=self.Stockmayer_source, CASRN=self.CAS) # Environmental self.GWP = GWP(CASRN=self.CAS, Method=self.GWP_source) self.ODP = ODP(CASRN=self.CAS, Method=self.ODP_source) self.logP = logP(CASRN=self.CAS, Method=self.logP_source) # Legal self.legal_status = legal_status(self.CAS, Method=self.legal_status_source) self.economic_status = economic_status(self.CAS, Method=self.economic_status_source) # Analytical self.RI, self.RIT = refractive_index(CASRN=self.CAS, Method=self.RI_source) self.conductivity, self.conductivityT = conductivity(CASRN=self.CAS, Method=self.conductivity_source) def set_T_sources(self): # Tempearture and Pressure Denepdence # Get and choose initial methods self.VaporPressure = VaporPressure(Tb=self.Tb, Tc=self.Tc, Pc=self.Pc, omega=self.omega, CASRN=self.CAS) self.Psat_298 = self.VaporPressure.T_dependent_property(298.15) self.VolumeLiquid = VolumeLiquid(MW=self.MW, Tb=self.Tb, Tc=self.Tc, Pc=self.Pc, Vc=self.Vc, Zc=self.Zc, omega=self.omega, dipole=self.dipole, Psat=self.VaporPressure.T_dependent_property, CASRN=self.CAS) self.Vml_Tb = self.VolumeLiquid.T_dependent_property(self.Tb) if self.Tb else None self.Vml_Tm = self.VolumeLiquid.T_dependent_property(self.Tm) if self.Tm else None self.Vml_STP = self.VolumeLiquid.T_dependent_property(298.15) # set molecular_diameter; depends on Vml_Tb, Vml_Tm self.molecular_diameter_sources = molecular_diameter(Tc=self.Tc, Pc=self.Pc, Vc=self.Vc, Zc=self.Zc, omega=self.omega, Vm=self.Vml_Tm, Vb=self.Vml_Tb, AvailableMethods=True, CASRN=self.CAS) self.molecular_diameter_source = self.molecular_diameter_sources[0] self.molecular_diameter = molecular_diameter(Tc=self.Tc, Pc=self.Pc, Vc=self.Vc, Zc=self.Zc, omega=self.omega, Vm=self.Vml_Tm, Vb=self.Vml_Tb, Method=self.molecular_diameter_source, CASRN=self.CAS) self.VolumeGas = VolumeGas(MW=self.MW, Tc=self.Tc, Pc=self.Pc, omega=self.omega, dipole=self.dipole, CASRN=self.CAS) self.VolumeSolid = VolumeSolid(CASRN=self.CAS, MW=self.MW, Tt=self.Tt) self.HeatCapacityGas = HeatCapacityGas(CASRN=self.CAS, MW=self.MW, similarity_variable=self.similarity_variable) self.HeatCapacitySolid = HeatCapacitySolid(MW=self.MW, similarity_variable=self.similarity_variable, CASRN=self.CAS) self.HeatCapacityLiquid = HeatCapacityLiquid(CASRN=self.CAS, MW=self.MW, similarity_variable=self.similarity_variable, Tc=self.Tc, omega=self.omega, Cpgm=self.HeatCapacityGas.T_dependent_property) self.EnthalpyVaporization = EnthalpyVaporization(CASRN=self.CAS, Tb=self.Tb, Tc=self.Tc, Pc=self.Pc, omega=self.omega, similarity_variable=self.similarity_variable) self.HvapTbm = self.EnthalpyVaporization.T_dependent_property(self.Tb) if self.Tb else None self.HvapTb = property_molar_to_mass(self.HvapTbm, self.MW) self.Hsub_methods = Hsub(T=self.T, P=self.P, MW=self.MW, AvailableMethods=True, CASRN=self.CAS) self.Hsub_method = self.Hsub_methods[0] self.ViscosityLiquid = ViscosityLiquid(CASRN=self.CAS, MW=self.MW, Tm=self.Tm, Tc=self.Tc, Pc=self.Pc, Vc=self.Vc, omega=self.omega, Psat=self.VaporPressure.T_dependent_property, Vml=self.VolumeLiquid.T_dependent_property) vmg_calc = lambda T : self.VolumeGas.TP_dependent_property(T, 101325) self.ViscosityGas = ViscosityGas(CASRN=self.CAS, MW=self.MW, Tc=self.Tc, Pc=self.Pc, Zc=self.Zc, dipole=self.dipole, Vmg=vmg_calc) self.ThermalConductivityLiquid = ThermalConductivityLiquid(CASRN=self.CAS, MW=self.MW, Tm=self.Tm, Tb=self.Tb, Tc=self.Tc, Pc=self.Pc, omega=self.omega, Hfus=self.Hfusm) cvgm_calc = lambda T : self.HeatCapacityGas.T_dependent_property(T) - R self.ThermalConductivityGas = ThermalConductivityGas(CASRN=self.CAS, MW=self.MW, Tb=self.Tb, Pc=self.Pc, Vc=self.Vc, Zc=self.Zc, omega=self.omega, dipole=self.dipole, Vmg=vmg_calc, Cvgm=cvgm_calc, mug=self.ViscosityGas.T_dependent_property) self.SurfaceTension = SurfaceTension(CASRN=self.CAS, Tb=self.Tb, Tc=self.Tc, Pc=self.Pc, Vc=self.Vc, Zc=self.Zc, omega=self.omega, StielPolar=self.StielPolar) self.Permittivity = Permittivity(CASRN=self.CAS) self.solubility_parameter_methods = solubility_parameter(T=self.T, Hvapm=self.HvapTbm, Vml=self.Vml_STP, AvailableMethods=True, CASRN=self.CAS) self.solubility_parameter_method = self.solubility_parameter_methods[0] def set_T(self, T=None): if T: self.T = T self.Psat = self.VaporPressure.T_dependent_property(T=self.T) self.Vms = self.VolumeSolid.T_dependent_property(T=self.T) self.rhos = Vm_to_rho(self.Vms, self.MW) if self.Vms else None self.rhosm = 1/self.Vms if self.Vms else None self.Zs = Z(self.T, self.P, self.Vms) if self.Vms else None self.Vml = self.VolumeLiquid.TP_dependent_property(self.T, self.P) # self.Vml = self.VolumeLiquid.T_dependent_property(self.T) if not self.Vml else self.Vml # TODO: derivative self.isobaric_expansion_l = isobaric_expansion(V1=self.Vml, dT=0.01, V2=self.VolumeLiquid.TP_dependent_property(self.T+0.01, self.P)) if not self.Vml: self.Vml = self.VolumeLiquid.T_dependent_property(self.T) self.isobaric_expansion_l = isobaric_expansion(V1=self.Vml, dT=0.01, V2=self.VolumeLiquid.T_dependent_property(self.T+0.01)) self.rhol = Vm_to_rho(self.Vml, self.MW) if self.Vml else None self.Zl = Z(self.T, self.P, self.Vml) if self.Vml else None self.rholm = 1./self.Vml if self.Vml else None self.Vmg = self.VolumeGas.TP_dependent_property(T=self.T, P=self.P) self.rhog = Vm_to_rho(self.Vmg, self.MW) if self.Vmg else None self.Zg = Z(self.T, self.P, self.Vmg) if self.Vmg else None self.rhogm = 1./self.Vmg if self.Vmg else None self.Bvirial = B_from_Z(self.Zg, self.T, self.P) if self.Vmg else None self.isobaric_expansion_g = isobaric_expansion(V1=self.Vmg, dT=0.01, V2=self.VolumeGas.TP_dependent_property(T=self.T+0.01, P=self.P)) self.Cpsm = self.HeatCapacitySolid.T_dependent_property(self.T) self.Cpgm = self.HeatCapacityGas.T_dependent_property(self.T) self.Cplm = self.HeatCapacityLiquid.T_dependent_property(self.T) self.Cpl = property_molar_to_mass(self.Cplm, self.MW) if self.Cplm else None self.Cps = property_molar_to_mass(self.Cpsm, self.MW) if self.Cpsm else None self.Cpg = property_molar_to_mass(self.Cpgm, self.MW) if self.Cpgm else None self.Cvgm = self.Cpgm - R if self.Cpgm else None self.Cvg = property_molar_to_mass(self.Cvgm, self.MW) if self.Cvgm else None self.isentropic_exponent = isentropic_exponent(self.Cpg, self.Cvg) if all((self.Cpg, self.Cvg)) else None self.Hvapm = self.EnthalpyVaporization.T_dependent_property(self.T) self.Hvap = property_molar_to_mass(self.Hvapm, self.MW) self.Hsub = Hsub(T=self.T, P=self.P, MW=self.MW, Method=self.Hsub_method, CASRN=self.CAS) self.Hsubm = property_mass_to_molar(self.Hsub, self.MW) self.mul = self.ViscosityLiquid.TP_dependent_property(self.T, self.P) if not self.mul: self.mul = self.ViscosityLiquid.T_dependent_property(self.T) self.mug = self.ViscosityGas.TP_dependent_property(self.T, self.P) if not self.mug: self.mug = self.ViscosityGas.T_dependent_property(self.T) self.kl = self.ThermalConductivityLiquid.TP_dependent_property(self.T, self.P) if not self.kl: self.kl = self.ThermalConductivityLiquid.T_dependent_property(self.T) self.kg = self.ThermalConductivityGas.TP_dependent_property(self.T, self.P) if not self.kg: self.kg = self.ThermalConductivityGas.T_dependent_property(self.T) self.sigma = self.SurfaceTension.T_dependent_property(self.T) self.permittivity = self.Permittivity.T_dependent_property(self.T) self.solubility_parameter = solubility_parameter(T=self.T, Hvapm=self.Hvapm, Vml=self.Vml, Method=self.solubility_parameter_method, CASRN=self.CAS) self.Parachor = Parachor(sigma=self.sigma, MW=self.MW, rhol=self.rhol, rhog=self.rhog) if all((self.sigma, self.MW, self.rhol, self.rhog)) else None self.JTl = JT(T=self.T, V=self.Vml, Cp=self.Cplm, isobaric_expansion=self.isobaric_expansion_l) self.JTg = JT(T=self.T, V=self.Vmg, Cp=self.Cpgm, isobaric_expansion=self.isobaric_expansion_g) self.nul = nu_mu_converter(mu=self.mul, rho=self.rhol) if all([self.mul, self.rhol]) else None self.nug = nu_mu_converter(mu=self.mug, rho=self.rhog) if all([self.mug, self.rhog]) else None self.Prl = Prandtl(Cp=self.Cpl, mu=self.mul, k=self.kl) if all([self.Cpl, self.mul, self.kl]) else None self.Prg = Prandtl(Cp=self.Cpg, mu=self.mug, k=self.kg) if all([self.Cpg, self.mug, self.kg]) else None self.alphal = thermal_diffusivity(k=self.kl, rho=self.rhol, Cp=self.Cpl) if all([self.kl, self.rhol, self.Cpl]) else None self.alphag = thermal_diffusivity(k=self.kg, rho=self.rhog, Cp=self.Cpg) if all([self.kg, self.rhog, self.Cpg]) else None self.set_phase() return True def set_phase(self): self.phase_STP = identify_phase(T=298.15, P=101325., Tm=self.Tm, Tb=self.Tb, Tc=self.Tc, Psat=self.Psat_298) self.phase = identify_phase(T=self.T, P=self.P, Tm=self.Tm, Tb=self.Tb, Tc=self.Tc, Psat=self.Psat) self.k = phase_set_property(phase=self.phase, s=None, l=self.kl, g=self.kg) # ks not implemented self.rho = phase_set_property(phase=self.phase, s=self.rhos, l=self.rhol, g=self.rhog) self.Vm = phase_set_property(phase=self.phase, s=self.Vms, l=self.Vml, g=self.Vmg) self.Z = Z(self.T, self.P, self.Vm) if self.Vm else None self.Cp = phase_set_property(phase=self.phase, s=self.Cps, l=self.Cpl, g=self.Cpg) self.Cpm = phase_set_property(phase=self.phase, s=self.Cpsm, l=self.Cplm, g=self.Cpgm) self.mu = phase_set_property(phase=self.phase, l=self.mul, g=self.mug) self.nu = phase_set_property(phase=self.phase, l=self.nul, g=self.nug) self.Pr = phase_set_property(phase=self.phase, l=self.Prl, g=self.Prg) self.alpha = phase_set_property(phase=self.phase, l=self.alphal, g=self.alphag) self.isobaric_expansion = phase_set_property(phase=self.phase, l=self.isobaric_expansion_l, g=self.isobaric_expansion_g) self.JT = phase_set_property(phase=self.phase, l=self.JTl, g=self.JTg) # TODO self.H = 0 self.Hm = 0 def Tsat(self, P): return self.VaporPressure.solve_prop(P) def Reynolds(self, V=None, D=None): return Reynolds(V=V, D=D, rho=self.rho, mu=self.mu) def Capillary(self, V=None): return Capillary(V=V, mu=self.mu, sigma=self.sigma) def Weber(self, V=None, D=None): return Weber(V=V, L=D, rho=self.rho, sigma=self.sigma) def Bond(self, L=None): return Bond(rhol=self.rhol, rhog=self.rhog, sigma=self.sigma, L=L) def Jakob(self, Tw=None): return Jakob(Cp=self.Cp, Hvap=self.Hvap, Te=Tw-self.T) def Grashof(self, Tw=None, L=None): return Grashof(L=L, beta=self.isobaric_expansion, T1=Tw, T2=self.T, rho=self.rho, mu=self.mu) def Peclet_heat(self, V=None, D=None): return Peclet_heat(V=V, L=D, rho=self.rho, Cp=self.Cp, k=self.k)
def Pt(CASRN, AvailableMethods=False, Method=None): r'''This function handles the retrieval of a chemical's triple pressure. Lookup is based on CASRNs. Will automatically select a data source to use if no Method is provided; returns None if the data is not available. Returns data from [1]_, or attempts to calculate the vapor pressure at the triple temperature, if data is available. Parameters ---------- CASRN : string CASRN [-] Returns ------- Pt : float Triple point pressure, [Pa] methods : list, only returned if AvailableMethods == True List of methods which can be used to obtain Pt with the given inputs Other Parameters ---------------- Method : string, optional A string for the method name to use, as defined by constants in Pt_methods AvailableMethods : bool, optional If True, function will determine which methods can be used to obtain the Pt for the desired chemical, and will return methods instead of the Pt Notes ----- Examples -------- Ammonia >>> Pt('7664-41-7') 6079.5 References ---------- .. [1] Staveley, L. A. K., L. Q. Lobo, and J. C. G. Calado. "Triple-Points of Low Melting Substances and Their Use in Cryogenic Work." Cryogenics 21, no. 3 (March 1981): 131-144. doi:10.1016/0011-2275(81)90264-2. ''' def list_methods(): methods = [] if CASRN in Staveley_data.index and not np.isnan( Staveley_data.at[CASRN, 'Pt']): methods.append(STAVELEY) if Tt(CASRN) and VaporPressure(CASRN=CASRN).T_dependent_property( T=Tt(CASRN)): methods.append(DEFINITION) methods.append(NONE) return methods if AvailableMethods: return list_methods() if not Method: Method = list_methods()[0] if Method == STAVELEY: Pt = Staveley_data.at[CASRN, 'Pt'] elif Method == DEFINITION: Pt = VaporPressure(CASRN=CASRN).T_dependent_property(T=Tt(CASRN)) elif Method == NONE: Pt = None else: raise Exception('Failure in in function') return Pt
def test_VolumeLiquidMixture_ExcessVolume(): # Excess volume # Vs -7.5E-7 in ddbst http://www.ddbst.com/en/EED/VE/VE0%20Ethanol%3BWater.php T = 298.15 P = 101325.0 MWs = [18.01528, 46.06844] zs = [1 - 0.15600, 0.15600] ws = zs_to_ws(zs, MWs) VaporPressures = [ VaporPressure(CASRN="7732-18-5", Tb=373.124, Tc=647.14, Pc=22048320.0, omega=0.344, extrapolation="AntoineAB|DIPPR101_ABC", method="WAGNER_MCGARRY"), VaporPressure(CASRN="64-17-5", Tb=351.39, Tc=514.0, Pc=6137000.0, omega=0.635, extrapolation="AntoineAB|DIPPR101_ABC", method="WAGNER_MCGARRY") ] drink = VolumeLiquidMixture(MWs=[18.01528, 46.06844], Tcs=[647.14, 514.0], Pcs=[22048320.0, 6137000.0], Vcs=[5.6000000000000006e-05, 0.000168], Zcs=[0.22947273972184645, 0.24125043269792065], omegas=[0.344, 0.635], CASs=['7732-18-5', '64-17-5'], correct_pressure_pure=True, method="LALIBERTE", VolumeLiquids=[ VolumeLiquid( CASRN="7732-18-5", MW=18.01528, Tb=373.124, Tc=647.14, Pc=22048320.0, Vc=5.6000000000000006e-05, Zc=0.22947273972184645, omega=0.344, dipole=1.85, Psat=VaporPressures[0], extrapolation="constant", method="VDI_PPDS", method_P="COSTALD_COMPRESSED"), VolumeLiquid(CASRN="64-17-5", MW=46.06844, Tb=351.39, Tc=514.0, Pc=6137000.0, Vc=0.000168, Zc=0.24125043269792065, omega=0.635, dipole=1.44, Psat=VaporPressures[1], extrapolation="constant", method="DIPPR_PERRY_8E", method_P="COSTALD_COMPRESSED") ]) V_Ex = drink.excess_property(T, P, zs, ws) assert_close(V_Ex, -7.242450496000289e-07, rtol=1e-12)
def test_VolumeLiquidMixture(): # from thermo.mixture import Mixture # m = Mixture(['benzene', 'toluene'], zs=[.5, .5], T=298.15, P=101325.) T, P, zs = 298.15, 101325.0, [0.5, 0.5] MWs = [78.11184, 92.13842] ws = zs_to_ws(zs, MWs=MWs) VaporPressures = [ VaporPressure(CASRN="71-43-2", Tb=353.23, Tc=562.05, Pc=4895000.0, omega=0.212, extrapolation="AntoineAB|DIPPR101_ABC", method=POLY_FIT, poly_fit=(278.68399999999997, 562.01, [ 4.547344107145341e-20, -1.3312501882259186e-16, 1.6282983902136683e-13, -1.0498233680158312e-10, 3.535838362096064e-08, -3.6181923213017173e-06, -0.001593607608896686, 0.6373679536454406, -64.4285974110459 ])), VaporPressure(CASRN="108-88-3", Tb=383.75, Tc=591.75, Pc=4108000.0, omega=0.257, extrapolation="AntoineAB|DIPPR101_ABC", method=POLY_FIT, poly_fit=(178.01, 591.74, [ -8.638045111752356e-20, 2.995512203611858e-16, -4.5148088801006036e-13, 3.8761537879200513e-10, -2.0856828984716705e-07, 7.279010846673517e-05, -0.01641020023565049, 2.2758331029405516, -146.04484159879843 ])) ] VolumeLiquids = [ VolumeLiquid(CASRN="71-43-2", MW=78.11184, Tb=353.23, Tc=562.05, Pc=4895000.0, Vc=0.000256, Zc=0.2681535335844513, omega=0.212, dipole=0.0, Psat=VaporPressures[0], extrapolation="constant", method=POLY_FIT, poly_fit=(278.68399999999997, 552.02, [ 2.5040222732960933e-22, -7.922607445206804e-19, 1.088548130214618e-15, -8.481605391952225e-13, 4.098451788397536e-10, -1.257577461969114e-07, 2.3927976459304723e-05, -0.0025810882828932375, 0.12092854717588034 ])), VolumeLiquid(CASRN="108-88-3", MW=92.13842, Tb=383.75, Tc=591.75, Pc=4108000.0, Vc=0.000316, Zc=0.2638426898300023, omega=0.257, dipole=0.33, Psat=VaporPressures[1], extrapolation="constant", method=POLY_FIT, poly_fit=(178.01, 581.75, [ 2.2801490297347937e-23, -6.411956871696508e-20, 7.723152902379232e-17, -5.197203733189603e-14, 2.1348482785660093e-11, -5.476649499770259e-09, 8.564670053875876e-07, -7.455178589434267e-05, 0.0028545812080104068 ])) ] obj = VolumeLiquidMixture(MWs=MWs, Tcs=[562.05, 591.75], Pcs=[4895000.0, 4108000.0], Vcs=[0.000256, 0.000316], Zcs=[0.2681535335844513, 0.2638426898300023], omegas=[0.212, 0.257], CASs=['71-43-2', '108-88-3'], VolumeLiquids=VolumeLiquids, correct_pressure_pure=False) hash0 = hash(obj) obj2 = VolumeLiquidMixture.from_json(json.loads(json.dumps(obj.as_json()))) assert obj == obj2 assert hash(obj) == hash0 assert hash(obj2) == hash0 obj2 = eval(str(obj)) assert obj == obj2 assert hash(obj) == hash0 assert hash(obj2) == hash0 Vml = 9.858773618507427e-05 assert_close(obj.calculate(T, P, zs, ws, COSTALD_MIXTURE), Vml, rtol=1e-11) obj.method = COSTALD_MIXTURE assert_close(obj(T, P, zs, ws), Vml, rtol=1e-11) Vml = 9.815400609778346e-05 assert_close(obj.calculate(T, P, zs, ws, COSTALD_MIXTURE_FIT), Vml, rtol=1e-11) obj.method = COSTALD_MIXTURE_FIT assert_close(obj(T, P, zs, ws), Vml, rtol=1e-11) Vml = 9.814047221052766e-05 assert_close(obj.calculate(T, P, zs, ws, LINEAR), Vml, rtol=1e-11) obj.method = LINEAR assert_close(obj(T, P, zs, ws), Vml, rtol=1e-11) Vml = 9.7377562180953e-05 assert_close(obj.calculate(T, P, zs, ws, RACKETT), Vml, rtol=1e-11) obj.method = RACKETT assert_close(obj(T, P, zs, ws), Vml, rtol=1e-11) Vml = 9.810986651973312e-05 assert_close(obj.calculate(T, P, zs, ws, RACKETT_PARAMETERS), Vml, rtol=1e-11) obj.method = RACKETT_PARAMETERS assert_close(obj(T, P, zs, ws), Vml, rtol=1e-11) # Unhappy paths with pytest.raises(Exception): obj.calculate(m.T, m.P, m.zs, m.ws, 'BADMETHOD') with pytest.raises(Exception): obj.test_method_validity(m.T, m.P, m.zs, m.ws, 'BADMETHOD')
def test_two_eos_pure_flash_all_properties(): # Methanol constants = ChemicalConstantsPackage( atom_fractions={ 'H': 0.6666666666666666, 'C': 0.16666666666666666, 'O': 0.16666666666666666 }, atomss=[{ 'H': 4, 'C': 1, 'O': 1 }], CASs=['67-56-1'], charges=[0], conductivities=[4.4e-05], dipoles=[1.7], formulas=['CH4O'], Gfgs=[-162000.13000000003], Gfgs_mass=[-5055890.325967345], Hcs=[-764464.0], Hcs_lower=[-676489.1], Hcs_lower_mass=[-21112666.368306957], Hcs_mass=[-23858290.373904638], Hfgs=[-200700.0], Hfgs_mass=[-6263681.321870828], Hfus_Tms=[3215.0000000000005], Hfus_Tms_mass=[100337.49601302797], Hvap_298s=[37486.47944178592], Hvap_298s_mass=[1169922.078237216], Hvap_Tbs=[35170.873821707064], Hvap_Tbs_mass=[1097653.9383702152], LFLs=[0.06], logPs=[-0.74], molecular_diameters=[3.7995699999999997], MWs=[32.04186], names=['methanol'], omegas=[0.5589999999999999], Parachors=[1.574169046057019e-05], Pcs=[8084000.0], phase_STPs=['l'], Psat_298s=[16905.960312551426], PSRK_groups=[{ 15: 1 }], Pts=[0.1758862695025245], PubChems=[887], rhocs=[8547.008547008547], rhocs_mass=[273.86205128205125], rhol_STPs=[24494.78614922483], rhol_STPs_mass=[784.8585085234012], RIs=[1.3288], S0gs=[239.9], S0gs_mass=[7487.080962216301], Sfgs=[-129.7999999999999], Sfgs_mass=[-4050.950849919446], similarity_variables=[0.18725504699165404], Skins=[True], smiless=['CO'], STELs=[(250.0, 'ppm')], StielPolars=[0.027243902847492674], Stockmayers=[685.96], Tautoignitions=[713.15], Tbs=[337.65], Tcs=[512.5], Tflashs=[282.15], Tms=[175.15], Tts=[175.59], UFLs=[0.36], UNIFAC_Dortmund_groups=[{ 15: 1 }], UNIFAC_groups=[{ 15: 1 }], Van_der_Waals_areas=[358000.0], Van_der_Waals_volumes=[2.1709787e-05], Vcs=[0.000117], Vml_STPs=[4.0825014511573776e-05], Vml_Tms=[3.541058756059562e-05], Zcs=[0.22196480200068586], UNIFAC_Rs=[1.4311], UNIFAC_Qs=[1.432], rhos_Tms=[1013.0221439813405], Vms_Tms=[3.162996997683616e-05], solubility_parameters=[29315.58469262365], Vml_60Fs=[4.033573571273147e-05], rhol_60Fs_mass=[794.3789652976724], rhol_60Fs=[24791.91174599953]) VaporPressures = [ VaporPressure(poly_fit=(175.7, 512.49, [ -1.446088049406911e-19, 4.565038519454878e-16, -6.278051259204248e-13, 4.935674274379539e-10, -2.443464113936029e-07, 7.893819658700523e-05, -0.016615779444332356, 2.1842496316772264, -134.19766175812708 ])), ] HeatCapacityGases = [ HeatCapacityGas(poly_fit=(50.0, 1000.0, [ 2.3511458696647882e-21, -9.223721411371584e-18, 1.3574178156001128e-14, -8.311274917169928e-12, 4.601738891380102e-10, 1.78316202142183e-06, -0.0007052056417063217, 0.13263597297874355, 28.44324970462924 ])), ] HeatCapacityLiquids = [ HeatCapacityLiquid(poly_fit=(180.0, 503.1, [ -5.042130764341761e-17, 1.3174414379504284e-13, -1.472202211288266e-10, 9.19934288272021e-08, -3.517841445216993e-05, 0.008434516406617465, -1.2381765320848312, 101.71442569958393, -3508.6245143327947 ])), ] VolumeLiquids = [ VolumeLiquid(poly_fit=(175.7, 502.5, [ 3.5725079384600736e-23, -9.031033742820083e-20, 9.819637959370411e-17, -5.993173551565636e-14, 2.2442465416964825e-11, -5.27776114586072e-09, 7.610461006178106e-07, -6.148574498547711e-05, 0.00216398089328537 ])), ] EnthalpyVaporizations = [ EnthalpyVaporization(poly_fit=(175.7, 512.499, 512.5, [ -0.004536133852590396, -0.2817551666837462, -7.344529282245696, -104.02286881045083, -860.5796142607192, -4067.8897875259267, -8952.300062896637, 2827.0089241465225, 44568.12528999141 ])), ] HeatCapacitySolids = [ HeatCapacitySolid(poly_fit=(1.0, 5000.0, [ -4.2547351607351175e-26, 9.58204543572984e-22, -8.928062818728625e-18, 4.438942190507877e-14, -1.2656161406049876e-10, 2.0651464217978594e-07, -0.0001691371394823046, 0.2038633833421581, -0.07254973910767148 ])), ] SublimationPressures = [ SublimationPressure(poly_fit=(61.5, 179.375, [ -1.9972190661146383e-15, 2.1648606414769645e-12, -1.0255776193312338e-09, 2.7846062954442135e-07, -4.771529410705124e-05, 0.005347189071525987, -0.3916553642749777, 18.072103851054266, -447.1556383160345 ])), ] EnthalpySublimations = [ EnthalpySublimation(poly_fit=(1.7515, 175.59, [ 2.3382707698778188e-17, -2.03890965442551e-12, 1.5374109464154768e-09, -4.640933157748743e-07, 6.931187040484687e-05, -0.004954625422589015, 0.045058888152305354, 32.52432385785916, 42213.605713250145 ])), ] VolumeSolids = [ VolumeSolid(poly_fit=(52.677, 175.59, [ 3.9379562779372194e-30, 1.4859309728437516e-27, 3.897856765862211e-24, 5.012758300685479e-21, 7.115820892078097e-18, 9.987967202910477e-15, 1.4030825662633013e-11, 1.970935889948393e-08, 2.7686131179275174e-05 ])), ] correlations = PropertyCorrelationsPackage( constants, VaporPressures=VaporPressures, HeatCapacityGases=HeatCapacityGases, HeatCapacityLiquids=HeatCapacityLiquids, VolumeLiquids=VolumeLiquids, EnthalpyVaporizations=EnthalpyVaporizations, HeatCapacitySolids=HeatCapacitySolids, SublimationPressures=SublimationPressures, EnthalpySublimations=EnthalpySublimations, VolumeSolids=VolumeSolids) eos_liquid = CEOSLiquid(PRMIX, dict(Tcs=constants.Tcs, Pcs=constants.Pcs, omegas=constants.omegas), HeatCapacityGases=HeatCapacityGases, Hfs=constants.Hfgs, Sfs=constants.Sfgs, Gfs=constants.Gfgs) gas = CEOSGas(PRMIX, dict(Tcs=constants.Tcs, Pcs=constants.Pcs, omegas=constants.omegas), HeatCapacityGases=HeatCapacityGases, Hfs=constants.Hfgs, Sfs=constants.Sfgs, Gfs=constants.Gfgs) # Pseudo vapor volume for eos gas? flasher = FlashPureVLS(constants, correlations, gas, [eos_liquid], []) # Test all the results T, VF = 300.0, 0.4 eq = flasher.flash(T=T, VF=VF) # Meta assert eq.phases[0] is eq.gas assert eq.phases[1] is eq.liquid0 assert eq.phase_count == 2 assert eq.liquid_count == 1 assert eq.gas_count == 1 assert eq.solid_count == 0 assert eq.zs == [1.0] # Phase fractions assert_close1d(eq.betas, [.4, .6], rtol=1e-12) assert_close1d(eq.betas_mass, [.4, .6], rtol=1e-12) assert_close1d(eq.betas_volume, [0.9994907285990579, 0.0005092714009421547], rtol=1e-12) assert_close(eq.T, T, rtol=1e-12) for phase in eq.phases: assert_close(phase.T, T, rtol=1e-12) P_eq_expect = 17641.849717291494 # Might change slightly in the future due to tolerance assert_close(eq.P, P_eq_expect, rtol=1e-9) for phase in eq.phases: assert_close(phase.P, eq.P, rtol=1e-12) # Mass and volume (liquid) fractions # Since liquid fraction does not make any sense, might as well use pure volumes. assert_close1d(eq.Vfls(), [1]) assert_close1d(eq.bulk.Vfls(), [1]) assert_close2d([eq.Vfls(phase) for phase in eq.phases], [[1], [1]]) assert_close1d(eq.Vfgs(), [1]) assert_close1d(eq.bulk.Vfgs(), [1]) assert_close2d([eq.Vfgs(phase) for phase in eq.phases], [[1], [1]]) assert_close1d(eq.ws(), [1]) assert_close1d(eq.bulk.ws(), [1]) assert_close2d([eq.ws(phase) for phase in eq.phases], [[1], [1]]) # H S G U A assert_close(eq.H(), -24104.760566193883, rtol=1e-12) assert_close(eq.bulk.H(), -24104.760566193883, rtol=1e-12) assert_close1d([i.H() for i in eq.phases], [51.18035762282534, -40208.72118207169], rtol=1e-12) assert_close(eq.S(), -65.77742662151137, rtol=1e-12) assert_close(eq.bulk.S(), -65.77742662151137, rtol=1e-12) assert_close1d([i.S() for i in eq.phases], [14.742376457877638, -119.45729534110404], rtol=1e-12) assert_close(eq.G(), -4371.532579740473, rtol=1e-12) assert_close(eq.bulk.G(), -4371.532579740473, rtol=1e-12) assert_close1d([i.G() for i in eq.phases], [-4371.532579740466, -4371.53257974048], rtol=1e-12) assert_close(eq.U(), -25098.583314964242, rtol=1e-12) assert_close(eq.bulk.U(), -25098.583314964242, rtol=1e-12) assert_close1d([i.U() for i in eq.phases], [-2432.11120054419, -40209.56472457761], rtol=1e-12) assert_close(eq.A(), -5365.355328510832, rtol=1e-12) assert_close(eq.bulk.A(), -5365.355328510832, rtol=1e-12) assert_close1d([i.A() for i in eq.phases], [-6854.824137907482, -4372.376122246402], rtol=1e-12) # Reactive H S G U A assert_close(eq.H_reactive(), -224804.7605661939, rtol=1e-12) assert_close(eq.bulk.H_reactive(), -224804.7605661939, rtol=1e-12) assert_close1d([i.H_reactive() for i in eq.phases], [-200648.81964237717, -240908.7211820717], rtol=1e-12) assert_close(eq.S_reactive(), -195.57742662151128, rtol=1e-12) assert_close(eq.bulk.S_reactive(), -195.57742662151128, rtol=1e-12) assert_close1d([i.S_reactive() for i in eq.phases], [-115.05762354212226, -249.25729534110394], rtol=1e-12) assert_close(eq.G_reactive(), -166131.5325797405, rtol=1e-12) assert_close(eq.bulk.G_reactive(), -166131.5325797405, rtol=1e-12) assert_close1d([i.G_reactive() for i in eq.phases], [-166131.5325797405] * 2, rtol=1e-12) assert_close(eq.U_reactive(), -225798.58331496426, rtol=1e-12) assert_close(eq.bulk.U_reactive(), -225798.58331496426, rtol=1e-12) assert_close1d([i.U_reactive() for i in eq.phases], [-203132.1112005442, -240909.56472457762], rtol=1e-12) assert_close(eq.A_reactive(), -167125.35532851086, rtol=1e-12) assert_close(eq.bulk.A_reactive(), -167125.35532851086, rtol=1e-12) assert_close1d([i.A_reactive() for i in eq.phases], [-168614.82413790753, -166132.37612224644], rtol=1e-12) # Mass H S G U A assert_close(eq.H_mass(), -752289.6787575341, rtol=1e-12) assert_close(eq.bulk.H_mass(), -752289.6787575341, rtol=1e-12) assert_close1d([i.H_mass() for i in eq.phases], [1597.2967119519697, -1254880.9957371918], rtol=1e-12) assert_close(eq.S_mass(), -2052.859185500198, rtol=1e-12) assert_close(eq.bulk.S_mass(), -2052.859185500198, rtol=1e-12) assert_close1d([i.S_mass() for i in eq.phases], [460.0973993980886, -3728.163575432389], rtol=1e-12) assert_close(eq.G_mass(), -136431.9231074748, rtol=1e-12) assert_close(eq.bulk.G_mass(), -136431.9231074748, rtol=1e-12) assert_close1d([i.G_mass() for i in eq.phases], [-136431.92310747458] * 2, rtol=1e-12) assert_close(eq.A_mass(), -167448.31069453622, rtol=1e-12) assert_close(eq.bulk.A_mass(), -167448.31069453622, rtol=1e-12) assert_close1d([i.A_mass() for i in eq.phases], [-213933.40267723164, -136458.24937273934], rtol=1e-12) assert_close(eq.U_mass(), -783306.0663445955, rtol=1e-12) assert_close(eq.bulk.U_mass(), -783306.0663445955, rtol=1e-12) assert_close1d([i.U_mass() for i in eq.phases], [-75904.18285780508, -1254907.322002456], rtol=1e-12) # Other assert_close(eq.MW(), 32.04186, rtol=1e-12) assert_close(eq.bulk.MW(), 32.04186, rtol=1e-12) assert_close1d([i.MW() for i in eq.phases], [32.04186, 32.04186], rtol=1e-12) # Volumetric assert_close(eq.rho_mass(), 0.568791245201322, rtol=1e-12) assert_close(eq.bulk.rho_mass(), 0.568791245201322, rtol=1e-12) assert_close1d([i.rho_mass() for i in eq.phases], [0.2276324247643884, 670.1235264525617], rtol=1e-12) assert_close(eq.V(), 0.05633325103071669, rtol=1e-12) assert_close(eq.bulk.V(), 0.05633325103071669, rtol=1e-12) assert_close1d([i.V() for i in eq.phases], [0.1407614052926116, 4.781485612006529e-05], rtol=1e-12) assert_close(eq.rho(), 17.75150522476916, rtol=1e-12) assert_close(eq.bulk.rho(), 17.75150522476916, rtol=1e-12) assert_close1d([i.rho() for i in eq.phases], [7.104220066013285, 20914.002072681225], rtol=1e-12) assert_close(eq.Z(), 0.3984313416321555, rtol=1e-12) assert_close(eq.bulk.Z(), 0.3984313416321555, rtol=1e-12) assert_close1d([i.Z() for i in eq.phases], [0.9955710798615588, 0.00033818281255378383], rtol=1e-12) assert_close(eq.V_mass(), 1.7581142614915828, rtol=1e-12) assert_close(eq.bulk.V_mass(), 1.7581142614915828, rtol=1e-12) assert_close1d([i.V_mass() for i in eq.phases], [4.393047260446541, 0.0014922621882770006], rtol=1e-12) # MW air may be adjusted in the future SG_gas_expect = 1.10647130731458 assert_close(eq.SG_gas(), SG_gas_expect, rtol=1e-5) assert_close(eq.bulk.SG_gas(), SG_gas_expect, rtol=1e-5) assert_close1d([i.SG_gas() for i in eq.phases], [SG_gas_expect] * 2, rtol=1e-5) assert_close(eq.SG(), 0.7951605425835767, rtol=1e-5) assert_close(eq.bulk.SG(), 0.7951605425835767, rtol=1e-5) assert_close1d([i.SG() for i in eq.phases], [0.7951605425835767] * 2, rtol=1e-5) # Cp and Cv related assert_close(eq.Cp(), 85.30634675113457, rtol=1e-12) assert_close(eq.bulk.Cp(), 85.30634675113457, rtol=1e-12) assert_close1d([i.Cp() for i in eq.phases], [44.63182543018587, 112.42269429843371], rtol=1e-12) assert_close(eq.Cp_mass(), 2662.340661595006, rtol=1e-12) assert_close(eq.bulk.Cp_mass(), 2662.340661595006, rtol=1e-12) assert_close1d([i.Cp_mass() for i in eq.phases], [1392.9224280421258, 3508.6194839635937], rtol=1e-12) assert_close(eq.Cv(), 65.77441970078021, rtol=1e-12) assert_close(eq.bulk.Cv(), 65.77441970078021, rtol=1e-12) assert_close1d([i.Cv() for i in eq.phases], [36.18313355107219, 79.87072617335762], rtol=1e-12) assert_close(eq.Cp_Cv_ratio(), 1.2969532401685737, rtol=1e-12) assert_close(eq.bulk.Cp_Cv_ratio(), 1.2969532401685737, rtol=1e-12) assert_close1d([i.Cp_Cv_ratio() for i in eq.phases], [1.2334980707845113, 1.4075581841389895], rtol=1e-12) assert_close(eq.Cv_mass(), 2052.765341986396, rtol=1e-12) assert_close(eq.bulk.Cv_mass(), 2052.765341986396, rtol=1e-12) assert_close1d([i.Cv_mass() for i in eq.phases], [1129.2457289018862, 2492.699430474936], rtol=1e-12) # ideal gas properties assert_close(eq.V_ideal_gas(), 0.14138759968016104, rtol=1e-12) assert_close(eq.bulk.V_ideal_gas(), 0.14138759968016104, rtol=1e-12) assert_close1d([i.V_ideal_gas() for i in eq.phases], [0.14138759968016104] * 2, rtol=1e-12) assert_close(eq.Cp_ideal_gas(), 44.47452555993428, rtol=1e-12) assert_close(eq.bulk.Cp_ideal_gas(), 44.47452555993428, rtol=1e-12) assert_close1d([i.Cp_ideal_gas() for i in eq.phases], [44.47452555993428] * 2, rtol=1e-12) assert_close(eq.Cv_ideal_gas(), 36.160062941781035, rtol=1e-12) assert_close(eq.bulk.Cv_ideal_gas(), 36.160062941781035, rtol=1e-12) assert_close1d([i.Cv_ideal_gas() for i in eq.phases], [36.160062941781035] * 2, rtol=1e-12) assert_close(eq.Cp_Cv_ratio_ideal_gas(), 1.229934959779794, rtol=1e-12) assert_close(eq.bulk.Cp_Cv_ratio_ideal_gas(), 1.229934959779794, rtol=1e-12) assert_close1d([i.Cp_Cv_ratio_ideal_gas() for i in eq.phases], [1.229934959779794] * 2, rtol=1e-12) assert_close(eq.H_ideal_gas(), 82.17715909331491, rtol=1e-12) assert_close(eq.bulk.H_ideal_gas(), 82.17715909331491, rtol=1e-12) assert_close1d([i.H_ideal_gas() for i in eq.phases], [82.17715909331491] * 2, rtol=1e-12) assert_close(eq.S_ideal_gas(), 14.808945043469695, rtol=1e-12) assert_close(eq.bulk.S_ideal_gas(), 14.808945043469695, rtol=1e-12) assert_close1d([i.S_ideal_gas() for i in eq.phases], [14.808945043469695] * 2, rtol=1e-12) assert_close(eq.G_ideal_gas(), -4360.506353947593, rtol=1e-12) assert_close(eq.bulk.G_ideal_gas(), -4360.506353947593, rtol=1e-12) assert_close1d([i.G_ideal_gas() for i in eq.phases], [-4360.506353947593] * 2, rtol=1e-12) assert_close(eq.A_ideal_gas(), -6854.845139393565, rtol=1e-12) assert_close(eq.bulk.A_ideal_gas(), -6854.845139393565, rtol=1e-12) assert_close1d([i.A_ideal_gas() for i in eq.phases], [-6854.845139393565] * 2, rtol=1e-12) assert_close(eq.U_ideal_gas(), -2412.161626352657, rtol=1e-12) assert_close(eq.bulk.U_ideal_gas(), -2412.161626352657, rtol=1e-12) assert_close1d([i.U_ideal_gas() for i in eq.phases], [-2412.161626352657] * 2, rtol=1e-12) # Ideal formation basis assert_close(eq.H_formation_ideal_gas(), -200700.0, rtol=1e-12) assert_close(eq.bulk.H_formation_ideal_gas(), -200700.0, rtol=1e-12) assert_close1d([i.H_formation_ideal_gas() for i in eq.phases], [-200700.0] * 2, rtol=1e-12) assert_close(eq.S_formation_ideal_gas(), -129.8, rtol=1e-12) assert_close(eq.bulk.S_formation_ideal_gas(), -129.8, rtol=1e-12) assert_close1d([i.S_formation_ideal_gas() for i in eq.phases], [-129.8] * 2, rtol=1e-12) assert_close(eq.G_formation_ideal_gas(), -162000.13, rtol=1e-12) assert_close(eq.bulk.G_formation_ideal_gas(), -162000.13, rtol=1e-12) assert_close1d([i.G_formation_ideal_gas() for i in eq.phases], [-162000.13] * 2, rtol=1e-12) assert_close(eq.U_formation_ideal_gas(), -215026.0985375923, rtol=1e-12) assert_close(eq.bulk.U_formation_ideal_gas(), -215026.0985375923, rtol=1e-12) assert_close1d([i.U_formation_ideal_gas() for i in eq.phases], [-215026.0985375923] * 2, rtol=1e-12) assert_close(eq.A_formation_ideal_gas(), -176326.22853759234, rtol=1e-12) assert_close(eq.bulk.A_formation_ideal_gas(), -176326.22853759234, rtol=1e-12) assert_close1d([i.A_formation_ideal_gas() for i in eq.phases], [-176326.22853759234] * 2, rtol=1e-12) # Pseudo critical properties assert_close(eq.pseudo_Tc(), constants.Tcs[0], rtol=1e-12) assert_close(eq.bulk.pseudo_Tc(), constants.Tcs[0], rtol=1e-12) assert_close1d([i.pseudo_Tc() for i in eq.phases], [constants.Tcs[0]] * 2, rtol=1e-12) assert_close(eq.pseudo_Pc(), constants.Pcs[0], rtol=1e-12) assert_close(eq.bulk.pseudo_Pc(), constants.Pcs[0], rtol=1e-12) assert_close1d([i.pseudo_Pc() for i in eq.phases], [constants.Pcs[0]] * 2, rtol=1e-12) assert_close(eq.pseudo_Vc(), constants.Vcs[0], rtol=1e-12) assert_close(eq.bulk.pseudo_Vc(), constants.Vcs[0], rtol=1e-12) assert_close1d([i.pseudo_Vc() for i in eq.phases], [constants.Vcs[0]] * 2, rtol=1e-12) assert_close(eq.pseudo_Zc(), constants.Zcs[0], rtol=1e-12) assert_close(eq.bulk.pseudo_Zc(), constants.Zcs[0], rtol=1e-12) assert_close1d([i.pseudo_Zc() for i in eq.phases], [constants.Zcs[0]] * 2, rtol=1e-12) # Standard volumes V_std_expect = 0.023690417461829063 assert_close(eq.V_gas_standard(), V_std_expect, rtol=1e-12) assert_close(eq.bulk.V_gas_standard(), V_std_expect, rtol=1e-12) assert_close1d([i.V_gas_standard() for i in eq.phases], [V_std_expect] * 2, rtol=1e-12) V_std_expect = 0.02364483003622853 assert_close(eq.V_gas_normal(), V_std_expect, rtol=1e-12) assert_close(eq.bulk.V_gas_normal(), V_std_expect, rtol=1e-12) assert_close1d([i.V_gas_normal() for i in eq.phases], [V_std_expect] * 2, rtol=1e-12) # Combustion properties Hc_expect = -764464.0 assert_close(eq.Hc(), Hc_expect, rtol=1e-12) assert_close(eq.bulk.Hc(), Hc_expect, rtol=1e-12) assert_close1d([i.Hc() for i in eq.phases], [Hc_expect] * 2, rtol=1e-12) Hc_mass_expect = -23858290.373904638 assert_close(eq.Hc_mass(), Hc_mass_expect, rtol=1e-12) assert_close(eq.bulk.Hc_mass(), Hc_mass_expect, rtol=1e-12) assert_close1d([i.Hc_mass() for i in eq.phases], [Hc_mass_expect] * 2, rtol=1e-12) Hc_lower_expect = -676489.1 assert_close(eq.Hc_lower(), Hc_lower_expect, rtol=1e-12) assert_close(eq.bulk.Hc_lower(), Hc_lower_expect, rtol=1e-12) assert_close1d([i.Hc_lower() for i in eq.phases], [Hc_lower_expect] * 2, rtol=1e-12) Hc_lower_mass_expect = -21112666.368306957 assert_close(eq.Hc_lower_mass(), Hc_lower_mass_expect, rtol=1e-12) assert_close(eq.bulk.Hc_lower_mass(), Hc_lower_mass_expect, rtol=1e-12) assert_close1d([i.Hc_lower_mass() for i in eq.phases], [Hc_lower_mass_expect] * 2, rtol=1e-12) # Volume combustion properties Hc_normal_expect = -32331126.881804217 assert_close(eq.Hc_normal(), Hc_normal_expect, rtol=1e-12) assert_close(eq.bulk.Hc_normal(), Hc_normal_expect, rtol=1e-12) assert_close1d([i.Hc_normal() for i in eq.phases], [Hc_normal_expect] * 2, rtol=1e-12) Hc_standard_expect = -32268912.155378208 assert_close(eq.Hc_standard(), Hc_standard_expect, rtol=1e-12) assert_close(eq.bulk.Hc_standard(), Hc_standard_expect, rtol=1e-12) assert_close1d([i.Hc_standard() for i in eq.phases], [Hc_standard_expect] * 2, rtol=1e-12) Hc_lower_normal_expect = -28610444.607277177 assert_close(eq.Hc_lower_normal(), Hc_lower_normal_expect, rtol=1e-12) assert_close(eq.bulk.Hc_lower_normal(), Hc_lower_normal_expect, rtol=1e-12) assert_close1d([i.Hc_lower_normal() for i in eq.phases], [Hc_lower_normal_expect] * 2, rtol=1e-12) Hc_lower_standard_expect = -28555389.582728375 assert_close(eq.Hc_lower_standard(), Hc_lower_standard_expect, rtol=1e-12) assert_close(eq.bulk.Hc_lower_standard(), Hc_lower_standard_expect, rtol=1e-12) assert_close1d([i.Hc_lower_standard() for i in eq.phases], [Hc_lower_standard_expect] * 2, rtol=1e-12) # Wobbe index Wobbe_index_expect = 726753.2127139702 assert_close(eq.Wobbe_index(), Wobbe_index_expect, rtol=1e-12) assert_close(eq.bulk.Wobbe_index(), Wobbe_index_expect, rtol=1e-12) assert_close1d([i.Wobbe_index() for i in eq.phases], [Wobbe_index_expect] * 2, rtol=1e-12) Wobbe_index_lower_expect = 643118.0890022058 assert_close(eq.Wobbe_index_lower(), Wobbe_index_lower_expect, rtol=1e-12) assert_close(eq.bulk.Wobbe_index_lower(), Wobbe_index_lower_expect, rtol=1e-12) assert_close1d([i.Wobbe_index_lower() for i in eq.phases], [Wobbe_index_lower_expect] * 2, rtol=1e-12) Wobbe_index_mass_expect = 22681367.83301501 assert_close(eq.Wobbe_index_mass(), Wobbe_index_mass_expect, rtol=1e-12) assert_close(eq.bulk.Wobbe_index_mass(), Wobbe_index_mass_expect, rtol=1e-12) assert_close1d([i.Wobbe_index_mass() for i in eq.phases], [Wobbe_index_mass_expect] * 2, rtol=1e-12) Wobbe_index_lower_mass_expect = 20071184.6628818 assert_close(eq.Wobbe_index_lower_mass(), Wobbe_index_lower_mass_expect, rtol=1e-12) assert_close(eq.bulk.Wobbe_index_lower_mass(), Wobbe_index_lower_mass_expect, rtol=1e-12) assert_close1d([i.Wobbe_index_lower_mass() for i in eq.phases], [Wobbe_index_lower_mass_expect] * 2, rtol=1e-12) # Wobbe index volume properties Wobbe_index_standard_expect = 30677096.082622595 assert_close(eq.Wobbe_index_standard(), Wobbe_index_standard_expect, rtol=1e-12) assert_close(eq.bulk.Wobbe_index_standard(), Wobbe_index_standard_expect, rtol=1e-12) assert_close1d([i.Wobbe_index_standard() for i in eq.phases], [Wobbe_index_standard_expect] * 2, rtol=1e-12) Wobbe_index_normal_expect = 30736241.774647623 assert_close(eq.Wobbe_index_normal(), Wobbe_index_normal_expect, rtol=1e-12) assert_close(eq.bulk.Wobbe_index_normal(), Wobbe_index_normal_expect, rtol=1e-12) assert_close1d([i.Wobbe_index_normal() for i in eq.phases], [Wobbe_index_normal_expect] * 2, rtol=1e-12) Wobbe_index_lower_standard_expect = 27146760.50088282 assert_close(eq.Wobbe_index_lower_standard(), Wobbe_index_lower_standard_expect, rtol=1e-12) assert_close(eq.bulk.Wobbe_index_lower_standard(), Wobbe_index_lower_standard_expect, rtol=1e-12) assert_close1d([i.Wobbe_index_lower_standard() for i in eq.phases], [Wobbe_index_lower_standard_expect] * 2, rtol=1e-12) Wobbe_index_lower_normal_expect = 27199099.677046627 assert_close(eq.Wobbe_index_lower_normal(), Wobbe_index_lower_normal_expect, rtol=1e-12) assert_close(eq.bulk.Wobbe_index_lower_normal(), Wobbe_index_lower_normal_expect, rtol=1e-12) assert_close1d([i.Wobbe_index_lower_normal() for i in eq.phases], [Wobbe_index_lower_normal_expect] * 2, rtol=1e-12) # Mechanical critical point - these have an inner solver Tmc_expect = 512.5 assert_close(eq.Tmc(), Tmc_expect, rtol=1e-12) assert_close(eq.bulk.Tmc(), Tmc_expect, rtol=1e-12) assert_close1d([i.Tmc() for i in eq.phases], [Tmc_expect] * 2, rtol=1e-12) Pmc_expect = 8084000.0 assert_close(eq.Pmc(), Pmc_expect, rtol=1e-12) assert_close(eq.bulk.Pmc(), Pmc_expect, rtol=1e-12) assert_close1d([i.Pmc() for i in eq.phases], [Pmc_expect] * 2, rtol=1e-12) # The solver tolerance here is loose Vmc_expect = 0.00016203642168563802 assert_close(eq.Vmc(), Vmc_expect, rtol=1e-4) assert_close(eq.bulk.Vmc(), Vmc_expect, rtol=1e-4) assert_close1d([i.Vmc() for i in eq.phases], [Vmc_expect] * 2, rtol=1e-4) # The solver tolerance here is loose Zmc_expect = 0.30740497655001947 assert_close(eq.Zmc(), Zmc_expect, rtol=1e-4) assert_close(eq.bulk.Zmc(), Zmc_expect, rtol=1e-4) assert_close1d([i.Zmc() for i in eq.phases], [Zmc_expect] * 2, rtol=1e-4) # Properties calculated form derivatives assert_close(eq.isobaric_expansion(), 0.002008218029645217, rtol=1e-12) assert_close(eq.bulk.isobaric_expansion(), 0.002008218029645217, rtol=1e-12) assert_close1d([i.isobaric_expansion() for i in eq.phases], [0.0033751089225799308, 0.0010969574343554077], rtol=1e-12) assert_close(eq.kappa(), 2.277492845010776e-05, rtol=1e-12) assert_close(eq.bulk.kappa(), 2.277492845010776e-05, rtol=1e-12) assert_close1d([i.kappa() for i in eq.phases], [5.693652573977374e-05, 5.302569971013028e-10], rtol=1e-12) assert_close(eq.Joule_Thomson(), 1.563918814309498e-05, rtol=1e-12) assert_close(eq.bulk.Joule_Thomson(), 1.563918814309498e-05, rtol=1e-12) assert_close1d([i.Joule_Thomson() for i in eq.phases], [3.9525992445522226e-05, -2.853480585231828e-07], rtol=1e-12) assert_close(eq.speed_of_sound(), 235.8471087474984, rtol=1e-12) assert_close(eq.bulk.speed_of_sound(), 235.8471087474984, rtol=1e-12) assert_close1d([i.speed_of_sound() for i in eq.phases], [55.22243501081154, 356.26355790528964], rtol=1e-12) assert_close(eq.speed_of_sound_mass(), 1317.5639311230432, rtol=1e-12) assert_close(eq.bulk.speed_of_sound_mass(), 1317.5639311230432, rtol=1e-12) assert_close1d([i.speed_of_sound_mass() for i in eq.phases], [308.5010833731638, 1990.2724962896298], rtol=1e-12) # Departure properties assert_close(eq.H_dep(), -24186.9377252872, rtol=1e-12) assert_close(eq.bulk.H_dep(), -24186.9377252872, rtol=1e-12) assert_close1d([i.H_dep() for i in eq.phases], [-30.99680147049139, -40290.898341165004], rtol=1e-12) assert_close(eq.S_dep(), -80.58637166498106, rtol=1e-12) assert_close(eq.bulk.S_dep(), -80.58637166498106, rtol=1e-12) assert_close1d([i.S_dep() for i in eq.phases], [-0.0665685855920503, -134.26624038457373], rtol=1e-12) assert_close(eq.G_dep(), -11.026225792880723, rtol=1e-9) assert_close(eq.bulk.G_dep(), -11.026225792880723, rtol=1e-9) assert_close1d([i.G_dep() for i in eq.phases], [-11.026225792876303, -11.026225792884361], rtol=1e-9) assert_close(eq.U_dep(), -22686.421688611586, rtol=1e-9) assert_close(eq.bulk.U_dep(), -22686.421688611586, rtol=1e-9) assert_close1d([i.U_dep() for i in eq.phases], [-19.949574191534843, -37797.40309822495], rtol=1e-9) assert_close(eq.A_dep(), 1489.4898108827329, rtol=1e-9) assert_close(eq.bulk.A_dep(), 1489.4898108827329, rtol=1e-9) assert_close1d([i.A_dep() for i in eq.phases], [0.021001486080244547, 2482.4690171471666], rtol=1e-9) assert_close(eq.Cp_dep(), 40.83182119120029, rtol=1e-9) assert_close(eq.bulk.Cp_dep(), 40.83182119120029, rtol=1e-9) assert_close1d([i.Cp_dep() for i in eq.phases], [0.1572998702515953, 67.94816873849943], rtol=1e-9) assert_close(eq.Cv_dep(), 29.61435675899918, rtol=1e-12) assert_close(eq.bulk.Cv_dep(), 29.61435675899918, rtol=1e-12) assert_close1d([i.Cv_dep() for i in eq.phases], [0.023070609291153232, 43.71066323157659], rtol=1e-12) # Standard liquid density rho_mass_liquid_ref_expect = 784.8585085234012 assert_close(eq.rho_mass_liquid_ref(), rho_mass_liquid_ref_expect, rtol=1e-12) assert_close(eq.bulk.rho_mass_liquid_ref(), rho_mass_liquid_ref_expect, rtol=1e-12) assert_close1d([i.rho_mass_liquid_ref() for i in eq.phases], [rho_mass_liquid_ref_expect] * 2, rtol=1e-12) V_liquid_ref_expect = 4.0825014511573776e-05 assert_close(eq.V_liquid_ref(), V_liquid_ref_expect, rtol=1e-12) assert_close(eq.bulk.V_liquid_ref(), V_liquid_ref_expect, rtol=1e-12) assert_close1d([i.V_liquid_ref() for i in eq.phases], [V_liquid_ref_expect] * 2, rtol=1e-12) # Water contect assert_close(eq.molar_water_content(), 0, atol=0) assert_close(eq.bulk.molar_water_content(), 0, atol=0) assert_close1d([i.molar_water_content() for i in eq.phases], [0] * 2, atol=0) assert_close1d(eq.zs_no_water(), [1], atol=0) assert_close1d(eq.bulk.zs_no_water(), [1], atol=0) assert_close2d([i.zs_no_water() for i in eq.phases], [[1.0]] * 2, atol=0) assert_close1d(eq.ws_no_water(), [1], atol=0) assert_close1d(eq.bulk.ws_no_water(), [1], atol=0) assert_close2d([i.ws_no_water() for i in eq.phases], [[1.0]] * 2, atol=0) # H/C ratio assert_close(eq.H_C_ratio(), 4, atol=0) assert_close(eq.bulk.H_C_ratio(), 4, atol=0) assert_close1d([i.H_C_ratio() for i in eq.phases], [4] * 2, atol=0) assert_close(eq.H_C_ratio_mass(), 0.3356806847227889, rtol=1e-12) assert_close(eq.bulk.H_C_ratio_mass(), 0.3356806847227889, rtol=1e-12) assert_close1d([i.H_C_ratio_mass() for i in eq.phases], [0.3356806847227889] * 2, rtol=1e-12)