Ticket #5770: TestTotal.mo

File TestTotal.mo, 454.9 KB (added by Francesco Casella, 5 years ago)
Line 
1model Test
2 extends FlexiCaL.FeedWater.Tests.Tests_FWPHs_Accurate.Test_FWPH_11(fWPH_11_1(N_des = 3), system(allowFlowReversal = false));
3end Test;
4
5package FlexiCaL
6 package Components
7 model NusseltCondenser "Base model of feedwater heater condensing section based on Nusselt theory"
8 replaceable package Medium = Modelica.Media.Water.WaterIF97_ph constrainedby Modelica.Media.Interfaces.PartialMedium;
9 ThermoPower.Water.FlangeA drained_in(redeclare package Medium = Medium);
10 ThermoPower.Water.FlangeB drained_out(redeclare package Medium = Medium);
11 ThermoPower.Water.FlangeA steam_in(redeclare package Medium = Medium);
12 Modelica.Blocks.Interfaces.RealOutput zl_SP;
13 Modelica.Blocks.Interfaces.RealOutput level;
14 Medium.ThermodynamicState vapour_state "Thermodynamic state of the vapour";
15 Medium.ThermodynamicState liquid_state "Thermodynamic state of the liquid";
16 Medium.ThermodynamicState[Nw] condensate_state "Thermodynamic state of the condensate";
17 Medium.ThermodynamicState steamIn_state "Thermodynamic state of the inlet vapour";
18 Medium.ThermodynamicState drainedIn_state "Thermodynamic state of the inlet drain";
19 Medium.SaturationProperties sat "Saturation properties of the vapour";
20 parameter Integer Nw = 5 "Number of volumes, tube side";
21 parameter Integer Ntubes "Number of tubes";
22 parameter Modelica.SIunits.Length r_ext_tube "tube External Radius";
23 parameter Modelica.SIunits.Length L "Length of Condensated section";
24 parameter Modelica.SIunits.Length r_int "Internal Shell Radius";
25 parameter Modelica.SIunits.CoefficientOfHeatTransfer gamma "Nusselt theory HTC";
26 parameter Modelica.SIunits.Time tauev = 0.5 "Time constant of bulk evaporation";
27 parameter Modelica.SIunits.Height zl_set "Liquid level set point";
28 parameter Modelica.SIunits.Height zl_start "Liquid level start";
29 parameter Modelica.SIunits.Pressure p_start "Medium start pressure";
30 parameter Boolean allowFlowReversal = system.allowFlowReversal "= true to allow flow reversal, false restricts to design direction";
31 parameter ThermoPower.Choices.Init.Options initOpt = system.initOpt "Initialisation option";
32 parameter Boolean noInitialPressure = false "Remove initial equation on pressure";
33 outer ThermoPower.System system "System wide properties";
34 final parameter Modelica.SIunits.Area S = 2 * Modelica.Constants.pi * r_ext_tube * L * Ntubes "Heat transfer surface of Tubes";
35 final parameter Modelica.SIunits.Volume Vtot = L * Modelica.Constants.pi * (r_int ^ 2 - r_ext_tube ^ 2 * Ntubes) "Total free Internal Volume of the shell (Volume not occupied by tubes)";
36 final parameter Modelica.SIunits.Acceleration g = Modelica.Constants.g_n "Gravity Acceleration on Earth";
37 final parameter Modelica.SIunits.SpecificEnthalpy hv_start = Medium.dewEnthalpy(Medium.setSat_p(p_start)) "Vapour Start Specific Enthalpy";
38 final parameter Modelica.SIunits.SpecificEnthalpy hl_start = Medium.bubbleEnthalpy(Medium.setSat_p(p_start)) "Liquid Start Specific Enthalpy";
39 final parameter Modelica.SIunits.Temperature Tsat_start = Medium.saturationTemperature(p_start);
40 Modelica.SIunits.DerEnthalpyByPressure dhdp_lsat "Derivative of Enthalpy by pressure";
41 Modelica.SIunits.ThermalConductance G_sub = 0 "Subcooling UA, its value depens on how much tubes are submerged";
42 Medium.MassFlowRate ws_in "Steam mass flow rate";
43 Medium.MassFlowRate wd_in "Drained inlet mass flow rate";
44 Medium.MassFlowRate wd_out "Drained outet mass flow rate";
45 Medium.MassFlowRate w_cond "Condensed vapour mass flow rate";
46 Medium.MassFlowRate[Nw] ww "Condensed vapour mass flow rate in single volumes";
47 Medium.MassFlowRate w_ev "Mass flowrate of bulk evaporation";
48 Modelica.SIunits.Height zl(start = zl_start, stateSelect = StateSelect.prefer) "Medium level (relative to reference)";
49 Medium.AbsolutePressure p(start = p_start, stateSelect = StateSelect.prefer) "Medium pressure";
50 Modelica.SIunits.SpecificEnthalpy hv(start = hv_start, stateSelect = StateSelect.prefer) "Specific vapor enthalpy";
51 Modelica.SIunits.SpecificEnthalpy hl(start = hl_start, stateSelect = StateSelect.prefer) "Specific liquid enthalpy";
52 Medium.SpecificEnthalpy hs_in "Steam inlet specific enthalpy";
53 Medium.SpecificEnthalpy hd_in "Drained inlet specific enthalpy";
54 Modelica.SIunits.SpecificEnthalpy[Nw] hc(start = ones(Nw) * Medium.bubbleEnthalpy(Medium.setSat_p(p_start))) "Specific condensate enthalpy";
55 Modelica.SIunits.SpecificEnthalpy hv_sat "Specific saturated steam enthalpy";
56 Modelica.SIunits.SpecificEnthalpy hl_sat "Specific saturated liquid enthalpy on the free surface";
57 Medium.Temperature Tv "Vapour temperature";
58 Medium.Temperature Tl "Liquid temperature";
59 Medium.Temperature[Nw] Tc(start = ones(Nw) * (Tsat_start - 2)) "Condensate temperature";
60 Medium.Temperature T_sat(start = Tsat_start) "Medium saturation temperature";
61 Modelica.SIunits.Temperature[Nw] Tw "Wall temperatures";
62 Modelica.SIunits.Volume Vl "Volume occupied by liquid medium";
63 Modelica.SIunits.Volume Vv "Volume occupied by vapour";
64 Modelica.SIunits.Area Across_l "Cross Section Area of the condensate liquid";
65 Modelica.SIunits.Mass Ml "Condensate liquid mass";
66 Modelica.SIunits.Mass Mv "Vapour mass";
67 Modelica.SIunits.Density rho_v "Steam density";
68 Modelica.SIunits.Density rho_l "Liquid density";
69 Modelica.SIunits.Density rho_ls "Satured Liquid density";
70 Real x_s "Vapour quality at steam inlet";
71 Real x_d "Vapour quality at drained inlet";
72 Modelica.SIunits.MassFraction x_l "Mass fraction of vapour in the liquid volume";
73 Modelica.SIunits.Power Q_cond "Condensation thermal load";
74 Modelica.SIunits.Power Q_sub "Total Subcooling Power";
75 Modelica.SIunits.Power[Nw] Q_s "Subcooling Power in a single volume";
76 Modelica.SIunits.Power[Nw] Qw "Condensation thermal load on a single volume";
77 Modelica.SIunits.Power Q_flux "Actual total condensing flux";
78 Modelica.SIunits.Energy El "Condensate liquid energy";
79 Modelica.SIunits.Energy Ev "Vapour energy";
80 ThermoPower.Thermal.DHTVolumes Tube_wall(N = Nw);
81 initial equation
82 if initOpt == ThermoPower.Choices.Init.Options.noInit then
83 elseif initOpt == ThermoPower.Choices.Init.Options.steadyState then
84 if not noInitialPressure then
85 der(p) = 0;
86 end if;
87 der(zl) = 0;
88 der(hv) = 0;
89 der(hl) = 0;
90 elseif initOpt == ThermoPower.Choices.Init.Options.fixedState then
91 if not noInitialPressure then
92 p = p_start;
93 end if;
94 hv = hv_sat;
95 hl = hl_sat;
96 zl = zl_start;
97 else
98 assert(false, "Unsupported initialisation option");
99 end if;
100 equation
101 sat = Medium.setSat_p(p);
102 vapour_state = Medium.setState_ph(p, hv);
103 liquid_state = Medium.setState_ph(p, hl);
104 steamIn_state = Medium.setState_ph(p, inStream(steam_in.h_outflow));
105 drainedIn_state = Medium.setState_ph(p, inStream(drained_in.h_outflow));
106 Tv = Medium.temperature(vapour_state);
107 Tl = Medium.temperature(liquid_state);
108 rho_v = Medium.density(vapour_state);
109 hv_sat = Medium.dewEnthalpy(sat);
110 hl_sat = Medium.bubbleEnthalpy(sat);
111 T_sat = Medium.saturationTemperature(p);
112 rho_l = Medium.density(liquid_state);
113 rho_ls = Medium.bubbleDensity(sat);
114 dhdp_lsat = Medium.dBubbleEnthalpy_dPressure(sat);
115 x_s = Medium.vapourQuality(steamIn_state);
116 x_d = Medium.vapourQuality(drainedIn_state);
117 x_l = homotopy(if hl <= hl_sat then 0 else (hl - hl_sat) / (hv_sat - hl_sat), 0);
118 der(Ml) = ws_in * (1 - x_s) + wd_in * (1 - x_d) + w_cond - wd_out - w_ev;
119 der(El) = ws_in * (1 - x_s) * min(hs_in, hl_sat) + wd_in * (1 - x_d) * min(hd_in, hl_sat) + Q_flux - wd_out * hl - w_ev * hv_sat - Q_sub;
120 der(Mv) = ws_in * x_s + wd_in * x_d + w_ev - w_cond;
121 der(Ev) = ws_in * x_s * max(hs_in, hv_sat) + wd_in * x_d * max(hd_in, hv_sat) - Q_flux + w_ev * hv_sat - Q_cond;
122 Mv = Vv * rho_v "Vapour volume mass";
123 Ml = Vl * rho_l "Liquid volume mass";
124 Ev = Mv * Medium.specificInternalEnergy(vapour_state) "Vapour volume energy";
125 El = Ml * Medium.specificInternalEnergy(liquid_state) "Liquid volume energy";
126 Vv = Vtot - Vl "Vapour Volume";
127 Vl = L * Across_l "Condensate liquid Volume on the bottom of the cylinder";
128 Across_l = r_int ^ 2 * Modelica.Math.acos(1 - zl / r_int) - (r_int - zl) * sqrt(2 * r_int * zl - zl ^ 2) "Cross section of the Condensate liquid volume (Circular Segment)";
129 for j in 1:Nw loop
130 Q_s[j] = G_sub / Nw * (Tl - Tw[j]) "Subcooling power used to cool down the condensate liquid in the j-th volume";
131 Qw[j] = max(0, gamma * S / Nw * (T_sat - Tw[j])) "Condensating Power in the j-th volume";
132 ww[j] = Qw[j] / (hv - hc[j]) "Condensate Mass Flow rate raining from the tubes in the j-th volume";
133 condensate_state[j] = Medium.setState_pT(p, Tc[j]);
134 hc[j] = min(Medium.specificEnthalpy(condensate_state[j]), hl_sat);
135 Tc[j] = (Tw[j] + T_sat) / 2;
136 end for;
137 Q_sub = sum(Q_s) "Total Subcooling Power";
138 Q_flux = ww * hc;
139 Q_cond = sum(Qw) "Total Condensate Power";
140 w_cond = sum(ww) "Total Condensate Mass Flow Rate";
141 w_ev = x_l * rho_l * Vl / tauev "Evaporating Mass Flow Rate from the condensate liquid volume";
142 hs_in = homotopy(if not allowFlowReversal then inStream(steam_in.h_outflow) else if ws_in >= 0 then inStream(steam_in.h_outflow) else hv, inStream(steam_in.h_outflow));
143 hd_in = homotopy(if not allowFlowReversal then inStream(drained_in.h_outflow) else if wd_in >= 0 then inStream(drained_in.h_outflow) else hv, inStream(drained_in.h_outflow));
144 drained_out.h_outflow = hl;
145 steam_in.h_outflow = inStream(drained_out.h_outflow);
146 drained_in.h_outflow = inStream(drained_out.h_outflow);
147 ws_in = steam_in.m_flow;
148 wd_in = drained_in.m_flow;
149 wd_out = -drained_out.m_flow;
150 steam_in.p = p;
151 drained_in.p = p;
152 drained_out.p = p;
153 Tw = Tube_wall.T;
154 Tube_wall.Q = (-Qw) - Q_s;
155 zl_SP = zl_set;
156 level = zl;
157 assert(Vv > 0.6 * Vtot, "Condensation section flooded!");
158 assert(Vl > 0.02 * Vtot, "Condensation section almost emptied out!");
159 end NusseltCondenser;
160
161 model FWPH_Base
162 Modelica.SIunits.Time Tr_FW = flowFW_sub.Tr + flowFW_cond.Tr + flowFW_des.Tr;
163 Medium.Temperature[N_des + N_cond + N_sub] Tsteam;
164 Medium.Temperature[N_des + N_cond + N_sub] Twater;
165 replaceable package Medium = Modelica.Media.Water.WaterIF97_ph constrainedby Modelica.Media.Interfaces.PartialMedium;
166 replaceable model HeatTransferFW_des = ThermoPower.Thermal.HeatTransferFV.FlowDependentHeatTransferCoefficient(alpha = 0.8, gamma_nom = gamma_FW_des) constrainedby ThermoPower.Thermal.BaseClasses.DistributedHeatTransferFV;
167 replaceable model HeatTransferFW_cond = ThermoPower.Thermal.HeatTransferFV.FlowDependentHeatTransferCoefficient(gamma_nom = gamma_FW_cond, alpha = 0.8) constrainedby ThermoPower.Thermal.BaseClasses.DistributedHeatTransferFV;
168 replaceable model HeatTransferFW_sub = ThermoPower.Thermal.HeatTransferFV.FlowDependentHeatTransferCoefficient(gamma_nom = gamma_FW_sub, alpha = 0.8) constrainedby ThermoPower.Thermal.BaseClasses.DistributedHeatTransferFV;
169 replaceable model HeatTransferSTEAM = ThermoPower.Thermal.HeatTransferFV.FlowDependentHeatTransferCoefficient(gamma_nom = gamma_STEAM, alpha = 0.6) constrainedby ThermoPower.Thermal.BaseClasses.DistributedHeatTransferFV;
170 replaceable model HeatTransferDRAIN = ThermoPower.Thermal.HeatTransferFV.FlowDependentHeatTransferCoefficient(gamma_nom = gamma_DRAIN, alpha = 0.6) constrainedby ThermoPower.Thermal.BaseClasses.DistributedHeatTransferFV;
171 replaceable model HeatExchangerTopology_des = ThermoPower.Thermal.HeatExchangerTopologies.CounterCurrentFlow(Nw = N_des - 1) constrainedby ThermoPower.Thermal.BaseClasses.HeatExchangerTopologyData;
172 replaceable model HeatExchangerTopology_cond = ThermoPower.Thermal.HeatExchangerTopologies.CounterCurrentFlow(Nw = N_cond - 1) constrainedby ThermoPower.Thermal.BaseClasses.HeatExchangerTopologyData;
173 replaceable model HeatExchangerTopology_sub = ThermoPower.Thermal.HeatExchangerTopologies.CounterCurrentFlow(Nw = N_sub - 1) constrainedby ThermoPower.Thermal.BaseClasses.HeatExchangerTopologyData;
174
175 function HeatTransferCoefficientsFWPH "Compute the Heat Transfer coefficients for a Des-Cond-Sub FWPH"
176 replaceable package Medium = Modelica.Media.Water.WaterIF97_ph "Water/steam fluid medium model" annotation(choicesAllMatching = true);
177 input Medium.Temperature Ti "Inlet Temperature of the FWPH section";
178 input Medium.Temperature To "Outlet Temperature of the FWPH section";
179 input Modelica.SIunits.AbsolutePressure pi "Inlet Pressure of the FWPH section";
180 input Modelica.SIunits.AbsolutePressure po "Outlet Pressure of the FWPH section";
181 input Modelica.SIunits.MassFlowRate w_FW "Water mass flow rate";
182 input Modelica.SIunits.Length L "Section length";
183 input Modelica.SIunits.Length ri "Internal Tube Diameter";
184 input Modelica.SIunits.Length ro "External Tube Diameter";
185 input Integer N_t "Number od tubes";
186 input Modelica.SIunits.CoefficientOfHeatTransfer U "Global Heat transfer coefficient of the section";
187 input Real Rf "Fouling Factor";
188 input Modelica.SIunits.ThermalConductivity lambda_w "Metal Tube Thermal COnductivitiy";
189 output Modelica.SIunits.CoefficientOfHeatTransfer[2] h "FWPH average water and steam heat transfer coefficient";
190 protected
191 final parameter Medium.Temperature T = (Ti + To) / 2 "Mean Temperature in the FWPH section";
192 final parameter Modelica.SIunits.AbsolutePressure p = (pi + po) / 2 "Mean Pressure in the FWPH section";
193 final parameter Modelica.SIunits.Length di = 2 * ri "Internal Tube Diameter";
194 final parameter Modelica.SIunits.Length do = 2 * ro "External Tube Diameter";
195 Medium.ThermodynamicState fluidState;
196 Modelica.SIunits.Area Af "Fluid cross Areas";
197 Modelica.SIunits.Area Ai "Internal Area in the section";
198 Modelica.SIunits.Area Ao "External Area in the section";
199 Modelica.SIunits.DynamicViscosity mu "Dynamic Viscosities";
200 Modelica.SIunits.ThermalConductivity k "Water Thermal COnductivities";
201 Modelica.SIunits.ReynoldsNumber Re "Section Reynolds numbers";
202 Modelica.SIunits.PrandtlNumber Pr "Section Prandtl numbers";
203 Modelica.SIunits.SpecificHeatCapacityAtConstantPressure Cp "Mean Specific Heat Capacity";
204 Modelica.SIunits.NusseltNumber Nu " Nusselt numbers computed with the Dittus-Boelter Correlation";
205 Modelica.SIunits.Density rho "Inlet and Outlet local Water density";
206 Modelica.SIunits.Velocity v "Water velocity";
207 Modelica.SIunits.CoefficientOfHeatTransfer hi "FWPH average water heat transfer coefficient";
208 Modelica.SIunits.CoefficientOfHeatTransfer ho "FWPH section steam heat transfer coefficient";
209 algorithm
210 Af := Modelica.Constants.pi * ri ^ 2;
211 Ai := Modelica.Constants.pi * 2 * ri * L * N_t;
212 Ao := Modelica.Constants.pi * 2 * ro * L * N_t;
213 fluidState := Medium.setState_pT(p, T);
214 rho := Medium.density(fluidState);
215 v := w_FW / (Af * rho * N_t);
216 Cp := Medium.specificHeatCapacityCp(fluidState);
217 mu := Medium.dynamicViscosity(fluidState);
218 k := Medium.thermalConductivity(fluidState);
219 Re := rho * v * 2 * ri / mu;
220 Pr := Cp * mu / k;
221 Nu := 0.023 * Re ^ 0.8 * Pr ^ 0.4;
222 hi := k * Nu / (2 * ri);
223 ho := 1 / (1 / (U * Ao) - 1 / (hi * Ai) - Rf / Ai - Modelica.Math.log(do / di) / (2 * Modelica.Constants.pi * lambda_w * L * N_t)) / Ao;
224 h[1] := hi;
225 h[2] := ho;
226 end HeatTransferCoefficientsFWPH;
227
228 parameter Integer N_des = 6 "Number of nodes for thermal variables in the Desuperheating Section";
229 parameter Integer N_cond = N_des "Number of nodes for thermal variables in the Condensing Section";
230 parameter Integer N_sub = N_des "Number of nodes for thermal variables in the Subcooling Section";
231 parameter Integer N_tubes = 582 "Number of tubes in parallel";
232 parameter Modelica.SIunits.Length L_tot "Total Tube length";
233 parameter Modelica.SIunits.Length L_des "Tube length in the Desuperheating Section";
234 final parameter Modelica.SIunits.Length L_cond = L_tot - L_des - L_sub "Tube length in the Condensing Section";
235 parameter Modelica.SIunits.Length L_sub "Tube length in the Subcooling Section";
236 parameter Modelica.SIunits.Length r_tube_int "Internal radius (single tube)";
237 parameter Modelica.SIunits.Length r_tube_ext "External radius (single tube)";
238 parameter Modelica.SIunits.Mass Mass_dry_tube "Total dry tubes mass";
239 final parameter Modelica.SIunits.Density rho_metal = Mass_dry_tube / ((r_tube_ext ^ 2 - r_tube_int ^ 2) * pi * L_tot * N_tubes) "Metal density";
240 parameter Modelica.SIunits.SpecificHeatCapacity c_metal = 500 "Metal Specific Heat Capacity";
241 parameter Modelica.SIunits.ThermalConductivity lambda_metal = 45 "Thermal conductivity";
242 parameter ThermoPower.Units.SpecificThermalResistance Rf = 0.0000581 "Fouling Thermal Resistance";
243 parameter Modelica.SIunits.MassFlowRate wnom_FW "Nominal mass flowrate (total)";
244 parameter Modelica.SIunits.CoefficientOfHeatTransfer U_des "Global heat transfer coefficient in Desuperheating section";
245 parameter Modelica.SIunits.CoefficientOfHeatTransfer U_cond "Global heat transfer coefficient in Condensing section";
246 parameter Modelica.SIunits.CoefficientOfHeatTransfer U_sub "Global heat transfer coefficient in Subcooling section";
247 parameter Modelica.SIunits.SpecificEnthalpy[N_des] hstart_des = linspace(flowFW_des.hstartin, flowFW_des.hstartout, N_des) "Specific Enthalpies Start Values";
248 parameter Modelica.SIunits.SpecificEnthalpy[N_cond] hstart_cond = linspace(flowFW_cond.hstartin, flowFW_cond.hstartout, N_cond) "Specific Enthalpies Start Values";
249 parameter Modelica.SIunits.SpecificEnthalpy[N_sub] hstart_sub = linspace(flowFW_sub.hstartin, flowFW_sub.hstartout, N_sub) "Specific Enthalpies Start Values";
250 final parameter Modelica.SIunits.CoefficientOfHeatTransfer[2] gamma_DES = HeatTransferCoefficientsFWPH(Tinlet_nom_FW_des, Toutlet_nom_FW_des, pnom_FW_des, pnom_out_FW_des, wnom_FW, L_des, r_tube_int, r_tube_ext, N_tubes, U_des, Rf, lambda_metal) "Nominal water and steam heat transfer coefficient in Desuperheating section";
251 final parameter Modelica.SIunits.CoefficientOfHeatTransfer gamma_FW_des = gamma_DES[1] "Nominal water heat transfer coefficient in Desuperheating section";
252 final parameter Modelica.SIunits.CoefficientOfHeatTransfer[2] gamma_COND = HeatTransferCoefficientsFWPH(Tinlet_nom_FW_cond, Toutlet_nom_FW_cond, pnom_FW_cond, pnom_out_FW_cond, wnom_FW, L_cond, r_tube_int, r_tube_ext, N_tubes, U_cond, Rf, lambda_metal) "Nominal water and steam heat transfer coefficient in Desuperheating section";
253 final parameter Modelica.SIunits.CoefficientOfHeatTransfer gamma_FW_cond = gamma_COND[1] "Nominal water heat transfer coefficient in Desuperheating section";
254 final parameter Modelica.SIunits.CoefficientOfHeatTransfer[2] gamma_SUB = HeatTransferCoefficientsFWPH(Tinlet_nom_FW_sub, Toutlet_nom_FW_sub, pnom_FW_sub, pnom_out_FW_sub, wnom_FW, L_sub, r_tube_int, r_tube_ext, N_tubes, U_sub, Rf, lambda_metal) "Nominal water and steam heat transfer coefficient in Desuperheating section";
255 final parameter Modelica.SIunits.CoefficientOfHeatTransfer gamma_FW_sub = gamma_SUB[1] "Nominal water heat transfer coefficient in Desuperheating section";
256 final parameter Modelica.SIunits.Pressure dpnom_FW = pnom_FW_sub - pnom_out_FW_des "Nominal pressure drop (friction term only!)";
257 final parameter Modelica.SIunits.Pressure dpnom_FW_des = dpnom_FW * L_des / (L_des + L_cond + L_sub) "Nominal pressure drop (friction term only!)";
258 final parameter Modelica.SIunits.Pressure dpnom_FW_cond = dpnom_FW * L_cond / (L_des + L_cond + L_sub) "Nominal pressure drop (friction term only!)";
259 final parameter Modelica.SIunits.Pressure dpnom_FW_sub = dpnom_FW * L_sub / (L_des + L_cond + L_sub) "Nominal pressure drop (friction term only!)";
260 final parameter Modelica.Media.Interfaces.Types.Density rhonom_FW_des = Medium.density_pT((pnom_out_FW_des + pnom_FW_des) / 2, (Tinlet_nom_FW_des + Toutlet_nom_FW_des) / 2) "Nominal inlet density";
261 final parameter Modelica.Media.Interfaces.Types.Density rhonom_FW_cond = Medium.density_pT((pnom_out_FW_cond + pnom_FW_cond) / 2, (Tinlet_nom_FW_cond + Toutlet_nom_FW_cond) / 2) "Nominal inlet density";
262 final parameter Modelica.Media.Interfaces.Types.Density rhonom_FW_sub = Medium.density_pT((pnom_out_FW_sub + pnom_FW_sub) / 2, (Tinlet_nom_FW_sub + Toutlet_nom_FW_sub) / 2) "Nominal inlet density";
263 parameter Modelica.SIunits.PerUnit wnf_FW = 0.1 "Fraction of nominal flow rate at which linear friction equals turbulent friction";
264 final parameter Real pi = Modelica.Constants.pi;
265 final parameter Modelica.SIunits.CoefficientOfHeatTransfer gamma_STEAM = gamma_DES[2] "Nominal STEAM heat transfer coefficient in Desuperheating section";
266 parameter Modelica.SIunits.MassFlowRate wnom_STEAM "Nominal mass flowrate (total)";
267 parameter Modelica.SIunits.PerUnit wnf_STEAM = 0.1 "Fraction of nominal flow rate at which linear friction equals turbulent friction";
268 parameter Modelica.SIunits.AbsolutePressure dpnom_STEAM = 10000 "Nominal pressure drop in the Steam Tube Side";
269 parameter Modelica.SIunits.SpecificEnthalpy[N_des] hstart_STEAM = linspace(flowSTEAM.hstartin, flowSTEAM.hstartout, N_des) "Specific Enthalpies Start Values";
270 final parameter Modelica.SIunits.Area Adp = r_tube_int ^ 2 * pi * N_tubes "Cross Section of the pressure drop in the Steam Tube Side";
271 final parameter Modelica.Media.Interfaces.Types.Density rhonom_STEAM = Medium.density_pT(pnom_STEAM, (Tinlet_nom_STEAM + Toutlet_nom_STEAM) / 2) "Nominal inlet density";
272 final parameter Modelica.SIunits.CoefficientOfHeatTransfer gamma_DRAIN = gamma_SUB[2] "Nominal DRAIN water heat transfer coefficient in Subcooling section";
273 parameter Modelica.SIunits.SpecificEnthalpy[N_sub] hstart_DRAIN = linspace(flowDRAIN.hstartin, flowDRAIN.hstartout, N_des) "Specific Enthalpies Start Values";
274 parameter Modelica.SIunits.PressureDifference dpnom_DRAIN = 10000 "Nominal Drop pressure on drain side";
275 final parameter Modelica.SIunits.MassFlowRate wnom_DRAIN_in = wnom_DRAIN - wnom_STEAM "Nominal Inlet Drain Mass Flow Rate";
276 parameter Modelica.SIunits.MassFlowRate wnom_DRAIN = wnom_STEAM "Nominal outlet drain mass flowrate (total)";
277 parameter Modelica.SIunits.PerUnit wnf_DRAIN = 1 "Fraction of nominal flow rate at which linear friction equals turbulent friction";
278 final parameter Modelica.Media.Interfaces.Types.Density rhonom_DRAIN = Medium.density_pT(pnom_DRAIN, (Tinlet_nom_DRAIN + Toutlet_nom_DRAIN) / 2) "Nominal inlet density";
279 parameter Medium.Temperature Tin_DRAIN_nom = Tinlet_nom_DRAIN "Nominal inlet drain temperature from previous FWPH";
280 parameter Modelica.SIunits.Length r_shell_int "Internal radius of the Shell";
281 final parameter Modelica.SIunits.CoefficientOfHeatTransfer gamma_cond = gamma_COND[2] "Nusselt theory HTC";
282 parameter Modelica.SIunits.Time tauev = 0.5 "Time constant of bulk evaporation";
283 parameter Modelica.SIunits.Height zl_set = 0.3 "Liquid level set point";
284 parameter Modelica.SIunits.Time T_level = 5 "Desired Time Response";
285 final parameter Modelica.SIunits.Length alpha = r_shell_int / sqrt(2 * zl_set / r_shell_int - (zl_set / r_shell_int) ^ 2) + sqrt(2 * r_shell_int * zl_set - zl_set ^ 2) + (r_shell_int - zl_set) ^ 2 / sqrt(2 * r_shell_int * zl_set - zl_set ^ 2) "Derivate of the Cross section area of the condensate liquid wrt zl";
286 final parameter Modelica.SIunits.Area Av = 1 / thetanom_valve * wnom_valve / sqrt(2 * rhonom_DRAIN * dpnom_valve) "Vena Contracta Area";
287 final parameter Real Kp_PID = -5 / T_level * rhonom_DRAIN * L_cond * alpha / (1 / thetanom_valve * wnom_valve) "Proportional gain (normalised units)";
288 parameter Modelica.SIunits.Time Ti_PID = 100 "Integral time";
289 parameter Real PVmin_PID = 0.05 "Minimum value of process variable for scaling";
290 parameter Real PVmax_PID = r_shell_int / 2 "Maximum value of process variable for scaling";
291 parameter Real CSmin_PID = 0.05 "Minimum value of control signal for scaling";
292 parameter Real CSmax_PID = 1 "Maximum value of control signal for scaling";
293 parameter Real PVstart_PID = zl_set "Start value of PV (scaled)";
294 parameter Real CSstart_PID = thetanom_valve "Start value of CS (scaled)";
295 parameter Modelica.Media.Interfaces.Types.AbsolutePressure pnom_in_valve = pnom_DRAIN "Nominal inlet pressure";
296 parameter Modelica.Media.Interfaces.Types.AbsolutePressure pnom_out_valve "Nominal inlet pressure";
297 final parameter Modelica.SIunits.PressureDifference dpnom_valve = pnom_in_valve - pnom_out_valve "Nominal Drain Valve Drop Pressure";
298 parameter Modelica.SIunits.MassFlowRate wnom_valve = wnom_DRAIN "Nominal mass flowrate";
299 parameter Modelica.SIunits.PerUnit thetanom_valve = 0.8 "Nominal valve opening";
300 parameter Real k_valvedyn = 1 "Gain of the Drain Valve Dynamic";
301 parameter Modelica.SIunits.Time T_valvedyn = 0.2 "Time Constant of the Drain valve";
302 parameter Real y_start_valvedyn = thetanom_valve "Initial or guess drain value of output (= state)";
303 parameter Medium.Temperature[metalTubeFV_des.Nw] Tstart_wall_des = ThermoPower.Functions.linspaceExt(metalTubeFV_des.Tstart1, metalTubeFV_des.TstartN, metalTubeFV_des.Nw) "Wall Start values in Desuperheating section";
304 parameter Medium.Temperature[metalTubeFV_cond.Nw] Tstart_wall_cond = ThermoPower.Functions.linspaceExt(metalTubeFV_cond.Tstart1, metalTubeFV_cond.TstartN, metalTubeFV_cond.Nw) "Wall Start values in Condensing section";
305 parameter Medium.Temperature[metalTubeFV_sub.Nw] Tstart_wall_sub = ThermoPower.Functions.linspaceExt(metalTubeFV_sub.Tstart1, metalTubeFV_sub.TstartN, metalTubeFV_sub.Nw) "Wall Start values in Subcooling section";
306 final parameter Modelica.Media.Interfaces.Types.AbsolutePressure pnom_FW_des = pnom_out_FW_cond "Pressure start value";
307 parameter Modelica.Media.Interfaces.Types.AbsolutePressure pnom_out_FW_des "Pressure outlet start value";
308 final parameter Medium.Temperature Tinlet_nom_FW_des = Toutlet_nom_FW_cond "Inlet Temperature Feed Water side";
309 parameter Medium.Temperature Toutlet_nom_FW_des "Outlet Temperature Feed Water side";
310 final parameter Modelica.Media.Interfaces.Types.AbsolutePressure pnom_FW_cond = pnom_out_FW_sub "Pressure start value";
311 final parameter Modelica.Media.Interfaces.Types.AbsolutePressure pnom_out_FW_cond = pnom_FW_cond - dpnom_FW_cond "Pressure outlet start value";
312 final parameter Medium.Temperature Tinlet_nom_FW_cond = Toutlet_nom_FW_sub "Inlet Temperature Feed Water side";
313 parameter Medium.Temperature Toutlet_nom_FW_cond "Outlet Temperature Feed Water side";
314 parameter Modelica.Media.Interfaces.Types.AbsolutePressure pnom_FW_sub "Pressure start value";
315 final parameter Modelica.Media.Interfaces.Types.AbsolutePressure pnom_out_FW_sub = pnom_FW_sub - dpnom_FW_sub "Pressure outlet start value";
316 parameter Medium.Temperature Tinlet_nom_FW_sub "Inlet Temperature Feed Water side";
317 parameter Medium.Temperature Toutlet_nom_FW_sub "Outlet Temperature Feed Water side";
318 parameter Modelica.Media.Interfaces.Types.AbsolutePressure pnom_steam "Pressure start value";
319 final parameter Modelica.Media.Interfaces.Types.AbsolutePressure pnom_STEAM = pnom_steam + dpnom_STEAM "Pressure start value";
320 parameter Modelica.Media.Interfaces.Types.AbsolutePressure pnom_out_STEAM = pnom_steam - dpnom_STEAM "Pressure outlet start value";
321 parameter Medium.Temperature Tinlet_nom_STEAM "Inlet Temperature Feed Water side";
322 parameter Medium.Temperature Toutlet_nom_STEAM "Outlet Temperature Feed Water side";
323 parameter Modelica.Media.Interfaces.Types.AbsolutePressure pnom_DRAIN = pnom_out_STEAM "Pressure start value";
324 parameter Modelica.Media.Interfaces.Types.AbsolutePressure pnom_out_DRAIN = pnom_DRAIN "Pressure outlet start value";
325 parameter Medium.Temperature Tinlet_nom_DRAIN "Inlet Temperature Feed Water side";
326 parameter Medium.Temperature Toutlet_nom_DRAIN "Outlet Temperature Feed Water side";
327 parameter Modelica.SIunits.Height zl_start = 0.1 "Liquid level start";
328 parameter Modelica.SIunits.Pressure p_start_cond = pnom_STEAM "Medium start pressure";
329 parameter Boolean noInitialPressure_FW_des = false "Remove initial equation on pressure";
330 parameter Boolean noInitialPressure_FW_cond = false "Remove initial equation on pressure";
331 parameter Boolean noInitialPressure_FW_sub = false "Remove initial equation on pressure";
332 parameter Boolean noInitialPressure_STEAM = false "Remove initial equation on pressure";
333 parameter Boolean noInitialPressure_DRAIN = false "Remove initial equation on pressure";
334 parameter Boolean noInitialPressure_NusseltCondenser = false "Remove initial equation on pressure";
335 final parameter Modelica.SIunits.Density simpl_rho_FW = (rhonom_FW_des * L_des + rhonom_FW_cond * L_cond + rhonom_FW_sub * L_sub) / L_tot "Feed Water average density";
336 final parameter Medium.ThermodynamicState simpl_state_FW = Medium.setState_pT((pnom_out_FW_des + pnom_FW_sub) / 2, (Toutlet_nom_FW_des + Tinlet_nom_FW_des) / 2) "Feed Water average state";
337 final parameter Modelica.SIunits.SpecificHeatCapacity simpl_c_FW = Medium.specificHeatCapacityCp(simpl_state_FW) "Feed Water average Specific Heat Capacity";
338 final parameter Modelica.SIunits.CoefficientOfHeatTransfer simpl_hi = (gamma_FW_des * L_des + gamma_FW_cond * L_cond + gamma_FW_sub * L_sub) / L_tot "Internal Heat Transfer Coefficient";
339 final parameter Modelica.SIunits.CoefficientOfHeatTransfer simpl_ho = gamma_cond "External Heat Transfer Coefficient";
340 Controllers.Blocks.FirstOrder_init ValveDynamic(k = k_valvedyn, T = T_valvedyn, y_start = y_start_valvedyn);
341 Controllers.Blocks.PID_ThermoPower Level_PID(Kp = Kp_PID, Ti = Ti_PID, PVmin = PVmin_PID, PVmax = PVmax_PID, CSmin = CSmin_PID, CSmax = CSmax_PID, PVstart = PVstart_PID, CSstart = CSstart_PID);
342 ThermoPower.Water.Flow1DFV flowFW_des(N = N_des, Nw = N_des - 1, Nt = N_tubes, L = L_des, dpnom = dpnom_FW * L_des / (L_des + L_cond + L_sub), A = pi * r_tube_int ^ 2, omega = 2 * pi * r_tube_int, wnom = wnom_FW, FFtype = ThermoPower.Choices.Flow1D.FFtypes.OpPoint, rhonom = rhonom_FW_des, wnf = wnf_FW, pstart = pnom_FW_des, hstartin = Medium.specificEnthalpy_pT(pnom_FW_des, Tinlet_nom_FW_des), hstartout = Medium.specificEnthalpy_pT(pnom_out_FW_des, Toutlet_nom_FW_des), redeclare package Medium = Medium, redeclare model HeatTransfer = HeatTransferFW_des, HydraulicCapacitance = ThermoPower.Choices.Flow1D.HCtypes.Middle, noInitialPressure = noInitialPressure_FW_des, hstart = hstart_des);
343 ThermoPower.Water.Flow1DFV flowFW_cond(N = N_cond, Nw = N_cond - 1, Nt = N_tubes, L = L_cond, A = pi * r_tube_int ^ 2, omega = 2 * pi * r_tube_int, wnom = wnom_FW, FFtype = ThermoPower.Choices.Flow1D.FFtypes.OpPoint, rhonom = rhonom_FW_cond, wnf = wnf_FW, dpnom = dpnom_FW * L_cond / (L_des + L_cond + L_sub), hstartin = Medium.specificEnthalpy_pT(pnom_FW_cond, Tinlet_nom_FW_cond), hstartout = Medium.specificEnthalpy_pT(pnom_out_FW_cond, Toutlet_nom_FW_cond), pstart = pnom_FW_cond, redeclare package Medium = Medium, redeclare model HeatTransfer = HeatTransferFW_cond, HydraulicCapacitance = ThermoPower.Choices.Flow1D.HCtypes.Middle, noInitialPressure = noInitialPressure_FW_cond, hstart = hstart_cond);
344 ThermoPower.Water.Flow1DFV flowFW_sub(A = pi * r_tube_int ^ 2, omega = 2 * pi * r_tube_int, wnom = wnom_FW, FFtype = ThermoPower.Choices.Flow1D.FFtypes.OpPoint, rhonom = rhonom_FW_sub, wnf = wnf_FW, N = N_sub, Nw = N_sub - 1, Nt = N_tubes, L = L_sub, dpnom = dpnom_FW * L_sub / (L_des + L_cond + L_sub), hstartin = Medium.specificEnthalpy_pT(pnom_FW_sub, Tinlet_nom_FW_sub), hstartout = Medium.specificEnthalpy_pT(pnom_out_FW_sub, Toutlet_nom_FW_sub), pstart = pnom_FW_sub, redeclare package Medium = Medium, redeclare model HeatTransfer = HeatTransferFW_sub, HydraulicCapacitance = ThermoPower.Choices.Flow1D.HCtypes.Middle, noInitialPressure = noInitialPressure_FW_sub, hstart = hstart_sub);
345 ThermoPower.Water.Flow1DFV2ph flowDRAIN(N = N_sub, Nw = N_sub - 1, Nt = N_tubes, L = L_sub, A = pi * r_tube_int ^ 2, omega = 2 * pi * r_tube_int, wnom = wnom_DRAIN, FFtype = ThermoPower.Choices.Flow1D.FFtypes.OpPoint, dpnom = dpnom_DRAIN, rhonom = rhonom_DRAIN, HydraulicCapacitance = ThermoPower.Choices.Flow1D.HCtypes.Middle, FluidPhaseStart = ThermoPower.Choices.FluidPhase.FluidPhases.TwoPhases, hstartin = Medium.specificEnthalpy_pT(pnom_DRAIN, Tinlet_nom_DRAIN), hstartout = Medium.specificEnthalpy_pT(pnom_out_DRAIN, Toutlet_nom_DRAIN), wnf = wnf_DRAIN, pstart = pnom_DRAIN, redeclare package Medium = Medium, noInitialPressure = noInitialPressure_DRAIN, redeclare model HeatTransfer = HeatTransferDRAIN, hstart = hstart_DRAIN);
346 ThermoPower.Water.Flow1DFV2ph flowSTEAM(N = N_des, Nw = N_des - 1, Nt = N_tubes, L = L_des, A = pi * r_tube_int ^ 2, omega = 2 * pi * r_tube_int, wnom = wnom_STEAM, HydraulicCapacitance = ThermoPower.Choices.Flow1D.HCtypes.Middle, wnf = wnf_STEAM, hstartin = Medium.specificEnthalpy_pT(pnom_STEAM, Tinlet_nom_STEAM), hstartout = Medium.specificEnthalpy_pT(pnom_out_STEAM, Toutlet_nom_STEAM), pstart = p_start_cond, rhonom = rhonom_STEAM, redeclare package Medium = Medium, noInitialPressure = noInitialPressure_STEAM, redeclare model HeatTransfer = HeatTransferSTEAM, FFtype = ThermoPower.Choices.Flow1D.FFtypes.OpPoint, dpnom = dpnom_STEAM, FluidPhaseStart = ThermoPower.Choices.FluidPhase.FluidPhases.Steam, hstart = hstart_STEAM);
347 ThermoPower.Water.ValveLiq DrainValve(CvData = ThermoPower.Choices.Valve.CvTypes.OpPoint, dpnom = dpnom_valve, wnom = wnom_valve, thetanom = thetanom_valve, pnom = pnom_in_valve, rhonom = rhonom_DRAIN, redeclare package Medium = Medium, pout_start = pnom_out_valve);
348 ThermoPower.Thermal.MetalTubeFV metalTubeFV_des(Nw = N_des - 1, L = L_des, Nt = N_tubes, rint = r_tube_int, rext = r_tube_ext, rhomcm = rho_metal * c_metal, lambda = lambda_metal, Tstartbar = (Toutlet_nom_FW_des + Tinlet_nom_STEAM) / 2, Tstart1 = (Toutlet_nom_FW_des + Tinlet_nom_STEAM) / 2, TstartN = (Tinlet_nom_FW_des + Toutlet_nom_STEAM) / 2, Tvolstart = Tstart_wall_des);
349 ThermoPower.Thermal.MetalTubeFV metalTubeFV_cond(Nt = N_tubes, rint = r_tube_int, rext = r_tube_ext, rhomcm = rho_metal * c_metal, lambda = lambda_metal, Nw = N_cond - 1, L = L_cond, Tstartbar = (Toutlet_nom_FW_cond + Medium.saturationTemperature(pnom_STEAM)) / 2, Tstart1 = (Toutlet_nom_FW_cond + Medium.saturationTemperature(pnom_STEAM)) / 2, TstartN = (Tinlet_nom_FW_cond + Medium.saturationTemperature(pnom_STEAM)) / 2, Tvolstart = Tstart_wall_cond);
350 ThermoPower.Thermal.MetalTubeFV metalTubeFV_sub(Nt = N_tubes, rint = r_tube_int, rext = r_tube_ext, rhomcm = rho_metal * c_metal, lambda = lambda_metal, Nw = N_sub - 1, L = L_sub, Tstartbar = (Toutlet_nom_FW_sub + Tinlet_nom_DRAIN) / 2, Tstart1 = (Toutlet_nom_FW_sub + Tinlet_nom_DRAIN) / 2, TstartN = (Tinlet_nom_FW_sub + Toutlet_nom_DRAIN) / 2, Tvolstart = Tstart_wall_sub);
351 ThermoPower.Thermal.HeatExchangerTopologyFV heatExchangerTopologyFV_des(Nw = N_des - 1, redeclare model HeatExchangerTopology = HeatExchangerTopology_des);
352 ThermoPower.Thermal.HeatExchangerTopologyFV heatExchangerTopologyFV_cond(Nw = N_cond - 1, redeclare model HeatExchangerTopology = HeatExchangerTopology_cond);
353 ThermoPower.Thermal.HeatExchangerTopologyFV heatExchangerTopologyFV_sub(Nw = N_sub - 1, redeclare model HeatExchangerTopology = HeatExchangerTopology_sub);
354 FlexiCaL.Components.NusseltCondenser nusseltCondenser(Nw = N_cond - 1, r_ext_tube = r_tube_ext, Ntubes = N_tubes, L = L_cond, r_int = r_shell_int, gamma = gamma_cond, tauev = tauev, p_start = p_start_cond, zl_set = zl_set, zl_start = zl_set, redeclare package Medium = Medium, noInitialPressure = noInitialPressure_NusseltCondenser);
355 ThermoPower.Water.FlangeA FWin(redeclare package Medium = Medium);
356 ThermoPower.Water.FlangeA STEAMin(redeclare package Medium = Medium);
357 ThermoPower.Water.FlangeA DRAINin(redeclare package Medium = Medium);
358 ThermoPower.Water.FlangeB FWout(redeclare package Medium = Medium);
359 ThermoPower.Water.FlangeB DRAINout(redeclare package Medium = Medium);
360 ThermoPower.Thermal.FoulingFV foulingFV_sub(Nv = N_sub - 1, R = Rf, A = r_tube_int * pi * 2 * N_tubes * L_sub);
361 ThermoPower.Thermal.FoulingFV foulingFV_cond(Nv = N_cond - 1, R = Rf, A = r_tube_int * pi * 2 * N_tubes * L_cond);
362 ThermoPower.Thermal.FoulingFV foulingFV_des(Nv = N_des - 1, R = Rf, A = r_tube_int * pi * 2 * N_tubes * L_des);
363 equation
364 for i in 1:N_des + N_cond + N_sub loop
365 if i <= N_sub then
366 Tsteam[i] = flowDRAIN.T[N_sub + 1 - i];
367 elseif i <= N_sub + N_cond then
368 Tsteam[i] = nusseltCondenser.T_sat;
369 else
370 Tsteam[i] = flowSTEAM.T[N_sub + N_cond + N_des + 1 - i];
371 end if;
372 end for;
373 for i in 1:N_des + N_cond + N_sub loop
374 if i <= N_sub then
375 Twater[i] = flowFW_sub.T[i];
376 elseif i <= N_sub + N_cond then
377 Twater[i] = flowFW_cond.T[i - N_sub];
378 else
379 Twater[i] = flowFW_des.T[i - N_sub - N_cond];
380 end if;
381 end for;
382 connect(ValveDynamic.u, Level_PID.CS);
383 connect(flowDRAIN.outfl, DrainValve.inlet);
384 connect(DrainValve.theta, ValveDynamic.y);
385 connect(flowFW_cond.outfl, flowFW_des.infl);
386 connect(flowFW_sub.outfl, flowFW_cond.infl);
387 connect(metalTubeFV_des.int, heatExchangerTopologyFV_des.side2);
388 connect(metalTubeFV_cond.int, heatExchangerTopologyFV_cond.side2);
389 connect(metalTubeFV_sub.int, heatExchangerTopologyFV_sub.side2);
390 connect(flowSTEAM.wall, metalTubeFV_des.ext);
391 connect(flowDRAIN.infl, nusseltCondenser.drained_out);
392 connect(nusseltCondenser.steam_in, flowSTEAM.outfl);
393 connect(flowFW_sub.infl, FWin);
394 connect(flowFW_des.outfl, FWout);
395 connect(DrainValve.outlet, DRAINout);
396 connect(nusseltCondenser.drained_in, DRAINin);
397 connect(nusseltCondenser.Tube_wall, metalTubeFV_cond.ext);
398 connect(flowDRAIN.wall, metalTubeFV_sub.ext);
399 connect(nusseltCondenser.level, Level_PID.PV);
400 connect(nusseltCondenser.zl_SP, Level_PID.SP);
401 connect(flowFW_sub.wall, foulingFV_sub.side1);
402 connect(flowFW_cond.wall, foulingFV_cond.side1);
403 connect(heatExchangerTopologyFV_cond.side1, foulingFV_cond.side2);
404 connect(heatExchangerTopologyFV_des.side1, foulingFV_des.side2);
405 connect(flowFW_des.wall, foulingFV_des.side1);
406 connect(foulingFV_sub.side2, heatExchangerTopologyFV_sub.side1);
407 connect(flowSTEAM.infl, STEAMin);
408 end FWPH_Base;
409 end Components;
410
411 package Controllers
412 package Blocks
413 model FirstOrder_init
414 import Modelica.Blocks.Types.Init;
415 import ThermoPower.Choices;
416 outer ThermoPower.System system "System wide properties";
417 parameter Real k(unit = "1") = 1 "Gain";
418 parameter Modelica.SIunits.Time T(start = 1) "Time Constant";
419 parameter Choices.Init.Options initOpt = system.initOpt "Initialisation option";
420 parameter Real y_start = 0 "Initial or guess value of output (= state)";
421 extends Modelica.Blocks.Interfaces.SISO;
422 initial equation
423 if initOpt == Choices.Init.Options.noInit then
424 elseif initOpt == Choices.Init.Options.fixedState then
425 y = y_start;
426 elseif initOpt == Choices.Init.Options.steadyState then
427 der(y) = 0;
428 else
429 assert(false, "Unsupported initialisation option");
430 end if;
431 equation
432 der(y) = (k * u - y) / T;
433 end FirstOrder_init;
434
435 model PID_ThermoPower "PID controller with anti-windup"
436 import ThermoPower.Choices;
437 outer ThermoPower.System system "System wide properties";
438 parameter ThermoPower.Choices.Init.Options initOpt = system.initOpt "Initialisation option";
439 parameter Real Kp "Proportional gain (normalised units)";
440 parameter Modelica.SIunits.Time Ti "Integral time";
441 parameter Modelica.SIunits.Time Td = 0 "Derivative time";
442 parameter Real Nd = 1 "Derivative action up to Nd / Td rad/s";
443 parameter Real Ni = 1 "Ni*Ti is the time constant of anti-windup compensation";
444 parameter Real b = 1 "Setpoint weight on proportional action";
445 parameter Real c = 0 "Setpoint weight on derivative action";
446 parameter Real PVmin "Minimum value of process variable for scaling";
447 parameter Real PVmax "Maximum value of process variable for scaling";
448 parameter Real CSmin "Minimum value of control signal for scaling";
449 parameter Real CSmax "Maximum value of control signal for scaling";
450 parameter Real PVstart = 0.5 "Start value of PV (scaled)";
451 parameter Real CSstart = 0.5 "Start value of CS (scaled)";
452 parameter Boolean holdWhenSimplified = false "Hold CSs at start value when homotopy=simplified";
453 Real CSs_hom "Control signal scaled in per units, used when homotopy=simplified";
454 Real P "Proportional action / Kp";
455 Real I(start = CSstart / Kp) "Integral action / Kp";
456 Real D "Derivative action / Kp";
457 Real Dx(start = c * PVstart - PVstart) "State of approximated derivator";
458 Real PVs "Process variable scaled in per unit";
459 Real SPs "Setpoint variable scaled in per unit";
460 Real CSs(start = CSstart) "Control signal scaled in per unit";
461 Real CSbs(start = CSstart) "Control signal scaled in per unit before saturation";
462 Real track "Tracking signal for anti-windup integral action";
463 Modelica.Blocks.Interfaces.RealInput PV "Process variable signal";
464 Modelica.Blocks.Interfaces.RealOutput CS "Control signal";
465 Modelica.Blocks.Interfaces.RealInput SP "Set point signal";
466 Modelica.Blocks.Interfaces.RealOutput HS;
467 Modelica.Blocks.Interfaces.RealOutput LS;
468 initial equation
469 if initOpt == Choices.Init.Options.noInit then
470 elseif initOpt == Choices.Init.Options.fixedState then
471 CS = CSstart;
472 elseif initOpt == Choices.Init.Options.steadyState then
473 der(I) = 0;
474 else
475 assert(false, "Unsupported initialisation option");
476 end if;
477 equation
478 LS = CSbs;
479 HS = CSs;
480 SPs = (SP - PVmin) / (PVmax - PVmin);
481 PVs = (PV - PVmin) / (PVmax - PVmin);
482 CS = CSmin + CSs * (CSmax - CSmin);
483 P = b * SPs - PVs;
484 if Ti > 0 then
485 Ti * der(I) = SPs - PVs + track;
486 else
487 I = 0;
488 end if;
489 if Td > 0 then
490 Td / Nd * der(Dx) + Dx = c * SPs - PVs "State equation of approximated derivator";
491 D = Nd * (c * SPs - PVs - Dx) "Output equation of approximated derivator";
492 else
493 Dx = 0;
494 D = 0;
495 end if;
496 if holdWhenSimplified then
497 CSs_hom = CSstart;
498 else
499 CSs_hom = CSbs;
500 end if;
501 CSbs = Kp * (P + I + D) "Control signal before saturation";
502 CSs = homotopy(smooth(0, if CSbs > 1 then 1 else if CSbs < 0 then 0 else CSbs), CSs_hom) "Saturated control signal";
503 track = (CSs - CSbs) / (Kp * Ni);
504 end PID_ThermoPower;
505 end Blocks;
506 end Controllers;
507
508 package FeedWater "Components for feed water train modelling"
509 package FWPHs_Accurate "FWPH Sized Model (and tests) of the FWPH_11, FWPH_12, FWPH_13, FWPH_14, FWPH_15, Base FWPH Model"
510 package Sized_FWPHs
511 model FWPH_11
512 extends FlexiCaL.Components.FWPH_Base(PVmax_PID = 1, wnf_FW = 0.1, wnf_STEAM = 0.02, wnf_DRAIN = 0.02, Rf = 0.0000581, r_tube_int = 0.00692, r_tube_ext = 0.01111, L_tot = 29.78, r_shell_int = 1.28, N_tubes = 1357, Mass_dry_tube = 78791, U_des = 471.6, U_cond = 2738.7, U_sub = 771.4, L_des = 8.4, L_sub = 7.4, wnom_FW = 348.4, wnom_STEAM = 31.2, pnom_out_valve = 5828000, pnom_out_FW_des = 32010000, Toutlet_nom_FW_des = 580.15, Toutlet_nom_FW_cond = 574.15, pnom_FW_sub = 32086000, Tinlet_nom_FW_sub = 546.45, Toutlet_nom_FW_sub = 548.65, pnom_steam = 9076000, Tinlet_nom_STEAM = 661.45, Toutlet_nom_STEAM = 577.65, Tinlet_nom_DRAIN = 576.65, Toutlet_nom_DRAIN = 551.45);
513 end FWPH_11;
514 end Sized_FWPHs;
515 end FWPHs_Accurate;
516
517 package Tests
518 package Tests_FWPHs_Accurate
519 model Test_FWPH_base "Base model to test a FWPH"
520 replaceable package Medium = Modelica.Media.Water.WaterIF97_ph constrainedby Modelica.Media.Interfaces.PartialMedium;
521 parameter Modelica.SIunits.AbsolutePressure po_STEAM "Boundary condition for inlet STEAM";
522 parameter Modelica.SIunits.SpecificEnthalpy ho_STEAM "Boundary condition for inlet STEAM";
523 parameter Modelica.SIunits.MassFlowRate wo_FW_in "Boundary condition for inlet FeedWater";
524 parameter Modelica.SIunits.SpecificEnthalpy ho_FW_in "Boundary condition for inlet FeedWater";
525 parameter Modelica.SIunits.AbsolutePressure po_FW_out "Boundary condition for outlet FeedWater";
526 parameter Modelica.SIunits.SpecificEnthalpy ho_FW_out "Boundary condition for outlet FeedWater";
527 parameter Modelica.SIunits.MassFlowRate wo_DRAIN_in "Boundary condition for inlet DRAIN";
528 parameter Modelica.SIunits.SpecificEnthalpy ho_DRAIN_in = ho_DRAIN_out "Boundary condition for inlet DRAIN";
529 parameter Modelica.SIunits.AbsolutePressure po_DRAIN_out "Boundary condition for outlet DRAIN";
530 parameter Modelica.SIunits.SpecificEnthalpy ho_DRAIN_out "Boundary condition for outlet DRAIN";
531 inner ThermoPower.System system(initOpt = ThermoPower.Choices.Init.Options.steadyState);
532 ThermoPower.Water.SourcePressure STEAMin(redeclare package Medium = Medium, use_in_T = false, p0 = po_STEAM, h = ho_STEAM);
533 ThermoPower.Water.SinkPressure FWout(redeclare package Medium = Medium, p0 = po_FW_out, h = ho_FW_out);
534 ThermoPower.Water.SensT sensTo(redeclare package Medium = Medium);
535 ThermoPower.Water.SourceMassFlow DRAINin(redeclare package Medium = Medium, w0 = wo_DRAIN_in, h = ho_DRAIN_in);
536 ThermoPower.Water.SinkPressure DRAINout(redeclare package Medium = Medium, p0 = po_DRAIN_out, h = ho_DRAIN_out);
537 ThermoPower.Water.SensW sensWDR(redeclare package Medium = Medium);
538 ThermoPower.Water.SensT sensTi(redeclare package Medium = Medium);
539 ThermoPower.Water.SensW senswFW(redeclare package Medium = Medium);
540 ThermoPower.Water.SourceMassFlow FWin(redeclare package Medium = Medium, use_in_w0 = false, use_in_T = false, w0 = wo_FW_in, h = ho_FW_in);
541 equation
542 connect(FWout.flange, sensTo.outlet);
543 connect(DRAINout.flange, sensWDR.outlet);
544 connect(FWin.flange, senswFW.inlet);
545 connect(senswFW.outlet, sensTi.inlet);
546 end Test_FWPH_base;
547
548 model Test_FWPH_11
549 extends Test_FWPH_base(wo_DRAIN_in = 0, ho_STEAM = 3082e3, wo_FW_in = 348.4, ho_FW_in = 1197.3e3, ho_FW_out = 1363.5e3, ho_DRAIN_out = 1226.4e3, po_STEAM = 9090000, po_FW_out = 32010000, po_DRAIN_out = 5818000);
550 FlexiCaL.FeedWater.FWPHs_Accurate.Sized_FWPHs.FWPH_11 fWPH_11_1;
551 equation
552 connect(sensTo.inlet, fWPH_11_1.FWout);
553 connect(STEAMin.flange, fWPH_11_1.STEAMin);
554 connect(fWPH_11_1.FWin, sensTi.outlet);
555 connect(fWPH_11_1.DRAINout, sensWDR.inlet);
556 connect(fWPH_11_1.DRAINin, DRAINin.flange);
557 annotation(experiment(StopTime = 1000));
558 end Test_FWPH_11;
559 end Tests_FWPHs_Accurate;
560 end Tests;
561 end FeedWater;
562end FlexiCaL;
563
564package ThermoPower "Open library for thermal power plant simulation"
565 extends Modelica.Icons.Package;
566 import SI = Modelica.SIunits;
567 import NonSI = Modelica.SIunits.Conversions.NonSIunits;
568
569 model System "System wide properties and defaults"
570 parameter Boolean allowFlowReversal = true "= false to restrict to design flow direction (flangeA -> flangeB)" annotation(Evaluate = true);
571 parameter Choices.Init.Options initOpt = ThermoPower.Choices.Init.Options.fixedState;
572 parameter SI.Pressure p_amb = 101325 "Ambient pressure";
573 parameter SI.Temperature T_amb = 293.15 "Ambient Temperature (dry bulb)";
574 parameter SI.Temperature T_wb = 288.15 "Ambient temperature (wet bulb)";
575 parameter SI.Frequency fnom = 50 "Nominal grid frequency";
576 annotation(defaultComponentPrefixes = "inner", missingInnerMessage = "The System object is missing, please drag it on the top layer of your model");
577 end System;
578
579 package Water "Models of components with water/steam as working fluid"
580 connector Flange "Flange connector for water/steam flows"
581 replaceable package Medium = StandardWater constrainedby Modelica.Media.Interfaces.PartialMedium;
582 flow Medium.MassFlowRate m_flow "Mass flow rate from the connection point into the component";
583 Medium.AbsolutePressure p "Thermodynamic pressure in the connection point";
584 stream Medium.SpecificEnthalpy h_outflow "Specific thermodynamic enthalpy close to the connection point if m_flow < 0";
585 stream Medium.MassFraction[Medium.nXi] Xi_outflow "Independent mixture mass fractions m_i/m close to the connection point if m_flow < 0";
586 stream Medium.ExtraProperty[Medium.nC] C_outflow "Properties c_i/m close to the connection point if m_flow < 0";
587 end Flange;
588
589 connector FlangeA "A-type flange connector for water/steam flows"
590 extends ThermoPower.Water.Flange;
591 end FlangeA;
592
593 connector FlangeB "B-type flange connector for water/steam flows"
594 extends ThermoPower.Water.Flange;
595 end FlangeB;
596
597 extends Modelica.Icons.Package;
598 package StandardWater = Modelica.Media.Water.StandardWater;
599
600 model SourcePressure "Pressure source for water/steam flows"
601 extends Icons.Water.SourceP;
602 replaceable package Medium = StandardWater constrainedby Modelica.Media.Interfaces.PartialMedium;
603 parameter Medium.AbsolutePressure p0 = 1.01325e5 "Nominal pressure";
604 parameter Units.HydraulicResistance R = 0 "Hydraulic resistance";
605 parameter Boolean use_T = false "Use the temperature if true, otherwise use specific enthalpy";
606 parameter Medium.Temperature T = 298.15 "Nominal temperature";
607 parameter Medium.SpecificEnthalpy h = 1e5 "Nominal specific enthalpy";
608 parameter Boolean allowFlowReversal = system.allowFlowReversal "= true to allow flow reversal, false restricts to design direction" annotation(Evaluate = true);
609 parameter Boolean use_in_p0 = false "Use connector input for the pressure";
610 parameter Boolean use_in_T = false "Use connector input for the temperature";
611 parameter Boolean use_in_h = false "Use connector input for the specific enthalpy";
612 outer ThermoPower.System system "System wide properties";
613 Medium.AbsolutePressure p "Actual pressure";
614 FlangeB flange(redeclare package Medium = Medium);
615 Modelica.Blocks.Interfaces.RealInput in_p0 if use_in_p0;
616 Modelica.Blocks.Interfaces.RealInput in_T if use_in_T "Externally supplied temperature";
617 Modelica.Blocks.Interfaces.RealInput in_h if use_in_h;
618 protected
619 Modelica.Blocks.Interfaces.RealInput in_p0_internal;
620 Modelica.Blocks.Interfaces.RealInput in_T_internal;
621 Modelica.Blocks.Interfaces.RealInput in_h_internal;
622 equation
623 if R > 0 then
624 flange.p = p + flange.m_flow * R;
625 else
626 flange.p = p;
627 end if;
628 p = in_p0_internal;
629 if not use_in_p0 then
630 in_p0_internal = p0 "Pressure set by parameter";
631 end if;
632 if use_T then
633 flange.h_outflow = Medium.specificEnthalpy_pT(p = flange.p, T = in_T_internal);
634 else
635 flange.h_outflow = in_h_internal "Enthalpy set by connector";
636 end if;
637 if not use_in_T then
638 in_T_internal = T "Temperature set by parameter";
639 end if;
640 if not use_in_h then
641 in_h_internal = h "Enthalpy set by parameter";
642 end if;
643 connect(in_p0, in_p0_internal);
644 connect(in_T, in_T_internal);
645 connect(in_h, in_h_internal);
646 assert(not (use_in_T and use_in_h), "Either temperature or specific enthalpy input");
647 assert(not (use_T and use_in_h), "use_in_h required use_T = false");
648 assert(not (not use_T and use_in_T), "use_in_T required use_T = true");
649 end SourcePressure;
650
651 model SinkPressure "Pressure sink for water/steam flows"
652 extends Icons.Water.SourceP;
653 replaceable package Medium = StandardWater constrainedby Modelica.Media.Interfaces.PartialMedium;
654 parameter Medium.AbsolutePressure p0 = 1.01325e5 "Nominal pressure";
655 parameter Units.HydraulicResistance R = 0 "Hydraulic resistance" annotation(Evaluate = true);
656 parameter Boolean use_T = false "Use the temperature if true, otherwise use specific enthalpy";
657 parameter Medium.Temperature T = 298.15 "Nominal temperature";
658 parameter Medium.SpecificEnthalpy h = 1e5 "Nominal specific enthalpy";
659 parameter Boolean allowFlowReversal = system.allowFlowReversal "= true to allow flow reversal, false restricts to design direction" annotation(Evaluate = true);
660 parameter Boolean use_in_p0 = false "Use connector input for the pressure";
661 parameter Boolean use_in_T = false "Use connector input for the temperature";
662 parameter Boolean use_in_h = false "Use connector input for the specific enthalpy";
663 outer ThermoPower.System system "System wide properties";
664 Medium.AbsolutePressure p "Actual pressure";
665 FlangeA flange(redeclare package Medium = Medium, m_flow(min = if allowFlowReversal then -Modelica.Constants.inf else 0));
666 Modelica.Blocks.Interfaces.RealInput in_p0 if use_in_p0;
667 Modelica.Blocks.Interfaces.RealInput in_T if use_in_T "Externally supplied temperature";
668 Modelica.Blocks.Interfaces.RealInput in_h if use_in_h;
669 protected
670 Modelica.Blocks.Interfaces.RealInput in_p0_internal;
671 Modelica.Blocks.Interfaces.RealInput in_T_internal;
672 Modelica.Blocks.Interfaces.RealInput in_h_internal;
673 equation
674 if R > 0 then
675 flange.p = p + flange.m_flow * R;
676 else
677 flange.p = p;
678 end if;
679 p = in_p0_internal;
680 if not use_in_p0 then
681 in_p0_internal = p0 "Pressure set by parameter";
682 end if;
683 if use_T then
684 flange.h_outflow = Medium.specificEnthalpy_pT(p = flange.p, T = in_T_internal);
685 else
686 flange.h_outflow = in_h_internal "Enthalpy set by connector";
687 end if;
688 if not use_in_T then
689 in_T_internal = T "Temperature set by parameter";
690 end if;
691 if not use_in_h then
692 in_h_internal = h "Enthalpy set by parameter";
693 end if;
694 connect(in_p0, in_p0_internal);
695 connect(in_T, in_T_internal);
696 connect(in_h, in_h_internal);
697 assert(not (use_in_T and use_in_h), "Either temperature or specific enthalpy input");
698 assert(not (use_T and use_in_h), "use_in_h required use_T = false");
699 assert(not (not use_T and use_in_T), "use_in_T required use_T = true");
700 end SinkPressure;
701
702 model SourceMassFlow "Flowrate source for water/steam flows"
703 extends Icons.Water.SourceW;
704 replaceable package Medium = StandardWater constrainedby Modelica.Media.Interfaces.PartialPureSubstance;
705 parameter Medium.MassFlowRate w0 = 0 "Nominal mass flowrate";
706 parameter Medium.AbsolutePressure p0 = 1e5 "Nominal pressure";
707 parameter Units.HydraulicConductance G = 0 "Hydraulic conductance";
708 parameter Boolean use_T = false "Use the temperature if true, otherwise use specific enthalpy";
709 parameter Medium.Temperature T = 298.15 "Nominal temperature";
710 parameter Medium.SpecificEnthalpy h = 1e5 "Nominal specific enthalpy";
711 parameter Boolean allowFlowReversal = system.allowFlowReversal "= true to allow flow reversal, false restricts to design direction" annotation(Evaluate = true);
712 parameter Boolean use_in_w0 = false "Use connector input for the mass flow";
713 parameter Boolean use_in_T = false "Use connector input for the temperature";
714 parameter Boolean use_in_h = false "Use connector input for the specific enthalpy";
715 outer ThermoPower.System system "System wide properties";
716 Medium.MassFlowRate w "Mass flow rate";
717 FlangeB flange(redeclare package Medium = Medium);
718 Modelica.Blocks.Interfaces.RealInput in_w0 if use_in_w0 "Externally supplied mass flow rate";
719 Modelica.Blocks.Interfaces.RealInput in_T if use_in_T "Externally supplied temperature";
720 Modelica.Blocks.Interfaces.RealInput in_h if use_in_h "Externally supplied specific enthalpy";
721 protected
722 Modelica.Blocks.Interfaces.RealInput in_w0_internal;
723 Modelica.Blocks.Interfaces.RealInput in_T_internal;
724 Modelica.Blocks.Interfaces.RealInput in_h_internal;
725 equation
726 if G > 0 then
727 flange.m_flow = (-w) + (flange.p - p0) * G;
728 else
729 flange.m_flow = -w;
730 end if;
731 w = in_w0_internal;
732 if not use_in_w0 then
733 in_w0_internal = w0 "Flow rate set by parameter";
734 end if;
735 if use_T then
736 flange.h_outflow = Medium.specificEnthalpy_pT(p = flange.p, T = in_T_internal);
737 else
738 flange.h_outflow = in_h_internal "Enthalpy set by connector";
739 end if;
740 if not use_in_T then
741 in_T_internal = T "Temperature set by parameter";
742 end if;
743 if not use_in_h then
744 in_h_internal = h "Enthalpy set by parameter";
745 end if;
746 connect(in_w0, in_w0_internal);
747 connect(in_h, in_h_internal);
748 connect(in_T, in_T_internal);
749 assert(not (use_in_T and use_in_h), "Either temperature or specific enthalpy input");
750 assert(not (use_T and use_in_h), "use_in_h required use_T = false");
751 assert(not (not use_T and use_in_T), "use_in_T required use_T = true");
752 end SourceMassFlow;
753
754 model Flow1DFV "1-dimensional fluid flow model for water/steam (finite volumes)"
755 extends BaseClasses.Flow1DBase;
756 import ThermoPower.Choices.Flow1D.FFtypes;
757 import ThermoPower.Choices.Flow1D.HCtypes;
758 parameter SI.PerUnit wnm = 1e-3 "Maximum fraction of the nominal flow rate allowed as reverse flow";
759 parameter Boolean fixedMassFlowSimplified = false "Fix flow rate = wnom for simplified homotopy model";
760 Medium.ThermodynamicState[N] fluidState "Thermodynamic state of the fluid at the nodes";
761 SI.Length omega_hyd "Wet perimeter (single tube)";
762 SI.Pressure Dpfric "Pressure drop due to friction (total)";
763 SI.Pressure Dpfric1 "Pressure drop due to friction (from inlet to capacitance)";
764 SI.Pressure Dpfric2 "Pressure drop due to friction (from capacitance to outlet)";
765 SI.Pressure Dpstat "Pressure drop due to static head";
766 Medium.MassFlowRate win "Flow rate at the inlet (single tube)";
767 Medium.MassFlowRate wout "Flow rate at the outlet (single tube)";
768 Real Kf "Hydraulic friction coefficient";
769 Real dwdt "Dynamic momentum term";
770 SI.PerUnit Cf "Fanning friction factor";
771 Medium.AbsolutePressure p(start = pstart, stateSelect = StateSelect.prefer) "Fluid pressure for property calculations";
772 Medium.MassFlowRate w(start = wnom / Nt) "Mass flow rate (single tube)";
773 Medium.MassFlowRate[N - 1] wbar(each start = wnom / Nt) "Average flow rate through volumes (single tube)";
774 SI.Power[N - 1] Q_single = heatTransfer.Qvol / Nt "Heat flows entering the volumes from the lateral boundary (single tube)";
775 SI.Velocity[N] u "Fluid velocity";
776 Medium.Temperature[N] T "Fluid temperature";
777 Medium.SpecificEnthalpy[N] h(start = hstart) "Fluid specific enthalpy at the nodes";
778 Medium.SpecificEnthalpy[N - 1] htilde(start = hstart[2:N], each stateSelect = StateSelect.prefer) "Enthalpy state variables";
779 Medium.Density[N] rho "Fluid nodal density";
780 SI.Mass M "Fluid mass (single tube)";
781 SI.Mass Mtot "Fluid mass (total)";
782 SI.MassFlowRate[N - 1] dMdt "Time derivative of mass in each cell between two nodes";
783 replaceable model HeatTransfer = Thermal.HeatTransferFV.IdealHeatTransfer constrainedby ThermoPower.Thermal.BaseClasses.DistributedHeatTransferFV;
784 HeatTransfer heatTransfer(redeclare package Medium = Medium, final Nf = N, final Nw = Nw, final Nt = Nt, final L = L, final A = A, final Dhyd = Dhyd, final omega = omega, final wnom = wnom / Nt, final w = w * ones(N), final fluidState = fluidState) "Instantiated heat transfer model";
785 ThermoPower.Thermal.DHTVolumes wall(final N = Nw);
786 protected
787 Medium.Density[N - 1] rhobar "Fluid average density";
788 SI.SpecificVolume[N - 1] vbar "Fluid average specific volume";
789 SI.DerDensityByEnthalpy[N] drdh "Derivative of density by enthalpy";
790 SI.DerDensityByEnthalpy[N - 1] drbdh "Derivative of average density by enthalpy";
791 SI.DerDensityByPressure[N] drdp "Derivative of density by pressure";
792 SI.DerDensityByPressure[N - 1] drbdp "Derivative of average density by pressure";
793 initial equation
794 if initOpt == Choices.Init.Options.noInit then
795 elseif initOpt == Choices.Init.Options.fixedState then
796 if not noInitialPressure then
797 p = pstart;
798 end if;
799 htilde = hstart[2:N];
800 elseif initOpt == Choices.Init.Options.steadyState then
801 der(htilde) = zeros(N - 1);
802 if not Medium.singleState and not noInitialPressure then
803 der(p) = 0;
804 end if;
805 elseif initOpt == Choices.Init.Options.steadyStateNoP then
806 der(htilde) = zeros(N - 1);
807 assert(false, "initOpt = steadyStateNoP deprecated, use steadyState and noInitialPressure", AssertionLevel.warning);
808 elseif initOpt == Choices.Init.Options.steadyStateNoT and not Medium.singleState then
809 der(p) = 0;
810 else
811 assert(false, "Unsupported initialisation option");
812 end if;
813 equation
814 omega_hyd = 4 * A / Dhyd;
815 if FFtype == FFtypes.Kfnom then
816 Kf = Kfnom * Kfc;
817 elseif FFtype == FFtypes.OpPoint then
818 Kf = dpnom * rhonom / (wnom / Nt) ^ 2 * Kfc;
819 elseif FFtype == FFtypes.Cfnom then
820 Cf = Cfnom * Kfc;
821 elseif FFtype == FFtypes.Colebrook then
822 Cf = f_colebrook(w, Dhyd / A, e, Medium.dynamicViscosity(fluidState[integer(N / 2)])) * Kfc;
823 else
824 Cf = 0;
825 end if;
826 Kf = Cf * omega_hyd * L / (2 * A ^ 3) "Relationship between friction coefficient and Fanning friction factor";
827 assert(Kf >= 0, "Negative friction coefficient");
828 if DynamicMomentum then
829 dwdt = der(w);
830 else
831 dwdt = 0;
832 end if;
833 sum(dMdt) = (infl.m_flow + outfl.m_flow) / Nt "Mass balance";
834 L / A * dwdt + outfl.p - infl.p + Dpstat + Dpfric = 0 "Momentum balance";
835 Dpfric = Dpfric1 + Dpfric2 "Total pressure drop due to friction";
836 if FFtype == FFtypes.NoFriction then
837 Dpfric1 = 0;
838 Dpfric2 = 0;
839 elseif HydraulicCapacitance == HCtypes.Middle then
840 Dpfric1 = homotopy(Kf * squareReg(win, wnom / Nt * wnf) * sum(vbar[1:integer((N - 1) / 2)]) / (N - 1), dpnom / 2 / (wnom / Nt) * win) "Pressure drop from inlet to capacitance";
841 Dpfric2 = homotopy(Kf * squareReg(wout, wnom / Nt * wnf) * sum(vbar[1 + integer((N - 1) / 2):N - 1]) / (N - 1), dpnom / 2 / (wnom / Nt) * wout) "Pressure drop from capacitance to outlet";
842 elseif HydraulicCapacitance == HCtypes.Upstream then
843 Dpfric1 = 0 "Pressure drop from inlet to capacitance";
844 Dpfric2 = homotopy(Kf * squareReg(wout, wnom / Nt * wnf) * sum(vbar) / (N - 1), dpnom / (wnom / Nt) * wout) "Pressure drop from capacitance to outlet";
845 else
846 Dpfric1 = homotopy(Kf * squareReg(win, wnom / Nt * wnf) * sum(vbar) / (N - 1), dpnom / (wnom / Nt) * win) "Pressure drop from inlet to capacitance";
847 Dpfric2 = 0 "Pressure drop from capacitance to outlet";
848 end if;
849 Dpstat = if abs(dzdx) < 1e-6 then 0 else g * l * dzdx * sum(rhobar) "Pressure drop due to static head";
850 for j in 1:N - 1 loop
851 if Medium.singleState then
852 A * l * rhobar[j] * der(htilde[j]) + wbar[j] * (h[j + 1] - h[j]) = Q_single[j] "Energy balance (pressure effects neglected)";
853 else
854 A * l * rhobar[j] * der(htilde[j]) + wbar[j] * (h[j + 1] - h[j]) - A * l * der(p) = Q_single[j] "Energy balance";
855 end if;
856 dMdt[j] = A * l * (drbdh[j] * der(htilde[j]) + drbdp[j] * der(p)) "Mass derivative for each volume";
857 rhobar[j] = (rho[j] + rho[j + 1]) / 2;
858 drbdp[j] = (drdp[j] + drdp[j + 1]) / 2;
859 drbdh[j] = (drdh[j] + drdh[j + 1]) / 2;
860 vbar[j] = 1 / rhobar[j];
861 if fixedMassFlowSimplified then
862 wbar[j] = homotopy(infl.m_flow / Nt - sum(dMdt[1:j - 1]) - dMdt[j] / 2, wnom / Nt);
863 else
864 wbar[j] = infl.m_flow / Nt - sum(dMdt[1:j - 1]) - dMdt[j] / 2;
865 end if;
866 end for;
867 for j in 1:N loop
868 fluidState[j] = Medium.setState_ph(p, h[j]);
869 T[j] = Medium.temperature(fluidState[j]);
870 rho[j] = Medium.density(fluidState[j]);
871 drdp[j] = if Medium.singleState then 0 else Medium.density_derp_h(fluidState[j]);
872 drdh[j] = Medium.density_derh_p(fluidState[j]);
873 u[j] = w / (rho[j] * A);
874 end for;
875 win = infl.m_flow / Nt;
876 wout = -outfl.m_flow / Nt;
877 assert(HydraulicCapacitance == HCtypes.Upstream or HydraulicCapacitance == HCtypes.Middle or HydraulicCapacitance == HCtypes.Downstream, "Unsupported HydraulicCapacitance option");
878 if HydraulicCapacitance == HCtypes.Middle then
879 p = infl.p - Dpfric1 - Dpstat / 2;
880 w = win;
881 elseif HydraulicCapacitance == HCtypes.Upstream then
882 p = infl.p;
883 w = -outfl.m_flow / Nt;
884 else
885 p = outfl.p;
886 w = win;
887 end if;
888 infl.h_outflow = htilde[1];
889 outfl.h_outflow = htilde[N - 1];
890 h[1] = inStream(infl.h_outflow);
891 h[2:N] = htilde;
892 connect(wall, heatTransfer.wall);
893 Q = heatTransfer.Q "Total heat flow through lateral boundary";
894 M = sum(rhobar) * A * l "Fluid mass (single tube)";
895 Mtot = M * Nt "Fluid mass (total)";
896 Tr = noEvent(M / max(win, Modelica.Constants.eps)) "Residence time";
897 assert(w > (-wnom * wnm), "Reverse flow not allowed, maybe you connected the component with wrong orientation");
898 end Flow1DFV;
899
900 model Flow1DFV2ph "1-dimensional fluid flow model for water/steam (finite volumes, 2-phase)"
901 extends BaseClasses.Flow1DBase(redeclare replaceable package Medium = StandardWater constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium, FluidPhaseStart = Choices.FluidPhase.FluidPhases.TwoPhases);
902 replaceable model HeatTransfer = Thermal.HeatTransferFV.IdealHeatTransfer constrainedby ThermoPower.Thermal.BaseClasses.DistributedHeatTransferFV;
903 HeatTransfer heatTransfer(redeclare package Medium = Medium, final Nf = N, final Nw = Nw, final Nt = Nt, final L = L, final A = A, final Dhyd = Dhyd, final omega = omega, final wnom = wnom / Nt, final w = w * ones(N), final fluidState = fluidState) "Instantiated heat transfer model";
904 ThermoPower.Thermal.DHTVolumes wall(final N = Nw);
905 import ThermoPower.Choices.Flow1D.FFtypes;
906 import ThermoPower.Choices.Flow1D.HCtypes;
907 constant SI.Pressure pzero = 10 "Small deltap for calculations";
908 constant Medium.AbsolutePressure pc = Medium.fluidConstants[1].criticalPressure;
909 constant SI.SpecificEnthalpy hzero = 1e-3 "Small value for deltah";
910 parameter SI.PerUnit wnm = 1e-3 "Maximum fraction of the nominal flow rate allowed as reverse flow";
911 parameter Boolean fixedMassFlowSimplified = false "Fix flow rate = wnom for simplified homotopy model";
912 Medium.ThermodynamicState[N] fluidState "Thermodynamic state of the fluid at the nodes";
913 Medium.SaturationProperties sat "Properties of saturated fluid";
914 SI.Length omega_hyd "Wet perimeter (single tube)";
915 SI.Pressure Dpfric "Pressure drop due to friction";
916 SI.Pressure Dpstat "Pressure drop due to static head";
917 Real[N - 1] Kf "Friction coefficient";
918 Real[N - 1] Kfl "Linear friction coefficient";
919 Real[N - 1] Cf "Fanning friction factor";
920 Real dwdt "Dynamic momentum term";
921 Medium.AbsolutePressure p(start = pstart) "Fluid pressure for property calculations";
922 SI.Pressure[N - 1] dpf "Pressure drop due to friction between two nodes";
923 Medium.MassFlowRate w(start = wnom / Nt) "Mass flowrate (single tube)";
924 Medium.MassFlowRate[N - 1] wbar(each start = wnom / Nt) "Average mass flow rates (single tube)";
925 SI.Power[N - 1] Q_single = heatTransfer.Qvol / Nt "Heat flows entering the volumes from the lateral boundary (single tube)";
926 SI.Velocity[N] u "Fluid velocity";
927 Medium.Temperature[N] T "Fluid temperature";
928 Medium.Temperature Ts "Saturated water temperature";
929 Medium.SpecificEnthalpy[N] h(start = hstart) "Fluid specific enthalpy";
930 Medium.SpecificEnthalpy[N - 1] htilde(start = hstart[2:N]) "Enthalpy state variables";
931 Medium.SpecificEnthalpy hl "Saturated liquid temperature";
932 Medium.SpecificEnthalpy hv "Saturated vapour temperature";
933 SI.PerUnit[N] x "Steam quality";
934 Medium.Density[N] rho "Fluid density";
935 Units.LiquidDensity rhol "Saturated liquid density";
936 Units.GasDensity rhov "Saturated vapour density";
937 SI.Mass M "Fluid mass";
938 protected
939 SI.DerEnthalpyByPressure dhldp "Derivative of saturated liquid enthalpy by pressure";
940 SI.DerEnthalpyByPressure dhvdp "Derivative of saturated vapour enthalpy by pressure";
941 Medium.Density[N - 1] rhobar "Fluid average density";
942 SI.DerDensityByPressure[N] drdp "Derivative of density by pressure";
943 SI.DerDensityByPressure[N - 1] drbdp "Derivative of average density by pressure";
944 SI.DerDensityByPressure drldp "Derivative of saturated liquid density by pressure";
945 SI.DerDensityByPressure drvdp "Derivative of saturated vapour density by pressure";
946 SI.SpecificVolume[N - 1] vbar "Average specific volume";
947 SI.DerDensityByEnthalpy[N] drdh "Derivative of density by enthalpy";
948 SI.DerDensityByEnthalpy[N - 1] drbdh1 "Derivative of average density by left enthalpy";
949 SI.DerDensityByEnthalpy[N - 1] drbdh2 "Derivative of average density by right enthalpy";
950 Real AA;
951 Real AA1;
952 SI.MassFlowRate[N - 1] dMdt "Derivative of fluid mass in each volume";
953 initial equation
954 if initOpt == Choices.Init.Options.noInit then
955 elseif initOpt == Choices.Init.Options.fixedState then
956 if not noInitialPressure then
957 p = pstart;
958 end if;
959 htilde = hstart[2:N];
960 elseif initOpt == Choices.Init.Options.steadyState then
961 der(htilde) = zeros(N - 1);
962 if not Medium.singleState and not noInitialPressure then
963 der(p) = 0;
964 end if;
965 elseif initOpt == Choices.Init.Options.steadyStateNoP then
966 der(htilde) = zeros(N - 1);
967 assert(false, "initOpt = steadyStateNoP deprecated, use steadyState and noInitialPressure", AssertionLevel.warning);
968 elseif initOpt == Choices.Init.Options.steadyStateNoT and not Medium.singleState then
969 der(p) = 0;
970 else
971 assert(false, "Unsupported initialisation option");
972 end if;
973 equation
974 omega_hyd = 4 * A / Dhyd;
975 for j in 1:N - 1 loop
976 if FFtype == FFtypes.Kfnom then
977 Kf[j] = Kfnom * Kfc / (N - 1);
978 Cf[j] = 2 * Kf[j] * A ^ 3 / (omega_hyd * l);
979 elseif FFtype == FFtypes.OpPoint then
980 Kf[j] = dpnom * rhonom / (wnom / Nt) ^ 2 / (N - 1) * Kfc;
981 Cf[j] = 2 * Kf[j] * A ^ 3 / (omega_hyd * l);
982 elseif FFtype == FFtypes.Cfnom then
983 Kf[j] = Cfnom * omega_hyd * l / (2 * A ^ 3) * Kfc;
984 Cf[j] = 2 * Kf[j] * A ^ 3 / (omega_hyd * l);
985 elseif FFtype == FFtypes.Colebrook then
986 Cf[j] = if noEvent(htilde[j] < hl or htilde[j] > hv) then f_colebrook(w, Dhyd / A, e, Medium.dynamicViscosity(fluidState[j])) * Kfc else f_colebrook_2ph(w, Dhyd / A, e, Medium.dynamicViscosity(Medium.setBubbleState(sat, 1)), Medium.dynamicViscosity(Medium.setDewState(sat, 1)), x[j]) * Kfc;
987 Kf[j] = Cf[j] * omega_hyd * l / (2 * A ^ 3);
988 elseif FFtype == FFtypes.NoFriction then
989 Cf[j] = 0;
990 Kf[j] = 0;
991 else
992 assert(FFtype <> FFtypes.NoFriction, "Unsupported FFtype");
993 Cf[j] = 0;
994 Kf[j] = 0;
995 end if;
996 assert(Kf[j] >= 0, "Negative friction coefficient");
997 Kfl[j] = wnom / Nt * wnf * Kf[j];
998 end for;
999 if DynamicMomentum then
1000 dwdt = der(w);
1001 else
1002 dwdt = 0;
1003 end if;
1004 sum(dMdt) = infl.m_flow / Nt + outfl.m_flow / Nt "Mass balance";
1005 sum(dpf) = Dpfric "Total pressure drop due to friction";
1006 Dpstat = if abs(dzdx) < 1e-6 then 0 else g * l * dzdx * sum(rhobar) "Pressure drop due to static head";
1007 L / A * dwdt + outfl.p - infl.p + Dpstat + Dpfric = 0 "Momentum balance";
1008 for j in 1:N - 1 loop
1009 A * l * rhobar[j] * der(htilde[j]) + wbar[j] * (h[j + 1] - h[j]) - A * l * der(p) = Q_single[j] "Energy balance";
1010 dMdt[j] = A * l * (drbdh1[j] * der(h[j]) + drbdh2[j] * der(h[j + 1]) + drbdp[j] * der(p)) "Mass balance for each volume";
1011 vbar[j] = 1 / rhobar[j] "Average specific volume";
1012 if fixedMassFlowSimplified then
1013 wbar[j] = homotopy(infl.m_flow / Nt - sum(dMdt[1:j - 1]) - dMdt[j] / 2, wnom / Nt);
1014 else
1015 wbar[j] = infl.m_flow / Nt - sum(dMdt[1:j - 1]) - dMdt[j] / 2;
1016 end if;
1017 dpf[j] = if FFtype == FFtypes.NoFriction then 0 else homotopy(smooth(1, Kf[j] * squareReg(w, wnom / Nt * wnf)) * vbar[j], dpnom / (N - 1) / (wnom / Nt) * w);
1018 if avoidInletEnthalpyDerivative and j == 1 then
1019 rhobar[j] = rho[j + 1];
1020 drbdp[j] = drdp[j + 1];
1021 drbdh1[j] = 0;
1022 drbdh2[j] = drdh[j + 1];
1023 elseif noEvent(h[j] < hl and h[j + 1] < hl or h[j] > hv and h[j + 1] > hv or p >= pc - pzero or abs(h[j + 1] - h[j]) < hzero) then
1024 rhobar[j] = (rho[j] + rho[j + 1]) / 2;
1025 drbdp[j] = (drdp[j] + drdp[j + 1]) / 2;
1026 drbdh1[j] = drdh[j] / 2;
1027 drbdh2[j] = drdh[j + 1] / 2;
1028 elseif noEvent(h[j] >= hl and h[j] <= hv and h[j + 1] >= hl and h[j + 1] <= hv) then
1029 rhobar[j] = AA * log(rho[j] / rho[j + 1]) / (h[j + 1] - h[j]);
1030 drbdp[j] = (AA1 * log(rho[j] / rho[j + 1]) + AA * (1 / rho[j] * drdp[j] - 1 / rho[j + 1] * drdp[j + 1])) / (h[j + 1] - h[j]);
1031 drbdh1[j] = (rhobar[j] - rho[j]) / (h[j + 1] - h[j]);
1032 drbdh2[j] = (rho[j + 1] - rhobar[j]) / (h[j + 1] - h[j]);
1033 elseif noEvent(h[j] < hl and h[j + 1] >= hl and h[j + 1] <= hv) then
1034 rhobar[j] = ((rho[j] + rhol) * (hl - h[j]) / 2 + AA * log(rhol / rho[j + 1])) / (h[j + 1] - h[j]);
1035 drbdp[j] = ((drdp[j] + drldp) * (hl - h[j]) / 2 + (rho[j] + rhol) / 2 * dhldp + AA1 * log(rhol / rho[j + 1]) + AA * (1 / rhol * drldp - 1 / rho[j + 1] * drdp[j + 1])) / (h[j + 1] - h[j]);
1036 drbdh1[j] = (rhobar[j] - (rho[j] + rhol) / 2 + drdh[j] * (hl - h[j]) / 2) / (h[j + 1] - h[j]);
1037 drbdh2[j] = (rho[j + 1] - rhobar[j]) / (h[j + 1] - h[j]);
1038 elseif noEvent(h[j] >= hl and h[j] <= hv and h[j + 1] > hv) then
1039 rhobar[j] = (AA * log(rho[j] / rhov) + (rhov + rho[j + 1]) * (h[j + 1] - hv) / 2) / (h[j + 1] - h[j]);
1040 drbdp[j] = (AA1 * log(rho[j] / rhov) + AA * (1 / rho[j] * drdp[j] - 1 / rhov * drvdp) + (drvdp + drdp[j + 1]) * (h[j + 1] - hv) / 2 - (rhov + rho[j + 1]) / 2 * dhvdp) / (h[j + 1] - h[j]);
1041 drbdh1[j] = (rhobar[j] - rho[j]) / (h[j + 1] - h[j]);
1042 drbdh2[j] = ((rhov + rho[j + 1]) / 2 - rhobar[j] + drdh[j + 1] * (h[j + 1] - hv) / 2) / (h[j + 1] - h[j]);
1043 elseif noEvent(h[j] < hl and h[j + 1] > hv) then
1044 rhobar[j] = ((rho[j] + rhol) * (hl - h[j]) / 2 + AA * log(rhol / rhov) + (rhov + rho[j + 1]) * (h[j + 1] - hv) / 2) / (h[j + 1] - h[j]);
1045 drbdp[j] = ((drdp[j] + drldp) * (hl - h[j]) / 2 + (rho[j] + rhol) / 2 * dhldp + AA1 * log(rhol / rhov) + AA * (1 / rhol * drldp - 1 / rhov * drvdp) + (drvdp + drdp[j + 1]) * (h[j + 1] - hv) / 2 - (rhov + rho[j + 1]) / 2 * dhvdp) / (h[j + 1] - h[j]);
1046 drbdh1[j] = (rhobar[j] - (rho[j] + rhol) / 2 + drdh[j] * (hl - h[j]) / 2) / (h[j + 1] - h[j]);
1047 drbdh2[j] = ((rhov + rho[j + 1]) / 2 - rhobar[j] + drdh[j + 1] * (h[j + 1] - hv) / 2) / (h[j + 1] - h[j]);
1048 elseif noEvent(h[j] >= hl and h[j] <= hv and h[j + 1] < hl) then
1049 rhobar[j] = (AA * log(rho[j] / rhol) + (rhol + rho[j + 1]) * (h[j + 1] - hl) / 2) / (h[j + 1] - h[j]);
1050 drbdp[j] = (AA1 * log(rho[j] / rhol) + AA * (1 / rho[j] * drdp[j] - 1 / rhol * drldp) + (drldp + drdp[j + 1]) * (h[j + 1] - hl) / 2 - (rhol + rho[j + 1]) / 2 * dhldp) / (h[j + 1] - h[j]);
1051 drbdh1[j] = (rhobar[j] - rho[j]) / (h[j + 1] - h[j]);
1052 drbdh2[j] = ((rhol + rho[j + 1]) / 2 - rhobar[j] + drdh[j + 1] * (h[j + 1] - hl) / 2) / (h[j + 1] - h[j]);
1053 elseif noEvent(h[j] > hv and h[j + 1] < hl) then
1054 rhobar[j] = ((rho[j] + rhov) * (hv - h[j]) / 2 + AA * log(rhov / rhol) + (rhol + rho[j + 1]) * (h[j + 1] - hl) / 2) / (h[j + 1] - h[j]);
1055 drbdp[j] = ((drdp[j] + drvdp) * (hv - h[j]) / 2 + (rho[j] + rhov) / 2 * dhvdp + AA1 * log(rhov / rhol) + AA * (1 / rhov * drvdp - 1 / rhol * drldp) + (drldp + drdp[j + 1]) * (h[j + 1] - hl) / 2 - (rhol + rho[j + 1]) / 2 * dhldp) / (h[j + 1] - h[j]);
1056 drbdh1[j] = (rhobar[j] - (rho[j] + rhov) / 2 + drdh[j] * (hv - h[j]) / 2) / (h[j + 1] - h[j]);
1057 drbdh2[j] = ((rhol + rho[j + 1]) / 2 - rhobar[j] + drdh[j + 1] * (h[j + 1] - hl) / 2) / (h[j + 1] - h[j]);
1058 else
1059 rhobar[j] = ((rho[j] + rhov) * (hv - h[j]) / 2 + AA * log(rhov / rho[j + 1])) / (h[j + 1] - h[j]);
1060 drbdp[j] = ((drdp[j] + drvdp) * (hv - h[j]) / 2 + (rho[j] + rhov) / 2 * dhvdp + AA1 * log(rhov / rho[j + 1]) + AA * (1 / rhov * drvdp - 1 / rho[j + 1] * drdp[j + 1])) / (h[j + 1] - h[j]);
1061 drbdh1[j] = (rhobar[j] - (rho[j] + rhov) / 2 + drdh[j] * (hv - h[j]) / 2) / (h[j + 1] - h[j]);
1062 drbdh2[j] = (rho[j + 1] - rhobar[j]) / (h[j + 1] - h[j]);
1063 end if;
1064 end for;
1065 sat = Medium.setSat_p(p);
1066 Ts = sat.Tsat;
1067 rhol = Medium.bubbleDensity(sat);
1068 rhov = Medium.dewDensity(sat);
1069 hl = Medium.bubbleEnthalpy(sat);
1070 hv = Medium.dewEnthalpy(sat);
1071 drldp = Medium.dBubbleDensity_dPressure(sat);
1072 drvdp = Medium.dDewDensity_dPressure(sat);
1073 dhldp = Medium.dBubbleEnthalpy_dPressure(sat);
1074 dhvdp = Medium.dDewEnthalpy_dPressure(sat);
1075 AA = (hv - hl) / (1 / rhov - 1 / rhol);
1076 AA1 = ((dhvdp - dhldp) * (rhol - rhov) * rhol * rhov - (hv - hl) * (rhov ^ 2 * drldp - rhol ^ 2 * drvdp)) / (rhol - rhov) ^ 2;
1077 for j in 1:N loop
1078 fluidState[j] = Medium.setState_ph(p, h[j]);
1079 T[j] = Medium.temperature(fluidState[j]);
1080 rho[j] = Medium.density(fluidState[j]);
1081 drdp[j] = Medium.density_derp_h(fluidState[j]);
1082 drdh[j] = Medium.density_derh_p(fluidState[j]);
1083 u[j] = w / (rho[j] * A);
1084 x[j] = noEvent(if h[j] <= hl then 0 else if h[j] >= hv then 1 else (h[j] - hl) / (hv - hl));
1085 end for;
1086 if HydraulicCapacitance == HCtypes.Upstream then
1087 p = infl.p;
1088 w = -outfl.m_flow / Nt;
1089 else
1090 p = outfl.p;
1091 w = infl.m_flow / Nt;
1092 end if;
1093 infl.h_outflow = htilde[1];
1094 outfl.h_outflow = htilde[N - 1];
1095 h[1] = inStream(infl.h_outflow);
1096 h[2:N] = htilde;
1097 connect(wall, heatTransfer.wall);
1098 Q = heatTransfer.Q "Total heat flow through lateral boundary";
1099 M = sum(rhobar) * A * l "Fluid mass (single tube)";
1100 Tr = noEvent(M / max(infl.m_flow / Nt, Modelica.Constants.eps)) "Residence time";
1101 assert(infl.m_flow > (-wnom * wnm), "Reverse flow not allowed, maybe you connected the component with wrong orientation");
1102 end Flow1DFV2ph;
1103
1104 model SensT "Temperature sensor for water-steam"
1105 extends Icons.Water.SensThrough;
1106 replaceable package Medium = StandardWater constrainedby Modelica.Media.Interfaces.PartialMedium;
1107 parameter Boolean allowFlowReversal = system.allowFlowReversal "= true to allow flow reversal, false restricts to design direction" annotation(Evaluate = true);
1108 outer ThermoPower.System system "System wide properties";
1109 Medium.SpecificEnthalpy h "Specific enthalpy of the fluid";
1110 Medium.ThermodynamicState fluidState "Thermodynamic state of the fluid";
1111 FlangeA inlet(redeclare package Medium = Medium, m_flow(min = if allowFlowReversal then -Modelica.Constants.inf else 0));
1112 FlangeB outlet(redeclare package Medium = Medium, m_flow(max = if allowFlowReversal then +Modelica.Constants.inf else 0));
1113 Modelica.Blocks.Interfaces.RealOutput T;
1114 equation
1115 inlet.m_flow + outlet.m_flow = 0 "Mass balance";
1116 inlet.p = outlet.p "No pressure drop";
1117 h = homotopy(if not allowFlowReversal then inStream(inlet.h_outflow) else actualStream(inlet.h_outflow), inStream(inlet.h_outflow));
1118 fluidState = Medium.setState_ph(inlet.p, h);
1119 T = Medium.temperature(fluidState);
1120 inlet.h_outflow = inStream(outlet.h_outflow);
1121 inStream(inlet.h_outflow) = outlet.h_outflow;
1122 end SensT;
1123
1124 model SensW "Mass Flowrate sensor for water/steam"
1125 extends Icons.Water.SensThrough;
1126 replaceable package Medium = StandardWater constrainedby Modelica.Media.Interfaces.PartialMedium;
1127 parameter Boolean allowFlowReversal = system.allowFlowReversal "= true to allow flow reversal, false restricts to design direction" annotation(Evaluate = true);
1128 outer ThermoPower.System system "System wide properties";
1129 FlangeA inlet(redeclare package Medium = Medium, m_flow(min = if allowFlowReversal then -Modelica.Constants.inf else 0));
1130 FlangeB outlet(redeclare package Medium = Medium, m_flow(max = if allowFlowReversal then +Modelica.Constants.inf else 0));
1131 Modelica.Blocks.Interfaces.RealOutput w;
1132 equation
1133 inlet.m_flow + outlet.m_flow = 0 "Mass balance";
1134 inlet.p = outlet.p;
1135 inlet.h_outflow = inStream(outlet.h_outflow);
1136 inStream(inlet.h_outflow) = outlet.h_outflow;
1137 w = inlet.m_flow;
1138 end SensW;
1139
1140 model ValveLiq "Valve for liquid water flow"
1141 extends BaseClasses.ValveBase;
1142 import ThermoPower.Choices.Valve.CvTypes;
1143 initial equation
1144 if CvData == CvTypes.OpPoint then
1145 wnom = FlowChar(thetanom) * Av * sqrt(rhonom) * sqrtR(dpnom) "Determination of Av by the operating point";
1146 end if;
1147 equation
1148 if CheckValve then
1149 w = homotopy(FlowChar(theta_act) * Av * sqrt(rho) * smooth(0, if dp >= 0 then sqrtR(dp) else 0), theta_act / thetanom * wnom / dpnom * (inlet.p - outlet.p));
1150 else
1151 w = homotopy(FlowChar(theta_act) * Av * sqrt(rho) * sqrtR(dp), theta_act / thetanom * wnom / dpnom * (inlet.p - outlet.p));
1152 end if;
1153 end ValveLiq;
1154
1155 function f_colebrook "Fanning friction factor for water/steam flows"
1156 input SI.MassFlowRate w;
1157 input Real D_A;
1158 input Real e;
1159 input SI.DynamicViscosity mu;
1160 output SI.PerUnit f;
1161 protected
1162 SI.PerUnit Re;
1163 algorithm
1164 Re := abs(w) * D_A / mu;
1165 Re := if Re > 2100 then Re else 2100;
1166 f := 0.332 / log(e / 3.7 + 5.47 / Re ^ 0.9) ^ 2;
1167 end f_colebrook;
1168
1169 function f_colebrook_2ph "Fanning friction factor for a two phase water/steam flow"
1170 input SI.MassFlowRate w;
1171 input Real D_A;
1172 input Real e;
1173 input SI.DynamicViscosity mul;
1174 input SI.DynamicViscosity muv;
1175 input SI.PerUnit x;
1176 output SI.PerUnit f;
1177 protected
1178 SI.PerUnit Re;
1179 SI.DynamicViscosity mu;
1180 algorithm
1181 mu := 1 / (x / muv + (1 - x) / mul);
1182 Re := w * D_A / mu;
1183 Re := if Re > 2100 then Re else 2100;
1184 f := 0.332 / log(e / 3.7 + 5.47 / Re ^ 0.9) ^ 2;
1185 end f_colebrook_2ph;
1186
1187 package BaseClasses "Contains partial models"
1188 extends Modelica.Icons.BasesPackage;
1189
1190 partial model Flow1DBase "Basic interface for 1-dimensional water/steam fluid flow models"
1191 import ThermoPower.Choices.Flow1D.FFtypes;
1192 replaceable package Medium = StandardWater constrainedby Modelica.Media.Interfaces.PartialMedium;
1193 extends Icons.Water.Tube;
1194 constant Real pi = Modelica.Constants.pi;
1195 parameter Integer N(min = 2) = 2 "Number of nodes for thermal variables";
1196 parameter Integer Nw = N - 1 "Number of volumes on the wall interface";
1197 parameter Integer Nt = 1 "Number of tubes in parallel";
1198 parameter SI.Distance L "Tube length" annotation(Evaluate = true);
1199 parameter SI.Position H = 0 "Elevation of outlet over inlet";
1200 parameter SI.Area A "Cross-sectional area (single tube)";
1201 parameter SI.Length omega "Perimeter of heat transfer surface (single tube)";
1202 parameter SI.Length Dhyd = omega / pi "Hydraulic Diameter (single tube)";
1203 parameter Medium.MassFlowRate wnom "Nominal mass flowrate (total)";
1204 parameter ThermoPower.Choices.Flow1D.FFtypes FFtype = ThermoPower.Choices.Flow1D.FFtypes.NoFriction "Friction Factor Type" annotation(Evaluate = true);
1205 parameter SI.PressureDifference dpnom = 0 "Nominal pressure drop (friction term only!)";
1206 parameter Real Kfnom = 0 "Nominal hydraulic resistance coefficient (DP = Kfnom*w^2/rho)";
1207 parameter Medium.Density rhonom = 0 "Nominal inlet density";
1208 parameter SI.PerUnit Cfnom = 0 "Nominal Fanning friction factor";
1209 parameter SI.PerUnit e = 0 "Relative roughness (ratio roughness/diameter)";
1210 parameter SI.PerUnit Kfc = 1 "Friction factor correction coefficient";
1211 parameter Boolean DynamicMomentum = false "Inertial phenomena accounted for" annotation(Evaluate = true);
1212 parameter ThermoPower.Choices.Flow1D.HCtypes HydraulicCapacitance = ThermoPower.Choices.Flow1D.HCtypes.Downstream "Location of the hydraulic capacitance";
1213 parameter Boolean avoidInletEnthalpyDerivative = true "Avoid inlet enthalpy derivative";
1214 parameter Boolean allowFlowReversal = system.allowFlowReversal "= true to allow flow reversal, false restricts to design direction" annotation(Evaluate = true);
1215 outer ThermoPower.System system "System wide properties";
1216 parameter Choices.FluidPhase.FluidPhases FluidPhaseStart = Choices.FluidPhase.FluidPhases.Liquid "Fluid phase (only for initialization!)";
1217 parameter Medium.AbsolutePressure pstart = 1e5 "Pressure start value";
1218 parameter Medium.SpecificEnthalpy hstartin = if FluidPhaseStart == Choices.FluidPhase.FluidPhases.Liquid then 1e5 else if FluidPhaseStart == Choices.FluidPhase.FluidPhases.Steam then 3e6 else 1e6 "Inlet enthalpy start value";
1219 parameter Medium.SpecificEnthalpy hstartout = if FluidPhaseStart == Choices.FluidPhase.FluidPhases.Liquid then 1e5 else if FluidPhaseStart == Choices.FluidPhase.FluidPhases.Steam then 3e6 else 1e6 "Outlet enthalpy start value";
1220 parameter Medium.SpecificEnthalpy[N] hstart = linspace(hstartin, hstartout, N) "Start value of enthalpy vector (initialized by default)";
1221 parameter SI.PerUnit wnf = 0.02 "Fraction of nominal flow rate at which linear friction equals turbulent friction";
1222 parameter Choices.Init.Options initOpt = system.initOpt "Initialisation option";
1223 parameter Boolean noInitialPressure = false "Remove initial equation on pressure";
1224 constant SI.Acceleration g = Modelica.Constants.g_n;
1225 function squareReg = ThermoPower.Functions.squareReg;
1226 FlangeA infl(h_outflow(start = hstartin), redeclare package Medium = Medium, m_flow(start = wnom, min = if allowFlowReversal then -Modelica.Constants.inf else 0));
1227 FlangeB outfl(h_outflow(start = hstartout), redeclare package Medium = Medium, m_flow(start = -wnom, max = if allowFlowReversal then +Modelica.Constants.inf else 0));
1228 SI.Power Q "Total heat flow through the lateral boundary (all Nt tubes)";
1229 SI.Time Tr "Residence time";
1230 final parameter SI.PerUnit dzdx = H / L "Slope" annotation(Evaluate = true);
1231 final parameter SI.Length l = L / (N - 1) "Length of a single volume";
1232 final parameter SI.Volume V = Nt * A * L "Total volume (all Nt tubes)";
1233 initial equation
1234 assert(wnom > 0, "Please set a positive value for wnom");
1235 assert(FFtype == FFtypes.NoFriction or dpnom > 0, "dpnom=0 not valid, it is also used in the homotopy trasformation during the inizialization");
1236 assert(not (FFtype == FFtypes.Kfnom and not Kfnom > 0), "Kfnom = 0 not valid, please set a positive value");
1237 assert(not (FFtype == FFtypes.OpPoint and not rhonom > 0), "rhonom = 0 not valid, please set a positive value");
1238 assert(not (FFtype == FFtypes.Cfnom and not Cfnom > 0), "Cfnom = 0 not valid, please set a positive value");
1239 assert(not (FFtype == FFtypes.Colebrook and not Dhyd > 0), "Dhyd = 0 not valid, please set a positive value");
1240 assert(not (FFtype == FFtypes.Colebrook and not e > 0), "e = 0 not valid, please set a positive value");
1241 annotation(Evaluate = true);
1242 end Flow1DBase;
1243
1244 partial model ValveBase "Base model for valves"
1245 extends Icons.Water.Valve;
1246 replaceable package Medium = StandardWater constrainedby Modelica.Media.Interfaces.PartialMedium;
1247 Medium.ThermodynamicState fluidState;
1248 parameter ThermoPower.Choices.Valve.CvTypes CvData = ThermoPower.Choices.Valve.CvTypes.Av "Selection of flow coefficient" annotation(Evaluate = true);
1249 final parameter Boolean fixedAv = if CvData == ThermoPower.Choices.Valve.CvTypes.Av then true else false annotation(Evaluate = true);
1250 parameter SI.Area Av(fixed = fixedAv, start = wnom / (sqrt(rhonom * dpnom) * FlowChar(thetanom))) "Av (metric) flow coefficient";
1251 parameter Real Kv(unit = "m3/h") = 0 "Kv (metric) flow coefficient";
1252 parameter Real Cv = 0 "Cv (US) flow coefficient [USG/min]";
1253 parameter Boolean useThetaInput = true "Use the input connector for the valve opening";
1254 parameter SI.PerUnit theta_fix = 1 "Fixed opening value when the input connector not used";
1255 parameter Medium.AbsolutePressure pnom "Nominal inlet pressure";
1256 parameter SI.PressureDifference dpnom "Nominal pressure drop";
1257 parameter Medium.MassFlowRate wnom "Nominal mass flowrate";
1258 parameter Medium.Density rhonom = 1000 "Nominal density";
1259 parameter SI.PerUnit thetanom = 1 "Nominal valve opening";
1260 parameter SI.Power Qnom = 0 "Nominal heat loss to ambient" annotation(Evaluate = true);
1261 parameter Boolean CheckValve = false "Reverse flow stopped";
1262 parameter Real b = 0.01 "Regularisation factor";
1263 replaceable function FlowChar = ThermoPower.Functions.ValveCharacteristics.linear constrainedby ThermoPower.Functions.ValveCharacteristics.baseFun;
1264 parameter Boolean allowFlowReversal = system.allowFlowReversal "= true to allow flow reversal, false restricts to design direction" annotation(Evaluate = true);
1265 outer ThermoPower.System system "System wide properties";
1266 parameter Medium.AbsolutePressure pin_start = pnom "Inlet pressure start value";
1267 parameter Medium.AbsolutePressure pout_start = pnom - dpnom "Inlet pressure start value";
1268 Medium.MassFlowRate w "Mass flow rate";
1269 Units.LiquidDensity rho "Inlet density";
1270 Medium.Temperature Tin;
1271 SI.PressureDifference dp "Pressure drop across the valve";
1272 SI.PerUnit theta_act "Actual valve opening";
1273 protected
1274 function sqrtR = Functions.sqrtReg(delta = b * dpnom);
1275 public
1276 FlangeA inlet(m_flow(start = wnom, min = if allowFlowReversal then -Modelica.Constants.inf else 0), p(start = pin_start), redeclare package Medium = Medium);
1277 FlangeB outlet(m_flow(start = -wnom, max = if allowFlowReversal then +Modelica.Constants.inf else 0), p(start = pout_start), redeclare package Medium = Medium);
1278 Modelica.Blocks.Interfaces.RealInput theta if useThetaInput "Valve opening in per unit";
1279 protected
1280 Modelica.Blocks.Interfaces.RealInput theta_int "Protected connector for conditional input connector handling";
1281 initial equation
1282 if CvData == ThermoPower.Choices.Valve.CvTypes.Kv then
1283 Av = 2.7778e-5 * Kv;
1284 elseif CvData == ThermoPower.Choices.Valve.CvTypes.Cv then
1285 Av = 2.4027e-5 * Cv;
1286 end if;
1287 equation
1288 inlet.m_flow + outlet.m_flow = 0 "Mass balance";
1289 w = inlet.m_flow;
1290 fluidState = Medium.setState_ph(inlet.p, inStream(inlet.h_outflow));
1291 Tin = Medium.temperature(fluidState);
1292 rho = Medium.density(fluidState);
1293 outlet.h_outflow = inStream(inlet.h_outflow) - Qnom / wnom;
1294 inlet.h_outflow = inStream(outlet.h_outflow) - Qnom / wnom;
1295 dp = inlet.p - outlet.p "Definition of dp";
1296 connect(theta, theta_int);
1297 if not useThetaInput then
1298 theta_int = theta_fix;
1299 end if;
1300 theta_act = theta_int;
1301 end ValveBase;
1302 end BaseClasses;
1303 end Water;
1304
1305 package Thermal "Thermal models of heat transfer"
1306 extends Modelica.Icons.Package;
1307
1308 connector DHTVolumes "Distributed Heat Terminal"
1309 parameter Integer N "Number of volumes";
1310 SI.Temperature[N] T "Temperature at the volumes";
1311 flow SI.Power[N] Q "Heat flow at the volumes";
1312 end DHTVolumes;
1313
1314 model MetalTubeFV "Cylindrical metal tube model with Nw finite volumes"
1315 extends Icons.MetalWall;
1316 parameter Integer Nw = 1 "Number of volumes on the wall ports";
1317 parameter Integer Nt = 1 "Number of tubes in parallel";
1318 parameter SI.Length L "Tube length";
1319 parameter SI.Length rint "Internal radius (single tube)";
1320 parameter SI.Length rext "External radius (single tube)";
1321 parameter Real rhomcm "Metal heat capacity per unit volume [J/m^3.K]";
1322 parameter SI.ThermalConductivity lambda "Thermal conductivity";
1323 parameter Boolean WallRes = true "Wall thermal resistance accounted for";
1324 parameter SI.Temperature Tstartbar = 300 "Avarage temperature";
1325 parameter SI.Temperature Tstart1 = Tstartbar "Temperature start value - first volume";
1326 parameter SI.Temperature TstartN = Tstartbar "Temperature start value - last volume";
1327 parameter SI.Temperature[Nw] Tvolstart = Functions.linspaceExt(Tstart1, TstartN, Nw);
1328 parameter Choices.Init.Options initOpt = system.initOpt "Initialisation option";
1329 constant Real pi = Modelica.Constants.pi;
1330 final parameter SI.Area Am = (rext ^ 2 - rint ^ 2) * pi "Area of the metal tube cross-section";
1331 final parameter SI.HeatCapacity Cm = Nt * L * Am * rhomcm "Total heat capacity";
1332 outer ThermoPower.System system "System wide properties";
1333 SI.Temperature[Nw] Tvol(start = Tvolstart) "Volume temperatures";
1334 ThermoPower.Thermal.DHTVolumes int(final N = Nw, T(start = Tvolstart)) "Internal surface";
1335 ThermoPower.Thermal.DHTVolumes ext(final N = Nw, T(start = Tvolstart)) "External surface";
1336 initial equation
1337 if initOpt == Choices.Init.Options.noInit then
1338 elseif initOpt == Choices.Init.Options.fixedState then
1339 Tvol = Tvolstart;
1340 elseif initOpt == Choices.Init.Options.steadyState then
1341 der(Tvol) = zeros(Nw);
1342 elseif initOpt == Choices.Init.Options.steadyStateNoT then
1343 else
1344 assert(false, "Unsupported initialisation option");
1345 end if;
1346 equation
1347 assert(rext > rint, "External radius must be greater than internal radius");
1348 L / Nw * Nt * rhomcm * Am * der(Tvol) = int.Q + ext.Q "Energy balance";
1349 if WallRes then
1350 int.Q = lambda * (2 * pi * L / Nw) * (int.T - Tvol) / log((rint + rext) / (2 * rint)) * Nt "Heat conduction through the internal half-thickness";
1351 ext.Q = lambda * (2 * pi * L / Nw) * (ext.T - Tvol) / log(2 * rext / (rint + rext)) * Nt "Heat conduction through the external half-thickness";
1352 else
1353 ext.T = Tvol;
1354 int.T = Tvol;
1355 end if;
1356 end MetalTubeFV;
1357
1358 model HeatExchangerTopologyFV "Connects two DHTVolumes ports according to a selected heat exchanger topology"
1359 extends Icons.HeatFlow;
1360 parameter Integer Nw "Number of volumes";
1361 replaceable model HeatExchangerTopology = HeatExchangerTopologies.CoCurrentFlow constrainedby ThermoPower.Thermal.BaseClasses.HeatExchangerTopologyData;
1362 HeatExchangerTopology HET(final Nw = Nw);
1363 Thermal.DHTVolumes side1(final N = Nw);
1364 Thermal.DHTVolumes side2(final N = Nw);
1365 equation
1366 for j in 1:Nw loop
1367 side2.T[HET.correspondingVolumes[j]] = side1.T[j];
1368 side2.Q[HET.correspondingVolumes[j]] + side1.Q[j] = 0;
1369 end for;
1370 end HeatExchangerTopologyFV;
1371
1372 model ConvHTFV "1D Constant thermal conductance"
1373 extends Icons.HeatFlow;
1374 parameter Integer Nv = 2 "Number of finite volumes";
1375 parameter SI.ThermalConductance G "Overall thermal conductance";
1376 DHTVolumes side1(final N = Nv);
1377 DHTVolumes side2(final N = Nv);
1378 equation
1379 side1.Q = G * (side1.T - side2.T) / Nv "Convective heat transfer";
1380 side1.Q + side2.Q = zeros(Nv) "Static energy balance";
1381 end ConvHTFV;
1382
1383 model FoulingFV "1D FV thermal resistance due to fouling"
1384 extends ConvHTFV(final G = A / R);
1385 parameter Units.SpecificThermalResistance R "Fouling factor";
1386 parameter SI.Area A "Total surface";
1387 end FoulingFV;
1388
1389 package HeatTransferFV "Heat transfer models for FV components"
1390 model IdealHeatTransfer "Delta T across the boundary layer is zero (infinite h.t.c.)"
1391 extends BaseClasses.DistributedHeatTransferFV(final useAverageTemperature = false);
1392 equation
1393 assert(Nw == Nf - 1, "Number of volumes Nw on wall side should be equal to number of volumes fluid side Nf - 1");
1394 for j in 1:Nw loop
1395 wall.T[j] = T[j + 1] "Ideal infinite heat transfer";
1396 end for;
1397 end IdealHeatTransfer;
1398
1399 model FlowDependentHeatTransferCoefficient "Flow-dependent h.t.c. gamma = gamma_nom*(w/wnom)^alpha"
1400 extends BaseClasses.DistributedHeatTransferFV;
1401 parameter SI.CoefficientOfHeatTransfer gamma_nom "Nominal heat transfer coefficient";
1402 parameter SI.PerUnit alpha "Exponent in the flow-dependency law";
1403 parameter SI.PerUnit beta = 0.1 "Fraction of nominal flow rate below which the heat transfer is not reduced";
1404 parameter SI.MassFlowRate wnom_ht = wnom "Nominal flow rate for heat transfer correlation (single tube)";
1405 parameter Boolean adaptiveAverageTemperature = true "Adapt the average temperature at low flow rates";
1406 parameter Modelica.SIunits.PerUnit sigma = 0.1 "Fraction of nominal flow rate below which the heat transfer is computed on outlet volume temperatures";
1407 Medium.Temperature[Nw] Tvol "Fluid temperature in the volumes";
1408 SI.CoefficientOfHeatTransfer gamma(start = gamma_nom) "Actual heat transfer coefficient";
1409 SI.PerUnit w_wnom(start = 1, final unit = "1") "Ratio between actual and nominal flow rate";
1410 SI.PerUnit w_wnom_reg "Regularized ratio between actual and nominal flow rate";
1411 equation
1412 assert(Nw == Nf - 1, "Number of volumes Nw on wall side should be equal to number of volumes fluid side Nf - 1");
1413 w_wnom = abs(w[1]) / wnom_ht;
1414 w_wnom_reg = Functions.smoothSat(w_wnom, beta, 1e9, beta / 2);
1415 gamma = homotopy(gamma_nom * w_wnom_reg ^ alpha, gamma_nom);
1416 for j in 1:Nw loop
1417 Tvol[j] = if not useAverageTemperature then T[j + 1] else if not adaptiveAverageTemperature then (T[j] + T[j + 1]) / 2 else (T[j] + T[j + 1]) / 2 + (T[j + 1] - T[j]) / 2 * exp(-w_wnom / sigma);
1418 Qw[j] = (Tw[j] - Tvol[j]) * gamma * omega * l * Nt;
1419 end for;
1420 end FlowDependentHeatTransferCoefficient;
1421 end HeatTransferFV;
1422
1423 package HeatExchangerTopologies
1424 model CoCurrentFlow "Co-current flow"
1425 extends BaseClasses.HeatExchangerTopologyData(final correspondingVolumes = 1:Nw);
1426 end CoCurrentFlow;
1427
1428 model CounterCurrentFlow "Counter-current flow"
1429 extends BaseClasses.HeatExchangerTopologyData(final correspondingVolumes = Nw:(-1):1);
1430 end CounterCurrentFlow;
1431 end HeatExchangerTopologies;
1432
1433 package BaseClasses
1434 partial model DistributedHeatTransferFV "Base class for distributed heat transfer models - finite volumes"
1435 extends ThermoPower.Icons.HeatFlow;
1436 input Medium.ThermodynamicState[Nf] fluidState;
1437 input Medium.MassFlowRate[Nf] w;
1438 parameter Boolean useAverageTemperature = true "= true to use average temperature for heat transfer";
1439 ThermoPower.Thermal.DHTVolumes wall(final N = Nw);
1440 replaceable package Medium = Modelica.Media.Interfaces.PartialMedium "Medium model";
1441 parameter Integer Nf(min = 2) = 2 "Number of nodes on the fluid side";
1442 parameter Integer Nw = Nf - 1 "Number of volumes on the wall side";
1443 parameter Integer Nt(min = 1) "Number of tubes in parallel";
1444 parameter SI.Distance L "Tube length";
1445 parameter SI.Area A "Cross-sectional area (single tube)";
1446 parameter SI.Length omega "Wet perimeter of heat transfer surface (single tube)";
1447 parameter SI.Length Dhyd "Hydraulic Diameter (single tube)";
1448 parameter SI.MassFlowRate wnom "Nominal mass flow rate (single tube)";
1449 final parameter SI.Length l = L / Nw "Length of a single volume";
1450 Medium.Temperature[Nf] T "Temperatures at the fluid side nodes";
1451 Medium.Temperature[Nw] Tw "Temperatures of the wall volumes";
1452 SI.Power[Nw] Qw "Heat flows entering from the wall volumes";
1453 SI.Power[Nf - 1] Qvol = Qw "Heat flows going to the fluid volumes";
1454 SI.Power Q "Total heat flow through lateral boundary";
1455 equation
1456 for j in 1:Nf loop
1457 T[j] = Medium.temperature(fluidState[j]);
1458 end for;
1459 Tw = wall.T;
1460 Qw = wall.Q;
1461 Q = sum(wall.Q);
1462 end DistributedHeatTransferFV;
1463
1464 partial model HeatExchangerTopologyData "Base class for heat exchanger topology data"
1465 parameter Integer Nw "Number of volumes on both sides";
1466 parameter Integer[Nw] correspondingVolumes "Indeces of corresponding volumes";
1467 end HeatExchangerTopologyData;
1468 end BaseClasses;
1469 end Thermal;
1470
1471 package Icons "Icons for ThermoPower library"
1472 extends Modelica.Icons.IconsPackage;
1473
1474 package Water "Icons for component using water/steam as working fluid"
1475 extends Modelica.Icons.Package;
1476
1477 partial model SourceP end SourceP;
1478
1479 partial model SourceW end SourceW;
1480
1481 partial model Tube end Tube;
1482
1483 partial model Valve end Valve;
1484
1485 model SensThrough end SensThrough;
1486 end Water;
1487
1488 partial model HeatFlow end HeatFlow;
1489
1490 partial model MetalWall end MetalWall;
1491 end Icons;
1492
1493 package Choices "Choice enumerations for ThermoPower models"
1494 extends Modelica.Icons.TypesPackage;
1495
1496 package Flow1D
1497 type FFtypes = enumeration(Kfnom "Kfnom friction factor", OpPoint "Friction factor defined by operating point", Cfnom "Cfnom friction factor", Colebrook "Colebrook's equation", NoFriction "No friction") "Type, constants and menu choices to select the friction factor";
1498 type HCtypes = enumeration(Middle "Middle of the pipe", Upstream "At the inlet", Downstream "At the outlet") "Type, constants and menu choices to select the location of the hydraulic capacitance";
1499 end Flow1D;
1500
1501 package Valve
1502 type CvTypes = enumeration(Av "Av (metric) flow coefficient", Kv "Kv (metric) flow coefficient", Cv "Cv (US) flow coefficient", OpPoint "Av defined by nominal operating point") "Type, constants and menu choices to select the type of Cv data";
1503 end Valve;
1504
1505 package Init "Options for initialisation"
1506 type Options = enumeration(noInit "No initial equations", fixedState "Fixed initial state variables", steadyState "Steady-state initialization", steadyStateNoP "Steady-state initialization except pressures (deprecated)", steadyStateNoT "Steady-state initialization except temperatures (deprecated)", steadyStateNoPT "Steady-state initialization except pressures and temperatures (deprecated)") "Type, constants and menu choices to select the initialisation options";
1507 end Init;
1508
1509 package FluidPhase
1510 type FluidPhases = enumeration(Liquid "Liquid", Steam "Steam", TwoPhases "Two Phases") "Type, constants and menu choices to select the fluid phase";
1511 end FluidPhase;
1512 end Choices;
1513
1514 package Functions "Miscellaneous functions"
1515 extends Modelica.Icons.Package;
1516
1517 function sqrtReg "Symmetric square root approximation with finite derivative in zero"
1518 extends Modelica.Icons.Function;
1519 input Real x;
1520 input Real delta = 0.01 "Range of significant deviation from sqrt(x)";
1521 output Real y;
1522 algorithm
1523 y := x / sqrt(sqrt(x * x + delta * delta));
1524 annotation(derivative(zeroDerivative = delta) = ThermoPower.Functions.sqrtReg_der);
1525 end sqrtReg;
1526
1527 function sqrtReg_der "Derivative of sqrtReg"
1528 extends Modelica.Icons.Function;
1529 input Real x;
1530 input Real delta = 0.01 "Range of significant deviation from sqrt(x)";
1531 input Real dx "Derivative of x";
1532 output Real dy;
1533 algorithm
1534 dy := dx * 0.5 * (x * x + 2 * delta * delta) / (x * x + delta * delta) ^ 1.25;
1535 end sqrtReg_der;
1536
1537 function squareReg "Anti-symmetric square approximation with non-zero derivative in the origin"
1538 extends Modelica.Icons.Function;
1539 input Real x;
1540 input Real delta = 0.01 "Range of significant deviation from x^2*sgn(x)";
1541 output Real y;
1542 algorithm
1543 y := x * sqrt(x * x + delta * delta);
1544 end squareReg;
1545
1546 function smoothSat "Smooth saturation function"
1547 input Real x;
1548 input Real xmin "Lower bound of range where y = x";
1549 input Real xmax "Upper bound of range where y = x";
1550 input Real dxmin "Width of lower smoothing range";
1551 input Real dxmax = dxmin "Width of upper smoothing range";
1552 output Real y;
1553 algorithm
1554 y := if x < xmin + dxmin then xmin + dxmin - dxmin * (xmin + dxmin - x) / (dxmin ^ 4 + (xmin + dxmin - x) ^ 4) ^ 0.25 else if x > xmax - dxmax then xmax - dxmax + dxmax * (x - xmax + dxmax) / (dxmax ^ 4 + (x - xmax + dxmax) ^ 4) ^ 0.25 else x;
1555 annotation(smoothOrder = 4, InLine = true, normallyConstant = xmin, normallyConstant = xmax, normallyConstant = dxmin, normallyConstant = dxmax);
1556 end smoothSat;
1557
1558 function linspaceExt "Extended linspace function handling also the N=1 case"
1559 input Real x1;
1560 input Real x2;
1561 input Integer N;
1562 output Real[N] vec;
1563 algorithm
1564 vec := if N == 1 then {x1} else linspace(x1, x2, N);
1565 end linspaceExt;
1566
1567 package ValveCharacteristics "Functions for valve characteristics"
1568 partial function baseFun "Base class for valve characteristics"
1569 extends Modelica.Icons.Function;
1570 input Real pos "Stem position (per unit)";
1571 output Real rc "Relative coefficient (per unit)";
1572 end baseFun;
1573
1574 function linear "Linear characteristic"
1575 extends baseFun;
1576 algorithm
1577 rc := pos;
1578 end linear;
1579 end ValveCharacteristics;
1580 end Functions;
1581
1582 package Units "Types with custom units"
1583 extends Modelica.Icons.Package;
1584 type HydraulicConductance = Real(final quantity = "HydraulicConductance", final unit = "(kg/s)/Pa");
1585 type HydraulicResistance = Real(final quantity = "HydraulicResistance", final unit = "Pa/(kg/s)");
1586 type LiquidDensity = SI.Density(start = 1000, nominal = 1000) "start value for liquids";
1587 type GasDensity = SI.Density(start = 5, nominal = 5) "start value for gases/vapours";
1588 type SpecificThermalResistance = Real(unit = "m2.K/W") "Unit for fouling factors";
1589 end Units;
1590 annotation(version = "3.1");
1591end ThermoPower;
1592
1593package ModelicaServices "ModelicaServices (OpenModelica implementation) - Models and functions used in the Modelica Standard Library requiring a tool specific implementation"
1594 extends Modelica.Icons.Package;
1595
1596 package Machine "Machine dependent constants"
1597 extends Modelica.Icons.Package;
1598 final constant Real eps = 1e-15 "Biggest number such that 1.0 + eps = 1.0";
1599 final constant Real small = 1e-60 "Smallest number such that small and -small are representable on the machine";
1600 final constant Real inf = 1e60 "Biggest Real number such that inf and -inf are representable on the machine";
1601 final constant Integer Integer_inf = OpenModelica.Internal.Architecture.integerMax() "Biggest Integer number such that Integer_inf and -Integer_inf are representable on the machine";
1602 end Machine;
1603 annotation(version = "3.2.3", versionBuild = 3, versionDate = "2019-01-23", dateModified = "2019-09-21 12:00:00Z");
1604end ModelicaServices;
1605
1606package Modelica "Modelica Standard Library - Version 3.2.3"
1607 extends Modelica.Icons.Package;
1608
1609 package Blocks "Library of basic input/output control blocks (continuous, discrete, logical, table blocks)"
1610 import SI = Modelica.SIunits;
1611 extends Modelica.Icons.Package;
1612
1613 package Interfaces "Library of connectors and partial models for input/output blocks"
1614 import Modelica.SIunits;
1615 extends Modelica.Icons.InterfacesPackage;
1616 connector RealInput = input Real "'input Real' as connector";
1617 connector RealOutput = output Real "'output Real' as connector";
1618
1619 partial block SISO "Single Input Single Output continuous control block"
1620 extends Modelica.Blocks.Icons.Block;
1621 RealInput u "Connector of Real input signal";
1622 RealOutput y "Connector of Real output signal";
1623 end SISO;
1624 end Interfaces;
1625
1626 package Icons "Icons for Blocks"
1627 extends Modelica.Icons.IconsPackage;
1628
1629 partial block Block "Basic graphical layout of input/output block" end Block;
1630 end Icons;
1631 end Blocks;
1632
1633 package Media "Library of media property models"
1634 extends Modelica.Icons.Package;
1635 import SI = Modelica.SIunits;
1636 import Cv = Modelica.SIunits.Conversions;
1637
1638 package Interfaces "Interfaces for media models"
1639 extends Modelica.Icons.InterfacesPackage;
1640
1641 partial package PartialMedium "Partial medium properties (base package of all media packages)"
1642 extends Modelica.Media.Interfaces.Types;
1643 extends Modelica.Icons.MaterialPropertiesPackage;
1644 constant Modelica.Media.Interfaces.Choices.IndependentVariables ThermoStates "Enumeration type for independent variables";
1645 constant String mediumName = "unusablePartialMedium" "Name of the medium";
1646 constant String[:] substanceNames = {mediumName} "Names of the mixture substances. Set substanceNames={mediumName} if only one substance.";
1647 constant String[:] extraPropertiesNames = fill("", 0) "Names of the additional (extra) transported properties. Set extraPropertiesNames=fill(\"\",0) if unused";
1648 constant Boolean singleState "= true, if u and d are not a function of pressure";
1649 constant Boolean reducedX = true "= true if medium contains the equation sum(X) = 1.0; set reducedX=true if only one substance (see docu for details)";
1650 constant Boolean fixedX = false "= true if medium contains the equation X = reference_X";
1651 constant MassFraction[nX] reference_X = fill(1 / nX, nX) "Default mass fractions of medium";
1652 constant AbsolutePressure p_default = 101325 "Default value for pressure of medium (for initialization)";
1653 constant Temperature T_default = Modelica.SIunits.Conversions.from_degC(20) "Default value for temperature of medium (for initialization)";
1654 constant MassFraction[nX] X_default = reference_X "Default value for mass fractions of medium (for initialization)";
1655 final constant Integer nS = size(substanceNames, 1) "Number of substances";
1656 constant Integer nX = nS "Number of mass fractions";
1657 constant Integer nXi = if fixedX then 0 else if reducedX then nS - 1 else nS "Number of structurally independent mass fractions (see docu for details)";
1658 final constant Integer nC = size(extraPropertiesNames, 1) "Number of extra (outside of standard mass-balance) transported properties";
1659 replaceable record FluidConstants = Modelica.Media.Interfaces.Types.Basic.FluidConstants "Critical, triple, molecular and other standard data of fluid";
1660
1661 replaceable record ThermodynamicState "Minimal variable set that is available as input argument to every medium function"
1662 extends Modelica.Icons.Record;
1663 end ThermodynamicState;
1664
1665 replaceable partial model BaseProperties "Base properties (p, d, T, h, u, R, MM and, if applicable, X and Xi) of a medium"
1666 InputAbsolutePressure p "Absolute pressure of medium";
1667 InputMassFraction[nXi] Xi(start = reference_X[1:nXi]) "Structurally independent mass fractions";
1668 InputSpecificEnthalpy h "Specific enthalpy of medium";
1669 Density d "Density of medium";
1670 Temperature T "Temperature of medium";
1671 MassFraction[nX] X(start = reference_X) "Mass fractions (= (component mass)/total mass m_i/m)";
1672 SpecificInternalEnergy u "Specific internal energy of medium";
1673 SpecificHeatCapacity R "Gas constant (of mixture if applicable)";
1674 MolarMass MM "Molar mass (of mixture or single fluid)";
1675 ThermodynamicState state "Thermodynamic state record for optional functions";
1676 parameter Boolean preferredMediumStates = false "= true if StateSelect.prefer shall be used for the independent property variables of the medium" annotation(Evaluate = true);
1677 parameter Boolean standardOrderComponents = true "If true, and reducedX = true, the last element of X will be computed from the other ones";
1678 SI.Conversions.NonSIunits.Temperature_degC T_degC = Modelica.SIunits.Conversions.to_degC(T) "Temperature of medium in [degC]";
1679 SI.Conversions.NonSIunits.Pressure_bar p_bar = Modelica.SIunits.Conversions.to_bar(p) "Absolute pressure of medium in [bar]";
1680 connector InputAbsolutePressure = input SI.AbsolutePressure "Pressure as input signal connector";
1681 connector InputSpecificEnthalpy = input SI.SpecificEnthalpy "Specific enthalpy as input signal connector";
1682 connector InputMassFraction = input SI.MassFraction "Mass fraction as input signal connector";
1683 equation
1684 if standardOrderComponents then
1685 Xi = X[1:nXi];
1686 if fixedX then
1687 X = reference_X;
1688 end if;
1689 if reducedX and not fixedX then
1690 X[nX] = 1 - sum(Xi);
1691 end if;
1692 for i in 1:nX loop
1693 assert(X[i] >= (-1.e-5) and X[i] <= 1 + 1.e-5, "Mass fraction X[" + String(i) + "] = " + String(X[i]) + "of substance " + substanceNames[i] + "\nof medium " + mediumName + " is not in the range 0..1");
1694 end for;
1695 end if;
1696 assert(p >= 0.0, "Pressure (= " + String(p) + " Pa) of medium \"" + mediumName + "\" is negative\n(Temperature = " + String(T) + " K)");
1697 end BaseProperties;
1698
1699 replaceable partial function setState_pTX "Return thermodynamic state as function of p, T and composition X or Xi"
1700 extends Modelica.Icons.Function;
1701 input AbsolutePressure p "Pressure";
1702 input Temperature T "Temperature";
1703 input MassFraction[:] X = reference_X "Mass fractions";
1704 output ThermodynamicState state "Thermodynamic state record";
1705 end setState_pTX;
1706
1707 replaceable partial function setState_phX "Return thermodynamic state as function of p, h and composition X or Xi"
1708 extends Modelica.Icons.Function;
1709 input AbsolutePressure p "Pressure";
1710 input SpecificEnthalpy h "Specific enthalpy";
1711 input MassFraction[:] X = reference_X "Mass fractions";
1712 output ThermodynamicState state "Thermodynamic state record";
1713 end setState_phX;
1714
1715 replaceable partial function setState_psX "Return thermodynamic state as function of p, s and composition X or Xi"
1716 extends Modelica.Icons.Function;
1717 input AbsolutePressure p "Pressure";
1718 input SpecificEntropy s "Specific entropy";
1719 input MassFraction[:] X = reference_X "Mass fractions";
1720 output ThermodynamicState state "Thermodynamic state record";
1721 end setState_psX;
1722
1723 replaceable partial function setState_dTX "Return thermodynamic state as function of d, T and composition X or Xi"
1724 extends Modelica.Icons.Function;
1725 input Density d "Density";
1726 input Temperature T "Temperature";
1727 input MassFraction[:] X = reference_X "Mass fractions";
1728 output ThermodynamicState state "Thermodynamic state record";
1729 end setState_dTX;
1730
1731 replaceable partial function setSmoothState "Return thermodynamic state so that it smoothly approximates: if x > 0 then state_a else state_b"
1732 extends Modelica.Icons.Function;
1733 input Real x "m_flow or dp";
1734 input ThermodynamicState state_a "Thermodynamic state if x > 0";
1735 input ThermodynamicState state_b "Thermodynamic state if x < 0";
1736 input Real x_small(min = 0) "Smooth transition in the region -x_small < x < x_small";
1737 output ThermodynamicState state "Smooth thermodynamic state for all x (continuous and differentiable)";
1738 end setSmoothState;
1739
1740 replaceable partial function dynamicViscosity "Return dynamic viscosity"
1741 extends Modelica.Icons.Function;
1742 input ThermodynamicState state "Thermodynamic state record";
1743 output DynamicViscosity eta "Dynamic viscosity";
1744 end dynamicViscosity;
1745
1746 replaceable partial function thermalConductivity "Return thermal conductivity"
1747 extends Modelica.Icons.Function;
1748 input ThermodynamicState state "Thermodynamic state record";
1749 output ThermalConductivity lambda "Thermal conductivity";
1750 end thermalConductivity;
1751
1752 replaceable partial function pressure "Return pressure"
1753 extends Modelica.Icons.Function;
1754 input ThermodynamicState state "Thermodynamic state record";
1755 output AbsolutePressure p "Pressure";
1756 end pressure;
1757
1758 replaceable partial function temperature "Return temperature"
1759 extends Modelica.Icons.Function;
1760 input ThermodynamicState state "Thermodynamic state record";
1761 output Temperature T "Temperature";
1762 end temperature;
1763
1764 replaceable partial function density "Return density"
1765 extends Modelica.Icons.Function;
1766 input ThermodynamicState state "Thermodynamic state record";
1767 output Density d "Density";
1768 end density;
1769
1770 replaceable partial function specificEnthalpy "Return specific enthalpy"
1771 extends Modelica.Icons.Function;
1772 input ThermodynamicState state "Thermodynamic state record";
1773 output SpecificEnthalpy h "Specific enthalpy";
1774 end specificEnthalpy;
1775
1776 replaceable partial function specificInternalEnergy "Return specific internal energy"
1777 extends Modelica.Icons.Function;
1778 input ThermodynamicState state "Thermodynamic state record";
1779 output SpecificEnergy u "Specific internal energy";
1780 end specificInternalEnergy;
1781
1782 replaceable partial function specificEntropy "Return specific entropy"
1783 extends Modelica.Icons.Function;
1784 input ThermodynamicState state "Thermodynamic state record";
1785 output SpecificEntropy s "Specific entropy";
1786 end specificEntropy;
1787
1788 replaceable partial function specificGibbsEnergy "Return specific Gibbs energy"
1789 extends Modelica.Icons.Function;
1790 input ThermodynamicState state "Thermodynamic state record";
1791 output SpecificEnergy g "Specific Gibbs energy";
1792 end specificGibbsEnergy;
1793
1794 replaceable partial function specificHelmholtzEnergy "Return specific Helmholtz energy"
1795 extends Modelica.Icons.Function;
1796 input ThermodynamicState state "Thermodynamic state record";
1797 output SpecificEnergy f "Specific Helmholtz energy";
1798 end specificHelmholtzEnergy;
1799
1800 replaceable partial function specificHeatCapacityCp "Return specific heat capacity at constant pressure"
1801 extends Modelica.Icons.Function;
1802 input ThermodynamicState state "Thermodynamic state record";
1803 output SpecificHeatCapacity cp "Specific heat capacity at constant pressure";
1804 end specificHeatCapacityCp;
1805
1806 replaceable partial function specificHeatCapacityCv "Return specific heat capacity at constant volume"
1807 extends Modelica.Icons.Function;
1808 input ThermodynamicState state "Thermodynamic state record";
1809 output SpecificHeatCapacity cv "Specific heat capacity at constant volume";
1810 end specificHeatCapacityCv;
1811
1812 replaceable partial function isentropicExponent "Return isentropic exponent"
1813 extends Modelica.Icons.Function;
1814 input ThermodynamicState state "Thermodynamic state record";
1815 output IsentropicExponent gamma "Isentropic exponent";
1816 end isentropicExponent;
1817
1818 replaceable partial function isentropicEnthalpy "Return isentropic enthalpy"
1819 extends Modelica.Icons.Function;
1820 input AbsolutePressure p_downstream "Downstream pressure";
1821 input ThermodynamicState refState "Reference state for entropy";
1822 output SpecificEnthalpy h_is "Isentropic enthalpy";
1823 end isentropicEnthalpy;
1824
1825 replaceable partial function velocityOfSound "Return velocity of sound"
1826 extends Modelica.Icons.Function;
1827 input ThermodynamicState state "Thermodynamic state record";
1828 output VelocityOfSound a "Velocity of sound";
1829 end velocityOfSound;
1830
1831 replaceable partial function isobaricExpansionCoefficient "Return overall the isobaric expansion coefficient beta"
1832 extends Modelica.Icons.Function;
1833 input ThermodynamicState state "Thermodynamic state record";
1834 output IsobaricExpansionCoefficient beta "Isobaric expansion coefficient";
1835 end isobaricExpansionCoefficient;
1836
1837 replaceable partial function isothermalCompressibility "Return overall the isothermal compressibility factor"
1838 extends Modelica.Icons.Function;
1839 input ThermodynamicState state "Thermodynamic state record";
1840 output SI.IsothermalCompressibility kappa "Isothermal compressibility";
1841 end isothermalCompressibility;
1842
1843 replaceable partial function density_derp_h "Return density derivative w.r.t. pressure at const specific enthalpy"
1844 extends Modelica.Icons.Function;
1845 input ThermodynamicState state "Thermodynamic state record";
1846 output DerDensityByPressure ddph "Density derivative w.r.t. pressure";
1847 end density_derp_h;
1848
1849 replaceable partial function density_derh_p "Return density derivative w.r.t. specific enthalpy at constant pressure"
1850 extends Modelica.Icons.Function;
1851 input ThermodynamicState state "Thermodynamic state record";
1852 output DerDensityByEnthalpy ddhp "Density derivative w.r.t. specific enthalpy";
1853 end density_derh_p;
1854
1855 replaceable partial function molarMass "Return the molar mass of the medium"
1856 extends Modelica.Icons.Function;
1857 input ThermodynamicState state "Thermodynamic state record";
1858 output MolarMass MM "Mixture molar mass";
1859 end molarMass;
1860
1861 replaceable function specificEnthalpy_pTX "Return specific enthalpy from p, T, and X or Xi"
1862 extends Modelica.Icons.Function;
1863 input AbsolutePressure p "Pressure";
1864 input Temperature T "Temperature";
1865 input MassFraction[:] X = reference_X "Mass fractions";
1866 output SpecificEnthalpy h "Specific enthalpy";
1867 algorithm
1868 h := specificEnthalpy(setState_pTX(p, T, X));
1869 annotation(inverse(T = temperature_phX(p, h, X)));
1870 end specificEnthalpy_pTX;
1871
1872 replaceable function temperature_phX "Return temperature from p, h, and X or Xi"
1873 extends Modelica.Icons.Function;
1874 input AbsolutePressure p "Pressure";
1875 input SpecificEnthalpy h "Specific enthalpy";
1876 input MassFraction[:] X = reference_X "Mass fractions";
1877 output Temperature T "Temperature";
1878 algorithm
1879 T := temperature(setState_phX(p, h, X));
1880 end temperature_phX;
1881
1882 replaceable function density_phX "Return density from p, h, and X or Xi"
1883 extends Modelica.Icons.Function;
1884 input AbsolutePressure p "Pressure";
1885 input SpecificEnthalpy h "Specific enthalpy";
1886 input MassFraction[:] X = reference_X "Mass fractions";
1887 output Density d "Density";
1888 algorithm
1889 d := density(setState_phX(p, h, X));
1890 end density_phX;
1891
1892 replaceable function temperature_psX "Return temperature from p,s, and X or Xi"
1893 extends Modelica.Icons.Function;
1894 input AbsolutePressure p "Pressure";
1895 input SpecificEntropy s "Specific entropy";
1896 input MassFraction[:] X = reference_X "Mass fractions";
1897 output Temperature T "Temperature";
1898 algorithm
1899 T := temperature(setState_psX(p, s, X));
1900 annotation(inverse(s = specificEntropy_pTX(p, T, X)));
1901 end temperature_psX;
1902
1903 replaceable function density_psX "Return density from p, s, and X or Xi"
1904 extends Modelica.Icons.Function;
1905 input AbsolutePressure p "Pressure";
1906 input SpecificEntropy s "Specific entropy";
1907 input MassFraction[:] X = reference_X "Mass fractions";
1908 output Density d "Density";
1909 algorithm
1910 d := density(setState_psX(p, s, X));
1911 end density_psX;
1912
1913 replaceable function specificEnthalpy_psX "Return specific enthalpy from p, s, and X or Xi"
1914 extends Modelica.Icons.Function;
1915 input AbsolutePressure p "Pressure";
1916 input SpecificEntropy s "Specific entropy";
1917 input MassFraction[:] X = reference_X "Mass fractions";
1918 output SpecificEnthalpy h "Specific enthalpy";
1919 algorithm
1920 h := specificEnthalpy(setState_psX(p, s, X));
1921 end specificEnthalpy_psX;
1922
1923 type MassFlowRate = SI.MassFlowRate(quantity = "MassFlowRate." + mediumName, min = -1.0e5, max = 1.e5) "Type for mass flow rate with medium specific attributes";
1924 end PartialMedium;
1925
1926 partial package PartialPureSubstance "Base class for pure substances of one chemical substance"
1927 extends PartialMedium(final reducedX = true, final fixedX = true);
1928
1929 replaceable function setState_pT "Return thermodynamic state from p and T"
1930 extends Modelica.Icons.Function;
1931 input AbsolutePressure p "Pressure";
1932 input Temperature T "Temperature";
1933 output ThermodynamicState state "Thermodynamic state record";
1934 algorithm
1935 state := setState_pTX(p, T, fill(0, 0));
1936 end setState_pT;
1937
1938 replaceable function setState_ph "Return thermodynamic state from p and h"
1939 extends Modelica.Icons.Function;
1940 input AbsolutePressure p "Pressure";
1941 input SpecificEnthalpy h "Specific enthalpy";
1942 output ThermodynamicState state "Thermodynamic state record";
1943 algorithm
1944 state := setState_phX(p, h, fill(0, 0));
1945 end setState_ph;
1946
1947 replaceable function density_ph "Return density from p and h"
1948 extends Modelica.Icons.Function;
1949 input AbsolutePressure p "Pressure";
1950 input SpecificEnthalpy h "Specific enthalpy";
1951 output Density d "Density";
1952 algorithm
1953 d := density_phX(p, h, fill(0, 0));
1954 end density_ph;
1955
1956 replaceable function temperature_ph "Return temperature from p and h"
1957 extends Modelica.Icons.Function;
1958 input AbsolutePressure p "Pressure";
1959 input SpecificEnthalpy h "Specific enthalpy";
1960 output Temperature T "Temperature";
1961 algorithm
1962 T := temperature_phX(p, h, fill(0, 0));
1963 end temperature_ph;
1964
1965 replaceable function pressure_dT "Return pressure from d and T"
1966 extends Modelica.Icons.Function;
1967 input Density d "Density";
1968 input Temperature T "Temperature";
1969 output AbsolutePressure p "Pressure";
1970 algorithm
1971 p := pressure(setState_dTX(d, T, fill(0, 0)));
1972 end pressure_dT;
1973
1974 replaceable function specificEnthalpy_dT "Return specific enthalpy from d and T"
1975 extends Modelica.Icons.Function;
1976 input Density d "Density";
1977 input Temperature T "Temperature";
1978 output SpecificEnthalpy h "Specific enthalpy";
1979 algorithm
1980 h := specificEnthalpy(setState_dTX(d, T, fill(0, 0)));
1981 end specificEnthalpy_dT;
1982
1983 replaceable function specificEnthalpy_ps "Return specific enthalpy from p and s"
1984 extends Modelica.Icons.Function;
1985 input AbsolutePressure p "Pressure";
1986 input SpecificEntropy s "Specific entropy";
1987 output SpecificEnthalpy h "Specific enthalpy";
1988 algorithm
1989 h := specificEnthalpy_psX(p, s, fill(0, 0));
1990 end specificEnthalpy_ps;
1991
1992 replaceable function temperature_ps "Return temperature from p and s"
1993 extends Modelica.Icons.Function;
1994 input AbsolutePressure p "Pressure";
1995 input SpecificEntropy s "Specific entropy";
1996 output Temperature T "Temperature";
1997 algorithm
1998 T := temperature_psX(p, s, fill(0, 0));
1999 end temperature_ps;
2000
2001 replaceable function density_ps "Return density from p and s"
2002 extends Modelica.Icons.Function;
2003 input AbsolutePressure p "Pressure";
2004 input SpecificEntropy s "Specific entropy";
2005 output Density d "Density";
2006 algorithm
2007 d := density_psX(p, s, fill(0, 0));
2008 end density_ps;
2009
2010 replaceable function specificEnthalpy_pT "Return specific enthalpy from p and T"
2011 extends Modelica.Icons.Function;
2012 input AbsolutePressure p "Pressure";
2013 input Temperature T "Temperature";
2014 output SpecificEnthalpy h "Specific enthalpy";
2015 algorithm
2016 h := specificEnthalpy_pTX(p, T, fill(0, 0));
2017 end specificEnthalpy_pT;
2018
2019 replaceable function density_pT "Return density from p and T"
2020 extends Modelica.Icons.Function;
2021 input AbsolutePressure p "Pressure";
2022 input Temperature T "Temperature";
2023 output Density d "Density";
2024 algorithm
2025 d := density(setState_pTX(p, T, fill(0, 0)));
2026 end density_pT;
2027
2028 redeclare replaceable partial model extends BaseProperties(final standardOrderComponents = true) end BaseProperties;
2029 end PartialPureSubstance;
2030
2031 partial package PartialTwoPhaseMedium "Base class for two phase medium of one substance"
2032 extends PartialPureSubstance(redeclare replaceable record FluidConstants = Modelica.Media.Interfaces.Types.TwoPhase.FluidConstants);
2033 constant Boolean smoothModel = false "True if the (derived) model should not generate state events";
2034 constant Boolean onePhase = false "True if the (derived) model should never be called with two-phase inputs";
2035 constant FluidConstants[nS] fluidConstants "Constant data for the fluid";
2036
2037 redeclare replaceable record extends ThermodynamicState "Thermodynamic state of two phase medium"
2038 FixedPhase phase(min = 0, max = 2) "Phase of the fluid: 1 for 1-phase, 2 for two-phase, 0 for not known, e.g., interactive use";
2039 end ThermodynamicState;
2040
2041 redeclare replaceable partial model extends BaseProperties "Base properties (p, d, T, h, u, R, MM, sat) of two phase medium"
2042 SaturationProperties sat "Saturation properties at the medium pressure";
2043 end BaseProperties;
2044
2045 replaceable partial function setDewState "Return the thermodynamic state on the dew line"
2046 extends Modelica.Icons.Function;
2047 input SaturationProperties sat "Saturation point";
2048 input FixedPhase phase(min = 1, max = 2) = 1 "Phase: default is one phase";
2049 output ThermodynamicState state "Complete thermodynamic state info";
2050 end setDewState;
2051
2052 replaceable partial function setBubbleState "Return the thermodynamic state on the bubble line"
2053 extends Modelica.Icons.Function;
2054 input SaturationProperties sat "Saturation point";
2055 input FixedPhase phase(min = 1, max = 2) = 1 "Phase: default is one phase";
2056 output ThermodynamicState state "Complete thermodynamic state info";
2057 end setBubbleState;
2058
2059 redeclare replaceable partial function extends setState_dTX "Return thermodynamic state as function of d, T and composition X or Xi"
2060 input FixedPhase phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
2061 end setState_dTX;
2062
2063 redeclare replaceable partial function extends setState_phX "Return thermodynamic state as function of p, h and composition X or Xi"
2064 input FixedPhase phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
2065 end setState_phX;
2066
2067 redeclare replaceable partial function extends setState_psX "Return thermodynamic state as function of p, s and composition X or Xi"
2068 input FixedPhase phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
2069 end setState_psX;
2070
2071 redeclare replaceable partial function extends setState_pTX "Return thermodynamic state as function of p, T and composition X or Xi"
2072 input FixedPhase phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
2073 end setState_pTX;
2074
2075 replaceable function setSat_p "Return saturation property record from pressure"
2076 extends Modelica.Icons.Function;
2077 input AbsolutePressure p "Pressure";
2078 output SaturationProperties sat "Saturation property record";
2079 algorithm
2080 sat.psat := p;
2081 sat.Tsat := saturationTemperature(p);
2082 end setSat_p;
2083
2084 replaceable partial function bubbleEnthalpy "Return bubble point specific enthalpy"
2085 extends Modelica.Icons.Function;
2086 input SaturationProperties sat "Saturation property record";
2087 output SI.SpecificEnthalpy hl "Boiling curve specific enthalpy";
2088 end bubbleEnthalpy;
2089
2090 replaceable partial function dewEnthalpy "Return dew point specific enthalpy"
2091 extends Modelica.Icons.Function;
2092 input SaturationProperties sat "Saturation property record";
2093 output SI.SpecificEnthalpy hv "Dew curve specific enthalpy";
2094 end dewEnthalpy;
2095
2096 replaceable partial function bubbleEntropy "Return bubble point specific entropy"
2097 extends Modelica.Icons.Function;
2098 input SaturationProperties sat "Saturation property record";
2099 output SI.SpecificEntropy sl "Boiling curve specific entropy";
2100 end bubbleEntropy;
2101
2102 replaceable partial function dewEntropy "Return dew point specific entropy"
2103 extends Modelica.Icons.Function;
2104 input SaturationProperties sat "Saturation property record";
2105 output SI.SpecificEntropy sv "Dew curve specific entropy";
2106 end dewEntropy;
2107
2108 replaceable partial function bubbleDensity "Return bubble point density"
2109 extends Modelica.Icons.Function;
2110 input SaturationProperties sat "Saturation property record";
2111 output Density dl "Boiling curve density";
2112 end bubbleDensity;
2113
2114 replaceable partial function dewDensity "Return dew point density"
2115 extends Modelica.Icons.Function;
2116 input SaturationProperties sat "Saturation property record";
2117 output Density dv "Dew curve density";
2118 end dewDensity;
2119
2120 replaceable partial function saturationPressure "Return saturation pressure"
2121 extends Modelica.Icons.Function;
2122 input Temperature T "Temperature";
2123 output AbsolutePressure p "Saturation pressure";
2124 end saturationPressure;
2125
2126 replaceable partial function saturationTemperature "Return saturation temperature"
2127 extends Modelica.Icons.Function;
2128 input AbsolutePressure p "Pressure";
2129 output Temperature T "Saturation temperature";
2130 end saturationTemperature;
2131
2132 replaceable partial function saturationTemperature_derp "Return derivative of saturation temperature w.r.t. pressure"
2133 extends Modelica.Icons.Function;
2134 input AbsolutePressure p "Pressure";
2135 output DerTemperatureByPressure dTp "Derivative of saturation temperature w.r.t. pressure";
2136 end saturationTemperature_derp;
2137
2138 replaceable partial function surfaceTension "Return surface tension sigma in the two phase region"
2139 extends Modelica.Icons.Function;
2140 input SaturationProperties sat "Saturation property record";
2141 output SurfaceTension sigma "Surface tension sigma in the two phase region";
2142 end surfaceTension;
2143
2144 redeclare replaceable function extends molarMass "Return the molar mass of the medium"
2145 algorithm
2146 MM := fluidConstants[1].molarMass;
2147 end molarMass;
2148
2149 replaceable partial function dBubbleDensity_dPressure "Return bubble point density derivative"
2150 extends Modelica.Icons.Function;
2151 input SaturationProperties sat "Saturation property record";
2152 output DerDensityByPressure ddldp "Boiling curve density derivative";
2153 end dBubbleDensity_dPressure;
2154
2155 replaceable partial function dDewDensity_dPressure "Return dew point density derivative"
2156 extends Modelica.Icons.Function;
2157 input SaturationProperties sat "Saturation property record";
2158 output DerDensityByPressure ddvdp "Saturated steam density derivative";
2159 end dDewDensity_dPressure;
2160
2161 replaceable partial function dBubbleEnthalpy_dPressure "Return bubble point specific enthalpy derivative"
2162 extends Modelica.Icons.Function;
2163 input SaturationProperties sat "Saturation property record";
2164 output DerEnthalpyByPressure dhldp "Boiling curve specific enthalpy derivative";
2165 end dBubbleEnthalpy_dPressure;
2166
2167 replaceable partial function dDewEnthalpy_dPressure "Return dew point specific enthalpy derivative"
2168 extends Modelica.Icons.Function;
2169 input SaturationProperties sat "Saturation property record";
2170 output DerEnthalpyByPressure dhvdp "Saturated steam specific enthalpy derivative";
2171 end dDewEnthalpy_dPressure;
2172
2173 redeclare replaceable function specificEnthalpy_pTX "Return specific enthalpy from pressure, temperature and mass fraction"
2174 extends Modelica.Icons.Function;
2175 input AbsolutePressure p "Pressure";
2176 input Temperature T "Temperature";
2177 input MassFraction[:] X "Mass fractions";
2178 input FixedPhase phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
2179 output SpecificEnthalpy h "Specific enthalpy at p, T, X";
2180 algorithm
2181 h := specificEnthalpy(setState_pTX(p, T, X, phase));
2182 end specificEnthalpy_pTX;
2183
2184 redeclare replaceable function temperature_phX "Return temperature from p, h, and X or Xi"
2185 extends Modelica.Icons.Function;
2186 input AbsolutePressure p "Pressure";
2187 input SpecificEnthalpy h "Specific enthalpy";
2188 input MassFraction[:] X "Mass fractions";
2189 input FixedPhase phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
2190 output Temperature T "Temperature";
2191 algorithm
2192 T := temperature(setState_phX(p, h, X, phase));
2193 end temperature_phX;
2194
2195 redeclare replaceable function density_phX "Return density from p, h, and X or Xi"
2196 extends Modelica.Icons.Function;
2197 input AbsolutePressure p "Pressure";
2198 input SpecificEnthalpy h "Specific enthalpy";
2199 input MassFraction[:] X "Mass fractions";
2200 input FixedPhase phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
2201 output Density d "Density";
2202 algorithm
2203 d := density(setState_phX(p, h, X, phase));
2204 end density_phX;
2205
2206 redeclare replaceable function temperature_psX "Return temperature from p, s, and X or Xi"
2207 extends Modelica.Icons.Function;
2208 input AbsolutePressure p "Pressure";
2209 input SpecificEntropy s "Specific entropy";
2210 input MassFraction[:] X "Mass fractions";
2211 input FixedPhase phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
2212 output Temperature T "Temperature";
2213 algorithm
2214 T := temperature(setState_psX(p, s, X, phase));
2215 end temperature_psX;
2216
2217 redeclare replaceable function density_psX "Return density from p, s, and X or Xi"
2218 extends Modelica.Icons.Function;
2219 input AbsolutePressure p "Pressure";
2220 input SpecificEntropy s "Specific entropy";
2221 input MassFraction[:] X "Mass fractions";
2222 input FixedPhase phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
2223 output Density d "Density";
2224 algorithm
2225 d := density(setState_psX(p, s, X, phase));
2226 end density_psX;
2227
2228 redeclare replaceable function specificEnthalpy_psX "Return specific enthalpy from p, s, and X or Xi"
2229 extends Modelica.Icons.Function;
2230 input AbsolutePressure p "Pressure";
2231 input SpecificEntropy s "Specific entropy";
2232 input MassFraction[:] X "Mass fractions";
2233 input FixedPhase phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
2234 output SpecificEnthalpy h "Specific enthalpy";
2235 algorithm
2236 h := specificEnthalpy(setState_psX(p, s, X, phase));
2237 end specificEnthalpy_psX;
2238
2239 redeclare replaceable function setState_pT "Return thermodynamic state from p and T"
2240 extends Modelica.Icons.Function;
2241 input AbsolutePressure p "Pressure";
2242 input Temperature T "Temperature";
2243 input FixedPhase phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
2244 output ThermodynamicState state "Thermodynamic state record";
2245 algorithm
2246 state := setState_pTX(p, T, fill(0, 0), phase);
2247 end setState_pT;
2248
2249 redeclare replaceable function setState_ph "Return thermodynamic state from p and h"
2250 extends Modelica.Icons.Function;
2251 input AbsolutePressure p "Pressure";
2252 input SpecificEnthalpy h "Specific enthalpy";
2253 input FixedPhase phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
2254 output ThermodynamicState state "Thermodynamic state record";
2255 algorithm
2256 state := setState_phX(p, h, fill(0, 0), phase);
2257 end setState_ph;
2258
2259 replaceable function vapourQuality "Return vapour quality"
2260 extends Modelica.Icons.Function;
2261 input ThermodynamicState state "Thermodynamic state record";
2262 output MassFraction x "Vapour quality";
2263 protected
2264 constant SpecificEnthalpy eps = 1e-8;
2265 algorithm
2266 x := min(max((specificEnthalpy(state) - bubbleEnthalpy(setSat_p(pressure(state)))) / (dewEnthalpy(setSat_p(pressure(state))) - bubbleEnthalpy(setSat_p(pressure(state))) + eps), 0), 1);
2267 end vapourQuality;
2268
2269 redeclare replaceable function density_ph "Return density from p and h"
2270 extends Modelica.Icons.Function;
2271 input AbsolutePressure p "Pressure";
2272 input SpecificEnthalpy h "Specific enthalpy";
2273 input FixedPhase phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
2274 output Density d "Density";
2275 algorithm
2276 d := density_phX(p, h, fill(0, 0), phase);
2277 end density_ph;
2278
2279 redeclare replaceable function temperature_ph "Return temperature from p and h"
2280 extends Modelica.Icons.Function;
2281 input AbsolutePressure p "Pressure";
2282 input SpecificEnthalpy h "Specific enthalpy";
2283 input FixedPhase phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
2284 output Temperature T "Temperature";
2285 algorithm
2286 T := temperature_phX(p, h, fill(0, 0), phase);
2287 end temperature_ph;
2288
2289 redeclare replaceable function pressure_dT "Return pressure from d and T"
2290 extends Modelica.Icons.Function;
2291 input Density d "Density";
2292 input Temperature T "Temperature";
2293 input FixedPhase phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
2294 output AbsolutePressure p "Pressure";
2295 algorithm
2296 p := pressure(setState_dTX(d, T, fill(0, 0), phase));
2297 end pressure_dT;
2298
2299 redeclare replaceable function specificEnthalpy_dT "Return specific enthalpy from d and T"
2300 extends Modelica.Icons.Function;
2301 input Density d "Density";
2302 input Temperature T "Temperature";
2303 input FixedPhase phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
2304 output SpecificEnthalpy h "Specific enthalpy";
2305 algorithm
2306 h := specificEnthalpy(setState_dTX(d, T, fill(0, 0), phase));
2307 end specificEnthalpy_dT;
2308
2309 redeclare replaceable function specificEnthalpy_ps "Return specific enthalpy from p and s"
2310 extends Modelica.Icons.Function;
2311 input AbsolutePressure p "Pressure";
2312 input SpecificEntropy s "Specific entropy";
2313 input FixedPhase phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
2314 output SpecificEnthalpy h "Specific enthalpy";
2315 algorithm
2316 h := specificEnthalpy_psX(p, s, fill(0, 0));
2317 end specificEnthalpy_ps;
2318
2319 redeclare replaceable function temperature_ps "Return temperature from p and s"
2320 extends Modelica.Icons.Function;
2321 input AbsolutePressure p "Pressure";
2322 input SpecificEntropy s "Specific entropy";
2323 input FixedPhase phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
2324 output Temperature T "Temperature";
2325 algorithm
2326 T := temperature_psX(p, s, fill(0, 0), phase);
2327 end temperature_ps;
2328
2329 redeclare replaceable function density_ps "Return density from p and s"
2330 extends Modelica.Icons.Function;
2331 input AbsolutePressure p "Pressure";
2332 input SpecificEntropy s "Specific entropy";
2333 input FixedPhase phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
2334 output Density d "Density";
2335 algorithm
2336 d := density_psX(p, s, fill(0, 0), phase);
2337 end density_ps;
2338
2339 redeclare replaceable function specificEnthalpy_pT "Return specific enthalpy from p and T"
2340 extends Modelica.Icons.Function;
2341 input AbsolutePressure p "Pressure";
2342 input Temperature T "Temperature";
2343 input FixedPhase phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
2344 output SpecificEnthalpy h "Specific enthalpy";
2345 algorithm
2346 h := specificEnthalpy_pTX(p, T, fill(0, 0), phase);
2347 end specificEnthalpy_pT;
2348
2349 redeclare replaceable function density_pT "Return density from p and T"
2350 extends Modelica.Icons.Function;
2351 input AbsolutePressure p "Pressure";
2352 input Temperature T "Temperature";
2353 input FixedPhase phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
2354 output Density d "Density";
2355 algorithm
2356 d := density(setState_pTX(p, T, fill(0, 0), phase));
2357 end density_pT;
2358 end PartialTwoPhaseMedium;
2359
2360 package Choices "Types, constants to define menu choices"
2361 extends Modelica.Icons.Package;
2362 type IndependentVariables = enumeration(T "Temperature", pT "Pressure, Temperature", ph "Pressure, Specific Enthalpy", phX "Pressure, Specific Enthalpy, Mass Fraction", pTX "Pressure, Temperature, Mass Fractions", dTX "Density, Temperature, Mass Fractions") "Enumeration defining the independent variables of a medium";
2363 end Choices;
2364
2365 package Types "Types to be used in fluid models"
2366 extends Modelica.Icons.Package;
2367 type AbsolutePressure = SI.AbsolutePressure(min = 0, max = 1.e8, nominal = 1.e5, start = 1.e5) "Type for absolute pressure with medium specific attributes";
2368 type Density = SI.Density(min = 0, max = 1.e5, nominal = 1, start = 1) "Type for density with medium specific attributes";
2369 type DynamicViscosity = SI.DynamicViscosity(min = 0, max = 1.e8, nominal = 1.e-3, start = 1.e-3) "Type for dynamic viscosity with medium specific attributes";
2370 type MassFraction = Real(quantity = "MassFraction", final unit = "kg/kg", min = 0, max = 1, nominal = 0.1) "Type for mass fraction with medium specific attributes";
2371 type MolarMass = SI.MolarMass(min = 0.001, max = 0.25, nominal = 0.032) "Type for molar mass with medium specific attributes";
2372 type MolarVolume = SI.MolarVolume(min = 1e-6, max = 1.0e6, nominal = 1.0) "Type for molar volume with medium specific attributes";
2373 type IsentropicExponent = SI.RatioOfSpecificHeatCapacities(min = 1, max = 500000, nominal = 1.2, start = 1.2) "Type for isentropic exponent with medium specific attributes";
2374 type SpecificEnergy = SI.SpecificEnergy(min = -1.0e8, max = 1.e8, nominal = 1.e6) "Type for specific energy with medium specific attributes";
2375 type SpecificInternalEnergy = SpecificEnergy "Type for specific internal energy with medium specific attributes";
2376 type SpecificEnthalpy = SI.SpecificEnthalpy(min = -1.0e10, max = 1.e10, nominal = 1.e6) "Type for specific enthalpy with medium specific attributes";
2377 type SpecificEntropy = SI.SpecificEntropy(min = -1.e7, max = 1.e7, nominal = 1.e3) "Type for specific entropy with medium specific attributes";
2378 type SpecificHeatCapacity = SI.SpecificHeatCapacity(min = 0, max = 1.e7, nominal = 1.e3, start = 1.e3) "Type for specific heat capacity with medium specific attributes";
2379 type SurfaceTension = SI.SurfaceTension "Type for surface tension with medium specific attributes";
2380 type Temperature = SI.Temperature(min = 1, max = 1.e4, nominal = 300, start = 288.15) "Type for temperature with medium specific attributes";
2381 type ThermalConductivity = SI.ThermalConductivity(min = 0, max = 500, nominal = 1, start = 1) "Type for thermal conductivity with medium specific attributes";
2382 type VelocityOfSound = SI.Velocity(min = 0, max = 1.e5, nominal = 1000, start = 1000) "Type for velocity of sound with medium specific attributes";
2383 type ExtraProperty = Real(min = 0.0, start = 1.0) "Type for unspecified, mass-specific property transported by flow";
2384 type IsobaricExpansionCoefficient = Real(min = 0, max = 1.0e8, unit = "1/K") "Type for isobaric expansion coefficient with medium specific attributes";
2385 type DipoleMoment = Real(min = 0.0, max = 2.0, unit = "debye", quantity = "ElectricDipoleMoment") "Type for dipole moment with medium specific attributes";
2386 type DerDensityByPressure = SI.DerDensityByPressure "Type for partial derivative of density with respect to pressure with medium specific attributes";
2387 type DerDensityByEnthalpy = SI.DerDensityByEnthalpy "Type for partial derivative of density with respect to enthalpy with medium specific attributes";
2388 type DerEnthalpyByPressure = SI.DerEnthalpyByPressure "Type for partial derivative of enthalpy with respect to pressure with medium specific attributes";
2389 type DerTemperatureByPressure = Real(final unit = "K/Pa") "Type for partial derivative of temperature with respect to pressure with medium specific attributes";
2390
2391 replaceable record SaturationProperties "Saturation properties of two phase medium"
2392 extends Modelica.Icons.Record;
2393 AbsolutePressure psat "Saturation pressure";
2394 Temperature Tsat "Saturation temperature";
2395 end SaturationProperties;
2396
2397 type FixedPhase = Integer(min = 0, max = 2) "Phase of the fluid: 1 for 1-phase, 2 for two-phase, 0 for not known, e.g., interactive use";
2398
2399 package Basic "The most basic version of a record used in several degrees of detail"
2400 extends Icons.Package;
2401
2402 record FluidConstants "Critical, triple, molecular and other standard data of fluid"
2403 extends Modelica.Icons.Record;
2404 String iupacName "Complete IUPAC name (or common name, if non-existent)";
2405 String casRegistryNumber "Chemical abstracts sequencing number (if it exists)";
2406 String chemicalFormula "Chemical formula, (brutto, nomenclature according to Hill";
2407 String structureFormula "Chemical structure formula";
2408 MolarMass molarMass "Molar mass";
2409 end FluidConstants;
2410 end Basic;
2411
2412 package TwoPhase "The two phase fluid version of a record used in several degrees of detail"
2413 extends Icons.Package;
2414
2415 record FluidConstants "Extended fluid constants"
2416 extends Modelica.Media.Interfaces.Types.Basic.FluidConstants;
2417 Temperature criticalTemperature "Critical temperature";
2418 AbsolutePressure criticalPressure "Critical pressure";
2419 MolarVolume criticalMolarVolume "Critical molar Volume";
2420 Real acentricFactor "Pitzer acentric factor";
2421 Temperature triplePointTemperature "Triple point temperature";
2422 AbsolutePressure triplePointPressure "Triple point pressure";
2423 Temperature meltingPoint "Melting point at 101325 Pa";
2424 Temperature normalBoilingPoint "Normal boiling point (at 101325 Pa)";
2425 DipoleMoment dipoleMoment "Dipole moment of molecule in Debye (1 debye = 3.33564e10-30 C.m)";
2426 Boolean hasIdealGasHeatCapacity = false "True if ideal gas heat capacity is available";
2427 Boolean hasCriticalData = false "True if critical data are known";
2428 Boolean hasDipoleMoment = false "True if a dipole moment known";
2429 Boolean hasFundamentalEquation = false "True if a fundamental equation";
2430 Boolean hasLiquidHeatCapacity = false "True if liquid heat capacity is available";
2431 Boolean hasSolidHeatCapacity = false "True if solid heat capacity is available";
2432 Boolean hasAccurateViscosityData = false "True if accurate data for a viscosity function is available";
2433 Boolean hasAccurateConductivityData = false "True if accurate data for thermal conductivity is available";
2434 Boolean hasVapourPressureCurve = false "True if vapour pressure data, e.g., Antoine coefficients are known";
2435 Boolean hasAcentricFactor = false "True if Pitzer acentric factor is known";
2436 SpecificEnthalpy HCRIT0 = 0.0 "Critical specific enthalpy of the fundamental equation";
2437 SpecificEntropy SCRIT0 = 0.0 "Critical specific entropy of the fundamental equation";
2438 SpecificEnthalpy deltah = 0.0 "Difference between specific enthalpy model (h_m) and f.eq. (h_f) (h_m - h_f)";
2439 SpecificEntropy deltas = 0.0 "Difference between specific enthalpy model (s_m) and f.eq. (s_f) (s_m - s_f)";
2440 end FluidConstants;
2441 end TwoPhase;
2442 end Types;
2443 end Interfaces;
2444
2445 package Common "Data structures and fundamental functions for fluid properties"
2446 extends Modelica.Icons.Package;
2447 type DerPressureByDensity = Real(final quantity = "DerPressureByDensity", final unit = "Pa.m3/kg");
2448 type DerPressureByTemperature = Real(final quantity = "DerPressureByTemperature", final unit = "Pa/K");
2449 constant Real MINPOS = 1.0e-9 "Minimal value for physical variables which are always > 0.0";
2450
2451 record IF97BaseTwoPhase "Intermediate property data record for IF 97"
2452 extends Modelica.Icons.Record;
2453 Integer phase(start = 0) "Phase: 2 for two-phase, 1 for one phase, 0 if unknown";
2454 Integer region(min = 1, max = 5) "IF 97 region";
2455 SI.Pressure p "Pressure";
2456 SI.Temperature T "Temperature";
2457 SI.SpecificEnthalpy h "Specific enthalpy";
2458 SI.SpecificHeatCapacity R "Gas constant";
2459 SI.SpecificHeatCapacity cp "Specific heat capacity";
2460 SI.SpecificHeatCapacity cv "Specific heat capacity";
2461 SI.Density rho "Density";
2462 SI.SpecificEntropy s "Specific entropy";
2463 DerPressureByTemperature pt "Derivative of pressure w.r.t. temperature";
2464 DerPressureByDensity pd "Derivative of pressure w.r.t. density";
2465 Real vt "Derivative of specific volume w.r.t. temperature";
2466 Real vp "Derivative of specific volume w.r.t. pressure";
2467 Real x "Dryness fraction";
2468 Real dpT "dp/dT derivative of saturation curve";
2469 end IF97BaseTwoPhase;
2470
2471 record IF97PhaseBoundaryProperties "Thermodynamic base properties on the phase boundary for IF97 steam tables"
2472 extends Modelica.Icons.Record;
2473 Boolean region3boundary "True if boundary between 2-phase and region 3";
2474 SI.SpecificHeatCapacity R "Specific heat capacity";
2475 SI.Temperature T "Temperature";
2476 SI.Density d "Density";
2477 SI.SpecificEnthalpy h "Specific enthalpy";
2478 SI.SpecificEntropy s "Specific entropy";
2479 SI.SpecificHeatCapacity cp "Heat capacity at constant pressure";
2480 SI.SpecificHeatCapacity cv "Heat capacity at constant volume";
2481 DerPressureByTemperature dpT "dp/dT derivative of saturation curve";
2482 DerPressureByTemperature pt "Derivative of pressure w.r.t. temperature";
2483 DerPressureByDensity pd "Derivative of pressure w.r.t. density";
2484 Real vt(unit = "m3/(kg.K)") "Derivative of specific volume w.r.t. temperature";
2485 Real vp(unit = "m3/(kg.Pa)") "Derivative of specific volume w.r.t. pressure";
2486 end IF97PhaseBoundaryProperties;
2487
2488 record GibbsDerivs "Derivatives of dimensionless Gibbs-function w.r.t. dimensionless pressure and temperature"
2489 extends Modelica.Icons.Record;
2490 SI.Pressure p "Pressure";
2491 SI.Temperature T "Temperature";
2492 SI.SpecificHeatCapacity R "Specific heat capacity";
2493 Real pi(unit = "1") "Dimensionless pressure";
2494 Real tau(unit = "1") "Dimensionless temperature";
2495 Real g(unit = "1") "Dimensionless Gibbs-function";
2496 Real gpi(unit = "1") "Derivative of g w.r.t. pi";
2497 Real gpipi(unit = "1") "2nd derivative of g w.r.t. pi";
2498 Real gtau(unit = "1") "Derivative of g w.r.t. tau";
2499 Real gtautau(unit = "1") "2nd derivative of g w.r.t. tau";
2500 Real gtaupi(unit = "1") "Mixed derivative of g w.r.t. pi and tau";
2501 end GibbsDerivs;
2502
2503 record HelmholtzDerivs "Derivatives of dimensionless Helmholtz-function w.r.t. dimensionless pressure, density and temperature"
2504 extends Modelica.Icons.Record;
2505 SI.Density d "Density";
2506 SI.Temperature T "Temperature";
2507 SI.SpecificHeatCapacity R "Specific heat capacity";
2508 Real delta(unit = "1") "Dimensionless density";
2509 Real tau(unit = "1") "Dimensionless temperature";
2510 Real f(unit = "1") "Dimensionless Helmholtz-function";
2511 Real fdelta(unit = "1") "Derivative of f w.r.t. delta";
2512 Real fdeltadelta(unit = "1") "2nd derivative of f w.r.t. delta";
2513 Real ftau(unit = "1") "Derivative of f w.r.t. tau";
2514 Real ftautau(unit = "1") "2nd derivative of f w.r.t. tau";
2515 Real fdeltatau(unit = "1") "Mixed derivative of f w.r.t. delta and tau";
2516 end HelmholtzDerivs;
2517
2518 record PhaseBoundaryProperties "Thermodynamic base properties on the phase boundary"
2519 extends Modelica.Icons.Record;
2520 SI.Density d "Density";
2521 SI.SpecificEnthalpy h "Specific enthalpy";
2522 SI.SpecificEnergy u "Inner energy";
2523 SI.SpecificEntropy s "Specific entropy";
2524 SI.SpecificHeatCapacity cp "Heat capacity at constant pressure";
2525 SI.SpecificHeatCapacity cv "Heat capacity at constant volume";
2526 DerPressureByTemperature pt "Derivative of pressure w.r.t. temperature";
2527 DerPressureByDensity pd "Derivative of pressure w.r.t. density";
2528 end PhaseBoundaryProperties;
2529
2530 record NewtonDerivatives_ph "Derivatives for fast inverse calculations of Helmholtz functions: p & h"
2531 extends Modelica.Icons.Record;
2532 SI.Pressure p "Pressure";
2533 SI.SpecificEnthalpy h "Specific enthalpy";
2534 DerPressureByDensity pd "Derivative of pressure w.r.t. density";
2535 DerPressureByTemperature pt "Derivative of pressure w.r.t. temperature";
2536 Real hd "Derivative of specific enthalpy w.r.t. density";
2537 Real ht "Derivative of specific enthalpy w.r.t. temperature";
2538 end NewtonDerivatives_ph;
2539
2540 record NewtonDerivatives_ps "Derivatives for fast inverse calculation of Helmholtz functions: p & s"
2541 extends Modelica.Icons.Record;
2542 SI.Pressure p "Pressure";
2543 SI.SpecificEntropy s "Specific entropy";
2544 DerPressureByDensity pd "Derivative of pressure w.r.t. density";
2545 DerPressureByTemperature pt "Derivative of pressure w.r.t. temperature";
2546 Real sd "Derivative of specific entropy w.r.t. density";
2547 Real st "Derivative of specific entropy w.r.t. temperature";
2548 end NewtonDerivatives_ps;
2549
2550 record NewtonDerivatives_pT "Derivatives for fast inverse calculations of Helmholtz functions:p & T"
2551 extends Modelica.Icons.Record;
2552 SI.Pressure p "Pressure";
2553 DerPressureByDensity pd "Derivative of pressure w.r.t. density";
2554 end NewtonDerivatives_pT;
2555
2556 function gibbsToBoundaryProps "Calculate phase boundary property record from dimensionless Gibbs function"
2557 extends Modelica.Icons.Function;
2558 input GibbsDerivs g "Dimensionless derivatives of Gibbs function";
2559 output PhaseBoundaryProperties sat "Phase boundary properties";
2560 protected
2561 Real vt "Derivative of specific volume w.r.t. temperature";
2562 Real vp "Derivative of specific volume w.r.t. pressure";
2563 algorithm
2564 sat.d := g.p / (g.R * g.T * g.pi * g.gpi);
2565 sat.h := g.R * g.T * g.tau * g.gtau;
2566 sat.u := g.T * g.R * (g.tau * g.gtau - g.pi * g.gpi);
2567 sat.s := g.R * (g.tau * g.gtau - g.g);
2568 sat.cp := -g.R * g.tau * g.tau * g.gtautau;
2569 sat.cv := g.R * ((-g.tau * g.tau * g.gtautau) + (g.gpi - g.tau * g.gtaupi) * (g.gpi - g.tau * g.gtaupi) / g.gpipi);
2570 vt := g.R / g.p * (g.pi * g.gpi - g.tau * g.pi * g.gtaupi);
2571 vp := g.R * g.T / (g.p * g.p) * g.pi * g.pi * g.gpipi;
2572 sat.pt := -g.p / g.T * (g.gpi - g.tau * g.gtaupi) / (g.gpipi * g.pi);
2573 sat.pd := -g.R * g.T * g.gpi * g.gpi / g.gpipi;
2574 end gibbsToBoundaryProps;
2575
2576 function helmholtzToBoundaryProps "Calculate phase boundary property record from dimensionless Helmholtz function"
2577 extends Modelica.Icons.Function;
2578 input HelmholtzDerivs f "Dimensionless derivatives of Helmholtz function";
2579 output PhaseBoundaryProperties sat "Phase boundary property record";
2580 protected
2581 SI.Pressure p "Pressure";
2582 algorithm
2583 p := f.R * f.d * f.T * f.delta * f.fdelta;
2584 sat.d := f.d;
2585 sat.h := f.R * f.T * (f.tau * f.ftau + f.delta * f.fdelta);
2586 sat.s := f.R * (f.tau * f.ftau - f.f);
2587 sat.u := f.R * f.T * f.tau * f.ftau;
2588 sat.cp := f.R * ((-f.tau * f.tau * f.ftautau) + (f.delta * f.fdelta - f.delta * f.tau * f.fdeltatau) ^ 2 / (2 * f.delta * f.fdelta + f.delta * f.delta * f.fdeltadelta));
2589 sat.cv := f.R * (-f.tau * f.tau * f.ftautau);
2590 sat.pt := f.R * f.d * f.delta * (f.fdelta - f.tau * f.fdeltatau);
2591 sat.pd := f.R * f.T * f.delta * (2.0 * f.fdelta + f.delta * f.fdeltadelta);
2592 end helmholtzToBoundaryProps;
2593
2594 function cv2Phase "Compute isochoric specific heat capacity inside the two-phase region"
2595 extends Modelica.Icons.Function;
2596 input PhaseBoundaryProperties liq "Properties on the boiling curve";
2597 input PhaseBoundaryProperties vap "Properties on the condensation curve";
2598 input SI.MassFraction x "Vapour mass fraction";
2599 input SI.Temperature T "Temperature";
2600 input SI.Pressure p "Properties";
2601 output SI.SpecificHeatCapacity cv "Isochoric specific heat capacity";
2602 protected
2603 Real dpT "Derivative of pressure w.r.t. temperature";
2604 Real dxv "Derivative of vapour mass fraction w.r.t. specific volume";
2605 Real dvTl "Derivative of liquid specific volume w.r.t. temperature";
2606 Real dvTv "Derivative of vapour specific volume w.r.t. temperature";
2607 Real duTl "Derivative of liquid specific inner energy w.r.t. temperature";
2608 Real duTv "Derivative of vapour specific inner energy w.r.t. temperature";
2609 Real dxt "Derivative of vapour mass fraction w.r.t. temperature";
2610 algorithm
2611 dxv := if liq.d <> vap.d then liq.d * vap.d / (liq.d - vap.d) else 0.0;
2612 dpT := (vap.s - liq.s) * dxv;
2613 dvTl := (liq.pt - dpT) / liq.pd / liq.d / liq.d;
2614 dvTv := (vap.pt - dpT) / vap.pd / vap.d / vap.d;
2615 dxt := -dxv * (dvTl + x * (dvTv - dvTl));
2616 duTl := liq.cv + (T * liq.pt - p) * dvTl;
2617 duTv := vap.cv + (T * vap.pt - p) * dvTv;
2618 cv := duTl + x * (duTv - duTl) + dxt * (vap.u - liq.u);
2619 end cv2Phase;
2620
2621 function Helmholtz_ph "Function to calculate analytic derivatives for computing d and t given p and h"
2622 extends Modelica.Icons.Function;
2623 input HelmholtzDerivs f "Dimensionless derivatives of Helmholtz function";
2624 output NewtonDerivatives_ph nderivs "Derivatives for Newton iteration to calculate d and t from p and h";
2625 protected
2626 SI.SpecificHeatCapacity cv "Isochoric heat capacity";
2627 algorithm
2628 cv := -f.R * (f.tau * f.tau * f.ftautau);
2629 nderivs.p := f.d * f.R * f.T * f.delta * f.fdelta;
2630 nderivs.h := f.R * f.T * (f.tau * f.ftau + f.delta * f.fdelta);
2631 nderivs.pd := f.R * f.T * f.delta * (2.0 * f.fdelta + f.delta * f.fdeltadelta);
2632 nderivs.pt := f.R * f.d * f.delta * (f.fdelta - f.tau * f.fdeltatau);
2633 nderivs.ht := cv + nderivs.pt / f.d;
2634 nderivs.hd := (nderivs.pd - f.T * nderivs.pt / f.d) / f.d;
2635 end Helmholtz_ph;
2636
2637 function Helmholtz_pT "Function to calculate analytic derivatives for computing d and t given p and t"
2638 extends Modelica.Icons.Function;
2639 input HelmholtzDerivs f "Dimensionless derivatives of Helmholtz function";
2640 output NewtonDerivatives_pT nderivs "Derivatives for Newton iteration to compute d and t from p and t";
2641 algorithm
2642 nderivs.p := f.d * f.R * f.T * f.delta * f.fdelta;
2643 nderivs.pd := f.R * f.T * f.delta * (2.0 * f.fdelta + f.delta * f.fdeltadelta);
2644 end Helmholtz_pT;
2645
2646 function Helmholtz_ps "Function to calculate analytic derivatives for computing d and t given p and s"
2647 extends Modelica.Icons.Function;
2648 input HelmholtzDerivs f "Dimensionless derivatives of Helmholtz function";
2649 output NewtonDerivatives_ps nderivs "Derivatives for Newton iteration to compute d and t from p and s";
2650 protected
2651 SI.SpecificHeatCapacity cv "Isochoric heat capacity";
2652 algorithm
2653 cv := -f.R * (f.tau * f.tau * f.ftautau);
2654 nderivs.p := f.d * f.R * f.T * f.delta * f.fdelta;
2655 nderivs.s := f.R * (f.tau * f.ftau - f.f);
2656 nderivs.pd := f.R * f.T * f.delta * (2.0 * f.fdelta + f.delta * f.fdeltadelta);
2657 nderivs.pt := f.R * f.d * f.delta * (f.fdelta - f.tau * f.fdeltatau);
2658 nderivs.st := cv / f.T;
2659 nderivs.sd := -nderivs.pt / (f.d * f.d);
2660 end Helmholtz_ps;
2661
2662 function smoothStep "Approximation of a general step, such that the characteristic is continuous and differentiable"
2663 extends Modelica.Icons.Function;
2664 input Real x "Abscissa value";
2665 input Real y1 "Ordinate value for x > 0";
2666 input Real y2 "Ordinate value for x < 0";
2667 input Real x_small(min = 0) = 1e-5 "Approximation of step for -x_small <= x <= x_small; x_small > 0 required";
2668 output Real y "Ordinate value to approximate y = if x > 0 then y1 else y2";
2669 algorithm
2670 y := smooth(1, if x > x_small then y1 else if x < (-x_small) then y2 else if abs(x_small) > 0 then x / x_small * ((x / x_small) ^ 2 - 3) * (y2 - y1) / 4 + (y1 + y2) / 2 else (y1 + y2) / 2);
2671 annotation(Inline = true, smoothOrder = 1);
2672 end smoothStep;
2673 end Common;
2674
2675 package Water "Medium models for water"
2676 extends Modelica.Icons.VariantsPackage;
2677 import Modelica.Media.Water.ConstantPropertyLiquidWater.simpleWaterConstants;
2678 constant Modelica.Media.Interfaces.Types.TwoPhase.FluidConstants[1] waterConstants(each chemicalFormula = "H2O", each structureFormula = "H2O", each casRegistryNumber = "7732-18-5", each iupacName = "oxidane", each molarMass = 0.018015268, each criticalTemperature = 647.096, each criticalPressure = 22064.0e3, each criticalMolarVolume = 1 / 322.0 * 0.018015268, each normalBoilingPoint = 373.124, each meltingPoint = 273.15, each triplePointTemperature = 273.16, each triplePointPressure = 611.657, each acentricFactor = 0.344, each dipoleMoment = 1.8, each hasCriticalData = true);
2679 package StandardWater = WaterIF97_ph "Water using the IF97 standard, explicit in p and h. Recommended for most applications";
2680
2681 package WaterIF97_ph "Water using the IF97 standard, explicit in p and h"
2682 extends WaterIF97_base(ThermoStates = Modelica.Media.Interfaces.Choices.IndependentVariables.ph, final ph_explicit = true, final dT_explicit = false, final pT_explicit = false, smoothModel = false, onePhase = false);
2683 end WaterIF97_ph;
2684
2685 partial package WaterIF97_base "Water: Steam properties as defined by IAPWS/IF97 standard"
2686 extends Interfaces.PartialTwoPhaseMedium(mediumName = "WaterIF97", substanceNames = {"water"}, singleState = false, SpecificEnthalpy(start = 1.0e5, nominal = 5.0e5), Density(start = 150, nominal = 500), AbsolutePressure(start = 50e5, nominal = 10e5, min = 611.657, max = 100e6), Temperature(start = 500, nominal = 500, min = 273.15, max = 2273.15), smoothModel = false, onePhase = false, fluidConstants = waterConstants);
2687
2688 redeclare record extends ThermodynamicState "Thermodynamic state"
2689 SpecificEnthalpy h "Specific enthalpy";
2690 Density d "Density";
2691 Temperature T "Temperature";
2692 AbsolutePressure p "Pressure";
2693 end ThermodynamicState;
2694
2695 constant Integer Region = 0 "Region of IF97, if known, zero otherwise";
2696 constant Boolean ph_explicit "True if explicit in pressure and specific enthalpy";
2697 constant Boolean dT_explicit "True if explicit in density and temperature";
2698 constant Boolean pT_explicit "True if explicit in pressure and temperature";
2699
2700 redeclare replaceable model extends BaseProperties(h(stateSelect = if ph_explicit and preferredMediumStates then StateSelect.prefer else StateSelect.default), d(stateSelect = if dT_explicit and preferredMediumStates then StateSelect.prefer else StateSelect.default), T(stateSelect = if (pT_explicit or dT_explicit) and preferredMediumStates then StateSelect.prefer else StateSelect.default), p(stateSelect = if (pT_explicit or ph_explicit) and preferredMediumStates then StateSelect.prefer else StateSelect.default)) "Base properties of water"
2701 Integer phase(min = 0, max = 2, start = 1, fixed = false) "2 for two-phase, 1 for one-phase, 0 if not known";
2702 equation
2703 MM = fluidConstants[1].molarMass;
2704 if Region > 0 then
2705 phase = if Region == 4 then 2 else 1;
2706 elseif smoothModel then
2707 if onePhase then
2708 phase = 1;
2709 if ph_explicit then
2710 assert(h < bubbleEnthalpy(sat) or h > dewEnthalpy(sat) or p > fluidConstants[1].criticalPressure, "With onePhase=true this model may only be called with one-phase states h < hl or h > hv!" + "(p = " + String(p) + ", h = " + String(h) + ")");
2711 else
2712 if dT_explicit then
2713 assert(not (d < bubbleDensity(sat) and d > dewDensity(sat) and T < fluidConstants[1].criticalTemperature), "With onePhase=true this model may only be called with one-phase states d > dl or d < dv!" + "(d = " + String(d) + ", T = " + String(T) + ")");
2714 end if;
2715 end if;
2716 else
2717 phase = 0;
2718 end if;
2719 else
2720 if ph_explicit then
2721 phase = if h < bubbleEnthalpy(sat) or h > dewEnthalpy(sat) or p > fluidConstants[1].criticalPressure then 1 else 2;
2722 elseif dT_explicit then
2723 phase = if not (d < bubbleDensity(sat) and d > dewDensity(sat) and T < fluidConstants[1].criticalTemperature) then 1 else 2;
2724 else
2725 phase = 1;
2726 end if;
2727 end if;
2728 if dT_explicit then
2729 p = pressure_dT(d, T, phase, Region);
2730 h = specificEnthalpy_dT(d, T, phase, Region);
2731 sat.Tsat = T;
2732 sat.psat = saturationPressure(T);
2733 elseif ph_explicit then
2734 d = density_ph(p, h, phase, Region);
2735 T = temperature_ph(p, h, phase, Region);
2736 sat.Tsat = saturationTemperature(p);
2737 sat.psat = p;
2738 else
2739 h = specificEnthalpy_pT(p, T, Region);
2740 d = density_pT(p, T, Region);
2741 sat.psat = p;
2742 sat.Tsat = saturationTemperature(p);
2743 end if;
2744 u = h - p / d;
2745 R = Modelica.Constants.R / fluidConstants[1].molarMass;
2746 h = state.h;
2747 p = state.p;
2748 T = state.T;
2749 d = state.d;
2750 phase = state.phase;
2751 end BaseProperties;
2752
2753 redeclare function density_ph "Computes density as a function of pressure and specific enthalpy"
2754 extends Modelica.Icons.Function;
2755 input AbsolutePressure p "Pressure";
2756 input SpecificEnthalpy h "Specific enthalpy";
2757 input FixedPhase phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
2758 input Integer region = Region "If 0, region is unknown, otherwise known and this input";
2759 output Density d "Density";
2760 algorithm
2761 d := IF97_Utilities.rho_ph(p, h, phase, region);
2762 annotation(Inline = true);
2763 end density_ph;
2764
2765 redeclare function temperature_ph "Computes temperature as a function of pressure and specific enthalpy"
2766 extends Modelica.Icons.Function;
2767 input AbsolutePressure p "Pressure";
2768 input SpecificEnthalpy h "Specific enthalpy";
2769 input FixedPhase phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
2770 input Integer region = Region "If 0, region is unknown, otherwise known and this input";
2771 output Temperature T "Temperature";
2772 algorithm
2773 T := IF97_Utilities.T_ph(p, h, phase, region);
2774 annotation(Inline = true);
2775 end temperature_ph;
2776
2777 redeclare function temperature_ps "Compute temperature from pressure and specific enthalpy"
2778 extends Modelica.Icons.Function;
2779 input AbsolutePressure p "Pressure";
2780 input SpecificEntropy s "Specific entropy";
2781 input FixedPhase phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
2782 input Integer region = Region "If 0, region is unknown, otherwise known and this input";
2783 output Temperature T "Temperature";
2784 algorithm
2785 T := IF97_Utilities.T_ps(p, s, phase, region);
2786 annotation(Inline = true);
2787 end temperature_ps;
2788
2789 redeclare function density_ps "Computes density as a function of pressure and specific enthalpy"
2790 extends Modelica.Icons.Function;
2791 input AbsolutePressure p "Pressure";
2792 input SpecificEntropy s "Specific entropy";
2793 input FixedPhase phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
2794 input Integer region = Region "If 0, region is unknown, otherwise known and this input";
2795 output Density d "Density";
2796 algorithm
2797 d := IF97_Utilities.rho_ps(p, s, phase, region);
2798 annotation(Inline = true);
2799 end density_ps;
2800
2801 redeclare function pressure_dT "Computes pressure as a function of density and temperature"
2802 extends Modelica.Icons.Function;
2803 input Density d "Density";
2804 input Temperature T "Temperature";
2805 input FixedPhase phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
2806 input Integer region = Region "If 0, region is unknown, otherwise known and this input";
2807 output AbsolutePressure p "Pressure";
2808 algorithm
2809 p := IF97_Utilities.p_dT(d, T, phase, region);
2810 annotation(Inline = true);
2811 end pressure_dT;
2812
2813 redeclare function specificEnthalpy_dT "Computes specific enthalpy as a function of density and temperature"
2814 extends Modelica.Icons.Function;
2815 input Density d "Density";
2816 input Temperature T "Temperature";
2817 input FixedPhase phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
2818 input Integer region = Region "If 0, region is unknown, otherwise known and this input";
2819 output SpecificEnthalpy h "Specific enthalpy";
2820 algorithm
2821 h := IF97_Utilities.h_dT(d, T, phase, region);
2822 annotation(Inline = true);
2823 end specificEnthalpy_dT;
2824
2825 redeclare function specificEnthalpy_pT "Computes specific enthalpy as a function of pressure and temperature"
2826 extends Modelica.Icons.Function;
2827 input AbsolutePressure p "Pressure";
2828 input Temperature T "Temperature";
2829 input FixedPhase phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
2830 input Integer region = Region "If 0, region is unknown, otherwise known and this input";
2831 output SpecificEnthalpy h "Specific enthalpy";
2832 algorithm
2833 h := IF97_Utilities.h_pT(p, T, region);
2834 annotation(Inline = true);
2835 end specificEnthalpy_pT;
2836
2837 redeclare function specificEnthalpy_ps "Computes specific enthalpy as a function of pressure and temperature"
2838 extends Modelica.Icons.Function;
2839 input AbsolutePressure p "Pressure";
2840 input SpecificEntropy s "Specific entropy";
2841 input FixedPhase phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
2842 input Integer region = Region "If 0, region is unknown, otherwise known and this input";
2843 output SpecificEnthalpy h "Specific enthalpy";
2844 algorithm
2845 h := IF97_Utilities.h_ps(p, s, phase, region);
2846 annotation(Inline = true);
2847 end specificEnthalpy_ps;
2848
2849 redeclare function density_pT "Computes density as a function of pressure and temperature"
2850 extends Modelica.Icons.Function;
2851 input AbsolutePressure p "Pressure";
2852 input Temperature T "Temperature";
2853 input FixedPhase phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
2854 input Integer region = Region "If 0, region is unknown, otherwise known and this input";
2855 output Density d "Density";
2856 algorithm
2857 d := IF97_Utilities.rho_pT(p, T, region);
2858 annotation(Inline = true);
2859 end density_pT;
2860
2861 redeclare function extends setDewState "Set the thermodynamic state on the dew line"
2862 algorithm
2863 state := ThermodynamicState(phase = phase, p = sat.psat, T = sat.Tsat, h = dewEnthalpy(sat), d = dewDensity(sat));
2864 annotation(Inline = true);
2865 end setDewState;
2866
2867 redeclare function extends setBubbleState "Set the thermodynamic state on the bubble line"
2868 algorithm
2869 state := ThermodynamicState(phase = phase, p = sat.psat, T = sat.Tsat, h = bubbleEnthalpy(sat), d = bubbleDensity(sat));
2870 annotation(Inline = true);
2871 end setBubbleState;
2872
2873 redeclare function extends dynamicViscosity "Dynamic viscosity of water"
2874 algorithm
2875 eta := IF97_Utilities.dynamicViscosity(state.d, state.T, state.p, state.phase);
2876 annotation(Inline = true);
2877 end dynamicViscosity;
2878
2879 redeclare function extends thermalConductivity "Thermal conductivity of water"
2880 algorithm
2881 lambda := IF97_Utilities.thermalConductivity(state.d, state.T, state.p, state.phase);
2882 annotation(Inline = true);
2883 end thermalConductivity;
2884
2885 redeclare function extends surfaceTension "Surface tension in two phase region of water"
2886 algorithm
2887 sigma := IF97_Utilities.surfaceTension(sat.Tsat);
2888 annotation(Inline = true);
2889 end surfaceTension;
2890
2891 redeclare function extends pressure "Return pressure of ideal gas"
2892 algorithm
2893 p := state.p;
2894 annotation(Inline = true);
2895 end pressure;
2896
2897 redeclare function extends temperature "Return temperature of ideal gas"
2898 algorithm
2899 T := state.T;
2900 annotation(Inline = true);
2901 end temperature;
2902
2903 redeclare function extends density "Return density of ideal gas"
2904 algorithm
2905 d := state.d;
2906 annotation(Inline = true);
2907 end density;
2908
2909 redeclare function extends specificEnthalpy "Return specific enthalpy"
2910 extends Modelica.Icons.Function;
2911 algorithm
2912 h := state.h;
2913 annotation(Inline = true);
2914 end specificEnthalpy;
2915
2916 redeclare function extends specificInternalEnergy "Return specific internal energy"
2917 extends Modelica.Icons.Function;
2918 algorithm
2919 u := state.h - state.p / state.d;
2920 annotation(Inline = true);
2921 end specificInternalEnergy;
2922
2923 redeclare function extends specificGibbsEnergy "Return specific Gibbs energy"
2924 extends Modelica.Icons.Function;
2925 algorithm
2926 g := state.h - state.T * specificEntropy(state);
2927 annotation(Inline = true);
2928 end specificGibbsEnergy;
2929
2930 redeclare function extends specificHelmholtzEnergy "Return specific Helmholtz energy"
2931 extends Modelica.Icons.Function;
2932 algorithm
2933 f := state.h - state.p / state.d - state.T * specificEntropy(state);
2934 annotation(Inline = true);
2935 end specificHelmholtzEnergy;
2936
2937 redeclare function extends specificEntropy "Specific entropy of water"
2938 algorithm
2939 s := if dT_explicit then IF97_Utilities.s_dT(state.d, state.T, state.phase, Region) else if pT_explicit then IF97_Utilities.s_pT(state.p, state.T, Region) else IF97_Utilities.s_ph(state.p, state.h, state.phase, Region);
2940 annotation(Inline = true);
2941 end specificEntropy;
2942
2943 redeclare function extends specificHeatCapacityCp "Specific heat capacity at constant pressure of water"
2944 algorithm
2945 cp := if dT_explicit then IF97_Utilities.cp_dT(state.d, state.T, Region) else if pT_explicit then IF97_Utilities.cp_pT(state.p, state.T, Region) else IF97_Utilities.cp_ph(state.p, state.h, Region);
2946 annotation(Inline = true);
2947 end specificHeatCapacityCp;
2948
2949 redeclare function extends specificHeatCapacityCv "Specific heat capacity at constant volume of water"
2950 algorithm
2951 cv := if dT_explicit then IF97_Utilities.cv_dT(state.d, state.T, state.phase, Region) else if pT_explicit then IF97_Utilities.cv_pT(state.p, state.T, Region) else IF97_Utilities.cv_ph(state.p, state.h, state.phase, Region);
2952 annotation(Inline = true);
2953 end specificHeatCapacityCv;
2954
2955 redeclare function extends isentropicExponent "Return isentropic exponent"
2956 algorithm
2957 gamma := if dT_explicit then IF97_Utilities.isentropicExponent_dT(state.d, state.T, state.phase, Region) else if pT_explicit then IF97_Utilities.isentropicExponent_pT(state.p, state.T, Region) else IF97_Utilities.isentropicExponent_ph(state.p, state.h, state.phase, Region);
2958 annotation(Inline = true);
2959 end isentropicExponent;
2960
2961 redeclare function extends isothermalCompressibility "Isothermal compressibility of water"
2962 algorithm
2963 kappa := if dT_explicit then IF97_Utilities.kappa_dT(state.d, state.T, state.phase, Region) else if pT_explicit then IF97_Utilities.kappa_pT(state.p, state.T, Region) else IF97_Utilities.kappa_ph(state.p, state.h, state.phase, Region);
2964 annotation(Inline = true);
2965 end isothermalCompressibility;
2966
2967 redeclare function extends isobaricExpansionCoefficient "Isobaric expansion coefficient of water"
2968 algorithm
2969 beta := if dT_explicit then IF97_Utilities.beta_dT(state.d, state.T, state.phase, Region) else if pT_explicit then IF97_Utilities.beta_pT(state.p, state.T, Region) else IF97_Utilities.beta_ph(state.p, state.h, state.phase, Region);
2970 annotation(Inline = true);
2971 end isobaricExpansionCoefficient;
2972
2973 redeclare function extends velocityOfSound "Return velocity of sound as a function of the thermodynamic state record"
2974 algorithm
2975 a := if dT_explicit then IF97_Utilities.velocityOfSound_dT(state.d, state.T, state.phase, Region) else if pT_explicit then IF97_Utilities.velocityOfSound_pT(state.p, state.T, Region) else IF97_Utilities.velocityOfSound_ph(state.p, state.h, state.phase, Region);
2976 annotation(Inline = true);
2977 end velocityOfSound;
2978
2979 redeclare function extends isentropicEnthalpy "Compute h(s,p)"
2980 algorithm
2981 h_is := IF97_Utilities.isentropicEnthalpy(p_downstream, specificEntropy(refState), 0);
2982 annotation(Inline = true);
2983 end isentropicEnthalpy;
2984
2985 redeclare function extends density_derh_p "Density derivative by specific enthalpy"
2986 algorithm
2987 ddhp := IF97_Utilities.ddhp(state.p, state.h, state.phase, Region);
2988 annotation(Inline = true);
2989 end density_derh_p;
2990
2991 redeclare function extends density_derp_h "Density derivative by pressure"
2992 algorithm
2993 ddph := IF97_Utilities.ddph(state.p, state.h, state.phase, Region);
2994 annotation(Inline = true);
2995 end density_derp_h;
2996
2997 redeclare function extends bubbleEnthalpy "Boiling curve specific enthalpy of water"
2998 algorithm
2999 hl := IF97_Utilities.BaseIF97.Regions.hl_p(sat.psat);
3000 annotation(Inline = true);
3001 end bubbleEnthalpy;
3002
3003 redeclare function extends dewEnthalpy "Dew curve specific enthalpy of water"
3004 algorithm
3005 hv := IF97_Utilities.BaseIF97.Regions.hv_p(sat.psat);
3006 annotation(Inline = true);
3007 end dewEnthalpy;
3008
3009 redeclare function extends bubbleEntropy "Boiling curve specific entropy of water"
3010 algorithm
3011 sl := IF97_Utilities.BaseIF97.Regions.sl_p(sat.psat);
3012 annotation(Inline = true);
3013 end bubbleEntropy;
3014
3015 redeclare function extends dewEntropy "Dew curve specific entropy of water"
3016 algorithm
3017 sv := IF97_Utilities.BaseIF97.Regions.sv_p(sat.psat);
3018 annotation(Inline = true);
3019 end dewEntropy;
3020
3021 redeclare function extends bubbleDensity "Boiling curve specific density of water"
3022 algorithm
3023 dl := if ph_explicit or pT_explicit then IF97_Utilities.BaseIF97.Regions.rhol_p(sat.psat) else IF97_Utilities.BaseIF97.Regions.rhol_T(sat.Tsat);
3024 annotation(Inline = true);
3025 end bubbleDensity;
3026
3027 redeclare function extends dewDensity "Dew curve specific density of water"
3028 algorithm
3029 dv := if ph_explicit or pT_explicit then IF97_Utilities.BaseIF97.Regions.rhov_p(sat.psat) else IF97_Utilities.BaseIF97.Regions.rhov_T(sat.Tsat);
3030 annotation(Inline = true);
3031 end dewDensity;
3032
3033 redeclare function extends saturationTemperature "Saturation temperature of water"
3034 algorithm
3035 T := IF97_Utilities.BaseIF97.Basic.tsat(p);
3036 annotation(Inline = true);
3037 end saturationTemperature;
3038
3039 redeclare function extends saturationTemperature_derp "Derivative of saturation temperature w.r.t. pressure"
3040 algorithm
3041 dTp := IF97_Utilities.BaseIF97.Basic.dtsatofp(p);
3042 annotation(Inline = true);
3043 end saturationTemperature_derp;
3044
3045 redeclare function extends saturationPressure "Saturation pressure of water"
3046 algorithm
3047 p := IF97_Utilities.BaseIF97.Basic.psat(T);
3048 annotation(Inline = true);
3049 end saturationPressure;
3050
3051 redeclare function extends dBubbleDensity_dPressure "Bubble point density derivative"
3052 algorithm
3053 ddldp := IF97_Utilities.BaseIF97.Regions.drhol_dp(sat.psat);
3054 annotation(Inline = true);
3055 end dBubbleDensity_dPressure;
3056
3057 redeclare function extends dDewDensity_dPressure "Dew point density derivative"
3058 algorithm
3059 ddvdp := IF97_Utilities.BaseIF97.Regions.drhov_dp(sat.psat);
3060 annotation(Inline = true);
3061 end dDewDensity_dPressure;
3062
3063 redeclare function extends dBubbleEnthalpy_dPressure "Bubble point specific enthalpy derivative"
3064 algorithm
3065 dhldp := IF97_Utilities.BaseIF97.Regions.dhl_dp(sat.psat);
3066 annotation(Inline = true);
3067 end dBubbleEnthalpy_dPressure;
3068
3069 redeclare function extends dDewEnthalpy_dPressure "Dew point specific enthalpy derivative"
3070 algorithm
3071 dhvdp := IF97_Utilities.BaseIF97.Regions.dhv_dp(sat.psat);
3072 annotation(Inline = true);
3073 end dDewEnthalpy_dPressure;
3074
3075 redeclare function extends setState_dTX "Return thermodynamic state of water as function of d, T, and optional region"
3076 input Integer region = Region "If 0, region is unknown, otherwise known and this input";
3077 algorithm
3078 state := ThermodynamicState(d = d, T = T, phase = if region == 0 then 0 else if region == 4 then 2 else 1, h = specificEnthalpy_dT(d, T, region = region), p = pressure_dT(d, T, region = region));
3079 annotation(Inline = true);
3080 end setState_dTX;
3081
3082 redeclare function extends setState_phX "Return thermodynamic state of water as function of p, h, and optional region"
3083 input Integer region = Region "If 0, region is unknown, otherwise known and this input";
3084 algorithm
3085 state := ThermodynamicState(d = density_ph(p, h, region = region), T = temperature_ph(p, h, region = region), phase = if region == 0 then 0 else if region == 4 then 2 else 1, h = h, p = p);
3086 annotation(Inline = true);
3087 end setState_phX;
3088
3089 redeclare function extends setState_psX "Return thermodynamic state of water as function of p, s, and optional region"
3090 input Integer region = Region "If 0, region is unknown, otherwise known and this input";
3091 algorithm
3092 state := ThermodynamicState(d = density_ps(p, s, region = region), T = temperature_ps(p, s, region = region), phase = if region == 0 then 0 else if region == 4 then 2 else 1, h = specificEnthalpy_ps(p, s, region = region), p = p);
3093 annotation(Inline = true);
3094 end setState_psX;
3095
3096 redeclare function extends setState_pTX "Return thermodynamic state of water as function of p, T, and optional region"
3097 input Integer region = Region "If 0, region is unknown, otherwise known and this input";
3098 algorithm
3099 state := ThermodynamicState(d = density_pT(p, T, region = region), T = T, phase = 1, h = specificEnthalpy_pT(p, T, region = region), p = p);
3100 annotation(Inline = true);
3101 end setState_pTX;
3102
3103 redeclare function extends setSmoothState "Return thermodynamic state so that it smoothly approximates: if x > 0 then state_a else state_b"
3104 import Modelica.Media.Common.smoothStep;
3105 algorithm
3106 state := ThermodynamicState(p = smoothStep(x, state_a.p, state_b.p, x_small), h = smoothStep(x, state_a.h, state_b.h, x_small), d = density_ph(smoothStep(x, state_a.p, state_b.p, x_small), smoothStep(x, state_a.h, state_b.h, x_small)), T = temperature_ph(smoothStep(x, state_a.p, state_b.p, x_small), smoothStep(x, state_a.h, state_b.h, x_small)), phase = 0);
3107 annotation(Inline = true);
3108 end setSmoothState;
3109 end WaterIF97_base;
3110
3111 package IF97_Utilities "Low level and utility computation for high accuracy water properties according to the IAPWS/IF97 standard"
3112 extends Modelica.Icons.UtilitiesPackage;
3113
3114 package BaseIF97 "Modelica Physical Property Model: the new industrial formulation IAPWS-IF97"
3115 extends Modelica.Icons.Package;
3116
3117 record IterationData "Constants for iterations internal to some functions"
3118 extends Modelica.Icons.Record;
3119 constant Integer IMAX = 50 "Maximum number of iterations for inverse functions";
3120 constant Real DELP = 1.0e-6 "Maximum iteration error in pressure, Pa";
3121 constant Real DELS = 1.0e-8 "Maximum iteration error in specific entropy, J/{kg.K}";
3122 constant Real DELH = 1.0e-8 "Maximum iteration error in specific enthalpy, J/kg";
3123 constant Real DELD = 1.0e-8 "Maximum iteration error in density, kg/m^3";
3124 end IterationData;
3125
3126 record data "Constant IF97 data and region limits"
3127 extends Modelica.Icons.Record;
3128 constant SI.SpecificHeatCapacity RH2O = 461.526 "Specific gas constant of water vapour";
3129 constant SI.MolarMass MH2O = 0.01801528 "Molar weight of water";
3130 constant SI.Temperature TSTAR1 = 1386.0 "Normalization temperature for region 1 IF97";
3131 constant SI.Pressure PSTAR1 = 16.53e6 "Normalization pressure for region 1 IF97";
3132 constant SI.Temperature TSTAR2 = 540.0 "Normalization temperature for region 2 IF97";
3133 constant SI.Pressure PSTAR2 = 1.0e6 "Normalization pressure for region 2 IF97";
3134 constant SI.Temperature TSTAR5 = 1000.0 "Normalization temperature for region 5 IF97";
3135 constant SI.Pressure PSTAR5 = 1.0e6 "Normalization pressure for region 5 IF97";
3136 constant SI.SpecificEnthalpy HSTAR1 = 2.5e6 "Normalization specific enthalpy for region 1 IF97";
3137 constant Real IPSTAR = 1.0e-6 "Normalization pressure for inverse function in region 2 IF97";
3138 constant Real IHSTAR = 5.0e-7 "Normalization specific enthalpy for inverse function in region 2 IF97";
3139 constant SI.Temperature TLIMIT1 = 623.15 "Temperature limit between regions 1 and 3";
3140 constant SI.Temperature TLIMIT2 = 1073.15 "Temperature limit between regions 2 and 5";
3141 constant SI.Temperature TLIMIT5 = 2273.15 "Upper temperature limit of 5";
3142 constant SI.Pressure PLIMIT1 = 100.0e6 "Upper pressure limit for regions 1, 2 and 3";
3143 constant SI.Pressure PLIMIT4A = 16.5292e6 "Pressure limit between regions 1 and 2, important for two-phase (region 4)";
3144 constant SI.Pressure PLIMIT5 = 10.0e6 "Upper limit of valid pressure in region 5";
3145 constant SI.Pressure PCRIT = 22064000.0 "The critical pressure";
3146 constant SI.Temperature TCRIT = 647.096 "The critical temperature";
3147 constant SI.Density DCRIT = 322.0 "The critical density";
3148 constant SI.SpecificEntropy SCRIT = 4412.02148223476 "The calculated specific entropy at the critical point";
3149 constant SI.SpecificEnthalpy HCRIT = 2087546.84511715 "The calculated specific enthalpy at the critical point";
3150 constant Real[5] n = array(0.34805185628969e3, -0.11671859879975e1, 0.10192970039326e-2, 0.57254459862746e3, 0.13918839778870e2) "Polynomial coefficients for boundary between regions 2 and 3";
3151 end data;
3152
3153 record triple "Triple point data"
3154 extends Modelica.Icons.Record;
3155 constant SI.Temperature Ttriple = 273.16 "The triple point temperature";
3156 constant SI.Pressure ptriple = 611.657 "The triple point pressure";
3157 constant SI.Density dltriple = 999.792520031617642 "The triple point liquid density";
3158 constant SI.Density dvtriple = 0.485457572477861372e-2 "The triple point vapour density";
3159 end triple;
3160
3161 package Regions "Functions to find the current region for given pairs of input variables"
3162 extends Modelica.Icons.FunctionsPackage;
3163
3164 function boundary23ofT "Boundary function for region boundary between regions 2 and 3 (input temperature)"
3165 extends Modelica.Icons.Function;
3166 input SI.Temperature t "Temperature (K)";
3167 output SI.Pressure p "Pressure";
3168 protected
3169 constant Real[5] n = data.n;
3170 algorithm
3171 p := 1.0e6 * (n[1] + t * (n[2] + t * n[3]));
3172 end boundary23ofT;
3173
3174 function boundary23ofp "Boundary function for region boundary between regions 2 and 3 (input pressure)"
3175 extends Modelica.Icons.Function;
3176 input SI.Pressure p "Pressure";
3177 output SI.Temperature t "Temperature (K)";
3178 protected
3179 constant Real[5] n = data.n;
3180 Real pi "Dimensionless pressure";
3181 algorithm
3182 pi := p / 1.0e6;
3183 assert(p > triple.ptriple, "IF97 medium function boundary23ofp called with too low pressure\n" + "p = " + String(p) + " Pa <= " + String(triple.ptriple) + " Pa (triple point pressure)");
3184 t := n[4] + ((pi - n[5]) / n[3]) ^ 0.5;
3185 end boundary23ofp;
3186
3187 function hlowerofp5 "Explicit lower specific enthalpy limit of region 5 as function of pressure"
3188 extends Modelica.Icons.Function;
3189 input SI.Pressure p "Pressure";
3190 output SI.SpecificEnthalpy h "Specific enthalpy";
3191 protected
3192 Real pi "Dimensionless pressure";
3193 algorithm
3194 pi := p / data.PSTAR5;
3195 assert(p > triple.ptriple, "IF97 medium function hlowerofp5 called with too low pressure\n" + "p = " + String(p) + " Pa <= " + String(triple.ptriple) + " Pa (triple point pressure)");
3196 h := 461526. * (9.01505286876203 + pi * ((-0.00979043490246092) + ((-0.0000203245575263501) + 3.36540214679088e-7 * pi) * pi));
3197 end hlowerofp5;
3198
3199 function hupperofp5 "Explicit upper specific enthalpy limit of region 5 as function of pressure"
3200 extends Modelica.Icons.Function;
3201 input SI.Pressure p "Pressure";
3202 output SI.SpecificEnthalpy h "Specific enthalpy";
3203 protected
3204 Real pi "Dimensionless pressure";
3205 algorithm
3206 pi := p / data.PSTAR5;
3207 assert(p > triple.ptriple, "IF97 medium function hupperofp5 called with too low pressure\n" + "p = " + String(p) + " Pa <= " + String(triple.ptriple) + " Pa (triple point pressure)");
3208 h := 461526. * (15.9838891400332 + pi * ((-0.000489898813722568) + ((-5.01510211858761e-8) + 7.5006972718273e-8 * pi) * pi));
3209 end hupperofp5;
3210
3211 function slowerofp5 "Explicit lower specific entropy limit of region 5 as function of pressure"
3212 extends Modelica.Icons.Function;
3213 input SI.Pressure p "Pressure";
3214 output SI.SpecificEntropy s "Specific entropy";
3215 protected
3216 Real pi "Dimensionless pressure";
3217 algorithm
3218 pi := p / data.PSTAR5;
3219 assert(p > triple.ptriple, "IF97 medium function slowerofp5 called with too low pressure\n" + "p = " + String(p) + " Pa <= " + String(triple.ptriple) + " Pa (triple point pressure)");
3220 s := 461.526 * (18.4296209980112 + pi * ((-0.00730911805860036) + ((-0.0000168348072093888) + 2.09066899426354e-7 * pi) * pi) - Modelica.Math.log(pi));
3221 end slowerofp5;
3222
3223 function supperofp5 "Explicit upper specific entropy limit of region 5 as function of pressure"
3224 extends Modelica.Icons.Function;
3225 input SI.Pressure p "Pressure";
3226 output SI.SpecificEntropy s "Specific entropy";
3227 protected
3228 Real pi "Dimensionless pressure";
3229 algorithm
3230 pi := p / data.PSTAR5;
3231 assert(p > triple.ptriple, "IF97 medium function supperofp5 called with too low pressure\n" + "p = " + String(p) + " Pa <= " + String(triple.ptriple) + " Pa (triple point pressure)");
3232 s := 461.526 * (22.7281531474243 + pi * ((-0.000656650220627603) + ((-1.96109739782049e-8) + 2.19979537113031e-8 * pi) * pi) - Modelica.Math.log(pi));
3233 end supperofp5;
3234
3235 function hlowerofp1 "Explicit lower specific enthalpy limit of region 1 as function of pressure"
3236 extends Modelica.Icons.Function;
3237 input SI.Pressure p "Pressure";
3238 output SI.SpecificEnthalpy h "Specific enthalpy";
3239 protected
3240 Real pi1 "Dimensionless pressure";
3241 Real[3] o "Vector of auxiliary variables";
3242 algorithm
3243 pi1 := 7.1 - p / data.PSTAR1;
3244 assert(p > triple.ptriple, "IF97 medium function hlowerofp1 called with too low pressure\n" + "p = " + String(p) + " Pa <= " + String(triple.ptriple) + " Pa (triple point pressure)");
3245 o[1] := pi1 * pi1;
3246 o[2] := o[1] * o[1];
3247 o[3] := o[2] * o[2];
3248 h := 639675.036 * (0.173379420894777 + pi1 * ((-0.022914084306349) + pi1 * ((-0.00017146768241932) + pi1 * ((-4.18695814670391e-6) + pi1 * ((-2.41630417490008e-7) + pi1 * (1.73545618580828e-11 + o[1] * pi1 * (8.43755552264362e-14 + o[2] * o[3] * pi1 * (5.35429206228374e-35 + o[1] * ((-8.12140581014818e-38) + o[1] * o[2] * ((-1.43870236842915e-44) + pi1 * (1.73894459122923e-45 + ((-7.06381628462585e-47) + 9.64504638626269e-49 * pi1) * pi1)))))))))));
3249 end hlowerofp1;
3250
3251 function hupperofp1 "Explicit upper specific enthalpy limit of region 1 as function of pressure (meets region 4 saturation pressure curve at 623.15 K)"
3252 extends Modelica.Icons.Function;
3253 input SI.Pressure p "Pressure";
3254 output SI.SpecificEnthalpy h "Specific enthalpy";
3255 protected
3256 Real pi1 "Dimensionless pressure";
3257 Real[3] o "Vector of auxiliary variables";
3258 algorithm
3259 pi1 := 7.1 - p / data.PSTAR1;
3260 assert(p > triple.ptriple, "IF97 medium function hupperofp1 called with too low pressure\n" + "p = " + String(p) + " Pa <= " + String(triple.ptriple) + " Pa (triple point pressure)");
3261 o[1] := pi1 * pi1;
3262 o[2] := o[1] * o[1];
3263 o[3] := o[2] * o[2];
3264 h := 639675.036 * (2.42896927729349 + pi1 * ((-0.00141131225285294) + pi1 * (0.00143759406818289 + pi1 * (0.000125338925082983 + pi1 * (0.0000123617764767172 + pi1 * (3.17834967400818e-6 + o[1] * pi1 * (1.46754947271665e-8 + o[2] * o[3] * pi1 * (1.86779322717506e-17 + o[1] * ((-4.18568363667416e-19) + o[1] * o[2] * ((-9.19148577641497e-22) + pi1 * (4.27026404402408e-22 + ((-6.66749357417962e-23) + 3.49930466305574e-24 * pi1) * pi1)))))))))));
3265 end hupperofp1;
3266
3267 function supperofp1 "Explicit upper specific entropy limit of region 1 as function of pressure (meets region 4 saturation pressure curve at 623.15 K)"
3268 extends Modelica.Icons.Function;
3269 input SI.Pressure p "Pressure";
3270 output SI.SpecificEntropy s "Specific entropy";
3271 protected
3272 Real pi1 "Dimensionless pressure";
3273 Real[3] o "Vector of auxiliary variables";
3274 algorithm
3275 pi1 := 7.1 - p / data.PSTAR1;
3276 assert(p > triple.ptriple, "IF97 medium function supperofp1 called with too low pressure\n" + "p = " + String(p) + " Pa <= " + String(triple.ptriple) + " Pa (triple point pressure)");
3277 o[1] := pi1 * pi1;
3278 o[2] := o[1] * o[1];
3279 o[3] := o[2] * o[2];
3280 s := 461.526 * (7.28316418503422 + pi1 * (0.070602197808399 + pi1 * (0.0039229343647356 + pi1 * (0.000313009170788845 + pi1 * (0.0000303619398631619 + pi1 * (7.46739440045781e-6 + o[1] * pi1 * (3.40562176858676e-8 + o[2] * o[3] * pi1 * (4.21886233340801e-17 + o[1] * ((-9.44504571473549e-19) + o[1] * o[2] * ((-2.06859611434475e-21) + pi1 * (9.60758422254987e-22 + ((-1.49967810652241e-22) + 7.86863124555783e-24 * pi1) * pi1)))))))))));
3281 end supperofp1;
3282
3283 function hlowerofp2 "Explicit lower specific enthalpy limit of region 2 as function of pressure (meets region 4 saturation pressure curve at 623.15 K)"
3284 extends Modelica.Icons.Function;
3285 input SI.Pressure p "Pressure";
3286 output SI.SpecificEnthalpy h "Specific enthalpy";
3287 protected
3288 Real pi "Dimensionless pressure";
3289 Real q1 "Auxiliary variable";
3290 Real q2 "Auxiliary variable";
3291 Real[18] o "Vector of auxiliary variables";
3292 algorithm
3293 pi := p / data.PSTAR2;
3294 assert(p > triple.ptriple, "IF97 medium function hlowerofp2 called with too low pressure\n" + "p = " + String(p) + " Pa <= " + String(triple.ptriple) + " Pa (triple point pressure)");
3295 q1 := 572.54459862746 + 31.3220101646784 * ((-13.91883977887) + pi) ^ 0.5;
3296 q2 := (-0.5) + 540. / q1;
3297 o[1] := q1 * q1;
3298 o[2] := o[1] * o[1];
3299 o[3] := o[2] * o[2];
3300 o[4] := pi * pi;
3301 o[5] := o[4] * o[4];
3302 o[6] := q2 * q2;
3303 o[7] := o[6] * o[6];
3304 o[8] := o[6] * o[7];
3305 o[9] := o[5] * o[5];
3306 o[10] := o[7] * o[7];
3307 o[11] := o[9] * o[9];
3308 o[12] := o[10] * o[10];
3309 o[13] := o[12] * o[12];
3310 o[14] := o[7] * q2;
3311 o[15] := o[6] * q2;
3312 o[16] := o[10] * o[6];
3313 o[17] := o[13] * o[6];
3314 o[18] := o[13] * o[6] * q2;
3315 h := (4.63697573303507e9 + 3.74686560065793 * o[2] + 3.57966647812489e-6 * o[1] * o[2] + 2.81881548488163e-13 * o[3] - 7.64652332452145e7 * q1 - 0.00450789338787835 * o[2] * q1 - 1.55131504410292e-9 * o[1] * o[2] * q1 + o[1] * (2.51383707870341e6 - 4.78198198764471e6 * o[10] * o[11] * o[12] * o[13] * o[4] + 49.9651389369988 * o[11] * o[12] * o[13] * o[4] * o[5] * o[7] + o[15] * o[4] * (1.03746636552761e-13 - 0.00349547959376899 * o[16] - 2.55074501962569e-7 * o[8]) * o[9] + ((-242662.235426958 * o[10] * o[12]) - 3.46022402653609 * o[16]) * o[4] * o[5] * pi + o[4] * (0.109336249381227 - 2248.08924686956 * o[14] - 354742.725841972 * o[17] - 24.1331193696374 * o[6]) * pi - 3.09081828396912e-19 * o[11] * o[12] * o[5] * o[7] * pi - 1.24107527851371e-8 * o[11] * o[13] * o[4] * o[5] * o[6] * o[7] * pi + 3.99891272904219 * o[5] * o[8] * pi + 0.0641817365250892 * o[10] * o[7] * o[9] * pi + pi * ((-4444.87643334512) - 75253.6156722047 * o[14] - 43051.9020511789 * o[6] - 22926.6247146068 * q2) + o[4] * ((-8.23252840892034) - 3927.0508365636 * o[15] - 239.325789467604 * o[18] - 76407.3727417716 * o[8] - 94.4508644545118 * q2) + 0.360567666582363 * o[5] * ((-0.0161221195808321) + q2) * (0.0338039844460968 + q2) + o[11] * ((-0.000584580992538624 * o[10] * o[12] * o[7]) + 1.33248030241755e6 * o[12] * o[13] * q2) + o[9] * ((-7.38502736990986e7 * o[18]) + 0.0000224425477627799 * o[6] * o[7] * q2) + o[4] * o[5] * ((-2.08438767026518e8 * o[17]) - 0.0000124971648677697 * o[6] - 8442.30378348203 * o[10] * o[6] * o[7] * q2) + o[11] * o[9] * (4.73594929247646e-22 * o[10] * o[12] * q2 - 13.6411358215175 * o[10] * o[12] * o[13] * q2 + 5.52427169406836e-10 * o[13] * o[6] * o[7] * q2) + o[11] * o[5] * (2.67174673301715e-6 * o[17] + 4.44545133805865e-18 * o[12] * o[6] * q2 - 50.2465185106411 * o[10] * o[13] * o[6] * o[7] * q2))) / o[1];
3316 end hlowerofp2;
3317
3318 function hupperofp2 "Explicit upper specific enthalpy limit of region 2 as function of pressure"
3319 extends Modelica.Icons.Function;
3320 input SI.Pressure p "Pressure";
3321 output SI.SpecificEnthalpy h "Specific enthalpy";
3322 protected
3323 Real pi "Dimensionless pressure";
3324 Real[2] o "Vector of auxiliary variables";
3325 algorithm
3326 pi := p / data.PSTAR2;
3327 assert(p > triple.ptriple, "IF97 medium function hupperofp2 called with too low pressure\n" + "p = " + String(p) + " Pa <= " + String(triple.ptriple) + " Pa (triple point pressure)");
3328 o[1] := pi * pi;
3329 o[2] := o[1] * o[1] * o[1];
3330 h := 4.16066337647071e6 + pi * ((-4518.48617188327) + pi * ((-8.53409968320258) + pi * (0.109090430596056 + pi * ((-0.000172486052272327) + pi * (4.2261295097284e-15 + pi * ((-1.27295130636232e-10) + pi * ((-3.79407294691742e-25) + pi * (7.56960433802525e-23 + pi * (7.16825117265975e-32 + pi * (3.37267475986401e-21 + ((-7.5656940729795e-74) + o[1] * ((-8.00969737237617e-134) + (1.6746290980312e-65 + pi * ((-3.71600586812966e-69) + pi * (8.06630589170884e-129 + ((-1.76117969553159e-103) + 1.88543121025106e-84 * pi) * pi))) * o[1])) * o[2]))))))))));
3331 end hupperofp2;
3332
3333 function slowerofp2 "Explicit lower specific entropy limit of region 2 as function of pressure (meets region 4 saturation pressure curve at 623.15 K)"
3334 extends Modelica.Icons.Function;
3335 input SI.Pressure p "Pressure";
3336 output SI.SpecificEntropy s "Specific entropy";
3337 protected
3338 Real pi "Dimensionless pressure";
3339 Real q1 "Auxiliary variable";
3340 Real q2 "Auxiliary variable";
3341 Real[40] o "Vector of auxiliary variables";
3342 algorithm
3343 pi := p / data.PSTAR2;
3344 assert(p > triple.ptriple, "IF97 medium function slowerofp2 called with too low pressure\n" + "p = " + String(p) + " Pa <= " + String(triple.ptriple) + " Pa (triple point pressure)");
3345 q1 := 572.54459862746 + 31.3220101646784 * ((-13.91883977887) + pi) ^ 0.5;
3346 q2 := (-0.5) + 540.0 / q1;
3347 o[1] := pi * pi;
3348 o[2] := o[1] * pi;
3349 o[3] := o[1] * o[1];
3350 o[4] := o[1] * o[3] * pi;
3351 o[5] := q1 * q1;
3352 o[6] := o[5] * q1;
3353 o[7] := 1 / o[5];
3354 o[8] := 1 / q1;
3355 o[9] := o[5] * o[5];
3356 o[10] := o[9] * q1;
3357 o[11] := q2 * q2;
3358 o[12] := o[11] * q2;
3359 o[13] := o[1] * o[3];
3360 o[14] := o[11] * o[11];
3361 o[15] := o[3] * o[3];
3362 o[16] := o[1] * o[15];
3363 o[17] := o[11] * o[14];
3364 o[18] := o[11] * o[14] * q2;
3365 o[19] := o[3] * pi;
3366 o[20] := o[14] * o[14];
3367 o[21] := o[11] * o[20];
3368 o[22] := o[15] * pi;
3369 o[23] := o[14] * o[20] * q2;
3370 o[24] := o[20] * o[20];
3371 o[25] := o[15] * o[15];
3372 o[26] := o[25] * o[3];
3373 o[27] := o[14] * o[24];
3374 o[28] := o[25] * o[3] * pi;
3375 o[29] := o[20] * o[24] * q2;
3376 o[30] := o[15] * o[25];
3377 o[31] := o[24] * o[24];
3378 o[32] := o[11] * o[31] * q2;
3379 o[33] := o[14] * o[31];
3380 o[34] := o[1] * o[25] * o[3] * pi;
3381 o[35] := o[11] * o[14] * o[31] * q2;
3382 o[36] := o[1] * o[25] * o[3];
3383 o[37] := o[1] * o[25];
3384 o[38] := o[20] * o[24] * o[31] * q2;
3385 o[39] := o[14] * q2;
3386 o[40] := o[11] * o[31];
3387 s := 461.526 * (9.692768600217 + 1.22151969114703e-16 * o[10] + 0.00018948987516315 * o[1] * o[11] + 1.6714766451061e-11 * o[12] * o[13] + 0.0039392777243355 * o[1] * o[14] - 1.0406965210174e-19 * o[14] * o[16] + 0.043797295650573 * o[1] * o[18] - 2.2922076337661e-6 * o[18] * o[19] - 2.0481737692309e-8 * o[2] + 0.00003227767723857 * o[12] * o[2] + 0.0015033924542148 * o[17] * o[2] - 1.1256211360459e-11 * o[15] * o[20] + 1.0018179379511e-9 * o[11] * o[14] * o[16] * o[20] + 1.0234747095929e-13 * o[16] * o[21] - 1.9809712802088e-8 * o[22] * o[23] + 0.0021171472321355 * o[13] * o[24] - 8.9185845355421e-25 * o[26] * o[27] - 1.2790717852285e-8 * o[11] * o[3] - 4.8225372718507e-7 * o[12] * o[3] - 7.3087610595061e-29 * o[11] * o[20] * o[24] * o[30] - 0.10693031879409 * o[11] * o[24] * o[25] * o[31] + 4.2002467698208e-6 * o[24] * o[26] * o[31] - 5.5414715350778e-17 * o[20] * o[30] * o[31] + 9.436970724121e-7 * o[11] * o[20] * o[24] * o[30] * o[31] + 23.895741934104 * o[13] * o[32] + 0.040668253562649 * o[2] * o[32] - 3.0629316876232e-13 * o[26] * o[32] + 0.000026674547914087 * o[1] * o[33] + 8.2311340897998 * o[15] * o[33] + 1.2768608934681e-15 * o[34] * o[35] + 0.33662250574171 * o[37] * o[38] + 5.905956432427e-18 * o[4] + 0.038946842435739 * o[29] * o[4] - 4.88368302964335e-6 * o[5] - 3.34901734177133e6 / o[6] + 2.58538448402683e-9 * o[6] + 82839.5726841115 * o[7] - 5446.7940672972 * o[8] - 8.40318337484194e-13 * o[9] + 0.0017731742473213 * pi + 0.045996013696365 * o[11] * pi + 0.057581259083432 * o[12] * pi + 0.05032527872793 * o[17] * pi + o[8] * pi * (9.63082563787332 - 0.008917431146179 * q1) + 0.00811842799898148 * q1 + 0.000033032641670203 * o[1] * q2 - 4.3870667284435e-7 * o[2] * q2 + 8.0882908646985e-11 * o[14] * o[20] * o[24] * o[25] * q2 + 5.9056029685639e-26 * o[14] * o[24] * o[28] * q2 + 7.8847309559367e-10 * o[3] * q2 - 3.7826947613457e-6 * o[14] * o[24] * o[31] * o[36] * q2 + 1.2621808899101e-6 * o[11] * o[20] * o[4] * q2 + 540. * o[8] * (10.08665568018 - 0.000033032641670203 * o[1] - 6.2245802776607e-15 * o[10] - 0.015757110897342 * o[1] * o[12] - 5.0144299353183e-11 * o[11] * o[13] + 4.1627860840696e-19 * o[12] * o[16] - 0.306581069554011 * o[1] * o[17] + 9.0049690883672e-11 * o[15] * o[18] + 0.0000160454534363627 * o[17] * o[19] + 4.3870667284435e-7 * o[2] - 0.00009683303171571 * o[11] * o[2] + 2.57526266427144e-7 * o[14] * o[20] * o[22] - 1.40254511313154e-8 * o[16] * o[23] - 2.34560435076256e-9 * o[14] * o[20] * o[24] * o[25] - 1.24017662339842e-24 * o[27] * o[28] - 7.8847309559367e-10 * o[3] + 1.44676118155521e-6 * o[11] * o[3] + 1.90027787547159e-27 * o[29] * o[30] - 0.000960283724907132 * o[1] * o[32] - 296.320827232793 * o[15] * o[32] - 4.97975748452559e-14 * o[11] * o[14] * o[31] * o[34] + 2.21658861403112e-15 * o[30] * o[35] + 0.000200482822351322 * o[14] * o[24] * o[31] * o[36] - 19.1874828272775 * o[20] * o[24] * o[31] * o[37] - 0.0000547344301999018 * o[30] * o[38] - 0.0090203547252888 * o[2] * o[39] - 0.0000138839897890111 * o[21] * o[4] - 0.973671060893475 * o[20] * o[24] * o[4] - 836.35096769364 * o[13] * o[40] - 1.42338887469272 * o[2] * o[40] + 1.07202609066812e-11 * o[26] * o[40] + 0.0000150341259240398 * o[5] - 1.8087714924605e-8 * o[6] + 18605.6518987296 * o[7] - 306.813232163376 * o[8] + 1.43632471334824e-11 * o[9] + 1.13103675106207e-18 * o[5] * o[9] - 0.017834862292358 * pi - 0.172743777250296 * o[11] * pi - 0.30195167236758 * o[39] * pi + o[8] * pi * ((-49.6756947920742) + 0.045996013696365 * q1) - 0.0003789797503263 * o[1] * q2 - 0.033874355714168 * o[11] * o[13] * o[14] * o[20] * q2 - 1.0234747095929e-12 * o[16] * o[20] * q2 + 1.78371690710842e-23 * o[11] * o[24] * o[26] * q2 + 2.558143570457e-8 * o[3] * q2 + 5.3465159397045 * o[24] * o[25] * o[31] * q2 - 0.000201611844951398 * o[11] * o[14] * o[20] * o[26] * o[31] * q2) - Modelica.Math.log(pi));
3388 end slowerofp2;
3389
3390 function supperofp2 "Explicit upper specific entropy limit of region 2 as function of pressure"
3391 extends Modelica.Icons.Function;
3392 input SI.Pressure p "Pressure";
3393 output SI.SpecificEntropy s "Specific entropy";
3394 protected
3395 Real pi "Dimensionless pressure";
3396 Real[2] o "Vector of auxiliary variables";
3397 algorithm
3398 pi := p / data.PSTAR2;
3399 assert(p > triple.ptriple, "IF97 medium function supperofp2 called with too low pressure\n" + "p = " + String(p) + " Pa <= " + String(triple.ptriple) + " Pa (triple point pressure)");
3400 o[1] := pi * pi;
3401 o[2] := o[1] * o[1] * o[1];
3402 s := 8505.73409708683 - 461.526 * Modelica.Math.log(pi) + pi * ((-3.36563543302584) + pi * ((-0.00790283552165338) + pi * (0.0000915558349202221 + pi * ((-1.59634706513e-7) + pi * (3.93449217595397e-18 + pi * ((-1.18367426347994e-13) + pi * (2.72575244843195e-15 + pi * (7.04803892603536e-26 + pi * (6.67637687381772e-35 + pi * (3.1377970315132e-24 + ((-7.04844558482265e-77) + o[1] * ((-7.46289531275314e-137) + (1.55998511254305e-68 + pi * ((-3.46166288915497e-72) + pi * (7.51557618628583e-132 + ((-1.64086406733212e-106) + 1.75648443097063e-87 * pi) * pi))) * o[1])) * o[2] * o[2]))))))))));
3403 end supperofp2;
3404
3405 function d1n "Density in region 1 as function of p and T"
3406 extends Modelica.Icons.Function;
3407 input SI.Pressure p "Pressure";
3408 input SI.Temperature T "Temperature (K)";
3409 output SI.Density d "Density";
3410 protected
3411 Real pi "Dimensionless pressure";
3412 Real pi1 "Dimensionless pressure";
3413 Real tau "Dimensionless temperature";
3414 Real tau1 "Dimensionless temperature";
3415 Real gpi "Dimensionless Gibbs-derivative w.r.t. pi";
3416 Real[11] o "Auxiliary variables";
3417 algorithm
3418 pi := p / data.PSTAR1;
3419 tau := data.TSTAR1 / T;
3420 pi1 := 7.1 - pi;
3421 tau1 := tau - 1.222;
3422 o[1] := tau1 * tau1;
3423 o[2] := o[1] * o[1];
3424 o[3] := o[2] * o[2];
3425 o[4] := o[1] * o[2];
3426 o[5] := o[1] * tau1;
3427 o[6] := o[2] * tau1;
3428 o[7] := pi1 * pi1;
3429 o[8] := o[7] * o[7];
3430 o[9] := o[8] * o[8];
3431 o[10] := o[3] * o[3];
3432 o[11] := o[10] * o[10];
3433 gpi := pi1 * (pi1 * ((0.000095038934535162 + o[2] * (8.4812393955936e-6 + 2.55615384360309e-9 * o[4])) / o[2] + pi1 * ((8.9701127632e-6 + (2.60684891582404e-6 + 5.7366919751696e-13 * o[2] * o[3]) * o[5]) / o[6] + pi1 * (2.02584984300585e-6 / o[3] + o[7] * pi1 * (o[8] * o[9] * pi1 * (o[7] * (o[7] * o[8] * ((-7.63737668221055e-22 / (o[1] * o[11] * o[2])) + pi1 * (pi1 * ((-5.65070932023524e-23 / (o[11] * o[3])) + 2.99318679335866e-24 * pi1 / (o[11] * o[3] * tau1)) + 3.5842867920213e-22 / (o[1] * o[11] * o[2] * tau1))) - 3.33001080055983e-19 / (o[1] * o[10] * o[2] * o[3] * tau1)) + 1.44400475720615e-17 / (o[10] * o[2] * o[3] * tau1)) + (1.01874413933128e-8 + 1.39398969845072e-9 * o[6]) / (o[1] * o[3] * tau1))))) + (0.00094368642146534 + o[5] * (0.00060003561586052 + ((-0.000095322787813974) + o[1] * (8.8283690661692e-6 + 1.45389992595188e-15 * o[1] * o[2] * o[3])) * tau1)) / o[5]) + ((-0.00028319080123804) + o[1] * (0.00060706301565874 + o[4] * (0.018990068218419 + tau1 * (0.032529748770505 + (0.021841717175414 + 0.00005283835796993 * o[1]) * tau1)))) / (o[3] * tau1);
3434 d := p / (data.RH2O * T * pi * gpi);
3435 end d1n;
3436
3437 function d2n "Density in region 2 as function of p and T"
3438 extends Modelica.Icons.Function;
3439 input SI.Pressure p "Pressure";
3440 input SI.Temperature T "Temperature (K)";
3441 output SI.Density d "Density";
3442 protected
3443 Real pi "Dimensionless pressure";
3444 Real tau "Dimensionless temperature";
3445 Real tau2 "Dimensionless temperature";
3446 Real gpi "Dimensionless Gibbs-derivative w.r.t. pi";
3447 Real[12] o "Auxiliary variables";
3448 algorithm
3449 pi := p / data.PSTAR2;
3450 tau := data.TSTAR2 / T;
3451 tau2 := tau - 0.5;
3452 o[1] := tau2 * tau2;
3453 o[2] := o[1] * tau2;
3454 o[3] := o[1] * o[1];
3455 o[4] := o[3] * o[3];
3456 o[5] := o[4] * o[4];
3457 o[6] := o[3] * o[4] * o[5] * tau2;
3458 o[7] := o[3] * o[4] * tau2;
3459 o[8] := o[1] * o[3] * o[4];
3460 o[9] := pi * pi;
3461 o[10] := o[9] * o[9];
3462 o[11] := o[3] * o[5] * tau2;
3463 o[12] := o[5] * o[5];
3464 gpi := (1. + pi * ((-0.0017731742473213) + tau2 * ((-0.017834862292358) + tau2 * ((-0.045996013696365) + ((-0.057581259083432) - 0.05032527872793 * o[2]) * tau2)) + pi * (tau2 * ((-0.000066065283340406) + ((-0.0003789797503263) + o[1] * ((-0.007878555448671) + o[2] * ((-0.087594591301146) - 0.000053349095828174 * o[6]))) * tau2) + pi * (6.1445213076927e-8 + (1.31612001853305e-6 + o[1] * ((-0.00009683303171571) + o[2] * ((-0.0045101773626444) - 0.122004760687947 * o[6]))) * tau2 + pi * (tau2 * ((-3.15389238237468e-9) + (5.116287140914e-8 + 1.92901490874028e-6 * tau2) * tau2) + pi * (0.0000114610381688305 * o[1] * o[3] * tau2 + pi * (o[2] * ((-1.00288598706366e-10) + o[7] * ((-0.012702883392813) - 143.374451604624 * o[1] * o[5] * tau2)) + pi * ((-4.1341695026989e-17) + o[1] * o[4] * ((-8.8352662293707e-6) - 0.272627897050173 * o[8]) * tau2 + pi * (o[4] * (9.0049690883672e-11 - 65.8490727183984 * o[3] * o[4] * o[5]) + pi * (1.78287415218792e-7 * o[7] + pi * (o[3] * (1.0406965210174e-18 + o[1] * ((-1.0234747095929e-12) - 1.0018179379511e-8 * o[3]) * o[3]) + o[10] * o[9] * (((-1.29412653835176e-9) + 1.71088510070544 * o[11]) * o[6] + o[9] * ((-6.05920510335078 * o[12] * o[4] * o[5] * tau2) + o[9] * (o[3] * o[5] * (1.78371690710842e-23 + o[1] * o[3] * o[4] * (6.1258633752464e-12 - 0.000084004935396416 * o[7]) * tau2) + pi * ((-1.24017662339842e-24 * o[11]) + pi * (0.0000832192847496054 * o[12] * o[3] * o[5] * tau2 + pi * (o[1] * o[4] * o[5] * (1.75410265428146e-27 + (1.32995316841867e-15 - 0.0000226487297378904 * o[1] * o[5]) * o[8]) * pi - 2.93678005497663e-14 * o[1] * o[12] * o[3] * tau2))))))))))))))))) / pi;
3465 d := p / (data.RH2O * T * pi * gpi);
3466 end d2n;
3467
3468 function hl_p_R4b "Explicit approximation of liquid specific enthalpy on the boundary between regions 4 and 3"
3469 extends Modelica.Icons.Function;
3470 input SI.Pressure p "Pressure";
3471 output SI.SpecificEnthalpy h "Specific enthalpy";
3472 protected
3473 Real x "Auxiliary variable";
3474 algorithm
3475 x := Modelica.Math.acos(p / data.PCRIT);
3476 h := (1 + x * ((-0.4945586958175176) + x * (1.346800016564904 + x * ((-3.889388153209752) + x * (6.679385472887931 + x * ((-6.75820241066552) + x * (3.558919744656498 + ((-0.7179818554978939) - 0.0001152032945617821 * x) * x))))))) * data.HCRIT;
3477 end hl_p_R4b;
3478
3479 function hv_p_R4b "Explicit approximation of vapour specific enthalpy on the boundary between regions 4 and 3"
3480 extends Modelica.Icons.Function;
3481 input SI.Pressure p "Pressure";
3482 output SI.SpecificEnthalpy h "Specific enthalpy";
3483 protected
3484 Real x "Auxiliary variable";
3485 algorithm
3486 x := Modelica.Math.acos(p / data.PCRIT);
3487 h := (1 + x * (0.4880153718655694 + x * (0.2079670746250689 + x * ((-6.084122698421623) + x * (25.08887602293532 + x * ((-48.38215180269516) + x * (45.66489164833212 + ((-16.98555442961553) + 0.0006616936460057691 * x) * x))))))) * data.HCRIT;
3488 end hv_p_R4b;
3489
3490 function sl_p_R4b "Explicit approximation of liquid specific entropy on the boundary between regions 4 and 3"
3491 extends Modelica.Icons.Function;
3492 input SI.Pressure p "Pressure";
3493 output SI.SpecificEntropy s "Specific entropy";
3494 protected
3495 Real x "Auxiliary variable";
3496 algorithm
3497 x := Modelica.Math.acos(p / data.PCRIT);
3498 s := (1 + x * ((-0.36160692245648063) + x * (0.9962778630486647 + x * ((-2.8595548144171103) + x * (4.906301159555333 + x * ((-4.974092309614206) + x * (2.6249651699204457 + ((-0.5319954375299023) - 0.00008064497431880644 * x) * x))))))) * data.SCRIT;
3499 end sl_p_R4b;
3500
3501 function sv_p_R4b "Explicit approximation of vapour specific entropy on the boundary between regions 4 and 3"
3502 extends Modelica.Icons.Function;
3503 input SI.Pressure p "Pressure";
3504 output SI.SpecificEntropy s;
3505 protected
3506 Real x "Auxiliary variable";
3507 algorithm
3508 x := Modelica.Math.acos(p / data.PCRIT);
3509 s := (1 + x * (0.35682641826674344 + x * (0.1642457027815487 + x * ((-4.425350377422446) + x * (18.324477859983133 + x * ((-35.338631625948665) + x * (33.36181025816282 + ((-12.408711490585757) + 0.0004810049834109226 * x) * x))))))) * data.SCRIT;
3510 end sv_p_R4b;
3511
3512 function rhol_p_R4b "Explicit approximation of liquid density on the boundary between regions 4 and 3"
3513 extends Modelica.Icons.Function;
3514 input SI.Pressure p "Pressure";
3515 output SI.Density dl "Liquid density";
3516 protected
3517 Real x "Auxiliary variable";
3518 algorithm
3519 if p < data.PCRIT then
3520 x := Modelica.Math.acos(p / data.PCRIT);
3521 dl := (1 + x * (1.903224079094824 + x * ((-2.5314861802401123) + x * ((-8.191449323843552) + x * (94.34196116778385 + x * ((-369.3676833623383) + x * (796.6627910598293 + x * ((-994.5385383600702) + x * (673.2581177021598 + ((-191.43077336405156) + 0.00052536560808895 * x) * x))))))))) * data.DCRIT;
3522 else
3523 dl := data.DCRIT;
3524 end if;
3525 end rhol_p_R4b;
3526
3527 function rhov_p_R4b "Explicit approximation of vapour density on the boundary between regions 4 and 2"
3528 extends Modelica.Icons.Function;
3529 input SI.Pressure p "Pressure";
3530 output SI.Density dv "Vapour density";
3531 protected
3532 Real x "Auxiliary variable";
3533 algorithm
3534 if p < data.PCRIT then
3535 x := Modelica.Math.acos(p / data.PCRIT);
3536 dv := (1 + x * ((-1.8463850803362596) + x * ((-1.1447872718878493) + x * (59.18702203076563 + x * ((-403.5391431811611) + x * (1437.2007245332388 + x * ((-3015.853540307519) + x * (3740.5790348670057 + x * ((-2537.375817253895) + (725.8761975803782 - 0.0011151111658332337 * x) * x))))))))) * data.DCRIT;
3537 else
3538 dv := data.DCRIT;
3539 end if;
3540 end rhov_p_R4b;
3541
3542 function boilingcurve_p "Properties on the boiling curve"
3543 extends Modelica.Icons.Function;
3544 input SI.Pressure p "Pressure";
3545 output Common.IF97PhaseBoundaryProperties bpro "Property record";
3546 protected
3547 Common.GibbsDerivs g "Dimensionless Gibbs function and derivatives";
3548 Common.HelmholtzDerivs f "Dimensionless Helmholtz function and derivatives";
3549 SI.Pressure plim = min(p, data.PCRIT - 1e-7) "Pressure limited to critical pressure - epsilon";
3550 algorithm
3551 bpro.R := data.RH2O;
3552 bpro.T := Basic.tsat(plim);
3553 bpro.dpT := Basic.dptofT(bpro.T);
3554 bpro.region3boundary := bpro.T > data.TLIMIT1;
3555 if not bpro.region3boundary then
3556 g := Basic.g1(p, bpro.T);
3557 bpro.d := p / (bpro.R * bpro.T * g.pi * g.gpi);
3558 bpro.h := if p > plim then data.HCRIT else bpro.R * bpro.T * g.tau * g.gtau;
3559 bpro.s := g.R * (g.tau * g.gtau - g.g);
3560 bpro.cp := -bpro.R * g.tau * g.tau * g.gtautau;
3561 bpro.vt := bpro.R / p * (g.pi * g.gpi - g.tau * g.pi * g.gtaupi);
3562 bpro.vp := bpro.R * bpro.T / (p * p) * g.pi * g.pi * g.gpipi;
3563 bpro.pt := -p / bpro.T * (g.gpi - g.tau * g.gtaupi) / (g.gpipi * g.pi);
3564 bpro.pd := -bpro.R * bpro.T * g.gpi * g.gpi / g.gpipi;
3565 else
3566 bpro.d := rhol_p_R4b(plim);
3567 f := Basic.f3(bpro.d, bpro.T);
3568 bpro.h := hl_p_R4b(plim);
3569 bpro.s := f.R * (f.tau * f.ftau - f.f);
3570 bpro.cv := bpro.R * (-f.tau * f.tau * f.ftautau);
3571 bpro.pt := bpro.R * bpro.d * f.delta * (f.fdelta - f.tau * f.fdeltatau);
3572 bpro.pd := bpro.R * bpro.T * f.delta * (2.0 * f.fdelta + f.delta * f.fdeltadelta);
3573 end if;
3574 end boilingcurve_p;
3575
3576 function dewcurve_p "Properties on the dew curve"
3577 extends Modelica.Icons.Function;
3578 input SI.Pressure p "Pressure";
3579 output Common.IF97PhaseBoundaryProperties bpro "Property record";
3580 protected
3581 Common.GibbsDerivs g "Dimensionless Gibbs function and derivatives";
3582 Common.HelmholtzDerivs f "Dimensionless Helmholtz function and derivatives";
3583 SI.Pressure plim = min(p, data.PCRIT - 1e-7) "Pressure limited to critical pressure - epsilon";
3584 algorithm
3585 bpro.R := data.RH2O;
3586 bpro.T := Basic.tsat(plim);
3587 bpro.dpT := Basic.dptofT(bpro.T);
3588 bpro.region3boundary := bpro.T > data.TLIMIT1;
3589 if not bpro.region3boundary then
3590 g := Basic.g2(p, bpro.T);
3591 bpro.d := p / (bpro.R * bpro.T * g.pi * g.gpi);
3592 bpro.h := if p > plim then data.HCRIT else bpro.R * bpro.T * g.tau * g.gtau;
3593 bpro.s := g.R * (g.tau * g.gtau - g.g);
3594 bpro.cp := -bpro.R * g.tau * g.tau * g.gtautau;
3595 bpro.vt := bpro.R / p * (g.pi * g.gpi - g.tau * g.pi * g.gtaupi);
3596 bpro.vp := bpro.R * bpro.T / (p * p) * g.pi * g.pi * g.gpipi;
3597 bpro.pt := -p / bpro.T * (g.gpi - g.tau * g.gtaupi) / (g.gpipi * g.pi);
3598 bpro.pd := -bpro.R * bpro.T * g.gpi * g.gpi / g.gpipi;
3599 else
3600 bpro.d := rhov_p_R4b(plim);
3601 f := Basic.f3(bpro.d, bpro.T);
3602 bpro.h := hv_p_R4b(plim);
3603 bpro.s := f.R * (f.tau * f.ftau - f.f);
3604 bpro.cv := bpro.R * (-f.tau * f.tau * f.ftautau);
3605 bpro.pt := bpro.R * bpro.d * f.delta * (f.fdelta - f.tau * f.fdeltatau);
3606 bpro.pd := bpro.R * bpro.T * f.delta * (2.0 * f.fdelta + f.delta * f.fdeltadelta);
3607 end if;
3608 end dewcurve_p;
3609
3610 function hvl_p
3611 extends Modelica.Icons.Function;
3612 input SI.Pressure p "Pressure";
3613 input Common.IF97PhaseBoundaryProperties bpro "Property record";
3614 output SI.SpecificEnthalpy h "Specific enthalpy";
3615 algorithm
3616 h := bpro.h;
3617 annotation(derivative(noDerivative = bpro) = hvl_p_der, Inline = false, LateInline = true);
3618 end hvl_p;
3619
3620 function hl_p "Liquid specific enthalpy on the boundary between regions 4 and 3 or 1"
3621 extends Modelica.Icons.Function;
3622 input SI.Pressure p "Pressure";
3623 output SI.SpecificEnthalpy h "Specific enthalpy";
3624 algorithm
3625 h := hvl_p(p, boilingcurve_p(p));
3626 annotation(Inline = true);
3627 end hl_p;
3628
3629 function hv_p "Vapour specific enthalpy on the boundary between regions 4 and 3 or 2"
3630 extends Modelica.Icons.Function;
3631 input SI.Pressure p "Pressure";
3632 output SI.SpecificEnthalpy h "Specific enthalpy";
3633 algorithm
3634 h := hvl_p(p, dewcurve_p(p));
3635 annotation(Inline = true);
3636 end hv_p;
3637
3638 function hvl_p_der "Derivative function for the specific enthalpy along the phase boundary"
3639 extends Modelica.Icons.Function;
3640 input SI.Pressure p "Pressure";
3641 input Common.IF97PhaseBoundaryProperties bpro "Property record";
3642 input Real p_der "Derivative of pressure";
3643 output Real h_der "Time derivative of specific enthalpy along the phase boundary";
3644 algorithm
3645 if bpro.region3boundary then
3646 h_der := ((bpro.d * bpro.pd - bpro.T * bpro.pt) * p_der + (bpro.T * bpro.pt * bpro.pt + bpro.d * bpro.d * bpro.pd * bpro.cv) / bpro.dpT * p_der) / (bpro.pd * bpro.d * bpro.d);
3647 else
3648 h_der := (1 / bpro.d - bpro.T * bpro.vt) * p_der + bpro.cp / bpro.dpT * p_der;
3649 end if;
3650 annotation(Inline = true);
3651 end hvl_p_der;
3652
3653 function rhovl_p
3654 extends Modelica.Icons.Function;
3655 input SI.Pressure p "Pressure";
3656 input Common.IF97PhaseBoundaryProperties bpro "Property record";
3657 output SI.Density rho "Density";
3658 algorithm
3659 rho := bpro.d;
3660 annotation(derivative(noDerivative = bpro) = rhovl_p_der, Inline = false, LateInline = true);
3661 end rhovl_p;
3662
3663 function rhol_p "Density of saturated water"
3664 extends Modelica.Icons.Function;
3665 input SI.Pressure p "Saturation pressure";
3666 output SI.Density rho "Density of steam at the condensation point";
3667 algorithm
3668 rho := rhovl_p(p, boilingcurve_p(p));
3669 annotation(Inline = true);
3670 end rhol_p;
3671
3672 function rhov_p "Density of saturated vapour"
3673 extends Modelica.Icons.Function;
3674 input SI.Pressure p "Saturation pressure";
3675 output SI.Density rho "Density of steam at the condensation point";
3676 algorithm
3677 rho := rhovl_p(p, dewcurve_p(p));
3678 annotation(Inline = true);
3679 end rhov_p;
3680
3681 function rhovl_p_der
3682 extends Modelica.Icons.Function;
3683 input SI.Pressure p "Saturation pressure";
3684 input Common.IF97PhaseBoundaryProperties bpro "Property record";
3685 input Real p_der "Derivative of pressure";
3686 output Real d_der "Time derivative of density along the phase boundary";
3687 algorithm
3688 d_der := if bpro.region3boundary then (p_der - bpro.pt * p_der / bpro.dpT) / bpro.pd else -bpro.d * bpro.d * (bpro.vp + bpro.vt / bpro.dpT) * p_der;
3689 annotation(Inline = true);
3690 end rhovl_p_der;
3691
3692 function sl_p "Liquid specific entropy on the boundary between regions 4 and 3 or 1"
3693 extends Modelica.Icons.Function;
3694 input SI.Pressure p "Pressure";
3695 output SI.SpecificEntropy s "Specific entropy";
3696 protected
3697 SI.Temperature Tsat "Saturation temperature";
3698 SI.SpecificEnthalpy h "Specific enthalpy";
3699 algorithm
3700 if p < data.PLIMIT4A then
3701 Tsat := Basic.tsat(p);
3702 (h, s) := Isentropic.handsofpT1(p, Tsat);
3703 elseif p < data.PCRIT then
3704 s := sl_p_R4b(p);
3705 else
3706 s := data.SCRIT;
3707 end if;
3708 end sl_p;
3709
3710 function sv_p "Vapour specific entropy on the boundary between regions 4 and 3 or 2"
3711 extends Modelica.Icons.Function;
3712 input SI.Pressure p "Pressure";
3713 output SI.SpecificEntropy s "Specific entropy";
3714 protected
3715 SI.Temperature Tsat "Saturation temperature";
3716 SI.SpecificEnthalpy h "Specific enthalpy";
3717 algorithm
3718 if p < data.PLIMIT4A then
3719 Tsat := Basic.tsat(p);
3720 (h, s) := Isentropic.handsofpT2(p, Tsat);
3721 elseif p < data.PCRIT then
3722 s := sv_p_R4b(p);
3723 else
3724 s := data.SCRIT;
3725 end if;
3726 end sv_p;
3727
3728 function rhol_T "Density of saturated water"
3729 extends Modelica.Icons.Function;
3730 input SI.Temperature T "Temperature";
3731 output SI.Density d "Density of water at the boiling point";
3732 protected
3733 SI.Pressure p "Saturation pressure";
3734 algorithm
3735 p := Basic.psat(T);
3736 if T < data.TLIMIT1 then
3737 d := d1n(p, T);
3738 elseif T < data.TCRIT then
3739 d := rhol_p_R4b(p);
3740 else
3741 d := data.DCRIT;
3742 end if;
3743 end rhol_T;
3744
3745 function rhov_T "Density of saturated vapour"
3746 extends Modelica.Icons.Function;
3747 input SI.Temperature T "Temperature";
3748 output SI.Density d "Density of steam at the condensation point";
3749 protected
3750 SI.Pressure p "Saturation pressure";
3751 algorithm
3752 p := Basic.psat(T);
3753 if T < data.TLIMIT1 then
3754 d := d2n(p, T);
3755 elseif T < data.TCRIT then
3756 d := rhov_p_R4b(p);
3757 else
3758 d := data.DCRIT;
3759 end if;
3760 end rhov_T;
3761
3762 function region_ph "Return the current region (valid values: 1,2,3,4,5) in IF97 for given pressure and specific enthalpy"
3763 extends Modelica.Icons.Function;
3764 input SI.Pressure p "Pressure";
3765 input SI.SpecificEnthalpy h "Specific enthalpy";
3766 input Integer phase = 0 "Phase: 2 for two-phase, 1 for one phase, 0 if not known";
3767 input Integer mode = 0 "Mode: 0 means check, otherwise assume region=mode";
3768 output Integer region "Region (valid values: 1,2,3,4,5) in IF97";
3769 protected
3770 Boolean hsubcrit;
3771 SI.Temperature Ttest;
3772 SI.SpecificEnthalpy hl "Bubble enthalpy";
3773 SI.SpecificEnthalpy hv "Dew enthalpy";
3774 algorithm
3775 if mode <> 0 then
3776 region := mode;
3777 else
3778 hl := hl_p(p);
3779 hv := hv_p(p);
3780 if phase == 2 then
3781 region := 4;
3782 else
3783 if p < triple.ptriple or p > data.PLIMIT1 or h < hlowerofp1(p) or p < 10.0e6 and h > hupperofp5(p) or p >= 10.0e6 and h > hupperofp2(p) then
3784 region := -1;
3785 else
3786 hsubcrit := h < data.HCRIT;
3787 if p < data.PLIMIT4A then
3788 if hsubcrit then
3789 if phase == 1 then
3790 region := 1;
3791 else
3792 if h < Isentropic.hofpT1(p, Basic.tsat(p)) then
3793 region := 1;
3794 else
3795 region := 4;
3796 end if;
3797 end if;
3798 else
3799 if h > hlowerofp5(p) then
3800 if p < data.PLIMIT5 and h < hupperofp5(p) then
3801 region := 5;
3802 else
3803 region := -2;
3804 end if;
3805 else
3806 if phase == 1 then
3807 region := 2;
3808 else
3809 if h > Isentropic.hofpT2(p, Basic.tsat(p)) then
3810 region := 2;
3811 else
3812 region := 4;
3813 end if;
3814 end if;
3815 end if;
3816 end if;
3817 else
3818 if hsubcrit then
3819 if h < hupperofp1(p) then
3820 region := 1;
3821 else
3822 if h < hl or p > data.PCRIT then
3823 region := 3;
3824 else
3825 region := 4;
3826 end if;
3827 end if;
3828 else
3829 if h > hlowerofp2(p) then
3830 region := 2;
3831 else
3832 if h > hv or p > data.PCRIT then
3833 region := 3;
3834 else
3835 region := 4;
3836 end if;
3837 end if;
3838 end if;
3839 end if;
3840 end if;
3841 end if;
3842 end if;
3843 end region_ph;
3844
3845 function region_ps "Return the current region (valid values: 1,2,3,4,5) in IF97 for given pressure and specific entropy"
3846 extends Modelica.Icons.Function;
3847 input SI.Pressure p "Pressure";
3848 input SI.SpecificEntropy s "Specific entropy";
3849 input Integer phase = 0 "Phase: 2 for two-phase, 1 for one phase, 0 if unknown";
3850 input Integer mode = 0 "Mode: 0 means check, otherwise assume region=mode";
3851 output Integer region "Region (valid values: 1,2,3,4,5) in IF97";
3852 protected
3853 Boolean ssubcrit;
3854 SI.Temperature Ttest;
3855 SI.SpecificEntropy sl "Bubble entropy";
3856 SI.SpecificEntropy sv "Dew entropy";
3857 algorithm
3858 if mode <> 0 then
3859 region := mode;
3860 else
3861 sl := sl_p(p);
3862 sv := sv_p(p);
3863 if phase == 2 or phase == 0 and s > sl and s < sv and p < data.PCRIT then
3864 region := 4;
3865 else
3866 region := 0;
3867 if p < triple.ptriple then
3868 region := -2;
3869 else
3870 end if;
3871 if p > data.PLIMIT1 then
3872 region := -3;
3873 else
3874 end if;
3875 if p < 10.0e6 and s > supperofp5(p) then
3876 region := -5;
3877 else
3878 end if;
3879 if p >= 10.0e6 and s > supperofp2(p) then
3880 region := -6;
3881 else
3882 end if;
3883 if region < 0 then
3884 assert(false, "Region computation from p and s failed: function called outside the legal region");
3885 else
3886 ssubcrit := s < data.SCRIT;
3887 if p < data.PLIMIT4A then
3888 if ssubcrit then
3889 region := 1;
3890 else
3891 if s > slowerofp5(p) then
3892 if p < data.PLIMIT5 and s < supperofp5(p) then
3893 region := 5;
3894 else
3895 region := -1;
3896 end if;
3897 else
3898 region := 2;
3899 end if;
3900 end if;
3901 else
3902 if ssubcrit then
3903 if s < supperofp1(p) then
3904 region := 1;
3905 else
3906 if s < sl or p > data.PCRIT then
3907 region := 3;
3908 else
3909 region := 4;
3910 end if;
3911 end if;
3912 else
3913 if s > slowerofp2(p) then
3914 region := 2;
3915 else
3916 if s > sv or p > data.PCRIT then
3917 region := 3;
3918 else
3919 region := 4;
3920 end if;
3921 end if;
3922 end if;
3923 end if;
3924 end if;
3925 end if;
3926 end if;
3927 end region_ps;
3928
3929 function region_pT "Return the current region (valid values: 1,2,3,5) in IF97, given pressure and temperature"
3930 extends Modelica.Icons.Function;
3931 input SI.Pressure p "Pressure";
3932 input SI.Temperature T "Temperature (K)";
3933 input Integer mode = 0 "Mode: 0 means check, otherwise assume region=mode";
3934 output Integer region "Region (valid values: 1,2,3,5) in IF97, region 4 is impossible!";
3935 algorithm
3936 if mode <> 0 then
3937 region := mode;
3938 else
3939 if p < data.PLIMIT4A then
3940 if T > data.TLIMIT2 then
3941 region := 5;
3942 elseif T > Basic.tsat(p) then
3943 region := 2;
3944 else
3945 region := 1;
3946 end if;
3947 else
3948 if T < data.TLIMIT1 then
3949 region := 1;
3950 elseif T < boundary23ofp(p) then
3951 region := 3;
3952 else
3953 region := 2;
3954 end if;
3955 end if;
3956 end if;
3957 end region_pT;
3958
3959 function region_dT "Return the current region (valid values: 1,2,3,4,5) in IF97, given density and temperature"
3960 extends Modelica.Icons.Function;
3961 input SI.Density d "Density";
3962 input SI.Temperature T "Temperature (K)";
3963 input Integer phase = 0 "Phase: 2 for two-phase, 1 for one phase, 0 if not known";
3964 input Integer mode = 0 "Mode: 0 means check, otherwise assume region=mode";
3965 output Integer region "(valid values: 1,2,3,4,5) in IF97";
3966 protected
3967 Boolean Tovercrit "Flag if overcritical temperature";
3968 SI.Pressure p23 "Pressure needed to know if region 2 or 3";
3969 algorithm
3970 Tovercrit := T > data.TCRIT;
3971 if mode <> 0 then
3972 region := mode;
3973 else
3974 p23 := boundary23ofT(T);
3975 if T > data.TLIMIT2 then
3976 if d < 20.5655874106483 then
3977 region := 5;
3978 else
3979 assert(false, "Out of valid region for IF97, pressure above region 5!");
3980 end if;
3981 elseif Tovercrit then
3982 if d > d2n(p23, T) and T > data.TLIMIT1 then
3983 region := 3;
3984 elseif T < data.TLIMIT1 then
3985 region := 1;
3986 else
3987 region := 2;
3988 end if;
3989 elseif d > rhol_T(T) then
3990 if T < data.TLIMIT1 then
3991 region := 1;
3992 else
3993 region := 3;
3994 end if;
3995 elseif d < rhov_T(T) then
3996 if d > d2n(p23, T) and T > data.TLIMIT1 then
3997 region := 3;
3998 else
3999 region := 2;
4000 end if;
4001 else
4002 region := 4;
4003 end if;
4004 end if;
4005 end region_dT;
4006
4007 function hvl_dp "Derivative function for the specific enthalpy along the phase boundary"
4008 extends Modelica.Icons.Function;
4009 input SI.Pressure p "Pressure";
4010 input Common.IF97PhaseBoundaryProperties bpro "Property record";
4011 output Real dh_dp "Derivative of specific enthalpy along the phase boundary";
4012 algorithm
4013 if bpro.region3boundary then
4014 dh_dp := (bpro.d * bpro.pd - bpro.T * bpro.pt + (bpro.T * bpro.pt * bpro.pt + bpro.d * bpro.d * bpro.pd * bpro.cv) / bpro.dpT) / (bpro.pd * bpro.d * bpro.d);
4015 else
4016 dh_dp := 1 / bpro.d - bpro.T * bpro.vt + bpro.cp / bpro.dpT;
4017 end if;
4018 end hvl_dp;
4019
4020 function dhl_dp "Derivative of liquid specific enthalpy on the boundary between regions 4 and 3 or 1 w.r.t. pressure"
4021 extends Modelica.Icons.Function;
4022 input SI.Pressure p "Pressure";
4023 output SI.DerEnthalpyByPressure dh_dp "Specific enthalpy derivative w.r.t. pressure";
4024 algorithm
4025 dh_dp := hvl_dp(p, boilingcurve_p(p));
4026 annotation(Inline = true);
4027 end dhl_dp;
4028
4029 function dhv_dp "Derivative of vapour specific enthalpy on the boundary between regions 4 and 3 or 1 w.r.t. pressure"
4030 extends Modelica.Icons.Function;
4031 input SI.Pressure p "Pressure";
4032 output SI.DerEnthalpyByPressure dh_dp "Specific enthalpy derivative w.r.t. pressure";
4033 algorithm
4034 dh_dp := hvl_dp(p, dewcurve_p(p));
4035 annotation(Inline = true);
4036 end dhv_dp;
4037
4038 function drhovl_dp
4039 extends Modelica.Icons.Function;
4040 input SI.Pressure p "Saturation pressure";
4041 input Common.IF97PhaseBoundaryProperties bpro "Property record";
4042 output Real dd_dp(unit = "kg/(m3.Pa)") "Derivative of density along the phase boundary";
4043 algorithm
4044 dd_dp := if bpro.region3boundary then (1.0 - bpro.pt / bpro.dpT) / bpro.pd else -bpro.d * bpro.d * (bpro.vp + bpro.vt / bpro.dpT);
4045 annotation(Inline = true);
4046 end drhovl_dp;
4047
4048 function drhol_dp "Derivative of density of saturated water w.r.t. pressure"
4049 extends Modelica.Icons.Function;
4050 input SI.Pressure p "Saturation pressure";
4051 output SI.DerDensityByPressure dd_dp "Derivative of density of water at the boiling point";
4052 algorithm
4053 dd_dp := drhovl_dp(p, boilingcurve_p(p));
4054 annotation(Inline = true);
4055 end drhol_dp;
4056
4057 function drhov_dp "Derivative of density of saturated steam w.r.t. pressure"
4058 extends Modelica.Icons.Function;
4059 input SI.Pressure p "Saturation pressure";
4060 output SI.DerDensityByPressure dd_dp "Derivative of density of water at the boiling point";
4061 algorithm
4062 dd_dp := drhovl_dp(p, dewcurve_p(p));
4063 annotation(Inline = true);
4064 end drhov_dp;
4065 end Regions;
4066
4067 package Basic "Base functions as described in IAWPS/IF97"
4068 extends Modelica.Icons.FunctionsPackage;
4069
4070 function g1 "Gibbs function for region 1: g(p,T)"
4071 extends Modelica.Icons.Function;
4072 input SI.Pressure p "Pressure";
4073 input SI.Temperature T "Temperature (K)";
4074 output Modelica.Media.Common.GibbsDerivs g "Dimensionless Gibbs function and derivatives w.r.t. pi and tau";
4075 protected
4076 Real pi1 "Dimensionless pressure";
4077 Real tau1 "Dimensionless temperature";
4078 Real[45] o "Vector of auxiliary variables";
4079 Real pl "Auxiliary variable";
4080 algorithm
4081 pl := min(p, data.PCRIT - 1);
4082 assert(p > triple.ptriple, "IF97 medium function g1 called with too low pressure\n" + "p = " + String(p) + " Pa <= " + String(triple.ptriple) + " Pa (triple point pressure)");
4083 assert(p <= 100.0e6, "IF97 medium function g1: the input pressure (= " + String(p) + " Pa) is higher than 100 Mpa");
4084 assert(T >= 273.15, "IF97 medium function g1: the temperature (= " + String(T) + " K) is lower than 273.15 K!");
4085 g.p := p;
4086 g.T := T;
4087 g.R := data.RH2O;
4088 g.pi := p / data.PSTAR1;
4089 g.tau := data.TSTAR1 / T;
4090 pi1 := 7.1000000000000 - g.pi;
4091 tau1 := (-1.22200000000000) + g.tau;
4092 o[1] := tau1 * tau1;
4093 o[2] := o[1] * o[1];
4094 o[3] := o[2] * o[2];
4095 o[4] := o[3] * tau1;
4096 o[5] := 1 / o[4];
4097 o[6] := o[1] * o[2];
4098 o[7] := o[1] * tau1;
4099 o[8] := 1 / o[7];
4100 o[9] := o[1] * o[2] * o[3];
4101 o[10] := 1 / o[2];
4102 o[11] := o[2] * tau1;
4103 o[12] := 1 / o[11];
4104 o[13] := o[2] * o[3];
4105 o[14] := 1 / o[3];
4106 o[15] := pi1 * pi1;
4107 o[16] := o[15] * pi1;
4108 o[17] := o[15] * o[15];
4109 o[18] := o[17] * o[17];
4110 o[19] := o[17] * o[18] * pi1;
4111 o[20] := o[15] * o[17];
4112 o[21] := o[3] * o[3];
4113 o[22] := o[21] * o[21];
4114 o[23] := o[22] * o[3] * tau1;
4115 o[24] := 1 / o[23];
4116 o[25] := o[22] * o[3];
4117 o[26] := 1 / o[25];
4118 o[27] := o[1] * o[2] * o[22] * tau1;
4119 o[28] := 1 / o[27];
4120 o[29] := o[1] * o[2] * o[22];
4121 o[30] := 1 / o[29];
4122 o[31] := o[1] * o[2] * o[21] * o[3] * tau1;
4123 o[32] := 1 / o[31];
4124 o[33] := o[2] * o[21] * o[3] * tau1;
4125 o[34] := 1 / o[33];
4126 o[35] := o[1] * o[3] * tau1;
4127 o[36] := 1 / o[35];
4128 o[37] := o[1] * o[3];
4129 o[38] := 1 / o[37];
4130 o[39] := 1 / o[6];
4131 o[40] := o[1] * o[22] * o[3];
4132 o[41] := 1 / o[40];
4133 o[42] := 1 / o[22];
4134 o[43] := o[1] * o[2] * o[21] * o[3];
4135 o[44] := 1 / o[43];
4136 o[45] := 1 / o[13];
4137 g.g := pi1 * (pi1 * (pi1 * (o[10] * ((-0.000031679644845054) + o[2] * ((-2.82707979853120e-6) - 8.5205128120103e-10 * o[6])) + pi1 * (o[12] * ((-2.24252819080000e-6) + ((-6.5171222895601e-7) - 1.43417299379240e-13 * o[13]) * o[7]) + pi1 * ((-4.0516996860117e-7 * o[14]) + o[16] * (((-1.27343017416410e-9) - 1.74248712306340e-10 * o[11]) * o[36] + o[19] * ((-6.8762131295531e-19 * o[34]) + o[15] * (1.44783078285210e-20 * o[32] + o[20] * (2.63357816627950e-23 * o[30] + pi1 * ((-1.19476226400710e-23 * o[28]) + pi1 * (1.82280945814040e-24 * o[26] - 9.3537087292458e-26 * o[24] * pi1))))))))) + o[8] * ((-0.00047184321073267) + o[7] * ((-0.000300017807930260) + (0.000047661393906987 + o[1] * ((-4.4141845330846e-6) - 7.2694996297594e-16 * o[9])) * tau1))) + o[5] * (0.000283190801238040 + o[1] * ((-0.00060706301565874) + o[6] * ((-0.0189900682184190) + tau1 * ((-0.032529748770505) + ((-0.0218417171754140) - 0.000052838357969930 * o[1]) * tau1))))) + (0.146329712131670 + tau1 * ((-0.84548187169114) + tau1 * ((-3.7563603672040) + tau1 * (3.3855169168385 + tau1 * ((-0.95791963387872) + tau1 * (0.157720385132280 + ((-0.0166164171995010) + 0.00081214629983568 * tau1) * tau1)))))) / o[1];
4138 g.gpi := pi1 * (pi1 * (o[10] * (0.000095038934535162 + o[2] * (8.4812393955936e-6 + 2.55615384360309e-9 * o[6])) + pi1 * (o[12] * (8.9701127632000e-6 + (2.60684891582404e-6 + 5.7366919751696e-13 * o[13]) * o[7]) + pi1 * (2.02584984300585e-6 * o[14] + o[16] * ((1.01874413933128e-8 + 1.39398969845072e-9 * o[11]) * o[36] + o[19] * (1.44400475720615e-17 * o[34] + o[15] * ((-3.3300108005598e-19 * o[32]) + o[20] * ((-7.6373766822106e-22 * o[30]) + pi1 * (3.5842867920213e-22 * o[28] + pi1 * ((-5.6507093202352e-23 * o[26]) + 2.99318679335866e-24 * o[24] * pi1))))))))) + o[8] * (0.00094368642146534 + o[7] * (0.00060003561586052 + ((-0.000095322787813974) + o[1] * (8.8283690661692e-6 + 1.45389992595188e-15 * o[9])) * tau1))) + o[5] * ((-0.000283190801238040) + o[1] * (0.00060706301565874 + o[6] * (0.0189900682184190 + tau1 * (0.032529748770505 + (0.0218417171754140 + 0.000052838357969930 * o[1]) * tau1))));
4139 g.gpipi := pi1 * (o[10] * ((-0.000190077869070324) + o[2] * ((-0.0000169624787911872) - 5.1123076872062e-9 * o[6])) + pi1 * (o[12] * ((-0.0000269103382896000) + ((-7.8205467474721e-6) - 1.72100759255088e-12 * o[13]) * o[7]) + pi1 * ((-8.1033993720234e-6 * o[14]) + o[16] * (((-7.1312089753190e-8) - 9.7579278891550e-9 * o[11]) * o[36] + o[19] * ((-2.88800951441230e-16 * o[34]) + o[15] * (7.3260237612316e-18 * o[32] + o[20] * (2.13846547101895e-20 * o[30] + pi1 * ((-1.03944316968618e-20 * o[28]) + pi1 * (1.69521279607057e-21 * o[26] - 9.2788790594118e-23 * o[24] * pi1))))))))) + o[8] * ((-0.00094368642146534) + o[7] * ((-0.00060003561586052) + (0.000095322787813974 + o[1] * ((-8.8283690661692e-6) - 1.45389992595188e-15 * o[9])) * tau1));
4140 g.gtau := pi1 * (o[38] * ((-0.00254871721114236) + o[1] * (0.0042494411096112 + (0.0189900682184190 + ((-0.0218417171754140) - 0.000158515073909790 * o[1]) * o[1]) * o[6])) + pi1 * (o[10] * (0.00141552963219801 + o[2] * (0.000047661393906987 + o[1] * ((-0.0000132425535992538) - 1.23581493705910e-14 * o[9]))) + pi1 * (o[12] * (0.000126718579380216 - 5.1123076872062e-9 * o[37]) + pi1 * (o[39] * (0.0000112126409540000 + (1.30342445791202e-6 - 1.43417299379240e-12 * o[13]) * o[7]) + pi1 * (3.2413597488094e-6 * o[5] + o[16] * ((1.40077319158051e-8 + 1.04549227383804e-9 * o[11]) * o[45] + o[19] * (1.99410180757040e-17 * o[44] + o[15] * ((-4.4882754268415e-19 * o[42]) + o[20] * ((-1.00075970318621e-21 * o[28]) + pi1 * (4.6595728296277e-22 * o[26] + pi1 * ((-7.2912378325616e-23 * o[24]) + 3.8350205789908e-24 * o[41] * pi1))))))))))) + o[8] * ((-0.292659424263340) + tau1 * (0.84548187169114 + o[1] * (3.3855169168385 + tau1 * ((-1.91583926775744) + tau1 * (0.47316115539684 + ((-0.066465668798004) + 0.0040607314991784 * tau1) * tau1)))));
4141 g.gtautau := pi1 * (o[36] * (0.0254871721114236 + o[1] * ((-0.033995528876889) + ((-0.037980136436838) - 0.00031703014781958 * o[2]) * o[6])) + pi1 * (o[12] * ((-0.0056621185287920) + o[6] * ((-0.0000264851071985076) - 1.97730389929456e-13 * o[9])) + pi1 * (((-0.00063359289690108) - 2.55615384360309e-8 * o[37]) * o[39] + pi1 * (pi1 * ((-0.0000291722377392842 * o[38]) + o[16] * (o[19] * ((-5.9823054227112e-16 * o[32]) + o[15] * (o[20] * (3.9029628424262e-20 * o[26] + pi1 * ((-1.86382913185108e-20 * o[24]) + pi1 * (2.98940751135026e-21 * o[41] - 1.61070864317613e-22 * pi1 / (o[1] * o[22] * o[3] * tau1)))) + 1.43624813658928e-17 / (o[22] * tau1))) + ((-1.68092782989661e-7) - 7.3184459168663e-9 * o[11]) / (o[2] * o[3] * tau1))) + ((-0.000067275845724000) + ((-3.9102733737361e-6) - 1.29075569441316e-11 * o[13]) * o[7]) / (o[1] * o[2] * tau1))))) + o[10] * (0.87797827279002 + tau1 * ((-1.69096374338228) + o[7] * ((-1.91583926775744) + tau1 * (0.94632231079368 + ((-0.199397006394012) + 0.0162429259967136 * tau1) * tau1))));
4142 g.gtaupi := o[38] * (0.00254871721114236 + o[1] * ((-0.0042494411096112) + ((-0.0189900682184190) + (0.0218417171754140 + 0.000158515073909790 * o[1]) * o[1]) * o[6])) + pi1 * (o[10] * ((-0.00283105926439602) + o[2] * ((-0.000095322787813974) + o[1] * (0.0000264851071985076 + 2.47162987411820e-14 * o[9]))) + pi1 * (o[12] * ((-0.00038015573814065) + 1.53369230616185e-8 * o[37]) + pi1 * (o[39] * ((-0.000044850563816000) + ((-5.2136978316481e-6) + 5.7366919751696e-12 * o[13]) * o[7]) + pi1 * ((-0.0000162067987440468 * o[5]) + o[16] * (((-1.12061855326441e-7) - 8.3639381907043e-9 * o[11]) * o[45] + o[19] * ((-4.1876137958978e-16 * o[44]) + o[15] * (1.03230334817355e-17 * o[42] + o[20] * (2.90220313924001e-20 * o[28] + pi1 * ((-1.39787184888831e-20 * o[26]) + pi1 * (2.26028372809410e-21 * o[24] - 1.22720658527705e-22 * o[41] * pi1))))))))));
4143 end g1;
4144
4145 function g2 "Gibbs function for region 2: g(p,T)"
4146 extends Modelica.Icons.Function;
4147 input SI.Pressure p "Pressure";
4148 input SI.Temperature T "Temperature (K)";
4149 output Modelica.Media.Common.GibbsDerivs g "Dimensionless Gibbs function and derivatives w.r.t. pi and tau";
4150 protected
4151 Real tau2 "Dimensionless temperature";
4152 Real[55] o "Vector of auxiliary variables";
4153 algorithm
4154 g.p := p;
4155 g.T := T;
4156 g.R := data.RH2O;
4157 assert(p > 0.0, "IF97 medium function g2 called with too low pressure\n" + "p = " + String(p) + " Pa <= 0.0 Pa");
4158 assert(p <= 100.0e6, "IF97 medium function g2: the input pressure (= " + String(p) + " Pa) is higher than 100 Mpa");
4159 assert(T >= 273.15, "IF97 medium function g2: the temperature (= " + String(T) + " K) is lower than 273.15 K!");
4160 assert(T <= 1073.15, "IF97 medium function g2: the input temperature (= " + String(T) + " K) is higher than the limit of 1073.15 K");
4161 g.pi := p / data.PSTAR2;
4162 g.tau := data.TSTAR2 / T;
4163 tau2 := (-0.5) + g.tau;
4164 o[1] := tau2 * tau2;
4165 o[2] := o[1] * tau2;
4166 o[3] := -0.050325278727930 * o[2];
4167 o[4] := (-0.057581259083432) + o[3];
4168 o[5] := o[4] * tau2;
4169 o[6] := (-0.045996013696365) + o[5];
4170 o[7] := o[6] * tau2;
4171 o[8] := (-0.0178348622923580) + o[7];
4172 o[9] := o[8] * tau2;
4173 o[10] := o[1] * o[1];
4174 o[11] := o[10] * o[10];
4175 o[12] := o[11] * o[11];
4176 o[13] := o[10] * o[11] * o[12] * tau2;
4177 o[14] := o[1] * o[10] * tau2;
4178 o[15] := o[10] * o[11] * tau2;
4179 o[16] := o[1] * o[12] * tau2;
4180 o[17] := o[1] * o[11] * tau2;
4181 o[18] := o[1] * o[10] * o[11];
4182 o[19] := o[10] * o[11] * o[12];
4183 o[20] := o[1] * o[10];
4184 o[21] := g.pi * g.pi;
4185 o[22] := o[21] * o[21];
4186 o[23] := o[21] * o[22];
4187 o[24] := o[10] * o[12] * tau2;
4188 o[25] := o[12] * o[12];
4189 o[26] := o[11] * o[12] * o[25] * tau2;
4190 o[27] := o[10] * o[12];
4191 o[28] := o[1] * o[10] * o[11] * tau2;
4192 o[29] := o[10] * o[12] * o[25] * tau2;
4193 o[30] := o[1] * o[10] * o[25] * tau2;
4194 o[31] := o[1] * o[11] * o[12];
4195 o[32] := o[1] * o[12];
4196 o[33] := g.tau * g.tau;
4197 o[34] := o[33] * o[33];
4198 o[35] := -0.000053349095828174 * o[13];
4199 o[36] := (-0.087594591301146) + o[35];
4200 o[37] := o[2] * o[36];
4201 o[38] := (-0.0078785554486710) + o[37];
4202 o[39] := o[1] * o[38];
4203 o[40] := (-0.00037897975032630) + o[39];
4204 o[41] := o[40] * tau2;
4205 o[42] := (-0.000066065283340406) + o[41];
4206 o[43] := o[42] * tau2;
4207 o[44] := 5.7870447262208e-6 * tau2;
4208 o[45] := -0.301951672367580 * o[2];
4209 o[46] := (-0.172743777250296) + o[45];
4210 o[47] := o[46] * tau2;
4211 o[48] := (-0.091992027392730) + o[47];
4212 o[49] := o[48] * tau2;
4213 o[50] := o[1] * o[11];
4214 o[51] := o[10] * o[11];
4215 o[52] := o[11] * o[12] * o[25];
4216 o[53] := o[10] * o[12] * o[25];
4217 o[54] := o[1] * o[10] * o[25];
4218 o[55] := o[11] * o[12] * tau2;
4219 g.g := g.pi * ((-0.00177317424732130) + o[9] + g.pi * (tau2 * ((-0.000033032641670203) + ((-0.000189489875163150) + o[1] * ((-0.0039392777243355) + ((-0.043797295650573) - 0.0000266745479140870 * o[13]) * o[2])) * tau2) + g.pi * (2.04817376923090e-8 + (4.3870667284435e-7 + o[1] * ((-0.000032277677238570) + ((-0.00150339245421480) - 0.040668253562649 * o[13]) * o[2])) * tau2 + g.pi * (g.pi * (2.29220763376610e-6 * o[14] + g.pi * (((-1.67147664510610e-11) + o[15] * ((-0.00211714723213550) - 23.8957419341040 * o[16])) * o[2] + g.pi * ((-5.9059564324270e-18) + o[17] * ((-1.26218088991010e-6) - 0.038946842435739 * o[18]) + g.pi * (o[11] * (1.12562113604590e-11 - 8.2311340897998 * o[19]) + g.pi * (1.98097128020880e-8 * o[15] + g.pi * (o[10] * (1.04069652101740e-19 + ((-1.02347470959290e-13) - 1.00181793795110e-9 * o[10]) * o[20]) + o[23] * (o[13] * ((-8.0882908646985e-11) + 0.106930318794090 * o[24]) + o[21] * ((-0.33662250574171 * o[26]) + o[21] * (o[27] * (8.9185845355421e-25 + (3.06293168762320e-13 - 4.2002467698208e-6 * o[15]) * o[28]) + g.pi * ((-5.9056029685639e-26 * o[24]) + g.pi * (3.7826947613457e-6 * o[29] + g.pi * ((-1.27686089346810e-15 * o[30]) + o[31] * (7.3087610595061e-29 + o[18] * (5.5414715350778e-17 - 9.4369707241210e-7 * o[32])) * g.pi)))))))))))) + tau2 * ((-7.8847309559367e-10) + (1.27907178522850e-8 + 4.8225372718507e-7 * tau2) * tau2))))) + ((-0.0056087911830200) + g.tau * (0.071452738814550 + g.tau * ((-0.40710498239280) + g.tau * (1.42408197144400 + g.tau * ((-4.3839511194500) + g.tau * ((-9.6927686002170) + g.tau * (10.0866556801800 + ((-0.284086326077200) + 0.0212684635330700 * g.tau) * g.tau) + Modelica.Math.log(g.pi))))))) / (o[34] * g.tau);
4220 g.gpi := (1.00000000000000 + g.pi * ((-0.00177317424732130) + o[9] + g.pi * (o[43] + g.pi * (6.1445213076927e-8 + (1.31612001853305e-6 + o[1] * ((-0.000096833031715710) + ((-0.0045101773626444) - 0.122004760687947 * o[13]) * o[2])) * tau2 + g.pi * (g.pi * (0.0000114610381688305 * o[14] + g.pi * (((-1.00288598706366e-10) + o[15] * ((-0.0127028833928130) - 143.374451604624 * o[16])) * o[2] + g.pi * ((-4.1341695026989e-17) + o[17] * ((-8.8352662293707e-6) - 0.272627897050173 * o[18]) + g.pi * (o[11] * (9.0049690883672e-11 - 65.849072718398 * o[19]) + g.pi * (1.78287415218792e-7 * o[15] + g.pi * (o[10] * (1.04069652101740e-18 + ((-1.02347470959290e-12) - 1.00181793795110e-8 * o[10]) * o[20]) + o[23] * (o[13] * ((-1.29412653835176e-9) + 1.71088510070544 * o[24]) + o[21] * ((-6.0592051033508 * o[26]) + o[21] * (o[27] * (1.78371690710842e-23 + (6.1258633752464e-12 - 0.000084004935396416 * o[15]) * o[28]) + g.pi * ((-1.24017662339842e-24 * o[24]) + g.pi * (0.000083219284749605 * o[29] + g.pi * ((-2.93678005497663e-14 * o[30]) + o[31] * (1.75410265428146e-27 + o[18] * (1.32995316841867e-15 - 0.0000226487297378904 * o[32])) * g.pi)))))))))))) + tau2 * ((-3.15389238237468e-9) + (5.1162871409140e-8 + 1.92901490874028e-6 * tau2) * tau2)))))) / g.pi;
4221 g.gpipi := ((-1.00000000000000) + o[21] * (o[43] + g.pi * (1.22890426153854e-7 + (2.63224003706610e-6 + o[1] * ((-0.000193666063431420) + ((-0.0090203547252888) - 0.244009521375894 * o[13]) * o[2])) * tau2 + g.pi * (g.pi * (0.000045844152675322 * o[14] + g.pi * (((-5.0144299353183e-10) + o[15] * ((-0.063514416964065) - 716.87225802312 * o[16])) * o[2] + g.pi * ((-2.48050170161934e-16) + o[17] * ((-0.000053011597376224) - 1.63576738230104 * o[18]) + g.pi * (o[11] * (6.3034783618570e-10 - 460.94350902879 * o[19]) + g.pi * (1.42629932175034e-6 * o[15] + g.pi * (o[10] * (9.3662686891566e-18 + ((-9.2112723863361e-12) - 9.0163614415599e-8 * o[10]) * o[20]) + o[23] * (o[13] * ((-1.94118980752764e-8) + 25.6632765105816 * o[24]) + o[21] * ((-103.006486756963 * o[26]) + o[21] * (o[27] * (3.3890621235060e-22 + (1.16391404129682e-10 - 0.00159609377253190 * o[15]) * o[28]) + g.pi * ((-2.48035324679684e-23 * o[24]) + g.pi * (0.00174760497974171 * o[29] + g.pi * ((-6.4609161209486e-13 * o[30]) + o[31] * (4.0344361048474e-26 + o[18] * (3.05889228736295e-14 - 0.00052092078397148 * o[32])) * g.pi)))))))))))) + tau2 * ((-9.4616771471240e-9) + (1.53488614227420e-7 + o[44]) * tau2))))) / o[21];
4222 g.gtau := (0.0280439559151000 + g.tau * ((-0.285810955258200) + g.tau * (1.22131494717840 + g.tau * ((-2.84816394288800) + g.tau * (4.3839511194500 + o[33] * (10.0866556801800 + ((-0.56817265215440) + 0.063805390599210 * g.tau) * g.tau)))))) / (o[33] * o[34]) + g.pi * ((-0.0178348622923580) + o[49] + g.pi * ((-0.000033032641670203) + ((-0.00037897975032630) + o[1] * ((-0.0157571108973420) + ((-0.306581069554011) - 0.00096028372490713 * o[13]) * o[2])) * tau2 + g.pi * (4.3870667284435e-7 + o[1] * ((-0.000096833031715710) + ((-0.0090203547252888) - 1.42338887469272 * o[13]) * o[2]) + g.pi * ((-7.8847309559367e-10) + g.pi * (0.0000160454534363627 * o[20] + g.pi * (o[1] * ((-5.0144299353183e-11) + o[15] * ((-0.033874355714168) - 836.35096769364 * o[16])) + g.pi * (((-0.0000138839897890111) - 0.97367106089347 * o[18]) * o[50] + g.pi * (o[14] * (9.0049690883672e-11 - 296.320827232793 * o[19]) + g.pi * (2.57526266427144e-7 * o[51] + g.pi * (o[2] * (4.1627860840696e-19 + ((-1.02347470959290e-12) - 1.40254511313154e-8 * o[10]) * o[20]) + o[23] * (o[19] * ((-2.34560435076256e-9) + 5.3465159397045 * o[24]) + o[21] * ((-19.1874828272775 * o[52]) + o[21] * (o[16] * (1.78371690710842e-23 + (1.07202609066812e-11 - 0.000201611844951398 * o[15]) * o[28]) + g.pi * ((-1.24017662339842e-24 * o[27]) + g.pi * (0.000200482822351322 * o[53] + g.pi * ((-4.9797574845256e-14 * o[54]) + (1.90027787547159e-27 + o[18] * (2.21658861403112e-15 - 0.000054734430199902 * o[32])) * o[55] * g.pi)))))))))))) + (2.55814357045700e-8 + 1.44676118155521e-6 * tau2) * tau2))));
4223 g.gtautau := ((-0.168263735490600) + g.tau * (1.42905477629100 + g.tau * ((-4.8852597887136) + g.tau * (8.5444918286640 + g.tau * ((-8.7679022389000) + o[33] * ((-0.56817265215440) + 0.127610781198420 * g.tau) * g.tau))))) / (o[33] * o[34] * g.tau) + g.pi * ((-0.091992027392730) + ((-0.34548755450059) - 1.50975836183790 * o[2]) * tau2 + g.pi * ((-0.00037897975032630) + o[1] * ((-0.047271332692026) + ((-1.83948641732407) - 0.033609930371750 * o[13]) * o[2]) + g.pi * (((-0.000193666063431420) + ((-0.045101773626444) - 48.395221739552 * o[13]) * o[2]) * tau2 + g.pi * (2.55814357045700e-8 + 2.89352236311042e-6 * tau2 + g.pi * (0.000096272720618176 * o[10] * tau2 + g.pi * (((-1.00288598706366e-10) + o[15] * ((-0.50811533571252) - 28435.9329015838 * o[16])) * tau2 + g.pi * (o[11] * ((-0.000138839897890111) - 23.3681054614434 * o[18]) * tau2 + g.pi * ((6.3034783618570e-10 - 10371.2289531477 * o[19]) * o[20] + g.pi * (3.09031519712573e-6 * o[17] + g.pi * (o[1] * (1.24883582522088e-18 + ((-9.2112723863361e-12) - 1.82330864707100e-7 * o[10]) * o[20]) + o[23] * (o[1] * o[11] * o[12] * ((-6.5676921821352e-8) + 261.979281045521 * o[24]) * tau2 + o[21] * ((-1074.49903832754 * o[1] * o[10] * o[12] * o[25] * tau2) + o[21] * ((3.3890621235060e-22 + (3.6448887082716e-10 - 0.0094757567127157 * o[15]) * o[28]) * o[32] + g.pi * ((-2.48035324679684e-23 * o[16]) + g.pi * (0.0104251067622687 * o[1] * o[12] * o[25] * tau2 + g.pi * (o[11] * o[12] * (4.7506946886790e-26 + o[18] * (8.6446955947214e-14 - 0.00311986252139440 * o[32])) * g.pi - 1.89230784411972e-12 * o[10] * o[25] * tau2))))))))))))))));
4224 g.gtaupi := (-0.0178348622923580) + o[49] + g.pi * ((-0.000066065283340406) + ((-0.00075795950065260) + o[1] * ((-0.0315142217946840) + ((-0.61316213910802) - 0.00192056744981426 * o[13]) * o[2])) * tau2 + g.pi * (1.31612001853305e-6 + o[1] * ((-0.000290499095147130) + ((-0.0270610641758664) - 4.2701666240781 * o[13]) * o[2]) + g.pi * ((-3.15389238237468e-9) + g.pi * (0.000080227267181813 * o[20] + g.pi * (o[1] * ((-3.00865796119098e-10) + o[15] * ((-0.203246134285008) - 5018.1058061618 * o[16])) + g.pi * (((-0.000097187928523078) - 6.8156974262543 * o[18]) * o[50] + g.pi * (o[14] * (7.2039752706938e-10 - 2370.56661786234 * o[19]) + g.pi * (2.31773639784430e-6 * o[51] + g.pi * (o[2] * (4.1627860840696e-18 + ((-1.02347470959290e-11) - 1.40254511313154e-7 * o[10]) * o[20]) + o[23] * (o[19] * ((-3.7529669612201e-8) + 85.544255035272 * o[24]) + o[21] * ((-345.37469089099 * o[52]) + o[21] * (o[16] * (3.5674338142168e-22 + (2.14405218133624e-10 - 0.0040322368990280 * o[15]) * o[28]) + g.pi * ((-2.60437090913668e-23 * o[27]) + g.pi * (0.0044106220917291 * o[53] + g.pi * ((-1.14534422144089e-12 * o[54]) + (4.5606669011318e-26 + o[18] * (5.3198126736747e-14 - 0.00131362632479764 * o[32])) * o[55] * g.pi)))))))))))) + (1.02325742818280e-7 + o[44]) * tau2)));
4225 end g2;
4226
4227 function f3 "Helmholtz function for region 3: f(d,T)"
4228 extends Modelica.Icons.Function;
4229 input SI.Density d "Density";
4230 input SI.Temperature T "Temperature (K)";
4231 output Modelica.Media.Common.HelmholtzDerivs f "Dimensionless Helmholtz function and derivatives w.r.t. delta and tau";
4232 protected
4233 Real[40] o "Vector of auxiliary variables";
4234 algorithm
4235 f.T := T;
4236 f.d := d;
4237 f.R := data.RH2O;
4238 f.tau := data.TCRIT / T;
4239 f.delta := if d == data.DCRIT and T == data.TCRIT then 1 - Modelica.Constants.eps else abs(d / data.DCRIT);
4240 o[1] := f.tau * f.tau;
4241 o[2] := o[1] * o[1];
4242 o[3] := o[2] * f.tau;
4243 o[4] := o[1] * f.tau;
4244 o[5] := o[2] * o[2];
4245 o[6] := o[1] * o[5] * f.tau;
4246 o[7] := o[5] * f.tau;
4247 o[8] := -0.64207765181607 * o[1];
4248 o[9] := 0.88521043984318 + o[8];
4249 o[10] := o[7] * o[9];
4250 o[11] := (-1.15244078066810) + o[10];
4251 o[12] := o[11] * o[2];
4252 o[13] := (-1.26543154777140) + o[12];
4253 o[14] := o[1] * o[13];
4254 o[15] := o[1] * o[2] * o[5] * f.tau;
4255 o[16] := o[2] * o[5];
4256 o[17] := o[1] * o[5];
4257 o[18] := o[5] * o[5];
4258 o[19] := o[1] * o[18] * o[2];
4259 o[20] := o[1] * o[18] * o[2] * f.tau;
4260 o[21] := o[18] * o[5];
4261 o[22] := o[1] * o[18] * o[5];
4262 o[23] := 0.251168168486160 * o[2];
4263 o[24] := 0.078841073758308 + o[23];
4264 o[25] := o[15] * o[24];
4265 o[26] := (-6.1005234513930) + o[25];
4266 o[27] := o[26] * f.tau;
4267 o[28] := 9.7944563083754 + o[27];
4268 o[29] := o[2] * o[28];
4269 o[30] := (-1.70429417648412) + o[29];
4270 o[31] := o[1] * o[30];
4271 o[32] := f.delta * f.delta;
4272 o[33] := -10.9153200808732 * o[1];
4273 o[34] := 13.2781565976477 + o[33];
4274 o[35] := o[34] * o[7];
4275 o[36] := (-6.9146446840086) + o[35];
4276 o[37] := o[2] * o[36];
4277 o[38] := (-2.53086309554280) + o[37];
4278 o[39] := o[38] * f.tau;
4279 o[40] := o[18] * o[5] * f.tau;
4280 f.f := (-15.7328452902390) + f.tau * (20.9443969743070 + ((-7.6867707878716) + o[3] * (2.61859477879540 + o[4] * ((-2.80807811486200) + o[1] * (1.20533696965170 - 0.0084566812812502 * o[6])))) * f.tau) + f.delta * (o[14] + f.delta * (0.38493460186671 + o[1] * ((-0.85214708824206) + o[2] * (4.8972281541877 + ((-3.05026172569650) + o[15] * (0.039420536879154 + 0.125584084243080 * o[2])) * f.tau)) + f.delta * ((-0.279993296987100) + o[1] * (1.38997995694600 + o[1] * ((-2.01899150235700) + o[16] * ((-0.0082147637173963) - 0.47596035734923 * o[17]))) + f.delta * (0.043984074473500 + o[1] * ((-0.44476435428739) + o[1] * (0.90572070719733 + 0.70522450087967 * o[19])) + f.delta * (f.delta * ((-0.0221754008730960) + o[1] * (0.094260751665092 + 0.164362784479610 * o[21]) + f.delta * ((-0.0135033722413480 * o[1]) + f.delta * ((-0.0148343453524720 * o[22]) + f.delta * (o[1] * (0.00057922953628084 + 0.0032308904703711 * o[21]) + f.delta * (0.000080964802996215 - 0.000044923899061815 * f.delta * o[22] - 0.000165576797950370 * f.tau))))) + (0.107705126263320 + o[1] * ((-0.32913623258954) - 0.50871062041158 * o[20])) * f.tau))))) + 1.06580700285130 * Modelica.Math.log(f.delta);
4281 f.fdelta := (1.06580700285130 + f.delta * (o[14] + f.delta * (0.76986920373342 + o[31] + f.delta * ((-0.83997989096130) + o[1] * (4.1699398708380 + o[1] * ((-6.0569745070710) + o[16] * ((-0.0246442911521889) - 1.42788107204769 * o[17]))) + f.delta * (0.175936297894000 + o[1] * ((-1.77905741714956) + o[1] * (3.6228828287893 + 2.82089800351868 * o[19])) + f.delta * (f.delta * ((-0.133052405238576) + o[1] * (0.56556450999055 + 0.98617670687766 * o[21]) + f.delta * ((-0.094523605689436 * o[1]) + f.delta * ((-0.118674762819776 * o[22]) + f.delta * (o[1] * (0.0052130658265276 + 0.0290780142333399 * o[21]) + f.delta * (0.00080964802996215 - 0.00049416288967996 * f.delta * o[22] - 0.00165576797950370 * f.tau))))) + (0.53852563131660 + o[1] * ((-1.64568116294770) - 2.54355310205790 * o[20])) * f.tau)))))) / f.delta;
4282 f.fdeltadelta := ((-1.06580700285130) + o[32] * (0.76986920373342 + o[31] + f.delta * ((-1.67995978192260) + o[1] * (8.3398797416760 + o[1] * ((-12.1139490141420) + o[16] * ((-0.049288582304378) - 2.85576214409538 * o[17]))) + f.delta * (0.52780889368200 + o[1] * ((-5.3371722514487) + o[1] * (10.8686484863680 + 8.4626940105560 * o[19])) + f.delta * (f.delta * ((-0.66526202619288) + o[1] * (2.82782254995276 + 4.9308835343883 * o[21]) + f.delta * ((-0.56714163413662 * o[1]) + f.delta * ((-0.83072333973843 * o[22]) + f.delta * (o[1] * (0.041704526612220 + 0.232624113866719 * o[21]) + f.delta * (0.0072868322696594 - 0.0049416288967996 * f.delta * o[22] - 0.0149019118155333 * f.tau))))) + (2.15410252526640 + o[1] * ((-6.5827246517908) - 10.1742124082316 * o[20])) * f.tau))))) / o[32];
4283 f.ftau := 20.9443969743070 + ((-15.3735415757432) + o[3] * (18.3301634515678 + o[4] * ((-28.0807811486200) + o[1] * (14.4640436358204 - 0.194503669468755 * o[6])))) * f.tau + f.delta * (o[39] + f.delta * (f.tau * ((-1.70429417648412) + o[2] * (29.3833689251262 + ((-21.3518320798755) + o[15] * (0.86725181134139 + 3.2651861903201 * o[2])) * f.tau)) + f.delta * ((2.77995991389200 + o[1] * ((-8.0759660094280) + o[16] * ((-0.131436219478341) - 12.3749692910800 * o[17]))) * f.tau + f.delta * (((-0.88952870857478) + o[1] * (3.6228828287893 + 18.3358370228714 * o[19])) * f.tau + f.delta * (0.107705126263320 + o[1] * ((-0.98740869776862) - 13.2264761307011 * o[20]) + f.delta * ((0.188521503330184 + 4.2734323964699 * o[21]) * f.tau + f.delta * ((-0.0270067444826960 * f.tau) + f.delta * ((-0.38569297916427 * o[40]) + f.delta * (f.delta * ((-0.000165576797950370) - 0.00116802137560719 * f.delta * o[40]) + (0.00115845907256168 + 0.084003152229649 * o[21]) * f.tau)))))))));
4284 f.ftautau := (-15.3735415757432) + o[3] * (109.980980709407 + o[4] * ((-252.727030337580) + o[1] * (159.104479994024 - 4.2790807283126 * o[6]))) + f.delta * ((-2.53086309554280) + o[2] * ((-34.573223420043) + (185.894192367068 - 174.645121293971 * o[1]) * o[7]) + f.delta * ((-1.70429417648412) + o[2] * (146.916844625631 + ((-128.110992479253) + o[15] * (18.2122880381691 + 81.629654758002 * o[2])) * f.tau) + f.delta * (2.77995991389200 + o[1] * ((-24.2278980282840) + o[16] * ((-1.97154329217511) - 309.374232277000 * o[17])) + f.delta * ((-0.88952870857478) + o[1] * (10.8686484863680 + 458.39592557179 * o[19]) + f.delta * (f.delta * (0.188521503330184 + 106.835809911747 * o[21] + f.delta * ((-0.0270067444826960) + f.delta * ((-9.6423244791068 * o[21]) + f.delta * (0.00115845907256168 + 2.10007880574121 * o[21] - 0.0292005343901797 * o[21] * o[32])))) + ((-1.97481739553724) - 330.66190326753 * o[20]) * f.tau)))));
4285 f.fdeltatau := o[39] + f.delta * (f.tau * ((-3.4085883529682) + o[2] * (58.766737850252 + ((-42.703664159751) + o[15] * (1.73450362268278 + 6.5303723806402 * o[2])) * f.tau)) + f.delta * ((8.3398797416760 + o[1] * ((-24.2278980282840) + o[16] * ((-0.39430865843502) - 37.124907873240 * o[17]))) * f.tau + f.delta * (((-3.5581148342991) + o[1] * (14.4915313151573 + 73.343348091486 * o[19])) * f.tau + f.delta * (0.53852563131660 + o[1] * ((-4.9370434888431) - 66.132380653505 * o[20]) + f.delta * ((1.13112901998110 + 25.6405943788192 * o[21]) * f.tau + f.delta * ((-0.189047211378872 * f.tau) + f.delta * ((-3.08554383331418 * o[40]) + f.delta * (f.delta * ((-0.00165576797950370) - 0.0128482351316791 * f.delta * o[40]) + (0.0104261316530551 + 0.75602837006684 * o[21]) * f.tau))))))));
4286 end f3;
4287
4288 function g5 "Base function for region 5: g(p,T)"
4289 extends Modelica.Icons.Function;
4290 input SI.Pressure p "Pressure";
4291 input SI.Temperature T "Temperature (K)";
4292 output Modelica.Media.Common.GibbsDerivs g "Dimensionless Gibbs function and derivatives w.r.t. pi and tau";
4293 protected
4294 Real[11] o "Vector of auxiliary variables";
4295 algorithm
4296 assert(p > 0.0, "IF97 medium function g5 called with too low pressure\n" + "p = " + String(p) + " Pa <= 0.0 Pa");
4297 assert(p <= data.PLIMIT5, "IF97 medium function g5: input pressure (= " + String(p) + " Pa) is higher than 10 Mpa in region 5");
4298 assert(T <= 2273.15, "IF97 medium function g5: input temperature (= " + String(T) + " K) is higher than limit of 2273.15K in region 5");
4299 g.p := p;
4300 g.T := T;
4301 g.R := data.RH2O;
4302 g.pi := p / data.PSTAR5;
4303 g.tau := data.TSTAR5 / T;
4304 o[1] := g.tau * g.tau;
4305 o[2] := -0.0045942820899910 * o[1];
4306 o[3] := 0.00217746787145710 + o[2];
4307 o[4] := o[3] * g.tau;
4308 o[5] := o[1] * g.tau;
4309 o[6] := o[1] * o[1];
4310 o[7] := o[6] * o[6];
4311 o[8] := o[7] * g.tau;
4312 o[9] := -7.9449656719138e-6 * o[8];
4313 o[10] := g.pi * g.pi;
4314 o[11] := -0.0137828462699730 * o[1];
4315 g.g := g.pi * ((-0.000125631835895920) + o[4] + g.pi * ((-3.9724828359569e-6 * o[8]) + 1.29192282897840e-7 * o[5] * g.pi)) + ((-0.0248051489334660) + g.tau * (0.36901534980333 + g.tau * ((-3.11613182139250) + g.tau * ((-13.1799836742010) + (6.8540841634434 - 0.32961626538917 * g.tau) * g.tau + Modelica.Math.log(g.pi))))) / o[5];
4316 g.gpi := (1.0 + g.pi * ((-0.000125631835895920) + o[4] + g.pi * (o[9] + 3.8757684869352e-7 * o[5] * g.pi))) / g.pi;
4317 g.gpipi := ((-1.00000000000000) + o[10] * (o[9] + 7.7515369738704e-7 * o[5] * g.pi)) / o[10];
4318 g.gtau := g.pi * (0.00217746787145710 + o[11] + g.pi * ((-0.000035752345523612 * o[7]) + 3.8757684869352e-7 * o[1] * g.pi)) + (0.074415446800398 + g.tau * ((-0.73803069960666) + (3.11613182139250 + o[1] * (6.8540841634434 - 0.65923253077834 * g.tau)) * g.tau)) / o[6];
4319 g.gtautau := ((-0.297661787201592) + g.tau * (2.21409209881998 + ((-6.2322636427850) - 0.65923253077834 * o[5]) * g.tau)) / (o[6] * g.tau) + g.pi * ((-0.0275656925399460 * g.tau) + g.pi * ((-0.000286018764188897 * o[1] * o[6] * g.tau) + 7.7515369738704e-7 * g.pi * g.tau));
4320 g.gtaupi := 0.00217746787145710 + o[11] + g.pi * ((-0.000071504691047224 * o[7]) + 1.16273054608056e-6 * o[1] * g.pi);
4321 end g5;
4322
4323 function tph1 "Inverse function for region 1: T(p,h)"
4324 extends Modelica.Icons.Function;
4325 input SI.Pressure p "Pressure";
4326 input SI.SpecificEnthalpy h "Specific enthalpy";
4327 output SI.Temperature T "Temperature (K)";
4328 protected
4329 Real pi "Dimensionless pressure";
4330 Real eta1 "Dimensionless specific enthalpy";
4331 Real[3] o "Vector of auxiliary variables";
4332 algorithm
4333 assert(p > triple.ptriple, "IF97 medium function tph1 called with too low pressure\n" + "p = " + String(p) + " Pa <= " + String(triple.ptriple) + " Pa (triple point pressure)");
4334 pi := p / data.PSTAR2;
4335 eta1 := h / data.HSTAR1 + 1.0;
4336 o[1] := eta1 * eta1;
4337 o[2] := o[1] * o[1];
4338 o[3] := o[2] * o[2];
4339 T := (-238.724899245210) - 13.3917448726020 * pi + eta1 * (404.21188637945 + 43.211039183559 * pi + eta1 * (113.497468817180 - 54.010067170506 * pi + eta1 * (30.5358922039160 * pi + eta1 * ((-6.5964749423638 * pi) + o[1] * ((-5.8457616048039) + o[2] * (pi * (0.0093965400878363 + ((-0.0000258586412820730) + 6.6456186191635e-8 * pi) * pi) + o[2] * o[3] * ((-0.000152854824131400) + o[1] * o[3] * ((-1.08667076953770e-6) + pi * (1.15736475053400e-7 + pi * ((-4.0644363084799e-9) + pi * (8.0670734103027e-11 + pi * ((-9.3477771213947e-13) + (5.8265442020601e-15 - 1.50201859535030e-17 * pi) * pi))))))))))));
4340 end tph1;
4341
4342 function tps1 "Inverse function for region 1: T(p,s)"
4343 extends Modelica.Icons.Function;
4344 input SI.Pressure p "Pressure";
4345 input SI.SpecificEntropy s "Specific entropy";
4346 output SI.Temperature T "Temperature (K)";
4347 protected
4348 constant SI.Pressure pstar = 1.0e6;
4349 constant SI.SpecificEntropy sstar = 1.0e3;
4350 Real pi "Dimensionless pressure";
4351 Real sigma1 "Dimensionless specific entropy";
4352 Real[6] o "Vector of auxiliary variables";
4353 algorithm
4354 pi := p / pstar;
4355 assert(p > triple.ptriple, "IF97 medium function tps1 called with too low pressure\n" + "p = " + String(p) + " Pa <= " + String(triple.ptriple) + " Pa (triple point pressure)");
4356 sigma1 := s / sstar + 2.0;
4357 o[1] := sigma1 * sigma1;
4358 o[2] := o[1] * o[1];
4359 o[3] := o[2] * o[2];
4360 o[4] := o[3] * o[3];
4361 o[5] := o[4] * o[4];
4362 o[6] := o[1] * o[2] * o[4];
4363 T := 174.782680583070 + sigma1 * (34.806930892873 + sigma1 * (6.5292584978455 + (0.33039981775489 + o[3] * ((-1.92813829231960e-7) - 2.49091972445730e-23 * o[2] * o[4])) * sigma1)) + pi * ((-0.261076364893320) + pi * (0.00056608900654837 + pi * (o[1] * o[3] * (2.64004413606890e-13 + 7.8124600459723e-29 * o[6]) - 3.07321999036680e-31 * o[5] * pi) + sigma1 * ((-0.00032635483139717) + sigma1 * (0.000044778286690632 + o[1] * o[2] * ((-5.1322156908507e-10) - 4.2522657042207e-26 * o[6]) * sigma1))) + sigma1 * (0.225929659815860 + sigma1 * ((-0.064256463395226) + sigma1 * (0.0078876289270526 + o[3] * sigma1 * (3.5672110607366e-10 + 1.73324969948950e-24 * o[1] * o[4] * sigma1)))));
4364 end tps1;
4365
4366 function tph2 "Reverse function for region 2: T(p,h)"
4367 extends Modelica.Icons.Function;
4368 input SI.Pressure p "Pressure";
4369 input SI.SpecificEnthalpy h "Specific enthalpy";
4370 output SI.Temperature T "Temperature (K)";
4371 protected
4372 Real pi "Dimensionless pressure";
4373 Real pi2b "Dimensionless pressure";
4374 Real pi2c "Dimensionless pressure";
4375 Real eta "Dimensionless specific enthalpy";
4376 Real etabc "Dimensionless specific enthalpy";
4377 Real eta2a "Dimensionless specific enthalpy";
4378 Real eta2b "Dimensionless specific enthalpy";
4379 Real eta2c "Dimensionless specific enthalpy";
4380 Real[8] o "Vector of auxiliary variables";
4381 algorithm
4382 pi := p * data.IPSTAR;
4383 eta := h * data.IHSTAR;
4384 etabc := h * 1.0e-3;
4385 if pi < 4.0 then
4386 eta2a := eta - 2.1;
4387 o[1] := eta2a * eta2a;
4388 o[2] := o[1] * o[1];
4389 o[3] := pi * pi;
4390 o[4] := o[3] * o[3];
4391 o[5] := o[3] * pi;
4392 T := 1089.89523182880 + (1.84457493557900 - 0.0061707422868339 * pi) * pi + eta2a * (849.51654495535 - 4.1792700549624 * pi + eta2a * ((-107.817480918260) + (6.2478196935812 - 0.310780466295830 * pi) * pi + eta2a * (33.153654801263 - 17.3445631081140 * pi + o[2] * ((-7.4232016790248) + pi * ((-200.581768620960) + 11.6708730771070 * pi) + o[1] * (271.960654737960 * pi + o[1] * ((-455.11318285818 * pi) + eta2a * (1.38657242832260 * o[4] + o[1] * o[2] * (3091.96886047550 * pi + o[1] * (11.7650487243560 + o[2] * ((-13551.3342407750 * o[5]) + o[2] * ((-62.459855192507 * o[3] * o[4] * pi) + o[2] * (o[4] * (235988.325565140 + 7399.9835474766 * pi) + o[1] * (19127.7292396600 * o[3] * o[4] + o[1] * (o[3] * (1.28127984040460e8 - 551966.97030060 * o[5]) + o[1] * ((-9.8554909623276e8 * o[3]) + o[1] * (2.82245469730020e9 * o[3] + o[1] * (o[3] * ((-3.5948971410703e9) + 3.7154085996233e6 * o[5]) + o[1] * pi * (252266.403578720 + pi * (1.72273499131970e9 + pi * (1.28487346646500e7 + ((-1.31052365450540e7) - 415351.64835634 * o[3]) * pi))))))))))))))))))));
4393 elseif pi < (0.12809002730136e-03 * etabc - 0.67955786399241) * etabc + 0.90584278514723e3 then
4394 eta2b := eta - 2.6;
4395 pi2b := pi - 2.0;
4396 o[1] := pi2b * pi2b;
4397 o[2] := o[1] * pi2b;
4398 o[3] := o[1] * o[1];
4399 o[4] := eta2b * eta2b;
4400 o[5] := o[4] * o[4];
4401 o[6] := o[4] * o[5];
4402 o[7] := o[5] * o[5];
4403 T := 1489.50410795160 + 0.93747147377932 * pi2b + eta2b * (743.07798314034 + o[2] * (0.000110328317899990 - 1.75652339694070e-18 * o[1] * o[3]) + eta2b * ((-97.708318797837) + pi2b * (3.3593118604916 + pi2b * ((-0.0218107553247610) + pi2b * (0.000189552483879020 + (2.86402374774560e-7 - 8.1456365207833e-14 * o[2]) * pi2b))) + o[5] * (3.3809355601454 * pi2b + o[4] * ((-0.108297844036770 * o[1]) + o[5] * (2.47424647056740 + (0.168445396719040 + o[1] * (0.00308915411605370 - 0.0000107798573575120 * pi2b)) * pi2b + o[6] * ((-0.63281320016026) + pi2b * (0.73875745236695 + ((-0.046333324635812) + o[1] * ((-0.000076462712454814) + 2.82172816350400e-7 * pi2b)) * pi2b) + o[6] * (1.13859521296580 + pi2b * ((-0.47128737436186) + o[1] * (0.00135555045549490 + (0.0000140523928183160 + 1.27049022719450e-6 * pi2b) * pi2b)) + o[5] * ((-0.47811863648625) + (0.150202731397070 + o[2] * ((-0.0000310838143314340) + o[1] * ((-1.10301392389090e-8) - 2.51805456829620e-11 * pi2b))) * pi2b + o[5] * o[7] * (0.0085208123431544 + pi2b * ((-0.00217641142197500) + pi2b * (0.000071280351959551 + o[1] * ((-1.03027382121030e-6) + (7.3803353468292e-8 + 8.6934156344163e-15 * o[3]) * pi2b))))))))))));
4404 else
4405 eta2c := eta - 1.8;
4406 pi2c := pi + 25.0;
4407 o[1] := pi2c * pi2c;
4408 o[2] := o[1] * o[1];
4409 o[3] := o[1] * o[2] * pi2c;
4410 o[4] := 1 / o[3];
4411 o[5] := o[1] * o[2];
4412 o[6] := eta2c * eta2c;
4413 o[7] := o[2] * o[2];
4414 o[8] := o[6] * o[6];
4415 T := eta2c * ((859777.22535580 + o[1] * (482.19755109255 + 1.12615974072300e-12 * o[5])) / o[1] + eta2c * (((-5.8340131851590e11) + (2.08255445631710e10 + 31081.0884227140 * o[2]) * pi2c) / o[5] + o[6] * (o[8] * (o[6] * (1.23245796908320e-7 * o[5] + o[6] * ((-1.16069211309840e-6 * o[5]) + o[8] * (0.0000278463670885540 * o[5] + ((-0.00059270038474176 * o[5]) + 0.00129185829918780 * o[5] * o[6]) * o[8]))) - 10.8429848800770 * pi2c) + o[4] * (7.3263350902181e12 + o[7] * (3.7966001272486 + ((-0.045364172676660) - 1.78049822406860e-11 * o[2]) * pi2c))))) + o[4] * ((-3.2368398555242e12) + pi2c * (3.5825089945447e11 + pi2c * ((-1.07830682174700e10) + o[1] * pi2c * (610747.83564516 + pi2c * ((-25745.7236041700) + (1208.23158659360 + 1.45591156586980e-13 * o[5]) * pi2c)))));
4416 end if;
4417 end tph2;
4418
4419 function tps2a "Reverse function for region 2a: T(p,s)"
4420 extends Modelica.Icons.Function;
4421 input SI.Pressure p "Pressure";
4422 input SI.SpecificEntropy s "Specific entropy";
4423 output SI.Temperature T "Temperature (K)";
4424 protected
4425 Real[12] o "Vector of auxiliary variables";
4426 constant Real IPSTAR = 1.0e-6 "Scaling variable";
4427 constant Real ISSTAR2A = 1 / 2000.0 "Scaling variable";
4428 Real pi "Dimensionless pressure";
4429 Real sigma2a "Dimensionless specific entropy";
4430 algorithm
4431 pi := p * IPSTAR;
4432 sigma2a := s * ISSTAR2A - 2.0;
4433 o[1] := pi ^ 0.5;
4434 o[2] := sigma2a * sigma2a;
4435 o[3] := o[2] * o[2];
4436 o[4] := o[3] * o[3];
4437 o[5] := o[4] * o[4];
4438 o[6] := pi ^ 0.25;
4439 o[7] := o[2] * o[4] * o[5];
4440 o[8] := 1 / o[7];
4441 o[9] := o[3] * sigma2a;
4442 o[10] := o[2] * o[3] * sigma2a;
4443 o[11] := o[3] * o[4] * sigma2a;
4444 o[12] := o[2] * sigma2a;
4445 T := (((-392359.83861984) + (515265.73827270 + o[3] * (40482.443161048 + o[2] * o[3] * ((-321.93790923902) + o[2] * (96.961424218694 - 22.8678463717730 * sigma2a)))) * sigma2a) / (o[4] * o[5]) + o[6] * (((-449429.14124357) + o[3] * ((-5011.8336020166) + 0.35684463560015 * o[4] * sigma2a)) / (o[2] * o[5] * sigma2a) + o[6] * (o[8] * (44235.335848190 + o[9] * ((-13673.3888117080) + o[3] * (421632.60207864 + (22516.9258374750 + o[10] * (474.42144865646 - 149.311307976470 * sigma2a)) * sigma2a))) + o[6] * (((-197811.263204520) - 23554.3994707600 * sigma2a) / (o[2] * o[3] * o[4] * sigma2a) + o[6] * (((-19070.6163020760) + o[11] * (55375.669883164 + (3829.3691437363 - 603.91860580567 * o[2]) * o[3])) * o[8] + o[6] * ((1936.31026203310 + o[2] * (4266.0643698610 + o[2] * o[3] * o[4] * ((-5978.0638872718) - 704.01463926862 * o[9]))) / (o[2] * o[4] * o[5] * sigma2a) + o[1] * ((338.36784107553 + o[12] * (20.8627866351870 + (0.033834172656196 - 0.000043124428414893 * o[12]) * o[3])) * sigma2a + o[6] * (166.537913564120 + sigma2a * ((-139.862920558980) + o[3] * ((-0.78849547999872) + (0.072132411753872 + o[3] * ((-0.0059754839398283) + ((-0.0000121413589539040) + 2.32270967338710e-7 * o[2]) * o[3])) * sigma2a)) + o[6] * ((-10.5384635661940) + o[3] * (2.07189254965020 + ((-0.072193155260427) + 2.07498870811200e-7 * o[4]) * o[9]) + o[6] * (o[6] * (o[12] * (0.210375278936190 + 0.000256812397299990 * o[3] * o[4]) + ((-0.0127990029337810) - 8.2198102652018e-6 * o[11]) * o[6] * o[9]) + o[10] * ((-0.0183406579113790) + 2.90362723486960e-7 * o[2] * o[4] * sigma2a))))))))))) / (o[1] * pi);
4446 end tps2a;
4447
4448 function tps2b "Reverse function for region 2b: T(p,s)"
4449 extends Modelica.Icons.Function;
4450 input SI.Pressure p "Pressure";
4451 input SI.SpecificEntropy s "Specific entropy";
4452 output SI.Temperature T "Temperature (K)";
4453 protected
4454 Real[8] o "Vector of auxiliary variables";
4455 constant Real IPSTAR = 1.0e-6 "Scaling variable";
4456 constant Real ISSTAR2B = 1 / 785.3 "Scaling variable";
4457 Real pi "Dimensionless pressure";
4458 Real sigma2b "Dimensionless specific entropy";
4459 algorithm
4460 pi := p * IPSTAR;
4461 sigma2b := 10.0 - s * ISSTAR2B;
4462 o[1] := pi * pi;
4463 o[2] := o[1] * o[1];
4464 o[3] := sigma2b * sigma2b;
4465 o[4] := o[3] * o[3];
4466 o[5] := o[4] * o[4];
4467 o[6] := o[3] * o[5] * sigma2b;
4468 o[7] := o[3] * o[5];
4469 o[8] := o[3] * sigma2b;
4470 T := (316876.65083497 + 20.8641758818580 * o[6] + pi * ((-398593.99803599) - 21.8160585188770 * o[6] + pi * (223697.851942420 + ((-2784.17034458170) + 9.9207436071480 * o[7]) * sigma2b + pi * ((-75197.512299157) + (2970.86059511580 + o[7] * ((-3.4406878548526) + 0.38815564249115 * sigma2b)) * sigma2b + pi * (17511.2950857500 + sigma2b * ((-1423.71128544490) + (1.09438033641670 + 0.89971619308495 * o[4]) * o[4] * sigma2b) + pi * ((-3375.9740098958) + (471.62885818355 + o[4] * ((-1.91882419936790) + o[8] * (0.41078580492196 - 0.33465378172097 * sigma2b))) * sigma2b + pi * (1387.00347775050 + sigma2b * ((-406.63326195838) + sigma2b * (41.727347159610 + o[3] * (2.19325494345320 + sigma2b * ((-1.03200500090770) + (0.35882943516703 + 0.0052511453726066 * o[8]) * sigma2b)))) + pi * (12.8389164507050 + sigma2b * ((-2.86424372193810) + sigma2b * (0.56912683664855 + ((-0.099962954584931) + o[4] * ((-0.0032632037778459) + 0.000233209225767230 * sigma2b)) * sigma2b)) + pi * ((-0.153348098574500) + (0.0290722882399020 + 0.00037534702741167 * o[4]) * sigma2b + pi * (0.00172966917024110 + ((-0.00038556050844504) - 0.000035017712292608 * o[3]) * sigma2b + pi * ((-0.0000145663936314920) + 5.6420857267269e-6 * sigma2b + pi * (4.1286150074605e-8 + ((-2.06846711188240e-8) + 1.64093936747250e-9 * sigma2b) * sigma2b)))))))))))) / (o[1] * o[2]);
4471 end tps2b;
4472
4473 function tps2c "Reverse function for region 2c: T(p,s)"
4474 extends Modelica.Icons.Function;
4475 input SI.Pressure p "Pressure";
4476 input SI.SpecificEntropy s "Specific entropy";
4477 output SI.Temperature T "Temperature (K)";
4478 protected
4479 constant Real IPSTAR = 1.0e-6 "Scaling variable";
4480 constant Real ISSTAR2C = 1 / 2925.1 "Scaling variable";
4481 Real pi "Dimensionless pressure";
4482 Real sigma2c "Dimensionless specific entropy";
4483 Real[3] o "Vector of auxiliary variables";
4484 algorithm
4485 pi := p * IPSTAR;
4486 sigma2c := 2.0 - s * ISSTAR2C;
4487 o[1] := pi * pi;
4488 o[2] := sigma2c * sigma2c;
4489 o[3] := o[2] * o[2];
4490 T := (909.68501005365 + 2404.56670884200 * sigma2c + pi * ((-591.62326387130) + pi * (541.45404128074 + sigma2c * ((-270.983084111920) + (979.76525097926 - 469.66772959435 * sigma2c) * sigma2c) + pi * (14.3992746047230 + ((-19.1042042304290) + o[2] * (5.3299167111971 - 21.2529753759340 * sigma2c)) * sigma2c + pi * ((-0.311473344137600) + (0.60334840894623 - 0.042764839702509 * sigma2c) * sigma2c + pi * (0.0058185597255259 + ((-0.0145970082847530) + 0.0056631175631027 * o[3]) * sigma2c + pi * ((-0.000076155864584577) + sigma2c * (0.000224403429193320 - 0.0000125610950134130 * o[2] * sigma2c) + pi * (6.3323132660934e-7 + ((-2.05419896753750e-6) + 3.6405370390082e-8 * sigma2c) * sigma2c + pi * ((-2.97598977892150e-9) + 1.01366185297630e-8 * sigma2c + pi * (5.9925719692351e-12 + sigma2c * ((-2.06778701051640e-11) + o[2] * ((-2.08742781818860e-11) + (1.01621668250890e-10 - 1.64298282813470e-10 * sigma2c) * sigma2c)))))))))))) / o[1];
4491 end tps2c;
4492
4493 function tps2 "Reverse function for region 2: T(p,s)"
4494 extends Modelica.Icons.Function;
4495 input SI.Pressure p "Pressure";
4496 input SI.SpecificEntropy s "Specific entropy";
4497 output SI.Temperature T "Temperature (K)";
4498 protected
4499 Real pi "Dimensionless pressure";
4500 constant SI.SpecificEntropy SLIMIT = 5.85e3 "Subregion boundary specific entropy between regions 2a and 2b";
4501 algorithm
4502 if p < 4.0e6 then
4503 T := tps2a(p, s);
4504 elseif s > SLIMIT then
4505 T := tps2b(p, s);
4506 else
4507 T := tps2c(p, s);
4508 end if;
4509 end tps2;
4510
4511 function tsat "Region 4 saturation temperature as a function of pressure"
4512 extends Modelica.Icons.Function;
4513 input SI.Pressure p "Pressure";
4514 output SI.Temperature t_sat "Temperature";
4515 protected
4516 Real pi "Dimensionless pressure";
4517 Real[20] o "Vector of auxiliary variables";
4518 algorithm
4519 assert(p > triple.ptriple, "IF97 medium function tsat called with too low pressure\n" + "p = " + String(p) + " Pa <= " + String(triple.ptriple) + " Pa (triple point pressure)");
4520 pi := min(p, data.PCRIT) * data.IPSTAR;
4521 o[1] := pi ^ 0.25;
4522 o[2] := -3.2325550322333e6 * o[1];
4523 o[3] := pi ^ 0.5;
4524 o[4] := -724213.16703206 * o[3];
4525 o[5] := 405113.40542057 + o[2] + o[4];
4526 o[6] := -17.0738469400920 * o[1];
4527 o[7] := 14.9151086135300 + o[3] + o[6];
4528 o[8] := -4.0 * o[5] * o[7];
4529 o[9] := 12020.8247024700 * o[1];
4530 o[10] := 1167.05214527670 * o[3];
4531 o[11] := (-4823.2657361591) + o[10] + o[9];
4532 o[12] := o[11] * o[11];
4533 o[13] := o[12] + o[8];
4534 o[14] := o[13] ^ 0.5;
4535 o[15] := -o[14];
4536 o[16] := -12020.8247024700 * o[1];
4537 o[17] := -1167.05214527670 * o[3];
4538 o[18] := 4823.2657361591 + o[15] + o[16] + o[17];
4539 o[19] := 1 / o[18];
4540 o[20] := 2.0 * o[19] * o[5];
4541 t_sat := 0.5 * (650.17534844798 + o[20] - ((-4.0 * ((-0.238555575678490) + 1300.35069689596 * o[19] * o[5])) + (650.17534844798 + o[20]) ^ 2.0) ^ 0.5);
4542 annotation(derivative = tsat_der);
4543 end tsat;
4544
4545 function dtsatofp "Derivative of saturation temperature w.r.t. pressure"
4546 extends Modelica.Icons.Function;
4547 input SI.Pressure p "Pressure";
4548 output Real dtsat(unit = "K/Pa") "Derivative of T w.r.t. p";
4549 protected
4550 Real pi "Dimensionless pressure";
4551 Real[49] o "Vector of auxiliary variables";
4552 algorithm
4553 pi := max(Modelica.Constants.small, p * data.IPSTAR);
4554 o[1] := pi ^ 0.75;
4555 o[2] := 1 / o[1];
4556 o[3] := -4.268461735023 * o[2];
4557 o[4] := sqrt(pi);
4558 o[5] := 1 / o[4];
4559 o[6] := 0.5 * o[5];
4560 o[7] := o[3] + o[6];
4561 o[8] := pi ^ 0.25;
4562 o[9] := -3.2325550322333e6 * o[8];
4563 o[10] := -724213.16703206 * o[4];
4564 o[11] := 405113.40542057 + o[10] + o[9];
4565 o[12] := -4 * o[11] * o[7];
4566 o[13] := -808138.758058325 * o[2];
4567 o[14] := -362106.58351603 * o[5];
4568 o[15] := o[13] + o[14];
4569 o[16] := -17.073846940092 * o[8];
4570 o[17] := 14.91510861353 + o[16] + o[4];
4571 o[18] := -4 * o[15] * o[17];
4572 o[19] := 3005.2061756175 * o[2];
4573 o[20] := 583.52607263835 * o[5];
4574 o[21] := o[19] + o[20];
4575 o[22] := 12020.82470247 * o[8];
4576 o[23] := 1167.0521452767 * o[4];
4577 o[24] := (-4823.2657361591) + o[22] + o[23];
4578 o[25] := 2.0 * o[21] * o[24];
4579 o[26] := o[12] + o[18] + o[25];
4580 o[27] := -4.0 * o[11] * o[17];
4581 o[28] := o[24] * o[24];
4582 o[29] := o[27] + o[28];
4583 o[30] := sqrt(o[29]);
4584 o[31] := 1 / o[30];
4585 o[32] := -o[30];
4586 o[33] := -12020.82470247 * o[8];
4587 o[34] := -1167.0521452767 * o[4];
4588 o[35] := 4823.2657361591 + o[32] + o[33] + o[34];
4589 o[36] := o[30];
4590 o[37] := (-4823.2657361591) + o[22] + o[23] + o[36];
4591 o[38] := o[37] * o[37];
4592 o[39] := 1 / o[38];
4593 o[40] := -1.72207339365771 * o[30];
4594 o[41] := 21592.2055343628 * o[8];
4595 o[42] := o[30] * o[8];
4596 o[43] := -8192.87114842946 * o[4];
4597 o[44] := -0.510632954559659 * o[30] * o[4];
4598 o[45] := -3100.02526152368 * o[1];
4599 o[46] := pi;
4600 o[47] := 1295.95640782102 * o[46];
4601 o[48] := 2862.09212505088 + o[40] + o[41] + o[42] + o[43] + o[44] + o[45] + o[47];
4602 o[49] := 1 / (o[35] * o[35]);
4603 dtsat := data.IPSTAR * 0.5 * (2.0 * o[15] / o[35] - 2. * o[11] * ((-3005.2061756175 * o[2]) - 0.5 * o[26] * o[31] - 583.52607263835 * o[5]) * o[49] - 20953.46356643991 * (o[39] * (1295.95640782102 + 5398.05138359071 * o[2] + 0.25 * o[2] * o[30] - 0.861036696828853 * o[26] * o[31] - 0.255316477279829 * o[26] * o[31] * o[4] - 4096.43557421473 * o[5] - 0.255316477279829 * o[30] * o[5] - 2325.01894614276 / o[8] + 0.5 * o[26] * o[31] * o[8]) - 2.0 * (o[19] + o[20] + 0.5 * o[26] * o[31]) * o[48] * o[37] ^ (-3)) / sqrt(o[39] * o[48]));
4604 end dtsatofp;
4605
4606 function tsat_der "Derivative function for tsat"
4607 extends Modelica.Icons.Function;
4608 input SI.Pressure p "Pressure";
4609 input Real der_p(unit = "Pa/s") "Pressure derivative";
4610 output Real der_tsat(unit = "K/s") "Temperature derivative";
4611 protected
4612 Real dtp;
4613 algorithm
4614 dtp := dtsatofp(p);
4615 der_tsat := dtp * der_p;
4616 end tsat_der;
4617
4618 function psat "Region 4 saturation pressure as a function of temperature"
4619 extends Modelica.Icons.Function;
4620 input SI.Temperature T "Temperature (K)";
4621 output SI.Pressure p_sat "Pressure";
4622 protected
4623 Real[8] o "Vector of auxiliary variables";
4624 Real Tlim = min(T, data.TCRIT);
4625 algorithm
4626 assert(T >= 273.16, "IF97 medium function psat: input temperature (= " + String(triple.Ttriple) + " K).\n" + "lower than the triple point temperature 273.16 K");
4627 o[1] := (-650.17534844798) + Tlim;
4628 o[2] := 1 / o[1];
4629 o[3] := -0.238555575678490 * o[2];
4630 o[4] := o[3] + Tlim;
4631 o[5] := -4823.2657361591 * o[4];
4632 o[6] := o[4] * o[4];
4633 o[7] := 14.9151086135300 * o[6];
4634 o[8] := 405113.40542057 + o[5] + o[7];
4635 p_sat := 16.0e6 * o[8] * o[8] * o[8] * o[8] * 1 / (3.2325550322333e6 - 12020.8247024700 * o[4] + 17.0738469400920 * o[6] + ((-4.0 * ((-724213.16703206) + 1167.05214527670 * o[4] + o[6]) * o[8]) + ((-3.2325550322333e6) + 12020.8247024700 * o[4] - 17.0738469400920 * o[6]) ^ 2.0) ^ 0.5) ^ 4.0;
4636 annotation(derivative = psat_der);
4637 end psat;
4638
4639 function dptofT "Derivative of pressure w.r.t. temperature along the saturation pressure curve"
4640 extends Modelica.Icons.Function;
4641 input SI.Temperature T "Temperature (K)";
4642 output Real dpt(unit = "Pa/K") "Temperature derivative of pressure";
4643 protected
4644 Real[31] o "Vector of auxiliary variables";
4645 Real Tlim "Temperature limited to TCRIT";
4646 algorithm
4647 Tlim := min(T, data.TCRIT);
4648 o[1] := (-650.17534844798) + Tlim;
4649 o[2] := 1 / o[1];
4650 o[3] := -0.238555575678490 * o[2];
4651 o[4] := o[3] + Tlim;
4652 o[5] := -4823.2657361591 * o[4];
4653 o[6] := o[4] * o[4];
4654 o[7] := 14.9151086135300 * o[6];
4655 o[8] := 405113.40542057 + o[5] + o[7];
4656 o[9] := o[8] * o[8];
4657 o[10] := o[9] * o[9];
4658 o[11] := o[1] * o[1];
4659 o[12] := 1 / o[11];
4660 o[13] := 0.238555575678490 * o[12];
4661 o[14] := 1.00000000000000 + o[13];
4662 o[15] := 12020.8247024700 * o[4];
4663 o[16] := -17.0738469400920 * o[6];
4664 o[17] := (-3.2325550322333e6) + o[15] + o[16];
4665 o[18] := -4823.2657361591 * o[14];
4666 o[19] := 29.8302172270600 * o[14] * o[4];
4667 o[20] := o[18] + o[19];
4668 o[21] := 1167.05214527670 * o[4];
4669 o[22] := (-724213.16703206) + o[21] + o[6];
4670 o[23] := o[17] * o[17];
4671 o[24] := -4.0000000000000 * o[22] * o[8];
4672 o[25] := o[23] + o[24];
4673 o[26] := sqrt(o[25]);
4674 o[27] := -12020.8247024700 * o[4];
4675 o[28] := 17.0738469400920 * o[6];
4676 o[29] := 3.2325550322333e6 + o[26] + o[27] + o[28];
4677 o[30] := o[29] * o[29];
4678 o[31] := o[30] * o[30];
4679 dpt := 1e6 * ((-64.0 * o[10] * ((-12020.8247024700 * o[14]) + 34.147693880184 * o[14] * o[4] + 0.5 * ((-4.0 * o[20] * o[22]) + 2.00000000000000 * o[17] * (12020.8247024700 * o[14] - 34.147693880184 * o[14] * o[4]) - 4.0 * (1167.05214527670 * o[14] + 2.0 * o[14] * o[4]) * o[8]) / o[26])) / (o[29] * o[31]) + 64. * o[20] * o[8] * o[9] / o[31]);
4680 end dptofT;
4681
4682 function psat_der "Derivative function for psat"
4683 extends Modelica.Icons.Function;
4684 input SI.Temperature T "Temperature (K)";
4685 input Real der_T(unit = "K/s") "Temperature derivative";
4686 output Real der_psat(unit = "Pa/s") "Pressure";
4687 protected
4688 Real dpt;
4689 algorithm
4690 dpt := dptofT(T);
4691 der_psat := dpt * der_T;
4692 end psat_der;
4693
4694 function h3ab_p "Region 3 a b boundary for pressure/enthalpy"
4695 extends Modelica.Icons.Function;
4696 output SI.SpecificEnthalpy h "Enthalpy";
4697 input SI.Pressure p "Pressure";
4698 protected
4699 constant Real[:] n = {0.201464004206875e4, 0.374696550136983e1, -0.219921901054187e-1, 0.875131686009950e-4};
4700 constant SI.SpecificEnthalpy hstar = 1000 "Normalization enthalpy";
4701 constant SI.Pressure pstar = 1e6 "Normalization pressure";
4702 Real pi = p / pstar "Normalized specific pressure";
4703 algorithm
4704 h := (n[1] + n[2] * pi + n[3] * pi ^ 2 + n[4] * pi ^ 3) * hstar;
4705 end h3ab_p;
4706
4707 function T3a_ph "Region 3 a: inverse function T(p,h)"
4708 extends Modelica.Icons.Function;
4709 input SI.Pressure p "Pressure";
4710 input SI.SpecificEnthalpy h "Specific enthalpy";
4711 output SI.Temp_K T "Temperature";
4712 protected
4713 constant Real[:] n = {-0.133645667811215e-6, 0.455912656802978e-5, -0.146294640700979e-4, 0.639341312970080e-2, 0.372783927268847e3, -0.718654377460447e4, 0.573494752103400e6, -0.267569329111439e7, -0.334066283302614e-4, -0.245479214069597e-1, 0.478087847764996e2, 0.764664131818904e-5, 0.128350627676972e-2, 0.171219081377331e-1, -0.851007304583213e1, -0.136513461629781e-1, -0.384460997596657e-5, 0.337423807911655e-2, -0.551624873066791, 0.729202277107470, -0.992522757376041e-2, -0.119308831407288, 0.793929190615421, 0.454270731799386, 0.209998591259910, -0.642109823904738e-2, -0.235155868604540e-1, 0.252233108341612e-2, -0.764885133368119e-2, 0.136176427574291e-1, -0.133027883575669e-1};
4714 constant Real[:] I = {-12, -12, -12, -12, -12, -12, -12, -12, -10, -10, -10, -8, -8, -8, -8, -5, -3, -2, -2, -2, -1, -1, 0, 0, 1, 3, 3, 4, 4, 10, 12};
4715 constant Real[:] J = {0, 1, 2, 6, 14, 16, 20, 22, 1, 5, 12, 0, 2, 4, 10, 2, 0, 1, 3, 4, 0, 2, 0, 1, 1, 0, 1, 0, 3, 4, 5};
4716 constant SI.SpecificEnthalpy hstar = 2300e3 "Normalization enthalpy";
4717 constant SI.Pressure pstar = 100e6 "Normalization pressure";
4718 constant SI.Temp_K Tstar = 760 "Normalization temperature";
4719 Real pi = p / pstar "Normalized specific pressure";
4720 Real eta = h / hstar "Normalized specific enthalpy";
4721 algorithm
4722 T := sum(n[i] * (pi + 0.240) ^ I[i] * (eta - 0.615) ^ J[i] for i in 1:31) * Tstar;
4723 end T3a_ph;
4724
4725 function T3b_ph "Region 3 b: inverse function T(p,h)"
4726 extends Modelica.Icons.Function;
4727 input SI.Pressure p "Pressure";
4728 input SI.SpecificEnthalpy h "Specific enthalpy";
4729 output SI.Temp_K T "Temperature";
4730 protected
4731 constant Real[:] n = {0.323254573644920e-4, -0.127575556587181e-3, -0.475851877356068e-3, 0.156183014181602e-2, 0.105724860113781, -0.858514221132534e2, 0.724140095480911e3, 0.296475810273257e-2, -0.592721983365988e-2, -0.126305422818666e-1, -0.115716196364853, 0.849000969739595e2, -0.108602260086615e-1, 0.154304475328851e-1, 0.750455441524466e-1, 0.252520973612982e-1, -0.602507901232996e-1, -0.307622221350501e1, -0.574011959864879e-1, 0.503471360939849e1, -0.925081888584834, 0.391733882917546e1, -0.773146007130190e2, 0.949308762098587e4, -0.141043719679409e7, 0.849166230819026e7, 0.861095729446704, 0.323346442811720, 0.873281936020439, -0.436653048526683, 0.286596714529479, -0.131778331276228, 0.676682064330275e-2};
4732 constant Real[:] I = {-12, -12, -10, -10, -10, -10, -10, -8, -8, -8, -8, -8, -6, -6, -6, -4, -4, -3, -2, -2, -1, -1, -1, -1, -1, -1, 0, 0, 1, 3, 5, 6, 8};
4733 constant Real[:] J = {0, 1, 0, 1, 5, 10, 12, 0, 1, 2, 4, 10, 0, 1, 2, 0, 1, 5, 0, 4, 2, 4, 6, 10, 14, 16, 0, 2, 1, 1, 1, 1, 1};
4734 constant SI.Temp_K Tstar = 860 "Normalization temperature";
4735 constant SI.Pressure pstar = 100e6 "Normalization pressure";
4736 constant SI.SpecificEnthalpy hstar = 2800e3 "Normalization enthalpy";
4737 Real pi = p / pstar "Normalized specific pressure";
4738 Real eta = h / hstar "Normalized specific enthalpy";
4739 algorithm
4740 T := sum(n[i] * (pi + 0.298) ^ I[i] * (eta - 0.720) ^ J[i] for i in 1:33) * Tstar;
4741 end T3b_ph;
4742
4743 function v3a_ph "Region 3 a: inverse function v(p,h)"
4744 extends Modelica.Icons.Function;
4745 input SI.Pressure p "Pressure";
4746 input SI.SpecificEnthalpy h "Specific enthalpy";
4747 output SI.SpecificVolume v "Specific volume";
4748 protected
4749 constant Real[:] n = {0.529944062966028e-2, -0.170099690234461, 0.111323814312927e2, -0.217898123145125e4, -0.506061827980875e-3, 0.556495239685324, -0.943672726094016e1, -0.297856807561527, 0.939353943717186e2, 0.192944939465981e-1, 0.421740664704763, -0.368914126282330e7, -0.737566847600639e-2, -0.354753242424366, -0.199768169338727e1, 0.115456297059049e1, 0.568366875815960e4, 0.808169540124668e-2, 0.172416341519307, 0.104270175292927e1, -0.297691372792847, 0.560394465163593, 0.275234661176914, -0.148347894866012, -0.651142513478515e-1, -0.292468715386302e1, 0.664876096952665e-1, 0.352335014263844e1, -0.146340792313332e-1, -0.224503486668184e1, 0.110533464706142e1, -0.408757344495612e-1};
4750 constant Real[:] I = {-12, -12, -12, -12, -10, -10, -10, -8, -8, -6, -6, -6, -4, -4, -3, -2, -2, -1, -1, -1, -1, 0, 0, 1, 1, 1, 2, 2, 3, 4, 5, 8};
4751 constant Real[:] J = {6, 8, 12, 18, 4, 7, 10, 5, 12, 3, 4, 22, 2, 3, 7, 3, 16, 0, 1, 2, 3, 0, 1, 0, 1, 2, 0, 2, 0, 2, 2, 2};
4752 constant SI.Volume vstar = 0.0028 "Normalization temperature";
4753 constant SI.Pressure pstar = 100e6 "Normalization pressure";
4754 constant SI.SpecificEnthalpy hstar = 2100e3 "Normalization enthalpy";
4755 Real pi = p / pstar "Normalized specific pressure";
4756 Real eta = h / hstar "Normalized specific enthalpy";
4757 algorithm
4758 v := sum(n[i] * (pi + 0.128) ^ I[i] * (eta - 0.727) ^ J[i] for i in 1:32) * vstar;
4759 end v3a_ph;
4760
4761 function v3b_ph "Region 3 b: inverse function v(p,h)"
4762 extends Modelica.Icons.Function;
4763 input SI.Pressure p "Pressure";
4764 input SI.SpecificEnthalpy h "Specific enthalpy";
4765 output SI.SpecificVolume v "Specific volume";
4766 protected
4767 constant Real[:] n = {-0.225196934336318e-8, 0.140674363313486e-7, 0.233784085280560e-5, -0.331833715229001e-4, 0.107956778514318e-2, -0.271382067378863, 0.107202262490333e1, -0.853821329075382, -0.215214194340526e-4, 0.769656088222730e-3, -0.431136580433864e-2, 0.453342167309331, -0.507749535873652, -0.100475154528389e3, -0.219201924648793, -0.321087965668917e1, 0.607567815637771e3, 0.557686450685932e-3, 0.187499040029550, 0.905368030448107e-2, 0.285417173048685, 0.329924030996098e-1, 0.239897419685483, 0.482754995951394e1, -0.118035753702231e2, 0.169490044091791, -0.179967222507787e-1, 0.371810116332674e-1, -0.536288335065096e-1, 0.160697101092520e1};
4768 constant Real[:] I = {-12, -12, -8, -8, -8, -8, -8, -8, -6, -6, -6, -6, -6, -6, -4, -4, -4, -3, -3, -2, -2, -1, -1, -1, -1, 0, 1, 1, 2, 2};
4769 constant Real[:] J = {0, 1, 0, 1, 3, 6, 7, 8, 0, 1, 2, 5, 6, 10, 3, 6, 10, 0, 2, 1, 2, 0, 1, 4, 5, 0, 0, 1, 2, 6};
4770 constant SI.Volume vstar = 0.0088 "Normalization temperature";
4771 constant SI.Pressure pstar = 100e6 "Normalization pressure";
4772 constant SI.SpecificEnthalpy hstar = 2800e3 "Normalization enthalpy";
4773 Real pi = p / pstar "Normalized specific pressure";
4774 Real eta = h / hstar "Normalized specific enthalpy";
4775 algorithm
4776 v := sum(n[i] * (pi + 0.0661) ^ I[i] * (eta - 0.720) ^ J[i] for i in 1:30) * vstar;
4777 end v3b_ph;
4778
4779 function T3a_ps "Region 3 a: inverse function T(p,s)"
4780 extends Modelica.Icons.Function;
4781 input SI.Pressure p "Pressure";
4782 input SI.SpecificEntropy s "Specific entropy";
4783 output SI.Temp_K T "Temperature";
4784 protected
4785 constant Real[:] n = {0.150042008263875e10, -0.159397258480424e12, 0.502181140217975e-3, -0.672057767855466e2, 0.145058545404456e4, -0.823889534888890e4, -0.154852214233853, 0.112305046746695e2, -0.297000213482822e2, 0.438565132635495e11, 0.137837838635464e-2, -0.297478527157462e1, 0.971777947349413e13, -0.571527767052398e-4, 0.288307949778420e5, -0.744428289262703e14, 0.128017324848921e2, -0.368275545889071e3, 0.664768904779177e16, 0.449359251958880e-1, -0.422897836099655e1, -0.240614376434179, -0.474341365254924e1, 0.724093999126110, 0.923874349695897, 0.399043655281015e1, 0.384066651868009e-1, -0.359344365571848e-2, -0.735196448821653, 0.188367048396131, 0.141064266818704e-3, -0.257418501496337e-2, 0.123220024851555e-2};
4786 constant Real[:] I = {-12, -12, -10, -10, -10, -10, -8, -8, -8, -8, -6, -6, -6, -5, -5, -5, -4, -4, -4, -2, -2, -1, -1, 0, 0, 0, 1, 2, 2, 3, 8, 8, 10};
4787 constant Real[:] J = {28, 32, 4, 10, 12, 14, 5, 7, 8, 28, 2, 6, 32, 0, 14, 32, 6, 10, 36, 1, 4, 1, 6, 0, 1, 4, 0, 0, 3, 2, 0, 1, 2};
4788 constant SI.Temp_K Tstar = 760 "Normalization temperature";
4789 constant SI.Pressure pstar = 100e6 "Normalization pressure";
4790 constant SI.SpecificEntropy sstar = 4.4e3 "Normalization entropy";
4791 Real pi = p / pstar "Normalized specific pressure";
4792 Real sigma = s / sstar "Normalized specific entropy";
4793 algorithm
4794 T := sum(n[i] * (pi + 0.240) ^ I[i] * (sigma - 0.703) ^ J[i] for i in 1:33) * Tstar;
4795 end T3a_ps;
4796
4797 function T3b_ps "Region 3 b: inverse function T(p,s)"
4798 extends Modelica.Icons.Function;
4799 input SI.Pressure p "Pressure";
4800 input SI.SpecificEntropy s "Specific entropy";
4801 output SI.Temp_K T "Temperature";
4802 protected
4803 constant Real[:] n = {0.527111701601660, -0.401317830052742e2, 0.153020073134484e3, -0.224799398218827e4, -0.193993484669048, -0.140467557893768e1, 0.426799878114024e2, 0.752810643416743, 0.226657238616417e2, -0.622873556909932e3, -0.660823667935396, 0.841267087271658, -0.253717501764397e2, 0.485708963532948e3, 0.880531517490555e3, 0.265015592794626e7, -0.359287150025783, -0.656991567673753e3, 0.241768149185367e1, 0.856873461222588, 0.655143675313458, -0.213535213206406, 0.562974957606348e-2, -0.316955725450471e15, -0.699997000152457e-3, 0.119845803210767e-1, 0.193848122022095e-4, -0.215095749182309e-4};
4804 constant Real[:] I = {-12, -12, -12, -12, -8, -8, -8, -6, -6, -6, -5, -5, -5, -5, -5, -4, -3, -3, -2, 0, 2, 3, 4, 5, 6, 8, 12, 14};
4805 constant Real[:] J = {1, 3, 4, 7, 0, 1, 3, 0, 2, 4, 0, 1, 2, 4, 6, 12, 1, 6, 2, 0, 1, 1, 0, 24, 0, 3, 1, 2};
4806 constant SI.Temp_K Tstar = 860 "Normalization temperature";
4807 constant SI.Pressure pstar = 100e6 "Normalization pressure";
4808 constant SI.SpecificEntropy sstar = 5.3e3 "Normalization entropy";
4809 Real pi = p / pstar "Normalized specific pressure";
4810 Real sigma = s / sstar "Normalized specific entropy";
4811 algorithm
4812 T := sum(n[i] * (pi + 0.760) ^ I[i] * (sigma - 0.818) ^ J[i] for i in 1:28) * Tstar;
4813 end T3b_ps;
4814
4815 function v3a_ps "Region 3 a: inverse function v(p,s)"
4816 extends Modelica.Icons.Function;
4817 input SI.Pressure p "Pressure";
4818 input SI.SpecificEntropy s "Specific entropy";
4819 output SI.SpecificVolume v "Specific volume";
4820 protected
4821 constant Real[:] n = {0.795544074093975e2, -0.238261242984590e4, 0.176813100617787e5, -0.110524727080379e-2, -0.153213833655326e2, 0.297544599376982e3, -0.350315206871242e8, 0.277513761062119, -0.523964271036888, -0.148011182995403e6, 0.160014899374266e7, 0.170802322663427e13, 0.246866996006494e-3, 0.165326084797980e1, -0.118008384666987, 0.253798642355900e1, 0.965127704669424, -0.282172420532826e2, 0.203224612353823, 0.110648186063513e1, 0.526127948451280, 0.277000018736321, 0.108153340501132e1, -0.744127885357893e-1, 0.164094443541384e-1, -0.680468275301065e-1, 0.257988576101640e-1, -0.145749861944416e-3};
4822 constant Real[:] I = {-12, -12, -12, -10, -10, -10, -10, -8, -8, -8, -8, -6, -5, -4, -3, -3, -2, -2, -1, -1, 0, 0, 0, 1, 2, 4, 5, 6};
4823 constant Real[:] J = {10, 12, 14, 4, 8, 10, 20, 5, 6, 14, 16, 28, 1, 5, 2, 4, 3, 8, 1, 2, 0, 1, 3, 0, 0, 2, 2, 0};
4824 constant SI.Volume vstar = 0.0028 "Normalization temperature";
4825 constant SI.Pressure pstar = 100e6 "Normalization pressure";
4826 constant SI.SpecificEntropy sstar = 4.4e3 "Normalization entropy";
4827 Real pi = p / pstar "Normalized specific pressure";
4828 Real sigma = s / sstar "Normalized specific entropy";
4829 algorithm
4830 v := sum(n[i] * (pi + 0.187) ^ I[i] * (sigma - 0.755) ^ J[i] for i in 1:28) * vstar;
4831 end v3a_ps;
4832
4833 function v3b_ps "Region 3 b: inverse function v(p,s)"
4834 extends Modelica.Icons.Function;
4835 input SI.Pressure p "Pressure";
4836 input SI.SpecificEntropy s "Specific entropy";
4837 output SI.SpecificVolume v "Specific volume";
4838 protected
4839 constant Real[:] n = {0.591599780322238e-4, -0.185465997137856e-2, 0.104190510480013e-1, 0.598647302038590e-2, -0.771391189901699, 0.172549765557036e1, -0.467076079846526e-3, 0.134533823384439e-1, -0.808094336805495e-1, 0.508139374365767, 0.128584643361683e-2, -0.163899353915435e1, 0.586938199318063e1, -0.292466667918613e1, -0.614076301499537e-2, 0.576199014049172e1, -0.121613320606788e2, 0.167637540957944e1, -0.744135838773463e1, 0.378168091437659e-1, 0.401432203027688e1, 0.160279837479185e2, 0.317848779347728e1, -0.358362310304853e1, -0.115995260446827e7, 0.199256573577909, -0.122270624794624, -0.191449143716586e2, -0.150448002905284e-1, 0.146407900162154e2, -0.327477787188230e1};
4840 constant Real[:] I = {-12, -12, -12, -12, -12, -12, -10, -10, -10, -10, -8, -5, -5, -5, -4, -4, -4, -4, -3, -2, -2, -2, -2, -2, -2, 0, 0, 0, 1, 1, 2};
4841 constant Real[:] J = {0, 1, 2, 3, 5, 6, 0, 1, 2, 4, 0, 1, 2, 3, 0, 1, 2, 3, 1, 0, 1, 2, 3, 4, 12, 0, 1, 2, 0, 2, 2};
4842 constant SI.Volume vstar = 0.0088 "Normalization temperature";
4843 constant SI.Pressure pstar = 100e6 "Normalization pressure";
4844 constant SI.SpecificEntropy sstar = 5.3e3 "Normalization entropy";
4845 Real pi = p / pstar "Normalized specific pressure";
4846 Real sigma = s / sstar "Normalized specific entropy";
4847 algorithm
4848 v := sum(n[i] * (pi + 0.298) ^ I[i] * (sigma - 0.816) ^ J[i] for i in 1:31) * vstar;
4849 end v3b_ps;
4850 end Basic;
4851
4852 package Transport "Transport properties for water according to IAPWS/IF97"
4853 extends Modelica.Icons.FunctionsPackage;
4854
4855 function visc_dTp "Dynamic viscosity eta(d,T,p), industrial formulation"
4856 extends Modelica.Icons.Function;
4857 input SI.Density d "Density";
4858 input SI.Temperature T "Temperature (K)";
4859 input SI.Pressure p "Pressure (only needed for region of validity)";
4860 input Integer phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
4861 output SI.DynamicViscosity eta "Dynamic viscosity";
4862 protected
4863 constant Real n0 = 1.0 "Viscosity coefficient";
4864 constant Real n1 = 0.978197 "Viscosity coefficient";
4865 constant Real n2 = 0.579829 "Viscosity coefficient";
4866 constant Real n3 = -0.202354 "Viscosity coefficient";
4867 constant Real[42] nn = array(0.5132047, 0.3205656, 0.0, 0.0, -0.7782567, 0.1885447, 0.2151778, 0.7317883, 1.241044, 1.476783, 0.0, 0.0, -0.2818107, -1.070786, -1.263184, 0.0, 0.0, 0.0, 0.1778064, 0.460504, 0.2340379, -0.4924179, 0.0, 0.0, -0.0417661, 0.0, 0.0, 0.1600435, 0.0, 0.0, 0.0, -0.01578386, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.003629481, 0.0, 0.0) "Viscosity coefficients";
4868 constant SI.Density rhostar = 317.763 "Scaling density";
4869 constant SI.DynamicViscosity etastar = 55.071e-6 "Scaling viscosity";
4870 constant SI.Temperature tstar = 647.226 "Scaling temperature";
4871 Integer i "Auxiliary variable";
4872 Integer j "Auxiliary variable";
4873 Real delta "Dimensionless density";
4874 Real deltam1 "Dimensionless density";
4875 Real tau "Dimensionless temperature";
4876 Real taum1 "Dimensionless temperature";
4877 Real Psi0 "Auxiliary variable";
4878 Real Psi1 "Auxiliary variable";
4879 Real tfun "Auxiliary variable";
4880 Real rhofun "Auxiliary variable";
4881 Real Tc = T - 273.15 "Celsius temperature for region check";
4882 algorithm
4883 delta := d / rhostar;
4884 assert(d > triple.dvtriple, "IF97 medium function visc_dTp for viscosity called with too low density\n" + "d = " + String(d) + " <= " + String(triple.dvtriple) + " (triple point density)");
4885 assert(p <= 500e6 and Tc >= 0.0 and Tc <= 150 or p <= 350e6 and Tc > 150.0 and Tc <= 600 or p <= 300e6 and Tc > 600.0 and Tc <= 900, "IF97 medium function visc_dTp: viscosity computed outside the range\n" + "of validity of the IF97 formulation: p = " + String(p) + " Pa, Tc = " + String(Tc) + " K");
4886 deltam1 := delta - 1.0;
4887 tau := tstar / T;
4888 taum1 := tau - 1.0;
4889 Psi0 := 1 / (n0 + (n1 + (n2 + n3 * tau) * tau) * tau) / tau ^ 0.5;
4890 Psi1 := 0.0;
4891 tfun := 1.0;
4892 for i in 1:6 loop
4893 if i <> 1 then
4894 tfun := tfun * taum1;
4895 else
4896 end if;
4897 rhofun := 1.;
4898 for j in 0:6 loop
4899 if j <> 0 then
4900 rhofun := rhofun * deltam1;
4901 else
4902 end if;
4903 Psi1 := Psi1 + nn[i + j * 6] * tfun * rhofun;
4904 end for;
4905 end for;
4906 eta := etastar * Psi0 * Modelica.Math.exp(delta * Psi1);
4907 end visc_dTp;
4908
4909 function cond_dTp "Thermal conductivity lam(d,T,p) (industrial use version) only in one-phase region"
4910 extends Modelica.Icons.Function;
4911 input SI.Density d "Density";
4912 input SI.Temperature T "Temperature (K)";
4913 input SI.Pressure p "Pressure";
4914 input Integer phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
4915 input Boolean industrialMethod = true "If true, the industrial method is used, otherwise the scientific one";
4916 output SI.ThermalConductivity lambda "Thermal conductivity";
4917 protected
4918 Integer region(min = 1, max = 5) "IF97 region, valid values:1,2,3, and 5";
4919 constant Real n0 = 1.0 "Conductivity coefficient";
4920 constant Real n1 = 6.978267 "Conductivity coefficient";
4921 constant Real n2 = 2.599096 "Conductivity coefficient";
4922 constant Real n3 = -0.998254 "Conductivity coefficient";
4923 constant Real[30] nn = array(1.3293046, 1.7018363, 5.2246158, 8.7127675, -1.8525999, -0.40452437, -2.2156845, -10.124111, -9.5000611, 0.9340469, 0.2440949, 1.6511057, 4.9874687, 4.3786606, 0.0, 0.018660751, -0.76736002, -0.27297694, -0.91783782, 0.0, -0.12961068, 0.37283344, -0.43083393, 0.0, 0.0, 0.044809953, -0.1120316, 0.13333849, 0.0, 0.0) "Conductivity coefficient";
4924 constant SI.ThermalConductivity lamstar = 0.4945 "Scaling conductivity";
4925 constant SI.Density rhostar = 317.763 "Scaling density";
4926 constant SI.Temperature tstar = 647.226 "Scaling temperature";
4927 constant SI.Pressure pstar = 22.115e6 "Scaling pressure";
4928 constant SI.DynamicViscosity etastar = 55.071e-6 "Scaling viscosity";
4929 Integer i "Auxiliary variable";
4930 Integer j "Auxiliary variable";
4931 Real delta "Dimensionless density";
4932 Real tau "Dimensionless temperature";
4933 Real deltam1 "Dimensionless density";
4934 Real taum1 "Dimensionless temperature";
4935 Real Lam0 "Part of thermal conductivity";
4936 Real Lam1 "Part of thermal conductivity";
4937 Real Lam2 "Part of thermal conductivity";
4938 Real tfun "Auxiliary variable";
4939 Real rhofun "Auxiliary variable";
4940 Real dpitau "Auxiliary variable";
4941 Real ddelpi "Auxiliary variable";
4942 Real d2 "Auxiliary variable";
4943 Modelica.Media.Common.GibbsDerivs g "Dimensionless Gibbs function and derivatives w.r.t. pi and tau";
4944 Modelica.Media.Common.HelmholtzDerivs f "Dimensionless Helmholtz function and derivatives w.r.t. delta and tau";
4945 Real Tc = T - 273.15 "Celsius temperature for region check";
4946 Real Chi "Symmetrized compressibility";
4947 constant SI.Density rhostar2 = 317.7 "Reference density";
4948 constant SI.Temperature Tstar2 = 647.25 "Reference temperature";
4949 constant SI.ThermalConductivity lambdastar = 1 "Reference thermal conductivity";
4950 Real TREL = T / Tstar2 "Relative temperature";
4951 Real rhoREL = d / rhostar2 "Relative density";
4952 Real lambdaREL "Relative thermal conductivity";
4953 Real deltaTREL "Relative temperature increment";
4954 constant Real[:] C = {0.642857, -4.11717, -6.17937, 0.00308976, 0.0822994, 10.0932};
4955 constant Real[:] dpar = {0.0701309, 0.0118520, 0.00169937, -1.0200};
4956 constant Real[:] b = {-0.397070, 0.400302, 1.060000};
4957 constant Real[:] B = {-0.171587, 2.392190};
4958 constant Real[:] a = {0.0102811, 0.0299621, 0.0156146, -0.00422464};
4959 Real Q;
4960 Real S;
4961 Real lambdaREL2 "Function, part of the interpolating equation of the thermal conductivity";
4962 Real lambdaREL1 "Function, part of the interpolating equation of the thermal conductivity";
4963 Real lambdaREL0 "Function, part of the interpolating equation of the thermal conductivity";
4964 algorithm
4965 assert(d > triple.dvtriple, "IF97 medium function cond_dTp called with too low density\n" + "d = " + String(d) + " <= " + String(triple.dvtriple) + " (triple point density)");
4966 assert(p <= 100e6 and Tc >= 0.0 and Tc <= 500 or p <= 70e6 and Tc > 500.0 and Tc <= 650 or p <= 40e6 and Tc > 650.0 and Tc <= 800, "IF97 medium function cond_dTp: thermal conductivity computed outside the range\n" + "of validity of the IF97 formulation: p = " + String(p) + " Pa, Tc = " + String(Tc) + " K");
4967 if industrialMethod == true then
4968 deltaTREL := abs(TREL - 1) + C[4];
4969 Q := 2 + C[5] / deltaTREL ^ (3 / 5);
4970 if TREL >= 1 then
4971 S := 1 / deltaTREL;
4972 else
4973 S := C[6] / deltaTREL ^ (3 / 5);
4974 end if;
4975 lambdaREL2 := (dpar[1] / TREL ^ 10 + dpar[2]) * rhoREL ^ (9 / 5) * Modelica.Math.exp(C[1] * (1 - rhoREL ^ (14 / 5))) + dpar[3] * S * rhoREL ^ Q * Modelica.Math.exp(Q / (1 + Q) * (1 - rhoREL ^ (1 + Q))) + dpar[4] * Modelica.Math.exp(C[2] * TREL ^ (3 / 2) + C[3] / rhoREL ^ 5);
4976 lambdaREL1 := b[1] + b[2] * rhoREL + b[3] * Modelica.Math.exp(B[1] * (rhoREL + B[2]) ^ 2);
4977 lambdaREL0 := TREL ^ (1 / 2) * sum(a[i] * TREL ^ (i - 1) for i in 1:4);
4978 lambdaREL := lambdaREL0 + lambdaREL1 + lambdaREL2;
4979 lambda := lambdaREL * lambdastar;
4980 else
4981 if p < data.PLIMIT4A then
4982 if d > data.DCRIT then
4983 region := 1;
4984 else
4985 region := 2;
4986 end if;
4987 else
4988 assert(false, "The scientific method works only for temperature up to 623.15 K");
4989 end if;
4990 tau := tstar / T;
4991 delta := d / rhostar;
4992 deltam1 := delta - 1.0;
4993 taum1 := tau - 1.0;
4994 Lam0 := 1 / (n0 + (n1 + (n2 + n3 * tau) * tau) * tau) / tau ^ 0.5;
4995 Lam1 := 0.0;
4996 tfun := 1.0;
4997 for i in 1:5 loop
4998 if i <> 1 then
4999 tfun := tfun * taum1;
5000 else
5001 end if;
5002 rhofun := 1.0;
5003 for j in 0:5 loop
5004 if j <> 0 then
5005 rhofun := rhofun * deltam1;
5006 else
5007 end if;
5008 Lam1 := Lam1 + nn[i + j * 5] * tfun * rhofun;
5009 end for;
5010 end for;
5011 if region == 1 then
5012 g := Basic.g1(p, T);
5013 dpitau := -tstar / pstar * (data.PSTAR1 * (g.gpi - data.TSTAR1 / T * g.gtaupi) / g.gpipi / T);
5014 ddelpi := -pstar / rhostar * data.RH2O / data.PSTAR1 / data.PSTAR1 * T * d * d * g.gpipi;
5015 Chi := delta * ddelpi;
5016 elseif region == 2 then
5017 g := Basic.g2(p, T);
5018 dpitau := -tstar / pstar * (data.PSTAR2 * (g.gpi - data.TSTAR2 / T * g.gtaupi) / g.gpipi / T);
5019 ddelpi := -pstar / rhostar * data.RH2O / data.PSTAR2 / data.PSTAR2 * T * d * d * g.gpipi;
5020 Chi := delta * ddelpi;
5021 else
5022 assert(false, "Thermal conductivity can only be called in the one-phase regions below 623.15 K\n" + "(p = " + String(p) + " Pa, T = " + String(T) + " K, region = " + String(region) + ")");
5023 end if;
5024 taum1 := 1 / tau - 1;
5025 d2 := deltam1 * deltam1;
5026 Lam2 := 0.0013848 * etastar / visc_dTp(d, T, p) / (tau * tau * delta * delta) * dpitau * dpitau * max(Chi, Modelica.Constants.small) ^ 0.4678 * delta ^ 0.5 * Modelica.Math.exp((-18.66 * taum1 * taum1) - d2 * d2);
5027 lambda := lamstar * (Lam0 * Modelica.Math.exp(delta * Lam1) + Lam2);
5028 end if;
5029 end cond_dTp;
5030
5031 function surfaceTension "Surface tension in region 4 between steam and water"
5032 extends Modelica.Icons.Function;
5033 input SI.Temperature T "Temperature (K)";
5034 output SI.SurfaceTension sigma "Surface tension in SI units";
5035 protected
5036 Real Theta "Dimensionless temperature";
5037 algorithm
5038 Theta := min(1.0, T / data.TCRIT);
5039 sigma := 235.8e-3 * (1 - Theta) ^ 1.256 * (1 - 0.625 * (1 - Theta));
5040 end surfaceTension;
5041 end Transport;
5042
5043 package Isentropic "Functions for calculating the isentropic enthalpy from pressure p and specific entropy s"
5044 extends Modelica.Icons.FunctionsPackage;
5045
5046 function hofpT1 "Intermediate function for isentropic specific enthalpy in region 1"
5047 extends Modelica.Icons.Function;
5048 input SI.Pressure p "Pressure";
5049 input SI.Temperature T "Temperature (K)";
5050 output SI.SpecificEnthalpy h "Specific enthalpy";
5051 protected
5052 Real[13] o "Vector of auxiliary variables";
5053 Real pi1 "Dimensionless pressure";
5054 Real tau "Dimensionless temperature";
5055 Real tau1 "Dimensionless temperature";
5056 algorithm
5057 tau := data.TSTAR1 / T;
5058 pi1 := 7.1 - p / data.PSTAR1;
5059 assert(p > triple.ptriple, "IF97 medium function hofpT1 called with too low pressure\n" + "p = " + String(p) + " Pa <= " + String(triple.ptriple) + " Pa (triple point pressure)");
5060 tau1 := (-1.222) + tau;
5061 o[1] := tau1 * tau1;
5062 o[2] := o[1] * tau1;
5063 o[3] := o[1] * o[1];
5064 o[4] := o[3] * o[3];
5065 o[5] := o[1] * o[4];
5066 o[6] := o[1] * o[3];
5067 o[7] := o[3] * tau1;
5068 o[8] := o[3] * o[4];
5069 o[9] := pi1 * pi1;
5070 o[10] := o[9] * o[9];
5071 o[11] := o[10] * o[10];
5072 o[12] := o[4] * o[4];
5073 o[13] := o[12] * o[12];
5074 h := data.RH2O * T * tau * (pi1 * (((-0.00254871721114236) + o[1] * (0.00424944110961118 + (0.018990068218419 + ((-0.021841717175414) - 0.00015851507390979 * o[1]) * o[1]) * o[6])) / o[5] + pi1 * ((0.00141552963219801 + o[3] * (0.000047661393906987 + o[1] * ((-0.0000132425535992538) - 1.2358149370591e-14 * o[1] * o[3] * o[4]))) / o[3] + pi1 * ((0.000126718579380216 - 5.11230768720618e-9 * o[5]) / o[7] + pi1 * ((0.000011212640954 + o[2] * (1.30342445791202e-6 - 1.4341729937924e-12 * o[8])) / o[6] + pi1 * (o[9] * pi1 * ((1.40077319158051e-8 + 1.04549227383804e-9 * o[7]) / o[8] + o[10] * o[11] * pi1 * (1.9941018075704e-17 / (o[1] * o[12] * o[3] * o[4]) + o[9] * ((-4.48827542684151e-19 / o[13]) + o[10] * o[9] * (pi1 * (4.65957282962769e-22 / (o[13] * o[4]) + pi1 * (3.83502057899078e-24 * pi1 / (o[1] * o[13] * o[4]) - 7.2912378325616e-23 / (o[13] * o[4] * tau1))) - 1.00075970318621e-21 / (o[1] * o[13] * o[3] * tau1))))) + 3.24135974880936e-6 / (o[4] * tau1)))))) + ((-0.29265942426334) + tau1 * (0.84548187169114 + o[1] * (3.3855169168385 + tau1 * ((-1.91583926775744) + tau1 * (0.47316115539684 + ((-0.066465668798004) + 0.0040607314991784 * tau1) * tau1))))) / o[2]);
5075 end hofpT1;
5076
5077 function handsofpT1 "Special function for specific enthalpy and specific entropy in region 1"
5078 extends Modelica.Icons.Function;
5079 input SI.Pressure p "Pressure";
5080 input SI.Temperature T "Temperature (K)";
5081 output SI.SpecificEnthalpy h "Specific enthalpy";
5082 output SI.SpecificEntropy s "Specific entropy";
5083 protected
5084 Real[28] o "Vector of auxiliary variables";
5085 Real pi1 "Dimensionless pressure";
5086 Real tau "Dimensionless temperature";
5087 Real tau1 "Dimensionless temperature";
5088 Real g "Dimensionless Gibbs energy";
5089 Real gtau "Derivative of dimensionless Gibbs energy w.r.t. tau";
5090 algorithm
5091 assert(p > triple.ptriple, "IF97 medium function handsofpT1 called with too low pressure\n" + "p = " + String(p) + " Pa <= " + String(triple.ptriple) + " Pa (triple point pressure)");
5092 tau := data.TSTAR1 / T;
5093 pi1 := 7.1 - p / data.PSTAR1;
5094 tau1 := (-1.222) + tau;
5095 o[1] := tau1 * tau1;
5096 o[2] := o[1] * o[1];
5097 o[3] := o[2] * o[2];
5098 o[4] := o[3] * tau1;
5099 o[5] := 1 / o[4];
5100 o[6] := o[1] * o[2];
5101 o[7] := o[1] * tau1;
5102 o[8] := 1 / o[7];
5103 o[9] := o[1] * o[2] * o[3];
5104 o[10] := 1 / o[2];
5105 o[11] := o[2] * tau1;
5106 o[12] := 1 / o[11];
5107 o[13] := o[2] * o[3];
5108 o[14] := pi1 * pi1;
5109 o[15] := o[14] * pi1;
5110 o[16] := o[14] * o[14];
5111 o[17] := o[16] * o[16];
5112 o[18] := o[16] * o[17] * pi1;
5113 o[19] := o[14] * o[16];
5114 o[20] := o[3] * o[3];
5115 o[21] := o[20] * o[20];
5116 o[22] := o[21] * o[3] * tau1;
5117 o[23] := 1 / o[22];
5118 o[24] := o[21] * o[3];
5119 o[25] := 1 / o[24];
5120 o[26] := o[1] * o[2] * o[21] * tau1;
5121 o[27] := 1 / o[26];
5122 o[28] := o[1] * o[3];
5123 g := pi1 * (pi1 * (pi1 * (o[10] * ((-0.000031679644845054) + o[2] * ((-2.8270797985312e-6) - 8.5205128120103e-10 * o[6])) + pi1 * (o[12] * ((-2.2425281908e-6) + ((-6.5171222895601e-7) - 1.4341729937924e-13 * o[13]) * o[7]) + pi1 * ((-4.0516996860117e-7 / o[3]) + o[15] * (o[18] * (o[14] * (o[19] * (2.6335781662795e-23 / (o[1] * o[2] * o[21]) + pi1 * ((-1.1947622640071e-23 * o[27]) + pi1 * (1.8228094581404e-24 * o[25] - 9.3537087292458e-26 * o[23] * pi1))) + 1.4478307828521e-20 / (o[1] * o[2] * o[20] * o[3] * tau1)) - 6.8762131295531e-19 / (o[2] * o[20] * o[3] * tau1)) + ((-1.2734301741641e-9) - 1.7424871230634e-10 * o[11]) / (o[1] * o[3] * tau1))))) + o[8] * ((-0.00047184321073267) + o[7] * ((-0.00030001780793026) + (0.000047661393906987 + o[1] * ((-4.4141845330846e-6) - 7.2694996297594e-16 * o[9])) * tau1))) + o[5] * (0.00028319080123804 + o[1] * ((-0.00060706301565874) + o[6] * ((-0.018990068218419) + tau1 * ((-0.032529748770505) + ((-0.021841717175414) - 0.00005283835796993 * o[1]) * tau1))))) + (0.14632971213167 + tau1 * ((-0.84548187169114) + tau1 * ((-3.756360367204) + tau1 * (3.3855169168385 + tau1 * ((-0.95791963387872) + tau1 * (0.15772038513228 + ((-0.016616417199501) + 0.00081214629983568 * tau1) * tau1)))))) / o[1];
5124 gtau := pi1 * (((-0.00254871721114236) + o[1] * (0.00424944110961118 + (0.018990068218419 + ((-0.021841717175414) - 0.00015851507390979 * o[1]) * o[1]) * o[6])) / o[28] + pi1 * (o[10] * (0.00141552963219801 + o[2] * (0.000047661393906987 + o[1] * ((-0.0000132425535992538) - 1.2358149370591e-14 * o[9]))) + pi1 * (o[12] * (0.000126718579380216 - 5.11230768720618e-9 * o[28]) + pi1 * ((0.000011212640954 + (1.30342445791202e-6 - 1.4341729937924e-12 * o[13]) * o[7]) / o[6] + pi1 * (3.24135974880936e-6 * o[5] + o[15] * ((1.40077319158051e-8 + 1.04549227383804e-9 * o[11]) / o[13] + o[18] * (1.9941018075704e-17 / (o[1] * o[2] * o[20] * o[3]) + o[14] * ((-4.48827542684151e-19 / o[21]) + o[19] * ((-1.00075970318621e-21 * o[27]) + pi1 * (4.65957282962769e-22 * o[25] + pi1 * ((-7.2912378325616e-23 * o[23]) + 3.83502057899078e-24 * pi1 / (o[1] * o[21] * o[3])))))))))))) + o[8] * ((-0.29265942426334) + tau1 * (0.84548187169114 + o[1] * (3.3855169168385 + tau1 * ((-1.91583926775744) + tau1 * (0.47316115539684 + ((-0.066465668798004) + 0.0040607314991784 * tau1) * tau1)))));
5125 h := data.RH2O * T * tau * gtau;
5126 s := data.RH2O * (tau * gtau - g);
5127 end handsofpT1;
5128
5129 function hofpT2 "Intermediate function for isentropic specific enthalpy in region 2"
5130 extends Modelica.Icons.Function;
5131 input SI.Pressure p "Pressure";
5132 input SI.Temperature T "Temperature (K)";
5133 output SI.SpecificEnthalpy h "Specific enthalpy";
5134 protected
5135 Real[16] o "Vector of auxiliary variables";
5136 Real pi "Dimensionless pressure";
5137 Real tau "Dimensionless temperature";
5138 Real tau2 "Dimensionless temperature";
5139 algorithm
5140 assert(p > triple.ptriple, "IF97 medium function hofpT2 called with too low pressure\n" + "p = " + String(p) + " Pa <= " + String(triple.ptriple) + " Pa (triple point pressure)");
5141 pi := p / data.PSTAR2;
5142 tau := data.TSTAR2 / T;
5143 tau2 := (-0.5) + tau;
5144 o[1] := tau * tau;
5145 o[2] := o[1] * o[1];
5146 o[3] := tau2 * tau2;
5147 o[4] := o[3] * tau2;
5148 o[5] := o[3] * o[3];
5149 o[6] := o[5] * o[5];
5150 o[7] := o[6] * o[6];
5151 o[8] := o[5] * o[6] * o[7] * tau2;
5152 o[9] := o[3] * o[5];
5153 o[10] := o[5] * o[6] * tau2;
5154 o[11] := o[3] * o[7] * tau2;
5155 o[12] := o[3] * o[5] * o[6];
5156 o[13] := o[5] * o[6] * o[7];
5157 o[14] := pi * pi;
5158 o[15] := o[14] * o[14];
5159 o[16] := o[7] * o[7];
5160 h := data.RH2O * T * tau * ((0.0280439559151 + tau * ((-0.2858109552582) + tau * (1.2213149471784 + tau * ((-2.848163942888) + tau * (4.38395111945 + o[1] * (10.08665568018 + ((-0.5681726521544) + 0.06380539059921 * tau) * tau)))))) / (o[1] * o[2]) + pi * ((-0.017834862292358) + tau2 * ((-0.09199202739273) + ((-0.172743777250296) - 0.30195167236758 * o[4]) * tau2) + pi * ((-0.000033032641670203) + ((-0.0003789797503263) + o[3] * ((-0.015757110897342) + o[4] * ((-0.306581069554011) - 0.000960283724907132 * o[8]))) * tau2 + pi * (4.3870667284435e-7 + o[3] * ((-0.00009683303171571) + o[4] * ((-0.0090203547252888) - 1.42338887469272 * o[8])) + pi * ((-7.8847309559367e-10) + (2.558143570457e-8 + 1.44676118155521e-6 * tau2) * tau2 + pi * (0.0000160454534363627 * o[9] + pi * (((-5.0144299353183e-11) + o[10] * ((-0.033874355714168) - 836.35096769364 * o[11])) * o[3] + pi * (((-0.0000138839897890111) - 0.973671060893475 * o[12]) * o[3] * o[6] + pi * ((9.0049690883672e-11 - 296.320827232793 * o[13]) * o[3] * o[5] * tau2 + pi * (2.57526266427144e-7 * o[5] * o[6] + pi * (o[4] * (4.1627860840696e-19 + ((-1.0234747095929e-12) - 1.40254511313154e-8 * o[5]) * o[9]) + o[14] * o[15] * (o[13] * ((-2.34560435076256e-9) + 5.3465159397045 * o[5] * o[7] * tau2) + o[14] * ((-19.1874828272775 * o[16] * o[6] * o[7]) + o[14] * (o[11] * (1.78371690710842e-23 + (1.07202609066812e-11 - 0.000201611844951398 * o[10]) * o[3] * o[5] * o[6] * tau2) + pi * ((-1.24017662339842e-24 * o[5] * o[7]) + pi * (0.000200482822351322 * o[16] * o[5] * o[7] + pi * ((-4.97975748452559e-14 * o[16] * o[3] * o[5]) + o[6] * o[7] * (1.90027787547159e-27 + o[12] * (2.21658861403112e-15 - 0.0000547344301999018 * o[3] * o[7])) * pi * tau2)))))))))))))))));
5161 end hofpT2;
5162
5163 function handsofpT2 "Function for isentropic specific enthalpy and specific entropy in region 2"
5164 extends Modelica.Icons.Function;
5165 input SI.Pressure p "Pressure";
5166 input SI.Temperature T "Temperature (K)";
5167 output SI.SpecificEnthalpy h "Specific enthalpy";
5168 output SI.SpecificEntropy s "Specific entropy";
5169 protected
5170 Real[22] o "Vector of auxiliary variables";
5171 Real pi "Dimensionless pressure";
5172 Real tau "Dimensionless temperature";
5173 Real tau2 "Dimensionless temperature";
5174 Real g "Dimensionless Gibbs energy";
5175 Real gtau "Derivative of dimensionless Gibbs energy w.r.t. tau";
5176 algorithm
5177 assert(p > triple.ptriple, "IF97 medium function handsofpT2 called with too low pressure\n" + "p = " + String(p) + " Pa <= " + String(triple.ptriple) + " Pa (triple point pressure)");
5178 tau := data.TSTAR2 / T;
5179 pi := p / data.PSTAR2;
5180 tau2 := tau - 0.5;
5181 o[1] := tau2 * tau2;
5182 o[2] := o[1] * tau2;
5183 o[3] := o[1] * o[1];
5184 o[4] := o[3] * o[3];
5185 o[5] := o[4] * o[4];
5186 o[6] := o[3] * o[4] * o[5] * tau2;
5187 o[7] := o[1] * o[3] * tau2;
5188 o[8] := o[3] * o[4] * tau2;
5189 o[9] := o[1] * o[5] * tau2;
5190 o[10] := o[1] * o[3] * o[4];
5191 o[11] := o[3] * o[4] * o[5];
5192 o[12] := o[1] * o[3];
5193 o[13] := pi * pi;
5194 o[14] := o[13] * o[13];
5195 o[15] := o[13] * o[14];
5196 o[16] := o[3] * o[5] * tau2;
5197 o[17] := o[5] * o[5];
5198 o[18] := o[3] * o[5];
5199 o[19] := o[1] * o[3] * o[4] * tau2;
5200 o[20] := o[1] * o[5];
5201 o[21] := tau * tau;
5202 o[22] := o[21] * o[21];
5203 g := pi * ((-0.0017731742473213) + tau2 * ((-0.017834862292358) + tau2 * ((-0.045996013696365) + ((-0.057581259083432) - 0.05032527872793 * o[2]) * tau2)) + pi * (tau2 * ((-0.000033032641670203) + ((-0.00018948987516315) + o[1] * ((-0.0039392777243355) + o[2] * ((-0.043797295650573) - 0.000026674547914087 * o[6]))) * tau2) + pi * (2.0481737692309e-8 + (4.3870667284435e-7 + o[1] * ((-0.00003227767723857) + o[2] * ((-0.0015033924542148) - 0.040668253562649 * o[6]))) * tau2 + pi * (tau2 * ((-7.8847309559367e-10) + (1.2790717852285e-8 + 4.8225372718507e-7 * tau2) * tau2) + pi * (2.2922076337661e-6 * o[7] + pi * (o[2] * ((-1.6714766451061e-11) + o[8] * ((-0.0021171472321355) - 23.895741934104 * o[9])) + pi * ((-5.905956432427e-18) + o[1] * ((-1.2621808899101e-6) - 0.038946842435739 * o[10]) * o[4] * tau2 + pi * ((1.1256211360459e-11 - 8.2311340897998 * o[11]) * o[4] + pi * (1.9809712802088e-8 * o[8] + pi * ((1.0406965210174e-19 + o[12] * ((-1.0234747095929e-13) - 1.0018179379511e-9 * o[3])) * o[3] + o[15] * (((-8.0882908646985e-11) + 0.10693031879409 * o[16]) * o[6] + o[13] * ((-0.33662250574171 * o[17] * o[4] * o[5] * tau2) + o[13] * (o[18] * (8.9185845355421e-25 + o[19] * (3.0629316876232e-13 - 4.2002467698208e-6 * o[8])) + pi * ((-5.9056029685639e-26 * o[16]) + pi * (3.7826947613457e-6 * o[17] * o[3] * o[5] * tau2 + pi * (o[1] * (7.3087610595061e-29 + o[10] * (5.5414715350778e-17 - 9.436970724121e-7 * o[20])) * o[4] * o[5] * pi - 1.2768608934681e-15 * o[1] * o[17] * o[3] * tau2)))))))))))))))) + ((-0.00560879118302) + tau * (0.07145273881455 + tau * ((-0.4071049823928) + tau * (1.424081971444 + tau * ((-4.38395111945) + tau * ((-9.692768600217) + tau * (10.08665568018 + ((-0.2840863260772) + 0.02126846353307 * tau) * tau) + Modelica.Math.log(pi))))))) / (o[22] * tau);
5204 gtau := (0.0280439559151 + tau * ((-0.2858109552582) + tau * (1.2213149471784 + tau * ((-2.848163942888) + tau * (4.38395111945 + o[21] * (10.08665568018 + ((-0.5681726521544) + 0.06380539059921 * tau) * tau)))))) / (o[21] * o[22]) + pi * ((-0.017834862292358) + tau2 * ((-0.09199202739273) + ((-0.172743777250296) - 0.30195167236758 * o[2]) * tau2) + pi * ((-0.000033032641670203) + ((-0.0003789797503263) + o[1] * ((-0.015757110897342) + o[2] * ((-0.306581069554011) - 0.000960283724907132 * o[6]))) * tau2 + pi * (4.3870667284435e-7 + o[1] * ((-0.00009683303171571) + o[2] * ((-0.0090203547252888) - 1.42338887469272 * o[6])) + pi * ((-7.8847309559367e-10) + (2.558143570457e-8 + 1.44676118155521e-6 * tau2) * tau2 + pi * (0.0000160454534363627 * o[12] + pi * (o[1] * ((-5.0144299353183e-11) + o[8] * ((-0.033874355714168) - 836.35096769364 * o[9])) + pi * (o[1] * ((-0.0000138839897890111) - 0.973671060893475 * o[10]) * o[4] + pi * ((9.0049690883672e-11 - 296.320827232793 * o[11]) * o[7] + pi * (2.57526266427144e-7 * o[3] * o[4] + pi * (o[2] * (4.1627860840696e-19 + o[12] * ((-1.0234747095929e-12) - 1.40254511313154e-8 * o[3])) + o[15] * (o[11] * ((-2.34560435076256e-9) + 5.3465159397045 * o[16]) + o[13] * ((-19.1874828272775 * o[17] * o[4] * o[5]) + o[13] * ((1.78371690710842e-23 + o[19] * (1.07202609066812e-11 - 0.000201611844951398 * o[8])) * o[9] + pi * ((-1.24017662339842e-24 * o[18]) + pi * (0.000200482822351322 * o[17] * o[3] * o[5] + pi * ((-4.97975748452559e-14 * o[1] * o[17] * o[3]) + (1.90027787547159e-27 + o[10] * (2.21658861403112e-15 - 0.0000547344301999018 * o[20])) * o[4] * o[5] * pi * tau2))))))))))))))));
5205 h := data.RH2O * T * tau * gtau;
5206 s := data.RH2O * (tau * gtau - g);
5207 end handsofpT2;
5208 end Isentropic;
5209
5210 package Inverses "Efficient inverses for selected pairs of variables"
5211 extends Modelica.Icons.FunctionsPackage;
5212
5213 function fixdT "Region limits for inverse iteration in region 3"
5214 extends Modelica.Icons.Function;
5215 input SI.Density din "Density";
5216 input SI.Temperature Tin "Temperature";
5217 output SI.Density dout "Density";
5218 output SI.Temperature Tout "Temperature";
5219 protected
5220 SI.Temperature Tmin "Approximation of minimum temperature";
5221 SI.Temperature Tmax "Approximation of maximum temperature";
5222 algorithm
5223 if din > 765.0 then
5224 dout := 765.0;
5225 elseif din < 110.0 then
5226 dout := 110.0;
5227 else
5228 dout := din;
5229 end if;
5230 if dout < 390.0 then
5231 Tmax := 554.3557377 + dout * 0.809344262;
5232 else
5233 Tmax := 1116.85 - dout * 0.632948717;
5234 end if;
5235 if dout < data.DCRIT then
5236 Tmin := data.TCRIT * (1.0 - (dout - data.DCRIT) * (dout - data.DCRIT) / 1.0e6);
5237 else
5238 Tmin := data.TCRIT * (1.0 - (dout - data.DCRIT) * (dout - data.DCRIT) / 1.44e6);
5239 end if;
5240 if Tin < Tmin then
5241 Tout := Tmin;
5242 elseif Tin > Tmax then
5243 Tout := Tmax;
5244 else
5245 Tout := Tin;
5246 end if;
5247 end fixdT;
5248
5249 function dofp13 "Density at the boundary between regions 1 and 3"
5250 extends Modelica.Icons.Function;
5251 input SI.Pressure p "Pressure";
5252 output SI.Density d "Density";
5253 protected
5254 Real p2 "Auxiliary variable";
5255 Real[3] o "Vector of auxiliary variables";
5256 algorithm
5257 p2 := 7.1 - 6.04960677555959e-8 * p;
5258 o[1] := p2 * p2;
5259 o[2] := o[1] * o[1];
5260 o[3] := o[2] * o[2];
5261 d := 57.4756752485113 / (0.0737412153522555 + p2 * (0.00145092247736023 + p2 * (0.000102697173772229 + p2 * (0.0000114683182476084 + p2 * (1.99080616601101e-6 + o[1] * p2 * (1.13217858826367e-8 + o[2] * o[3] * p2 * (1.35549330686006e-17 + o[1] * ((-3.11228834832975e-19) + o[1] * o[2] * ((-7.02987180039442e-22) + p2 * (3.29199117056433e-22 + ((-5.17859076694812e-23) + 2.73712834080283e-24 * p2) * p2))))))))));
5262 end dofp13;
5263
5264 function dofp23 "Density at the boundary between regions 2 and 3"
5265 extends Modelica.Icons.Function;
5266 input SI.Pressure p "Pressure";
5267 output SI.Density d "Density";
5268 protected
5269 SI.Temperature T;
5270 Real[13] o "Vector of auxiliary variables";
5271 Real taug "Auxiliary variable";
5272 Real pi "Dimensionless pressure";
5273 Real gpi23 "Derivative of g w.r.t. pi on the boundary between regions 2 and 3";
5274 algorithm
5275 pi := p / data.PSTAR2;
5276 T := 572.54459862746 + 31.3220101646784 * ((-13.91883977887) + pi) ^ 0.5;
5277 o[1] := ((-13.91883977887) + pi) ^ 0.5;
5278 taug := (-0.5) + 540.0 / (572.54459862746 + 31.3220101646784 * o[1]);
5279 o[2] := taug * taug;
5280 o[3] := o[2] * taug;
5281 o[4] := o[2] * o[2];
5282 o[5] := o[4] * o[4];
5283 o[6] := o[5] * o[5];
5284 o[7] := o[4] * o[5] * o[6] * taug;
5285 o[8] := o[4] * o[5] * taug;
5286 o[9] := o[2] * o[4] * o[5];
5287 o[10] := pi * pi;
5288 o[11] := o[10] * o[10];
5289 o[12] := o[4] * o[6] * taug;
5290 o[13] := o[6] * o[6];
5291 gpi23 := (1.0 + pi * ((-0.0017731742473213) + taug * ((-0.017834862292358) + taug * ((-0.045996013696365) + ((-0.057581259083432) - 0.05032527872793 * o[3]) * taug)) + pi * (taug * ((-0.000066065283340406) + ((-0.0003789797503263) + o[2] * ((-0.007878555448671) + o[3] * ((-0.087594591301146) - 0.000053349095828174 * o[7]))) * taug) + pi * (6.1445213076927e-8 + (1.31612001853305e-6 + o[2] * ((-0.00009683303171571) + o[3] * ((-0.0045101773626444) - 0.122004760687947 * o[7]))) * taug + pi * (taug * ((-3.15389238237468e-9) + (5.116287140914e-8 + 1.92901490874028e-6 * taug) * taug) + pi * (0.0000114610381688305 * o[2] * o[4] * taug + pi * (o[3] * ((-1.00288598706366e-10) + o[8] * ((-0.012702883392813) - 143.374451604624 * o[2] * o[6] * taug)) + pi * ((-4.1341695026989e-17) + o[2] * o[5] * ((-8.8352662293707e-6) - 0.272627897050173 * o[9]) * taug + pi * (o[5] * (9.0049690883672e-11 - 65.8490727183984 * o[4] * o[5] * o[6]) + pi * (1.78287415218792e-7 * o[8] + pi * (o[4] * (1.0406965210174e-18 + o[2] * ((-1.0234747095929e-12) - 1.0018179379511e-8 * o[4]) * o[4]) + o[10] * o[11] * (((-1.29412653835176e-9) + 1.71088510070544 * o[12]) * o[7] + o[10] * ((-6.05920510335078 * o[13] * o[5] * o[6] * taug) + o[10] * (o[4] * o[6] * (1.78371690710842e-23 + o[2] * o[4] * o[5] * (6.1258633752464e-12 - 0.000084004935396416 * o[8]) * taug) + pi * ((-1.24017662339842e-24 * o[12]) + pi * (0.0000832192847496054 * o[13] * o[4] * o[6] * taug + pi * (o[2] * o[5] * o[6] * (1.75410265428146e-27 + (1.32995316841867e-15 - 0.0000226487297378904 * o[2] * o[6]) * o[9]) * pi - 2.93678005497663e-14 * o[13] * o[2] * o[4] * taug))))))))))))))))) / pi;
5292 d := p / (data.RH2O * T * pi * gpi23);
5293 end dofp23;
5294
5295 function dofpt3 "Inverse iteration in region 3: (d) = f(p,T)"
5296 extends Modelica.Icons.Function;
5297 input SI.Pressure p "Pressure";
5298 input SI.Temperature T "Temperature (K)";
5299 input SI.Pressure delp "Iteration converged if (p-pre(p) < delp)";
5300 output SI.Density d "Density";
5301 output Integer error = 0 "Error flag: iteration failed if different from 0";
5302 protected
5303 SI.Density dguess "Guess density";
5304 Integer i = 0 "Loop counter";
5305 Real dp "Pressure difference";
5306 SI.Density deld "Density step";
5307 Modelica.Media.Common.HelmholtzDerivs f "Dimensionless Helmholtz function and derivatives w.r.t. delta and tau";
5308 Modelica.Media.Common.NewtonDerivatives_pT nDerivs "Derivatives needed in Newton iteration";
5309 Boolean found = false "Flag for iteration success";
5310 Boolean supercritical "Flag, true for supercritical states";
5311 Boolean liquid "Flag, true for liquid states";
5312 SI.Density dmin "Lower density limit";
5313 SI.Density dmax "Upper density limit";
5314 SI.Temperature Tmax "Maximum temperature";
5315 Real damping "Damping factor";
5316 algorithm
5317 found := false;
5318 assert(p >= data.PLIMIT4A, "BaseIF97.dofpt3: function called outside of region 3! p too low\n" + "p = " + String(p) + " Pa < " + String(data.PLIMIT4A) + " Pa");
5319 assert(T >= data.TLIMIT1, "BaseIF97.dofpt3: function called outside of region 3! T too low\n" + "T = " + String(T) + " K < " + String(data.TLIMIT1) + " K");
5320 assert(p >= Regions.boundary23ofT(T), "BaseIF97.dofpt3: function called outside of region 3! T too high\n" + "p = " + String(p) + " Pa, T = " + String(T) + " K");
5321 supercritical := p > data.PCRIT;
5322 damping := if supercritical then 1.0 else 1.0;
5323 Tmax := Regions.boundary23ofp(p);
5324 if supercritical then
5325 dmax := dofp13(p);
5326 dmin := dofp23(p);
5327 dguess := dmax - (T - data.TLIMIT1) / (data.TLIMIT1 - Tmax) * (dmax - dmin);
5328 else
5329 liquid := T < Basic.tsat(p);
5330 if liquid then
5331 dmax := dofp13(p);
5332 dmin := Regions.rhol_p_R4b(p);
5333 dguess := 1.1 * Regions.rhol_T(T) "Guess: 10 percent more than on the phase boundary for same T";
5334 else
5335 dmax := Regions.rhov_p_R4b(p);
5336 dmin := dofp23(p);
5337 dguess := 0.9 * Regions.rhov_T(T) "Guess: 10% less than on the phase boundary for same T";
5338 end if;
5339 end if;
5340 while i < IterationData.IMAX and not found loop
5341 d := dguess;
5342 f := Basic.f3(d, T);
5343 nDerivs := Modelica.Media.Common.Helmholtz_pT(f);
5344 dp := nDerivs.p - p;
5345 if abs(dp / p) <= delp then
5346 found := true;
5347 else
5348 end if;
5349 deld := dp / nDerivs.pd * damping;
5350 d := d - deld;
5351 if d > dmin and d < dmax then
5352 dguess := d;
5353 else
5354 if d > dmax then
5355 dguess := dmax - sqrt(Modelica.Constants.eps);
5356 else
5357 dguess := dmin + sqrt(Modelica.Constants.eps);
5358 end if;
5359 end if;
5360 i := i + 1;
5361 end while;
5362 if not found then
5363 error := 1;
5364 else
5365 end if;
5366 assert(error <> 1, "Error in inverse function dofpt3: iteration failed");
5367 end dofpt3;
5368
5369 function dtofph3 "Inverse iteration in region 3: (d,T) = f(p,h)"
5370 extends Modelica.Icons.Function;
5371 input SI.Pressure p "Pressure";
5372 input SI.SpecificEnthalpy h "Specific enthalpy";
5373 input SI.Pressure delp "Iteration accuracy";
5374 input SI.SpecificEnthalpy delh "Iteration accuracy";
5375 output SI.Density d "Density";
5376 output SI.Temperature T "Temperature (K)";
5377 output Integer error "Error flag: iteration failed if different from 0";
5378 protected
5379 SI.Temperature Tguess "Initial temperature";
5380 SI.Density dguess "Initial density";
5381 Integer i "Iteration counter";
5382 Real dh "Newton-error in h-direction";
5383 Real dp "Newton-error in p-direction";
5384 Real det "Determinant of directional derivatives";
5385 Real deld "Newton-step in d-direction";
5386 Real delt "Newton-step in T-direction";
5387 Modelica.Media.Common.HelmholtzDerivs f "Dimensionless Helmholtz function and derivatives w.r.t. delta and tau";
5388 Modelica.Media.Common.NewtonDerivatives_ph nDerivs "Derivatives needed in Newton iteration";
5389 Boolean found = false "Flag for iteration success";
5390 Integer subregion "1 for subregion 3a, 2 for subregion 3b";
5391 algorithm
5392 if p < data.PCRIT then
5393 subregion := if h < Regions.hl_p(p) + 10.0 then 1 else if h > Regions.hv_p(p) - 10.0 then 2 else 0;
5394 assert(subregion <> 0, "Inverse iteration of dt from ph called in 2 phase region: this can not work");
5395 else
5396 subregion := if h < Basic.h3ab_p(p) then 1 else 2;
5397 end if;
5398 T := if subregion == 1 then Basic.T3a_ph(p, h) else Basic.T3b_ph(p, h);
5399 d := if subregion == 1 then 1 / Basic.v3a_ph(p, h) else 1 / Basic.v3b_ph(p, h);
5400 i := 0;
5401 error := 0;
5402 while i < IterationData.IMAX and not found loop
5403 f := Basic.f3(d, T);
5404 nDerivs := Modelica.Media.Common.Helmholtz_ph(f);
5405 dh := nDerivs.h - h;
5406 dp := nDerivs.p - p;
5407 if abs(dh / h) <= delh and abs(dp / p) <= delp then
5408 found := true;
5409 else
5410 end if;
5411 det := nDerivs.ht * nDerivs.pd - nDerivs.pt * nDerivs.hd;
5412 delt := (nDerivs.pd * dh - nDerivs.hd * dp) / det;
5413 deld := (nDerivs.ht * dp - nDerivs.pt * dh) / det;
5414 T := T - delt;
5415 d := d - deld;
5416 dguess := d;
5417 Tguess := T;
5418 i := i + 1;
5419 (d, T) := fixdT(dguess, Tguess);
5420 end while;
5421 if not found then
5422 error := 1;
5423 else
5424 end if;
5425 assert(error <> 1, "Error in inverse function dtofph3: iteration failed");
5426 end dtofph3;
5427
5428 function dtofps3 "Inverse iteration in region 3: (d,T) = f(p,s)"
5429 extends Modelica.Icons.Function;
5430 input SI.Pressure p "Pressure";
5431 input SI.SpecificEntropy s "Specific entropy";
5432 input SI.Pressure delp "Iteration accuracy";
5433 input SI.SpecificEntropy dels "Iteration accuracy";
5434 output SI.Density d "Density";
5435 output SI.Temperature T "Temperature (K)";
5436 output Integer error "Error flag: iteration failed if different from 0";
5437 protected
5438 SI.Temperature Tguess "Initial temperature";
5439 SI.Density dguess "Initial density";
5440 Integer i "Iteration counter";
5441 Real ds "Newton-error in s-direction";
5442 Real dp "Newton-error in p-direction";
5443 Real det "Determinant of directional derivatives";
5444 Real deld "Newton-step in d-direction";
5445 Real delt "Newton-step in T-direction";
5446 Modelica.Media.Common.HelmholtzDerivs f "Dimensionless Helmholtz function and derivatives w.r.t. delta and tau";
5447 Modelica.Media.Common.NewtonDerivatives_ps nDerivs "Derivatives needed in Newton iteration";
5448 Boolean found "Flag for iteration success";
5449 Integer subregion "1 for subregion 3a, 2 for subregion 3b";
5450 algorithm
5451 i := 0;
5452 error := 0;
5453 found := false;
5454 if p < data.PCRIT then
5455 subregion := if s < Regions.sl_p(p) + 10.0 then 1 else if s > Regions.sv_p(p) - 10.0 then 2 else 0;
5456 assert(subregion <> 0, "Inverse iteration of dt from ps called in 2 phase region: this is illegal!");
5457 else
5458 subregion := if s < data.SCRIT then 1 else 2;
5459 end if;
5460 T := if subregion == 1 then Basic.T3a_ps(p, s) else Basic.T3b_ps(p, s);
5461 d := if subregion == 1 then 1 / Basic.v3a_ps(p, s) else 1 / Basic.v3b_ps(p, s);
5462 while i < IterationData.IMAX and not found loop
5463 f := Basic.f3(d, T);
5464 nDerivs := Modelica.Media.Common.Helmholtz_ps(f);
5465 ds := nDerivs.s - s;
5466 dp := nDerivs.p - p;
5467 if abs(ds / s) <= dels and abs(dp / p) <= delp then
5468 found := true;
5469 else
5470 end if;
5471 det := nDerivs.st * nDerivs.pd - nDerivs.pt * nDerivs.sd;
5472 delt := (nDerivs.pd * ds - nDerivs.sd * dp) / det;
5473 deld := (nDerivs.st * dp - nDerivs.pt * ds) / det;
5474 T := T - delt;
5475 d := d - deld;
5476 dguess := d;
5477 Tguess := T;
5478 i := i + 1;
5479 (d, T) := fixdT(dguess, Tguess);
5480 end while;
5481 if not found then
5482 error := 1;
5483 else
5484 end if;
5485 assert(error <> 1, "Error in inverse function dtofps3: iteration failed");
5486 end dtofps3;
5487
5488 function pofdt125 "Inverse iteration in region 1,2 and 5: p = g(d,T)"
5489 extends Modelica.Icons.Function;
5490 input SI.Density d "Density";
5491 input SI.Temperature T "Temperature (K)";
5492 input SI.Pressure reldd "Relative iteration accuracy of density";
5493 input Integer region "Region in IAPWS/IF97 in which inverse should be calculated";
5494 output SI.Pressure p "Pressure";
5495 output Integer error "Error flag: iteration failed if different from 0";
5496 protected
5497 Integer i "Counter for while-loop";
5498 Modelica.Media.Common.GibbsDerivs g "Dimensionless Gibbs function and derivatives w.r.t. pi and tau";
5499 Boolean found "Flag if iteration has been successful";
5500 Real dd "Difference between density for guessed p and the current density";
5501 Real delp "Step in p in Newton-iteration";
5502 Real relerr "Relative error in d";
5503 SI.Pressure pguess1 = 1.0e6 "Initial pressure guess in region 1";
5504 SI.Pressure pguess2 "Initial pressure guess in region 2";
5505 constant SI.Pressure pguess5 = 0.5e6 "Initial pressure guess in region 5";
5506 algorithm
5507 i := 0;
5508 error := 0;
5509 pguess2 := 42800 * d;
5510 found := false;
5511 if region == 1 then
5512 p := pguess1;
5513 elseif region == 2 then
5514 p := pguess2;
5515 else
5516 p := pguess5;
5517 end if;
5518 while i < IterationData.IMAX and not found loop
5519 if region == 1 then
5520 g := Basic.g1(p, T);
5521 elseif region == 2 then
5522 g := Basic.g2(p, T);
5523 else
5524 g := Basic.g5(p, T);
5525 end if;
5526 dd := p / (data.RH2O * T * g.pi * g.gpi) - d;
5527 relerr := dd / d;
5528 if abs(relerr) < reldd then
5529 found := true;
5530 else
5531 end if;
5532 delp := dd * (-p * p / (d * d * data.RH2O * T * g.pi * g.pi * g.gpipi));
5533 p := p - delp;
5534 i := i + 1;
5535 if not found then
5536 if p < triple.ptriple then
5537 p := 2.0 * triple.ptriple;
5538 else
5539 end if;
5540 if p > data.PLIMIT1 then
5541 p := 0.95 * data.PLIMIT1;
5542 else
5543 end if;
5544 else
5545 end if;
5546 end while;
5547 if not found then
5548 error := 1;
5549 else
5550 end if;
5551 assert(error <> 1, "Error in inverse function pofdt125: iteration failed");
5552 end pofdt125;
5553
5554 function tofph5 "Inverse iteration in region 5: (p,T) = f(p,h)"
5555 extends Modelica.Icons.Function;
5556 input SI.Pressure p "Pressure";
5557 input SI.SpecificEnthalpy h "Specific enthalpy";
5558 input SI.SpecificEnthalpy reldh "Iteration accuracy";
5559 output SI.Temperature T "Temperature (K)";
5560 output Integer error "Error flag: iteration failed if different from 0";
5561 protected
5562 Modelica.Media.Common.GibbsDerivs g "Dimensionless Gibbs function and derivatives w.r.t. pi and tau";
5563 SI.SpecificEnthalpy proh "H for current guess in T";
5564 constant SI.Temperature Tguess = 1500 "Initial temperature";
5565 Integer i "Iteration counter";
5566 Real relerr "Relative error in h";
5567 Real dh "Newton-error in h-direction";
5568 Real dT "Newton-step in T-direction";
5569 Boolean found "Flag for iteration success";
5570 algorithm
5571 i := 0;
5572 error := 0;
5573 T := Tguess;
5574 found := false;
5575 while i < IterationData.IMAX and not found loop
5576 g := Basic.g5(p, T);
5577 proh := data.RH2O * T * g.tau * g.gtau;
5578 dh := proh - h;
5579 relerr := dh / h;
5580 if abs(relerr) < reldh then
5581 found := true;
5582 else
5583 end if;
5584 dT := dh / (-data.RH2O * g.tau * g.tau * g.gtautau);
5585 T := T - dT;
5586 i := i + 1;
5587 end while;
5588 if not found then
5589 error := 1;
5590 else
5591 end if;
5592 assert(error <> 1, "Error in inverse function tofph5: iteration failed");
5593 end tofph5;
5594
5595 function tofps5 "Inverse iteration in region 5: (p,T) = f(p,s)"
5596 extends Modelica.Icons.Function;
5597 input SI.Pressure p "Pressure";
5598 input SI.SpecificEntropy s "Specific entropy";
5599 input SI.SpecificEnthalpy relds "Iteration accuracy";
5600 output SI.Temperature T "Temperature (K)";
5601 output Integer error "Error flag: iteration failed if different from 0";
5602 protected
5603 Modelica.Media.Common.GibbsDerivs g "Dimensionless Gibbs function and derivatives w.r.t. pi and tau";
5604 SI.SpecificEntropy pros "S for current guess in T";
5605 parameter SI.Temperature Tguess = 1500 "Initial temperature";
5606 Integer i "Iteration counter";
5607 Real relerr "Relative error in s";
5608 Real ds "Newton-error in s-direction";
5609 Real dT "Newton-step in T-direction";
5610 Boolean found "Flag for iteration success";
5611 algorithm
5612 i := 0;
5613 error := 0;
5614 T := Tguess;
5615 found := false;
5616 while i < IterationData.IMAX and not found loop
5617 g := Basic.g5(p, T);
5618 pros := data.RH2O * (g.tau * g.gtau - g.g);
5619 ds := pros - s;
5620 relerr := ds / s;
5621 if abs(relerr) < relds then
5622 found := true;
5623 else
5624 end if;
5625 dT := ds * T / (-data.RH2O * g.tau * g.tau * g.gtautau);
5626 T := T - dT;
5627 i := i + 1;
5628 end while;
5629 if not found then
5630 error := 1;
5631 else
5632 end if;
5633 assert(error <> 1, "Error in inverse function tofps5: iteration failed");
5634 end tofps5;
5635 end Inverses;
5636 end BaseIF97;
5637
5638 function waterBaseProp_ph "Intermediate property record for water"
5639 extends Modelica.Icons.Function;
5640 input SI.Pressure p "Pressure";
5641 input SI.SpecificEnthalpy h "Specific enthalpy";
5642 input Integer phase = 0 "Phase: 2 for two-phase, 1 for one phase, 0 if unknown";
5643 input Integer region = 0 "If 0, do region computation, otherwise assume the region is this input";
5644 output Common.IF97BaseTwoPhase aux "Auxiliary record";
5645 protected
5646 Common.GibbsDerivs g "Dimensionless Gibbs function and derivatives w.r.t. pi and tau";
5647 Common.HelmholtzDerivs f "Dimensionless Helmholtz function and derivatives w.r.t. delta and tau";
5648 Integer error "Error flag for inverse iterations";
5649 SI.SpecificEnthalpy h_liq "Liquid specific enthalpy";
5650 SI.Density d_liq "Liquid density";
5651 SI.SpecificEnthalpy h_vap "Vapour specific enthalpy";
5652 SI.Density d_vap "Vapour density";
5653 Common.PhaseBoundaryProperties liq "Phase boundary property record";
5654 Common.PhaseBoundaryProperties vap "Phase boundary property record";
5655 Common.GibbsDerivs gl "Dimensionless Gibbs function and derivatives w.r.t. pi and tau";
5656 Common.GibbsDerivs gv "Dimensionless Gibbs function and derivatives w.r.t. pi and tau";
5657 Modelica.Media.Common.HelmholtzDerivs fl "Dimensionless Helmholtz function and derivatives w.r.t. delta and tau";
5658 Modelica.Media.Common.HelmholtzDerivs fv "Dimensionless Helmholtz function and derivatives w.r.t. delta and tau";
5659 SI.Temperature t1 "Temperature at phase boundary, using inverse from region 1";
5660 SI.Temperature t2 "Temperature at phase boundary, using inverse from region 2";
5661 algorithm
5662 aux.region := if region == 0 then if phase == 2 then 4 else BaseIF97.Regions.region_ph(p = p, h = h, phase = phase) else region;
5663 aux.phase := if phase <> 0 then phase else if aux.region == 4 then 2 else 1;
5664 aux.p := max(p, 611.657);
5665 aux.h := max(h, 1e3);
5666 aux.R := BaseIF97.data.RH2O;
5667 aux.vt := 0.0 "initialized in case it is not needed";
5668 aux.vp := 0.0 "initialized in case it is not needed";
5669 if aux.region == 1 then
5670 aux.T := BaseIF97.Basic.tph1(aux.p, aux.h);
5671 g := BaseIF97.Basic.g1(p, aux.T);
5672 aux.s := aux.R * (g.tau * g.gtau - g.g);
5673 aux.rho := p / (aux.R * aux.T * g.pi * g.gpi);
5674 aux.vt := aux.R / p * (g.pi * g.gpi - g.tau * g.pi * g.gtaupi);
5675 aux.pt := -g.p / g.T * (g.gpi - g.tau * g.gtaupi) / (g.gpipi * g.pi);
5676 aux.pd := -g.R * g.T * g.gpi * g.gpi / g.gpipi;
5677 aux.vp := aux.R * aux.T / (p * p) * g.pi * g.pi * g.gpipi;
5678 aux.cp := -aux.R * g.tau * g.tau * g.gtautau;
5679 aux.cv := aux.R * ((-g.tau * g.tau * g.gtautau) + (g.gpi - g.tau * g.gtaupi) * (g.gpi - g.tau * g.gtaupi) / g.gpipi);
5680 aux.x := 0.0;
5681 aux.dpT := -aux.vt / aux.vp;
5682 elseif aux.region == 2 then
5683 aux.T := BaseIF97.Basic.tph2(aux.p, aux.h);
5684 g := BaseIF97.Basic.g2(p, aux.T);
5685 aux.s := aux.R * (g.tau * g.gtau - g.g);
5686 aux.rho := p / (aux.R * aux.T * g.pi * g.gpi);
5687 aux.vt := aux.R / p * (g.pi * g.gpi - g.tau * g.pi * g.gtaupi);
5688 aux.vp := aux.R * aux.T / (p * p) * g.pi * g.pi * g.gpipi;
5689 aux.pt := -g.p / g.T * (g.gpi - g.tau * g.gtaupi) / (g.gpipi * g.pi);
5690 aux.pd := -g.R * g.T * g.gpi * g.gpi / g.gpipi;
5691 aux.cp := -aux.R * g.tau * g.tau * g.gtautau;
5692 aux.cv := aux.R * ((-g.tau * g.tau * g.gtautau) + (g.gpi - g.tau * g.gtaupi) * (g.gpi - g.tau * g.gtaupi) / g.gpipi);
5693 aux.x := 1.0;
5694 aux.dpT := -aux.vt / aux.vp;
5695 elseif aux.region == 3 then
5696 (aux.rho, aux.T, error) := BaseIF97.Inverses.dtofph3(p = aux.p, h = aux.h, delp = 1.0e-7, delh = 1.0e-6);
5697 f := BaseIF97.Basic.f3(aux.rho, aux.T);
5698 aux.h := aux.R * aux.T * (f.tau * f.ftau + f.delta * f.fdelta);
5699 aux.s := aux.R * (f.tau * f.ftau - f.f);
5700 aux.pd := aux.R * aux.T * f.delta * (2.0 * f.fdelta + f.delta * f.fdeltadelta);
5701 aux.pt := aux.R * aux.rho * f.delta * (f.fdelta - f.tau * f.fdeltatau);
5702 aux.cv := abs(aux.R * (-f.tau * f.tau * f.ftautau)) "Can be close to neg. infinity near critical point";
5703 aux.cp := (aux.rho * aux.rho * aux.pd * aux.cv + aux.T * aux.pt * aux.pt) / (aux.rho * aux.rho * aux.pd);
5704 aux.x := 0.0;
5705 aux.dpT := aux.pt;
5706 elseif aux.region == 4 then
5707 h_liq := hl_p(p);
5708 h_vap := hv_p(p);
5709 aux.x := if h_vap <> h_liq then (h - h_liq) / (h_vap - h_liq) else 1.0;
5710 if p < BaseIF97.data.PLIMIT4A then
5711 t1 := BaseIF97.Basic.tph1(aux.p, h_liq);
5712 t2 := BaseIF97.Basic.tph2(aux.p, h_vap);
5713 gl := BaseIF97.Basic.g1(aux.p, t1);
5714 gv := BaseIF97.Basic.g2(aux.p, t2);
5715 liq := Common.gibbsToBoundaryProps(gl);
5716 vap := Common.gibbsToBoundaryProps(gv);
5717 aux.T := t1 + aux.x * (t2 - t1);
5718 else
5719 aux.T := BaseIF97.Basic.tsat(aux.p);
5720 d_liq := rhol_T(aux.T);
5721 d_vap := rhov_T(aux.T);
5722 fl := BaseIF97.Basic.f3(d_liq, aux.T);
5723 fv := BaseIF97.Basic.f3(d_vap, aux.T);
5724 liq := Common.helmholtzToBoundaryProps(fl);
5725 vap := Common.helmholtzToBoundaryProps(fv);
5726 end if;
5727 aux.dpT := if liq.d <> vap.d then (vap.s - liq.s) * liq.d * vap.d / (liq.d - vap.d) else BaseIF97.Basic.dptofT(aux.T);
5728 aux.s := liq.s + aux.x * (vap.s - liq.s);
5729 aux.rho := liq.d * vap.d / (vap.d + aux.x * (liq.d - vap.d));
5730 aux.cv := Common.cv2Phase(liq, vap, aux.x, aux.T, p);
5731 aux.cp := liq.cp + aux.x * (vap.cp - liq.cp);
5732 aux.pt := liq.pt + aux.x * (vap.pt - liq.pt);
5733 aux.pd := liq.pd + aux.x * (vap.pd - liq.pd);
5734 elseif aux.region == 5 then
5735 (aux.T, error) := BaseIF97.Inverses.tofph5(p = aux.p, h = aux.h, reldh = 1.0e-7);
5736 assert(error == 0, "Error in inverse iteration of steam tables");
5737 g := BaseIF97.Basic.g5(aux.p, aux.T);
5738 aux.s := aux.R * (g.tau * g.gtau - g.g);
5739 aux.rho := p / (aux.R * aux.T * g.pi * g.gpi);
5740 aux.vt := aux.R / p * (g.pi * g.gpi - g.tau * g.pi * g.gtaupi);
5741 aux.vp := aux.R * aux.T / (p * p) * g.pi * g.pi * g.gpipi;
5742 aux.pt := -g.p / g.T * (g.gpi - g.tau * g.gtaupi) / (g.gpipi * g.pi);
5743 aux.pd := -g.R * g.T * g.gpi * g.gpi / g.gpipi;
5744 aux.cp := -aux.R * g.tau * g.tau * g.gtautau;
5745 aux.cv := aux.R * ((-g.tau * g.tau * g.gtautau) + (g.gpi - g.tau * g.gtaupi) * (g.gpi - g.tau * g.gtaupi) / g.gpipi);
5746 aux.dpT := -aux.vt / aux.vp;
5747 else
5748 assert(false, "Error in region computation of IF97 steam tables" + "(p = " + String(p) + ", h = " + String(h) + ")");
5749 end if;
5750 end waterBaseProp_ph;
5751
5752 function waterBaseProp_ps "Intermediate property record for water"
5753 extends Modelica.Icons.Function;
5754 input SI.Pressure p "Pressure";
5755 input SI.SpecificEntropy s "Specific entropy";
5756 input Integer phase = 0 "Phase: 2 for two-phase, 1 for one phase, 0 if unknown";
5757 input Integer region = 0 "If 0, do region computation, otherwise assume the region is this input";
5758 output Common.IF97BaseTwoPhase aux "Auxiliary record";
5759 protected
5760 Common.GibbsDerivs g "Dimensionless Gibbs function and derivatives w.r.t. pi and tau";
5761 Common.HelmholtzDerivs f "Dimensionless Helmholtz function and derivatives w.r.t. delta and tau";
5762 Integer error "Error flag for inverse iterations";
5763 SI.SpecificEntropy s_liq "Liquid specific entropy";
5764 SI.Density d_liq "Liquid density";
5765 SI.SpecificEntropy s_vap "Vapour specific entropy";
5766 SI.Density d_vap "Vapour density";
5767 Common.PhaseBoundaryProperties liq "Phase boundary property record";
5768 Common.PhaseBoundaryProperties vap "Phase boundary property record";
5769 Common.GibbsDerivs gl "Dimensionless Gibbs function and derivatives w.r.t. pi and tau";
5770 Common.GibbsDerivs gv "Dimensionless Gibbs function and derivatives w.r.t. pi and tau";
5771 Modelica.Media.Common.HelmholtzDerivs fl "Dimensionless Helmholtz function and derivatives w.r.t. delta and tau";
5772 Modelica.Media.Common.HelmholtzDerivs fv "Dimensionless Helmholtz function and derivatives w.r.t. delta and tau";
5773 SI.Temperature t1 "Temperature at phase boundary, using inverse from region 1";
5774 SI.Temperature t2 "Temperature at phase boundary, using inverse from region 2";
5775 algorithm
5776 aux.region := if region == 0 then if phase == 2 then 4 else BaseIF97.Regions.region_ps(p = p, s = s, phase = phase) else region;
5777 aux.phase := if phase <> 0 then phase else if aux.region == 4 then 2 else 1;
5778 aux.p := p;
5779 aux.s := s;
5780 aux.R := BaseIF97.data.RH2O;
5781 aux.vt := 0.0 "initialized in case it is not needed";
5782 aux.vp := 0.0 "initialized in case it is not needed";
5783 if aux.region == 1 then
5784 aux.T := BaseIF97.Basic.tps1(p, s);
5785 g := BaseIF97.Basic.g1(p, aux.T);
5786 aux.h := aux.R * aux.T * g.tau * g.gtau;
5787 aux.rho := p / (aux.R * aux.T * g.pi * g.gpi);
5788 aux.vt := aux.R / p * (g.pi * g.gpi - g.tau * g.pi * g.gtaupi);
5789 aux.vp := aux.R * aux.T / (p * p) * g.pi * g.pi * g.gpipi;
5790 aux.pt := -g.p / g.T * (g.gpi - g.tau * g.gtaupi) / (g.gpipi * g.pi);
5791 aux.pd := -g.R * g.T * g.gpi * g.gpi / g.gpipi;
5792 aux.cp := -aux.R * g.tau * g.tau * g.gtautau;
5793 aux.cv := aux.R * ((-g.tau * g.tau * g.gtautau) + (g.gpi - g.tau * g.gtaupi) * (g.gpi - g.tau * g.gtaupi) / g.gpipi);
5794 aux.x := 0.0;
5795 aux.dpT := -aux.vt / aux.vp;
5796 elseif aux.region == 2 then
5797 aux.T := BaseIF97.Basic.tps2(p, s);
5798 g := BaseIF97.Basic.g2(p, aux.T);
5799 aux.h := aux.R * aux.T * g.tau * g.gtau;
5800 aux.rho := p / (aux.R * aux.T * g.pi * g.gpi);
5801 aux.vt := aux.R / p * (g.pi * g.gpi - g.tau * g.pi * g.gtaupi);
5802 aux.vp := aux.R * aux.T / (p * p) * g.pi * g.pi * g.gpipi;
5803 aux.pt := -g.p / g.T * (g.gpi - g.tau * g.gtaupi) / (g.gpipi * g.pi);
5804 aux.pd := -g.R * g.T * g.gpi * g.gpi / g.gpipi;
5805 aux.cp := -aux.R * g.tau * g.tau * g.gtautau;
5806 aux.cv := aux.R * ((-g.tau * g.tau * g.gtautau) + (g.gpi - g.tau * g.gtaupi) * (g.gpi - g.tau * g.gtaupi) / g.gpipi);
5807 aux.x := 1.0;
5808 aux.dpT := -aux.vt / aux.vp;
5809 elseif aux.region == 3 then
5810 (aux.rho, aux.T, error) := BaseIF97.Inverses.dtofps3(p = p, s = s, delp = 1.0e-7, dels = 1.0e-6);
5811 f := BaseIF97.Basic.f3(aux.rho, aux.T);
5812 aux.h := aux.R * aux.T * (f.tau * f.ftau + f.delta * f.fdelta);
5813 aux.s := aux.R * (f.tau * f.ftau - f.f);
5814 aux.pd := aux.R * aux.T * f.delta * (2.0 * f.fdelta + f.delta * f.fdeltadelta);
5815 aux.pt := aux.R * aux.rho * f.delta * (f.fdelta - f.tau * f.fdeltatau);
5816 aux.cv := aux.R * (-f.tau * f.tau * f.ftautau);
5817 aux.cp := (aux.rho * aux.rho * aux.pd * aux.cv + aux.T * aux.pt * aux.pt) / (aux.rho * aux.rho * aux.pd);
5818 aux.x := 0.0;
5819 aux.dpT := aux.pt;
5820 elseif aux.region == 4 then
5821 s_liq := BaseIF97.Regions.sl_p(p);
5822 s_vap := BaseIF97.Regions.sv_p(p);
5823 aux.x := if s_vap <> s_liq then (s - s_liq) / (s_vap - s_liq) else 1.0;
5824 if p < BaseIF97.data.PLIMIT4A then
5825 t1 := BaseIF97.Basic.tps1(p, s_liq);
5826 t2 := BaseIF97.Basic.tps2(p, s_vap);
5827 gl := BaseIF97.Basic.g1(p, t1);
5828 gv := BaseIF97.Basic.g2(p, t2);
5829 liq := Common.gibbsToBoundaryProps(gl);
5830 vap := Common.gibbsToBoundaryProps(gv);
5831 aux.T := t1 + aux.x * (t2 - t1);
5832 else
5833 aux.T := BaseIF97.Basic.tsat(p);
5834 d_liq := rhol_T(aux.T);
5835 d_vap := rhov_T(aux.T);
5836 fl := BaseIF97.Basic.f3(d_liq, aux.T);
5837 fv := BaseIF97.Basic.f3(d_vap, aux.T);
5838 liq := Common.helmholtzToBoundaryProps(fl);
5839 vap := Common.helmholtzToBoundaryProps(fv);
5840 end if;
5841 aux.dpT := if liq.d <> vap.d then (vap.s - liq.s) * liq.d * vap.d / (liq.d - vap.d) else BaseIF97.Basic.dptofT(aux.T);
5842 aux.h := liq.h + aux.x * (vap.h - liq.h);
5843 aux.rho := liq.d * vap.d / (vap.d + aux.x * (liq.d - vap.d));
5844 aux.cv := Common.cv2Phase(liq, vap, aux.x, aux.T, p);
5845 aux.cp := liq.cp + aux.x * (vap.cp - liq.cp);
5846 aux.pt := liq.pt + aux.x * (vap.pt - liq.pt);
5847 aux.pd := liq.pd + aux.x * (vap.pd - liq.pd);
5848 elseif aux.region == 5 then
5849 (aux.T, error) := BaseIF97.Inverses.tofps5(p = p, s = s, relds = 1.0e-7);
5850 assert(error == 0, "Error in inverse iteration of steam tables");
5851 g := BaseIF97.Basic.g5(p, aux.T);
5852 aux.h := aux.R * aux.T * g.tau * g.gtau;
5853 aux.rho := p / (aux.R * aux.T * g.pi * g.gpi);
5854 aux.vt := aux.R / p * (g.pi * g.gpi - g.tau * g.pi * g.gtaupi);
5855 aux.vp := aux.R * aux.T / (p * p) * g.pi * g.pi * g.gpipi;
5856 aux.pt := -g.p / g.T * (g.gpi - g.tau * g.gtaupi) / (g.gpipi * g.pi);
5857 aux.pd := -g.R * g.T * g.gpi * g.gpi / g.gpipi;
5858 aux.cp := -aux.R * g.tau * g.tau * g.gtautau;
5859 aux.cv := aux.R * ((-g.tau * g.tau * g.gtautau) + (g.gpi - g.tau * g.gtaupi) * (g.gpi - g.tau * g.gtaupi) / g.gpipi);
5860 aux.dpT := -aux.vt / aux.vp;
5861 aux.x := 1.0;
5862 else
5863 assert(false, "Error in region computation of IF97 steam tables" + "(p = " + String(p) + ", s = " + String(s) + ")");
5864 end if;
5865 end waterBaseProp_ps;
5866
5867 function rho_props_ps "Density as function of pressure and specific entropy"
5868 extends Modelica.Icons.Function;
5869 input SI.Pressure p "Pressure";
5870 input SI.SpecificEntropy s "Specific entropy";
5871 input Common.IF97BaseTwoPhase properties "Auxiliary record";
5872 output SI.Density rho "Density";
5873 algorithm
5874 rho := properties.rho;
5875 annotation(Inline = false, LateInline = true);
5876 end rho_props_ps;
5877
5878 function rho_ps "Density as function of pressure and specific entropy"
5879 extends Modelica.Icons.Function;
5880 input SI.Pressure p "Pressure";
5881 input SI.SpecificEntropy s "Specific entropy";
5882 input Integer phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
5883 input Integer region = 0 "If 0, region is unknown, otherwise known and this input";
5884 output SI.Density rho "Density";
5885 algorithm
5886 rho := rho_props_ps(p, s, waterBaseProp_ps(p, s, phase, region));
5887 annotation(Inline = true);
5888 end rho_ps;
5889
5890 function T_props_ps "Temperature as function of pressure and specific entropy"
5891 extends Modelica.Icons.Function;
5892 input SI.Pressure p "Pressure";
5893 input SI.SpecificEntropy s "Specific entropy";
5894 input Common.IF97BaseTwoPhase properties "Auxiliary record";
5895 output SI.Temperature T "Temperature";
5896 algorithm
5897 T := properties.T;
5898 annotation(Inline = false, LateInline = true);
5899 end T_props_ps;
5900
5901 function T_ps "Temperature as function of pressure and specific entropy"
5902 extends Modelica.Icons.Function;
5903 input SI.Pressure p "Pressure";
5904 input SI.SpecificEntropy s "Specific entropy";
5905 input Integer phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
5906 input Integer region = 0 "If 0, region is unknown, otherwise known and this input";
5907 output SI.Temperature T "Temperature";
5908 algorithm
5909 T := T_props_ps(p, s, waterBaseProp_ps(p, s, phase, region));
5910 annotation(Inline = true);
5911 end T_ps;
5912
5913 function h_props_ps "Specific enthalpy as function or pressure and temperature"
5914 extends Modelica.Icons.Function;
5915 input SI.Pressure p "Pressure";
5916 input SI.SpecificEntropy s "Specific entropy";
5917 input Common.IF97BaseTwoPhase aux "Auxiliary record";
5918 output SI.SpecificEnthalpy h "Specific enthalpy";
5919 algorithm
5920 h := aux.h;
5921 annotation(Inline = false, LateInline = true);
5922 end h_props_ps;
5923
5924 function h_ps "Specific enthalpy as function or pressure and temperature"
5925 extends Modelica.Icons.Function;
5926 input SI.Pressure p "Pressure";
5927 input SI.SpecificEntropy s "Specific entropy";
5928 input Integer phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
5929 input Integer region = 0 "If 0, region is unknown, otherwise known and this input";
5930 output SI.SpecificEnthalpy h "Specific enthalpy";
5931 algorithm
5932 h := h_props_ps(p, s, waterBaseProp_ps(p, s, phase, region));
5933 annotation(Inline = true);
5934 end h_ps;
5935
5936 function rho_props_ph "Density as function of pressure and specific enthalpy"
5937 extends Modelica.Icons.Function;
5938 input SI.Pressure p "Pressure";
5939 input SI.SpecificEnthalpy h "Specific enthalpy";
5940 input Common.IF97BaseTwoPhase properties "Auxiliary record";
5941 output SI.Density rho "Density";
5942 algorithm
5943 rho := properties.rho;
5944 annotation(derivative(noDerivative = properties) = rho_ph_der, Inline = false, LateInline = true);
5945 end rho_props_ph;
5946
5947 function rho_ph "Density as function of pressure and specific enthalpy"
5948 extends Modelica.Icons.Function;
5949 input SI.Pressure p "Pressure";
5950 input SI.SpecificEnthalpy h "Specific enthalpy";
5951 input Integer phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
5952 input Integer region = 0 "If 0, region is unknown, otherwise known and this input";
5953 output SI.Density rho "Density";
5954 algorithm
5955 rho := rho_props_ph(p, h, waterBaseProp_ph(p, h, phase, region));
5956 annotation(Inline = true);
5957 end rho_ph;
5958
5959 function rho_ph_der "Derivative function of rho_ph"
5960 extends Modelica.Icons.Function;
5961 input SI.Pressure p "Pressure";
5962 input SI.SpecificEnthalpy h "Specific enthalpy";
5963 input Common.IF97BaseTwoPhase properties "Auxiliary record";
5964 input Real p_der "Derivative of pressure";
5965 input Real h_der "Derivative of specific enthalpy";
5966 output Real rho_der "Derivative of density";
5967 algorithm
5968 if properties.region == 4 then
5969 rho_der := properties.rho * (properties.rho * properties.cv / properties.dpT + 1.0) / (properties.dpT * properties.T) * p_der + (-properties.rho * properties.rho / (properties.dpT * properties.T)) * h_der;
5970 elseif properties.region == 3 then
5971 rho_der := properties.rho * (properties.cv * properties.rho + properties.pt) / (properties.rho * properties.rho * properties.pd * properties.cv + properties.T * properties.pt * properties.pt) * p_der + (-properties.rho * properties.rho * properties.pt / (properties.rho * properties.rho * properties.pd * properties.cv + properties.T * properties.pt * properties.pt)) * h_der;
5972 else
5973 rho_der := (-properties.rho * properties.rho * (properties.vp * properties.cp - properties.vt / properties.rho + properties.T * properties.vt * properties.vt) / properties.cp) * p_der + (-properties.rho * properties.rho * properties.vt / properties.cp) * h_der;
5974 end if;
5975 end rho_ph_der;
5976
5977 function T_props_ph "Temperature as function of pressure and specific enthalpy"
5978 extends Modelica.Icons.Function;
5979 input SI.Pressure p "Pressure";
5980 input SI.SpecificEnthalpy h "Specific enthalpy";
5981 input Common.IF97BaseTwoPhase properties "Auxiliary record";
5982 output SI.Temperature T "Temperature";
5983 algorithm
5984 T := properties.T;
5985 annotation(derivative(noDerivative = properties) = T_ph_der, Inline = false, LateInline = true);
5986 end T_props_ph;
5987
5988 function T_ph "Temperature as function of pressure and specific enthalpy"
5989 extends Modelica.Icons.Function;
5990 input SI.Pressure p "Pressure";
5991 input SI.SpecificEnthalpy h "Specific enthalpy";
5992 input Integer phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
5993 input Integer region = 0 "If 0, region is unknown, otherwise known and this input";
5994 output SI.Temperature T "Temperature";
5995 algorithm
5996 T := T_props_ph(p, h, waterBaseProp_ph(p, h, phase, region));
5997 annotation(Inline = true);
5998 end T_ph;
5999
6000 function T_ph_der "Derivative function of T_ph"
6001 extends Modelica.Icons.Function;
6002 input SI.Pressure p "Pressure";
6003 input SI.SpecificEnthalpy h "Specific enthalpy";
6004 input Common.IF97BaseTwoPhase properties "Auxiliary record";
6005 input Real p_der "Derivative of pressure";
6006 input Real h_der "Derivative of specific enthalpy";
6007 output Real T_der "Derivative of temperature";
6008 algorithm
6009 if properties.region == 4 then
6010 T_der := 1 / properties.dpT * p_der;
6011 elseif properties.region == 3 then
6012 T_der := ((-properties.rho * properties.pd) + properties.T * properties.pt) / (properties.rho * properties.rho * properties.pd * properties.cv + properties.T * properties.pt * properties.pt) * p_der + properties.rho * properties.rho * properties.pd / (properties.rho * properties.rho * properties.pd * properties.cv + properties.T * properties.pt * properties.pt) * h_der;
6013 else
6014 T_der := ((-1 / properties.rho) + properties.T * properties.vt) / properties.cp * p_der + 1 / properties.cp * h_der;
6015 end if;
6016 end T_ph_der;
6017
6018 function s_props_ph "Specific entropy as function of pressure and specific enthalpy"
6019 extends Modelica.Icons.Function;
6020 input SI.Pressure p "Pressure";
6021 input SI.SpecificEnthalpy h "Specific enthalpy";
6022 input Common.IF97BaseTwoPhase properties "Auxiliary record";
6023 output SI.SpecificEntropy s "Specific entropy";
6024 algorithm
6025 s := properties.s;
6026 annotation(derivative(noDerivative = properties) = s_ph_der, Inline = false, LateInline = true);
6027 end s_props_ph;
6028
6029 function s_ph "Specific entropy as function of pressure and specific enthalpy"
6030 extends Modelica.Icons.Function;
6031 input SI.Pressure p "Pressure";
6032 input SI.SpecificEnthalpy h "Specific enthalpy";
6033 input Integer phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
6034 input Integer region = 0 "If 0, region is unknown, otherwise known and this input";
6035 output SI.SpecificEntropy s "Specific entropy";
6036 algorithm
6037 s := s_props_ph(p, h, waterBaseProp_ph(p, h, phase, region));
6038 annotation(Inline = true);
6039 end s_ph;
6040
6041 function s_ph_der "Specific entropy as function of pressure and specific enthalpy"
6042 extends Modelica.Icons.Function;
6043 input SI.Pressure p "Pressure";
6044 input SI.SpecificEnthalpy h "Specific enthalpy";
6045 input Common.IF97BaseTwoPhase properties "Auxiliary record";
6046 input Real p_der "Derivative of pressure";
6047 input Real h_der "Derivative of specific enthalpy";
6048 output Real s_der "Derivative of entropy";
6049 algorithm
6050 s_der := (-1 / (properties.rho * properties.T) * p_der) + 1 / properties.T * h_der;
6051 annotation(Inline = true);
6052 end s_ph_der;
6053
6054 function cv_props_ph "Specific heat capacity at constant volume as function of pressure and specific enthalpy"
6055 extends Modelica.Icons.Function;
6056 input SI.Pressure p "Pressure";
6057 input SI.SpecificEnthalpy h "Specific enthalpy";
6058 input Common.IF97BaseTwoPhase aux "Auxiliary record";
6059 output SI.SpecificHeatCapacity cv "Specific heat capacity";
6060 algorithm
6061 cv := aux.cv;
6062 annotation(Inline = false, LateInline = true);
6063 end cv_props_ph;
6064
6065 function cv_ph "Specific heat capacity at constant volume as function of pressure and specific enthalpy"
6066 extends Modelica.Icons.Function;
6067 input SI.Pressure p "Pressure";
6068 input SI.SpecificEnthalpy h "Specific enthalpy";
6069 input Integer phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
6070 input Integer region = 0 "If 0, region is unknown, otherwise known and this input";
6071 output SI.SpecificHeatCapacity cv "Specific heat capacity";
6072 algorithm
6073 cv := cv_props_ph(p, h, waterBaseProp_ph(p, h, phase, region));
6074 annotation(Inline = true);
6075 end cv_ph;
6076
6077 function cp_props_ph "Specific heat capacity at constant pressure as function of pressure and specific enthalpy"
6078 extends Modelica.Icons.Function;
6079 input SI.Pressure p "Pressure";
6080 input SI.SpecificEnthalpy h "Specific enthalpy";
6081 input Common.IF97BaseTwoPhase aux "Auxiliary record";
6082 output SI.SpecificHeatCapacity cp "Specific heat capacity";
6083 algorithm
6084 cp := aux.cp;
6085 annotation(Inline = false, LateInline = true);
6086 end cp_props_ph;
6087
6088 function cp_ph "Specific heat capacity at constant pressure as function of pressure and specific enthalpy"
6089 extends Modelica.Icons.Function;
6090 input SI.Pressure p "Pressure";
6091 input SI.SpecificEnthalpy h "Specific enthalpy";
6092 input Integer phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
6093 input Integer region = 0 "If 0, region is unknown, otherwise known and this input";
6094 output SI.SpecificHeatCapacity cp "Specific heat capacity";
6095 algorithm
6096 cp := cp_props_ph(p, h, waterBaseProp_ph(p, h, phase, region));
6097 annotation(Inline = true);
6098 end cp_ph;
6099
6100 function beta_props_ph "Isobaric expansion coefficient as function of pressure and specific enthalpy"
6101 extends Modelica.Icons.Function;
6102 input SI.Pressure p "Pressure";
6103 input SI.SpecificEnthalpy h "Specific enthalpy";
6104 input Common.IF97BaseTwoPhase aux "Auxiliary record";
6105 output SI.RelativePressureCoefficient beta "Isobaric expansion coefficient";
6106 algorithm
6107 beta := if aux.region == 3 or aux.region == 4 then aux.pt / (aux.rho * aux.pd) else aux.vt * aux.rho;
6108 annotation(Inline = false, LateInline = true);
6109 end beta_props_ph;
6110
6111 function beta_ph "Isobaric expansion coefficient as function of pressure and specific enthalpy"
6112 extends Modelica.Icons.Function;
6113 input SI.Pressure p "Pressure";
6114 input SI.SpecificEnthalpy h "Specific enthalpy";
6115 input Integer phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
6116 input Integer region = 0 "If 0, region is unknown, otherwise known and this input";
6117 output SI.RelativePressureCoefficient beta "Isobaric expansion coefficient";
6118 algorithm
6119 beta := beta_props_ph(p, h, waterBaseProp_ph(p, h, phase, region));
6120 annotation(Inline = true);
6121 end beta_ph;
6122
6123 function kappa_props_ph "Isothermal compressibility factor as function of pressure and specific enthalpy"
6124 extends Modelica.Icons.Function;
6125 input SI.Pressure p "Pressure";
6126 input SI.SpecificEnthalpy h "Specific enthalpy";
6127 input Common.IF97BaseTwoPhase aux "Auxiliary record";
6128 output SI.IsothermalCompressibility kappa "Isothermal compressibility factor";
6129 algorithm
6130 kappa := if aux.region == 3 or aux.region == 4 then 1 / (aux.rho * aux.pd) else -aux.vp * aux.rho;
6131 annotation(Inline = false, LateInline = true);
6132 end kappa_props_ph;
6133
6134 function kappa_ph "Isothermal compressibility factor as function of pressure and specific enthalpy"
6135 extends Modelica.Icons.Function;
6136 input SI.Pressure p "Pressure";
6137 input SI.SpecificEnthalpy h "Specific enthalpy";
6138 input Integer phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
6139 input Integer region = 0 "If 0, region is unknown, otherwise known and this input";
6140 output SI.IsothermalCompressibility kappa "Isothermal compressibility factor";
6141 algorithm
6142 kappa := kappa_props_ph(p, h, waterBaseProp_ph(p, h, phase, region));
6143 annotation(Inline = true);
6144 end kappa_ph;
6145
6146 function velocityOfSound_props_ph "Speed of sound as function of pressure and specific enthalpy"
6147 extends Modelica.Icons.Function;
6148 input SI.Pressure p "Pressure";
6149 input SI.SpecificEnthalpy h "Specific enthalpy";
6150 input Common.IF97BaseTwoPhase aux "Auxiliary record";
6151 output SI.Velocity v_sound "Speed of sound";
6152 algorithm
6153 v_sound := if aux.region == 3 then sqrt(max(0, (aux.pd * aux.rho * aux.rho * aux.cv + aux.pt * aux.pt * aux.T) / (aux.rho * aux.rho * aux.cv))) else if aux.region == 4 then sqrt(max(0, 1 / (aux.rho * (aux.rho * aux.cv / aux.dpT + 1.0) / (aux.dpT * aux.T) - 1 / aux.rho * aux.rho * aux.rho / (aux.dpT * aux.T)))) else sqrt(max(0, -aux.cp / (aux.rho * aux.rho * (aux.vp * aux.cp + aux.vt * aux.vt * aux.T))));
6154 annotation(Inline = false, LateInline = true);
6155 end velocityOfSound_props_ph;
6156
6157 function velocityOfSound_ph
6158 extends Modelica.Icons.Function;
6159 input SI.Pressure p "Pressure";
6160 input SI.SpecificEnthalpy h "Specific enthalpy";
6161 input Integer phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
6162 input Integer region = 0 "If 0, region is unknown, otherwise known and this input";
6163 output SI.Velocity v_sound "Speed of sound";
6164 algorithm
6165 v_sound := velocityOfSound_props_ph(p, h, waterBaseProp_ph(p, h, phase, region));
6166 annotation(Inline = true);
6167 end velocityOfSound_ph;
6168
6169 function isentropicExponent_props_ph "Isentropic exponent as function of pressure and specific enthalpy"
6170 extends Modelica.Icons.Function;
6171 input SI.Pressure p "Pressure";
6172 input SI.SpecificEnthalpy h "Specific enthalpy";
6173 input Common.IF97BaseTwoPhase aux "Auxiliary record";
6174 output Real gamma "Isentropic exponent";
6175 algorithm
6176 gamma := if aux.region == 3 then 1 / (aux.rho * p) * ((aux.pd * aux.cv * aux.rho * aux.rho + aux.pt * aux.pt * aux.T) / aux.cv) else if aux.region == 4 then 1 / (aux.rho * p) * aux.dpT * aux.dpT * aux.T / aux.cv else -1 / (aux.rho * aux.p) * aux.cp / (aux.vp * aux.cp + aux.vt * aux.vt * aux.T);
6177 annotation(Inline = false, LateInline = true);
6178 end isentropicExponent_props_ph;
6179
6180 function isentropicExponent_ph "Isentropic exponent as function of pressure and specific enthalpy"
6181 extends Modelica.Icons.Function;
6182 input SI.Pressure p "Pressure";
6183 input SI.SpecificEnthalpy h "Specific enthalpy";
6184 input Integer phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
6185 input Integer region = 0 "If 0, region is unknown, otherwise known and this input";
6186 output Real gamma "Isentropic exponent";
6187 algorithm
6188 gamma := isentropicExponent_props_ph(p, h, waterBaseProp_ph(p, h, phase, region));
6189 annotation(Inline = false, LateInline = true);
6190 end isentropicExponent_ph;
6191
6192 function ddph_props "Density derivative by pressure"
6193 extends Modelica.Icons.Function;
6194 input SI.Pressure p "Pressure";
6195 input SI.SpecificEnthalpy h "Specific enthalpy";
6196 input Common.IF97BaseTwoPhase aux "Auxiliary record";
6197 output SI.DerDensityByPressure ddph "Density derivative by pressure";
6198 algorithm
6199 ddph := if aux.region == 3 then aux.rho * (aux.cv * aux.rho + aux.pt) / (aux.rho * aux.rho * aux.pd * aux.cv + aux.T * aux.pt * aux.pt) else if aux.region == 4 then aux.rho * (aux.rho * aux.cv / aux.dpT + 1.0) / (aux.dpT * aux.T) else -aux.rho * aux.rho * (aux.vp * aux.cp - aux.vt / aux.rho + aux.T * aux.vt * aux.vt) / aux.cp;
6200 annotation(Inline = false, LateInline = true);
6201 end ddph_props;
6202
6203 function ddph "Density derivative by pressure"
6204 extends Modelica.Icons.Function;
6205 input SI.Pressure p "Pressure";
6206 input SI.SpecificEnthalpy h "Specific enthalpy";
6207 input Integer phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
6208 input Integer region = 0 "If 0, region is unknown, otherwise known and this input";
6209 output SI.DerDensityByPressure ddph "Density derivative by pressure";
6210 algorithm
6211 ddph := ddph_props(p, h, waterBaseProp_ph(p, h, phase, region));
6212 annotation(Inline = true);
6213 end ddph;
6214
6215 function ddhp_props "Density derivative by specific enthalpy"
6216 extends Modelica.Icons.Function;
6217 input SI.Pressure p "Pressure";
6218 input SI.SpecificEnthalpy h "Specific enthalpy";
6219 input Common.IF97BaseTwoPhase aux "Auxiliary record";
6220 output SI.DerDensityByEnthalpy ddhp "Density derivative by specific enthalpy";
6221 algorithm
6222 ddhp := if aux.region == 3 then -aux.rho * aux.rho * aux.pt / (aux.rho * aux.rho * aux.pd * aux.cv + aux.T * aux.pt * aux.pt) else if aux.region == 4 then -aux.rho * aux.rho / (aux.dpT * aux.T) else -aux.rho * aux.rho * aux.vt / aux.cp;
6223 annotation(Inline = false, LateInline = true);
6224 end ddhp_props;
6225
6226 function ddhp "Density derivative by specific enthalpy"
6227 extends Modelica.Icons.Function;
6228 input SI.Pressure p "Pressure";
6229 input SI.SpecificEnthalpy h "Specific enthalpy";
6230 input Integer phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
6231 input Integer region = 0 "If 0, region is unknown, otherwise known and this input";
6232 output SI.DerDensityByEnthalpy ddhp "Density derivative by specific enthalpy";
6233 algorithm
6234 ddhp := ddhp_props(p, h, waterBaseProp_ph(p, h, phase, region));
6235 annotation(Inline = true);
6236 end ddhp;
6237
6238 function waterBaseProp_pT "Intermediate property record for water (p and T preferred states)"
6239 extends Modelica.Icons.Function;
6240 input SI.Pressure p "Pressure";
6241 input SI.Temperature T "Temperature";
6242 input Integer region = 0 "If 0, do region computation, otherwise assume the region is this input";
6243 output Common.IF97BaseTwoPhase aux "Auxiliary record";
6244 protected
6245 Common.GibbsDerivs g "Dimensionless Gibbs function and derivatives w.r.t. pi and tau";
6246 Common.HelmholtzDerivs f "Dimensionless Helmholtz function and derivatives w.r.t. delta and tau";
6247 Integer error "Error flag for inverse iterations";
6248 algorithm
6249 aux.phase := 1;
6250 aux.region := if region == 0 then BaseIF97.Regions.region_pT(p = p, T = T) else region;
6251 aux.R := BaseIF97.data.RH2O;
6252 aux.p := p;
6253 aux.T := T;
6254 aux.vt := 0.0 "initialized in case it is not needed";
6255 aux.vp := 0.0 "initialized in case it is not needed";
6256 if aux.region == 1 then
6257 g := BaseIF97.Basic.g1(p, T);
6258 aux.h := aux.R * aux.T * g.tau * g.gtau;
6259 aux.s := aux.R * (g.tau * g.gtau - g.g);
6260 aux.rho := p / (aux.R * T * g.pi * g.gpi);
6261 aux.vt := aux.R / p * (g.pi * g.gpi - g.tau * g.pi * g.gtaupi);
6262 aux.vp := aux.R * T / (p * p) * g.pi * g.pi * g.gpipi;
6263 aux.cp := -aux.R * g.tau * g.tau * g.gtautau;
6264 aux.cv := aux.R * ((-g.tau * g.tau * g.gtautau) + (g.gpi - g.tau * g.gtaupi) * (g.gpi - g.tau * g.gtaupi) / g.gpipi);
6265 aux.x := 0.0;
6266 aux.dpT := -aux.vt / aux.vp;
6267 aux.pt := -g.p / g.T * (g.gpi - g.tau * g.gtaupi) / (g.gpipi * g.pi);
6268 aux.pd := -g.R * g.T * g.gpi * g.gpi / g.gpipi;
6269 elseif aux.region == 2 then
6270 g := BaseIF97.Basic.g2(p, T);
6271 aux.h := aux.R * aux.T * g.tau * g.gtau;
6272 aux.s := aux.R * (g.tau * g.gtau - g.g);
6273 aux.rho := p / (aux.R * T * g.pi * g.gpi);
6274 aux.vt := aux.R / p * (g.pi * g.gpi - g.tau * g.pi * g.gtaupi);
6275 aux.vp := aux.R * T / (p * p) * g.pi * g.pi * g.gpipi;
6276 aux.pt := -g.p / g.T * (g.gpi - g.tau * g.gtaupi) / (g.gpipi * g.pi);
6277 aux.pd := -g.R * g.T * g.gpi * g.gpi / g.gpipi;
6278 aux.cp := -aux.R * g.tau * g.tau * g.gtautau;
6279 aux.cv := aux.R * ((-g.tau * g.tau * g.gtautau) + (g.gpi - g.tau * g.gtaupi) * (g.gpi - g.tau * g.gtaupi) / g.gpipi);
6280 aux.x := 1.0;
6281 aux.dpT := -aux.vt / aux.vp;
6282 elseif aux.region == 3 then
6283 (aux.rho, error) := BaseIF97.Inverses.dofpt3(p = p, T = T, delp = 1.0e-7);
6284 f := BaseIF97.Basic.f3(aux.rho, T);
6285 aux.h := aux.R * T * (f.tau * f.ftau + f.delta * f.fdelta);
6286 aux.s := aux.R * (f.tau * f.ftau - f.f);
6287 aux.pd := aux.R * T * f.delta * (2.0 * f.fdelta + f.delta * f.fdeltadelta);
6288 aux.pt := aux.R * aux.rho * f.delta * (f.fdelta - f.tau * f.fdeltatau);
6289 aux.cv := aux.R * (-f.tau * f.tau * f.ftautau);
6290 aux.x := 0.0;
6291 aux.dpT := aux.pt;
6292 elseif aux.region == 5 then
6293 g := BaseIF97.Basic.g5(p, T);
6294 aux.h := aux.R * aux.T * g.tau * g.gtau;
6295 aux.s := aux.R * (g.tau * g.gtau - g.g);
6296 aux.rho := p / (aux.R * T * g.pi * g.gpi);
6297 aux.vt := aux.R / p * (g.pi * g.gpi - g.tau * g.pi * g.gtaupi);
6298 aux.vp := aux.R * T / (p * p) * g.pi * g.pi * g.gpipi;
6299 aux.pt := -g.p / g.T * (g.gpi - g.tau * g.gtaupi) / (g.gpipi * g.pi);
6300 aux.pd := -g.R * g.T * g.gpi * g.gpi / g.gpipi;
6301 aux.cp := -aux.R * g.tau * g.tau * g.gtautau;
6302 aux.cv := aux.R * ((-g.tau * g.tau * g.gtautau) + (g.gpi - g.tau * g.gtaupi) * (g.gpi - g.tau * g.gtaupi) / g.gpipi);
6303 aux.x := 1.0;
6304 aux.dpT := -aux.vt / aux.vp;
6305 else
6306 assert(false, "Error in region computation of IF97 steam tables" + "(p = " + String(p) + ", T = " + String(T) + ")");
6307 end if;
6308 end waterBaseProp_pT;
6309
6310 function rho_props_pT "Density as function or pressure and temperature"
6311 extends Modelica.Icons.Function;
6312 input SI.Pressure p "Pressure";
6313 input SI.Temperature T "Temperature";
6314 input Common.IF97BaseTwoPhase aux "Auxiliary record";
6315 output SI.Density rho "Density";
6316 algorithm
6317 rho := aux.rho;
6318 annotation(derivative(noDerivative = aux) = rho_pT_der, Inline = false, LateInline = true);
6319 end rho_props_pT;
6320
6321 function rho_pT "Density as function or pressure and temperature"
6322 extends Modelica.Icons.Function;
6323 input SI.Pressure p "Pressure";
6324 input SI.Temperature T "Temperature";
6325 input Integer region = 0 "If 0, region is unknown, otherwise known and this input";
6326 output SI.Density rho "Density";
6327 algorithm
6328 rho := rho_props_pT(p, T, waterBaseProp_pT(p, T, region));
6329 annotation(Inline = true);
6330 end rho_pT;
6331
6332 function h_props_pT "Specific enthalpy as function or pressure and temperature"
6333 extends Modelica.Icons.Function;
6334 input SI.Pressure p "Pressure";
6335 input SI.Temperature T "Temperature";
6336 input Common.IF97BaseTwoPhase aux "Auxiliary record";
6337 output SI.SpecificEnthalpy h "Specific enthalpy";
6338 algorithm
6339 h := aux.h;
6340 annotation(derivative(noDerivative = aux) = h_pT_der, Inline = false, LateInline = true);
6341 end h_props_pT;
6342
6343 function h_pT "Specific enthalpy as function or pressure and temperature"
6344 extends Modelica.Icons.Function;
6345 input SI.Pressure p "Pressure";
6346 input SI.Temperature T "Temperature";
6347 input Integer region = 0 "If 0, region is unknown, otherwise known and this input";
6348 output SI.SpecificEnthalpy h "Specific enthalpy";
6349 algorithm
6350 h := h_props_pT(p, T, waterBaseProp_pT(p, T, region));
6351 annotation(Inline = true);
6352 end h_pT;
6353
6354 function h_pT_der "Derivative function of h_pT"
6355 extends Modelica.Icons.Function;
6356 input SI.Pressure p "Pressure";
6357 input SI.Temperature T "Temperature";
6358 input Common.IF97BaseTwoPhase aux "Auxiliary record";
6359 input Real p_der "Derivative of pressure";
6360 input Real T_der "Derivative of temperature";
6361 output Real h_der "Derivative of specific enthalpy";
6362 algorithm
6363 if aux.region == 3 then
6364 h_der := ((-aux.rho * aux.pd) + T * aux.pt) / (aux.rho * aux.rho * aux.pd) * p_der + (aux.rho * aux.rho * aux.pd * aux.cv + aux.T * aux.pt * aux.pt) / (aux.rho * aux.rho * aux.pd) * T_der;
6365 else
6366 h_der := (1 / aux.rho - aux.T * aux.vt) * p_der + aux.cp * T_der;
6367 end if;
6368 end h_pT_der;
6369
6370 function rho_pT_der "Derivative function of rho_pT"
6371 extends Modelica.Icons.Function;
6372 input SI.Pressure p "Pressure";
6373 input SI.Temperature T "Temperature";
6374 input Common.IF97BaseTwoPhase aux "Auxiliary record";
6375 input Real p_der "Derivative of pressure";
6376 input Real T_der "Derivative of temperature";
6377 output Real rho_der "Derivative of density";
6378 algorithm
6379 if aux.region == 3 then
6380 rho_der := 1 / aux.pd * p_der - aux.pt / aux.pd * T_der;
6381 else
6382 rho_der := (-aux.rho * aux.rho * aux.vp) * p_der + (-aux.rho * aux.rho * aux.vt) * T_der;
6383 end if;
6384 end rho_pT_der;
6385
6386 function s_props_pT "Specific entropy as function of pressure and temperature"
6387 extends Modelica.Icons.Function;
6388 input SI.Pressure p "Pressure";
6389 input SI.Temperature T "Temperature";
6390 input Common.IF97BaseTwoPhase aux "Auxiliary record";
6391 output SI.SpecificEntropy s "Specific entropy";
6392 algorithm
6393 s := aux.s;
6394 annotation(Inline = false, LateInline = true);
6395 end s_props_pT;
6396
6397 function s_pT "Temperature as function of pressure and temperature"
6398 extends Modelica.Icons.Function;
6399 input SI.Pressure p "Pressure";
6400 input SI.Temperature T "Temperature";
6401 input Integer region = 0 "If 0, region is unknown, otherwise known and this input";
6402 output SI.SpecificEntropy s "Specific entropy";
6403 algorithm
6404 s := s_props_pT(p, T, waterBaseProp_pT(p, T, region));
6405 annotation(Inline = true);
6406 end s_pT;
6407
6408 function cv_props_pT "Specific heat capacity at constant volume as function of pressure and temperature"
6409 extends Modelica.Icons.Function;
6410 input SI.Pressure p "Pressure";
6411 input SI.Temperature T "Temperature";
6412 input Common.IF97BaseTwoPhase aux "Auxiliary record";
6413 output SI.SpecificHeatCapacity cv "Specific heat capacity";
6414 algorithm
6415 cv := aux.cv;
6416 annotation(Inline = false, LateInline = true);
6417 end cv_props_pT;
6418
6419 function cv_pT "Specific heat capacity at constant volume as function of pressure and temperature"
6420 extends Modelica.Icons.Function;
6421 input SI.Pressure p "Pressure";
6422 input SI.Temperature T "Temperature";
6423 input Integer region = 0 "If 0, region is unknown, otherwise known and this input";
6424 output SI.SpecificHeatCapacity cv "Specific heat capacity";
6425 algorithm
6426 cv := cv_props_pT(p, T, waterBaseProp_pT(p, T, region));
6427 annotation(Inline = true);
6428 end cv_pT;
6429
6430 function cp_props_pT "Specific heat capacity at constant pressure as function of pressure and temperature"
6431 extends Modelica.Icons.Function;
6432 input SI.Pressure p "Pressure";
6433 input SI.Temperature T "Temperature";
6434 input Common.IF97BaseTwoPhase aux "Auxiliary record";
6435 output SI.SpecificHeatCapacity cp "Specific heat capacity";
6436 algorithm
6437 cp := if aux.region == 3 then (aux.rho * aux.rho * aux.pd * aux.cv + aux.T * aux.pt * aux.pt) / (aux.rho * aux.rho * aux.pd) else aux.cp;
6438 annotation(Inline = false, LateInline = true);
6439 end cp_props_pT;
6440
6441 function cp_pT "Specific heat capacity at constant pressure as function of pressure and temperature"
6442 extends Modelica.Icons.Function;
6443 input SI.Pressure p "Pressure";
6444 input SI.Temperature T "Temperature";
6445 input Integer region = 0 "If 0, region is unknown, otherwise known and this input";
6446 output SI.SpecificHeatCapacity cp "Specific heat capacity";
6447 algorithm
6448 cp := cp_props_pT(p, T, waterBaseProp_pT(p, T, region));
6449 annotation(Inline = true);
6450 end cp_pT;
6451
6452 function beta_props_pT "Isobaric expansion coefficient as function of pressure and temperature"
6453 extends Modelica.Icons.Function;
6454 input SI.Pressure p "Pressure";
6455 input SI.Temperature T "Temperature";
6456 input Common.IF97BaseTwoPhase aux "Auxiliary record";
6457 output SI.RelativePressureCoefficient beta "Isobaric expansion coefficient";
6458 algorithm
6459 beta := if aux.region == 3 then aux.pt / (aux.rho * aux.pd) else aux.vt * aux.rho;
6460 annotation(Inline = false, LateInline = true);
6461 end beta_props_pT;
6462
6463 function beta_pT "Isobaric expansion coefficient as function of pressure and temperature"
6464 extends Modelica.Icons.Function;
6465 input SI.Pressure p "Pressure";
6466 input SI.Temperature T "Temperature";
6467 input Integer region = 0 "If 0, region is unknown, otherwise known and this input";
6468 output SI.RelativePressureCoefficient beta "Isobaric expansion coefficient";
6469 algorithm
6470 beta := beta_props_pT(p, T, waterBaseProp_pT(p, T, region));
6471 annotation(Inline = true);
6472 end beta_pT;
6473
6474 function kappa_props_pT "Isothermal compressibility factor as function of pressure and temperature"
6475 extends Modelica.Icons.Function;
6476 input SI.Pressure p "Pressure";
6477 input SI.Temperature T "Temperature";
6478 input Common.IF97BaseTwoPhase aux "Auxiliary record";
6479 output SI.IsothermalCompressibility kappa "Isothermal compressibility factor";
6480 algorithm
6481 kappa := if aux.region == 3 then 1 / (aux.rho * aux.pd) else -aux.vp * aux.rho;
6482 annotation(Inline = false, LateInline = true);
6483 end kappa_props_pT;
6484
6485 function kappa_pT "Isothermal compressibility factor as function of pressure and temperature"
6486 extends Modelica.Icons.Function;
6487 input SI.Pressure p "Pressure";
6488 input SI.Temperature T "Temperature";
6489 input Integer region = 0 "If 0, region is unknown, otherwise known and this input";
6490 output SI.IsothermalCompressibility kappa "Isothermal compressibility factor";
6491 algorithm
6492 kappa := kappa_props_pT(p, T, waterBaseProp_pT(p, T, region));
6493 annotation(Inline = true);
6494 end kappa_pT;
6495
6496 function velocityOfSound_props_pT "Speed of sound as function of pressure and temperature"
6497 extends Modelica.Icons.Function;
6498 input SI.Pressure p "Pressure";
6499 input SI.Temperature T "Temperature";
6500 input Common.IF97BaseTwoPhase aux "Auxiliary record";
6501 output SI.Velocity v_sound "Speed of sound";
6502 algorithm
6503 v_sound := if aux.region == 3 then sqrt(max(0, (aux.pd * aux.rho * aux.rho * aux.cv + aux.pt * aux.pt * aux.T) / (aux.rho * aux.rho * aux.cv))) else sqrt(max(0, -aux.cp / (aux.rho * aux.rho * (aux.vp * aux.cp + aux.vt * aux.vt * aux.T))));
6504 annotation(Inline = false, LateInline = true);
6505 end velocityOfSound_props_pT;
6506
6507 function velocityOfSound_pT "Speed of sound as function of pressure and temperature"
6508 extends Modelica.Icons.Function;
6509 input SI.Pressure p "Pressure";
6510 input SI.Temperature T "Temperature";
6511 input Integer region = 0 "If 0, region is unknown, otherwise known and this input";
6512 output SI.Velocity v_sound "Speed of sound";
6513 algorithm
6514 v_sound := velocityOfSound_props_pT(p, T, waterBaseProp_pT(p, T, region));
6515 annotation(Inline = true);
6516 end velocityOfSound_pT;
6517
6518 function isentropicExponent_props_pT "Isentropic exponent as function of pressure and temperature"
6519 extends Modelica.Icons.Function;
6520 input SI.Pressure p "Pressure";
6521 input SI.Temperature T "Temperature";
6522 input Common.IF97BaseTwoPhase aux "Auxiliary record";
6523 output Real gamma "Isentropic exponent";
6524 algorithm
6525 gamma := if aux.region == 3 then 1 / (aux.rho * p) * ((aux.pd * aux.cv * aux.rho * aux.rho + aux.pt * aux.pt * aux.T) / aux.cv) else -1 / (aux.rho * aux.p) * aux.cp / (aux.vp * aux.cp + aux.vt * aux.vt * aux.T);
6526 annotation(Inline = false, LateInline = true);
6527 end isentropicExponent_props_pT;
6528
6529 function isentropicExponent_pT "Isentropic exponent as function of pressure and temperature"
6530 extends Modelica.Icons.Function;
6531 input SI.Pressure p "Pressure";
6532 input SI.Temperature T "Temperature";
6533 input Integer region = 0 "If 0, region is unknown, otherwise known and this input";
6534 output Real gamma "Isentropic exponent";
6535 algorithm
6536 gamma := isentropicExponent_props_pT(p, T, waterBaseProp_pT(p, T, region));
6537 annotation(Inline = false, LateInline = true);
6538 end isentropicExponent_pT;
6539
6540 function waterBaseProp_dT "Intermediate property record for water (d and T preferred states)"
6541 extends Modelica.Icons.Function;
6542 input SI.Density rho "Density";
6543 input SI.Temperature T "Temperature";
6544 input Integer phase = 0 "Phase: 2 for two-phase, 1 for one phase, 0 if unknown";
6545 input Integer region = 0 "If 0, do region computation, otherwise assume the region is this input";
6546 output Common.IF97BaseTwoPhase aux "Auxiliary record";
6547 protected
6548 SI.SpecificEnthalpy h_liq "Liquid specific enthalpy";
6549 SI.Density d_liq "Liquid density";
6550 SI.SpecificEnthalpy h_vap "Vapour specific enthalpy";
6551 SI.Density d_vap "Vapour density";
6552 Common.GibbsDerivs g "Dimensionless Gibbs function and derivatives w.r.t. pi and tau";
6553 Common.HelmholtzDerivs f "Dimensionless Helmholtz function and derivatives w.r.t. delta and tau";
6554 Modelica.Media.Common.PhaseBoundaryProperties liq "Phase boundary property record";
6555 Modelica.Media.Common.PhaseBoundaryProperties vap "Phase boundary property record";
6556 Modelica.Media.Common.GibbsDerivs gl "Dimensionless Gibbs function and derivatives w.r.t. pi and tau";
6557 Modelica.Media.Common.GibbsDerivs gv "Dimensionless Gibbs function and derivatives w.r.t. pi and tau";
6558 Modelica.Media.Common.HelmholtzDerivs fl "Dimensionless Helmholtz function and derivatives w.r.t. delta and tau";
6559 Modelica.Media.Common.HelmholtzDerivs fv "Dimensionless Helmholtz function and derivatives w.r.t. delta and tau";
6560 Integer error "Error flag for inverse iterations";
6561 algorithm
6562 aux.region := if region == 0 then if phase == 2 then 4 else BaseIF97.Regions.region_dT(d = rho, T = T, phase = phase) else region;
6563 aux.phase := if aux.region == 4 then 2 else 1;
6564 aux.R := BaseIF97.data.RH2O;
6565 aux.rho := rho;
6566 aux.T := T;
6567 aux.vt := 0.0 "initialized in case it is not needed";
6568 aux.vp := 0.0 "initialized in case it is not needed";
6569 if aux.region == 1 then
6570 (aux.p, error) := BaseIF97.Inverses.pofdt125(d = rho, T = T, reldd = 1.0e-8, region = 1);
6571 g := BaseIF97.Basic.g1(aux.p, T);
6572 aux.h := aux.R * aux.T * g.tau * g.gtau;
6573 aux.s := aux.R * (g.tau * g.gtau - g.g);
6574 aux.rho := aux.p / (aux.R * T * g.pi * g.gpi);
6575 aux.vt := aux.R / aux.p * (g.pi * g.gpi - g.tau * g.pi * g.gtaupi);
6576 aux.vp := aux.R * T / (aux.p * aux.p) * g.pi * g.pi * g.gpipi;
6577 aux.pt := -g.p / g.T * (g.gpi - g.tau * g.gtaupi) / (g.gpipi * g.pi);
6578 aux.pd := -g.R * g.T * g.gpi * g.gpi / g.gpipi;
6579 aux.cp := -aux.R * g.tau * g.tau * g.gtautau;
6580 aux.cv := aux.R * ((-g.tau * g.tau * g.gtautau) + (g.gpi - g.tau * g.gtaupi) * (g.gpi - g.tau * g.gtaupi) / g.gpipi);
6581 aux.x := 0.0;
6582 elseif aux.region == 2 then
6583 (aux.p, error) := BaseIF97.Inverses.pofdt125(d = rho, T = T, reldd = 1.0e-8, region = 2);
6584 g := BaseIF97.Basic.g2(aux.p, T);
6585 aux.h := aux.R * aux.T * g.tau * g.gtau;
6586 aux.s := aux.R * (g.tau * g.gtau - g.g);
6587 aux.rho := aux.p / (aux.R * T * g.pi * g.gpi);
6588 aux.vt := aux.R / aux.p * (g.pi * g.gpi - g.tau * g.pi * g.gtaupi);
6589 aux.vp := aux.R * T / (aux.p * aux.p) * g.pi * g.pi * g.gpipi;
6590 aux.pt := -g.p / g.T * (g.gpi - g.tau * g.gtaupi) / (g.gpipi * g.pi);
6591 aux.pd := -g.R * g.T * g.gpi * g.gpi / g.gpipi;
6592 aux.cp := -aux.R * g.tau * g.tau * g.gtautau;
6593 aux.cv := aux.R * ((-g.tau * g.tau * g.gtautau) + (g.gpi - g.tau * g.gtaupi) * (g.gpi - g.tau * g.gtaupi) / g.gpipi);
6594 aux.x := 1.0;
6595 elseif aux.region == 3 then
6596 f := BaseIF97.Basic.f3(rho, T);
6597 aux.p := aux.R * rho * T * f.delta * f.fdelta;
6598 aux.h := aux.R * T * (f.tau * f.ftau + f.delta * f.fdelta);
6599 aux.s := aux.R * (f.tau * f.ftau - f.f);
6600 aux.pd := aux.R * T * f.delta * (2.0 * f.fdelta + f.delta * f.fdeltadelta);
6601 aux.pt := aux.R * rho * f.delta * (f.fdelta - f.tau * f.fdeltatau);
6602 aux.cv := aux.R * (-f.tau * f.tau * f.ftautau);
6603 aux.cp := (aux.rho * aux.rho * aux.pd * aux.cv + aux.T * aux.pt * aux.pt) / (aux.rho * aux.rho * aux.pd);
6604 aux.x := 0.0;
6605 elseif aux.region == 4 then
6606 aux.p := BaseIF97.Basic.psat(T);
6607 d_liq := rhol_T(T);
6608 d_vap := rhov_T(T);
6609 h_liq := hl_p(aux.p);
6610 h_vap := hv_p(aux.p);
6611 aux.x := if d_vap <> d_liq then (1 / rho - 1 / d_liq) / (1 / d_vap - 1 / d_liq) else 1.0;
6612 aux.h := h_liq + aux.x * (h_vap - h_liq);
6613 if T < BaseIF97.data.TLIMIT1 then
6614 gl := BaseIF97.Basic.g1(aux.p, T);
6615 gv := BaseIF97.Basic.g2(aux.p, T);
6616 liq := Common.gibbsToBoundaryProps(gl);
6617 vap := Common.gibbsToBoundaryProps(gv);
6618 else
6619 fl := BaseIF97.Basic.f3(d_liq, T);
6620 fv := BaseIF97.Basic.f3(d_vap, T);
6621 liq := Common.helmholtzToBoundaryProps(fl);
6622 vap := Common.helmholtzToBoundaryProps(fv);
6623 end if;
6624 aux.dpT := if liq.d <> vap.d then (vap.s - liq.s) * liq.d * vap.d / (liq.d - vap.d) else BaseIF97.Basic.dptofT(aux.T);
6625 aux.s := liq.s + aux.x * (vap.s - liq.s);
6626 aux.cv := Common.cv2Phase(liq, vap, aux.x, aux.T, aux.p);
6627 aux.cp := liq.cp + aux.x * (vap.cp - liq.cp);
6628 aux.pt := liq.pt + aux.x * (vap.pt - liq.pt);
6629 aux.pd := liq.pd + aux.x * (vap.pd - liq.pd);
6630 elseif aux.region == 5 then
6631 (aux.p, error) := BaseIF97.Inverses.pofdt125(d = rho, T = T, reldd = 1.0e-8, region = 5);
6632 g := BaseIF97.Basic.g2(aux.p, T);
6633 aux.h := aux.R * aux.T * g.tau * g.gtau;
6634 aux.s := aux.R * (g.tau * g.gtau - g.g);
6635 aux.rho := aux.p / (aux.R * T * g.pi * g.gpi);
6636 aux.vt := aux.R / aux.p * (g.pi * g.gpi - g.tau * g.pi * g.gtaupi);
6637 aux.vp := aux.R * T / (aux.p * aux.p) * g.pi * g.pi * g.gpipi;
6638 aux.pt := -g.p / g.T * (g.gpi - g.tau * g.gtaupi) / (g.gpipi * g.pi);
6639 aux.pd := -g.R * g.T * g.gpi * g.gpi / g.gpipi;
6640 aux.cp := -aux.R * g.tau * g.tau * g.gtautau;
6641 aux.cv := aux.R * ((-g.tau * g.tau * g.gtautau) + (g.gpi - g.tau * g.gtaupi) * (g.gpi - g.tau * g.gtaupi) / g.gpipi);
6642 else
6643 assert(false, "Error in region computation of IF97 steam tables" + "(rho = " + String(rho) + ", T = " + String(T) + ")");
6644 end if;
6645 end waterBaseProp_dT;
6646
6647 function h_props_dT "Specific enthalpy as function of density and temperature"
6648 extends Modelica.Icons.Function;
6649 input SI.Density d "Density";
6650 input SI.Temperature T "Temperature";
6651 input Common.IF97BaseTwoPhase aux "Auxiliary record";
6652 output SI.SpecificEnthalpy h "Specific enthalpy";
6653 algorithm
6654 h := aux.h;
6655 annotation(derivative(noDerivative = aux) = h_dT_der, Inline = false, LateInline = true);
6656 end h_props_dT;
6657
6658 function h_dT "Specific enthalpy as function of density and temperature"
6659 extends Modelica.Icons.Function;
6660 input SI.Density d "Density";
6661 input SI.Temperature T "Temperature";
6662 input Integer phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
6663 input Integer region = 0 "If 0, region is unknown, otherwise known and this input";
6664 output SI.SpecificEnthalpy h "Specific enthalpy";
6665 algorithm
6666 h := h_props_dT(d, T, waterBaseProp_dT(d, T, phase, region));
6667 annotation(Inline = true);
6668 end h_dT;
6669
6670 function h_dT_der "Derivative function of h_dT"
6671 extends Modelica.Icons.Function;
6672 input SI.Density d "Density";
6673 input SI.Temperature T "Temperature";
6674 input Common.IF97BaseTwoPhase aux "Auxiliary record";
6675 input Real d_der "Derivative of density";
6676 input Real T_der "Derivative of temperature";
6677 output Real h_der "Derivative of specific enthalpy";
6678 algorithm
6679 if aux.region == 3 then
6680 h_der := ((-d * aux.pd) + T * aux.pt) / (d * d) * d_der + (aux.cv * d + aux.pt) / d * T_der;
6681 elseif aux.region == 4 then
6682 h_der := T * aux.dpT / (d * d) * d_der + (aux.cv * d + aux.dpT) / d * T_der;
6683 else
6684 h_der := (-((-1 / d) + T * aux.vt) / (d * d * aux.vp)) * d_der + (aux.vp * aux.cp - aux.vt / d + T * aux.vt * aux.vt) / aux.vp * T_der;
6685 end if;
6686 end h_dT_der;
6687
6688 function p_props_dT "Pressure as function of density and temperature"
6689 extends Modelica.Icons.Function;
6690 input SI.Density d "Density";
6691 input SI.Temperature T "Temperature";
6692 input Common.IF97BaseTwoPhase aux "Auxiliary record";
6693 output SI.Pressure p "Pressure";
6694 algorithm
6695 p := aux.p;
6696 annotation(derivative(noDerivative = aux) = p_dT_der, Inline = false, LateInline = true);
6697 end p_props_dT;
6698
6699 function p_dT "Pressure as function of density and temperature"
6700 extends Modelica.Icons.Function;
6701 input SI.Density d "Density";
6702 input SI.Temperature T "Temperature";
6703 input Integer phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
6704 input Integer region = 0 "If 0, region is unknown, otherwise known and this input";
6705 output SI.Pressure p "Pressure";
6706 algorithm
6707 p := p_props_dT(d, T, waterBaseProp_dT(d, T, phase, region));
6708 annotation(Inline = true);
6709 end p_dT;
6710
6711 function p_dT_der "Derivative function of p_dT"
6712 extends Modelica.Icons.Function;
6713 input SI.Density d "Density";
6714 input SI.Temperature T "Temperature";
6715 input Common.IF97BaseTwoPhase aux "Auxiliary record";
6716 input Real d_der "Derivative of density";
6717 input Real T_der "Derivative of temperature";
6718 output Real p_der "Derivative of pressure";
6719 algorithm
6720 if aux.region == 3 then
6721 p_der := aux.pd * d_der + aux.pt * T_der;
6722 elseif aux.region == 4 then
6723 p_der := aux.dpT * T_der;
6724 else
6725 p_der := (-1 / (d * d * aux.vp)) * d_der + (-aux.vt / aux.vp) * T_der;
6726 end if;
6727 end p_dT_der;
6728
6729 function s_props_dT "Specific entropy as function of density and temperature"
6730 extends Modelica.Icons.Function;
6731 input SI.Density d "Density";
6732 input SI.Temperature T "Temperature";
6733 input Common.IF97BaseTwoPhase aux "Auxiliary record";
6734 output SI.SpecificEntropy s "Specific entropy";
6735 algorithm
6736 s := aux.s;
6737 annotation(Inline = false, LateInline = true);
6738 end s_props_dT;
6739
6740 function s_dT "Temperature as function of density and temperature"
6741 extends Modelica.Icons.Function;
6742 input SI.Density d "Density";
6743 input SI.Temperature T "Temperature";
6744 input Integer phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
6745 input Integer region = 0 "If 0, region is unknown, otherwise known and this input";
6746 output SI.SpecificEntropy s "Specific entropy";
6747 algorithm
6748 s := s_props_dT(d, T, waterBaseProp_dT(d, T, phase, region));
6749 annotation(Inline = true);
6750 end s_dT;
6751
6752 function cv_props_dT "Specific heat capacity at constant volume as function of density and temperature"
6753 extends Modelica.Icons.Function;
6754 input SI.Density d "Density";
6755 input SI.Temperature T "Temperature";
6756 input Common.IF97BaseTwoPhase aux "Auxiliary record";
6757 output SI.SpecificHeatCapacity cv "Specific heat capacity";
6758 algorithm
6759 cv := aux.cv;
6760 annotation(Inline = false, LateInline = true);
6761 end cv_props_dT;
6762
6763 function cv_dT "Specific heat capacity at constant volume as function of density and temperature"
6764 extends Modelica.Icons.Function;
6765 input SI.Density d "Density";
6766 input SI.Temperature T "Temperature";
6767 input Integer phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
6768 input Integer region = 0 "If 0, region is unknown, otherwise known and this input";
6769 output SI.SpecificHeatCapacity cv "Specific heat capacity";
6770 algorithm
6771 cv := cv_props_dT(d, T, waterBaseProp_dT(d, T, phase, region));
6772 annotation(Inline = true);
6773 end cv_dT;
6774
6775 function cp_props_dT "Specific heat capacity at constant pressure as function of density and temperature"
6776 extends Modelica.Icons.Function;
6777 input SI.Density d "Density";
6778 input SI.Temperature T "Temperature";
6779 input Common.IF97BaseTwoPhase aux "Auxiliary record";
6780 output SI.SpecificHeatCapacity cp "Specific heat capacity";
6781 algorithm
6782 cp := aux.cp;
6783 annotation(Inline = false, LateInline = true);
6784 end cp_props_dT;
6785
6786 function cp_dT "Specific heat capacity at constant pressure as function of density and temperature"
6787 extends Modelica.Icons.Function;
6788 input SI.Density d "Density";
6789 input SI.Temperature T "Temperature";
6790 input Integer phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
6791 input Integer region = 0 "If 0, region is unknown, otherwise known and this input";
6792 output SI.SpecificHeatCapacity cp "Specific heat capacity";
6793 algorithm
6794 cp := cp_props_dT(d, T, waterBaseProp_dT(d, T, phase, region));
6795 annotation(Inline = true);
6796 end cp_dT;
6797
6798 function beta_props_dT "Isobaric expansion coefficient as function of density and temperature"
6799 extends Modelica.Icons.Function;
6800 input SI.Density d "Density";
6801 input SI.Temperature T "Temperature";
6802 input Common.IF97BaseTwoPhase aux "Auxiliary record";
6803 output SI.RelativePressureCoefficient beta "Isobaric expansion coefficient";
6804 algorithm
6805 beta := if aux.region == 3 or aux.region == 4 then aux.pt / (aux.rho * aux.pd) else aux.vt * aux.rho;
6806 annotation(Inline = false, LateInline = true);
6807 end beta_props_dT;
6808
6809 function beta_dT "Isobaric expansion coefficient as function of density and temperature"
6810 extends Modelica.Icons.Function;
6811 input SI.Density d "Density";
6812 input SI.Temperature T "Temperature";
6813 input Integer phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
6814 input Integer region = 0 "If 0, region is unknown, otherwise known and this input";
6815 output SI.RelativePressureCoefficient beta "Isobaric expansion coefficient";
6816 algorithm
6817 beta := beta_props_dT(d, T, waterBaseProp_dT(d, T, phase, region));
6818 annotation(Inline = true);
6819 end beta_dT;
6820
6821 function kappa_props_dT "Isothermal compressibility factor as function of density and temperature"
6822 extends Modelica.Icons.Function;
6823 input SI.Density d "Density";
6824 input SI.Temperature T "Temperature";
6825 input Common.IF97BaseTwoPhase aux "Auxiliary record";
6826 output SI.IsothermalCompressibility kappa "Isothermal compressibility factor";
6827 algorithm
6828 kappa := if aux.region == 3 or aux.region == 4 then 1 / (aux.rho * aux.pd) else -aux.vp * aux.rho;
6829 annotation(Inline = false, LateInline = true);
6830 end kappa_props_dT;
6831
6832 function kappa_dT "Isothermal compressibility factor as function of density and temperature"
6833 extends Modelica.Icons.Function;
6834 input SI.Density d "Density";
6835 input SI.Temperature T "Temperature";
6836 input Integer phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
6837 input Integer region = 0 "If 0, region is unknown, otherwise known and this input";
6838 output SI.IsothermalCompressibility kappa "Isothermal compressibility factor";
6839 algorithm
6840 kappa := kappa_props_dT(d, T, waterBaseProp_dT(d, T, phase, region));
6841 annotation(Inline = true);
6842 end kappa_dT;
6843
6844 function velocityOfSound_props_dT "Speed of sound as function of density and temperature"
6845 extends Modelica.Icons.Function;
6846 input SI.Density d "Density";
6847 input SI.Temperature T "Temperature";
6848 input Common.IF97BaseTwoPhase aux "Auxiliary record";
6849 output SI.Velocity v_sound "Speed of sound";
6850 algorithm
6851 v_sound := if aux.region == 3 then sqrt(max(0, (aux.pd * aux.rho * aux.rho * aux.cv + aux.pt * aux.pt * aux.T) / (aux.rho * aux.rho * aux.cv))) else if aux.region == 4 then sqrt(max(0, 1 / (aux.rho * (aux.rho * aux.cv / aux.dpT + 1.0) / (aux.dpT * aux.T) - 1 / aux.rho * aux.rho * aux.rho / (aux.dpT * aux.T)))) else sqrt(max(0, -aux.cp / (aux.rho * aux.rho * (aux.vp * aux.cp + aux.vt * aux.vt * aux.T))));
6852 annotation(Inline = false, LateInline = true);
6853 end velocityOfSound_props_dT;
6854
6855 function velocityOfSound_dT "Speed of sound as function of density and temperature"
6856 extends Modelica.Icons.Function;
6857 input SI.Density d "Density";
6858 input SI.Temperature T "Temperature";
6859 input Integer phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
6860 input Integer region = 0 "If 0, region is unknown, otherwise known and this input";
6861 output SI.Velocity v_sound "Speed of sound";
6862 algorithm
6863 v_sound := velocityOfSound_props_dT(d, T, waterBaseProp_dT(d, T, phase, region));
6864 annotation(Inline = true);
6865 end velocityOfSound_dT;
6866
6867 function isentropicExponent_props_dT "Isentropic exponent as function of density and temperature"
6868 extends Modelica.Icons.Function;
6869 input SI.Density d "Density";
6870 input SI.Temperature T "Temperature";
6871 input Common.IF97BaseTwoPhase aux "Auxiliary record";
6872 output Real gamma "Isentropic exponent";
6873 algorithm
6874 gamma := if aux.region == 3 then 1 / (aux.rho * aux.p) * ((aux.pd * aux.cv * aux.rho * aux.rho + aux.pt * aux.pt * aux.T) / aux.cv) else if aux.region == 4 then 1 / (aux.rho * aux.p) * aux.dpT * aux.dpT * aux.T / aux.cv else -1 / (aux.rho * aux.p) * aux.cp / (aux.vp * aux.cp + aux.vt * aux.vt * aux.T);
6875 annotation(Inline = false, LateInline = true);
6876 end isentropicExponent_props_dT;
6877
6878 function isentropicExponent_dT "Isentropic exponent as function of density and temperature"
6879 extends Modelica.Icons.Function;
6880 input SI.Density d "Density";
6881 input SI.Temperature T "Temperature";
6882 input Integer phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
6883 input Integer region = 0 "If 0, region is unknown, otherwise known and this input";
6884 output Real gamma "Isentropic exponent";
6885 algorithm
6886 gamma := isentropicExponent_props_dT(d, T, waterBaseProp_dT(d, T, phase, region));
6887 annotation(Inline = false, LateInline = true);
6888 end isentropicExponent_dT;
6889
6890 function hl_p = BaseIF97.Regions.hl_p "Compute the saturated liquid specific h(p)";
6891 function hv_p = BaseIF97.Regions.hv_p "Compute the saturated vapour specific h(p)";
6892 function rhol_T = BaseIF97.Regions.rhol_T "Compute the saturated liquid d(T)";
6893 function rhov_T = BaseIF97.Regions.rhov_T "Compute the saturated vapour d(T)";
6894 function dynamicViscosity = BaseIF97.Transport.visc_dTp "Compute eta(d,T) in the one-phase region";
6895 function thermalConductivity = BaseIF97.Transport.cond_dTp "Compute lambda(d,T,p) in the one-phase region";
6896 function surfaceTension = BaseIF97.Transport.surfaceTension "Compute sigma(T) at saturation T";
6897
6898 function isentropicEnthalpy "Isentropic specific enthalpy from p,s (preferably use dynamicIsentropicEnthalpy in dynamic simulation!)"
6899 extends Modelica.Icons.Function;
6900 input SI.Pressure p "Pressure";
6901 input SI.SpecificEntropy s "Specific entropy";
6902 input Integer phase = 0 "2 for two-phase, 1 for one-phase, 0 if not known";
6903 input Integer region = 0 "If 0, region is unknown, otherwise known and this input";
6904 output SI.SpecificEnthalpy h "Specific enthalpy";
6905 algorithm
6906 h := isentropicEnthalpy_props(p, s, waterBaseProp_ps(p, s, phase, region));
6907 annotation(Inline = true);
6908 end isentropicEnthalpy;
6909
6910 function isentropicEnthalpy_props
6911 extends Modelica.Icons.Function;
6912 input SI.Pressure p "Pressure";
6913 input SI.SpecificEntropy s "Specific entropy";
6914 input Common.IF97BaseTwoPhase aux "Auxiliary record";
6915 output SI.SpecificEnthalpy h "Isentropic enthalpy";
6916 algorithm
6917 h := aux.h;
6918 annotation(derivative(noDerivative = aux) = isentropicEnthalpy_der, Inline = false, LateInline = true);
6919 end isentropicEnthalpy_props;
6920
6921 function isentropicEnthalpy_der "Derivative of isentropic specific enthalpy from p,s"
6922 extends Modelica.Icons.Function;
6923 input SI.Pressure p "Pressure";
6924 input SI.SpecificEntropy s "Specific entropy";
6925 input Common.IF97BaseTwoPhase aux "Auxiliary record";
6926 input Real p_der "Pressure derivative";
6927 input Real s_der "Entropy derivative";
6928 output Real h_der "Specific enthalpy derivative";
6929 algorithm
6930 h_der := 1 / aux.rho * p_der + aux.T * s_der;
6931 annotation(Inline = true);
6932 end isentropicEnthalpy_der;
6933 end IF97_Utilities;
6934 end Water;
6935 end Media;
6936
6937 package Math "Library of mathematical functions (e.g., sin, cos) and of functions operating on vectors and matrices"
6938 import SI = Modelica.SIunits;
6939 extends Modelica.Icons.Package;
6940
6941 package Icons "Icons for Math"
6942 extends Modelica.Icons.IconsPackage;
6943
6944 partial function AxisLeft "Basic icon for mathematical function with y-axis on left side" end AxisLeft;
6945
6946 partial function AxisCenter "Basic icon for mathematical function with y-axis in the center" end AxisCenter;
6947 end Icons;
6948
6949 function asin "Inverse sine (-1 <= u <= 1)"
6950 extends Modelica.Math.Icons.AxisCenter;
6951 input Real u;
6952 output SI.Angle y;
6953 external "builtin" y = asin(u);
6954 end asin;
6955
6956 function acos "Inverse cosine (-1 <= u <= 1)"
6957 extends Modelica.Math.Icons.AxisCenter;
6958 input Real u;
6959 output SI.Angle y;
6960 external "builtin" y = acos(u);
6961 end acos;
6962
6963 function exp "Exponential, base e"
6964 extends Modelica.Math.Icons.AxisCenter;
6965 input Real u;
6966 output Real y;
6967 external "builtin" y = exp(u);
6968 end exp;
6969
6970 function log "Natural (base e) logarithm (u shall be > 0)"
6971 extends Modelica.Math.Icons.AxisLeft;
6972 input Real u;
6973 output Real y;
6974 external "builtin" y = log(u);
6975 end log;
6976 end Math;
6977
6978 package Constants "Library of mathematical constants and constants of nature (e.g., pi, eps, R, sigma)"
6979 import SI = Modelica.SIunits;
6980 import NonSI = Modelica.SIunits.Conversions.NonSIunits;
6981 extends Modelica.Icons.Package;
6982 final constant Real pi = 2 * Modelica.Math.asin(1.0);
6983 final constant Real eps = ModelicaServices.Machine.eps "Biggest number such that 1.0 + eps = 1.0";
6984 final constant Real small = ModelicaServices.Machine.small "Smallest number such that small and -small are representable on the machine";
6985 final constant Real inf = ModelicaServices.Machine.inf "Biggest Real number such that inf and -inf are representable on the machine";
6986 final constant SI.Velocity c = 299792458 "Speed of light in vacuum";
6987 final constant SI.Acceleration g_n = 9.80665 "Standard acceleration of gravity on earth";
6988 final constant SI.FaradayConstant F = 9.648533289e4 "Faraday constant, C/mol (previous value: 9.64853399e4)";
6989 final constant Real R(final unit = "J/(mol.K)") = 8.3144598 "Molar gas constant (previous value: 8.314472)";
6990 final constant Real N_A(final unit = "1/mol") = 6.022140857e23 "Avogadro constant (previous value: 6.0221415e23)";
6991 final constant Real mue_0(final unit = "N/A2") = 4 * pi * 1.e-7 "Magnetic constant";
6992 final constant NonSI.Temperature_degC T_zero = -273.15 "Absolute zero temperature";
6993 end Constants;
6994
6995 package Icons "Library of icons"
6996 extends Icons.Package;
6997
6998 partial package Package "Icon for standard packages" end Package;
6999
7000 partial package BasesPackage "Icon for packages containing base classes"
7001 extends Modelica.Icons.Package;
7002 end BasesPackage;
7003
7004 partial package VariantsPackage "Icon for package containing variants"
7005 extends Modelica.Icons.Package;
7006 end VariantsPackage;
7007
7008 partial package InterfacesPackage "Icon for packages containing interfaces"
7009 extends Modelica.Icons.Package;
7010 end InterfacesPackage;
7011
7012 partial package UtilitiesPackage "Icon for utility packages"
7013 extends Modelica.Icons.Package;
7014 end UtilitiesPackage;
7015
7016 partial package TypesPackage "Icon for packages containing type definitions"
7017 extends Modelica.Icons.Package;
7018 end TypesPackage;
7019
7020 partial package FunctionsPackage "Icon for packages containing functions"
7021 extends Modelica.Icons.Package;
7022 end FunctionsPackage;
7023
7024 partial package IconsPackage "Icon for packages containing icons"
7025 extends Modelica.Icons.Package;
7026 end IconsPackage;
7027
7028 partial package MaterialPropertiesPackage "Icon for package containing property classes"
7029 extends Modelica.Icons.Package;
7030 end MaterialPropertiesPackage;
7031
7032 partial function Function "Icon for functions" end Function;
7033
7034 partial record Record "Icon for records" end Record;
7035 end Icons;
7036
7037 package SIunits "Library of type and unit definitions based on SI units according to ISO 31-1992"
7038 extends Modelica.Icons.Package;
7039
7040 package Icons "Icons for SIunits"
7041 extends Modelica.Icons.IconsPackage;
7042
7043 partial function Conversion "Base icon for conversion functions" end Conversion;
7044 end Icons;
7045
7046 package Conversions "Conversion functions to/from non SI units and type definitions of non SI units"
7047 extends Modelica.Icons.Package;
7048
7049 package NonSIunits "Type definitions of non SI units"
7050 extends Modelica.Icons.Package;
7051 type Temperature_degC = Real(final quantity = "ThermodynamicTemperature", final unit = "degC") "Absolute temperature in degree Celsius (for relative temperature use SIunits.TemperatureDifference)" annotation(absoluteValue = true);
7052 type Pressure_bar = Real(final quantity = "Pressure", final unit = "bar") "Absolute pressure in bar";
7053 end NonSIunits;
7054
7055 function to_degC "Convert from Kelvin to degCelsius"
7056 extends Modelica.SIunits.Icons.Conversion;
7057 input Temperature Kelvin "Kelvin value";
7058 output NonSIunits.Temperature_degC Celsius "Celsius value";
7059 algorithm
7060 Celsius := Kelvin + Modelica.Constants.T_zero;
7061 annotation(Inline = true);
7062 end to_degC;
7063
7064 function from_degC "Convert from degCelsius to Kelvin"
7065 extends Modelica.SIunits.Icons.Conversion;
7066 input NonSIunits.Temperature_degC Celsius "Celsius value";
7067 output Temperature Kelvin "Kelvin value";
7068 algorithm
7069 Kelvin := Celsius - Modelica.Constants.T_zero;
7070 annotation(Inline = true);
7071 end from_degC;
7072
7073 function to_bar "Convert from Pascal to bar"
7074 extends Modelica.SIunits.Icons.Conversion;
7075 input Pressure Pa "Pascal value";
7076 output NonSIunits.Pressure_bar bar "bar value";
7077 algorithm
7078 bar := Pa / 1e5;
7079 annotation(Inline = true);
7080 end to_bar;
7081 end Conversions;
7082
7083 type Angle = Real(final quantity = "Angle", final unit = "rad", displayUnit = "deg");
7084 type Length = Real(final quantity = "Length", final unit = "m");
7085 type Position = Length;
7086 type Distance = Length(min = 0);
7087 type Height = Length(min = 0);
7088 type Area = Real(final quantity = "Area", final unit = "m2");
7089 type Volume = Real(final quantity = "Volume", final unit = "m3");
7090 type Time = Real(final quantity = "Time", final unit = "s");
7091 type Velocity = Real(final quantity = "Velocity", final unit = "m/s");
7092 type Acceleration = Real(final quantity = "Acceleration", final unit = "m/s2");
7093 type Frequency = Real(final quantity = "Frequency", final unit = "Hz");
7094 type Mass = Real(quantity = "Mass", final unit = "kg", min = 0);
7095 type Density = Real(final quantity = "Density", final unit = "kg/m3", displayUnit = "g/cm3", min = 0.0);
7096 type SpecificVolume = Real(final quantity = "SpecificVolume", final unit = "m3/kg", min = 0.0);
7097 type Pressure = Real(final quantity = "Pressure", final unit = "Pa", displayUnit = "bar");
7098 type AbsolutePressure = Pressure(min = 0.0, nominal = 1e5);
7099 type PressureDifference = Pressure;
7100 type DynamicViscosity = Real(final quantity = "DynamicViscosity", final unit = "Pa.s", min = 0);
7101 type SurfaceTension = Real(final quantity = "SurfaceTension", final unit = "N/m");
7102 type Energy = Real(final quantity = "Energy", final unit = "J");
7103 type Power = Real(final quantity = "Power", final unit = "W");
7104 type MassFlowRate = Real(quantity = "MassFlowRate", final unit = "kg/s");
7105 type MomentumFlux = Real(final quantity = "MomentumFlux", final unit = "N");
7106 type ThermodynamicTemperature = Real(final quantity = "ThermodynamicTemperature", final unit = "K", min = 0.0, start = 288.15, nominal = 300, displayUnit = "degC") "Absolute temperature (use type TemperatureDifference for relative temperatures)" annotation(absoluteValue = true);
7107 type Temp_K = ThermodynamicTemperature;
7108 type Temperature = ThermodynamicTemperature;
7109 type RelativePressureCoefficient = Real(final quantity = "RelativePressureCoefficient", final unit = "1/K");
7110 type Compressibility = Real(final quantity = "Compressibility", final unit = "1/Pa");
7111 type IsothermalCompressibility = Compressibility;
7112 type ThermalConductivity = Real(final quantity = "ThermalConductivity", final unit = "W/(m.K)");
7113 type CoefficientOfHeatTransfer = Real(final quantity = "CoefficientOfHeatTransfer", final unit = "W/(m2.K)");
7114 type ThermalConductance = Real(final quantity = "ThermalConductance", final unit = "W/K");
7115 type HeatCapacity = Real(final quantity = "HeatCapacity", final unit = "J/K");
7116 type SpecificHeatCapacity = Real(final quantity = "SpecificHeatCapacity", final unit = "J/(kg.K)");
7117 type SpecificHeatCapacityAtConstantPressure = SpecificHeatCapacity;
7118 type RatioOfSpecificHeatCapacities = Real(final quantity = "RatioOfSpecificHeatCapacities", final unit = "1");
7119 type Entropy = Real(final quantity = "Entropy", final unit = "J/K");
7120 type SpecificEntropy = Real(final quantity = "SpecificEntropy", final unit = "J/(kg.K)");
7121 type SpecificEnergy = Real(final quantity = "SpecificEnergy", final unit = "J/kg");
7122 type SpecificEnthalpy = SpecificEnergy;
7123 type DerDensityByEnthalpy = Real(final unit = "kg.s2/m5");
7124 type DerDensityByPressure = Real(final unit = "s2/m2");
7125 type DerEnthalpyByPressure = Real(final unit = "J.m.s2/kg2");
7126 type ElectricCharge = Real(final quantity = "ElectricCharge", final unit = "C");
7127 type AmountOfSubstance = Real(final quantity = "AmountOfSubstance", final unit = "mol", min = 0);
7128 type MolarMass = Real(final quantity = "MolarMass", final unit = "kg/mol", min = 0);
7129 type MolarVolume = Real(final quantity = "MolarVolume", final unit = "m3/mol", min = 0);
7130 type MassFraction = Real(final quantity = "MassFraction", final unit = "1", min = 0, max = 1);
7131 type MoleFraction = Real(final quantity = "MoleFraction", final unit = "1", min = 0, max = 1);
7132 type FaradayConstant = Real(final quantity = "FaradayConstant", final unit = "C/mol");
7133 type ReynoldsNumber = Real(final quantity = "ReynoldsNumber", final unit = "1");
7134 type NusseltNumber = Real(final quantity = "NusseltNumber", final unit = "1");
7135 type PrandtlNumber = Real(final quantity = "PrandtlNumber", final unit = "1");
7136 type PerUnit = Real(unit = "1");
7137 end SIunits;
7138 annotation(version = "3.2.3", versionBuild = 3, versionDate = "2019-01-23", dateModified = "2019-09-21 12:00:00Z");
7139end Modelica;
7140
7141model Test_total
7142 extends Test;
7143end Test_total;