Changeset 498
- Timestamp:
- 04/20/2007 01:57:03 PM (21 months ago)
- Location:
- Modelica/trunk/Modelica
- Files:
-
- 3 added
- 1 modified
-
Images/Media/Air (added)
-
Images/Media/Air/Mollier.png (added)
-
Images/Media/Air/PsycroChart.png (added)
-
Media/Air.mo (modified) (26 diffs)
Legend:
- Unmodified
- Added
- Removed
-
Modelica/trunk/Modelica/Media/Air.mo
r496 r498 3 3 package SimpleAir "Air: Simple dry air model (0..100 degC)" 4 4 5 extends Interfaces.PartialSimpleIdealGasMedium 6 (mediumName="SimpleAir",5 extends Interfaces.PartialSimpleIdealGasMedium( 6 mediumName="SimpleAir", 7 7 cp_const=1005.45, 8 8 MM_const=0.0289651159, … … 17 17 import Modelica.Constants; 18 18 19 constant FluidConstants[nS] fluidConstants =19 constant FluidConstants[nS] fluidConstants= 20 20 FluidConstants(iupacName={"simple air"}, 21 21 casRegistryNumber={"not a real substance"}, 22 22 chemicalFormula={"N2, O2"}, 23 23 structureFormula={"N2, O2"}, 24 molarMass=Modelica.Media.IdealGases.Common.SingleGasesData.N2.MM) "constant data for the fluid"; 25 24 molarMass=Modelica.Media.IdealGases.Common.SingleGasesData.N2.MM) 25 "constant data for the fluid"; 26 26 27 annotation (Documentation(info="<html> 27 <h2>Simple Ideal gas air model for low temperatures< h1>28 <h2>Simple Ideal gas air model for low temperatures</h2> 28 29 <p>This model demonstrats how to use the PartialSimpleIdealGas base class to build a 29 30 simple ideal gas model with a limited temperature validity range.</p> … … 59 60 end DryAirNasa; 60 61 61 package MoistAir "Air: Moist air model (fog but no ice, 0..150 degC)"62 package MoistAir "Air: Moist air model" 62 63 extends Interfaces.PartialCondensingGases( 63 64 mediumName="Moist air", … … 107 108 MassFraction X_steam "mass fraction of steam water"; 108 109 MassFraction X_air "mass fraction of air"; 109 MassFraction X_sat 110 MassFraction X_sat 110 111 "steam water mass fraction of saturation boundary in kg_water/kg_moistair"; 111 MassFraction x_sat 112 MassFraction x_sat 112 113 "steam water mass content of saturation boundary in kg_water/kg_dryair"; 113 114 AbsolutePressure p_steam_sat "Partial saturation pressure of steam"; … … 120 121 121 122 p_steam_sat = min(saturationPressure(T),0.999*p); 122 X_sat = min(p_steam_sat * k_mair/max(100*Constants.eps, p - p_steam_sat)*(1 - Xi[Water]), 1.0) 123 "Water content at saturation with respect to actual water content";124 X_liquid = max(Xi[Water] - X_sat, 0.0); 123 X_sat = min(p_steam_sat * k_mair/max(100*Constants.eps, p - p_steam_sat)*(1 - Xi[Water]), 1.0) 124 "Water content at saturation with respect to actual water content"; 125 X_liquid = max(Xi[Water] - X_sat, 0.0); 125 126 X_steam = Xi[Water]-X_liquid; 126 127 X_air = 1-Xi[Water]; … … 138 139 state.X = X; 139 140 140 // th is x_steam is water load / dry air!!!!!!!!!!!141 // these x are per unit mass of DRY air! 141 142 x_sat = k_mair*p_steam_sat/max(100*Constants.eps,p - p_steam_sat); 142 143 x_water = Xi[Water]/max(X_air,100*Constants.eps); 143 144 phi = p/p_steam_sat*Xi[Water]/(Xi[Water] + k_mair*X_air); 144 145 end BaseProperties; 145 146 function Xsaturation "steam water mass fraction of saturation boundary in kg_water/kg_moistair" 146 147 function Xsaturation 148 "Steam water mass fraction of saturation boundary in kg_water/kg_moistair" 147 149 input ThermodynamicState state "shermodynamic state"; 148 150 output MassFraction X_sat "steam mass fraction of sat. boundary"; 149 protected 150 algorithm 151 algorithm 151 152 X_sat := k_mair/(state.p/min(saturationPressure(state.T),0.999*state.p) - 1 + k_mair); 152 153 end Xsaturation; 153 154 154 function massFraction_pTphi "compute the steam mass fraction from relative humidity and T" 155 function massFraction_pTphi 156 "Compute the steam mass fraction from relative humidity and T" 155 157 input AbsolutePressure p "Pressure"; 156 158 input Temperature T "Temperature"; 157 159 input Real phi "relative humidity (0 ... 1.0)"; 158 160 output MassFraction X_steam "steam Mass fractions"; 159 protected 161 protected 160 162 constant Real k = 0.621964713077499 "ratio of molar masses"; 161 163 AbsolutePressure psat = saturationPressure(T) "saturation pressure"; 162 algorithm 164 algorithm 163 165 X_steam := phi*k/(k*phi+p/psat-phi); 164 166 end massFraction_pTphi; 165 167 166 redeclare function setState_pTX "Return thermodynamic state as function of p, T and composition X" 168 redeclare function setState_pTX 169 "Return thermodynamic state as function of p, T and composition X" 167 170 extends Modelica.Icons.Function; 168 171 input AbsolutePressure p "Pressure"; … … 170 173 input MassFraction X[:]=reference_X "Mass fractions"; 171 174 output ThermodynamicState state; 172 algorithm 173 state := if size(X,1) == nX then ThermodynamicState(p=p,T=T, X=X) 174 elseThermodynamicState(p=p,T=T, X=cat(1,X,{1-sum(X)}));175 algorithm 176 state := if size(X,1) == nX then ThermodynamicState(p=p,T=T, X=X) else 177 ThermodynamicState(p=p,T=T, X=cat(1,X,{1-sum(X)})); 175 178 end setState_pTX; 176 179 177 redeclare function setState_phX "Return thermodynamic state as function of p, h and composition X" 180 redeclare function setState_phX 181 "Return thermodynamic state as function of p, h and composition X" 178 182 extends Modelica.Icons.Function; 179 183 input AbsolutePressure p "Pressure"; … … 181 185 input MassFraction X[:]=reference_X "Mass fractions"; 182 186 output ThermodynamicState state; 183 algorithm 184 state := if size(X,1) == nX then ThermodynamicState(p=p,T=T_phX(p,h,X),X=X) 185 elseThermodynamicState(p=p,T=T_phX(p,h,X), X=cat(1,X,{1-sum(X)}));187 algorithm 188 state := if size(X,1) == nX then ThermodynamicState(p=p,T=T_phX(p,h,X),X=X) else 189 ThermodynamicState(p=p,T=T_phX(p,h,X), X=cat(1,X,{1-sum(X)})); 186 190 end setState_phX; 187 /*191 /* 188 192 redeclare function setState_psX "Return thermodynamic state as function of p, s and composition X" 189 193 extends Modelica.Icons.Function; … … 196 200 else ThermodynamicState(p=p,T=T_psX(p,s,X), X=cat(1,X,{1-sum(X)})); 197 201 end setState_psX; 198 */ 199 redeclare function setState_dTX "Return thermodynamic state as function of d, T and composition X" 202 */ 203 redeclare function setState_dTX 204 "Return thermodynamic state as function of d, T and composition X" 200 205 extends Modelica.Icons.Function; 201 206 input Density d "density"; … … 203 208 input MassFraction X[:]=reference_X "Mass fractions"; 204 209 output ThermodynamicState state; 205 algorithm 206 state := if size(X,1) == nX then ThermodynamicState(p=d*({steam.R,dryair.R}*X)*T,T=T,X=X) 207 elseThermodynamicState(p=d*({steam.R,dryair.R}*cat(1,X,{1-sum(X)}))*T,T=T, X=cat(1,X,{1-sum(X)}));210 algorithm 211 state := if size(X,1) == nX then ThermodynamicState(p=d*({steam.R,dryair.R}*X)*T,T=T,X=X) else 212 ThermodynamicState(p=d*({steam.R,dryair.R}*cat(1,X,{1-sum(X)}))*T,T=T, X=cat(1,X,{1-sum(X)})); 208 213 end setState_dTX; 209 210 redeclare function extends gasConstant "gas constnat: computation neglects liquid fraction" 214 215 redeclare function extends gasConstant 216 "Gas constnat: computation neglects liquid fraction" 211 217 algorithm 212 218 R := dryair.R*(1-state.X[Water]) + steam.R*state.X[Water]; … … 214 220 215 221 function saturationPressureLiquid 216 " saturation curve valid for 273.16 <= T <= 373.16. Outside of these limits a (less accurate) result is returned"222 "Saturation curve valid for 273.16 <= T <= 373.16. Outside of these limits a (less accurate) result is returned" 217 223 extends Modelica.Icons.Function; 218 224 input SI.Temperature Tsat "saturation temperature"; … … 224 230 225 231 function sublimationPressureIce 226 " saturation curve valid for 223.16 <= T <= 273.16. Outside of these limits a (less accurate) result is returned"232 "Saturation curve valid for 223.16 <= T <= 273.16. Outside of these limits a (less accurate) result is returned" 227 233 extends Modelica.Icons.Function; 228 234 input SI.Temperature Tsat "sublimation temperature"; … … 234 240 235 241 redeclare function extends saturationPressure 236 " saturation curve valid for 223.16 <= T <= 373.16 (and slightly outside with less accuracy)"242 "Saturation curve valid for 223.16 <= T <= 373.16 (and slightly outside with less accuracy)" 237 243 238 244 annotation(Inline=false,smoothOrder=5); … … 241 247 end saturationPressure; 242 248 249 function saturationTemperature 250 "Computes saturation temperature from (partial) pressure via numerical inversion of the function 'saturationPressure'" 251 input SI.Pressure p "pressure"; 252 input SI.Temperature T_min=200 "lower boundary of solution"; 253 input SI.Temperature T_max=400 "upper boundary of solution"; 254 output SI.Temperature T "temperature"; 255 256 protected 257 package Internal 258 extends Modelica.Media.Common.OneNonLinearEquation; 259 260 redeclare record extends f_nonlinear_Data 261 // Define data to be passed to user function 262 end f_nonlinear_Data; 263 264 redeclare function extends f_nonlinear 265 algorithm 266 y:=saturationPressure(x); 267 // Compute the non-linear equation: y = f(x, Data) 268 end f_nonlinear; 269 270 // Dummy definition 271 redeclare function extends solve 272 end solve; 273 end Internal; 274 algorithm 275 T:=Internal.solve(p, T_min, T_max); 276 end saturationTemperature; 277 243 278 redeclare function extends enthalpyOfVaporization 244 "enthalpy of vaporization of water" 245 algorithm 246 r0 := 1e3*(2501.0145 - (T - 273.15)*(2.3853 + (T - 273.15)*(0.002969 - (T 247 - 273.15)*(7.5293e-5 + (T - 273.15)*4.6084e-7)))); 279 "Enthalpy of vaporization of water, 0 - 130 degC" 280 algorithm 281 /*r0 := 1e3*(2501.0145 - (T - 273.15)*(2.3853 + (T - 273.15)*(0.002969 - (T 282 - 273.15)*(7.5293e-5 + (T - 273.15)*4.6084e-7))));*/ 283 //katrin: replaced by linear correlation, simpler and more accurate in the entire region 284 //source VDI-Waermeatlas, linear inter- and extrapolation between values for 0.01°C and 40°C. 285 r0:=(2405900-2500500)/(40-0)*(T-273.16)+2500500; 248 286 end enthalpyOfVaporization; 249 287 250 288 function HeatCapacityOfWater 251 " specific heat capacity of water (liquid only)"289 "Specific heat capacity of water (liquid only)" 252 290 extends Modelica.Icons.Function; 253 291 input Temperature T; … … 261 299 262 300 redeclare function extends enthalpyOfLiquid 301 "Computes enthalpy of liquid water from temperature (use enthalpyOfWater instead" 263 302 264 303 annotation(Inline=false,smoothOrder=5); … … 269 308 270 309 redeclare function extends enthalpyOfGas 310 "Computes specific enthalpy of gas (air and steam) from temperature and composition" 271 311 272 312 annotation(Inline=false,smoothOrder=5); … … 277 317 278 318 redeclare function extends enthalpyOfCondensingGas 319 "Computes specific enthalpy of steam from temperature" 279 320 annotation(Inline=false,smoothOrder=5); 280 321 algorithm … … 282 323 end enthalpyOfCondensingGas; 283 324 284 redeclare function extends pressure "return pressure of ideal gas" 325 function enthalpyOfWater 326 "Computes specific enthalpy of water (solid/liquid) near atmospheric pressure from temperature" 327 input SIunits.Temperature T; 328 output SIunits.SpecificEnthalpy h; 329 annotation (derivative=enthalpyOfWater_der); 330 algorithm 331 /*simple model assuming constant properties: 332 heat capacity of liquid water:4200 J/kg 333 heat capacity of solid water: 2050 J/kg 334 enthalpy of fusion (liquid=>solid): 333000 J/kg*/ 335 336 h:=Utilities.spliceFunction(4200*(T-273.15),2050*(T-273.15)-333000,T-273.16,0.1); 337 end enthalpyOfWater; 338 339 redeclare function extends pressure "Returns pressure of ideal gas" 285 340 algorithm 286 341 p := state.p; 287 342 end pressure; 288 289 redeclare function extends temperature " return temperature of ideal gas"343 344 redeclare function extends temperature "Return temperature of ideal gas" 290 345 algorithm 291 346 T := state.T; 292 347 end temperature; 293 294 redeclare function extends density " returndensity of ideal gas"348 349 redeclare function extends density "Returns density of ideal gas" 295 350 algorithm 296 351 d := state.p/(gasConstant(state)*state.T); 297 352 end density; 298 299 redeclare function extends specificEntropy 300 "return specific entropy (liquid part neglected, mixing entropy included)"353 354 redeclare function extends specificEntropy 355 "Return specific entropy (liquid part neglected, mixing entropy included)" 301 356 annotation(Inline=false,smoothOrder=5); 302 protected 303 MoleFraction[2] Y = massToMoleFractions(state.X,{steam.MM,dryair.MM}) "molar fraction"; 304 algorithm 357 protected 358 MoleFraction[2] Y = massToMoleFractions(state.X,{steam.MM,dryair.MM}) 359 "molar fraction"; 360 algorithm 305 361 s := SingleGasNasa.s0_Tlow(dryair, state.T)*(1-state.X[Water]) 306 362 + SingleGasNasa.s0_Tlow(steam, state.T)*state.X[Water] … … 309 365 Y[i] for i in 1:size(Y,1)); 310 366 end specificEntropy; 311 367 312 368 redeclare function extends specificHeatCapacityCp 313 "Return specific heat capacity at constant pressure"369 "Returns specific heat capacity at constant pressure" 314 370 annotation(Inline=false,smoothOrder=5); 315 algorithm371 algorithm 316 372 cp:= SingleGasNasa.cp_Tlow(dryair, state.T)*(1-state.X[Water]) 317 373 + SingleGasNasa.cp_Tlow(steam, state.T)*state.X[Water]; 318 end specificHeatCapacityCp;374 end specificHeatCapacityCp; 319 375 320 376 redeclare function extends specificHeatCapacityCv 321 "Return specific heat capacity at constant volume"377 "Returns specific heat capacity at constant volume" 322 378 annotation(Inline=false,smoothOrder=5); 323 379 algorithm … … 328 384 329 385 redeclare function extends dynamicViscosity 330 " simple polynomial for dry air (moisture influence small), valid from 73.15 K to 373.15 K"386 "Simple polynomial for dry air (moisture influence small), valid from 73.15 K to 373.15 K" 331 387 import Modelica.Media.Incompressible.TableBased.Polynomials_Temp; 332 388 algorithm … … 336 392 337 393 redeclare function extends thermalConductivity 338 " simple polynomial for dry air (moisture influence small), valid from 73.15 K to 373.15 K"394 "Simple polynomial for dry air (moisture influence small), valid from 73.15 K to 373.15 K" 339 395 import Modelica.Media.Incompressible.TableBased.Polynomials_Temp; 340 396 algorithm … … 344 400 345 401 function h_pTX 346 "Compute specific enthalpy from pressure, temperature and mass fraction"402 "Compute specific enthalpy from pressure, temperature and mass fraction" 347 403 extends Modelica.Icons.Function; 348 404 input SI.Pressure p "Pressure"; … … 351 407 output SI.SpecificEnthalpy h "Specific enthalpy at p, T, X"; 352 408 annotation(Inline=false,smoothOrder=1); 353 protected409 protected 354 410 SI.AbsolutePressure p_steam_sat "Partial saturation pressure of steam"; 355 411 SI.MassFraction x_sat "steam water mass fraction of saturation boundary"; … … 363 419 X_steam :=X[Water] - X_liquid; 364 420 X_air :=1 - X[Water]; 365 h := {SingleGasNasa.h_Tlow(data=steam, T=T, refChoice=3, h_off=46479.819+2501014.5), 421 /* h := {SingleGasNasa.h_Tlow(data=steam, T=T, refChoice=3, h_off=46479.819+2501014.5), 422 SingleGasNasa.h_Tlow(data=dryair, T=T, refChoice=3, h_off=25104.684)}* 423 {X_steam, X_air} + enthalpyOfLiquid(T)*X_liquid;*/ 424 h := {SingleGasNasa.h_Tlow(data=steam, T=T, refChoice=3, h_off=46479.819+2501014.5), 366 425 SingleGasNasa.h_Tlow(data=dryair, T=T, refChoice=3, h_off=25104.684)}* 367 {X_steam, X_air} + enthalpyOf Liquid(T)*X_liquid;426 {X_steam, X_air} + enthalpyOfWater(T)*X_liquid; 368 427 end h_pTX; 369 428 370 redeclare function extends specificEnthalpy 371 "specific enthalpy" 372 algorithm 373 h := h_pTX(state.p, state.T, state.X); 429 redeclare function extends specificEnthalpy "specific enthalpy" 430 algorithm 431 h := h_pTX(state.p, state.T, state.X); 374 432 end specificEnthalpy; 375 433 376 redeclare function extends specificInternalEnergy "Return specific internal energy" 434 redeclare function extends specificInternalEnergy 435 "Return specific internal energy" 377 436 extends Modelica.Icons.Function; 378 437 algorithm 379 438 u := h_pTX(state.p,state.T,state.X) - gasConstant(state)*state.T; 380 439 end specificInternalEnergy; 381 440 382 441 redeclare function extends specificGibbsEnergy "Return specific Gibbs energy" 383 442 extends Modelica.Icons.Function; … … 385 444 g := h_pTX(state.p,state.T,state.X) - state.T*specificEntropy(state); 386 445 end specificGibbsEnergy; 387 388 redeclare function extends specificHelmholtzEnergy "Return specific Helmholtz energy" 446 447 redeclare function extends specificHelmholtzEnergy 448 "Return specific Helmholtz energy" 389 449 extends Modelica.Icons.Function; 390 450 algorithm 391 451 f := h_pTX(state.p,state.T,state.X) - gasConstant(state)*state.T - state.T*specificEntropy(state); 392 452 end specificHelmholtzEnergy; 393 394 function T_phX 395 "Compute temperature from specific enthalpy and mass fraction" 453 454 function T_phX "Compute temperature from specific enthalpy and mass fraction" 396 455 input AbsolutePressure p "Pressure"; 397 456 input SpecificEnthalpy h "specific enthalpy"; 398 457 input MassFraction[:] X "mass fractions of composition"; 399 458 output Temperature T "temperature"; 400 protected 459 460 protected 401 461 package Internal 402 "Solve h(data,T) for T with given h (use only indirectly via temperature_phX)"462 "Solve h(data,T) for T with given h (use only indirectly via temperature_phX)" 403 463 extends Modelica.Media.Common.OneNonLinearEquation; 404 464 redeclare record extends f_nonlinear_Data 405 "Data to be passed to non-linear function"465 "Data to be passed to non-linear function" 406 466 extends Modelica.Media.IdealGases.Common.DataRecord; 407 467 end f_nonlinear_Data; 408 468 409 469 redeclare function extends f_nonlinear 410 470 algorithm 411 471 y := h_pTX(p,x,X); 412 472 end f_nonlinear; 413 473 414 474 // Dummy definition has to be added for current Dymola 415 475 redeclare function extends solve 416 476 end solve; 417 477 end Internal; 418 478 419 479 algorithm 420 480 T := Internal.solve(h, 200, 6000, p, X[1:nXi], steam); 421 481 end T_phX; 422 482 483 function enthalpyOfWater_der 484 "Computes specific enthalpy of water (solid/liquid) near atmospheric pressure from temperature" 485 input SIunits.Temperature T; 486 input SIunits.Temperature dT; 487 output SIunits.SpecificEnthalpy dh; 488 algorithm 489 /*simple model assuming constant properties: 490 heat capacity of liquid water:4200 J/kg 491 heat capacity of solid water: 2050 J/kg 492 enthalpy of fusion (liquid=>solid): 333000 J/kg*/ 493 494 //h:=Utilities.spliceFunction(4200*(T-273.15),2050*(T-273.15)-333000,T-273.16,0.1); 495 dh:=Utilities.spliceFunction_der(4200*(T-273.15),2050*(T-273.15)-333000,T-273.16,0.1,4200*dT,2050*dT,dT,0); 496 end enthalpyOfWater_der; 497 423 498 package Utilities "utility functions" 424 499 function spliceFunction … … 483 558 484 559 annotation (Documentation(info="<html> 560 <h3><font color=\"#008000\" size=5>Moist Air Medium Package</font></h3> 561 <h4><font color=\"#008000\" size=4>Thermodynamic Model</font></h4> 562 <p>This package provides a full thermodynamic model of moist air including the fog region and temperatures below zero degC. 563 The governing assumptions in this model are:</p> 564 <ul> 565 <li>the perfect gas law applies</li> 566 <li>water volume other than that of steam is neglected</li></ul> 567 <p>All extensive properties are expressed in terms of the total mass in order to comply with other media in this libary. However, it is rather common to express the absolute humidity in terms of mass of dry air only, which has advantages when working with charts. Therefore two absolute humidities are computed in the <b>BaseProperties</b> model: <b>X</b> denotes the absolute humidity in terms of the total mass while <b>x</b> denotes the absolute humitity per unit mass of dry air. In addition, the relative humidity <b>phi</b> is also computed.</p> 568 <p>At the triple point temperature of water of 0.01°C or 273.16 K and a relative humidity greater than 1 fog may be present as liquid and as ice resulting in a specific enthalpy somewhere between those of the two isotherms for solid and liquid fog, respectively. For numerical reasons in this model a coexisting mixture of 50% solid and 50% liquid fog is assumed in the fog region at the triple point. 569 570 <h4><font color=\"#008000\" size=4>Range of validity</font></h4> 571 <p>From the assumptions mentioned above it follows that the <b>pressure</b> should be in the region around <b>atmospheric</b> conditions or below (a few bars may still be fine though). Additionally a very high water content at low temperatures would yield incorrect densities, because the volume of the liquid or solid phase would not be negligible anymore. The model does not provide any information on limits for water drop size in the fog region or transport information for the actual condensation or evaporation process in combination with surfaces. All excess water which is not in its vapour state is assumed to be still present in the air regarding its energy but not in terms of its spatial extent.<br><br> 572 The thermodynamic model may be used for <b>temperatures</b> ranging from <b>240 - 400 K</b>. This holds for all functions unless otherwise stated in their description. However, although the model works at temperatures above the saturation temperature it is questionable to use the term \"relative humidity\" in this region.</p> 573 574 <h4><font color=\"#008000\" size=4>Transport Properties</font></h4> 575 <p>Several additional functions that are not needed to describe the thermodynamic system, but are required to model transport processes, like heat and mass transfer, may be called. They usually neglect the moisture influence unless otherwise stated.</p> 485 576 577 <h4><font color=\"#008000\" size=4>Application</font></h4> 578 <p>The model's main area of application is all processes that involve moist air cooling under near atmospheric pressure with possible moisture condensation. This is the case in all domestic and industrial air conditioning applications. Another large domain of moist air applications covers all processes that deal with the dehydration of bulk material using air as the transport medium. Engineering tasks involving moist air are often performed (or at least visualized) by using charts that contain all relevant thermodynamic data for a moist air system. These so called psychrometric charts can be generated from the medium properties in this package. The model <a href=\"Modelica://Modelica.Media.Air.MoistAir.PsychrometricData\">PsychrometricData</a> may be used for this purpose in order to obtain data for figures like those below (the plotting itself is not part of the model though).</p> 579 580 <p><img src=\"../../Modelica/Images/Media/Air/Mollier.png\"> 581 <img src=\"../../Modelica/Images/Media/Air/PsycroChart.png\"></p> 582 <p> 583 <b>Legend:</b> blue - constant specific enthalpy, red - constant temperature, black - constant relative humidity</p> 584 486 585 </html>")); 586 model PsychrometricData "produces plot data for psychrometric charts" 587 extends Modelica.Icons.Example; 588 package Medium = Modelica.Media.Air.MoistAir; 589 parameter SIunits.Pressure p_const=1e5 "pressure"; 590 parameter Integer n_T=11 "number of isotherms"; 591 parameter SIunits.Temperature T_min=253.15 "lowest isotherm"; 592 parameter SIunits.Temperature T_step=10 593 "temperature step between two isotherms"; 594 parameter Integer n_h=16 595 "number of lines with constant specific enthalpy"; 596 parameter SIunits.SpecificEnthalpy h_min=-20e3 597 "lowest line of constant enthalpy"; 598 parameter SIunits.SpecificEnthalpy h_step=1e4 599 "enthalpy step between two lines of constant enthalpy"; 600 parameter Integer n_phi=10 601 "number of lines with constant relative humidity"; 602 parameter Real phi_min=0.1 "lowest line of constant humidity"; 603 parameter Real phi_step=0.1 "step between two lines of constant humidity"; 604 parameter SIunits.MassFraction x_min=0.00 605 "minimum diagram absolute humidity"; 606 parameter SIunits.MassFraction x_max=0.03 607 "maximum diagram absolute humidity"; 608 parameter SIunits.Time t=1 "simulation time"; 609 610 final parameter SIunits.Temperature[n_T] T_const={T_min - T_step + i*T_step for i in 611 1:n_T}; 612 final parameter SIunits.SpecificEnthalpy[n_h] h_const={(i-1)*h_step+h_min for i in 1:n_h}; 613 final parameter Real[n_phi] phi_const={(i-1)*phi_step+phi_min for i in 1:n_phi}; 614 final parameter Real diagSlope=Medium.enthalpyOfVaporization(273.15) 615 "rotation of diagram that zero degrees isotherm becomes horizontal outside the fog region"; 616 final parameter SIunits.MassFraction x_start=x_min 617 "initial absolute humidity in kg water/kg dry air"; 618 619 SIunits.MassFraction x(start=x_start) 620 "absolute humidity in kg water/kg dry air"; 621 SIunits.SpecificEnthalpy[n_T] hx_T "h_1+x for const T"; 622 SIunits.SpecificEnthalpy[n_h] hx_h(start=h_const) "const h_1+x"; 623 SIunits.SpecificEnthalpy[n_phi] hx_phi "h_1+x for const phi"; 624 SIunits.SpecificEnthalpy[n_T] y_T "chart enthalpy for const T"; 625 SIunits.SpecificEnthalpy[n_h] y_h "chart enthalpy for const h"; 626 SIunits.SpecificEnthalpy[n_phi] y_phi "chart enthalpy for const phi"; 627 Medium.BaseProperties[n_T] medium_T "medium properties for const T"; 628 Medium.BaseProperties[n_phi] medium_phi "medium properties for const phi"; 629 630 protected 631 SIunits.Pressure[n_phi] ps_phi 632 "saturation pressure for constant-phi-lines"; 633 SIunits.Temperature[n_phi] T_phi(each start=290); 634 Boolean[n_T] fog(start=fill(false, n_T)) 635 "triggers events at intersection of isotherms with phi=1"; 636 SIunits.Pressure[n_T] pd "steam partial pressure along isotherms"; 637 initial equation 638 x = x_min; 639 equation 640 641 der(x) = (x_max - x_min)/t; 642 643 for i in 1:n_T loop 644 medium_T[i].T=T_const[i]; 645 medium_T[i].p=p_const; 646 medium_T[i].Xi = {x/(1 + x)}; 647 hx_T[i] = medium_T[i].h*(medium_T[i].x_water + 1); 648 y_T[i] = hx_T[i] - diagSlope*x; 649 650 //trigger events 651 pd[i] = medium_T[i].Xi[1]*medium_T[i].MM/medium_T[i].MMX[1]*p_const; 652 fog[i] = pd[i] >= Medium.saturationPressure(T_const[i]); 653 end for; 654 for i in 1:n_h loop 655 der(hx_h[i]) = 0.0; 656 y_h[i] = hx_h[i] - diagSlope*x; 657 end for; 658 for i in 1:n_phi loop 659 medium_phi[i].p=p_const; 660 ps_phi[i] = p_const*x/phi_const[i]/(Medium.k_mair + x); 661 T_phi[i] = if x < 5e-6 then 200 else Medium.saturationTemperature( 662 ps_phi[i]); 663 medium_phi[i].T = T_phi[i]; 664 medium_phi[i].Xi = {x/(1 + x)}; 665 hx_phi[i] = medium_phi[i].h*(medium_phi[i].x_water + 1); 666 y_phi[i] = hx_phi[i] - diagSlope*x; 667 end for; 668 669 annotation (experiment(StopTime=1), Documentation(info="<html> 670 <p>This model produces psychrometric data from the moist air model in this library to be plotted in charts. The two most common chart varieties are the Mollier Diagram and the Psycrometric Chart. The first is widely used in some European countries while the second is more common in the Anglo-American world. Specific enthalpy is plotted over absolute humidity in the Mollier Diagram, it is the other way round in the Psychrometric Chart.<br> 671 It must be noted that the relationship of both axis variables is not right-angled, the absolute humidity follows a slope which equals the enthalpy of vaporization at 0°C. For better reading and in oder to reduce the fog region the humidity axis is rotated to obtain a right-angled plot. Both charts usually contain additional information as isochores or auxiliary scales for e.g. heat ratios. Those information are omitted in this model and the charts below. Other important features of psychrometric chart data are that all mass specific variables (like absolute humidity, specific enthalpy etc.) are expressed in terms of kg dry air and that their baseline of 0 enthalpy is found at 0°C and zero humidity. </p> 672 673 <p><img src=\"../../Modelica/Images/Media/Air/Mollier.png\"> 674 <img src=\"../../Modelica/Images/Media/Air/PsycroChart.png\"></p> 675 <p> 676 <b>Legend:</b> blue - constant specific enthalpy, red - constant temperature, black - constant relative humidity</p> 677 678 <p>The model provides data for lines of constant specific enthalpy, temperature and relative humidity in a Mollier Diagram or Psychrometric Chart as they were used for the figures above. For limitations and ranges of validity please refer to the MoistAir package description. Absolute humidity <b>x</b> is increased with time in this model. The specific enthalpies adjusted for plotting are then obtained from:</p> 679 <ul> 680 <li><b>y_h</b>: constant specific enthalpy</li> 681 <li><b>y_T</b>: constant temperature</li> 682 <li><b>y_phi</b>: constant relative humidity</li> 683 </ul> 684 </html>")); 685 end PsychrometricData;
