Commit 32d105de authored by Henning Francke's avatar Henning Francke
Browse files

-Bug fixed: massFractions instead of molefractions

parent 465b3d7d
......@@ -128,8 +128,8 @@ protected
<p><b>BrineProp.Brine_5salts</b> is a medium package that provides properties of one-phase solution of five salts (NaCl, KCl, CaCl<sub>2</sub>, MgCl<sub>2</sub>, SrCl<sub>2</sub>).</p>
<h4>Usage</h4>
<p>It is based on Modelica.Media, the usage is accordingly:</p>
<p>Create an instance of the Medium: </p>
<pre> package Medium = Brine_5salts;</pre>
<p>Create an instance of the Medium (optionally deactivating range checks, for all options see .PartialFlags): </p>
<pre> package Medium = Brine_5salts(AssertLevel=1,ignoreLimitSalt_T={false,true,true,false,false});</pre>
<p>Create an instance of Medium.Baseproperties: </p>
<pre> Medium.BaseProperties props;</pre>
<p>Use the BaseProperties model to define the actual brine composition(Xi or X), to define the thermodynamic state and calculate the corresponding properties. </p>
......
......@@ -211,7 +211,7 @@ protected
<p>It was used for the calculations documented in this <a href=\"http://nbn-resolving.de/urn:nbn:de:kobv:83-opus4-47126\">PhD thesis</a>.</p>
<h4>Usage</h4>
<p>As it is based on Modelica.Media, the usage differs little from the usage of the two-phase water model:</p>
<p>Create an Instance of the Medium: </p>
<p>Create an Instance of the Medium (optionally deactivating range checks, for all options see .PartialFlags): </p>
<pre> package Medium = Brine_Duan_Multi_TwoPhase_ngas_3;</pre>
<p>Create an Instance of Medium.Baseproperties: </p>
<pre> Medium.BaseProperties props;</pre>
......
......@@ -224,8 +224,8 @@ protected
<p><b>BrineGas_3Gas</b> is a medium package that, based on Brine.PartialBrineGas, defines a brine with 3 gases (CO<sub>2</sub>, N<sub>2</sub>, CH<sub>4</sub>), which are the main gases in the geofluid in Gross Schoenebeck, Germany.</p>
<h4>Usage</h4>
<p>It is based on Modelica.Media, the usage is accordingly:</p>
<p>Create an instance of the Medium: </p>
<pre> package Medium = BrineGas_3Gas;</pre>
<p>Create an instance of the Medium (optionally deactivating range checks, for all options see .PartialFlags): </p>
<pre> package Medium = BrineGas_3Gas(ignoreLimitN2_T=false);</pre>
<p>Create an instance of Medium.Baseproperties: </p>
<pre> Medium.BaseProperties props;</pre>
<p>Use the BaseProperties model to define the actual brine composition(Xi or X), to define the thermodynamic state and calculate the corresponding properties. </p>
......
......@@ -78,7 +78,7 @@ protected
Real[23] c;
BrineProp.SaltDataDuan.SaltConstants salt;
constant Types.Molality[:] m=Utilities.massToMoleFractions(X,MM_vec);
constant Types.Molality[:] m=Utilities.massFractionsToMolalities(X,MM_vec);
SI.Pressure p_sat=Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T);
algorithm
if debugmode then
......@@ -102,7 +102,7 @@ algorithm
else
salt :=BrineProp.SaltDataDuan.saltConstants[i];
if debugmode then
print(salt.name+": "+String(X[i]));
print("X["+salt.name+"]: "+String(X[i]));
end if;
if AssertLevel>0 then
......@@ -111,6 +111,10 @@ algorithm
assert(ignoreLimitSalt_b[i] or (m[i] >= 0 and m[i] <= salt.mola_max_rho),salt.name + "\nMolality is out of validity range: m[i]=" + String(m[i]) + " mol/kg.\nTo ignore set ignoreLimitSalt_b["+String(i)+"]=true",aLevel);
end if;
if debugmode then
print("m["+String(i)+"]= "+String(m[i])+"");
end if;
M_salt[i] := salt.M_salt*1000 "in g/mol";
m_r := salt.m_r;
z_plus := salt.z_plus;
......@@ -131,6 +135,9 @@ algorithm
//Equation 3: Ionic strength
I := 1/2*(m[i]*v_plus*z_plus^2 + m[i]*v_minus*z_minus^2);
if debugmode then
print("I["+String(i)+"]= "+String(I)+"");
end if;
I_mr := 1/2*(m_r*v_plus*z_plus^2 + m_r*v_minus*z_minus^2);
//Equation 4:
......@@ -196,10 +203,12 @@ algorithm
//Equation 13: apparent molar Volume at infinite dilution in cm^3/mol
V_o_Phi := (V_m_r/m_r - 1000/(m_r*rho_H2O) - v*abs(z_plus*z_minus)*A_v*h_mr - 2*v_plus*
v_minus*R*T*(B_v*m_r + v_plus*z_plus*C_v*m_r^2));
/* if debugmode then
print("V_o_Phi["+String(i)+"]= "+String(V_o_Phi)+"");
end if;*/
//Equation 2: apparent molar Volume in cm^3/mol
V_Phi[i] := V_o_Phi + v*abs(z_plus*z_minus)*A_v*h + 2*v_plus*v_minus*m[i]*R*T*(
B_v + v_plus*z_plus*m[i]*C_v);
V_Phi[i] := V_o_Phi + v*abs(z_plus*z_minus)*A_v*h + 2*v_plus*v_minus*m[i]*R*T*(B_v + v_plus*z_plus*m[i]*C_v);
//Equation 1: density of the solution
// rho[i] := ((1000 + m[i]*M_salt[i])*rho_H2O)/(1000 + m[i]*V_Phi[i]*rho_H2O)*1000;
......@@ -223,7 +232,6 @@ algorithm
end for;
// d := m[1:nX_salt]*rho/(1-X[end]) "mass fraction weighted linear mixture (matrix multiplication)";
// d := m[1:nX_salt]*rho/(sum(m[1:nX_salt])) "molality weighted linear mixture (matrix multiplication)";
// d := ((1 + m[1:end-1]*MM_vec[1:end-1])*1000*rho_H2O)/(1000 + m[1:nX_salt]*V_Phi*rho_H2O)*1000 "Mixing rule frei nach Duan";
d := 1/(X[end]/(rho_H2O*1000) + X[1:nX_salt]*( V_Phi/1e6 ./ (M_salt/1000)))
......
......@@ -3,7 +3,7 @@ model BrineProps1PhaseFull
"Example for 1-phase brine property model using all properties"
//SPECIFY MEDIUM
package Medium = Brine5salts(ignoreLimitSalt_T={false,true,false,false,false});
package Medium = Brine5salts(AssertLevel=2,ignoreLimitSalt_T={false,true,true,false,false});
//package Medium = Modelica.Media.Water.WaterIF97_pT;
Medium.BaseProperties props;
......@@ -45,11 +45,11 @@ equation
// props.Xi = { 0, 0, 0, 0, 0} "pure water";
// props.Xi = {6*SaltData.M_NaCl/(1+6*SaltData.M_NaCl),0,0,0,0} "6-molar NaCl solution";
// props.Xi = {n_Na*SaltData.M_NaCl,n_K*SaltData.M_KCl,n_Ca*SaltData.M_CaCl2,0,0}/(1+n_Na*SaltData.M_NaCl+n_K*SaltData.M_KCl+n_Ca*SaltData.M_CaCl2) "specify molalities above";
props.Xi = {0.0839077010751,0.00253365118988,0.122786737978,0,0}
props.Xi = {0*0.0839077010751,0*0.00253365118988,0.122786737978,0,0}
"GrSk brine composition (Feldbusch 2-2013 1.1775g/ml V2)";
//SPECIFY THERMODYNAMIC STATE
props.p = 10e5;
props.T = 273.15+50;
props.p = 10*1.01325e5;
props.T = 273.15+20;
// props.T = 273.15+50+time "transient - DOES NOT WORK";
end BrineProps1PhaseFull;
......@@ -71,7 +71,7 @@ algorithm
end if;
// (molefractions,molalities):=massFractionsToMoleFractions(X, MM);
molalities:=Utilities.massToMoleFractions(X, MM_vec);
molalities:=Utilities.massFractionsToMolalities(X, MM_vec);
// print("molefractions[NaCl]="+String(molefractions[NaCl])+" (GasData.solubility_CH4_pTX_Duan1992)");
m_Cl :=molalities[iNaCl] + molalities[iKCl] + 2*molalities[iMgCl2] + 2*
molalities[iCaCl2];
......
......@@ -5,9 +5,7 @@ function solubility_CH4_pTX_Harting
extends partial_solubility_pTX;
protected
Types.Molality molalities[size(X, 1)]=
Utilities.massToMoleFractions(X,
MM_vec);
Types.Molality molalities[size(X, 1)]=Utilities.massFractionsToMolalities(X,MM_vec);
SI.Temp_C T_C = SI.Conversions.to_degC(T);
Real L_0=0.454 "CH4 solubility in H2O at 25, 75degC";
Real L_rel_p "pressure influence";
......
......@@ -59,9 +59,8 @@ protected
Real zeta_CO2_NaCl;
//constant
Types.Molality molalities[size(X, 1)]=
Utilities.massToMoleFractions(X,
MM_vec) "TODO neglecting CO2?";
Types.Molality molalities[size(X, 1)]=Utilities.massFractionsToMolalities(X,MM_vec)
"TODO neglecting CO2?";
Types.Molality m_Cl=molalities[iNaCl] + molalities[iKCl] + 2*molalities[iMgCl2]
+ 2*molalities[iCaCl2];
Types.Molality m_Na=molalities[iNaCl];
......
......@@ -46,8 +46,7 @@ protected
SI.MolarMass M_H2O = MM_vec[end];
Types.Molality molalities[size(X, 1)]=
Utilities.massToMoleFractions(X,
MM_vec);
Utilities.massFractionsToMolalities(X,MM_vec);
Types.Molality m_Cl=molalities[iNaCl] + molalities[iKCl] + 2*molalities[iMgCl2]
+ 2*molalities[iCaCl2];
Types.Molality m_Na=molalities[iNaCl];
......
......@@ -11,9 +11,7 @@ function solubility_N2_pTX_Harting
output SI.MassFraction c_gas "gas concentration in kg_gas/kg_H2O";
*/
protected
Types.Molality molalities[size(X, 1)]=
Utilities.massToMoleFractions(X,
MM_vec);
Types.Molality molalities[size(X, 1)]= Utilities.massFractionsToMolalities(X,MM_vec);
SI.Temp_C T_C = SI.Conversions.to_degC(T);
Real L_0=0.252 "N2 solubility in H2O at 25 atm, 75degC";
Real L_rel_p "pressure influence";
......
......@@ -577,7 +577,7 @@ protected
if (p_H2O>p) then
print("p_H2O(" + String(p/1e5) + " bar," +
String(T2 - 273.15) + "degC, " + Modelica.Math.Matrices.toString(transpose([X])) + ") = "
+ String(p_H2O/1e5) + " bar>p ! (PartialBrine_ngas_Newton.setState_pTX)");
+ String(p_H2O/1e5) + " bar>p ! (PartialBrineMultiSaltMultiGasTwoPhase.setState_pTX())");
x:=1;
break;
end if;
......
......@@ -50,10 +50,7 @@ protected
"J/mol_salt solid enthalpy";
Types.Molality mola[size(X, 1)]=
Utilities.massToMoleFractions(X,
cat(1,
MM_vec_salt,
fill(-1, size(X, 1) - size(MM_vec_salt, 1))));
Utilities.massFractionsToMolalities(X,cat(1,MM_vec_salt,fill(-1, size(X, 1) - size(MM_vec_salt, 1))));
Types.Molality mola_salt[5]=mola[1:5];
SI.Temp_C T_C = SI.Conversions.to_degC(T);
Types.Pressure_bar p_bar=SI.Conversions.to_bar(p);
......
......@@ -33,10 +33,7 @@ protected
Delta_h_solution_SrCl2};*/
Types.Molality b[size(X, 1)]=
Utilities.massToMoleFractions(X,
cat(1,
MM_vec,
fill(-1, size(X, 1) - size(MM_vec, 1))));
Utilities.massFractionsToMolalities(X,cat(1,MM_vec,fill(-1, size(X, 1) - size(MM_vec, 1))));
// SI.SpecificEnthalpy h_H2O = Modelica.Media.Water.WaterIF97_pT.specificEnthalpy_pT(p, T);
SI.SpecificEnthalpy h_Driesner = specificEnthalpy_pTX_Driesner(p, T, X[1]/(X[1]+X[end]));
......
......@@ -10,10 +10,7 @@ function specificHeatCapacityCp_pTX_liq_Francke
protected
Types.Molality b[size(X_, 1)]=
Utilities.massToMoleFractions(X_,
cat(1,
MM_vec,
fill(-1, size(X_, 1) - size(MM_vec, 1))));
Utilities.massFractionsToMolalities(X_,cat(1,MM_vec,fill(-1, size(X_, 1) - size(MM_vec, 1))));
/* Real cp_by_cpWater[:]={0,
SpecificEnthalpies.HeatCapacityRatio_KCl_White(T, b[KCl]),
......
within BrineProp.Utilities;
function massFractionsToMolalities
// extends Modelica.Media.Interfaces.PartialMixtureMedium.massToMoleFractions;
extends Modelica.Icons.Function;
input SI.MassFraction X[:] "Mass fractions of mixture";
input SI.MolarMass MMX[:] "molar masses of components";
output Types.Molality molalities[size(X, 1)] "Molalities moles/m_H2O";
protected
Integer n=size(X, 1);
algorithm
assert(n==size(MMX, 1), "Inconsistent vectors for mass fraction("+String(n)+") and molar masses("+String(size(MMX, 1))+")");
// assert(min(MMX)>0, "Invalid molar mass vectors");
// print(String(size(X,1))+" "+String(X[end]));
// printVector(MM);
for i in 1:n loop
// print("MMX["+String(i)+"]="+String(MMX[i]));
// assert(MMX[i]>0, "Invalid molar mass: "+String(MMX[i])+"");
molalities[i] := if X[end]>0 then X[i]/(MMX[i]*X[end]) else -1;
// n[i] := X[i]/MMX[i];
end for;
annotation(smoothOrder=5);
end massFractionsToMolalities;
......@@ -14,12 +14,15 @@ algorithm
// assert(min(MMX)>0, "Invalid molar mass vectors");
// print(String(size(X,1))+" "+String(X[end]));
// printVector(MM);
for i in 1:n loop
molalities:=massFractionsToMolalities(X, MMX);
/* for i in 1:n loop
// print("MMX["+String(i)+"]="+String(MMX[i]));
// assert(MMX[i]>0, "Invalid molar mass: "+String(MMX[i])+"");
molalities[i] := if X[end]>0 then X[i]/(MMX[i]*X[end]) else -1;
// n[i] := X[i]/MMX[i];
end for;
end for;*/
n_total :=sum(molalities);
for i in 1:n loop
molefractions[i] := molalities[i]/n_total;
......
within BrineProp;
package Utilities
end Utilities;
massToMoleFractions
massFractionsToMolalities
......@@ -27,7 +27,7 @@ protected
Modelica.Media.Water.WaterIF97_pT.ThermodynamicState state_H2O;
SaltDataDuan.SaltConstants salt;
constant Molality[:] molalities=Utilities.massToMoleFractions(X,MM);
constant Molality[:] molalities=Utilities.massFractionsToMolalities(X,MM);
// constant Partial_Units.Molality[:] molalities=X[1:nX_salt] ./ MM[1:nX_salt]/X[end];
Molarity_molperliter c;
Molality b "component molality";
......
......@@ -26,8 +26,7 @@ protected
Modelica.Media.Water.WaterIF97_pT.ThermodynamicState state_H2O;
SaltDataDuan.SaltConstants salt;
constant Molality[:] molalities=Utilities.massToMoleFractions(
X,MM);
constant Molality[:] molalities=Utilities.massFractionsToMolalities(X,MM);
String msg;
algorithm
print("X[1]="+String(X[1])+" (Brine.Viscosities.dynamicViscosity_Duan_pTX)");
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment