Commit 4d617fe6 authored by Henning Francke's avatar Henning Francke
Browse files

Fixed variable nX_gas in 2Phase packages

made BrineProp3Salts4Gas as BrineProp work
reorganized UnitTests
parent e103807b
......@@ -24,6 +24,7 @@ package Brine3salts3gas "Two-phase aqueous solution of NaCl, KCl, CaCl2, N2, CO2
gasNames = {"carbondioxide","nitrogen","methane"},
MM_gas = {M_CO2,M_N2,M_CH4},
nM_gas = {nM_CO2,nM_N2,nM_CH4}); //iGas not final, because reassigned in Brine5salts3gas
//order of gases must be consistent with Brine3Gas TODO: pass order or copy enthalpy/density/cp here
redeclare function extends setState_pTX "to avoid check error"
end setState_pTX;
......@@ -52,23 +53,24 @@ package Brine3salts3gas "Two-phase aqueous solution of NaCl, KCl, CaCl2, N2, CO2
end solubilities_pTX;
redeclare function extends density_liq_pTX
// extends density_Duan2008_pTX(MM_vec=cat(1,MM_salt, {M_H2O}));
//TODO should take MM_vec;
// PowerPlant.Media.Brine.Salt_Data_Duan.density_Duan2008_pTX;
protected
constant Integer[:] liqIndex=cat(1,1:nX_salt,{nX});
Real X_[:] = cat(1, X[1:nX_salt], {1-sum(X[1:nX_salt])}); //recalculate water mass fraction when gases are omitted (which they are in the density function)
algorithm
d := density_Duan2008_pTX(p,T,X_,MM[liqIndex],
saltConstants);
// print("density_liquid_pTX: "+String(p*1e-5)+" bar,"+String(T)+" K->"+String(d)+"kg/m^3");
end density_liq_pTX;
/*function extends density_Duan2008_pTX(nX_salt_=nX_salt, ignoreLimitSalt_p_=ignoreLimitSalt_p_global)
"just to set the flags"
end density_Duan2008_pTX;*/
redeclare replaceable function extends density_gas_pTX
algorithm
d := BrineGas3Gas.density_pTX(p,T,X,MM);
// print("density_liquid_pTX: "+String(p*1e-5)+" bar,"+String(T)+" K->"+String(d)+"kg/m^3");
end density_gas_pTX;
redeclare function extends specificEnthalpy_liq_pTX
// Partial_Units.Molality molalities = massFractionsToMoleFractions(X, MM_vec);
// SI.SpecificEnthalpy h_H2O := Modelica.Media.Water.WaterIF97_pT.specificEnthalpy_pT(p, T) "H2O";
......@@ -81,13 +83,10 @@ protected
// print(String(p*1e-5)+" bar,"+String(T)+" K->"+String(h)+" J/kg (Brine_Duan_Multi_TwoPhase_ngas_3.specificEnthalpy_liq_pTX)");
end specificEnthalpy_liq_pTX;
redeclare function extends specificEnthalpy_gas_pTX
redeclare replaceable function extends specificEnthalpy_gas_pTX
algorithm
h :=BrineGas3Gas.specificEnthalpy_pTX(
p,
T,
X);
h :=BrineGas3Gas.specificEnthalpy_pTX(p,T,X); //,MM
end specificEnthalpy_gas_pTX;
redeclare function extends dynamicViscosity_liq
......
......@@ -3,6 +3,7 @@ setState_pTX
setState_phX
solubilities_pTX
density_liq_pTX
density_gas_pTX
specificEnthalpy_liq_pTX
specificEnthalpy_gas_pTX
dynamicViscosity_liq
......
......@@ -6,7 +6,7 @@ package Brine3salts4gas
final gasNames = {"carbondioxide","nitrogen","methane","hydrogen"},
final MM_gas = {M_CO2,M_N2,M_CH4,M_H2},
final nM_gas = {nM_CO2,nM_N2,nM_CH4,nM_H2}); //iGas not final, because reassigned in Brine5salts3gas
//order of gases must be consistent with Brine3Gas TODO: pass order or copy enthalpy/density/cp here
redeclare function solubilities_pTX
"solubility calculation"
......@@ -91,4 +91,21 @@ package Brine3salts4gas
liquid and vapour state heat capacities.</p>
</html>"));
end specificHeatCapacityCp_gas;
redeclare function density_gas_pTX
extends PartialBrineMultiSaltMultiGasTwoPhase.density_gas_pTX;
/* input SI.Pressure p;
input SI.Temp_K T;
input MassFraction X[:] "nX_gas mass fraction";
input SI.MolarMass MM[:] "=MM_vec =fill(0,nX) molar masses of components";
output SI.Density d;*/
algorithm
d := BrineGas4Gas.density_pTX(p,T,X,MM);
// print("density_liquid_pTX: "+String(p*1e-5)+" bar,"+String(T)+" K->"+String(d)+"kg/m^3");
end density_gas_pTX;
redeclare function specificEnthalpy_gas_pTX
extends PartialBrineMultiSaltMultiGasTwoPhase.specificEnthalpy_gas_pTX;
algorithm
h :=BrineGas4Gas.specificEnthalpy_pTX(p,T,X); //,MM
end specificEnthalpy_gas_pTX;
end Brine3salts4gas;
......@@ -8,10 +8,8 @@ package BrineGas3Gas "Gas mixture of CO2+N2+CH4+H2O"
MM_vec = {M_CO2,M_N2,M_CH4,M_H2O},
nM_vec = {nM_CO2,nM_N2,nM_CH4,nM_H2O});
extends PartialFlags;
redeclare model extends BaseProperties
//Dummy for OM
end BaseProperties;
......@@ -21,7 +19,6 @@ package BrineGas3Gas "Gas mixture of CO2+N2+CH4+H2O"
*/
constant Boolean waterSaturated=false "activates water saturation";
replaceable function waterSaturatedComposition_pTX
"calculates the water saturated mass vector for a given Temperature"
//saturates the mixture with water
......@@ -67,37 +64,6 @@ protected
// assert(lambda>0,"lambda="+String(lambda));
end density;
redeclare function extends density_pTX
"Density of an ideal mixture of ideal gases"
// SpecificHeatCapacity R_gas; //= sum(Modelica.Constants.R*X ./ MM_vec);
// MassFraction[:] X_=cat(1,fill(nX-1,0),{1});
// MassFraction[size(X,1)] X_=cat(1,fill(size(X,1),0),{1});
algorithm
/* if not R_gas >0 then
print("R_gas="+String(R_gas)+", (MM="+Modelica.Math.Matrices.toString({MM_vec})+", X="+Modelica.Math.Matrices.toString({X})+")");
end if;*/
// print("size(X_,1)="+String(size(X_,1))+",size(X,1)="+String(size(X,1)));
if debugmode then
print("Running density_pTX("+String(p/1e5)+" bar,"+String(T-273.15)+" degC, X="+Modelica.Math.Matrices.toString(transpose([X]))+")");
end if;
// assert(min(X)>0,"Cannot calculate with empty composition.");
if not min(X)>0 and not ignoreNoCompositionInBrineGas then
print("No gas composition, assuming water vapour.(BrineProp.BrineGas_3Gas.density_pTX)");
end if;
R_gas :=Modelica.Constants.R*sum(cat(1,X[1:end-1],{(if min(X)>0 then X[end] else 1)})./ MM_vec);
/* if waterSaturated then
R_gas :=sum(Modelica.Constants.R*waterSaturatedComposition_pTX(
p,
T,
X[end - nX + 1:end]) ./ MM_vec);
d :=p/(T*R_gas);
else*/
d :=p/(T*R_gas);
// end if;
// print("d="+String(d)+" kg/m^3");
end density_pTX;
replaceable function extends specificHeatCapacityCp_pTX
"calculation of specific heat capacities of gas mixture"
import Modelica.Media.IdealGases.Common.SingleGasNasa;
......@@ -113,7 +79,7 @@ protected
SI.SpecificHeatCapacity cp_H2O=Water.IF97_Utilities.cp_pT(min(p,Water.IF97_Utilities.BaseIF97.Basic.psat(T)-1),T=T)
"below psat -> gaseous";
SI.SpecificHeatCapacity cp_vec[:]={cp_CO2,cp_N2,cp_CH4,cp_H2O};
SI.SpecificHeatCapacity cp_vec[:]={cp_CO2,cp_N2,cp_CH4,cp_H2O}; //the two-phase models rely on this order!
algorithm
if debugmode then
......@@ -216,7 +182,7 @@ protected
SI.SpecificEnthalpy h_N2=SingleGases.N2.specificEnthalpy(state);
SI.SpecificEnthalpy h_CH4=SingleGases.CH4.specificEnthalpy(state);
SI.SpecificEnthalpy[:] h_vec={h_CO2,h_N2,h_CH4,h_H2O};
SI.SpecificEnthalpy[:] h_vec={h_CO2,h_N2,h_CH4,h_H2O}; //the two-phase models rely on this order!
SI.MassFraction X_[size(X,1)] "OM workaround for cat";
algorithm
X_[1:end-1]:=X[1:end-1] "OM workaround for cat";
......
......@@ -2,7 +2,6 @@ BaseProperties
waterSaturated
waterSaturatedComposition_pTX
density
density_pTX
specificHeatCapacityCp
specificHeatCapacityCp_pTX
dynamicViscosity
......
......@@ -26,7 +26,7 @@ protected
SI.SpecificEnthalpy h_CH4=SingleGases.CH4.specificEnthalpy(state);
SI.SpecificEnthalpy h_H2=SingleGases.H2.specificEnthalpy(state);
// SI.SpecificEnthalpy[:] h_vec={h_CO2,h_N2,h_CH4,h_H2,h_H2O};
// SI.SpecificEnthalpy[:] h_vec={h_CO2,h_N2,h_CH4,h_H2,h_H2O}; //the two-phase models rely on this order!
SI.SpecificEnthalpy[nX] h_vec;
SI.MassFraction X_[size(X,1)] "OM workaround for cat";
algorithm
......
......@@ -22,7 +22,7 @@ algorithm
cp_vec[iN2]:=cp_N2;
cp_vec[iCH4]:=cp_CH4;
cp_vec[iH2]:=cp_H2;
cp_vec[iCO2]:=cp_H2O;
cp_vec[iCO2]:=cp_H2O; //the two-phase models rely on this order!
if debugmode then
print("Running specificHeatCapacityCp_pTX("+String(p/1e5)+" bar,"+String(T-273.15)+" degC, X="+Modelica.Math.Matrices.toString(transpose([X]))+")");
......
within BrineProp.Examples.Gas;
model Brine3Gas
model UnitTestBrine3Gas
package Medium = BrineProp.BrineGas3Gas (ignoreNoCompositionInBrineGas=true);
//package Medium = Modelica.Media.Air.SimpleAir;
//package Medium = PartialBrineGas;
......@@ -58,9 +58,14 @@ equation
// props.Xi={0.8};
props.Xi={0.0892134,0.0051995,0.137699,0,0,0.000639217,7.0356e-6,1.5464e-5};
*/
// assert(abs(props.GVF-0.0497710432105261)<1e6,"GVF differs!");
assert(abs(props.h-2777119.5)<1e6,"h differs!");
assert(abs(props.d-0.007391231)<1e6,"d differs!");
algorithm
// print("rho="+String(d)+" kg/m^3, TDS = " + String(TDS) + " g/l -> "+ String(f*265/TDS));
// print("sum(X_l)="+String(sum(props.state.X_l)-1)+"");
// print("sum(X_sat)="+String(sum(X_sat)));
end Brine3Gas;
end UnitTestBrine3Gas;
Brine3Gas_Minimal
Brine3Gas
Brine4Gas_Minimal
UnitTestBrine3Gas
within BrineProp.Examples.Liquid;
model UnitTestsLiquid "To be filled..."
package Medium_3s = BrineProp.Brine3salts (ignoreLimitSalt_p={false,true,true});
Medium_3s.BaseProperties props_3s;
package Medium = Brine3salts3gas (ignoreLimitN2_T=true);
Medium.BaseProperties props_3s3g;
equation
props_3s.p = 455e5;
props_3s.T = 145+273.15;
props_3s.Xi = {0.082870031,0.00486001,0.125914128};
assert(abs(props_3s.d-1127.8458262083673)<1e9, "Not the expecteded density!");
props_3s3g.p = 455e5;
props_3s3g.T = 145+273.15;
props_3s3g.Xi = {0.082870031,0.00486001,0.125914128,1.6E-6, 465.6E-6, 49.9E-6};//-2313 m
assert(abs(props_3s3g.d-1127.8458262083673)<1e9, "Not the expecteded density!");
// print(String(props_3s.d-1127.85417379));
annotation ();
end UnitTestsLiquid;
UnitTestsLiquid
SingleSaltBrine
BrineProps1PhaseMinimal
BrineProps1PhaseFull
......
within BrineProp.Examples.TwoPhase;
model UnitTestsTwoPhase3Gas
//Compares calculation result with hardcoded values.
//no assert should be triggered
//To be filled...
//SPECIFY MEDIUM and COMPOSITION
package Medium = BrineProp.Brine3salts3gas(ignoreLimitN2_T=true,ignoreLimitSalt_T=fill(true,3));
Real[Medium.nXi] Xi = {0.0839077010751,0.00253365118988,0.122786737978,0.00016883,0.00073459,0.000065652};
//DEFINE BRINE COMPOSITION (NaCl, KCl, CaCl2, MgCl2, SrCl2, CO2, N2, CH4)
/* package Medium = BrineProp.Brine5salts3gas;
Real[Medium.nXi] Xi = {0.0839077010751,0.00253365118988,0.122786737978,0,0,7.2426359111e-05,0.000689505657647,6.14906384726e-05} ;
*/
/* package Medium = BrineProp.Water_MixtureTwoPhase_pT;
Real[Medium.nXi] Xi= fill(0,0);*/
Medium.BaseProperties props;
equation
props.p = 200000;
props.T = 300;
props.Xi = Xi;
assert(abs(props.GVF-0.32448128)<1e6,"GVF differs!");
assert(abs(props.h-188780.97)<1e6,"GVF differs!");
annotation (experiment(StopTime=1, __Dymola_NumberOfIntervals=1),
__Dymola_experimentSetupOutput);
end UnitTestsTwoPhase3Gas;
within BrineProp.Examples.TwoPhase;
model UnitTestsTwoPhase4Gas
//Compares calculation result with hardcoded values.
//no assert should be triggered
//To be filled...
//SPECIFY MEDIUM and COMPOSITION
package Medium = BrineProp.Brine3salts4gas(ignoreLimitN2_T=true,ignoreLimitSalt_T=fill(true,3));
Real[Medium.nXi] Xi = {0.0839077010751,0.00253365118988,0.122786737978,0.00016883,0.00073459,0.000065652,0.00001};
//DEFINE BRINE COMPOSITION (NaCl, KCl, CaCl2, MgCl2, SrCl2, CO2, N2, CH4)
/* package Medium = BrineProp.Brine5salts3gas;
Real[Medium.nXi] Xi = {0.0839077010751,0.00253365118988,0.122786737978,0,0,7.2426359111e-05,0.000689505657647,6.14906384726e-05} ;
*/
/* package Medium = BrineProp.Water_MixtureTwoPhase_pT;
Real[Medium.nXi] Xi= fill(0,0);*/
Medium.BaseProperties props;
equation
props.p = 20e5;
props.T = 330;
props.Xi = Xi;
//Unit Test
assert(abs(props.GVF-0.0497710432105261)<1e6,"GVF differs!");
assert(abs(props.h-288702.455)<1e6,"h differs!");
//direct Chabab
assert(abs(GasData.solubility_H2_pT_Chabab2020_y(1e7, 323.15) - 0.001272328226268451)< 1e-8, "Nope");
assert(abs(GasData.solubility_H2_pTb_Chabab2020_y(1e7,323.15,1) - 0.000958406222692535) < 1e-8, "Nope");
assert(abs(GasData.solubility_H2_pTb_Chabab2020_molality(1e7,323.15,1) - 0.0532507008145311) < 1e-8, "Nope");
assert(abs(0.00396636796628623-Medium.solubility_H2_pTX_Chabab2020_molality(50e5, 323.15,{0.0839077010751,0.00253365118988,0.122786737978,0.00016883,0.00073459,0.000065652,0.00001,0.789792838},Medium.MM_vec,15e5))<1e-8, "Nope");
assert(abs(6.31433733266665E-06-Medium.solubility_H2_pTX_Chabab2020(50e5, 323.15,{0.0839077010751,0.00253365118988,0.122786737978,0.00016883,0.00073459,0.000065652,0.00001,0.789792838},Medium.MM_vec, 15e5,false))<1e-8, "Nope");
annotation (experiment(StopTime=1, __Dymola_NumberOfIntervals=1),
__Dymola_experimentSetupOutput);
end UnitTestsTwoPhase4Gas;
UnitTestsTwoPhase3Gas
UnitTestsTwoPhase4Gas
PureWaterMinimal
PureWaterFlashing
BrineProps2PhaseMinimal
......
within BrineProp.Examples.UnitTests;
model H2solubility_Chabab
package Medium = BrineProp.Brine3salts3gas (ignoreNoCompositionInBrineGas=true);
package Medium = BrineProp.Brine3salts4gas (ignoreNoCompositionInBrineGas=true);
//package Medium = Modelica.Media.Air.SimpleAir;
//package Medium = PartialBrineGas;
// Medium.BaseProperties props;
equation
assert(abs(GasData.solubility_H2_pT_Chabab2020_y(1e7, 323.15) -
0.001272328226268451) < 1e-8, "Nope");
assert(abs(GasData.solubility_H2_pTb_Chabab2020_y(
1e7,
323.15,
1) - 0.0009584062226925354) < 1e-8, "Nope");
assert(abs(GasData.solubility_H2_pTb_Chabab2020_molality(
1e7,
323.15,
1) - 0.05325070081453114) < 1e-8, "Nope");
assert(abs(Medium.solubility_H2_pTX_Chabab2020_molality(102e5, 323.15,{0.0552160106873965,0,0,0,0,0,0}, 100e5, Modelica.Media.Water.WaterIF97_pT.saturationPressure(323.15))-0.05325070081453114)<1e-8, "Nope");
assert(abs(GasData.solubility_H2_pT_Chabab2020_y(1e7, 323.15) - 0.001272328226268451)< 1e-8, "Nope");
assert(abs(GasData.solubility_H2_pTb_Chabab2020_y(1e7,323.15,1) - 0.000958406222692535) < 1e-8, "Nope");
assert(abs(GasData.solubility_H2_pTb_Chabab2020_molality(1e7,323.15,1) - 0.0532507008145311) < 1e-8, "Nope");
assert(abs(0.00396636796628623-Medium.solubility_H2_pTX_Chabab2020_molality(50e5, 323.15,{0.0839077010751,0.00253365118988,0.122786737978,0.00016883,0.00073459,0.000065652,0.00001,0.789792838},Medium.MM_vec,15e5))<1e-8, "Nope");
assert(abs(6.31433733266665E-06-Medium.solubility_H2_pTX_Chabab2020(50e5, 323.15,{0.0839077010751,0.00253365118988,0.122786737978,0.00016883,0.00073459,0.000065652,0.00001,0.789792838},Medium.MM_vec, 15e5,false))<1e-8, "Nope");
annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram(
coordinateSystem(preserveAspectRatio=false)));
end H2solubility_Chabab;
......@@ -24,7 +24,7 @@ equation
props.Xi = Xi;
assert(abs(props.GVF-0.0497710432105261)<1e6,"GVF differs!");
assert(abs(props.h-288702.455)<1e6,"GVF differs!");
assert(abs(props.h-288702.455)<1e6,"h differs!");
annotation (experiment(StopTime=1, __Dymola_NumberOfIntervals=1),
__Dymola_experimentSetupOutput);
end UnitTestsTwoPhase4Gas;
within BrineProp.Examples;
package UnitTests
extends Modelica.Icons.ExamplesPackage;
end UnitTests;
......@@ -23,7 +23,7 @@ partial package PartialBrineGas "Medium template for gas mixture of nX_gas gases
// (h,x,d,d_g,d_l) = specificEnthalpy_pTX(p,T,X) unfortunately, this is not invertable;
h = specificEnthalpy_pTX(p,T,X);
// d=density_pTX(p,T,X);
(d,R) = density_pTX(p,T,X);
(d,R) = density_pTX(p,T,X, MM_vec);
state=ThermodynamicState(p=p,T=T,X=X);
end BaseProperties;
......@@ -47,9 +47,20 @@ constant String gasNames[:]={""};
input SI.Pressure p;
input SI.Temp_K T;
input MassFraction X[nX] "Mass fractions";
input SI.MolarMass MM[:]=fill(0,nX) "molar masses of components";
output SI.Density d;
output SpecificHeatCapacity R_gas;
//algorithm
algorithm
if debugmode then
print("Running density_pTX("+String(p/1e5)+" bar,"+String(T-273.15)+" degC, X="+Modelica.Math.Matrices.toString(transpose([X]))+")");
end if;
if not min(X)>0 and not ignoreNoCompositionInBrineGas then
print("No gas composition, assuming water vapour.(BrineProp.BrineGas_3Gas.density_pTX)");
end if;
R_gas :=Modelica.Constants.R*sum(cat(1,X[1:end-1],{(if min(X)>0 then X[end] else 1)})./ MM);
d :=p/(T*R_gas);
end density_pTX;
......
......@@ -126,6 +126,52 @@ partial package PartialBrineMultiSaltMultiGasTwoPhase "Template medium for aqueo
</html>"));
end ThermodynamicState;
redeclare function extends density "return density of ideal gas"
algorithm
d := state.d;
end density;
redeclare function density_pTX "wrapper to extract d from state"
//necessary for declaration of inverse function p(T,d)
input SI.Pressure p;
input SI.Temp_K T;
input MassFraction X[:] "mass fraction m_NaCl/m_Sol";
input FixedPhase phase=0
"2 for two-phase, 1 for one-phase, 0 if not known";
input Real[nX_gas+1] n_g_norm_start=fill(0.5,nX_gas+1)
"start value, all gas in gas phase, all water liquid";
output SI.Density d;
algorithm
if debugmode then
print("Running density_pTX("+String(p/1e5)+","+String(T-273.15)+"degC, X="+Modelica.Math.Matrices.toString(transpose([X]))+")");
end if;
d:=density(setState_pTX(p,T,X,phase,n_g_norm_start));
annotation(LateInline=true,inverse(p=pressure_dTX(d,T,X,phase,n_g_norm_start)));
end density_pTX;
replaceable function density_liq_pTX "Density of the liquid phase"
input SI.Pressure p "TODO: Rename to density_liq_pTX";
input SI.Temp_K T;
input MassFraction X[nX] "mass fraction m_NaCl/m_Sol";
input SI.MolarMass MM[:] "=MM_vec =fill(0,nX) molar masses of components";
output SI.Density d;
end density_liq_pTX;
replaceable function density_gas_pTX "Density of the gas phase"
input SI.Pressure p;
input SI.Temp_K T;
input MassFraction X[:] "nX_gas mass fraction";
input SI.MolarMass MM[:] "=MM_vec =fill(0,nX) molar masses of components";
output SI.Density d;
end density_gas_pTX;
redeclare function extends saturationTemperature "saturation temperature"
algorithm
T := 373.15;
end saturationTemperature;
redeclare function extends dewEnthalpy
"dew curve specific enthalpy of water"
algorithm
......@@ -138,11 +184,6 @@ partial package PartialBrineMultiSaltMultiGasTwoPhase "Template medium for aqueo
hl := 2000;
end bubbleEnthalpy;
redeclare function extends saturationTemperature "saturation temperature"
algorithm
T := 373.15;
end saturationTemperature;
replaceable partial function solutionEnthalpy
input SI.Temp_K T;
output SI.SpecificEnthalpy Delta_h_solution;
......@@ -172,14 +213,6 @@ protected
Types.Pressure_bar p_bar=SI.Conversions.to_bar(p);
end fugacity_pTX;
replaceable function density_liq_pTX "Density of the liquid phase"
input SI.Pressure p "TODO: Rename to density_liq_pTX";
input SI.Temp_K T;
input MassFraction X[nX] "mass fraction m_NaCl/m_Sol";
input SI.MolarMass MM[:] "=MM_vec =fill(0,nX) molar masses of components";
output SI.Density d;
end density_liq_pTX;
redeclare function vapourQuality
"Returns vapour quality, needs to be defined to overload function defined in PartialMixtureTwoPhaseMedium"
input ThermodynamicState state "Thermodynamic state record";
......@@ -188,56 +221,6 @@ protected
x := state.x;
end vapourQuality;
redeclare function specificEnthalpy_pTX "wrapper to extract h from state"
//necessary for declaration of inverse function T(p,h)
input SI.Pressure p;
input SI.Temp_K T;
input MassFraction X[:] "mass fraction m_NaCl/m_Sol";
input FixedPhase phase=0
"2 for two-phase, 1 for one-phase, 0 if not known";
input Real[nX_gas+1] n_g_norm_start=fill(0.5,nX_gas+1)
"start value, all gas in gas phase, all water liquid";
input Boolean ignoreTlimit=false;
output SI.SpecificEnthalpy h;
algorithm
if debugmode then
print("Running specificEnthalpy_pTX("+String(p/1e5)+" bar,"+String(T-273.15)+" C, ignoreTlimit="+String(ignoreTlimit)+", X="+Modelica.Math.Matrices.toString(transpose([X]))+")");
end if;
h:=specificEnthalpy(setState_pTX(
p,
T,
X,
phase,
n_g_norm_start,
ignoreTlimit));
//print(String(p)+","+String(T)+" K->"+String(h)+" J/kg & (PartialBrine_Multi_TwoPhase_ngas.specificEnthalpy_pTX)");
//,p=pressure_ThX(T,h,X);
annotation(LateInline=true,inverse(T=temperature_phX(p,h,X,phase,n_g_norm_start,ignoreTlimit)));
end specificEnthalpy_pTX;
redeclare function density_pTX "wrapper to extract d from state"
//necessary for declaration of inverse function p(T,d)
input SI.Pressure p;
input SI.Temp_K T;
input MassFraction X[:] "mass fraction m_NaCl/m_Sol";
input FixedPhase phase=0
"2 for two-phase, 1 for one-phase, 0 if not known";
input Real[nX_gas+1] n_g_norm_start=fill(0.5,nX_gas+1)
"start value, all gas in gas phase, all water liquid";
output SI.Density d;
algorithm
if debugmode then
print("Running density_pTX("+String(p/1e5)+","+String(T-273.15)+"degC, X="+Modelica.Math.Matrices.toString(transpose([X]))+")");
end if;
d:=density(setState_pTX(p,T,X,phase,n_g_norm_start));
annotation(LateInline=true,inverse(p=pressure_dTX(d,T,X,phase,n_g_norm_start)));
end density_pTX;
redeclare function temperature_phX
"iterative inversion of specificEnthalpy_pTX by regula falsi"
extends Modelica.Icons.Function;
......@@ -400,6 +383,36 @@ protected
end pressure_dTX;
redeclare function specificEnthalpy_pTX "wrapper to extract h from state"
//necessary for declaration of inverse function T(p,h)
input SI.Pressure p;
input SI.Temp_K T;
input MassFraction X[:] "mass fraction m_NaCl/m_Sol";
input FixedPhase phase=0
"2 for two-phase, 1 for one-phase, 0 if not known";
input Real[nX_gas+1] n_g_norm_start=fill(0.5,nX_gas+1)
"start value, all gas in gas phase, all water liquid";
input Boolean ignoreTlimit=false;
output SI.SpecificEnthalpy h;
algorithm
if debugmode then
print("Running specificEnthalpy_pTX("+String(p/1e5)+" bar,"+String(T-273.15)+" C, ignoreTlimit="+String(ignoreTlimit)+", X="+Modelica.Math.Matrices.toString(transpose([X]))+")");
end if;
h:=specificEnthalpy(setState_pTX(
p,
T,
X,
phase,
n_g_norm_start,
ignoreTlimit));
//print(String(p)+","+String(T)+" K->"+String(h)+" J/kg & (PartialBrine_Multi_TwoPhase_ngas.specificEnthalpy_pTX)");
//,p=pressure_ThX(T,h,X);
annotation(LateInline=true,inverse(T=temperature_phX(p,h,X,phase,n_g_norm_start,ignoreTlimit)));
end specificEnthalpy_pTX;
replaceable function specificEnthalpy_liq_pTX
"Specific enthalpy of liquid phase"
input SI.Pressure p;
......@@ -414,8 +427,8 @@ protected
"Specific enthalpy of gas in gas phase"
input SI.Pressure p;
input SI.Temp_K T;
// input SI.MolarMass MM[:]=fill(0,nX) "molar masses of components";
input MassFraction X[:] "mass fraction m_NaCl/m_Sol";
// input SI.MolarMass MM[:]=fill(0,nX) "molar masses of components";
output SI.SpecificEnthalpy h;
end specificEnthalpy_gas_pTX;
......@@ -429,7 +442,6 @@ protected
output SI.Pressure[nX_gas] p_sat;
end saturationPressures;
<