### VBA: Added Henry sheet and exported VBA code

parent 8d53a8ee
This diff is collapsed.
 ... @@ -2,123 +2,140 @@ Attribute VB_Name = "Brine_gas" ... @@ -2,123 +2,140 @@ Attribute VB_Name = "Brine_gas" ' Properties of gas mixture (density, viscosity, specific heat capacity, specific enthalpy) ' Properties of gas mixture (density, viscosity, specific heat capacity, specific enthalpy) ' by Henning Francke francke@gfz-potsdam.de ' by Henning Francke francke@gfz-potsdam.de ' 2014 GFZ Potsdam ' 2020 GFZ Potsdam Option Explicit Option Explicit Option Base 1 Option Base 1 Const nX = nX_gas + 1 Public Const nX_gas = 3 Public GasDataSet As Boolean Public Const nX = nX_gas + 1 Public Const ignoreLimitN2_T = True Const R = 8.314472 Const nM_CO2 = 1 'number of ions per molecule Const nM_N2 = 1 'number of ions per molecule Const nM_CH4 = 1 'number of ions per molecule Function MM_vec() Function MM_vec() 'generates double vector of molar masses 'generates double vector of molar masses Dim V(1 To nX_gas + 1) As Double Dim V(1 To nX_gas + 1) As Double V(1) = M_CO2 If Not GasDataSet Then V(2) = M_N2 DefineGasData V(3) = M_CH4 End If V(4) = M_H2O If i_CO2 > 0 Then V(i_CO2 - nX_salt) = CO2.MM End If If i_N2 > 0 Then V(i_N2 - nX_salt) = N2.MM End If If i_CH4 > 0 Then V(i_CH4 - nX_salt) = CH4.MM End If If i_H2 > 0 Then V(i_H2 - nX_salt) = H2.MM End If If H2O.MM = 0 Then DefineWater End If V(nX_gas + 1) = H2O.MM MM_vec = V MM_vec = V End Function End Function Function nM_vec() As Double() Function nM_vec() As Double() 'generates double vector of molar masses 'generates double vector of molar numbers Dim V(1 To nX_gas + 1) As Double Dim V(1 To nX_gas + 1) As Double V(1) = CO2.nM V(1) = CO2.nM V(2) = N2.nM V(2) = N2.nM V(3) = CH4.nM V(3) = CH4.nM V(4) = H2O.nM ' V(4) = nM_H2 nM_vec = V End Function Function R_gas(Xi) Dim X_ X_ = CheckMassVector(Xi, nX) If VarType(X_) = vbString Then R_gas = X_ Exit Function End If R_gas = ScalProd(X_, Array(CO2.R, N2.R, CH4.R, H2O.R)) End Function 'ABOVE SPECIFIC TO GAS COMPOSITION If i_CO2 > 0 Then 'BELOW GENERIC PART V(i_CO2 - nX_salt) = CO2.nM Private Function MM_gas(X_) As Double MM_gas = CheckMassVector(X_) If VarType(MM_gas) <> vbBoolean Then Exit Function End If End If MM_gas = ScalProd(X_, MM_vec) End Function If i_N2 > 0 Then V(i_N2 - nX_salt) = N2.nM Function density(p As Double, T As Double, Xin) 'Density of an ideal mixture of ideal gases If DebugMode Then Debug.Print "Running BrineGas.Density(" & p / 10 ^ 5 & " bar," & T - 273.15 & " C" End If End If Dim X_ If i_CH4 > 0 Then X_ = CheckMassVector(Xin, nX) V(i_CH4 - nX_salt) = CH4.nM If VarType(X_) = vbString Then density = X_ & " (Brine_gas.density)" Exit Function End If End If density = p / (T * R_gas(X_)) If i_H2 > 0 Then Debug.Assert density > 0 V(i_H2 - nX_salt) = H2.nM End If V(nX_gas + 1) = H2O.nM nM_vec = V End Function End Function Private Function SingleGasNasa_h_T(data As DataRecord, T As Double, Optional exclEnthForm As Boolean = True, Optional ZeroAt0K As Boolean = True, Optional h_off As Double = 0) As Double ' end of gas definition SingleGasNasa_h_T = _ IIf(T < data.Tlimit, data.R * ((-data.alow(1) + T * (data.blow(1) + data.alow(2) * Math.Log(T) + T * (1# * data.alow(3) + T * (0.5 * data.alow(4) + T * (1 / 3 * data.alow(5) + T * (0.25 * data.alow(6) + 0.2 * data.alow(7) * T)))))) / T) _ , data.R * ((-data.ahigh(1) + T * (data.bhigh(1) + data.ahigh(2) * Math.Log(T) + T * (1# * data.ahigh(3) + T * (0.5 * data.ahigh(4) + T * (1 / 3 * data.ahigh(5) + T * (0.25 * data.ahigh(6) + 0.2 * data.ahigh(7) * T)))))) / T)) _ + IIf(exclEnthForm, -data.Hf, 0#) + IIf(ZeroAt0K, data.h0, 0#) + h_off End Function Function specificEnthalpy(p As Double, T As Double, Xin) Function specificEnthalpy(p As Double, T As Double, Xin) 'calculation of specific enthalpy of gas mixture 'calculation of specific enthalpy of gas mixture Dim X_ Dim X_: X_ = CheckMassVector(Xin, nX) X_ = CheckMassVector(Xin, nX) If VarType(X_) = vbString Then If VarType(X_) = vbString Then specificEnthalpy = X_ & " (Brine_gas.specificEnthalpy)" specificEnthalpy = X_ & " (Brine_gas.specificEnthalpy)" Exit Function Exit Function End If End If Dim h_H2O_sat As Double, h_H2O As Double, h_CO2 As Double, h_N2 As Double, h_CH4 As Double ' Dim h_H2O_sat As Double, h_H2O As Double, h_CO2 As Double, h_N2 As Double, h_CH4 As Double h_H2O_sat = Waterh_satv_p(p) 'Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.hv_p(p) ' h_H2O_sat = Waterh_satv_p(p) 'Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.hv_p(p) Dim h_vec() Dim h_vec(nX_gas + 1), h_tmp As Double h_vec() = Array( _ ' h_vec() = Array( _ SingleGasNasa_h_T(CO2, T), _ ' SingleGasNasa_h_T(CO2, T), _ SingleGasNasa_h_T(N2, T), _ ' SingleGasNasa_h_T(N2, T), _ SingleGasNasa_h_T(CH4, T), _ ' SingleGasNasa_h_T(CH4, T), _ Application.Max(h_H2O_sat, SpecificEnthalpy_pT(p, T)) _ ' Application.Max(h_H2O_sat, SpecificEnthalpy_pT(p, T)) _ ) 'to make sure it is gaseous TODO:Take regions directly ' ) 'to make sure it is gaseous TODO:Take regions directly ' For i = 1 To nX_gas If i_CO2 > 0 Then h_tmp = SingleGasNasa_h_T(CO2, T) If Not VarType(h_tmp) = vbDouble Then specificEnthalpy = X_ & "Error in cp calculation for " & CO2.name & " (Brine_gas.specificEnthalpy)" Exit Function End If h_vec(i_CO2 - nX_salt) = h_tmp End If If i_N2 > 0 Then h_tmp = SingleGasNasa_h_T(N2, T) If Not VarType(h_tmp) = vbDouble Then specificEnthalpy = X_ & "Error in cp calculation for " & N2.name & " (Brine_gas.specificEnthalpy" Exit Function End If h_vec(i_N2 - nX_salt) = h_tmp End If If i_CH4 > 0 Then h_tmp = SingleGasNasa_h_T(CH4, T) If Not VarType(h_tmp) = vbDouble Then specificEnthalpy = X_ & "Error in cp calculation for " & CH4.name & " (Brine_gas.specificEnthalpy)" Exit Function End If h_vec(i_CH4 - nX_salt) = h_tmp End If If i_H2 > 0 Then h_tmp = SingleGasNasa_h_T(H2, T) If Not VarType(h_tmp) = vbDouble Then specificEnthalpy = X_ & "Error in cp calculation for " & H2.name & " (Brine_gas.specificEnthalpy)" Exit Function End If h_vec(i_H2 - nX_salt) = h_tmp End If h_tmp = Waterh_satv_p(p) If Not VarType(h_tmp) = vbDouble Then specificEnthalpy = X_ & "Error in cp calculation for " & H2.name & " (Brine_gas.specificEnthalpy)" Exit Function End If h_vec(nX_gas + 1) = Application.Max(h_tmp, SpecificEnthalpy_pT(p, T)) If DebugMode Then If DebugMode Then Debug.Print "Running BrineGas.SpecificEnthalpy(" & p / 10 ^ 5 & " bar," & T - 273.15 & " C, X=" & Vector2String(X_) & ")" Debug.Print "Running BrineGas.SpecificEnthalpy(" & p / 10 ^ 5 & " bar," & T - 273.15 & " C, X=" & Vector2String(X_) & ")" ' Debug.Print "No gas composition, assuming water vapour.(Brine_gas.SpecificHeatCapacity_pTX)" End If End If 'If Not Application.Min(X) > 0 Then ' Debug.Print "No gas composition, assuming water vapour.(Brine_gas.SpecificHeatCapacity_pTX)" 'End If specificEnthalpy = ScalProd(h_vec, X_) 'mass weighted average specificEnthalpy = ScalProd(h_vec, X_) 'mass weighted average End Function Private Function SingleGasNasa_cp_T(data As DataRecord, T As Double, Optional exclEnthForm As Boolean = True, Optional ZeroAt0K As Boolean = True, Optional h_off As Double = 0) As Double SingleGasNasa_cp_T = _ IIf(T < data.Tlimit, _ data.R * (1 / (T * T) * (data.alow(1) + T * (data.alow(2) + T * (1# * data.alow(3) + T * (data.alow(4) + T * (data.alow(5) + T * (data.alow(6) + data.alow(7) * T))))))) _ , data.R * (1 / (T * T) * (data.ahigh(1) + T * (data.ahigh(2) + T * (1# * data.ahigh(3) + T * (data.ahigh(4) + T * (data.ahigh(5) + T * (data.ahigh(6) + data.ahigh(7) * T))))))) _ ) End Function End Function Function specificHeatCapacityCp(p As Double, T As Double, Xin) 'calculation of specific enthalpy of gas mixture Function specificHeatCapacityCp(p As Double, T As Double, Xin) 'calculation of specific enthalpy of gas mixture ... @@ -134,25 +151,120 @@ Function specificHeatCapacityCp(p As Double, T As Double, Xin) 'calculation of s ... @@ -134,25 +151,120 @@ Function specificHeatCapacityCp(p As Double, T As Double, Xin) 'calculation of s Exit Function Exit Function End If End If Dim cp_H2O_sat As Double, cp_H2O As Double, cp_CO2 As Double, cp_N2 As Double, cp_CH4 As Double Dim cp_H2O_sat As Double ', cp_H2O As Double, cp_CO2 As Double, cp_N2 As Double, cp_CH4 As Double cp_CO2 = SingleGasNasa_cp_T(CO2, T) Dim cp_vec(nX_gas + 1) As Double, cp_tmp cp_N2 = SingleGasNasa_cp_T(N2, T) ' cp_vec() = Array(cp_CO2, cp_N2, cp_CH4, cp_H2O) cp_CH4 = SingleGasNasa_cp_T(CH4, T) If i_CO2 > 0 Then cp_tmp = SingleGasNasa_cp_T(CO2, T) If Not VarType(cp_tmp) = vbDouble Then specificHeatCapacityCp = cp_tmp & "Error in cp calculation for " & CO2.name & " (Brine_gas.specificHeatCapacityCp)" Exit Function End If cp_vec(i_CO2 - nX_salt) = cp_tmp End If If i_N2 > 0 Then 'cp_N2 = SingleGasNasa_cp_T(N2, T) cp_tmp = SingleGasNasa_cp_T(N2, T) If Not VarType(cp_tmp) = vbDouble Then specificHeatCapacityCp = X_ & "Error in cp calculation for " & N2.name & " (Brine_gas.specificHeatCapacityCp)" Exit Function End If cp_vec(i_N2 - nX_salt) = cp_tmp End If If i_H2 > 0 Then If Not VarType(cp_tmp) = vbDouble Then specificHeatCapacityCp = X_ & "Error in cp calculation for " & H2.name & " (Brine_gas.specificHeatCapacityCp)" Exit Function End If cp_vec(i_H2 - nX_salt) = cp_tmp End If If i_CH4 > 0 Then ' cp_CH4 = SingleGasNasa_cp_T(CH4, T) cp_tmp = SingleGasNasa_cp_T(CH4, T) If Not VarType(cp_tmp) = vbDouble Then specificHeatCapacityCp = X_ & "Error in cp calculation for " & CH4.name & " (Brine_gas.specificHeatCapacityCp)" Exit Function End If cp_vec(i_CH4 - nX_salt) = cp_tmp End If 'cp_H2O = SingleGasNasa_cp_T(H2O, T) 'cp_H2O = SingleGasNasa_cp_T(H2O, T) cp_H2O = IAPWS.SpecificHeatCapacityCp_pT(Application.Min(p, IAPWS.Waterpsat_T(T) - 1), T) cp_tmp = IAPWS.SpecificHeatCapacityCp_pT(Application.Min(p, IAPWS.Waterpsat_T(T) - 1), T) Dim cp_vec() If Not VarType(cp_tmp) = vbDouble Then cp_vec() = Array(cp_CO2, cp_N2, cp_CH4, cp_H2O) specificHeatCapacityCp = X_ & "Error in cp calculation for " & H2O.name & " (Brine_gas.specificHeatCapacityCp)" Exit Function End If cp_vec(nX_gas + 1) = cp_tmp If DebugMode Then If DebugMode Then Debug.Print "cp_CO2: " & cp_CO2 Debug.Print String2Vector(cp_vec) Debug.Print "cp_N2: " & cp_N2 Debug.Print "cp_CH4: " & cp_CH4 Debug.Print "cp_H2O: " & cp_H2O End If End If specificHeatCapacityCp = ScalProd(cp_vec, X_) 'mass weighted average specificHeatCapacityCp = ScalProd(cp_vec, X_) 'mass weighted average End Function End Function 'ABOVE SPECIFIC TO GAS COMPOSITION 'BELOW GENERIC PART Function R_gas(Xi) Dim X_: X_ = CheckMassVector(Xi, nX) If VarType(X_) = vbString Then R_gas = X_ Exit Function End If ' R_gas = ScalProd(X_, Array(CO2.R_s, N2.R_s, CH4.R_s, H2O.R_s)) ' R_gas = ScalProd(X_, Array(CO2.R, R / M_H2, CH4.R, H2O.R)) R_gas = ScalProd(X_, VecDiv(R, MM_vec)) End Function Private Function MM_gas(X_) As Double MM_gas = CheckMassVector(X_) If VarType(MM_gas) <> vbBoolean Then Exit Function End If MM_gas = ScalProd(X_, MM_vec) End Function Function density(p As Double, T As Double, Xin) 'Density of an ideal mixture of ideal gases If DebugMode Then Debug.Print "Running BrineGas.Density(" & p / 10 ^ 5 & " bar," & T - 273.15 & " C" End If Dim X_ X_ = CheckMassVector(Xin, nX) If VarType(X_) = vbString Then density = X_ & " (Brine_gas.density)" Exit Function End If density = p / (T * R_gas(X_)) Debug.Assert density > 0 End Function Private Function SingleGasNasa_h_T(data As GasDataRecord, T As Double, Optional exclEnthForm As Boolean = True, Optional ZeroAt0K As Boolean = True, Optional h_off As Double = 0) As Double With data SingleGasNasa_h_T = _ IIf(T < .Tlimit, .R_s * ((-.alow(1) + T * (.blow(1) + .alow(2) * Math.Log(T) + T * (1# * .alow(3) + T * (0.5 * .alow(4) + T * (1 / 3 * .alow(5) + T * (0.25 * .alow(6) + 0.2 * .alow(7) * T)))))) / T) _ , .R_s * ((-.ahigh(1) + T * (.bhigh(1) + .ahigh(2) * Math.Log(T) + T * (1# * .ahigh(3) + T * (0.5 * .ahigh(4) + T * (1 / 3 * .ahigh(5) + T * (0.25 * .ahigh(6) + 0.2 * .ahigh(7) * T)))))) / T)) _ + IIf(exclEnthForm, -.Hf, 0#) + IIf(ZeroAt0K, .h0, 0#) + h_off End With End Function Private Function SingleGasNasa_cp_T(data As GasDataRecord, T As Double, Optional exclEnthForm As Boolean = True, Optional ZeroAt0K As Boolean = True, Optional h_off As Double = 0) As Double With data SingleGasNasa_cp_T = _ IIf(T < .Tlimit, _ .R_s * (1 / (T * T) * (.alow(1) + T * (.alow(2) + T * (1# * .alow(3) + T * (.alow(4) + T * (.alow(5) + T * (.alow(6) + .alow(7) * T))))))) _ , .R_s * (1 / (T * T) * (.ahigh(1) + T * (.ahigh(2) + T * (1# * .ahigh(3) + T * (.ahigh(4) + T * (.ahigh(5) + T * (.ahigh(6) + .ahigh(7) * T))))))) _ ) End With End Function Function dynamicViscosity(p As Double, T As Double, Optional X_) Function dynamicViscosity(p As Double, T As Double, Optional X_) dynamicViscosity = GasData.MoistAirDynamicViscosity(T) dynamicViscosity = GasProps.MoistAirDynamicViscosity(T) End Function End Function
This diff is collapsed.
 Attribute VB_Name = "Constants" Attribute VB_Name = "Constants" ' Public Const R = 8.314472 ' Public Const R = 8.314472 Public Const R = 8.3144598 ' Modelica.Constants.R Public Const R = 8.31446261815324 ' Modelica.Constants.R Sub DefineWater() With H2O .name = "H2O" .MM = 0.018015268 '[kg/mol] from Modelica.Media.Water.waterConstants .Hf = -13423382.8172529 .h0 = 549760.647628014 .Tlimit = 1000 .alow = Array(-39479.6083, 575.573102, 0.931782653, 0.00722271286, -0.00000734255737, 4.95504349E-09, -1.336933246E-12) .blow = Array(-33039.7431, 17.24205775) .ahigh = Array(1034972.096, -2412.698562, 4.64611078, 0.002291998307, -0.000000683683048, 9.42646893E-11, -4.82238053E-15) .bhigh = Array(-13842.86509, -7.97814851) .R_s = R / .MM '461.523329085088 .nM = 1 End With End Sub
VBA/GasProps.bas 0 → 100644
This diff is collapsed.
 Attribute VB_Name = "H2solubility_Chabab" ' by Henning Francke francke@gfz-potsdam.de ' 2021 GFZ Potsdam ' Chabab, S., Thveneau, P., Coquelet, C., Corvisier, J. & Paricaud, P. Measurements and predictive models of high-pressure H2 solubility in brine (H2O+NaCl) for underground hydrogen storage application. Int. J. Hydrogen Energy 45, 3220632220 (2020). ' For H2 solubility in pure water (Eq. (13)): 273.15 < T (K) < 373.15; 1 < P (bar) < 203 ' For H2 solubility in NaCl-brine (Eq. (12)): 323.15 < T (K) < 373.15; 10 < P (bar) < 230; 0 < molality (mol/kgw) < 5 Option Explicit Option Base 1 'Const ignoreLimitH2_T = False 'Const ignoreLimitH2_p = False 'Const ignoreLimitH2_b = False 'Public Const M_H2 = 1.008 * 2 / 1000 '[kg/mol] 'Function MM_H2() As Double ' MM_H2 = M_H2 'End Function Function solubility_H2_pTX_Chabab2020(p As Double, T As Double, Xin, p_gas) ' converts from molaltity to mass fraction Dim x: x = CheckMassVector(Xin, Brine.nX) If VarType(x) = vbString Then solubility_H2_pTX_Chabab2020 = x Exit Function End If Dim solu: solu = solubility_H2_pTX_Chabab2020_molality(p, T, x, p_gas) ' mol/kg_H2O If VarType(solu) = vbString Then solubility_H2_pTX_Chabab2020 = solu Exit Function End If Dim X_H2O As Double: X_H2O = x(Brine.nX) ' to be used in solubility_H2_pTX_Li2018 solubility_H2_pTX_Chabab2020 = solu * H2.MM * X_H2O 'molality->mass fraction End Function Function solubility_H2_pTX_Chabab2020_molality(p As Double, T As Double, Xin, p_gas) ' passes on p_gas + p_H2O as absolute pressure to correlation function ' returns mass fraction Dim x: x = CheckMassVector(Xin, Brine.nX) If VarType(x) = vbString Then solubility_H2_pTX_Chabab2020_molality = x Exit Function End If Dim molalities molalities = ToDouble(massFractionsToMolalities(x, Brine.MM_vec)) If VarType(molalities) = vbString Then solubility_H2_pTX_Chabab2020_molality = molalities Exit Function End If Dim m_Cl As Double, m_Na As Double, m_K As Double, m_Ca As Double, m_Mg As Double, m_SO4 As Double m_Cl = molalities(i_NaCl) + molalities(i_KCl) + 2 * molalities(i_CaCl2) ' + 2 * molalities(i_MgCl2) m_Na = molalities(i_NaCl) m_K = molalities(i_KCl) m_Ca = molalities(i_CaCl2) m_Mg = 0 ' molalities(i_MgCl2) m_SO4 = 0 ' molalities(i_MgCl2) Dim b_NaCl As Double: b_NaCl = m_Na + m_K + 2 * m_Ca + 2 * m_Mg ' Debug.Print "b_NaCl: "; b_NaCl Dim p_H2O: p_H2O = IAPWS.Waterpsat_T(T) Dim solu: solu = solubility_H2_pTb_Chabab2020_molality(p_gas + p_H2O, T, b_NaCl) ' mol/kg_H2O If VarType(solu) = vbString Then solubility_H2_pTX_Chabab2020_molality = solu Exit Function End If solubility_H2_pTX_Chabab2020_molality = solu End Function Function solubility_H2_pTb_Chabab2020_molality(p As Double, T As Double, b_NaCl As Double) ' conversion mole fraction to molality Dim y_H2: y_H2 = solubility_H2_pTb_Chabab2020_y(p, T, b_NaCl) ' mole fraction b_H2 / b/H2O If VarType(y_H2) = vbString Then solubility_H2_pTb_Chabab2020_molality = y_H2 Else solubility_H2_pTb_Chabab2020_molality = y_H2 / (1 - y_H2) / H2O.MM ' mol/kg_H2O End If End Function ' equations from article Function solubility_H2_pTb_Chabab2020_y(p As Double, T As Double, b_NaCl As Double) ' mole fraction b_H2 / b/H2O ' p is absolute pressure, here p_H2 + p_H2O ' Debug.Print "p="; p / 100000#; " bar, b_NaCl="; b_NaCl Dim T_min As Double: T_min = IIf(b_NaCl > 0, 323.15, 273.15) Dim T_max As Double: T_max = 373.15 Dim p_min As Double: p_min = IIf(b_NaCl > 0, 10 ^ 5, 10 ^ 6) Dim p_max As Double: p_max = 23000000# Dim b_max As Double: b_max = 5 Dim msg As String msg = RangeCheck_pTb(p, T, b_NaCl, ignoreLimitH2_p, ignoreLimitH2_T, ignoreLimitH2_b, p_min, p_max, T_min, T_max, b_max, "solubility_H2_pTb_Chabab2020_molality") If Len(msg) > 0 Then solubility_H2_pTb_Chabab2020_y = msg Exit Function End If ' If Not (ignoreLimitH2_T Or (T_min <= T And T <= T_max)) Then ' solubility_H2_pTb_Chabab2020_molality = "# T=" & T - 273.15 & "C out of range (GasData.VirialEquation)" ' Exit Function ' End If ' If Not (ignoreLimitH2_p Or (p_min <= p And p <= p_max)) Then ' solubility_H2_pTb_Chabab2020_molality = "# p=" & p / 100000# & " out of range {" & p_min / 100000# & "..." & p_max / 100000# & " bar} (solubility_H2_pTb_Chabab2020_molality)" ' Exit Function ' End If Dim x_H2_0 As Double: x_H2_0 = solubility_H2_pT_Chabab2020_y(p, T) Dim a1 As Double: a1 = 0.018519 Dim a2 As Double: a2 = -0.30185103 'Dim x_H2 As Double: x_H2 solubility_H2_pTb_Chabab2020_y = x_H2_0 * Exp(a1 * b_NaCl ^ 2 + a2 * b_NaCl) 'equ. 12 (mol H2 per kg H2O) End Function Private Function solubility_H2_pT_Chabab2020_y(p As Double, T As Double) ' returns salt-free mole fraction Dim p_bar As Double: p_bar = p / 100000# If Not p > 0 Then ' = 0 solubility_H2_pT_Chabab2020_y = 0 Exit Function ElseIf p < 0 Then solubility_H2_pT_Chabab2020_y = "#p_gas negative! (GasData.solubility_H2_pT_Chabab2020_molality)" Exit Function End If Dim b1 As Double: b1 = 0.0000003338844 Dim b2 As Double: b2 = 0.0363161 Dim b3 As Double: b3 = -0.00020734 Dim b4 As Double: b4 = -2.1301815E-09 solubility_H2_pT_Chabab2020_y = b1 * p_bar * T + b2 * p_bar / T + b3 * p_bar + b4 * p_bar ^ 2 'equ. 13 End Function
 Attribute VB_Name = "H2solubility_Li" ' by Henning Francke francke@gfz-potsdam.de ' 2021 GFZ Potsdam 'Li, D., Beyer, C., & Bauer, S. (2018). A unified phase equilibrium model for hydrogen solubility and solution density. International Journal of Hydrogen Energy, 43(1), 512529. https://doi.org/10.1016/j.ijhydene.2017.07.228 ' NOT USED Option Explicit Option Base 1 Const ignoreLimitH2_T = False Const ignoreLimitH2_p = False Const ignoreLimitH2_b = False 'Const M_H2 = 1.00784 * 2 * 0.001 Public Type VirialCoeffs 'Public name As String 'Name of ideal gas a As Double b As Double c As Double d As Double e As Double f As Double p_min As Double p_max As Double T_min As Double T_max As Double End Type ' Public Const nX_salt = 3 ' Public Const nX_gas = 3 Function solubility_H2_pTX_Li2018(p As Double, T As Double, Xin, p_gas) Dim solu ' mol/kg_H2O Dim X_H2O As Double solu = solubility_H2_pTX_Li2018_molality(p, T, Xin, p_gas, X_H2O) If VarType(solu) = vbString Then solubility_H2_pTX_Li2018 = solu Exit Function End If solubility_H2_pTX_Li2018 = solu * H2.MM * X_H2O 'molality->mass fraction End Function Function solubility_H2_pTX_Li2018_molality(p As Double, T As Double, Xin, p_gas, Optional ByRef X_H2O As Double) 'solubility calculation of N2 in seawater Mao&Duan(2006) 'Li, D., Beyer, C., & Bauer, S. (2018). A unified phase equilibrium model for hydrogen solubility and solution density. International Journal of Hydrogen Energy, 43(1), 512529. https://doi.org/10.1016/j.ijhydene.2017.07.228 ' 273-373 K, 1-50 MPa and 0-5 mol/kg NaCl 'Calculates solubility for y_H2 = p_gas/p Dim T_min As Double: T_min = 0 + 273.15 Dim T_max As Double: T_max = 100 + 273.15 Dim p_min As Double: p_min = 1 * 10 ^ 6 Dim p_max As Double: p_max = 50 * 10 ^ 6 Dim b_max As Double: b_max = 5 If Not p_gas > 0 Then ' = 0 solubility_H2_pTX_Li2018_molality = 0 Exit Function ElseIf p_gas < 0 Then solubility_H2_pTX_Li2018_molality = "#p_gas negative! (GasData.solubility_H2_pTX_Li2018_molality)" Exit Function ElseIf p_gas > p Then solubility_H2_pTX_Li2018_molality = "#p_gas > p ! (GasData.solubility_H2_pTX_Li2018_molality)" Exit Function End If If p < 0 Then solubility_H2_pTX_Li2018_molality = "#p negative! (GasData.solubility_H2_pTX_Li2018_molality)" Exit Function End If ' p is not used other than in the checks! The total pressure for equation 16 is calculated as p = p_gas + p_H2O Dim x: x = CheckMassVector(Xin, Brine.nX) If VarType(x) = vbString Then solubility_H2_pTX_Li2018_molality = x Exit Function End If X_H2O = x(Brine.nX) ' to be used in solubility_H2_pTX_Li2018 avoiding double calculation Dim molalities molalities = ToDouble(massFractionsToMolalities(x, Brine.MM_vec)) If VarType(molalities) = vbString Then solubility_H2_pTX_Li2018_molality = molalities Exit Function End If Dim m_Cl As Double, m_Na As Double, m_K As Double, m_Ca As Double, m_Mg As Double, m_SO4 As Double m_Cl = molalities(i_NaCl) + molalities(i_KCl) + 2 * molalities(i_CaCl2) ' + 2 * molalities(i_MgCl2) m_Na = molalities(i_NaCl) m_K = molalities(i_KCl) m_Ca = molalities(i_CaCl2) m_Mg = 0 ' molalities(i_MgCl2) m_SO4 = 0 ' molalities(i_MgCl2) Dim b_NaCl As Double: b_NaCl = m_Na + m_K + 2 * m_Ca + 2 * m_Mg ' Debug.Print "b_NaCl: "; b_NaCl Dim p_H2O As Double: p_H2O = IAPWS.Waterpsat_T(T) If VarType(p_H2O) = vbString Then 'if error solubility_H2_pTX_Li2018_molality = p_H2O & "(GasData.solubility_H2_pTX_Li2018_molality)" Exit Function