def test_ThermalConductivityLiquidMixture(): from thermo.thermal_conductivity import MAGOMEDOV, DIPPR_9H, FILIPPOV, SIMPLE, ThermalConductivityLiquidMixture m = Mixture(['ethanol', 'pentanol'], ws=[0.258, 0.742], T=298.15) ThermalConductivityLiquids = [i.ThermalConductivityLiquid for i in m.Chemicals] kl_mix = ThermalConductivityLiquidMixture(CASs=m.CASs, ThermalConductivityLiquids=ThermalConductivityLiquids) k = kl_mix.mixture_property(m.T, m.P, m.zs, m.ws) assert_allclose(k, 0.15300152782218343) k = kl_mix.calculate(m.T, m.P, m.zs, m.ws, FILIPPOV) assert_allclose(k, 0.15522139770330717) k = kl_mix.calculate(m.T, m.P, m.zs, m.ws, SIMPLE) assert_allclose(k, 0.1552717795028546) # Test electrolytes m = Mixture(['water', 'sulfuric acid'], ws=[.5, .5], T=298.15) ThermalConductivityLiquids = [i.ThermalConductivityLiquid for i in m.Chemicals] kl_mix = ThermalConductivityLiquidMixture(CASs=m.CASs, ThermalConductivityLiquids=ThermalConductivityLiquids) k = kl_mix.mixture_property(m.T, m.P, m.zs, m.ws) assert_allclose(k, 0.4677453168207703) assert kl_mix.sorted_valid_methods == [MAGOMEDOV] # Unhappy paths with pytest.raises(Exception): kl_mix.calculate(m.T, m.P, m.zs, m.ws, 'BADMETHOD') with pytest.raises(Exception): kl_mix.test_method_validity(m.T, m.P, m.zs, m.ws, 'BADMETHOD')
def test_ViscosityLiquidMixture(): # DIPPR 1983 manual example m = Mixture(['carbon tetrachloride', 'isopropanol'], zs=[0.5, 0.5], T=313.2) ViscosityLiquids = [i.ViscosityLiquid for i in m.Chemicals] obj = ViscosityLiquidMixture(ViscosityLiquids=ViscosityLiquids, CASs=m.CASs) mu = obj.mixture_property(m.T, m.P, m.zs, m.ws) assert_allclose(mu, 0.0009956952502281852) mu = obj.calculate(m.T, m.P, m.zs, m.ws, MIXING_LOG_MOLAR) assert_allclose(mu, 0.0009956952502281852) mu = obj.calculate(m.T, m.P, m.zs, m.ws, MIXING_LOG_MASS) assert_allclose(mu, 0.0008741268796817256) # Test Laliberte m = Mixture(['water', 'sulfuric acid'], zs=[0.5, 0.5], T=298.15) ViscosityLiquids = [i.ViscosityLiquid for i in m.Chemicals] obj = ViscosityLiquidMixture(ViscosityLiquids=ViscosityLiquids, CASs=m.CASs) mu = obj.mixture_property(m.T, m.P, m.zs, m.ws) assert_allclose(mu, 0.024955325569420893) assert obj.sorted_valid_methods == [LALIBERTE_MU] # 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_real_residue_gas_dry_heating_value(self): self.compounds = [ 'methane', 'ethane', 'propane', 'i_butane', 'n_butane', 'i_pentane', 'n_pentane', 'hexane_plus', 'hydrogen_sulfide' ] self.mole_fractions = [0.2, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1] self.recovery_factors = [ 0.0, 0.75, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.0 ] self.composition = list( zip(self.compounds, self.mole_fractions, self.recovery_factors)) self.property_package = PropertyPackage(self.library, self.composition) results = Mixture(self.property_package, self.temperature, self.pressure, self.volume).real_residue_gas_dry_heating_value( self.hydrogen_sulfide) self.assertTrue( abs(results - 1163.9761) < settings.FLOAT_COMPARE_TOLERANCE) results = Mixture( self.property_package, self.temperature, self.pressure, self.volume).real_residue_gas_dry_heating_value(False) self.assertTrue( abs(results - 1369.9023) < settings.FLOAT_COMPARE_TOLERANCE) results = Mixture( self.property_package, self.temperature, 14.65, self.volume).real_residue_gas_dry_heating_value(False) self.assertTrue( abs(results - 1365.1853) < settings.FLOAT_COMPARE_TOLERANCE) return
def test_Mixture(): Mixture(['water', 'ethanol'], ws=[.5, .5], T=320, P=1E5) Mixture(['water', 'phosphoric acid'], ws=[.5, .5], T=320, P=1E5) Mixture('air', T=320, P=1E5) Mixture(['ethanol', 'water'], ws=[0.5, 0.5], T=500) Mixture('water')
def test_mixtures_from_property_calcs(): m = Mixture(['carbon tetrachloride', 'isopropanol'], zs=[0.5, 0.5], T=313.2) m = Mixture(['oxygen', 'nitrogen'], ws=[.4, .6], T=350, P=1E6) m = Mixture(['water', 'sodium chloride'], ws=[.9, .1], T=301.5) m = Mixture(['toluene', 'decane'], ws=[.9, .1], T=300)
def initialize(): global Pdepth, Thot, Tcold, rhoHot, rhoCold Pdepth = 1000 * 9.806 * depth Thot = Tsurface - dTfinal Tcold = Tdeep + dTfinal air = Mixture('air', T=Thot, P=Pdepth) rhoHot = air.rho air = Mixture('air', T=Tcold, P=Pdepth) rhoCold = air.rho
def test_compressibility_factor(self): results = Mixture(self.property_package, self.temperature, self.pressure, self.volume).compressibility_factor() self.assertTrue( abs(results - 0.9954) < settings.FLOAT_COMPARE_TOLERANCE) results = Mixture(self.property_package, self.temperature, 15.0, self.volume).compressibility_factor() self.assertTrue( abs(results - 0.9953) < settings.FLOAT_COMPARE_TOLERANCE) return
def test_Mixture_input_basics(): # Run a test initializing a mixture from mole fractions, mass fractions, # liquid fractions, gas fractions (liq/gas are with volumes of pure components at T and P) kwargs = {'ws': [0.5, 0.5], 'zs': [0.7188789914193495, 0.2811210085806504], 'Vfls': [0.44054617180108374, 0.5594538281989162], 'Vfgs': [0.7188789914193495, 0.2811210085806504]} for key, val in kwargs.items(): m = Mixture(['water', 'ethanol'], **{key:val}) assert_close1d(m.zs, kwargs['zs'], rtol=1E-6) assert_close1d(m.zs, m.xs) assert_close1d(m.Vfls(), kwargs['Vfls'], rtol=1E-5) assert_close1d(m.Vfgs(), kwargs['Vfgs'])
def test_Mixture_input_odds_and_ends(): with pytest.raises(Exception): Mixture(['water', 'ethanol']) Mixture(['water'], ws=[1], T=300, P=1E5) Mixture('water', ws=[1], T=365).SGl # Define the composition for a pure compound to be 1 if not specified Mixture(['ethylene oxide']) # Flash failed BC P not specified - maybe should raise exception here Mixture('air', VF=0.5)
def test_VolumeLiquidMixture(): from thermo.mixture import Mixture from thermo.volume import LALIBERTE, COSTALD_MIXTURE_FIT, RACKETT_PARAMETERS, COSTALD_MIXTURE, SIMPLE, RACKETT m = Mixture(['benzene', 'toluene'], zs=[.5, .5], T=298.15, P=101325.) VolumeLiquids = [i.VolumeLiquid for i in m.Chemicals] obj = VolumeLiquidMixture(MWs=m.MWs, Tcs=m.Tcs, Pcs=m.Pcs, Vcs=m.Vcs, Zcs=m.Zcs, omegas=m.omegas, CASs=m.CASs, VolumeLiquids=VolumeLiquids) Vm = obj.mixture_property(m.T, m.P, m.zs, m.ws) assert_allclose(Vm, 9.814092676573469e-05) Vms = [ obj.calculate(m.T, m.P, m.zs, m.ws, method) for method in obj.all_methods ] Vms_expect = [ 9.814092676573469e-05, 9.737758899339708e-05, 9.8109833265793461e-05, 9.8154006097783393e-05, 9.858773618507426e-05 ] assert_allclose(sorted(Vms), sorted(Vms_expect)) # Test Laliberte m = Mixture(['water', 'sulfuric acid'], zs=[0.01, 0.99], T=298.15) VolumeLiquids = [i.VolumeLiquid for i in m.Chemicals] obj = VolumeLiquidMixture(MWs=m.MWs, Tcs=m.Tcs, Pcs=m.Pcs, Vcs=m.Vcs, Zcs=m.Zcs, omegas=m.omegas, CASs=m.CASs, VolumeLiquids=VolumeLiquids) Vm = obj.mixture_property(m.T, m.P, m.zs, m.ws) assert_allclose(Vm, 4.824170609370422e-05) # 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_Mixture_input_np_array(): # numpy array inputs IDs = ['pentane', 'hexane', 'heptane'] kwargs = {'ws': np.array([0.4401066297270966, 0.31540115235588945, 0.24449221791701395]), 'zs': np.array([.5, .3, .2]), 'Vfls': np.array([0.45711574619871703, 0.31076035223551646, 0.23212390156576654]), 'Vfgs': np.array([.5, .3, .2])} for key, val in kwargs.items(): m = Mixture(IDs, **{key:val}) assert_close1d(m.zs, kwargs['zs'], rtol=1E-6) assert_close1d(m.zs, m.xs) assert_close1d(m.Vfls(), kwargs['Vfls'], rtol=1E-5) assert_close1d(m.Vfgs(), kwargs['Vfgs'], rtol=2E-5)
def n2o_density(external_temp): n2o = Mixture(['n2o'], Vfls=[1], T=external_temp.to(constants.ureg.degK).magnitude) return (n2o.rhol * (constants.ureg.kg / (constants.ureg.m**3))).to_base_units()
def test_UNIFAC_PP_fuzz(): m = Mixture(['ethanol', 'water'], zs=[0.5, 0.5], P=5000, T=298.15) vodka = UNIFAC_PP(m.UNIFAC_groups, m.VaporPressures, m.Tms, m.Tcs, m.Pcs) for i in range(500): zs = [uniform(0, 1) for i in range(2)] zs = [i/sum(zs) for i in zs] T_known = uniform(274, 513) V_over_F_known = uniform(0, 1) vodka.flash(T=T_known, VF=V_over_F_known, zs=zs) P_known = vodka.P xs_known = vodka.xs ys_known = vodka.ys phase_known = vodka.phase # test TP flash gives the same as TVF vodka.flash(T=T_known, P=P_known, zs=zs) assert_allclose(V_over_F_known, vodka.V_over_F, rtol=1E-5) assert_allclose(xs_known, vodka.xs, rtol=1E-5) assert_allclose(ys_known, vodka.ys, rtol=1E-5) assert vodka.phase == phase_known # Test PVF flash gives same as well vodka.flash(VF=V_over_F_known, P=P_known, zs=zs) assert_allclose(xs_known, vodka.xs) assert_allclose(ys_known, vodka.ys) assert_allclose(xs_known, vodka.xs) assert_allclose(T_known, vodka.T) assert vodka.phase == phase_known
def test_Mixture_predefined(): for name in ['Air', 'air', u'Air', ['air']]: air = Mixture(name) assert air.CASs == ['7727-37-9', '7440-37-1', '7782-44-7'] assert_close1d(air.zs, [0.7811979754734807, 0.009206322604387548, 0.20959570192213187], rtol=1E-4) assert_close1d(air.ws, [0.7557, 0.0127, 0.2316], rtol=1E-3) R401A = Mixture('R401A') assert R401A.CASs == ['75-45-6', '75-37-6', '2837-89-0'] assert_close1d(R401A.zs, [0.578852219944875, 0.18587468325478565, 0.2352730968003393], rtol=1E-4) assert_close1d(R401A.ws, [0.53, 0.13, 0.34], rtol=1E-3) natural_gas = Mixture('Natural gas') assert natural_gas.CASs == ['74-82-8', '7727-37-9', '124-38-9', '74-84-0', '74-98-6', '75-28-5', '106-97-8', '78-78-4', '109-66-0', '110-54-3'] assert_close1d(natural_gas.zs, [0.9652228316853225, 0.002594967217109564, 0.005955831022086067, 0.018185509193506685, 0.004595963476244077, 0.0009769695915451998, 0.001006970610302194, 0.0004729847624453981, 0.0003239924667435125, 0.0006639799746946288], rtol=1E-3) assert_close1d(natural_gas.ws, [0.921761382642074, 0.004327306490959737, 0.015603023404535107, 0.03255104882657324, 0.012064018096027144, 0.0033802050703076055, 0.0034840052260078393, 0.002031403047104571, 0.001391502087253131, 0.003406105109157664], rtol=1E-4)
def test_ViscosityLiquidMixture(): # DIPPR 1983 manual example ViscosityLiquids = [ViscosityLiquid(CASRN=CAS) for CAS in ['56-23-5', '67-63-0']] for obj in ViscosityLiquids: obj.method = DIPPR_PERRY_8E T, P, zs, ws = 313.2, 101325.0, [0.5, 0.5], [0.7190741374767832, 0.2809258625232169] obj = ViscosityLiquidMixture(ViscosityLiquids=ViscosityLiquids, CASs=['56-23-5', '67-63-0'], MWs=[153.8227, 60.09502]) mu = obj.mixture_property(T, P, zs, ws) assert_close(mu, 0.0009948528627794172) mu = obj.calculate(T, P, zs, ws, MIXING_LOG_MOLAR) assert_close(mu, 0.0009948528627794172) mu = obj.calculate(T, P, zs, ws, SIMPLE) assert_close(mu, 0.001039155803329608) # Test Laliberte m = Mixture(['water', 'sulfuric acid'], zs=[0.5, 0.5], T=298.15) ViscosityLiquids = [i.ViscosityLiquid for i in m.Chemicals] obj = ViscosityLiquidMixture(ViscosityLiquids=ViscosityLiquids, CASs=m.CASs, MWs=m.MWs) mu = obj.mixture_property(m.T, m.P, m.zs, m.ws) assert_close(mu, 0.024955325569420893) assert obj.method == LALIBERTE_MU # 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_ViscosityGasMixture(): # DIPPR 1983 manual example m = Mixture(['dimethyl ether', 'sulfur dioxide'], zs=[.95, .05], T=308.2) ViscosityGases = [i.ViscosityGas for i in m.Chemicals] obj = ViscosityGasMixture(MWs=m.MWs, molecular_diameters=m.molecular_diameters, Stockmayers=m.Stockmayers, CASs=m.CASs, ViscosityGases=ViscosityGases) mu = obj.mixture_property(m.T, m.P, m.zs, m.ws) assert_allclose(mu, 9.637173494726528e-06) viscosity_gas_mixture_methods = [BROKAW, HERNING_ZIPPERER, WILKE, SIMPLE] mus = [ obj.calculate(m.T, m.P, m.zs, m.ws, method) for method in viscosity_gas_mixture_methods ] assert_allclose(mus, [ 9.637173494726528e-06, 9.672122280295219e-06, 9.642294904686337e-06, 9.638962759382555e-06 ]) # 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_Mixture_VF_input(): test_mix = Mixture( ['ethylene oxide', 'tetrahydrofuran', 'beta-propiolactone'], ws=[6021, 111569.76, 30711.21], T=400, VF=0.5) assert_allclose(test_mix.P, 370054, rtol=1E-2)
def test_SurfaceTensionMixture(): from thermo.mixture import Mixture from thermo.interface import SurfaceTensionMixture, DIGUILIOTEJA, SIMPLE, WINTERFELDSCRIVENDAVIS m = Mixture(['pentane', 'dichloromethane'], zs=[.1606, .8394], T=298.15) SurfaceTensions = [i.SurfaceTension for i in m.Chemicals] VolumeLiquids = [i.VolumeLiquid for i in m.Chemicals] a = SurfaceTensionMixture(MWs=m.MWs, Tbs=m.Tbs, Tcs=m.Tcs, CASs=m.CASs, SurfaceTensions=SurfaceTensions, VolumeLiquids=VolumeLiquids) sigma = a.mixture_property(m.T, m.P, m.zs, m.ws) assert_close(sigma, 0.023887948426185343) sigma = a.calculate(m.T, m.P, m.zs, m.ws, SIMPLE) assert_close(sigma, 0.025331490604571537) sigmas = [ a.calculate(m.T, m.P, m.zs, m.ws, i) for i in [DIGUILIOTEJA, SIMPLE, WINTERFELDSCRIVENDAVIS] ] assert_close1d( sigmas, [0.025257338967448677, 0.025331490604571537, 0.023887948426185343]) with pytest.raises(Exception): a.test_method_validity(m.T, m.P, m.zs, m.ws, 'BADMETHOD') with pytest.raises(Exception): a.calculate(m.T, m.P, m.zs, m.ws, 'BADMETHOD')
def test_real_gas_dry_heating_value(self): results = Mixture( self.property_package, self.temperature, self.pressure, self.volume).real_gas_dry_heating_value(self.hydrogen_sulfide) self.assertTrue( abs(results - 1282.4994) < settings.FLOAT_COMPARE_TOLERANCE) results = Mixture(self.property_package, self.temperature, self.pressure, self.volume).real_gas_dry_heating_value(False) self.assertTrue( abs(results - 1353.4037) < settings.FLOAT_COMPARE_TOLERANCE) results = Mixture(self.property_package, self.temperature, 14.65, self.volume).real_gas_dry_heating_value(False) self.assertTrue( abs(results - 1349.1494) < settings.FLOAT_COMPARE_TOLERANCE) return
def test_Mixture_input_ordered_dict(): # Ordered dict inputs IDs = ['pentane', 'hexane', 'heptane'] kwargs = {'ws': [0.4401066297270966, 0.31540115235588945, 0.24449221791701395], 'zs': [.5, .3, .2], 'Vfls': [0.45711574619871703, 0.31076035223551646, 0.23212390156576654], 'Vfgs': [.5, .3, .2]} for key, val in kwargs.items(): d = OrderedDict() for i, j in zip(IDs, val): d.update({i: j}) m = Mixture(**{key:d}) assert_close1d(m.zs, kwargs['zs'], rtol=1E-6) assert_close1d(m.zs, m.xs) assert_close1d(m.Vfls(), kwargs['Vfls'], rtol=1E-5) assert_close1d(m.Vfgs(), kwargs['Vfgs'], rtol=2E-5)
def ideal_gas_dry_heating_value(compounds, mole_fractions, recovery_factors, pressure, temperature, volume): composition = list(zip(compounds, mole_fractions, recovery_factors)) property_package = PropertyPackage(settings.FLUID_PROPERTY_LIBRARY, composition) results = Mixture(property_package, temperature, pressure, volume).ideal_gas_dry_heating_value() return results
def compressibility_factor(compounds, mole_fractions, recovery_factors, pressure, temperature, volume): composition = list(zip(compounds, mole_fractions, recovery_factors)) property_package = PropertyPackage(settings.FLUID_PROPERTY_LIBRARY, composition) results = Mixture(property_package, temperature, pressure, volume).compressibility_factor() return results
def liquid_shrinkage_energy(compounds, mole_fractions, recovery_factors, pressure, temperature, volume, component): composition = list(zip(compounds, mole_fractions, recovery_factors)) property_package = PropertyPackage(settings.FLUID_PROPERTY_LIBRARY, composition) results = Mixture(property_package, temperature, pressure, volume).liquid_shrinkage_energy(component) return results
def test_IdealPPThermodynamic_nitrogen_S(): m = Mixture(['nitrogen'], zs=[1], T=298.15) pkg = IdealPPThermodynamic(VaporPressures=m.VaporPressures, Tms=m.Tms, Tbs=m.Tbs, Tcs=m.Tcs, Pcs=m.Pcs, HeatCapacityLiquids=m.HeatCapacityLiquids, HeatCapacityGases=m.HeatCapacityGases, EnthalpyVaporizations=m.EnthalpyVaporizations) # Check the enthalpy of vaporization matches at the reference temperature for a gas pkg.flash(T=298.15, P=101325, zs=m.zs) S_pp = pkg.entropy_Cpg_Hvap() assert_allclose(S_pp, 0, atol=1E-9) # Check a entropy difference vs coolprop (N2)- 1.5% error pkg.flash(T=298.15, P=101325, zs=m.zs) S1 = pkg.entropy_Cpg_Hvap() pkg.flash(T=298.15, P=2000325, zs=m.zs) S2 = pkg.entropy_Cpg_Hvap() assert_allclose(S2-S1, -25.16418, rtol=0.015) # # Check a entropy difference vs coolprop (N2)- 0.3% error pkg.flash(T=298.15, P=101325, zs=m.zs) S1 = pkg.entropy_Cpg_Hvap() pkg.flash(T=298.15, P=102325, zs=m.zs) S2 = pkg.entropy_Cpg_Hvap() # 0.3% error with 1 kPa difference assert_allclose(S2-S1, -0.08184949145277187, rtol=0.003) # PropsSI('SMOLAR', 'T', 298.15, 'P', 102325, 'N2') - PropsSI('SMOLAR', 'T', 298.15, 'P', 101325, 'N2') # S2-S1 # <2.5% error on a 10 MPa/500K N2 vs 298.15 and 1 atm vs coolprop pkg.flash(T=298.15, P=101325, zs=m.zs) S1 = pkg.entropy_Cpg_Hvap() pkg.flash(T=500, P=1E7, zs=m.zs) S2 = pkg.entropy_Cpg_Hvap() assert_allclose(S2-S1, -23.549468174122012, rtol=0.026) # PropsSI('SMOLAR', 'T', 500, 'P', 1E7, 'N2') - PropsSI('SMOLAR', 'T', 298.15, 'P', 101325, 'N2') # Entropy change of condensation at the saturation point of 1 bar - very low error pkg.flash(VF=1, P=1E5, zs=m.zs) S1 = pkg.entropy_Cpg_Hvap() pkg.flash(VF=0, P=1E5, zs=m.zs) S2 = pkg.entropy_Cpg_Hvap() # T_change = PropsSI('T', 'Q', 0, 'P', 1E5, 'N2') # 77.24349973069587 # dS = PropsSI('SMOLAR', 'Q', 0, 'T', T_change, 'N2') - PropsSI('SMOLAR', 'Q', 1, 'T', T_change, 'N2') assert_allclose(S2 - S1, -72.28618677058911, rtol=5E-4) # Same test as before, 50% condensed pkg.flash(VF=1, P=1E5, zs=m.zs) S1 = pkg.entropy_Cpg_Hvap() pkg.flash(VF=0.5, P=1E5, zs=m.zs) S2 = pkg.entropy_Cpg_Hvap() assert_allclose(S2 - S1, -72.28618677058911/2, rtol=5E-4) # Test compressing a liquid doesn't add any entropy pkg.flash(VF=0, P=1E5, zs=m.zs) S1 = pkg.entropy_Cpg_Hvap() T = pkg.T pkg.flash(T=T, P=2E5, zs=m.zs) S2 = pkg.entropy_Cpg_Hvap() assert_allclose(S1-S2, 0)
def test_plotting_failures(): m = Mixture(['ethanol', 'methanol', 'water'], zs=[0.3, 0.3, 0.4], P=5000, T=298.15) ternary = Ideal_PP(m.VaporPressures, m.Tms, m.Tcs, m.Pcs) with pytest.raises(Exception): ternary.plot_Pxy(300) with pytest.raises(Exception): ternary.plot_Txy(300) with pytest.raises(Exception): ternary.plot_xy(300)
def test_ideal_gas_dry_heating_value(self): results = Mixture(self.property_package, self.temperature, self.pressure, self.volume).ideal_gas_dry_heating_value() self.assertTrue( abs(results - 1276.5900) < settings.FLOAT_COMPARE_TOLERANCE) results = Mixture(self.property_package, self.temperature, 14.65, self.volume).ideal_gas_dry_heating_value() self.assertTrue( abs(results - 1272.5941) < settings.FLOAT_COMPARE_TOLERANCE) results = Mixture( PropertyPackage(self.library, [('methane', 0.5, 0.0), ('hexane_plus', 0.4, 0.98), ('hydrogen_sulfide', 0.1, 0.0)]), self.temperature, self.pressure, self.volume).ideal_gas_dry_heating_value() self.assertTrue( abs(results - 2620.3980) < settings.FLOAT_COMPARE_TOLERANCE) return
def test_prints(): startT = Thot t = 0 air = Mixture('air', T=startT, P=Pdepth) y = [ startT, Pdepth, air.rho * volume, startT, Pdepth, air.rho * volume, 0, 0, 0 ] # equalized z = blowdownAugmented(t, y) printState(t, y, z)
def test_ThermalConductivityGasMixture(): from thermo.thermal_conductivity import ThermalConductivityGasMixture, LINDSAY_BROMLEY, SIMPLE m2 = Mixture(['nitrogen', 'argon', 'oxygen'], ws=[0.7557, 0.0127, 0.2316]) ThermalConductivityGases = [i.ThermalConductivityGas for i in m2.Chemicals] ViscosityGases = [i.ViscosityGas for i in m2.Chemicals] kg_mix = ThermalConductivityGasMixture( MWs=m2.MWs, Tbs=m2.Tbs, CASs=m2.CASs, ThermalConductivityGases=ThermalConductivityGases, ViscosityGases=ViscosityGases) k = kg_mix.mixture_property(m2.T, m2.P, m2.zs, m2.ws) assert_allclose( k, 0.025864474514829254) # test LINDSAY_BROMLEY and mixture property # Do it twice to test the stored method k = kg_mix.mixture_property(m2.T, m2.P, m2.zs, m2.ws) assert_allclose( k, 0.025864474514829254) # test LINDSAY_BROMLEY and mixture property k = kg_mix.calculate(m2.T, m2.P, m2.zs, m2.ws, SIMPLE) # Test calculate, and simple assert_allclose(k, 0.02586655464213776) dT1 = kg_mix.calculate_derivative_T(m2.T, m2.P, m2.zs, m2.ws, LINDSAY_BROMLEY) dT2 = kg_mix.property_derivative_T(m2.T, m2.P, m2.zs, m2.ws) assert_allclose([dT1, dT2], [7.3391064059347144e-05] * 2) dP1 = kg_mix.calculate_derivative_P(m2.P, m2.T, m2.zs, m2.ws, LINDSAY_BROMLEY) dP2 = kg_mix.property_derivative_P(m2.T, m2.P, m2.zs, m2.ws) assert_allclose([dP1, dP2], [3.5325319058809868e-10] * 2, rtol=1E-4) # Test other methods assert kg_mix.user_methods == [] assert kg_mix.all_methods == {LINDSAY_BROMLEY, SIMPLE} assert kg_mix.ranked_methods == [LINDSAY_BROMLEY, SIMPLE] # set a method kg_mix.set_user_method([SIMPLE]) assert None == kg_mix.method k = kg_mix.mixture_property(m2.T, m2.P, m2.zs, m2.ws) assert_allclose(k, 0.02586655464213776) # Unhappy paths with pytest.raises(Exception): kg_mix.calculate(m2.T, m2.P, m2.zs, m2.ws, 'BADMETHOD') with pytest.raises(Exception): kg_mix.test_method_validity(m2.T, m2.P, m2.zs, m2.ws, 'BADMETHOD')
def test_UNIFAC_Dortmund_PP(): m = Mixture(['ethanol', 'water'], zs=[0.5, 0.5], P=6500, T=298.15) vodka = UNIFAC_Dortmund_PP(UNIFAC_groups=m.UNIFAC_Dortmund_groups, VaporPressures=m.VaporPressures, Tms=m.Tms, Tcs=m.Tcs, Pcs=m.Pcs) # Low pressure ethanol-water ideal TP flash phase, xs, ys, V_over_F = vodka.flash_TP_zs(m.T, m.P, m.zs) V_over_F_expect = 0.721802969194136 xs_expect = [0.26331608196660095, 0.736683918033399] ys_expect = [0.5912226272910779, 0.408777372708922] assert phase == 'l/g' assert_allclose(xs, xs_expect) assert_allclose(ys, ys_expect) assert_allclose(V_over_F, V_over_F_expect) # Same flash with T-VF spec phase, xs, ys, V_over_F, P = vodka.flash_TVF_zs(m.T, V_over_F_expect, m.zs) assert phase == 'l/g' assert_allclose(xs, xs_expect, rtol=1E-5) assert_allclose(ys, ys_expect, rtol=1E-5) assert_allclose(V_over_F, V_over_F_expect, rtol=1E-5) # Same flash with P-VF spec phase, xs, ys, V_over_F, T = vodka.flash_PVF_zs(m.P, V_over_F_expect, m.zs) assert phase == 'l/g' assert_allclose(xs, xs_expect, rtol=1E-5) assert_allclose(ys, ys_expect, rtol=1E-5) assert_allclose(V_over_F, V_over_F_expect, rtol=1E-5) # Test the flash interface directly T_known = m.T V_over_F_known = V_over_F_expect zs = m.zs vodka.flash(T=T_known, VF=V_over_F_known, zs=zs) P_known = vodka.P xs_known = vodka.xs ys_known = vodka.ys phase_known = vodka.phase # test TP flash gives the same as TVF vodka.flash(T=T_known, P=P_known, zs=zs) assert_allclose(V_over_F_known, vodka.V_over_F) assert_allclose(xs_known, vodka.xs) assert_allclose(ys_known, vodka.ys) assert vodka.phase == phase_known # Test PVF flash gives same as well vodka.flash(VF=V_over_F_known, P=P_known, zs=zs) assert_allclose(xs_known, vodka.xs) assert_allclose(ys_known, vodka.ys) assert_allclose(xs_known, vodka.xs) assert_allclose(T_known, vodka.T) assert vodka.phase == phase_known
def test_IdealPPThermodynamic_binary_H(): m = Mixture(['water', 'ethanol'], zs=[0.3, 0.7], T=298.15) pkg = IdealPPThermodynamic(VaporPressures=m.VaporPressures, Tms=m.Tms, Tbs=m.Tbs, Tcs=m.Tcs, Pcs=m.Pcs, HeatCapacityLiquids=m.HeatCapacityLiquids, HeatCapacityGases=m.HeatCapacityGases, EnthalpyVaporizations=m.EnthalpyVaporizations) # Check the enthalpy of vaporization matches at the reference temperature (as a liquid) pkg.flash(T=298.15, P=1E5, zs=m.zs) H_pp = pkg.enthalpy_Cpg_Hvap() assert_allclose(H_pp, (-0.3*m.EnthalpyVaporizations[0](298.15) -0.7*m.EnthalpyVaporizations[1](298.15))) # Check the enthalpy of 0 matches at the reference temperature (as a gas) pkg.flash(T=298.15, VF=1, zs=m.zs) assert_allclose(0, pkg.enthalpy_Cpg_Hvap(), atol=1E-9) # Check the gas, at various pressure but still Tref, has enthalpy of 0 pkg.flash(T=298.15, zs=m.zs, VF=1) P_dew = pkg.P kw_options = [{'P': P_dew}, {'P': 100}, {'P': 1E-10}, {'VF': 1}] for kw in kw_options: pkg.flash(T=298.15, zs=m.zs, **kw) H_pp = pkg.enthalpy_Cpg_Hvap() assert_allclose(H_pp, 0, atol=1E-7) # Check it's pressure is independent (so long as it stays liquid), has enthalpy of 0 pkg.flash(T=298.15, zs=m.zs, VF=0) P_bubble = pkg.P kw_options = [{'P': P_bubble+1E-4}, {'P': 1E4}, {'P': 1E10}, {'VF': 0}] for kw in kw_options: pkg.flash(T=298.15, zs=m.zs, **kw) H_pp = pkg.enthalpy_Cpg_Hvap() H_handcalc = -0.3*m.EnthalpyVaporizations[0](298.15) -0.7*m.EnthalpyVaporizations[1](298.15) assert_allclose(H_pp, H_handcalc) # For a variety of vapor fractions and temperatures, check the enthapy is correctly described for VF in np.linspace(0., 1, 6): for T in np.linspace(280, 400, 8): z1 = uniform(0, 1) z2 = 1-z1 zs = [z1, z2] pkg.flash(T=T, zs=zs, VF=VF) pkg_calc = pkg.enthalpy_Cpg_Hvap() # bad hack as the behavior changed after if pkg.xs == None: pkg.xs = pkg.zs hand_calc =(-(1 - VF)*(pkg.xs[0]*m.EnthalpyVaporizations[0](T) + pkg.xs[1]*m.EnthalpyVaporizations[1](T)) + (z1*m.HeatCapacityGases[0].T_dependent_property_integral(298.15, T) + z2*m.HeatCapacityGases[1].T_dependent_property_integral(298.15, T))) assert_allclose(pkg_calc, hand_calc)