def test_compressibility(self): # compressibility of water at [temperature(C), pressure(applied_bar), compressibility (10^6 bar-1)] Millero TABLE V param = np.array([[5, 0, 49.175], [30, 0, 44.771], [75, 0, 45.622], [35, 100, 43.305], [55, 300, 40.911]]) # converting param to [temperature(K), pressure(atm), compressibility (atm-1)] param[:, 0] = un.celsius_2_kelvin(param[:, 0]) # 1 atm = 1 applied_atm + 1, according to Millero param[:, 1] = (param[:, 1] / un.atm_2_bar(1)) + 1 param[:, 2] = (param[:, 2] / 1e6) * un.atm_2_bar(1) # testing compressibility up to a precision of 10^-9 wfm = fm.WaterPropertiesFineMillero(param[:, 0], param[:, 1]) test_vals = np.allclose(wfm.compressibility(), param[:, 2], 0, 1e-9) self.assertTrue(test_vals)
def test_a_v(self): # apparent molal volume [temperature(C), Pressure(bar), molal vol (cc/mol)] Bradley & Pitzer TABLE IV param = np.array([[10, 100, 1.61], [60, 100, 2.55], [120, 100, 4.91], [70, 400, 2.59], [25, 600, 1.66]]) # converting param to [temperature(K), pressure(atm), molal vol (cc/mol)] param[:, 0] = un.celsius_2_kelvin(param[:, 0]) param[:, 1] = param[:, 1] / un.atm_2_bar(1) # testing apparent molal volume up to a precision of 10^-2 wfm = fm.WaterPropertiesFineMillero(param[:, 0], param[:, 1]) test_vals = np.allclose(wfm.a_v(), param[:, 2], 0, 1e-2) self.assertTrue(test_vals)
def test_molar_vol_infinite_dilution(self): # parameters in [temperature (C), pressure (bar), partial molal volume of solute cm^3/mol] param = np.array([[70, 1, 1.781e1], [60, 1, 1.791e1], [90, 1, 1.710e1], [80, 400, 1.884e1], [60, 800, 2.024e1]]) # converting to [temperature (K), pressure (atm), partial molal volume of solute m^3/mol] param[:, 0] = un.celsius_2_kelvin(param[:, 0]) param[:, 1] = param[:, 1] / un.atm_2_bar(1) param[:, 2] = param[:, 2] / 1e6 # testing params up to a precision of 10^-8 salt_nacl = nacl.NaClPropertiesRogersPitzer(param[:, 0], param[:, 1]) test_vals = np.allclose(salt_nacl.vp * 1e-6, param[:, 2], 0, 1e-8) self.assertTrue(test_vals)
def test_a_phi(self): # osmotic coefficient of water [temperature(C), Pressure(bar), osmotic coefficient] Bradley & Pitzer TABLE II param = np.array([[10, 100, 3.80e-1], [60, 100, 4.17e-1], [120, 100, 4.82e-1], [70, 400, 4.19e-1], [25, 600, 3.81e-1]]) # converting param to [temperature(K), pressure(atm), osmotic coefficient] param[:, 0] = un.celsius_2_kelvin(param[:, 0]) param[:, 1] = param[:, 1] / un.atm_2_bar(1) # testing osmotic coefficient up to a precision of 10^-3 wfm = fm.WaterPropertiesFineMillero(param[:, 0], param[:, 1]) test_vals = np.allclose(wfm.a_phi(), param[:, 2], 0, 1e-3) self.assertTrue(test_vals)
def test_a_h(self): # enthalpy coefficient [temperature(C), Pressure(bar), enthalpy coeff (AH / RT)] Bradley & Pitzer TABLE III param = np.array([[10, 100, 0.641], [60, 100, 1.180], [120, 100, 2.05], [70, 400, 1.24], [25, 600, 0.736]]) # converting param to [temperature(K), pressure(atm), enthalpy coeff (AH / RT)] param[:, 0] = un.celsius_2_kelvin(param[:, 0]) param[:, 1] = param[:, 1] / un.atm_2_bar(1) # testing enthalpy coeff up to a precision of 10^-2 wfm = fm.WaterPropertiesFineMillero(param[:, 0], param[:, 1]) test_vals = np.allclose( ((2 / 3) * wfm.a_h()) / (un.r_gas() * param[:, 0]), param[:, 2], 0, 1e-2) self.assertTrue(test_vals, (wfm.a_h()) / (un.r_gas() * param[:, 0]))
def test_density(self): # density of water at [temperature(C), pressure(applied_bar), specific volume] Millero TABLEIV param = np.array([[5, 0, 1.000036], [30, 0, 1.004369], [75, 0, 1.025805], [30, 100, 0.999939], [55, 300, 1.001642]]) # converting param to [temperature(K), pressure(atm), specific volume] param[:, 0] = un.celsius_2_kelvin(param[:, 0]) # 1 atm = 1 applied_atm + 1, according to Millero param[:, 1] = (param[:, 1] / un.atm_2_bar(1)) + 1 # testing density up to a precision of 10^-6 wfm = fm.WaterPropertiesFineMillero(param[:, 0], param[:, 1]) test_vals = np.allclose(1e3 / wfm.density(), param[:, 2], 0, 1e-6) self.assertTrue(test_vals)
def test_density_sol(self): # parameters in [temperature (C), pressure (bar), molality, specific volume of NaCl(aq) cm^3/g] param = np.array([[60, 1, 1, 0.9797], [60, 1, 0.1, 1.0130], [60, 1, 0.5, 0.9976], [80, 1, 2, 0.9581], [80, 1, 3, 0.9293], [80, 1, 0.75, 0.9999], [70, 200, 1, 0.9772], [90, 200, 3, 0.9280], [80, 400, 0.1, 1.0074], [90, 600, 0.25, 0.9998]]) # converting to [temperature (K), pressure (atm), molality, specific volume of NaCl(aq) cm^3/g] param[:, 0] = un.celsius_2_kelvin(param[:, 0]) param[:, 1] = param[:, 1] / un.atm_2_bar(1) # testing params up to a precision of 10^-4 salt_nacl = nacl.NaClPropertiesRogersPitzer(param[:, 0], param[:, 1]) test_vals = np.allclose((1 / salt_nacl.density_sol(param[:, 2])) * 1e3, param[:, 3], 0, 1e-4) self.assertTrue(test_vals)
def test_log_gamma(self): # parameters in [temperature (C), molality, activity coefficient] param = np.array([[25, 1, 0.605], [25, 0.1, 0.768], [25, 0.5, 0.650], [25, 0.3, 0.687], [25, 2.0, 0.574], [50, 3.0, 0.584], [50, 0.5, 0.646]]) # converting to [temperature (K), molality, activity coefficient] param[:, 0] = un.celsius_2_kelvin(param[:, 0]) # testing params up to a precision of 10^-3 salt_kcl = kcl.KClPropertiesPabalanPitzer(param[:, 0], 1 / un.atm_2_bar(1)) test_vals = np.allclose(np.exp(salt_kcl.log_gamma(param[:, 1])), param[:, 2], 0, 1e-3) self.assertTrue( test_vals, str(np.exp(salt_kcl.log_gamma(param[:, 1]))) + " & " + str(param[:, 2]))
def test_molar_volume(self): # molar volume of water at [temperature(C), pressure(applied_bar), specific volume] Millero TABLE IV param = np.array([[5, 0, 1.000036], [30, 0, 1.004369], [75, 0, 1.025805], [35, 100, 1.001597], [55, 300, 1.001642]]) # converting param to [temperature(K), pressure(atm), molar volume] param[:, 0] = un.celsius_2_kelvin(param[:, 0]) # 1 atm = 1 applied_atm + 1, according to Millero param[:, 1] = (param[:, 1] / un.atm_2_bar(1)) + 1 param[:, 2] = (param[:, 2] / 1e6) * fm.WaterPropertiesFineMillero(300).MolecularWeight # testing molar volume up to a precision of 10^-11 wfm = fm.WaterPropertiesFineMillero(param[:, 0], param[:, 1]) test_vals = np.allclose(wfm.molar_volume(), param[:, 2], 0, 1e-11) self.assertTrue(test_vals)
def test_osmotic_coeff(self): # parameters in [temperature (C), molality, osmotic coefficient] param = np.array([[25, 1, 0.899], [25, 0.1, 0.927], [25, 0.5, 0.901], [25, 0.3, 0.907], [25, 2, 0.914], [50, 3, 0.954], [50, 0.5, 0.903]]) # converting to [temperature (K), molality, osmotic coefficient] param[:, 0] = un.celsius_2_kelvin(param[:, 0]) # testing params up to a precision of 10^-3 salt_kcl = kcl.KClPropertiesPabalanPitzer(param[:, 0], 1 / un.atm_2_bar(1)) test_vals = np.allclose(salt_kcl.osmotic_coeff(param[:, 1]), param[:, 2], 0, 1e-3) self.assertTrue( test_vals, str(salt_kcl.osmotic_coeff(param[:, 1])) + " & " + str(param[:, 2]))
def test_apparent_molal_enthalpy(self): # parameters in [temperature (C), molality, apparent relative molal enthalpy (kJ/mol)] param = np.array([[25, 1.0, -0.06], [25, 0.1, 0.34], [25, 0.5, 0.24], [25, 0.3, 0.33], [25, 2.0, -0.67], [25, 3.0, -1.21], [50, 0.5, 0.79], [50, 3.0, 0.30], [50, 0.1, 0.59], [50, 0.3, 0.75]]) # converting to [temperature (K), molality, apparent relative molal enthalpy (kJ/mol)] param[:, 0] = un.celsius_2_kelvin(param[:, 0]) # testing params up to a precision of 10^-2 salt_kcl = kcl.KClPropertiesPabalanPitzer(param[:, 0], (1 / un.atm_2_bar(1))) test_vals = np.allclose( salt_kcl.apparent_molal_enthalpy(param[:, 1]) / 1e3, param[:, 2], 0, 1e-2) self.assertTrue( test_vals, str(salt_kcl.apparent_molal_enthalpy(param[:, 1]) / 1e3) + " & " + str(param[:, 2]))
def test_params_der_p(self): # pressure derivative parameters in [temperature (C), pressure (bar), [BV, 2CV]] param = np.array([[70, 1, 3.513e-6, -1.22e-7], [60, 1, 4.415e-6, -2.00e-7], [90, 1, 2.577e-6, -6.02e-8], [80, 400, 2.552e-6, -7.97e-8], [60, 800, 3.062e-6, -2.00e-7]]) # converting to [temperature (K), pressure (atm), [bp, cp]] param[:, 0] = un.celsius_2_kelvin(param[:, 0]) param[:, 1] = param[:, 1] / un.atm_2_bar(1) param[:, 3] = param[:, 3] / 2 # testing params up to a precision of 10^-9 salt_nacl = nacl.NaClPropertiesRogersPitzer(param[:, 0], param[:, 1]) test_vals1 = np.allclose(salt_nacl.params_der_p[1], param[:, 2], 0, 1e-9) test_vals2 = np.allclose(salt_nacl.params_der_p[4], param[:, 3], 0, 1e-9) self.assertTrue(test_vals1) self.assertTrue(test_vals2)
def test_molar_vol(self): # parameters in [temperature (C), pressure (bar), molality, molar volume cm^3/mol] param = np.array([[0, 196.62, 0.3331, 26.280], [0, 196.62, 0.5009, 26.573], [0, 196.62, 0.6693, 26.856], [0, 196.62, 0.8360, 26.976], [25, 196.62, 0.3331, 28.873], [25, 196.62, 0.5009, 29.104], [25, 196.62, 0.6693, 29.258], [50, 196.62, 0.3331, 29.757], [50, 196.62, 0.5009, 29.968], [50, 196.62, 0.6693, 30.125]]) # converting to [temperature (K), pressure (atm), molality, molar volume m^3/mol] param[:, 0] = un.celsius_2_kelvin(param[:, 0]) param[:, 1] = param[:, 1] / un.atm_2_bar(1) param[:, 3] = param[:, 3] / 1e6 # testing params up to a precision of 10^-9 salt_kcl = kcl.KClPropertiesPabalanPitzer(param[:, 0], param[:, 1]) test_vals = np.allclose(salt_kcl.molar_vol(param[:, 2]), param[:, 3], 0, 1e-9) self.assertTrue( test_vals, str(salt_kcl.molar_vol(param[:, 2])) + " & " + str(param[:, 3]))
def test_density_sol(self): # parameters in [temperature (K), pressure (bar), molality, density of solution g/cm^3] param = np.array([[323.90, 22.3, 0.0723, 0.99720], [324.48, 22.3, 0.0723, 0.99699], [324.24, 49.1, 0.0723, 0.99819], [324.26, 98.3, 0.0723, 1.00020], [294.21, 21.9, 0.1693, 1.01927], [294.23, 23.1, 0.1693, 1.01924], [293.84, 47.6, 0.1693, 1.02043], [324.76, 47.5, 0.1693, 1.00917], [325.27, 95.6, 0.1693, 1.01083], [294.90, 95.2, 0.2503, 1.03156]]) # converting to [temperature (K), pressure (atm), molality, density of solution g/cm^3] param[:, 1] = param[:, 1] / un.atm_2_bar(1) # testing params up to a precision of 10^-5 salt_mgso4 = mgso4.MgSO4PropertiesPhutelaPitzer( param[:, 0], param[:, 1]) test_vals = np.allclose((salt_mgso4.density_sol(param[:, 2])) / 1e3, param[:, 3], 0, 1e-5) self.assertTrue( test_vals, str((salt_mgso4.density_sol(param[:, 2])) * 1e3) + " & " + str(param[:, 3]))
def test_density_sol(self): # parameters in [temperature (K), pressure (bar), molality, density of solution g/cm^3] param = np.array([[294.87, 20.2, 0.0578, 1.00608], [325.16, 20.4, 0.0578, 0.99503], [325.09, 20.5, 0.0578, 0.99507], [295.18, 20.3, 0.0578, 1.00604], [295.67, 48.8, 0.0578, 1.00717], [325.01, 49.1, 0.0578, 0.99634], [295.47, 95.3, 0.0578, 1.00928], [325.08, 96.6, 0.0578, 0.99833], [296.35, 20.0, 0.1085, 1.01207], [294.85, 47.6, 0.1085, 1.01366]]) # converting to [temperature (K), pressure (atm), molality, density of solution g/cm^3] param[:, 1] = param[:, 1] / un.atm_2_bar(1) # testing params up to a precision of 10^-5 salt_na2so4 = na2so4.Na2SO4PropertiesPhutelaPitzer( param[:, 0], param[:, 1]) test_vals = np.allclose((salt_na2so4.density_sol(param[:, 2])) * 1e3, param[:, 3], 0, 1e-5) self.assertTrue( test_vals, str((salt_na2so4.density_sol(param[:, 2])) * 1e3) + " & " + str(param[:, 3]))
def __init__(self, tk, pa=1): """ constructor :param tk: temperature in kelvin :param pa: pressure in atmospheres :instantiate: temperature, pressure, stoichiometry coefficients, Pitzer Parameters """ self.tk = tk self.pa = pa # Calculations MgSO4 parameters and coefficients self.mat_stoich = np.array([[1, 1], [2, -2]]) self.m_ref = 5.550825 self.y_ref = 10 self.m_weight = 120.366 self.p_ref = np.array([self.m_weight, self.m_ref, self.y_ref]) # values for ion strength dependence and ion size constants in the extended Pitzer model self.alpha_b1 = 1.4 self.alpha_b2 = 12.0 self.alpha_c1 = 0 self.alpha_c2 = 0 self.alpha_d1 = 0 self.alpha_d2 = 0 self.b_param = 1.2 self.ion_param = np.array([ self.alpha_b1, self.alpha_b2, self.alpha_c1, self.alpha_c2, self.alpha_d1, self.alpha_d2, self.b_param ]) self.q = np.zeros(15) self.q[0] = -7.97433e5 self.q[1] = 8.94735e3 self.q[2] = -3.78219e1 self.q[3] = 7.15424e-2 self.q[4] = -5.14523e-5 self.q[5] = 7.42784 self.q[6] = -6.12133e-2 self.q[7] = 1.77378e-4 self.q[8] = -1.82737e-7 self.q[9] = 2.06777e3 self.q[10] = -2.39043e1 self.q[11] = 1.03110e-1 self.q[12] = -1.96675e-4 self.q[13] = 1.40527e-7 self.q[14] = 1.18481e-4 # Pitzer Parameters self.beta0 = 0 self.beta1 = 0 self.beta2 = 0 self.C0 = 0 self.C1 = 0 self.C2 = 0 self.D0 = 0 self.D1 = 0 self.D2 = 0 self.params = np.array([ self.beta0, self.beta1, self.beta2, self.C0, self.C1, self.C2, self.D0, self.D1, self.D2 ]) # Pitzer Parameters pressure derivative self.pr = un.atm_2_bar(self.pa) self.vp = self.q[0] / self.tk + self.q[1] + self.q[ 2] * self.tk + self.q[3] * self.tk**2 + self.q[4] * self.tk**3 self.beta0_der_p = 0 self.beta1_der_p = self.q[5] / self.tk + self.q[ 6] + self.q[7] * self.tk + self.q[8] * self.tk**2 self.beta2_der_p = self.q[9] / self.tk + self.q[ 10] + self.q[11] * self.tk + self.q[12] * self.tk**2 + self.q[ 13] * self.tk**3 + self.q[14] * self.pr self.C0_der_p = 0 self.C1_der_p = 0 self.C2_der_p = 0 self.D0_der_p = 0 self.D1_der_p = 0 self.D2_der_p = 0 self.params_der_p = np.array([ self.vp, self.beta0_der_p, self.beta1_der_p, self.beta2_der_p, self.C0_der_p, self.C1_der_p, self.C2_der_p, self.D0_der_p, self.D1_der_p, self.D2_der_p ]) # Pitzer Parameters temperature derivative self.beta0_der_t = 0 self.beta1_der_t = 0 self.beta2_der_t = 0 self.C0_der_t = 0 self.C1_der_t = 0 self.C2_der_t = 0 self.D0_der_t = 0 self.D1_der_t = 0 self.D2_der_t = 0 self.params_der_t = np.array([ self.beta0_der_t, self.beta1_der_t, self.beta2_der_t, self.C0_der_t, self.C1_der_t, self.C2_der_t, self.D0_der_t, self.D1_der_t, self.D2_der_t ]) super().__init__(tk, pa)
def __init__(self, tk, pa=1): """ constructor :param tk: temperature in kelvin :param pa: pressure in atmospheres :instantiate: temperature, pressure, stoichiometry coefficients, Pitzer Parameters """ self.tk = tk self.pa = pa # Calculations nacl parameters and coefficients self.mat_stoich = np.array([[1, 1], [1, -1]]) self.m_ref = 5.550825 self.y_ref = 10 self.m_weight = 74.5513 self.p_ref = np.array([self.m_weight, self.m_ref, self.y_ref]) # values for ion strength dependence and ion size constants in the extended Pitzer model self.alpha_b1 = 2.0 self.alpha_b2 = 0 self.alpha_c1 = 0 self.alpha_c2 = 0 self.alpha_d1 = 0 self.alpha_d2 = 0 self.b_param = 1.2 self.ion_param = np.array([self.alpha_b1, self.alpha_b2, self.alpha_c1, self.alpha_c2, self.alpha_d1, self.alpha_d2, self.b_param]) self.q = np.array([[1.56152e3, 0.0], [-1.69234e5, 0.0], [-4.29918, 9.45015e-8], [4.59233e-3, -2.90741e-10], [-3.25686e4, 3.26205e-3], [-6.86887, 8.39662e-7], [7.35220e2, 0.0], [2.02245e-2, -4.41638e-9], [-2.15779e-5, 6.71235e-12], [1.03212e2, -4.42327e-5], [5.34941e-3, -7.97437e-10], [-5.73121e-1, 0.0], [-1.57862e-5, 4.12771e-12], [1.66987e-8, -6.24996e-15], [-7.22012e-2, 4.16221e-8]]) self.u = np.array([[-2.10289e-2, 2.208130e-1, 0.000000000], [6.039670e-1, -4.61849000, 7.648910e-4], [3.677680e-3, -4.10116e-2, 0.000000000], [-7.05537e-6, 1.104450e-4, -1.12131e-8], [1.979680e-9, -4.73196e-8, 1.72256e-11], [-2.47588e-3, -2.74120e-2, 0.000000000], [1.441600e-1, 3.328830e-1, -5.71188e-3]]) self.fl_1 = [6.771360e-4, 9.678540e-4, -4.12364e-5] self.fg_1 = [4.808000e-2, 2.187520e-1, -3.94000e-4] self.fl = [6.56838000e-4, 9.678540e-4, -4.12364e-5] self.fg = [5.00380000e-2, 2.187520e-1, -3.94000e-4] self.k_1 = [-2931.268116, 6353.355434, 28.17218000] self.k_2 = [-33.95314300, 193.0040590, -0.12556700] # Pitzer Parameters self.tc = 298.15 def Fg(x): f_1 = (self.u[0][x] * self.tk ** 2) / 6 + (self.u[1][x] * self.tk) / 2 + (self.u[2][x] * self.tk ** 2) * ((np.log(self.tk) / 2) - (5 / 12)) / 3 f_2 = (self.u[3][x] * self.tk ** 3) / 12 + (self.u[4][x] * self.tk ** 4) / 20 + self.u[5][x] * (self.tk / 2 + (3 * (227 ** 2)) / (2 * self.tk) + 227 * (self.tk - 227) * np.log(self.tk - 227) / self.tk) f_3 = (-self.u[6][x]) * (2 * (647 - self.tk) * np.log(647 - self.tk) / self.tk + np.log(647 - self.tk)) f_4 = (-self.k_1[x]) / self.tk - self.fl[x] * ((self.tc ** 2) / self.tk) + self.k_2[x] + self.fg[x] f_sum = f_1 + f_2 + f_3 + f_4 return f_sum self.beta0 = Fg(0) self.beta1 = Fg(1) self.beta2 = 0 self.C0 = Fg(2) self.C1 = 0 self.C2 = 0 self.D0 = 0 self.D1 = 0 self.D2 = 0 self.params = np.array([self.beta0, self.beta1, self.beta2, self.C0, self.C1, self.C2, self.D0, self.D1, self.D2]) # Pitzer Parameters pressure derivative self.pr = self.pa * un.atm_2_bar(1) self.pr_atm = un.atm_2_bar(1) def Fv(x): f_1 = self.q[0][x] + self.q[1][x] / self.tk + self.q[2][x] * self.tk + self.q[3][x] * self.tk ** 2 + self.q[4][x] / (647 - self.tk) f_2 = self.pr * (self.q[5][x] + self.q[6][x] / self.tk + self.q[7][x] * self.tk + self.q[8][x] * self.tk ** 2 + self.q[9][x] / (647 - self.tk)) f_3 = (self.pr ** 2) * (self.q[10][x] + self.q[11][x] / self.tk + self.q[12][x] * self.tk + self.q[13][x] * self.tk ** 2 + self.q[14][x] / (647 - self.tk)) return f_1 + f_2 + f_3 self.vp = Fv(0) self.beta0_der_p = Fv(1) self.beta1_der_p = 0 self.beta2_der_p = 0 self.C0_der_p = 0 self.C1_der_p = 0 self.C2_der_p = 0 self.D0_der_p = 0 self.D1_der_p = 0 self.D2_der_p = 0 self.params_der_p = np.array([self.vp, self.beta0_der_p, self.beta1_der_p, self.beta2_der_p, self.C0_der_p, self.C1_der_p, self.C2_der_p, self.D0_der_p, self.D1_der_p, self.D2_der_p]) # Pitzer Parameters temperature derivative def Fl(x): f_1 = (self.u[0][x] * self.tk) / 3 + self.u[1][x] / 2 + self.u[2][x] * self.tk * (np.log(self.tk) - (1 / 3)) / 3 f_2 = (self.u[3][x] * self.tk ** 2) / 4 + (self.u[4][x] * self.tk ** 3) / 5 f_3 = (self.u[5][x] / (self.tk ** 2)) * (((self.tk - 227) ** 2) / 2 + 454 * (self.tk - 227) + (227 ** 2) * np.log(self.tk - 227)) f_4 = (self.u[6][x] / (self.tk ** 2)) * (-(647 - self.tk) + 1294 * np.log(647 - self.tk) + (647 ** 2) / (647 - self.tk)) f_5 = self.k_1[x] / (self.tk ** 2) + self.fl[x] * ((self.tc ** 2) / (self.tk ** 2)) return f_1 + f_2 + f_3 + f_4 + f_5 self.beta0_der_t = Fl(0) self.beta1_der_t = Fl(1) self.beta2_der_t = 0 self.C0_der_t = Fl(2) self.C1_der_t = 0 self.C2_der_t = 0 self.D0_der_t = 0 self.D1_der_t = 0 self.D2_der_t = 0 self.params_der_t = np.array([self.beta0_der_t, self.beta1_der_t, self.beta2_der_t, self.C0_der_t, self.C1_der_t, self.C2_der_t, self.D0_der_t, self.D1_der_t, self.D2_der_t]) super().__init__(tk, pa)
def __init__(self, tk, pa=1): """ constructor :param tk: temperature in kelvin :param pa: pressure in atmospheres :instantiate: temperature, pressure, stoichiometry coefficients, Pitzer Parameters """ self.tk = tk self.pa = pa # Calculations Na2SO4 parameters and coefficients self.mat_stoich = np.array([[2, 1], [1, -2]]) self.m_ref = 5.550825 self.y_ref = 10 self.m_weight = 142.04 self.p_ref = np.array([self.m_weight, self.m_ref, self.y_ref]) # values for ion strength dependence and ion size constants in the extended Pitzer model self.alpha_b1 = 2.0 self.alpha_b2 = 0 self.alpha_c1 = 0 self.alpha_c2 = 0 self.alpha_d1 = 0 self.alpha_d2 = 0 self.b_param = 1.2 self.ion_param = np.array([ self.alpha_b1, self.alpha_b2, self.alpha_c1, self.alpha_c2, self.alpha_d1, self.alpha_d2, self.b_param ]) self.p = np.zeros(12) self.p[0] = -5.11686e5 self.p[1] = 5.43000e3 self.p[2] = -2.18218e1 self.p[3] = 3.99915e-2 self.p[4] = -2.83513e-5 self.p[5] = 1.79274e-2 self.p[6] = 1.28610 self.p[7] = -1.06978e-2 self.p[8] = 2.96022e-5 self.p[9] = -2.70365e-8 self.p[10] = 4.59690e-1 self.p[11] = -1.31097e-3 # Pitzer Parameters self.beta0 = 0 self.beta1 = 0 self.beta2 = 0 self.C0 = 0 self.C1 = 0 self.C2 = 0 self.D0 = 0 self.D1 = 0 self.D2 = 0 self.params = np.array([ self.beta0, self.beta1, self.beta2, self.C0, self.C1, self.C2, self.D0, self.D1, self.D2 ]) # Pitzer Parameters pressure derivative self.pr = un.atm_2_bar(self.pa) self.vp = self.p[0] / self.tk + self.p[ 1] + self.p[2] * self.tk + self.p[3] * self.tk**2 + self.p[ 4] * self.tk**3 + self.p[5] * self.pr self.beta0_der_p = self.p[6] / self.tk + self.p[ 7] + self.p[8] * self.tk + self.p[9] * self.tk**2 self.beta1_der_p = self.p[10] / self.tk + self.p[11] self.beta2_der_p = 0 self.C0_der_p = 0 self.C1_der_p = 0 self.C2_der_p = 0 self.D0_der_p = 0 self.D1_der_p = 0 self.D2_der_p = 0 self.params_der_p = np.array([ self.vp, self.beta0_der_p, self.beta1_der_p, self.beta2_der_p, self.C0_der_p, self.C1_der_p, self.C2_der_p, self.D0_der_p, self.D1_der_p, self.D2_der_p ]) # Pitzer Parameters temperature derivative self.beta0_der_t = 0 self.beta1_der_t = 0 self.beta2_der_t = 0 self.C0_der_t = 0 self.C1_der_t = 0 self.C2_der_t = 0 self.D0_der_t = 0 self.D1_der_t = 0 self.D2_der_t = 0 self.params_der_t = np.array([ self.beta0_der_t, self.beta1_der_t, self.beta2_der_t, self.C0_der_t, self.C1_der_t, self.C2_der_t, self.D0_der_t, self.D1_der_t, self.D2_der_t ]) super().__init__(tk, pa)
def __init__(self, tk, pa=1): """ constructor :param tk: temperature in kelvin :param pa: pressure in atmospheres :instantiate: temperature, pressure, molecular weight, polarizability, dipole moment """ super().__init__(tk, pa) # Calculations for density self.t = self.tk - un.celsius_2_kelvin(0) # pressure in applied bar according to Fine and Millero self.y = un.atm_2_bar(self.pa - 1) self.den1 = 0.9998396 + self.t * 18.224944e-3 - 7.922210e-6 * self.t**2 - 55.44846e-9 * self.t**3 self.den2 = 149.7562e-12 * self.t**4 - 393.2952e-15 * self.t**5 self.V0 = (1 + self.t * 18.159725e-3) / (self.den1 + self.den2) self.B = 19654.320 + 147.037 * self.t - 2.21554 * self.t**2 + 1.0478e-2 * self.t**3 - 2.2789e-5 * self.t**4 self.a1 = 3.2891 - 2.3910e-3 * self.t + 2.8446e-4 * self.t**2 - 2.82e-6 * self.t**3 + 8.477e-9 * self.t**4 self.a2 = 6.245e-5 - 3.913e-6 * self.t - 3.499e-8 * self.t**2 + 7.942e-10 * self.t**3 - 3.299e-12 * self.t**4 # this in cm^3/gram self.vol = self.V0 * ( 1 - (self.y / (self.B + self.a1 * self.y + self.a2 * self.y**2))) # density in kg/m^3 self.rt = 1e3 / self.vol # Calculations for molar volume self.molVol = 1e-3 * self.MolecularWeight / self.rt # Calculations for dielectric constant # convert from atmospheres to MPa self.p_mpa = 1e-6 * un.atm_2_pascal(self.pa) # coefficients self.b = np.zeros(9) self.b[0] = -4.044525e-2 self.b[1] = 103.6180 self.b[2] = 75.32165 self.b[3] = -23.23778 self.b[4] = -3.548184 self.b[5] = -1246.311 self.b[6] = 263307.7 self.b[7] = -6.928953e-1 self.b[8] = -204.4473 def g(x, y): t1 = self.b[0] * y / x + self.b[1] / np.sqrt(x) + self.b[2] / ( x - 215) + self.b[3] / np.sqrt(x - 215) t2 = self.b[4] / (self.tk - 215)**0.25 t3 = np.exp(self.b[5] / x + self.b[6] / x**2 + self.b[7] * y / x + self.b[8] * y / x**2) return 1 + 1e-3 * self.rt * (t1 + t2 + t3) self.fac = un.one_over4pi_epsilon0() * 4 * np.pi * self.mu**2 / ( 3 * un.k_boltzmann() * self.tk) self.b_fac_0 = self.fac * g(self.tk, self.p_mpa) self.b_fac_1 = self.alpha + self.b_fac_0 self.b_fac = self.rt * un.avogadro() * self.b_fac_1 / ( 3.0 * self.MolecularWeight / 1000) self.dielectricConstant = 0.25 * ( 1 + 9 * self.b_fac + 3 * np.sqrt(1 + 2 * self.b_fac + 9 * self.b_fac**2)) # Calculations for compressibility self.beta = self.V0 * (self.B - self.a2 * self.y**2) / ( self.vol * (self.B + self.a1 * self.y + self.a2 * self.y**2)**2) self.comp = un.atm_2_bar(self.beta)
def __init__(self, tk, pa=1): """ constructor :param tk: temperature in kelvin :param pa: pressure in atmospheres :instantiate: temperature, pressure, stoichiometry coefficients, Pitzer Parameters """ self.tk = tk self.pa = pa # Calculations MgCl2 parameters and coefficients self.mat_stoich = np.array([[1, 2], [2, -1]]) self.m_ref = 5.550825 self.y_ref = 10 self.m_weight = 95.211 self.p_ref = np.array([self.m_weight, self.m_ref, self.y_ref]) # values for ion strength dependence and ion size constants in the extended Pitzer model self.alpha_b1 = 2.0 self.alpha_b2 = 0 self.alpha_c1 = 0.4 self.alpha_c2 = 0.28 self.alpha_d1 = 0 self.alpha_d2 = 0 self.b_param = 1.2 self.ion_param = np.array([ self.alpha_b1, self.alpha_b2, self.alpha_c1, self.alpha_c2, self.alpha_d1, self.alpha_d2, self.b_param ]) self.a = np.array([[[ -5.50111455e1, 7.2122055200e1, 5.924282400000, 0.000000000000, 0.000000000000, 4.0898005200e-2 ], [ 1.5013032600e1, -1.771450850e1, -1.65126386000, -1.02256042000, 0.000000000000, 0.0000000000000 ], [ -1.58107430e-1, 1.143971530e-1, 1.893998220e-2, 3.770186170e-2, -2.28040769e-3, -2.951198450e-4 ], [ 2.304099190e-4, 0.000000000000, -2.99972128e-5, -7.91682934e-5, 1.374258890e-5, 6.9100122700e-7 ], [ -1.31768095e-7, -1.43588435e-7, 1.891742910e-8, 5.913142580e-8, -1.94821902e-8, -5.32314849e-10 ], [ -1.26699609e-28, 1.72952766e-27, 0.00000000000, 0.000000000000, 1.04649784e-28, 3.979618090e-31 ], [ 2.821974990e2, 3.41920714000e3, 5.4903020100e1, -2.284930840e2, 0.000000000000, 0.0000000000000 ]], [[ 0.00000000000, 0.0000000000000, 4.501140480e-2, 0.000000000000, 0.000000000000, 0.0000000000000 ], [ 0.00000000000, 2.2844061200e-4, -1.08427926e-2, 0.000000000000, 0.000000000000, 0.0000000000000 ], [ 8.396619600e-5, 0.000000000000, 7.410418640e-5, -7.79259941e-5, 0.000000000000, 0.0000000000000 ], [ -4.60207270e-7, 0.000000000000, -5.99961498e-8, 4.286758760e-7, 0.000000000000, 0.0000000000000 ], [ 6.21165614e-10, 0.000000000000, 0.000000000000, -5.77509662e-10, 0.000000000000, 0.000000000000 ], [ 8.43555937e-31, -1.77573402e-29, 0.00000000000, 0.000000000000, 0.000000000000, 0.0000000000000 ], [ 0.000000000000, -2.2966887900e2, -4.6056284700, 0.000000000000, 0.000000000000, 0.0000000000000 ]], [[ 0.000000000000, 0.0000000000000, 0.00000000000, -5.13962051e-4, 0.000000000000, 0.0000000000000 ], [ 0.000000000000, 0.0000000000000, 0.00000000000, 9.307611420e-5, 0.000000000000, 0.0000000000000 ], [ 0.000000000000, -2.714850860e-7, 0.00000000000, 0.000000000000, 0.000000000000, 0.0000000000000 ], [ 0.000000000000, 0.0000000000000, 0.00000000000, 0.000000000000, 0.000000000000, 0.0000000000000 ], [ 0.000000000000, 0.0000000000000, -1.39016981e-15, -7.43350922e-13, 0.000000000000, 0.0000000000 ], [ 0.000000000000, 0.0000000000000, 0.00000000000, 0.000000000000, 0.000000000000, 0.0000000000000 ], [ -1.11176553000, 1.01000272e1, 1.40556304000e-1, 1.127215570000, 0.000000000000, 0.0000000000000 ]]]) self.b = np.array([[ -1.17446972e4, 2.865416060e3, -2.279680760e1, 3.09897542e-2, -1.92379975e-5, 1.674471870e-26, -1.91185804e6 ], [ 0.00000000000, 0.00000000000, -4.00100143e-4, 0.00000000000, -2.43204343e-8, -6.04921882e-28, 1.080249060e5 ], [ 0.00000000000, 1.19091585e-2, -4.19764987e-4, 7.93310194e-7, 0.000000000000, 0.0000000000000, -1.66310231e3 ]]) # Pitzer Parameters self.pr = un.atm_2_pascal(self.pa) / 1e6 self.tc = 298.15 def Fg(x): f_1 = self.a[0][0][x] + self.a[0][1][x] * np.log( self.tk) + self.a[0][2][x] * self.tk + self.a[0][3][ x] * self.tk**2 + self.a[0][4][x] * self.tk**3 + self.a[0][ 5][x] * self.tk**10 + self.a[0][6][x] / ( (647 - self.tk)**2) f_2 = self.a[1][0][x] + self.a[1][1][x] * np.log( self.tk) + self.a[1][2][x] * self.tk + self.a[1][3][ x] * self.tk**2 + self.a[1][4][x] * self.tk**3 + self.a[1][ 5][x] * self.tk**10 + self.a[1][6][x] / ( (647 - self.tk)**2) f_3 = self.a[2][0][x] + self.a[2][1][x] * np.log( self.tk) + self.a[2][2][x] * self.tk + self.a[2][3][ x] * self.tk**2 + self.a[2][4][x] * self.tk**3 + self.a[2][ 5][x] * self.tk**10 + self.a[2][6][x] / ( (647 - self.tk)**2) return f_1 + f_2 * self.pr + f_3 * (self.pr**2) / 2 self.beta0 = Fg(0) self.beta1 = Fg(1) self.beta2 = 0 self.C0 = Fg(2) self.C1 = Fg(3) self.C2 = Fg(4) self.D0 = Fg(5) self.D1 = 0 self.D2 = 0 self.params = np.array([ self.beta0, self.beta1, self.beta2, self.C0, self.C1, self.C2, self.D0, self.D1, self.D2 ]) # Pitzer Parameters pressure derivative def Fv(x): f_2 = self.a[1][0][x] + self.a[1][1][x] * np.log( self.tk) + self.a[1][2][x] * self.tk + self.a[1][3][ x] * self.tk**2 + self.a[1][4][x] * self.tk**3 + self.a[1][ 5][x] * self.tk**10 + self.a[1][6][x] / ( (647 - self.tk)**2) f_3 = self.a[2][0][x] + self.a[2][1][x] * np.log( self.tk) + self.a[2][2][x] * self.tk + self.a[2][3][ x] * self.tk**2 + self.a[2][4][x] * self.tk**3 + self.a[2][ 5][x] * self.tk**10 + self.a[2][6][x] / ( (647 - self.tk)**2) return f_2 + f_3 * self.pr def Fv_vp(): V_1 = self.b[0][0] + self.b[0][1] * np.log( self.tk ) + self.b[0][2] * self.tk + self.b[0][3] * self.tk**2 + self.b[0][ 4] * self.tk**3 + self.b[0][5] * self.tk**10 + self.b[0][6] / ( (647 - self.tk)**2) V_2 = self.b[1][0] + self.b[1][1] * np.log( self.tk ) + self.b[1][2] * self.tk + self.b[1][3] * self.tk**2 + self.b[1][ 4] * self.tk**3 + self.b[1][5] * self.tk**10 + self.b[1][6] / ( (647 - self.tk)**2) V_3 = self.b[2][0] + self.b[2][1] * np.log( self.tk ) + self.b[2][2] * self.tk + self.b[2][3] * self.tk**2 + self.b[2][ 4] * self.tk**3 + self.b[2][5] * self.tk**10 + self.b[2][6] / ( (647 - self.tk)**2) return V_1 + V_2 * self.pr + V_3 * self.pr**2 self.vp = Fv_vp() self.beta0_der_p = ( (Fv(0) / 1e6) * un.atm_2_pascal(1)) / un.atm_2_bar(1) self.beta1_der_p = ( (Fv(1) / 1e6) * un.atm_2_pascal(1)) / un.atm_2_bar(1) self.beta2_der_p = 0 self.C0_der_p = ((Fv(2) / 1e6) * un.atm_2_pascal(1)) / un.atm_2_bar(1) self.C1_der_p = ((Fv(3) / 1e6) * un.atm_2_pascal(1)) / un.atm_2_bar(1) self.C2_der_p = ((Fv(4) / 1e6) * un.atm_2_pascal(1)) / un.atm_2_bar(1) self.D0_der_p = ((Fv(5) / 1e6) * un.atm_2_pascal(1)) / un.atm_2_bar(1) self.D1_der_p = 0 self.D2_der_p = 0 self.params_der_p = np.array([ self.vp, self.beta0_der_p, self.beta1_der_p, self.beta2_der_p, self.C0_der_p, self.C1_der_p, self.C2_der_p, self.D0_der_p, self.D1_der_p, self.D2_der_p ]) # Pitzer Parameters temperature derivative def Fl(x): f_1 = self.a[0][1][x] / self.tk + self.a[0][2][ x] + 2 * self.a[0][3][x] * self.tk + 3 * self.a[0][4][ x] * self.tk**2 + 10 * self.a[0][5][ x] * self.tk**9 + 2 * self.a[0][6][x] / ( (647 - self.tk)**3) f_2 = self.a[1][1][x] / self.tk + self.a[1][2][ x] + 2 * self.a[1][3][x] * self.tk + 3 * self.a[1][4][ x] * self.tk**2 + 10 * self.a[1][5][ x] * self.tk**9 + 2 * self.a[1][6][x] / ( (647 - self.tk)**3) f_3 = self.a[2][1][x] / self.tk + self.a[2][2][ x] + 2 * self.a[2][3][x] * self.tk + 3 * self.a[2][4][ x] * self.tk**2 + 10 * self.a[2][5][ x] * self.tk**9 + 2 * self.a[2][6][x] / ( (647 - self.tk)**3) return f_1 + f_2 * self.pr + f_3 * (self.pr**2) / 2 self.beta0_der_t = Fl(0) self.beta1_der_t = Fl(1) self.beta2_der_t = 0 self.C0_der_t = Fl(2) self.C1_der_t = 0 self.C2_der_t = 0 self.D0_der_t = 0 self.D1_der_t = 0 self.D2_der_t = 0 self.params_der_t = np.array([ self.beta0_der_t, self.beta1_der_t, self.beta2_der_t, self.C0_der_t, self.C1_der_t, self.C2_der_t, self.D0_der_t, self.D1_der_t, self.D2_der_t ]) super().__init__(tk, pa)
def __init__(self, tk, pa=1): """ constructor :param tk: temperature in kelvin :param pa: pressure in atmospheres :instantiate: temperature, pressure, stoichiometry coefficients, Pitzer Parameters """ self.tk = tk self.pa = pa # Calculations nacl parameters and coefficients self.mat_stoich = np.array([[1, 1], [1, -1]]) self.m_ref = 5.550825 self.y_ref = 10 self.m_weight = 58.4428 self.p_ref = np.array([self.m_weight, self.m_ref, self.y_ref]) # values for ion strength dependence and ion size constants in the extended Pitzer model self.alpha_b1 = 2.0 self.alpha_b2 = 0 self.alpha_c1 = 0 self.alpha_c2 = 0 self.alpha_d1 = 0 self.alpha_d2 = 0 self.b_param = 1.2 self.ion_param = np.array([ self.alpha_b1, self.alpha_b2, self.alpha_c1, self.alpha_c2, self.alpha_d1, self.alpha_d2, self.b_param ]) self.cm = np.zeros(28) self.cm[0] = 1.0249125e3 self.cm[1] = 2.7796679e-1 self.cm[2] = -3.0203919e-4 self.cm[3] = 1.4977178e-6 self.cm[4] = -7.2002329e-2 self.cm[5] = 3.1453130e-4 self.cm[6] = -5.9795994e-7 self.cm[7] = -6.6596010e-6 self.cm[8] = 3.0407621e-8 self.cm[9] = 5.3699517e-5 self.cm[10] = 2.2020163e-3 self.cm[11] = -2.6538013e-7 self.cm[12] = 8.6255554e-10 self.cm[13] = -2.6829310e-2 self.cm[14] = -1.1173488e-7 self.cm[15] = -2.6249802e-7 self.cm[16] = 3.4926500e-10 self.cm[17] = -8.3571924e-13 # exponent in 18 (19 in reference) is barely visible, it is 5 (confirmed) self.cm[18] = 3.0669940e-5 self.cm[19] = 1.9767979e-11 self.cm[20] = -1.9144105e-10 self.cm[21] = 3.1387857e-14 self.cm[22] = -9.6461948e-9 self.cm[23] = 2.2902837e-5 self.cm[24] = -4.3314252e-4 self.cm[25] = -9.0550901e-8 self.cm[26] = 8.6926600e-11 self.cm[27] = 5.1904777e-4 self.qm = np.zeros(19) self.qm[0] = 0.0765 self.qm[1] = -777.03 self.qm[2] = -4.4706 self.qm[3] = 0.008946 self.qm[4] = -3.3158e-6 self.qm[5] = 0.2664 # this value is not provided self.qm[6] = 0 # this value is not provided self.qm[7] = 0 self.qm[8] = 6.1608e-5 self.qm[9] = 1.0715e-6 self.qm[10] = 0.00127 self.qm[11] = 33.317 self.qm[12] = 0.09421 self.qm[13] = -4.655e-5 # this value is not provided self.qm[14] = 0 self.qm[15] = 41587.11 self.qm[16] = -315.90 self.qm[17] = 0.8514 self.qm[18] = -8.3637e-4 # Pitzer Parameters self.tc = 298.15 self.beta0_1 = self.qm[0] + self.qm[1] * ( 1 / self.tk - 1 / self.tc) + self.qm[2] * np.log(self.tk / self.tc) self.beta0_2 = self.qm[3] * (self.tk - self.tc) + self.qm[4] * ( self.tk**2 - self.tc**2) self.beta0 = self.beta0_1 + self.beta0_2 self.beta1 = self.qm[5] + self.qm[8] * ( self.tk - self.tc) + self.qm[9] * (self.tk**2 - self.tc**2) self.beta2 = 0 self.c_phi_1 = self.qm[10] + self.qm[11] * ( 1 / self.tk - 1 / self.tc) + self.qm[12] * np.log( self.tk / self.tc) self.c_phi = self.c_phi_1 + self.qm[13] * (self.tk - self.tc) self.C0 = self.c_phi / 2 self.C1 = 0 self.C2 = 0 self.D0 = 0 self.D1 = 0 self.D2 = 0 self.params = np.array([ self.beta0, self.beta1, self.beta2, self.C0, self.C1, self.C2, self.D0, self.D1, self.D2 ]) # Pitzer Parameters pressure derivative self.pr = un.atm_2_bar(self.pa) self.pr_atm = un.atm_2_bar(1) self.vp_0 = self.cm[0] + self.cm[1] * self.tk + self.cm[ 2] * self.tk**2 + self.cm[3] * self.tk**3 self.vp_1 = (self.pr - self.pr_atm) * ( self.cm[4] + self.cm[5] * self.tk + self.cm[6] * self.tk**2) self.vp_2 = (self.pr - self.pr_atm)**2 * (self.cm[7] + self.cm[8] * self.tk) self.vp_sum = self.vp_0 + self.vp_1 + self.vp_2 self.bp_0 = self.cm[9] + self.cm[10] / (self.tk - 227) + self.cm[ 11] * self.tk + self.cm[12] * self.tk**2 + self.cm[13] / (680 - self.tk) self.bp_1_1 = self.cm[14] + self.cm[15] / ( self.tk - 227) + self.cm[16] * self.tk + self.cm[17] * self.tk**2 self.bp_1 = (self.bp_1_1 + self.cm[18] / (680 - self.tk)) * (self.pr - self.pr_atm) self.bp_2_1 = self.cm[19] + self.cm[20] / ( self.tk - 227) + self.cm[21] * self.tk + self.cm[22] / (680 - self.tk) self.bp_2 = self.bp_2_1 * (self.pr - self.pr_atm)**2 self.beta0_der_p = self.bp_0 + self.bp_1 + self.bp_2 self.beta1_der_p = 0 self.beta2_der_p = 0 self.cq = self.cm[23] + self.cm[24] / (self.tk - 227) + self.cm[ 25] * self.tk + self.cm[26] * self.tk**2 + self.cm[27] / (680 - self.tk) self.cp = 0.5 * self.cq self.C0_der_p = self.cp self.C1_der_p = 0 self.C2_der_p = 0 self.D0_der_p = 0 self.D1_der_p = 0 self.D2_der_p = 0 # calculates the molar volume at infinite dilution (vp) # the factor 10 is the conversion from J to bar cm^3 self.ct = 10 * un.r_gas() * self.tk # molar volume water in cm^3/mol self.vol_water = 1e6 * bp.WaterPropertiesFineMillero( self.tk, self.pa).molar_volume() self.mv_i_0 = self.vp_sum / self.m_ref - self.y_ref * self.vol_water self.mv_i_1 = -2 * bp.WaterPropertiesFineMillero(self.tk, self.pa).a_v( ) * (0.5 * np.log(1 + self.b_param * np.sqrt(self.m_ref)) / self.b_param) self.mv_i_2 = -2 * self.ct * (self.m_ref * self.beta0_der_p + self.m_ref**2 * self.C0_der_p) # this is in cm^3/mol self.mv_i = self.mv_i_0 + self.mv_i_1 + self.mv_i_2 # return in SI m^3 self.molar_vol_infinite_dilution = 1e-6 * self.mv_i # infinite molar volume, convert to cm^3/mol self.vp = 1e6 * self.molar_vol_infinite_dilution self.params_der_p = np.array([ self.vp, self.beta0_der_p, self.beta1_der_p, self.beta2_der_p, self.C0_der_p, self.C1_der_p, self.C2_der_p, self.D0_der_p, self.D1_der_p, self.D2_der_p ]) # Pitzer Parameters temperature derivative self.beta0_der_t = 2 * self.qm[4] * self.tk + self.qm[ 2] / self.tk - self.qm[1] / (self.tk**2) + self.qm[3] self.beta1_der_t = 2 * self.qm[9] * self.tk + self.qm[8] self.beta2_der_t = 0 self.c_phi_der_t = self.qm[12] / self.tk - self.qm[11] / ( self.tk**2) + self.qm[13] self.C0_der_t = self.c_phi_der_t / 2 self.C1_der_t = 0 self.C2_der_t = 0 self.D0_der_t = 0 self.D1_der_t = 0 self.D2_der_t = 0 self.params_der_t = np.array([ self.beta0_der_t, self.beta1_der_t, self.beta2_der_t, self.C0_der_t, self.C1_der_t, self.C2_der_t, self.D0_der_t, self.D1_der_t, self.D2_der_t ]) super().__init__(tk, pa)
def test_atm_conversion(self): # 1 atm = 101325 Pa self.assertEqual(un.atm_2_pascal(1), 101325) # 1 atm = 1.01325 bar self.assertEqual(un.atm_2_bar(1), 1.01325)
def __init__(self, tk, pa=1): """ constructor :param tk: temperature in kelvin :param pa: pressure in atmospheres :instantiate: temperature, pressure, molecular weight, polarizability, dipole moment """ super().__init__(tk, pa) """ Calculations for density """ self.t = self.tk - un.celsius_2_kelvin(0) # pressure in applied bar according to Fine and Millero self.y = un.atm_2_bar(self.pa - 1) self.den1 = 0.9998396 + self.t * 18.224944e-3 - 7.922210e-6 * self.t ** 2 - 55.44846e-9 * self.t ** 3 self.den2 = 149.7562e-12 * self.t ** 4 - 393.2952e-15 * self.t ** 5 self.V0 = (1 + self.t * 18.159725e-3) / (self.den1 + self.den2) self.B = 19654.320 + 147.037 * self.t - 2.21554 * self.t ** 2 + 1.0478e-2 * self.t ** 3 - 2.2789e-5 * self.t ** 4 self.a1 = 3.2891 - 2.3910e-3 * self.t + 2.8446e-4 * self.t ** 2 - 2.82e-6 * self.t ** 3 + 8.477e-9 * self.t ** 4 self.a2 = 6.245e-5 - 3.913e-6 * self.t - 3.499e-8 * self.t ** 2 + 7.942e-10 * self.t ** 3 - 3.299e-12 * self.t ** 4 # this in cm^3/gram self.vol = self.V0 * (1 - (self.y / (self.B + self.a1 * self.y + self.a2 * self.y ** 2))) # density in kg/m^3 self.rt = 1e3 / self.vol # Calculations for molar volume self.molVol = 1e-3 * self.MolecularWeight / self.rt # Calculations for dielectric constant # coefficients self.U = np.zeros(9) self.U[0] = 3.4279e2 self.U[1] = -5.0866e-3 self.U[2] = 9.4690e-7 self.U[3] = -2.0525 self.U[4] = 3.1159e3 self.U[5] = -1.8289e2 self.U[6] = -8.0325e3 self.U[7] = 4.2142e6 self.U[8] = 2.1417 self.D100 = self.U[0] * (np.exp(self.U[1] * self.tk + self.U[2] * self.tk ** 2)) self.C = self.U[3] + self.U[4] / (self.U[5] + self.tk) self.B_dc = self.U[6] + (self.U[7] / self.tk) + self.U[8] * self.tk self.dielectricConstant = self.D100 + self.C * np.log((self.B_dc + un.atm_2_bar(self.pa)) / (self.B_dc + 1000)) # dielectric constant derivative with respect to pressure self.dielectricConstant_der_p = un.atm_2_bar(1) * self.C / (self.B_dc + (un.atm_2_bar(self.pa))) # dielectric constant derivative with respect to temperature self.val_1 = (un.atm_2_bar(self.pa) - 1000) * (self.U[3] * (self.U[5] + self.tk) + self.U[4]) * (self.U[8] * self.tk ** 2 - self.U[7]) self.val_2 = (self.U[5] + self.tk) * (self.U[6] * self.tk + self.tk * (self.U[8] * self.tk + 1000) + self.U[7]) * (self.tk * (un.atm_2_bar(self.pa) + self.U[8] * self.tk) + self.U[6] * self.tk + self.U[7]) self.val_3 = (self.U[4] * np.log((un.atm_2_bar(self.pa) + (self.U[7] / self.tk) + self.U[8] * self.tk + self.U[6]) / (1000 + (self.U[7] / self.tk) + self.U[8] * self.tk + self.U[6]))) / ((self.U[5] + self.tk) ** 2) self.val_4 = (self.U[0] * np.exp(self.U[1] * self.tk + self.U[2] * self.tk ** 2)) * (2 * self.U[2] * self.tk + self.U[1]) self.dielectricConstant_der_t = -(self.val_1 / self.val_2) - self.val_3 + self.val_4 # Calculations for compressibility self.beta = self.V0 * (self.B - self.a2 * self.y ** 2) / ( self.vol * (self.B + self.a1 * self.y + self.a2 * self.y ** 2) ** 2) self.comp = un.atm_2_bar(self.beta) # Calculations for osmotic coefficient # Bjerrum length self.l_b = un.e_square() / (un.k_boltzmann() * self.tk * self.dielectricConstant) self.fac = 2 * np.pi * un.avogadro() * self.rt * self.l_b ** 3 self.osmotic_coefficient = np.sqrt(self.fac) / 3 # Calculations for apparent molal volume # add a factor 1e6 and convert to Pascal (lat two parts of a_v_0) self.a_v_0 = 2 * self.osmotic_coefficient * un.r_gas() * self.tk * 1e6 / un.atm_2_pascal(1) self.a_v_1 = self.dielectricConstant self.a_v_2 = 3 * self.dielectricConstant_der_p self.a_v_3 = self.comp self.app_molal_vol = self.a_v_0 * (self.a_v_2 / self.a_v_1 - self.a_v_3) # Calculations for enthalpy coefficient # thermal expansion coefficient self.V0_der_1 = 2.85685e-14 * self.t ** 5 - 6.19212e-12 * self.t ** 4 + 1.41483e-9 * self.t ** 3 self.V0_der_2 = 3.10211e-7 * self.t ** 2 + 0.0000158444 * self.t - 0.0000681318 self.V0_der_3 = -3.93295e-13 * self.t ** 5 + 1.49756e-10 * self.t ** 4 - 5.54485e-8 * self.t ** 3 self.V0_der_4 = -7.92221e-6 * self.t ** 2 + 0.0182249 * self.t + 0.99984 self.V0_der = (self.V0_der_1 + self.V0_der_2) / ((self.V0_der_3 + self.V0_der_4) ** 2) self.B_der = -0.000091156 * self.t ** 3 + 0.031434 * self.t ** 2 - 4.43108 * self.t + 147.037 self.a1_der = 3.3908e-8 * self.t ** 3 - 8.46e-6 * self.t ** 2 + 0.00056892 * self.t - 0.002391 self.a2_der = -1.3196e-11 * self.t ** 3 + 2.3826e-9 * self.t ** 2 - 6.998e-8 * self.t - 3.913e-6 self.aw_term_1 = (1 / self.vol) * self.V0_der self.aw_term_2 = -((self.y * self.V0_der) / (self.vol * (self.B + self.a1 * self.y + self.a2 * self.y ** 2))) self.aw_term_3 = self.y * self.V0 * ((self.B_der + self.y * self.a1_der + self.a2_der * self.y ** 2) / (self.vol * (self.B + self.a1 * self.y + self.a2 * self.y ** 2) ** 2)) self.aw = self.aw_term_1 + self.aw_term_2 + self.aw_term_3 # enthalpy coefficient self.enthalpy_coefficient = -6 * self.osmotic_coefficient * un.r_gas() * self.tk * (1 + self.tk * (1 / self.dielectricConstant) * self.dielectricConstant_der_t + self.tk * (self.aw / 3))