Ticket #1334: TestGlycolTotal.mo

File TestGlycolTotal.mo, 67.7 KB (added by Martin Sjölund, 14 years ago)

I can't remember if I modified this test or not work around lookup issues. So I'll attach the model I used.

Line 
1package Modelica "Modelica Standard Library (Version 3.1)"
2extends Modelica.Icons.Library;
3
4 package Media "Library of media property models"
5 extends Modelica.Icons.Library;
6 import SI = Modelica.SIunits;
7
8 package Interfaces "Interfaces for media models"
9 extends Modelica.Icons.Library;
10 import SI = Modelica.SIunits;
11
12 partial package PartialMedium
13 "Partial medium properties (base package of all media packages)"
14
15 import SI = Modelica.SIunits;
16 extends Modelica.Icons.Library;
17
18 // Constants to be set in Medium
19 constant
20 Modelica.Media.Interfaces.PartialMedium.Choices.IndependentVariables
21 ThermoStates "Enumeration type for independent variables";
22 constant String mediumName = "unusablePartialMedium" "Name of the medium";
23 constant String substanceNames[:]={mediumName}
24 "Names of the mixture substances. Set substanceNames={mediumName} if only one substance.";
25 constant String extraPropertiesNames[:]=fill("", 0)
26 "Names of the additional (extra) transported properties. Set extraPropertiesNames=fill(\"\",0) if unused";
27 constant Boolean singleState
28 "= true, if u and d are not a function of pressure";
29 constant Boolean reducedX=true
30 "= true if medium contains the equation sum(X) = 1.0; set reducedX=true if only one substance (see docu for details)";
31 constant Boolean fixedX=false
32 "= true if medium contains the equation X = reference_X";
33 constant AbsolutePressure reference_p=101325
34 "Reference pressure of Medium: default 1 atmosphere";
35 constant Temperature reference_T=298.15
36 "Reference temperature of Medium: default 25 deg Celsius";
37 constant MassFraction reference_X[nX]= fill(1/nX, nX)
38 "Default mass fractions of medium";
39 constant AbsolutePressure p_default=101325
40 "Default value for pressure of medium (for initialization)";
41 constant Temperature T_default = Modelica.SIunits.Conversions.from_degC(20)
42 "Default value for temperature of medium (for initialization)";
43 constant SpecificEnthalpy h_default = specificEnthalpy_pTX(p_default, T_default, X_default)
44 "Default value for specific enthalpy of medium (for initialization)";
45 constant MassFraction X_default[nX]=reference_X
46 "Default value for mass fractions of medium (for initialization)";
47
48 final constant Integer nS=size(substanceNames, 1) "Number of substances";
49 constant Integer nX = nS "Number of mass fractions";
50 constant Integer nXi=if fixedX then 0 else if reducedX then nS - 1 else nS
51 "Number of structurally independent mass fractions (see docu for details)";
52
53 final constant Integer nC=size(extraPropertiesNames, 1)
54 "Number of extra (outside of standard mass-balance) transported properties";
55
56 replaceable record FluidConstants
57 "critical, triple, molecular and other standard data of fluid"
58 extends Modelica.Icons.Record;
59 String iupacName
60 "complete IUPAC name (or common name, if non-existent)";
61 String casRegistryNumber
62 "chemical abstracts sequencing number (if it exists)";
63 String chemicalFormula
64 "Chemical formula, (brutto, nomenclature according to Hill";
65 String structureFormula "Chemical structure formula";
66 MolarMass molarMass "molar mass";
67 end FluidConstants;
68
69 replaceable record ThermodynamicState
70 "Minimal variable set that is available as input argument to every medium function"
71 extends Modelica.Icons.Record;
72 end ThermodynamicState;
73
74 replaceable partial model BaseProperties
75 "Base properties (p, d, T, h, u, R, MM and, if applicable, X and Xi) of a medium"
76 InputAbsolutePressure p "Absolute pressure of medium";
77 InputMassFraction[nXi] Xi(start=reference_X[1:nXi])
78 "Structurally independent mass fractions";
79 InputSpecificEnthalpy h "Specific enthalpy of medium";
80 Density d "Density of medium";
81 Temperature T "Temperature of medium";
82 MassFraction[nX] X(start=reference_X)
83 "Mass fractions (= (component mass)/total mass m_i/m)";
84 SpecificInternalEnergy u "Specific internal energy of medium";
85 SpecificHeatCapacity R "Gas constant (of mixture if applicable)";
86 MolarMass MM "Molar mass (of mixture or single fluid)";
87 ThermodynamicState state
88 "thermodynamic state record for optional functions";
89 parameter Boolean preferredMediumStates=false
90 "= true if StateSelect.prefer shall be used for the independent property variables of the medium";
91 parameter Boolean standardOrderComponents = true
92 "if true, and reducedX = true, the last element of X will be computed from the other ones";
93 SI.Conversions.NonSIunits.Temperature_degC T_degC=
94 Modelica.SIunits.Conversions.to_degC(T)
95 "Temperature of medium in [degC]";
96 SI.Conversions.NonSIunits.Pressure_bar p_bar=
97 Modelica.SIunits.Conversions.to_bar(p)
98 "Absolute pressure of medium in [bar]";
99
100 // Local connector definition, used for equation balancing check
101 connector InputAbsolutePressure = input SI.AbsolutePressure
102 "Pressure as input signal connector";
103 connector InputSpecificEnthalpy = input SI.SpecificEnthalpy
104 "Specific enthalpy as input signal connector";
105 connector InputMassFraction = input SI.MassFraction
106 "Mass fraction as input signal connector";
107
108 equation
109 if standardOrderComponents then
110 Xi = X[1:nXi];
111
112 if fixedX then
113 X = reference_X;
114 end if;
115 if reducedX and not fixedX then
116 X[nX] = 1 - sum(Xi);
117 end if;
118 for i in 1:nX loop
119 assert(X[i] >= -1.e-5 and X[i] <= 1 + 1.e-5, "Mass fraction X[" +
120 String(i) + "] = " + String(X[i]) + "of substance "
121 + substanceNames[i] + "\nof medium " + mediumName + " is not in the range 0..1");
122 end for;
123
124 end if;
125
126 assert(p >= 0.0, "Pressure (= " + String(p) + " Pa) of medium \"" +
127 mediumName + "\" is negative\n(Temperature = " + String(T) + " K)");
128 end BaseProperties;
129
130 replaceable partial function setState_pTX
131 "Return thermodynamic state as function of p, T and composition X or Xi"
132 extends Modelica.Icons.Function;
133 input AbsolutePressure p "Pressure";
134 input Temperature T "Temperature";
135 input MassFraction X[:]=reference_X "Mass fractions";
136 output ThermodynamicState state "thermodynamic state record";
137 end setState_pTX;
138
139 replaceable partial function setState_phX
140 "Return thermodynamic state as function of p, h and composition X or Xi"
141 extends Modelica.Icons.Function;
142 input AbsolutePressure p "Pressure";
143 input SpecificEnthalpy h "Specific enthalpy";
144 input MassFraction X[:]=reference_X "Mass fractions";
145 output ThermodynamicState state "thermodynamic state record";
146 end setState_phX;
147
148 replaceable partial function setState_psX
149 "Return thermodynamic state as function of p, s and composition X or Xi"
150 extends Modelica.Icons.Function;
151 input AbsolutePressure p "Pressure";
152 input SpecificEntropy s "Specific entropy";
153 input MassFraction X[:]=reference_X "Mass fractions";
154 output ThermodynamicState state "thermodynamic state record";
155 end setState_psX;
156
157 replaceable partial function setState_dTX
158 "Return thermodynamic state as function of d, T and composition X or Xi"
159 extends Modelica.Icons.Function;
160 input Density d "density";
161 input Temperature T "Temperature";
162 input MassFraction X[:]=reference_X "Mass fractions";
163 output ThermodynamicState state "thermodynamic state record";
164 end setState_dTX;
165
166 replaceable partial function setSmoothState
167 "Return thermodynamic state so that it smoothly approximates: if x > 0 then state_a else state_b"
168 extends Modelica.Icons.Function;
169 input Real x "m_flow or dp";
170 input ThermodynamicState state_a "Thermodynamic state if x > 0";
171 input ThermodynamicState state_b "Thermodynamic state if x < 0";
172 input Real x_small(min=0)
173 "Smooth transition in the region -x_small < x < x_small";
174 output ThermodynamicState state
175 "Smooth thermodynamic state for all x (continuous and differentiable)";
176 end setSmoothState;
177
178 replaceable partial function dynamicViscosity "Return dynamic viscosity"
179 extends Modelica.Icons.Function;
180 input ThermodynamicState state "thermodynamic state record";
181 output DynamicViscosity eta "Dynamic viscosity";
182 end dynamicViscosity;
183
184 replaceable partial function thermalConductivity
185 "Return thermal conductivity"
186 extends Modelica.Icons.Function;
187 input ThermodynamicState state "thermodynamic state record";
188 output ThermalConductivity lambda "Thermal conductivity";
189 end thermalConductivity;
190
191 replaceable function prandtlNumber "Return the Prandtl number"
192 extends Modelica.Icons.Function;
193 input ThermodynamicState state "thermodynamic state record";
194 output PrandtlNumber Pr "Prandtl number";
195 algorithm
196 Pr := dynamicViscosity(state)*specificHeatCapacityCp(state)/thermalConductivity(
197 state);
198 end prandtlNumber;
199
200 replaceable partial function pressure "Return pressure"
201 extends Modelica.Icons.Function;
202 input ThermodynamicState state "thermodynamic state record";
203 output AbsolutePressure p "Pressure";
204 end pressure;
205
206 replaceable partial function temperature "Return temperature"
207 extends Modelica.Icons.Function;
208 input ThermodynamicState state "thermodynamic state record";
209 output Temperature T "Temperature";
210 end temperature;
211
212 replaceable partial function density "Return density"
213 extends Modelica.Icons.Function;
214 input ThermodynamicState state "thermodynamic state record";
215 output Density d "Density";
216 end density;
217
218 replaceable partial function specificEnthalpy "Return specific enthalpy"
219 extends Modelica.Icons.Function;
220 input ThermodynamicState state "thermodynamic state record";
221 output SpecificEnthalpy h "Specific enthalpy";
222 end specificEnthalpy;
223
224 replaceable partial function specificInternalEnergy
225 "Return specific internal energy"
226 extends Modelica.Icons.Function;
227 input ThermodynamicState state "thermodynamic state record";
228 output SpecificEnergy u "Specific internal energy";
229 end specificInternalEnergy;
230
231 replaceable partial function specificEntropy "Return specific entropy"
232 extends Modelica.Icons.Function;
233 input ThermodynamicState state "thermodynamic state record";
234 output SpecificEntropy s "Specific entropy";
235 end specificEntropy;
236
237 replaceable partial function specificGibbsEnergy
238 "Return specific Gibbs energy"
239 extends Modelica.Icons.Function;
240 input ThermodynamicState state "thermodynamic state record";
241 output SpecificEnergy g "Specific Gibbs energy";
242 end specificGibbsEnergy;
243
244 replaceable partial function specificHelmholtzEnergy
245 "Return specific Helmholtz energy"
246 extends Modelica.Icons.Function;
247 input ThermodynamicState state "thermodynamic state record";
248 output SpecificEnergy f "Specific Helmholtz energy";
249 end specificHelmholtzEnergy;
250
251 replaceable partial function specificHeatCapacityCp
252 "Return specific heat capacity at constant pressure"
253 extends Modelica.Icons.Function;
254 input ThermodynamicState state "thermodynamic state record";
255 output SpecificHeatCapacity cp
256 "Specific heat capacity at constant pressure";
257 end specificHeatCapacityCp;
258
259 function heatCapacity_cp = specificHeatCapacityCp
260 "alias for deprecated name";
261
262 replaceable partial function specificHeatCapacityCv
263 "Return specific heat capacity at constant volume"
264 extends Modelica.Icons.Function;
265 input ThermodynamicState state "thermodynamic state record";
266 output SpecificHeatCapacity cv
267 "Specific heat capacity at constant volume";
268 end specificHeatCapacityCv;
269
270 function heatCapacity_cv = specificHeatCapacityCv
271 "alias for deprecated name";
272
273 replaceable partial function isentropicExponent
274 "Return isentropic exponent"
275 extends Modelica.Icons.Function;
276 input ThermodynamicState state "thermodynamic state record";
277 output IsentropicExponent gamma "Isentropic exponent";
278 end isentropicExponent;
279
280 replaceable partial function isentropicEnthalpy
281 "Return isentropic enthalpy"
282 extends Modelica.Icons.Function;
283 input AbsolutePressure p_downstream "downstream pressure";
284 input ThermodynamicState refState "reference state for entropy";
285 output SpecificEnthalpy h_is "Isentropic enthalpy";
286 end isentropicEnthalpy;
287
288 replaceable partial function velocityOfSound "Return velocity of sound"
289 extends Modelica.Icons.Function;
290 input ThermodynamicState state "thermodynamic state record";
291 output VelocityOfSound a "Velocity of sound";
292 end velocityOfSound;
293
294 replaceable partial function isobaricExpansionCoefficient
295 "Return overall the isobaric expansion coefficient beta"
296 extends Modelica.Icons.Function;
297 input ThermodynamicState state "thermodynamic state record";
298 output IsobaricExpansionCoefficient beta
299 "Isobaric expansion coefficient";
300 end isobaricExpansionCoefficient;
301
302 function beta = isobaricExpansionCoefficient
303 "alias for isobaricExpansionCoefficient for user convenience";
304
305 replaceable partial function isothermalCompressibility
306 "Return overall the isothermal compressibility factor"
307 extends Modelica.Icons.Function;
308 input ThermodynamicState state "thermodynamic state record";
309 output SI.IsothermalCompressibility kappa "Isothermal compressibility";
310 end isothermalCompressibility;
311
312 function kappa = isothermalCompressibility
313 "alias of isothermalCompressibility for user convenience";
314
315 // explicit derivative functions for finite element models
316 replaceable partial function density_derp_h
317 "Return density derivative wrt pressure at const specific enthalpy"
318 extends Modelica.Icons.Function;
319 input ThermodynamicState state "thermodynamic state record";
320 output DerDensityByPressure ddph "Density derivative wrt pressure";
321 end density_derp_h;
322
323 replaceable partial function density_derh_p
324 "Return density derivative wrt specific enthalpy at constant pressure"
325 extends Modelica.Icons.Function;
326 input ThermodynamicState state "thermodynamic state record";
327 output DerDensityByEnthalpy ddhp
328 "Density derivative wrt specific enthalpy";
329 end density_derh_p;
330
331 replaceable partial function density_derp_T
332 "Return density derivative wrt pressure at const temperature"
333 extends Modelica.Icons.Function;
334 input ThermodynamicState state "thermodynamic state record";
335 output DerDensityByPressure ddpT "Density derivative wrt pressure";
336 end density_derp_T;
337
338 replaceable partial function density_derT_p
339 "Return density derivative wrt temperature at constant pressure"
340 extends Modelica.Icons.Function;
341 input ThermodynamicState state "thermodynamic state record";
342 output DerDensityByTemperature ddTp
343 "Density derivative wrt temperature";
344 end density_derT_p;
345
346 replaceable partial function density_derX
347 "Return density derivative wrt mass fraction"
348 extends Modelica.Icons.Function;
349 input ThermodynamicState state "thermodynamic state record";
350 output Density[nX] dddX "Derivative of density wrt mass fraction";
351 end density_derX;
352
353 replaceable partial function molarMass
354 "Return the molar mass of the medium"
355 extends Modelica.Icons.Function;
356 input ThermodynamicState state "thermodynamic state record";
357 output MolarMass MM "Mixture molar mass";
358 end molarMass;
359
360 replaceable function specificEnthalpy_pTX
361 "Return specific enthalpy from p, T, and X or Xi"
362 extends Modelica.Icons.Function;
363 input AbsolutePressure p "Pressure";
364 input Temperature T "Temperature";
365 input MassFraction X[:]=reference_X "Mass fractions";
366 output SpecificEnthalpy h "Specific enthalpy";
367 algorithm
368 h := specificEnthalpy(setState_pTX(p,T,X));
369 end specificEnthalpy_pTX;
370
371 replaceable function density_pTX "Return density from p, T, and X or Xi"
372 extends Modelica.Icons.Function;
373 input AbsolutePressure p "Pressure";
374 input Temperature T "Temperature";
375 input MassFraction X[:] "Mass fractions";
376 output Density d "Density";
377 algorithm
378 d := density(setState_pTX(p,T,X));
379 end density_pTX;
380
381 replaceable function temperature_phX
382 "Return temperature from p, h, and X or Xi"
383 extends Modelica.Icons.Function;
384 input AbsolutePressure p "Pressure";
385 input SpecificEnthalpy h "Specific enthalpy";
386 input MassFraction X[:]=reference_X "Mass fractions";
387 output Temperature T "Temperature";
388 algorithm
389 T := temperature(setState_phX(p,h,X));
390 end temperature_phX;
391
392 replaceable function density_phX "Return density from p, h, and X or Xi"
393 extends Modelica.Icons.Function;
394 input AbsolutePressure p "Pressure";
395 input SpecificEnthalpy h "Specific enthalpy";
396 input MassFraction X[:]=reference_X "Mass fractions";
397 output Density d "Density";
398 algorithm
399 d := density(setState_phX(p,h,X));
400 end density_phX;
401
402 replaceable function temperature_psX
403 "Return temperature from p,s, and X or Xi"
404 extends Modelica.Icons.Function;
405 input AbsolutePressure p "Pressure";
406 input SpecificEntropy s "Specific entropy";
407 input MassFraction X[:]=reference_X "Mass fractions";
408 output Temperature T "Temperature";
409 algorithm
410 T := temperature(setState_psX(p,s,X));
411 end temperature_psX;
412
413 replaceable function density_psX "Return density from p, s, and X or Xi"
414 extends Modelica.Icons.Function;
415 input AbsolutePressure p "Pressure";
416 input SpecificEntropy s "Specific entropy";
417 input MassFraction X[:]=reference_X "Mass fractions";
418 output Density d "Density";
419 algorithm
420 d := density(setState_psX(p,s,X));
421 end density_psX;
422
423 replaceable function specificEnthalpy_psX
424 "Return specific enthalpy from p, s, and X or Xi"
425 extends Modelica.Icons.Function;
426 input AbsolutePressure p "Pressure";
427 input SpecificEntropy s "Specific entropy";
428 input MassFraction X[:]=reference_X "Mass fractions";
429 output SpecificEnthalpy h "Specific enthalpy";
430 algorithm
431 h := specificEnthalpy(setState_psX(p,s,X));
432 end specificEnthalpy_psX;
433
434 type AbsolutePressure = SI.AbsolutePressure (
435 min=0,
436 max=1.e8,
437 nominal=1.e5,
438 start=1.e5)
439 "Type for absolute pressure with medium specific attributes";
440
441 type Density = SI.Density (
442 min=0,
443 max=1.e5,
444 nominal=1,
445 start=1) "Type for density with medium specific attributes";
446 type DynamicViscosity = SI.DynamicViscosity (
447 min=0,
448 max=1.e8,
449 nominal=1.e-3,
450 start=1.e-3)
451 "Type for dynamic viscosity with medium specific attributes";
452 type EnthalpyFlowRate = SI.EnthalpyFlowRate (
453 nominal=1000.0,
454 min=-1.0e8,
455 max=1.e8)
456 "Type for enthalpy flow rate with medium specific attributes";
457 type MassFlowRate = SI.MassFlowRate (
458 quantity="MassFlowRate." + mediumName,
459 min=-1.0e5,
460 max=1.e5) "Type for mass flow rate with medium specific attributes";
461 type MassFraction = Real (
462 quantity="MassFraction",
463 final unit="kg/kg",
464 min=0,
465 max=1,
466 nominal=0.1) "Type for mass fraction with medium specific attributes";
467 type MoleFraction = Real (
468 quantity="MoleFraction",
469 final unit="mol/mol",
470 min=0,
471 max=1,
472 nominal=0.1) "Type for mole fraction with medium specific attributes";
473 type MolarMass = SI.MolarMass (
474 min=0.001,
475 max=0.25,
476 nominal=0.032) "Type for molar mass with medium specific attributes";
477 type MolarVolume = SI.MolarVolume (
478 min=1e-6,
479 max=1.0e6,
480 nominal=1.0) "Type for molar volume with medium specific attributes";
481 type IsentropicExponent = SI.RatioOfSpecificHeatCapacities (
482 min=1,
483 max=500000,
484 nominal=1.2,
485 start=1.2)
486 "Type for isentropic exponent with medium specific attributes";
487 type SpecificEnergy = SI.SpecificEnergy (
488 min=-1.0e8,
489 max=1.e8,
490 nominal=1.e6)
491 "Type for specific energy with medium specific attributes";
492 type SpecificInternalEnergy = SpecificEnergy
493 "Type for specific internal energy with medium specific attributes";
494 type SpecificEnthalpy = SI.SpecificEnthalpy (
495 min=-1.0e8,
496 max=1.e8,
497 nominal=1.e6)
498 "Type for specific enthalpy with medium specific attributes";
499 type SpecificEntropy = SI.SpecificEntropy (
500 min=-1.e6,
501 max=1.e6,
502 nominal=1.e3)
503 "Type for specific entropy with medium specific attributes";
504 type SpecificHeatCapacity = SI.SpecificHeatCapacity (
505 min=0,
506 max=1.e6,
507 nominal=1.e3,
508 start=1.e3)
509 "Type for specific heat capacity with medium specific attributes";
510 type SurfaceTension = SI.SurfaceTension
511 "Type for surface tension with medium specific attributes";
512 type Temperature = SI.Temperature (
513 min=1,
514 max=1.e4,
515 nominal=300,
516 start=300) "Type for temperature with medium specific attributes";
517 type ThermalConductivity = SI.ThermalConductivity (
518 min=0,
519 max=500,
520 nominal=1,
521 start=1)
522 "Type for thermal conductivity with medium specific attributes";
523 type PrandtlNumber = SI.PrandtlNumber (
524 min=1e-3,
525 max=1e5,
526 nominal=1.0)
527 "Type for Prandtl number with medium specific attributes";
528 type VelocityOfSound = SI.Velocity (
529 min=0,
530 max=1.e5,
531 nominal=1000,
532 start=1000)
533 "Type for velocity of sound with medium specific attributes";
534 type ExtraProperty = Real (min=0.0, start=1.0)
535 "Type for unspecified, mass-specific property transported by flow";
536 type CumulativeExtraProperty = Real (min=0.0, start=1.0)
537 "Type for conserved integral of unspecified, mass specific property";
538 type ExtraPropertyFlowRate = Real(unit="kg/s")
539 "Type for flow rate of unspecified, mass-specific property";
540 type IsobaricExpansionCoefficient = Real (
541 min=1e-8,
542 max=1.0e8,
543 unit="1/K")
544 "Type for isobaric expansion coefficient with medium specific attributes";
545 type DipoleMoment = Real (
546 min=0.0,
547 max=2.0,
548 unit="debye",
549 quantity="ElectricDipoleMoment")
550 "Type for dipole moment with medium specific attributes";
551
552 type DerDensityByPressure = SI.DerDensityByPressure
553 "Type for partial derivative of density with resect to pressure with medium specific attributes";
554 type DerDensityByEnthalpy = SI.DerDensityByEnthalpy
555 "Type for partial derivative of density with resect to enthalpy with medium specific attributes";
556 type DerEnthalpyByPressure = SI.DerEnthalpyByPressure
557 "Type for partial derivative of enthalpy with resect to pressure with medium specific attributes";
558 type DerDensityByTemperature = SI.DerDensityByTemperature
559 "Type for partial derivative of density with resect to temperature with medium specific attributes";
560
561 package Choices "Types, constants to define menu choices"
562
563 type IndependentVariables = enumeration(
564 T "Temperature",
565 pT "Pressure, Temperature",
566 ph "Pressure, Specific Enthalpy",
567 phX "Pressure, Specific Enthalpy, Mass Fraction",
568 pTX "Pressure, Temperature, Mass Fractions",
569 dTX "Density, Temperature, Mass Fractions")
570 "Enumeration defining the independent variables of a medium";
571
572 type Init = enumeration(
573 NoInit "NoInit (no initialization)",
574 InitialStates "InitialStates (initialize medium states)",
575 SteadyState "SteadyState (initialize in steady state)",
576 SteadyMass
577 "SteadyMass (initialize density or pressure in steady state)")
578 "Enumeration defining initialization for fluid flow";
579
580 type ReferenceEnthalpy = enumeration(
581 ZeroAt0K
582 "The enthalpy is 0 at 0 K (default), if the enthalpy of formation is excluded",
583
584 ZeroAt25C
585 "The enthalpy is 0 at 25 degC, if the enthalpy of formation is excluded",
586
587 UserDefined
588 "The user-defined reference enthalpy is used at 293.15 K (25 degC)")
589 "Enumeration defining the reference enthalpy of a medium";
590
591 type ReferenceEntropy = enumeration(
592 ZeroAt0K "The entropy is 0 at 0 K (default)",
593 ZeroAt0C "The entropy is 0 at 0 degC",
594 UserDefined
595 "The user-defined reference entropy is used at 293.15 K (25 degC)")
596 "Enumeration defining the reference entropy of a medium";
597
598 type pd = enumeration(
599 default "Default (no boundary condition for p or d)",
600 p_known "p_known (pressure p is known)",
601 d_known "d_known (density d is known)")
602 "Enumeration defining whether p or d are known for the boundary condition";
603
604 type Th = enumeration(
605 default "Default (no boundary condition for T or h)",
606 T_known "T_known (temperature T is known)",
607 h_known "h_known (specific enthalpy h is known)")
608 "Enumeration defining whether T or h are known as boundary condition";
609
610 end Choices;
611
612 end PartialMedium;
613 end Interfaces;
614
615 package Common
616 "data structures and fundamental functions for fluid properties"
617 extends Modelica.Icons.Library;
618
619 function smoothStep
620 "Approximation of a general step, such that the characteristic is continuous and differentiable"
621 extends Modelica.Icons.Function;
622 input Real x "Abszissa value";
623 input Real y1 "Ordinate value for x > 0";
624 input Real y2 "Ordinate value for x < 0";
625 input Real x_small(min=0) = 1e-5
626 "Approximation of step for -x_small <= x <= x_small; x_small > 0 required";
627 output Real y
628 "Ordinate value to approximate y = if x > 0 then y1 else y2";
629 algorithm
630 y := smooth(1, if x > x_small then y1 else
631 if x < -x_small then y2 else
632 if abs(x_small)>0 then (x/x_small)*((x/x_small)^2 - 3)*(y2-y1)/4 + (y1+y2)/2 else (y1+y2)/2);
633
634 end smoothStep;
635
636 package OneNonLinearEquation
637 "Determine solution of a non-linear algebraic equation in one unknown without derivatives in a reliable and efficient way"
638 extends Modelica.Icons.Library;
639
640 replaceable record f_nonlinear_Data
641 "Data specific for function f_nonlinear"
642 extends Modelica.Icons.Record;
643 end f_nonlinear_Data;
644
645 replaceable partial function f_nonlinear
646 "Nonlinear algebraic equation in one unknown: y = f_nonlinear(x,p,X)"
647 extends Modelica.Icons.Function;
648 input Real x "Independent variable of function";
649 input Real p = 0.0
650 "disregaded variables (here always used for pressure)";
651 input Real[:] X = fill(0,0)
652 "disregaded variables (her always used for composition)";
653 input f_nonlinear_Data f_nonlinear_data
654 "Additional data for the function";
655 output Real y "= f_nonlinear(x)";
656 // annotation(derivative(zeroDerivative=y)); // this must hold for all replaced functions
657 end f_nonlinear;
658
659 replaceable function solve
660 "Solve f_nonlinear(x_zero)=y_zero; f_nonlinear(x_min) - y_zero and f_nonlinear(x_max)-y_zero must have different sign"
661 import Modelica.Utilities.Streams.error;
662 extends Modelica.Icons.Function;
663 input Real y_zero
664 "Determine x_zero, such that f_nonlinear(x_zero) = y_zero";
665 input Real x_min "Minimum value of x";
666 input Real x_max "Maximum value of x";
667 input Real pressure = 0.0
668 "disregaded variables (here always used for pressure)";
669 input Real[:] X = fill(0,0)
670 "disregaded variables (here always used for composition)";
671 input f_nonlinear_Data f_nonlinear_data
672 "Additional data for function f_nonlinear";
673 input Real x_tol = 100*Modelica.Constants.eps
674 "Relative tolerance of the result";
675 output Real x_zero "f_nonlinear(x_zero) = y_zero";
676 protected
677 constant Real eps = Modelica.Constants.eps "machine epsilon";
678 Real a = x_min "Current best minimum interval value";
679 Real b = x_max "Current best maximum interval value";
680 Real c "Intermediate point a <= c <= b";
681 Real d;
682 Real e "b - a";
683 Real m;
684 Real s;
685 Real p;
686 Real q;
687 Real r;
688 Real tol;
689 Real fa "= f_nonlinear(a) - y_zero";
690 Real fb "= f_nonlinear(b) - y_zero";
691 Real fc;
692 Boolean found = false;
693 algorithm
694 // Check that f(x_min) and f(x_max) have different sign
695 fa :=f_nonlinear(x_min, pressure, X, f_nonlinear_data) - y_zero;
696 fb :=f_nonlinear(x_max, pressure, X, f_nonlinear_data) - y_zero;
697 fc := fb;
698 if fa > 0.0 and fb > 0.0 or
699 fa < 0.0 and fb < 0.0 then
700 error("The arguments x_min and x_max to OneNonLinearEquation.solve(..)\n" +
701 "do not bracket the root of the single non-linear equation:\n" +
702 " x_min = " + String(x_min) + "\n" +
703 " x_max = " + String(x_max) + "\n" +
704 " y_zero = " + String(y_zero) + "\n" +
705 " fa = f(x_min) - y_zero = " + String(fa) + "\n" +
706 " fb = f(x_max) - y_zero = " + String(fb) + "\n" +
707 "fa and fb must have opposite sign which is not the case");
708 end if;
709
710 // Initialize variables
711 c :=a;
712 fc :=fa;
713 e :=b - a;
714 d :=e;
715
716 // Search loop
717 while not found loop
718 if abs(fc) < abs(fb) then
719 a :=b;
720 b :=c;
721 c :=a;
722 fa :=fb;
723 fb :=fc;
724 fc :=fa;
725 end if;
726
727 tol :=2*eps*abs(b) + x_tol;
728 m :=(c - b)/2;
729
730 if abs(m) <= tol or fb == 0.0 then
731 // root found (interval is small enough)
732 found :=true;
733 x_zero :=b;
734 else
735 // Determine if a bisection is needed
736 if abs(e) < tol or abs(fa) <= abs(fb) then
737 e :=m;
738 d :=e;
739 else
740 s :=fb/fa;
741 if a == c then
742 // linear interpolation
743 p :=2*m*s;
744 q :=1 - s;
745 else
746 // inverse quadratic interpolation
747 q :=fa/fc;
748 r :=fb/fc;
749 p :=s*(2*m*q*(q - r) - (b - a)*(r - 1));
750 q :=(q - 1)*(r - 1)*(s - 1);
751 end if;
752
753 if p > 0 then
754 q :=-q;
755 else
756 p :=-p;
757 end if;
758
759 s :=e;
760 e :=d;
761 if 2*p < 3*m*q-abs(tol*q) and p < abs(0.5*s*q) then
762 // interpolation successful
763 d :=p/q;
764 else
765 // use bi-section
766 e :=m;
767 d :=e;
768 end if;
769 end if;
770
771 // Best guess value is defined as "a"
772 a :=b;
773 fa :=fb;
774 b :=b + (if abs(d) > tol then d else if m > 0 then tol else -tol);
775 fb :=f_nonlinear(b, pressure, X, f_nonlinear_data) - y_zero;
776
777 if fb > 0 and fc > 0 or
778 fb < 0 and fc < 0 then
779 // initialize variables
780 c :=a;
781 fc :=fa;
782 e :=b - a;
783 d :=e;
784 end if;
785 end if;
786 end while;
787 end solve;
788
789 end OneNonLinearEquation;
790 end Common;
791
792 package Incompressible
793 "Medium model for T-dependent properties, defined by tables or polynomials"
794 import SI = Modelica.SIunits;
795 import Cv = Modelica.SIunits.Conversions;
796 import Modelica.Constants;
797 import Modelica.Math;
798
799 package Common "Common data structures"
800
801 record BaseProps_Tpoly "Fluid state record"
802 extends Modelica.Icons.Record;
803 SI.Temperature T "temperature";
804 SI.Pressure p "pressure";
805 // SI.Density d "density";
806 end BaseProps_Tpoly;
807 end Common;
808
809 package TableBased "Incompressible medium properties based on tables"
810 import Poly = Modelica.Media.Incompressible.TableBased.Polynomials_Temp;
811
812 extends Modelica.Media.Interfaces.PartialMedium(
813 ThermoStates = if enthalpyOfT then Choices.IndependentVariables.T else Choices.IndependentVariables.pT,
814 final reducedX=true,
815 final fixedX = true,
816 mediumName="tableMedium",
817 redeclare record ThermodynamicState=Common.BaseProps_Tpoly,
818 singleState=true);
819 // Constants to be set in actual Medium
820 constant Boolean enthalpyOfT=true
821 "true if enthalpy is approximated as a function of T only, (p-dependence neglected)";
822 constant Boolean densityOfT = size(tableDensity,1) > 1
823 "true if density is a function of temperature";
824 constant Temperature T_min "Minimum temperature valid for medium model";
825 constant Temperature T_max "Maximum temperature valid for medium model";
826 constant Temperature T0=273.15 "reference Temperature";
827 constant SpecificEnthalpy h0=0 "reference enthalpy at T0, reference_p";
828 constant SpecificEntropy s0=0 "reference entropy at T0, reference_p";
829 constant MolarMass MM_const=0.1 "Molar mass";
830 constant Integer npol=2 "degree of polynomial used for fitting";
831 constant Integer neta=size(tableViscosity,1)
832 "number of data points for viscosity";
833 constant Real[:,:] tableDensity "Table for rho(T)";
834 constant Real[:,:] tableHeatCapacity "Table for Cp(T)";
835 constant Real[:,:] tableViscosity "Table for eta(T)";
836 constant Real[:,:] tableVaporPressure "Table for pVap(T)";
837 constant Real[:,:] tableConductivity "Table for lambda(T)";
838 // constant Real[:] TK=tableViscosity[:,1]+T0*ones(neta) "Temperature for Viscosity";
839 constant Boolean TinK "true if T[K],Kelvin used for table temperatures";
840 constant Boolean hasDensity = not (size(tableDensity,1)==0)
841 "true if table tableDensity is present";
842 constant Boolean hasHeatCapacity = not (size(tableHeatCapacity,1)==0)
843 "true if table tableHeatCapacity is present";
844 constant Boolean hasViscosity = not (size(tableViscosity,1)==0)
845 "true if table tableViscosity is present";
846 constant Boolean hasVaporPressure = not (size(tableVaporPressure,1)==0)
847 "true if table tableVaporPressure is present";
848 final constant Real invTK[neta] = if size(tableViscosity,1) > 0 then
849 invertTemp(tableViscosity[:,1],TinK) else fill(0,0);
850 final constant Real poly_rho[:] = if hasDensity then
851 Poly.fitting(tableDensity[:,1],tableDensity[:,2],npol) else
852 zeros(npol+1);
853 final constant Real poly_Cp[:] = if hasHeatCapacity then
854 Poly.fitting(tableHeatCapacity[:,1],tableHeatCapacity[:,2],npol) else
855 zeros(npol+1);
856 final constant Real poly_eta[:] = if hasViscosity then
857 Poly.fitting(invTK, Math.log(tableViscosity[:,2]),npol) else
858 zeros(npol+1);
859 final constant Real poly_pVap[:] = if hasVaporPressure then
860 Poly.fitting(tableVaporPressure[:,1],tableVaporPressure[:,2],npol) else
861 zeros(npol+1);
862 final constant Real poly_lam[:] = if size(tableConductivity,1)>0 then
863 Poly.fitting(tableConductivity[:,1],tableConductivity[:,2],npol) else
864 zeros(npol+1);
865 function invertTemp "function to invert temperatures"
866 input Real[:] table "table temperature data";
867 input Boolean Tink "flag for Celsius or Kelvin";
868 output Real invTable[size(table,1)] "inverted temperatures";
869 algorithm
870 for i in 1:size(table,1) loop
871 invTable[i] := if TinK then 1/table[i] else 1/Cv.from_degC(table[i]);
872 end for;
873 end invertTemp;
874
875 redeclare model extends BaseProperties(
876 final standardOrderComponents=true,
877 p_bar=Cv.to_bar(p),
878 T_degC(start = T_start-273.15)=Cv.to_degC(T),
879 T(start = T_start,
880 stateSelect=if preferredMediumStates then StateSelect.prefer else StateSelect.default))
881 "Base properties of T dependent medium"
882 // redeclare parameter SpecificHeatCapacity R=Modelica.Constants.R,
883
884 SI.SpecificHeatCapacity cp "specific heat capacity";
885 parameter SI.Temperature T_start = 298.15 "initial temperature";
886 equation
887 assert(hasDensity,"Medium " + mediumName +
888 " can not be used without assigning tableDensity.");
889 assert(T >= T_min and T <= T_max, "Temperature T (= " + String(T) +
890 " K) is not in the allowed range (" + String(T_min) +
891 " K <= T <= " + String(T_max) + " K) required from medium model \""
892 + mediumName + "\".");
893 R = Modelica.Constants.R;
894 cp = Poly.evaluate(poly_Cp,if TinK then T else T_degC);
895 h = if enthalpyOfT then h_T(T) else h_pT(p,T,densityOfT);
896 if singleState then
897 u = h_T(T) - reference_p/d;
898 else
899 u = h - p/d;
900 end if;
901 d = Poly.evaluate(poly_rho,if TinK then T else T_degC);
902 state.T = T;
903 state.p = p;
904 MM = MM_const;
905 end BaseProperties;
906
907 redeclare function extends setState_pTX
908 "Returns state record, given pressure and temperature"
909 algorithm
910 state := ThermodynamicState(p=p,T=T);
911 end setState_pTX;
912
913 redeclare function extends setState_dTX
914 "Returns state record, given pressure and temperature"
915 algorithm
916 assert(false, "for incompressible media with d(T) only, state can not be set from density and temperature");
917 end setState_dTX;
918
919 function setState_pT "returns state record as function of p and T"
920 input AbsolutePressure p "pressure";
921 input Temperature T "temperature";
922 output ThermodynamicState state "thermodynamic state";
923 algorithm
924 state.T := T;
925 state.p := p;
926 end setState_pT;
927
928 redeclare function extends setState_phX
929 "Returns state record, given pressure and specific enthalpy"
930 algorithm
931 state :=ThermodynamicState(p=p,T=T_ph(p,h));
932 end setState_phX;
933
934 function setState_ph "returns state record as function of p and h"
935 input AbsolutePressure p "pressure";
936 input SpecificEnthalpy h "specific enthalpy";
937 output ThermodynamicState state "thermodynamic state";
938 algorithm
939 state :=ThermodynamicState(p=p,T=T_ph(p,h));
940 end setState_ph;
941
942 redeclare function extends setState_psX
943 "Returns state record, given pressure and specific entropy"
944 algorithm
945 state :=ThermodynamicState(p=p,T=T_ps(p,s));
946 end setState_psX;
947
948 function setState_ps "returns state record as function of p and s"
949 input AbsolutePressure p "pressure";
950 input SpecificEntropy s "specific entropy";
951 output ThermodynamicState state "thermodynamic state";
952 algorithm
953 state :=ThermodynamicState(p=p,T=T_ps(p,s));
954 end setState_ps;
955
956 redeclare function extends setSmoothState
957 "Return thermodynamic state so that it smoothly approximates: if x > 0 then state_a else state_b"
958 algorithm
959 state :=ThermodynamicState(p=Media.Common.smoothStep(x, state_a.p, state_b.p, x_small),
960 T=Media.Common.smoothStep(x, state_a.T, state_b.T, x_small));
961 end setSmoothState;
962
963 redeclare function extends specificHeatCapacityCv
964 "Specific heat capacity at constant volume (or pressure) of medium"
965
966 algorithm
967 assert(hasHeatCapacity,"Specific Heat Capacity, Cv, is not defined for medium "
968 + mediumName + ".");
969 cv := Poly.evaluate(poly_Cp,if TinK then state.T else state.T - 273.15);
970 end specificHeatCapacityCv;
971
972 redeclare function extends specificHeatCapacityCp
973 "Specific heat capacity at constant volume (or pressure) of medium"
974
975 algorithm
976 assert(hasHeatCapacity,"Specific Heat Capacity, Cv, is not defined for medium "
977 + mediumName + ".");
978 cp := Poly.evaluate(poly_Cp,if TinK then state.T else state.T - 273.15);
979 end specificHeatCapacityCp;
980
981 redeclare function extends dynamicViscosity
982 "Return dynamic viscosity as a function of the thermodynamic state record"
983
984 algorithm
985 assert(size(tableViscosity,1)>0,"DynamicViscosity, eta, is not defined for medium "
986 + mediumName + ".");
987 eta := Math.exp(Poly.evaluate(poly_eta, 1/state.T));
988 end dynamicViscosity;
989
990 redeclare function extends thermalConductivity
991 "Return thermal conductivity as a function of the thermodynamic state record"
992
993 algorithm
994 assert(size(tableConductivity,1)>0,"ThermalConductivity, lambda, is not defined for medium "
995 + mediumName + ".");
996 lambda := Poly.evaluate(poly_lam,if TinK then state.T else Cv.to_degC(state.T));
997 end thermalConductivity;
998
999 function s_T "compute specific entropy"
1000 input Temperature T "temperature";
1001 output SpecificEntropy s "specific entropy";
1002 algorithm
1003 s := s0 + (if TinK then
1004 Poly.integralValue(poly_Cp[1:npol],T, T0) else
1005 Poly.integralValue(poly_Cp[1:npol],Cv.to_degC(T),Cv.to_degC(T0)))
1006 + Modelica.Math.log(T/T0)*
1007 Poly.evaluate(poly_Cp,if TinK then 0 else Modelica.Constants.T_zero);
1008 end s_T;
1009
1010 redeclare function extends specificEntropy "Return specific entropy
1011 as a function of the thermodynamic state record"
1012
1013 protected
1014 Integer npol=size(poly_Cp,1)-1;
1015 algorithm
1016 assert(hasHeatCapacity,"Specific Entropy, s(T), is not defined for medium "
1017 + mediumName + ".");
1018 s := s_T(state.T);
1019 end specificEntropy;
1020
1021 function h_T "Compute specific enthalpy from temperature"
1022 import Modelica.SIunits.Conversions.to_degC;
1023 extends Modelica.Icons.Function;
1024 input SI.Temperature T "Temperature";
1025 output SI.SpecificEnthalpy h "Specific enthalpy at p, T";
1026 algorithm
1027 h :=h0 + Poly.integralValue(poly_Cp, if TinK then T else Cv.to_degC(T), if TinK then
1028 T0 else Cv.to_degC(T0));
1029 end h_T;
1030
1031 function h_T_der "Compute specific enthalpy from temperature"
1032 import Modelica.SIunits.Conversions.to_degC;
1033 extends Modelica.Icons.Function;
1034 input SI.Temperature T "Temperature";
1035 input Real dT "temperature derivative";
1036 output Real dh "derivative of Specific enthalpy at T";
1037 algorithm
1038 dh :=Poly.evaluate(poly_Cp, if TinK then T else Cv.to_degC(T))*dT;
1039 end h_T_der;
1040
1041 function h_pT "Compute specific enthalpy from pressure and temperature"
1042 import Modelica.SIunits.Conversions.to_degC;
1043 extends Modelica.Icons.Function;
1044 input SI.Pressure p "Pressure";
1045 input SI.Temperature T "Temperature";
1046 input Boolean densityOfT = false
1047 "include or neglect density derivative dependence of enthalpy";
1048 output SI.SpecificEnthalpy h "Specific enthalpy at p, T";
1049 algorithm
1050 h :=h0 + Poly.integralValue(poly_Cp, if TinK then T else Cv.to_degC(T), if TinK then
1051 T0 else Cv.to_degC(T0)) + (p - reference_p)/Poly.evaluate(poly_rho, if TinK then
1052 T else Cv.to_degC(T))
1053 *(if densityOfT then (1 + T/Poly.evaluate(poly_rho, if TinK then T else Cv.to_degC(T))
1054 *Poly.derivativeValue(poly_rho,if TinK then T else Cv.to_degC(T))) else 1.0);
1055 end h_pT;
1056
1057 function density_T "Return density as function of temperature"
1058
1059 input Temperature T "temperature";
1060 output Density d "density";
1061 algorithm
1062 d := Poly.evaluate(poly_rho,if TinK then T else Cv.to_degC(T));
1063 end density_T;
1064
1065 redeclare function extends temperature
1066 "Return temperature as a function of the thermodynamic state record"
1067 algorithm
1068 T := state.T;
1069 end temperature;
1070
1071 redeclare function extends pressure
1072 "Return pressure as a function of the thermodynamic state record"
1073 algorithm
1074 p := state.p;
1075 end pressure;
1076
1077 redeclare function extends density
1078 "Return density as a function of the thermodynamic state record"
1079 algorithm
1080 d := Poly.evaluate(poly_rho,if TinK then state.T else Cv.to_degC(state.T));
1081 end density;
1082
1083 redeclare function extends specificEnthalpy
1084 "Return specific enthalpy as a function of the thermodynamic state record"
1085 algorithm
1086 h := if enthalpyOfT then h_T(state.T) else h_pT(state.p,state.T);
1087 end specificEnthalpy;
1088
1089 redeclare function extends specificInternalEnergy
1090 "Return specific internal energy as a function of the thermodynamic state record"
1091 algorithm
1092 u := if enthalpyOfT then h_T(state.T) else h_pT(state.p,state.T)
1093 - (if singleState then reference_p/density(state) else state.p/density(state));
1094 end specificInternalEnergy;
1095
1096 function T_ph "Compute temperature from pressure and specific enthalpy"
1097 input AbsolutePressure p "pressure";
1098 input SpecificEnthalpy h "specific enthalpy";
1099 output Temperature T "temperature";
1100 protected
1101 package Internal
1102 "Solve h(T) for T with given h (use only indirectly via temperature_phX)"
1103 extends Modelica.Media.Common.OneNonLinearEquation;
1104
1105 redeclare record extends f_nonlinear_Data
1106 "superfluous record, fix later when better structure of inverse functions exists"
1107 constant Real[5] dummy = {1,2,3,4,5};
1108 end f_nonlinear_Data;
1109
1110 redeclare function extends f_nonlinear
1111 "p is smuggled in via vector"
1112 algorithm
1113 y := if singleState then h_T(x) else h_pT(p,x);
1114 end f_nonlinear;
1115
1116 // Dummy definition has to be added for current Dymola
1117 redeclare function extends solve
1118 end solve;
1119 end Internal;
1120 algorithm
1121 T := Internal.solve(h, T_min, T_max, p, {1}, Internal.f_nonlinear_Data());
1122 end T_ph;
1123
1124 function T_ps "Compute temperature from pressure and specific enthalpy"
1125 input AbsolutePressure p "pressure";
1126 input SpecificEntropy s "specific entropy";
1127 output Temperature T "temperature";
1128 protected
1129 package Internal
1130 "Solve h(T) for T with given h (use only indirectly via temperature_phX)"
1131 extends Modelica.Media.Common.OneNonLinearEquation;
1132
1133 redeclare record extends f_nonlinear_Data
1134 "superfluous record, fix later when better structure of inverse functions exists"
1135 constant Real[5] dummy = {1,2,3,4,5};
1136 end f_nonlinear_Data;
1137
1138 redeclare function extends f_nonlinear
1139 "p is smuggled in via vector"
1140 algorithm
1141 y := s_T(x);
1142 end f_nonlinear;
1143
1144 // Dummy definition has to be added for current Dymola
1145 redeclare function extends solve
1146 end solve;
1147 end Internal;
1148 algorithm
1149 T := Internal.solve(s, T_min, T_max, p, {1}, Internal.f_nonlinear_Data());
1150 end T_ps;
1151
1152 package Polynomials_Temp
1153 "Temporary Functions operating on polynomials (including polynomial fitting); only to be used in Modelica.Media.Incompressible.TableBased"
1154 extends Modelica.Icons.Library;
1155
1156 function evaluate "Evaluate polynomial at a given abszissa value"
1157 extends Modelica.Icons.Function;
1158 input Real p[:]
1159 "Polynomial coefficients (p[1] is coefficient of highest power)";
1160 input Real u "Abszissa value";
1161 output Real y "Value of polynomial at u";
1162 algorithm
1163 y := p[1];
1164 for j in 2:size(p, 1) loop
1165 y := p[j] + u*y;
1166 end for;
1167 end evaluate;
1168
1169 function derivative "Derivative of polynomial"
1170 extends Modelica.Icons.Function;
1171 input Real p1[:]
1172 "Polynomial coefficients (p1[1] is coefficient of highest power)";
1173 output Real p2[size(p1, 1) - 1] "Derivative of polynomial p1";
1174 protected
1175 Integer n=size(p1, 1);
1176 algorithm
1177 for j in 1:n-1 loop
1178 p2[j] := p1[j]*(n - j);
1179 end for;
1180 end derivative;
1181
1182 function derivativeValue
1183 "Value of derivative of polynomial at abszissa value u"
1184 extends Modelica.Icons.Function;
1185 input Real p[:]
1186 "Polynomial coefficients (p[1] is coefficient of highest power)";
1187 input Real u "Abszissa value";
1188 output Real y "Value of derivative of polynomial at u";
1189 protected
1190 Integer n=size(p, 1);
1191 algorithm
1192 y := p[1]*(n - 1);
1193 for j in 2:size(p, 1)-1 loop
1194 y := p[j]*(n - j) + u*y;
1195 end for;
1196 end derivativeValue;
1197
1198 function secondDerivativeValue
1199 "Value of 2nd derivative of polynomial at abszissa value u"
1200 extends Modelica.Icons.Function;
1201 input Real p[:]
1202 "Polynomial coefficients (p[1] is coefficient of highest power)";
1203 input Real u "Abszissa value";
1204 output Real y "Value of 2nd derivative of polynomial at u";
1205 protected
1206 Integer n=size(p, 1);
1207 algorithm
1208 y := p[1]*(n - 1)*(n - 2);
1209 for j in 2:size(p, 1)-2 loop
1210 y := p[j]*(n - j)*(n - j - 1) + u*y;
1211 end for;
1212 end secondDerivativeValue;
1213
1214 function integral "Indefinite integral of polynomial p(u)"
1215 extends Modelica.Icons.Function;
1216 input Real p1[:]
1217 "Polynomial coefficients (p1[1] is coefficient of highest power)";
1218 output Real p2[size(p1, 1) + 1]
1219 "Polynomial coefficients of indefinite integral of polynomial p1 (polynomial p2 + C is the indefinite integral of p1, where C is an arbitrary constant)";
1220 protected
1221 Integer n=size(p1, 1) + 1 "degree of output polynomial";
1222 algorithm
1223 for j in 1:n-1 loop
1224 p2[j] := p1[j]/(n-j);
1225 end for;
1226 end integral;
1227
1228 function integralValue
1229 "Integral of polynomial p(u) from u_low to u_high"
1230 extends Modelica.Icons.Function;
1231 input Real p[:] "Polynomial coefficients";
1232 input Real u_high "High integrand value";
1233 input Real u_low=0 "Low integrand value, default 0";
1234 output Real integral=0.0
1235 "Integral of polynomial p from u_low to u_high";
1236 protected
1237 Integer n=size(p, 1) "degree of integrated polynomial";
1238 Real y_low=0 "value at lower integrand";
1239 algorithm
1240 for j in 1:n loop
1241 integral := u_high*(p[j]/(n - j + 1) + integral);
1242 y_low := u_low*(p[j]/(n - j + 1) + y_low);
1243 end for;
1244 integral := integral - y_low;
1245 end integralValue;
1246
1247 function fitting
1248 "Computes the coefficients of a polynomial that fits a set of data points in a least-squares sense"
1249 extends Modelica.Icons.Function;
1250 input Real u[:] "Abscissa data values";
1251 input Real y[size(u, 1)] "Ordinate data values";
1252 input Integer n(min=1)
1253 "Order of desired polynomial that fits the data points (u,y)";
1254 output Real p[n + 1]
1255 "Polynomial coefficients of polynomial that fits the date points";
1256 protected
1257 Real V[size(u, 1), n + 1] "Vandermonde matrix";
1258 algorithm
1259 // Construct Vandermonde matrix
1260 V[:, n + 1] := ones(size(u, 1));
1261 for j in n:-1:1 loop
1262 V[:, j] := {u[i] * V[i, j + 1] for i in 1:size(u,1)};
1263 end for;
1264
1265 // Solve least squares problem
1266 p :=Modelica.Math.Matrices.leastSquares(V, y);
1267 end fitting;
1268
1269 function evaluate_der "Evaluate polynomial at a given abszissa value"
1270 extends Modelica.Icons.Function;
1271 input Real p[:]
1272 "Polynomial coefficients (p[1] is coefficient of highest power)";
1273 input Real u "Abszissa value";
1274 input Real du "Abszissa value";
1275 output Real dy "Value of polynomial at u";
1276 protected
1277 Integer n=size(p, 1);
1278 algorithm
1279 dy := p[1]*(n - 1);
1280 for j in 2:size(p, 1)-1 loop
1281 dy := p[j]*(n - j) + u*dy;
1282 end for;
1283 dy := dy*du;
1284 end evaluate_der;
1285
1286 function integralValue_der
1287 "Time derivative of integral of polynomial p(u) from u_low to u_high, assuming only u_high as time-dependent (Leibnitz rule)"
1288 extends Modelica.Icons.Function;
1289 input Real p[:] "Polynomial coefficients";
1290 input Real u_high "High integrand value";
1291 input Real u_low=0 "Low integrand value, default 0";
1292 input Real du_high "High integrand value";
1293 input Real du_low=0 "Low integrand value, default 0";
1294 output Real dintegral=0.0
1295 "Integral of polynomial p from u_low to u_high";
1296 algorithm
1297 dintegral := evaluate(p,u_high)*du_high;
1298 end integralValue_der;
1299
1300 function derivativeValue_der
1301 "time derivative of derivative of polynomial"
1302 extends Modelica.Icons.Function;
1303 input Real p[:]
1304 "Polynomial coefficients (p[1] is coefficient of highest power)";
1305 input Real u "Abszissa value";
1306 input Real du "delta of abszissa value";
1307 output Real dy
1308 "time-derivative of derivative of polynomial w.r.t. input variable at u";
1309 protected
1310 Integer n=size(p, 1);
1311 algorithm
1312 dy := secondDerivativeValue(p,u)*du;
1313 end derivativeValue_der;
1314 end Polynomials_Temp;
1315
1316 end TableBased;
1317
1318 package Examples "Examples for incompressible media"
1319
1320 package Glycol47 "1,2-Propylene glycol, 47% mixture with water"
1321 extends TableBased(
1322 mediumName="Glycol-Water 47%",
1323 T_min = Cv.from_degC(-30), T_max = Cv.from_degC(100),
1324 TinK = false, T0=273.15,
1325 tableDensity=
1326 [-30, 1066; -20, 1062; -10, 1058; 0, 1054;
1327 20, 1044; 40, 1030; 60, 1015; 80, 999; 100, 984],
1328 tableHeatCapacity=
1329 [-30, 3450; -20, 3490; -10, 3520; 0, 3560;
1330 20, 3620; 40, 3690; 60, 3760; 80, 3820; 100, 3890],
1331 tableConductivity=
1332 [-30,0.397; -20,0.396; -10,0.395; 0,0.395;
1333 20,0.394; 40,0.393; 60,0.392; 80,0.391; 100,0.390],
1334 tableViscosity=
1335 [-30, 0.160; -20, 0.0743; -10, 0.0317; 0, 0.0190;
1336 20, 0.00626; 40, 0.00299; 60, 0.00162; 80, 0.00110; 100, 0.00081],
1337 tableVaporPressure=
1338 [0, 500; 20, 1.9e3; 40, 5.3e3; 60, 16e3; 80, 37e3; 100, 80e3]);
1339 end Glycol47;
1340
1341 model TestGlycol "Test Glycol47 Medium model"
1342 extends Modelica.Icons.Example;
1343 package Medium = Glycol47 "Medium model (Glycol47)";
1344 Medium.BaseProperties medium;
1345
1346 Medium.DynamicViscosity eta=Medium.dynamicViscosity(medium.state);
1347 Medium.ThermalConductivity lambda=Medium.thermalConductivity(medium.state);
1348 Medium.SpecificEntropy s=Medium.specificEntropy(medium.state);
1349 Medium.SpecificHeatCapacity cv=Medium.specificHeatCapacityCv(medium.state);
1350 protected
1351 constant Modelica.SIunits.Time timeUnit = 1;
1352 constant Modelica.SIunits.Temperature Ta = 1;
1353 equation
1354 medium.p = 1e5;
1355 medium.T = Medium.T_min + time/timeUnit*Ta;
1356 end TestGlycol;
1357 end Examples;
1358 end Incompressible;
1359 end Media;
1360
1361 package Math
1362 "Library of mathematical functions (e.g., sin, cos) and of functions operating on vectors and matrices"
1363 import SI = Modelica.SIunits;
1364 extends Modelica.Icons.Library2;
1365
1366 package Matrices "Library of functions operating on matrices"
1367 extends Modelica.Icons.Library;
1368
1369 function leastSquares
1370 "Solve overdetermined or underdetermined real system of linear equations A*x=b in a least squares sense (A may be rank deficient)"
1371 extends Modelica.Icons.Function;
1372 input Real A[:, :] "Matrix A";
1373 input Real b[size(A, 1)] "Vector b";
1374 output Real x[size(A, 2)]
1375 "Vector x such that min|A*x-b|^2 if size(A,1) >= size(A,2) or min|x|^2 and A*x=b, if size(A,1) < size(A,2)";
1376
1377
1378 protected
1379 Integer info;
1380 Integer rank;
1381 Real xx[max(size(A,1),size(A,2))];
1382 algorithm
1383 (xx,info,rank) := LAPACK.dgelsx_vec(A, b, 100*Modelica.Constants.eps);
1384 x := xx[1:size(A,2)];
1385 assert(info == 0, "Solving an overdetermined or underdetermined linear system of
1386equations with function \"Matrices.leastSquares\" failed.");
1387 end leastSquares;
1388
1389 package LAPACK
1390 "Interface to LAPACK library (should usually not directly be used but only indirectly via Modelica.Math.Matrices)"
1391 extends Modelica.Icons.Library;
1392
1393 function dgelsx_vec
1394 "Computes the minimum-norm solution to a real linear least squares problem with rank deficient A"
1395
1396 extends Modelica.Icons.Function;
1397 input Real A[:, :];
1398 input Real b[size(A,1)];
1399 input Real rcond=0.0 "Reciprocal condition number to estimate rank";
1400 output Real x[max(nrow,ncol)]= cat(1,b,zeros(max(nrow,ncol)-nrow))
1401 "solution is in first size(A,2) rows";
1402 output Integer info;
1403 output Integer rank "Effective rank of A";
1404 protected
1405 Integer nrow=size(A,1);
1406 Integer ncol=size(A,2);
1407 Integer nx=max(nrow,ncol);
1408 Integer lwork=max( min(nrow,ncol)+3*ncol, 2*min(nrow,ncol)+1);
1409 Real work[lwork];
1410 Real Awork[nrow,ncol]=A;
1411 Integer jpvt[ncol]=zeros(ncol);
1412 external "FORTRAN 77" dgelsx(nrow, ncol, 1, Awork, nrow, x, nx, jpvt,
1413 rcond, rank, work, lwork, info);
1414
1415
1416 end dgelsx_vec;
1417 end LAPACK;
1418 end Matrices;
1419
1420 function exp "Exponential, base e"
1421 extends baseIcon2;
1422 input Real u;
1423 output Real y;
1424
1425
1426 external "C" y= exp(u);
1427 end exp;
1428
1429 function log "Natural (base e) logarithm (u shall be > 0)"
1430 extends baseIcon1;
1431 input Real u;
1432 output Real y;
1433
1434
1435 external "C" y= log(u);
1436 end log;
1437
1438 partial function baseIcon1
1439 "Basic icon for mathematical function with y-axis on left side"
1440
1441 end baseIcon1;
1442
1443 partial function baseIcon2
1444 "Basic icon for mathematical function with y-axis in middle"
1445
1446 end baseIcon2;
1447 end Math;
1448
1449 package Utilities
1450 "Library of utility functions dedicated to scripting (operating on files, streams, strings, system)"
1451 extends Modelica.Icons.Library;
1452
1453 package Streams "Read from files and write to files"
1454 extends Modelica.Icons.Library;
1455
1456 function error "Print error message and cancel all actions"
1457 extends Modelica.Icons.Function;
1458 input String string "String to be printed to error message window";
1459 external "C" ModelicaError(string);
1460 end error;
1461 end Streams;
1462 end Utilities;
1463
1464 package Constants
1465 "Library of mathematical constants and constants of nature (e.g., pi, eps, R, sigma)"
1466 import SI = Modelica.SIunits;
1467 import NonSI = Modelica.SIunits.Conversions.NonSIunits;
1468 extends Modelica.Icons.Library2;
1469
1470 final constant Real eps=1.e-15 "Biggest number such that 1.0 + eps = 1.0";
1471
1472 final constant Real R(final unit="J/(mol.K)") = 8.314472
1473 "Molar gas constant";
1474
1475 final constant NonSI.Temperature_degC T_zero=-273.15
1476 "Absolute zero temperature";
1477 end Constants;
1478
1479 package Icons "Library of icons"
1480
1481 partial package Library "Icon for library"
1482
1483 end Library;
1484
1485 partial package Library2
1486 "Icon for library where additional icon elements shall be added"
1487
1488 end Library2;
1489
1490 partial model Example "Icon for an example model"
1491
1492 equation
1493
1494 end Example;
1495
1496 partial function Function "Icon for a function"
1497
1498 end Function;
1499
1500 partial record Record "Icon for a record"
1501
1502 end Record;
1503 end Icons;
1504
1505 package SIunits
1506 "Library of type and unit definitions based on SI units according to ISO 31-1992"
1507 extends Modelica.Icons.Library2;
1508
1509 package Conversions
1510 "Conversion functions to/from non SI units and type definitions of non SI units"
1511 extends Modelica.Icons.Library2;
1512
1513 package NonSIunits "Type definitions of non SI units"
1514 extends Modelica.Icons.Library2;
1515
1516 type Temperature_degC = Real (final quantity="ThermodynamicTemperature",
1517 final unit="degC")
1518 "Absolute temperature in degree Celsius (for relative temperature use SIunits.TemperatureDifference)";
1519
1520 type Pressure_bar = Real (final quantity="Pressure", final unit="bar")
1521 "Absolute pressure in bar";
1522 end NonSIunits;
1523
1524 function to_degC "Convert from Kelvin to °Celsius"
1525 extends ConversionIcon;
1526 input Temperature Kelvin "Kelvin value";
1527 output NonSIunits.Temperature_degC Celsius "Celsius value";
1528 algorithm
1529 Celsius := Kelvin + Modelica.Constants.T_zero;
1530 end to_degC;
1531
1532 function from_degC "Convert from °Celsius to Kelvin"
1533 extends ConversionIcon;
1534 input NonSIunits.Temperature_degC Celsius "Celsius value";
1535 output Temperature Kelvin "Kelvin value";
1536 algorithm
1537 Kelvin := Celsius - Modelica.Constants.T_zero;
1538 end from_degC;
1539
1540 function to_bar "Convert from Pascal to bar"
1541 extends ConversionIcon;
1542 input Pressure Pa "Pascal value";
1543 output NonSIunits.Pressure_bar bar "bar value";
1544 algorithm
1545 bar := Pa/1e5;
1546 end to_bar;
1547
1548 partial function ConversionIcon "Base icon for conversion functions"
1549 end ConversionIcon;
1550 end Conversions;
1551
1552 type Time = Real (final quantity="Time", final unit="s");
1553
1554 type Velocity = Real (final quantity="Velocity", final unit="m/s");
1555
1556 type Density = Real (
1557 final quantity="Density",
1558 final unit="kg/m3",
1559 displayUnit="g/cm3",
1560 min=0);
1561
1562 type Pressure = Real (
1563 final quantity="Pressure",
1564 final unit="Pa",
1565 displayUnit="bar");
1566
1567 type AbsolutePressure = Pressure (min=0);
1568
1569 type DynamicViscosity = Real (
1570 final quantity="DynamicViscosity",
1571 final unit="Pa.s",
1572 min=0);
1573
1574 type SurfaceTension = Real (final quantity="SurfaceTension", final unit="N/m");
1575
1576 type EnthalpyFlowRate = Real (final quantity="EnthalpyFlowRate", final unit
1577 = "W");
1578
1579 type MassFlowRate = Real (quantity="MassFlowRate", final unit="kg/s");
1580
1581 type ThermodynamicTemperature = Real (
1582 final quantity="ThermodynamicTemperature",
1583 final unit="K",
1584 min = 0,
1585 displayUnit="degC")
1586 "Absolute temperature (use type TemperatureDifference for relative temperatures)";
1587
1588 type Temperature = ThermodynamicTemperature;
1589
1590 type Compressibility = Real (final quantity="Compressibility", final unit=
1591 "1/Pa");
1592
1593 type IsothermalCompressibility = Compressibility;
1594
1595 type ThermalConductivity = Real (final quantity="ThermalConductivity", final unit
1596 = "W/(m.K)");
1597
1598 type SpecificHeatCapacity = Real (final quantity="SpecificHeatCapacity",
1599 final unit="J/(kg.K)");
1600
1601 type RatioOfSpecificHeatCapacities = Real (final quantity=
1602 "RatioOfSpecificHeatCapacities", final unit="1");
1603
1604 type SpecificEntropy = Real (final quantity="SpecificEntropy", final unit=
1605 "J/(kg.K)");
1606
1607 type SpecificEnergy = Real (final quantity="SpecificEnergy", final unit=
1608 "J/kg");
1609
1610 type SpecificEnthalpy = SpecificEnergy;
1611
1612 type DerDensityByEnthalpy = Real (final unit="kg.s2/m5");
1613
1614 type DerDensityByPressure = Real (final unit="s2/m2");
1615
1616 type DerDensityByTemperature = Real (final unit="kg/(m3.K)");
1617
1618 type DerEnthalpyByPressure = Real (final unit="J.m.s2/kg2");
1619
1620 type MolarMass = Real (final quantity="MolarMass", final unit="kg/mol",min=0);
1621
1622 type MolarVolume = Real (final quantity="MolarVolume", final unit="m3/mol", min=0);
1623
1624 type MassFraction = Real (final quantity="MassFraction", final unit="1");
1625
1626 type PrandtlNumber = Real (final quantity="PrandtlNumber", final unit="1");
1627 end SIunits;
1628end Modelica;
1629model Modelica_Media_Incompressible_Examples_TestGlycol
1630 extends Modelica.Media.Incompressible.Examples.TestGlycol;
1631 annotation(experiment(
1632 StopTime=1,
1633 NumberOfIntervals=500,
1634 Tolerance=0.0001,
1635 Algorithm="dassl"),uses(Modelica(version="3.1")));
1636end Modelica_Media_Incompressible_Examples_TestGlycol;