within AixLib.Media;
package Steam
  "Package with model for pure steam water vapor"
  extends Modelica.Media.Interfaces.PartialMedium(
    mediumName="steam",
    final substanceNames={"water"},
    singleState=true,
    reducedX=true,
    fixedX=true,
    FluidConstants={Modelica.Media.IdealGases.Common.FluidData.H2O},
    ThermoStates=Modelica.Media.Interfaces.Choices.IndependentVariables.pTX,
    reference_T=273.15,
    reference_p=101325,
    reference_X={1},
    AbsolutePressure(start=p_default),
    Temperature(start=T_default),
    SpecificEnthalpy(start=2.7e6, nominal=2.7e6),
    Density(start=0.6, nominal=1),
    T_default=Modelica.Units.Conversions.from_degC(100),
    p_default=100000);
  extends Modelica.Icons.Package;

  redeclare record ThermodynamicState
    "Thermodynamic state variables"
    AbsolutePressure p "Absolute pressure of medium";
    Temperature T "Temperature of medium";
  end ThermodynamicState;

redeclare replaceable model extends BaseProperties(
    preferredMediumStates = true,
    final standardOrderComponents=true)
    "Base properties (p, d, T, h, u, R, MM) of water"
equation
    MM = steam.MM;
    h = specificEnthalpy(state);
    d = density(state);
    u = h - p/d;
    R_s = steam.R;
    state.p = p;
    state.T = T;
end BaseProperties;

redeclare replaceable function extends density
  "Returns density"
algorithm
  d := rho_pT(state.p, state.T);
end density;

redeclare replaceable function extends dynamicViscosity
    "Return dynamic viscosity"
algorithm
    eta := Modelica.Media.Water.IF97_Utilities.dynamicViscosity(
          d=density(state),
          T=state.T,
          p=state.p);
end dynamicViscosity;

redeclare replaceable function extends molarMass
  "Return the molar mass of the medium"
algorithm
  MM := steam.MM;
end molarMass;

redeclare function extends pressure
  "Return pressure"
algorithm
  p := state.p;
end pressure;

replaceable function saturationPressure
  "Return saturation pressure of condensing fluid"
    extends Modelica.Icons.Function;
    input Temperature Tsat "Saturation temperature";
    output AbsolutePressure psat "Saturation pressure";
algorithm
   psat := Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(Tsat);
end saturationPressure;

replaceable function saturationTemperature
    "Return saturation temperature"
  input AbsolutePressure psat "Saturation pressure";
  output Temperature Tsat "Saturation temperature";
algorithm
    Tsat := Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.tsat(psat);
end saturationTemperature;

redeclare replaceable function extends specificEnthalpy
  "Returns specific enthalpy"
  protected
    constant Real a[:] = {2.749e+06,-9118,2.752e+04} "Regression coefficients";
    constant AbsolutePressure pMean = 2.50427896656637E+05 "Mean pressure";
    constant Temperature TMean =  4.15555698340926E+02 "Mean temperature";
    constant Real pSD = 1.13236055019318E+05 "Normalization value";
    constant Real TSD = 1.32971013463839E+01 "Normalization value";
    Modelica.Units.SI.PressureDifference pHat;
    Modelica.Units.SI.TemperatureDifference THat;
algorithm
  pHat := (state.p - pMean)/pSD;
  THat := (state.T - TMean)/TSD;
  h := a[1] + a[2]*pHat + a[3]*THat;
end specificEnthalpy;

redeclare replaceable function extends specificEntropy
  "Return specific entropy"
  protected
    constant Real a[:] = {7135,-252.4,70.03,40.6,4.953} "Regression coefficients";
    constant AbsolutePressure pMean = 2.50427896656637E+05 "Mean pressure";
    constant Temperature TMean =  4.15555698340926E+02 "Mean temperature";
    constant Real pSD = 1.13236055019318E+05 "Normalization value";
    constant Real TSD = 1.32971013463839E+01 "Normalization value";
    Modelica.Units.SI.PressureDifference pHat;
    Modelica.Units.SI.TemperatureDifference THat;
algorithm
  pHat := (state.p - pMean)/pSD;
  THat := (state.T - TMean)/TSD;
  s := a[1] + a[2]*pHat + a[3]*THat + pHat*(a[4]*pHat + a[5]*THat);
end specificEntropy;

redeclare replaceable function extends specificInternalEnergy
  "Return specific internal energy"
algorithm
  u := specificEnthalpy(state) - state.p/density(state);
end specificInternalEnergy;

redeclare replaceable function extends specificHeatCapacityCp
  "Specific heat capacity at constant pressure"

  protected
  Modelica.Media.Common.GibbsDerivs g
    "Dimensionless Gibbs function and derivatives w.r.t. pi and tau";
  SpecificHeatCapacity R "Specific gas constant of water vapor";
algorithm
  R := Modelica.Media.Water.IF97_Utilities.BaseIF97.data.RH2O;
  // Region 2 properties
  g := g2(state.p, state.T);
  cp := -R*g.tau*g.tau*g.gtautau;
end specificHeatCapacityCp;

redeclare replaceable function extends specificHeatCapacityCv
  "Specific heat capacity at constant volume"

  protected
  Modelica.Media.Common.GibbsDerivs g
    "Dimensionless Gibbs function and derivatives w.r.t. pi and tau";
  SpecificHeatCapacity R "Specific gas constant of water vapor";
algorithm
  R := Modelica.Media.Water.IF97_Utilities.BaseIF97.data.RH2O;
  // Region 2 properties
  g := g2(state.p, state.T);
  cv := R*(-g.tau*g.tau*g.gtautau + ((g.gpi - g.tau*g.gtaupi)*(g.gpi
     - g.tau*g.gtaupi)/g.gpipi));
end specificHeatCapacityCv;

redeclare replaceable function extends specificGibbsEnergy
   "Specific Gibbs energy"
algorithm
  g := specificEnthalpy(state) - state.T*specificEntropy(state);
end specificGibbsEnergy;

redeclare replaceable function extends specificHelmholtzEnergy
   "Specific Helmholtz energy"
algorithm
  f := specificEnthalpy(state) - steam.R*state.T - state.T*specificEntropy(state);
end specificHelmholtzEnergy;

redeclare replaceable function extends setState_dTX
    "Return the thermodynamic state as function of d and T"
algorithm
  state := ThermodynamicState(p=pressure_dT(d,T), T=T);
end setState_dTX;

redeclare replaceable function extends setState_pTX
    "Return the thermodynamic state as function of p and T"
algorithm
  state := ThermodynamicState(p=p, T=T);
end setState_pTX;

redeclare replaceable function extends setState_phX
    "Return the thermodynamic state as function of p and h"
algorithm
  state := ThermodynamicState(p=p, T=temperature_ph(p,h));
end setState_phX;

redeclare replaceable function extends setState_psX
    "Return the thermodynamic state as function of p and s"
algorithm
  state := ThermodynamicState(p=p, T=temperature_ps(p,s));
end setState_psX;

redeclare function extends temperature
    "Return temperature"
algorithm
  T := state.T;
end temperature;

redeclare replaceable function extends thermalConductivity
  "Return thermal conductivity"
algorithm
  lambda := Modelica.Media.Water.IF97_Utilities.thermalConductivity(
        density(state),
        state.T,
        state.p);
end thermalConductivity;

redeclare function extends density_derh_p
  "Density derivative by specific enthalpy"
algorithm
  ddhp := Modelica.Media.Water.IF97_Utilities.ddhp(
        p = state.p,
        h = specificEnthalpy(state),
        phase = 1,
        region = 2);
end density_derh_p;

redeclare function extends density_derp_h
  "Density derivative by pressure"
algorithm
  ddph := Modelica.Media.Water.IF97_Utilities.ddph(
        p = state.p,
        h = specificEnthalpy(state),
        phase = 1,
        region = 2);
end density_derp_h;

redeclare replaceable function extends isentropicExponent
  "Return isentropic exponent"
algorithm
  gamma := Modelica.Media.Water.IF97_Utilities.isentropicExponent_pT(
        p = state.p,
        T = state.T,
        region = 2);
end isentropicExponent;

redeclare replaceable function extends isothermalCompressibility
  "Isothermal compressibility of water"
algorithm
  kappa := Modelica.Media.Water.IF97_Utilities.kappa_pT(
        p = state.p,
        T = state.T,
        region = 2);
end isothermalCompressibility;

redeclare replaceable function extends isobaricExpansionCoefficient
  "Isobaric expansion coefficient of water"
algorithm
  beta := Modelica.Media.Water.IF97_Utilities.beta_pT(
        p = state.p,
        T = state.T,
        region = 2);
end isobaricExpansionCoefficient;

redeclare replaceable function extends isentropicEnthalpy
  "Isentropic enthalpy"
algorithm
  h_is := Modelica.Media.Water.IF97_Utilities.isentropicEnthalpy(
        p = p_downstream,
        s = specificEntropy(refState),
        phase = 0); // phase 0 means unknown
end isentropicEnthalpy;
//////////////////////////////////////////////////////////////////////
// Protected classes

protected
record GasProperties
  "Coefficient data record for properties of perfect gases"
  extends Modelica.Icons.Record;
    Modelica.Units.SI.MolarMass MM "Molar mass";
    Modelica.Units.SI.SpecificHeatCapacity R "Gas constant";
end GasProperties;
  constant GasProperties steam(R=Modelica.Media.IdealGases.Common.SingleGasesData.H2O.R_s,
      MM=Modelica.Media.IdealGases.Common.SingleGasesData.H2O.MM)
    "Steam properties";

function g2 "Gibbs function for region 2: g(p,T)"
  extends Modelica.Icons.Function;
    input Modelica.Units.SI.Pressure p "Pressure";
    input Modelica.Units.SI.Temperature T "Temperature (K)";
  output Modelica.Media.Common.GibbsDerivs g
    "Dimensionless Gibbs function and derivatives w.r.t. pi and tau";
  protected
  Real tau2 "Dimensionless temperature";
  Real[55] o "Vector of auxiliary variables";
algorithm
  g.p := p;
  g.T := T;
    g.R_s := Modelica.Media.Water.IF97_Utilities.BaseIF97.data.RH2O;
//  assert(p > 0.0,
//    "IF97 medium function g2 called with too low pressure\n" + "p = " +
//    String(p) + " Pa <=  0.0 Pa");
//  assert(p <= 100.0e6, "IF97 medium function g2: the input pressure (= "
//     + String(p) + " Pa) is higher than 100 Mpa");
//  assert(T >= 273.15, "IF97 medium function g2: the temperature (= " +
//    String(T) + " K) is lower than 273.15 K!");
//  assert(T <= 1073.15,
//    "IF97 medium function g2: the input temperature (= " + String(T) +
//    " K) is higher than the limit of 1073.15 K");
  g.pi := p/Modelica.Media.Water.IF97_Utilities.BaseIF97.data.PSTAR2;
  g.tau := Modelica.Media.Water.IF97_Utilities.BaseIF97.data.TSTAR2/T;
  tau2 := -0.5 + g.tau;
  o[1] := tau2*tau2;
  o[2] := o[1]*tau2;
  o[3] := -0.050325278727930*o[2];
  o[4] := -0.057581259083432 + o[3];
  o[5] := o[4]*tau2;
  o[6] := -0.045996013696365 + o[5];
  o[7] := o[6]*tau2;
  o[8] := -0.0178348622923580 + o[7];
  o[9] := o[8]*tau2;
  o[10] := o[1]*o[1];
  o[11] := o[10]*o[10];
  o[12] := o[11]*o[11];
  o[13] := o[10]*o[11]*o[12]*tau2;
  o[14] := o[1]*o[10]*tau2;
  o[15] := o[10]*o[11]*tau2;
  o[16] := o[1]*o[12]*tau2;
  o[17] := o[1]*o[11]*tau2;
  o[18] := o[1]*o[10]*o[11];
  o[19] := o[10]*o[11]*o[12];
  o[20] := o[1]*o[10];
  o[21] := g.pi*g.pi;
  o[22] := o[21]*o[21];
  o[23] := o[21]*o[22];
  o[24] := o[10]*o[12]*tau2;
  o[25] := o[12]*o[12];
  o[26] := o[11]*o[12]*o[25]*tau2;
  o[27] := o[10]*o[12];
  o[28] := o[1]*o[10]*o[11]*tau2;
  o[29] := o[10]*o[12]*o[25]*tau2;
  o[30] := o[1]*o[10]*o[25]*tau2;
  o[31] := o[1]*o[11]*o[12];
  o[32] := o[1]*o[12];
  o[33] := g.tau*g.tau;
  o[34] := o[33]*o[33];
  o[35] := -0.000053349095828174*o[13];
  o[36] := -0.087594591301146 + o[35];
  o[37] := o[2]*o[36];
  o[38] := -0.0078785554486710 + o[37];
  o[39] := o[1]*o[38];
  o[40] := -0.00037897975032630 + o[39];
  o[41] := o[40]*tau2;
  o[42] := -0.000066065283340406 + o[41];
  o[43] := o[42]*tau2;
  o[44] := 5.7870447262208e-6*tau2;
  o[45] := -0.301951672367580*o[2];
  o[46] := -0.172743777250296 + o[45];
  o[47] := o[46]*tau2;
  o[48] := -0.091992027392730 + o[47];
  o[49] := o[48]*tau2;
  o[50] := o[1]*o[11];
  o[51] := o[10]*o[11];
  o[52] := o[11]*o[12]*o[25];
  o[53] := o[10]*o[12]*o[25];
  o[54] := o[1]*o[10]*o[25];
  o[55] := o[11]*o[12]*tau2;

  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);

  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;

  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];

  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))));

  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))))))))))))))));

  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)));
end g2;

function temperature_ph
  "Return temperature from p and h, inverse function of h(p,T)"
    input AbsolutePressure p "Pressure";
    input SpecificEnthalpy h "Specific Enthalpy";
    output Temperature T "Temperature";
  protected
    constant Real a[:] = {2.749e+06,-9118,2.752e+04} "Coefficients from forward function h(p,T)";
    constant Real b[:] = {-a[1]*TSD/a[3]+TMean, -a[2]*TSD/a[3], TSD/a[3]} "Regression coefficients";
    constant AbsolutePressure pMean = 2.50427896656637E+05 "Mean pressure";
    constant Temperature TMean =  4.15555698340926E+02 "Mean temperature";
    constant Real pSD = 1.13236055019318E+05 "Normalization value";
    constant Real TSD = 1.32971013463839E+01 "Normalization value";
    Modelica.Units.SI.PressureDifference pHat;
algorithm
  pHat := (p - pMean)/pSD;
  T := b[1] + b[2]*pHat + b[3]*h;
end temperature_ph;

function temperature_ps
  "Return temperature from p and s, inverse function of s(p,T)"
    input AbsolutePressure p "Pressure";
    input SpecificEntropy s "Specific Entropy";
    output Temperature T "Temperature";
  protected
    constant Real a[:] = {7135,-252.4,70.03,40.6,4.953} "Coefficients from forward function s(p,T)";
    constant AbsolutePressure pMean = 2.50427896656637E+05 "Mean pressure";
    constant Temperature TMean =  4.15555698340926E+02 "Mean temperature";
    constant Real pSD = 1.13236055019318E+05 "Normalization value";
    constant Real TSD = 1.32971013463839E+01 "Normalization value";
    Modelica.Units.SI.PressureDifference pHat;
    Modelica.Units.SI.TemperatureDifference THat;
algorithm
  pHat := (p - pMean)/pSD;
  THat := (s - a[1] - pHat*(a[2] + a[4]*pHat))/(a[3] + a[5]*pHat);
  T := THat*TSD + TMean;
end temperature_ps;

function rho_pT "Density as function of temperature and pressure"
  extends Modelica.Icons.Function;
  input AbsolutePressure p "Pressure";
  input Temperature T "Temperature";
  output Density rho "Density";
  protected
  Modelica.Media.Common.GibbsDerivs g
    "Dimensionless Gibbs function and derivatives w.r.t. pi and tau";
  SpecificHeatCapacity R "Specific gas constant of water vapor";
  function g2_smooth
    extends Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.g2;
  end g2_smooth;
algorithm
  R := Modelica.Media.Water.IF97_Utilities.BaseIF97.data.RH2O;
  // Region 2 properties
  g := g2_smooth(p, T);
  rho := p/(R*T*g.pi*g.gpi);
end rho_pT;

function pressure_dT
  "Computes pressure as a function of density and temperature"
  input Density d "Density";
  input Temperature T "Temperature";
  output AbsolutePressure p "Pressure";
algorithm
  p := Modelica.Media.Water.IF97_Utilities.BaseIF97.Inverses.pofdt125(
        d=d,
        T=T,
        reldd=1.0e-8,
        region=2);
end pressure_dT;
end Steam;


within AixLib.Media;
package Water "Package with model for liquid water with constant density"
   extends Modelica.Media.Water.ConstantPropertyLiquidWater(
     p_default=300000,
     reference_p=300000,
     reference_T=273.15,
     reference_X={1},
     AbsolutePressure(start=p_default),
     Temperature(start=T_default),
     Density(start=d_const),
     final cv_const=cp_const);
  // cp_const and cv_const have been made final because the model sets u=h.
  extends Modelica.Icons.Package;

  redeclare replaceable model BaseProperties "Base properties (p, d, T, h, u, R, MM and X and Xi) of a medium"
    parameter Boolean preferredMediumStates=false
      "= true if StateSelect.prefer shall be used for the independent property variables of the medium"
    final parameter Boolean standardOrderComponents=true
      "If true, and reducedX = true, the last element of X will be computed from the other ones";
    Modelica.Units.SI.Density d=d_const "Density of medium";
    Temperature T(
      start=293.15,
      stateSelect=if preferredMediumStates then StateSelect.prefer else StateSelect.default)
      "Temperature of medium";
    InputAbsolutePressure p "Absolute pressure of medium";
    InputMassFraction[nXi] Xi=fill(0, 0)
      "Structurally independent mass fractions";
    InputSpecificEnthalpy h "Specific enthalpy of medium";
    Modelica.Units.SI.SpecificInternalEnergy u
      "Specific internal energy of medium";

    Modelica.Units.SI.MassFraction[nX] X={1}
      "Mass fractions (= (component mass)/total mass  m_i/m)";
    final Modelica.Units.SI.SpecificHeatCapacity R_s=0
      "Gas constant (of mixture if applicable)";
    final Modelica.Units.SI.MolarMass MM=MM_const
      "Molar mass (of mixture or single fluid)";
    ThermodynamicState state
      "Thermodynamic state record for optional functions";

    Modelica.Units.NonSI.Temperature_degC T_degC=
        Modelica.Units.Conversions.to_degC(T) "Temperature of medium in [degC]";
    Modelica.Units.NonSI.Pressure_bar p_bar=Modelica.Units.Conversions.to_bar(p)
      "Absolute pressure of medium in [bar]";

    // Local connector definition, used for equation balancing check
    connector InputAbsolutePressure = input Modelica.Units.SI.AbsolutePressure
      "Pressure as input signal connector";
    connector InputSpecificEnthalpy = input Modelica.Units.SI.SpecificEnthalpy
      "Specific enthalpy as input signal connector";
    connector InputMassFraction = input Modelica.Units.SI.MassFraction
      "Mass fraction as input signal connector";

  equation
    h = cp_const*(T-reference_T);
    u = h;
    state.T = T;
    state.p = p;

    // Assertions to test for bounds
    assert(noEvent(T >= T_min), "In " + getInstanceName() + ": Temperature T = " + String(T) + " K exceeded its minimum allowed value of " +
  String(T_min-273.15) + " degC (" + String(T_min) + " Kelvin) as required from medium model \"AixLib.Media.Water\".");

    assert(noEvent(T <= T_max), "In " + getInstanceName() + ": Temperature T = " + String(T) + " K exceeded its maximum allowed value of " +
  String(T_max-273.15) + " degC (" + String(T_max) + " Kelvin) as required from medium model \"AixLib.Media.Water\".");

    assert(noEvent(p >= 0.0), "Pressure (= " + String(p) + " Pa) of medium \"AixLib.Media.Water\" is negative\n(Temperature = " + String(T) + " K)");
  end BaseProperties;

function enthalpyOfLiquid "Return the specific enthalpy of liquid"
  extends Modelica.Icons.Function;
    input Modelica.Units.SI.Temperature T "Temperature";
    output Modelica.Units.SI.SpecificEnthalpy h "Specific enthalpy";
algorithm
  h := cp_const*(T-reference_T);
end enthalpyOfLiquid;
end Water;


within AixLib.Media.Antifreeze;
package EthyleneGlycolWater
  "Package with model for ethylene glycol - water with constant properties"
  extends Modelica.Media.Interfaces.PartialSimpleMedium(
    mediumName="EthyleneGlycolWater(X_a = " + String(X_a) + ", property_T = "
         + String(property_T) + ")",
    final cp_const=specificHeatCapacityCp_TX_a(T=property_T, X_a=X_a),
    final cv_const=cp_const,
    final d_const=density_TX_a(T=property_T, X_a=X_a),
    final eta_const=dynamicViscosity_TX_a(T=property_T, X_a=X_a),
    final lambda_const=thermalConductivity_TX_a(T=property_T, X_a=X_a),
    a_const=1484,
    final T_min=fusionTemperature_TX_a(T=property_T, X_a=X_a),
    T_max=Modelica.Units.Conversions.from_degC(100),
    T0=273.15,
    MM_const=(X_a/simpleEthyleneGlycolWaterConstants[1].molarMass + (1 - X_a)/
        0.018015268)^(-1),
    fluidConstants=simpleEthyleneGlycolWaterConstants,
    p_default=300000,
    reference_p=300000,
    reference_T=273.15,
    reference_X={1},
    AbsolutePressure(start=p_default),
    Temperature(start=T_default),
    Density(start=d_const));

  constant Modelica.Units.SI.Temperature property_T
    "Temperature for evaluation of constant fluid properties";
  constant Modelica.Units.SI.MassFraction X_a
    "Mass fraction of propylene glycol in water";

  redeclare model BaseProperties "Base properties"
    Temperature T(stateSelect=
      if preferredMediumStates then StateSelect.prefer else StateSelect.default)
      "Temperature of medium";

    InputAbsolutePressure p "Absolute pressure of medium";
    InputMassFraction[nXi] Xi=fill(0, 0)
      "Structurally independent mass fractions";
    InputSpecificEnthalpy h "Specific enthalpy of medium";
    Modelica.Units.SI.SpecificInternalEnergy u
      "Specific internal energy of medium";
    Modelica.Units.SI.Density d=d_const "Density of medium";
    Modelica.Units.SI.MassFraction[nX] X={1}
      "Mass fractions (= (component mass)/total mass  m_i/m)";
    final Modelica.Units.SI.SpecificHeatCapacity R_s=0
      "Gas constant (of mixture if applicable)";
    final Modelica.Units.SI.MolarMass MM=MM_const
      "Molar mass (of mixture or single fluid)";
    ThermodynamicState state
      "Thermodynamic state record for optional functions";
    parameter Boolean preferredMediumStates=false
      "= true if StateSelect.prefer shall be used for the independent property variables of the medium"
    final parameter Boolean standardOrderComponents=true
      "If true, and reducedX = true, the last element of X will be computed from the other ones";
    Modelica.Units.NonSI.Temperature_degC T_degC=
        Modelica.Units.Conversions.to_degC(T) "Temperature of medium in [degC]";
    Modelica.Units.NonSI.Pressure_bar p_bar=Modelica.Units.Conversions.to_bar(p)
      "Absolute pressure of medium in [bar]";

    // Local connector definition, used for equation balancing check
    connector InputAbsolutePressure = input Modelica.Units.SI.AbsolutePressure
      "Pressure as input signal connector";
    connector InputSpecificEnthalpy = input Modelica.Units.SI.SpecificEnthalpy
      "Specific enthalpy as input signal connector";
    connector InputMassFraction = input Modelica.Units.SI.MassFraction
      "Mass fraction as input signal connector";

  equation
  assert(T >= T_min, "
In "   + getInstanceName() + ": Temperature T exceeded its minimum allowed value of " + String(T_min-273.15)
    + " degC (" + String(T_min) + " Kelvin)
as required from medium model \"" + mediumName + "\".");
  assert(T <= T_max, "
In "   + getInstanceName() + ": Temperature T exceeded its maximum allowed value of " + String(T_max-273.15)
    + " degC (" + String(T_max) + " Kelvin)
as required from medium model \"" + mediumName + "\".");

  assert(X_a >= X_a_min, "
In "   + getInstanceName() + ": Mass fraction x_a exceeded its minimum allowed value of " + String(X_a_min) + "
as required from medium model \"" + mediumName + "\".");
  assert(X_a <= X_a_max, "
In "   + getInstanceName() + ": Mass fraction x_a exceeded its maximum allowed value of " + String(X_a_max) + "
as required from medium model \"" + mediumName + "\".");

    h = cp_const*(T-reference_T);
    u = h;
    state.T = T;
    state.p = p;
  end BaseProperties;
protected
  constant Modelica.Units.SI.MassFraction X_a_min=0.
    "Minimum allowed mass fraction of ethylene glycol in water";
  constant Modelica.Units.SI.MassFraction X_a_max=0.6
    "Maximum allowed mass fraction of propylene glycol in water";

  // Fluid constants based on pure Ethylene Glycol
  constant Modelica.Media.Interfaces.Types.Basic.FluidConstants[1]
    simpleEthyleneGlycolWaterConstants(
    each chemicalFormula="C2H6O2",
    each structureFormula="HOCH2CH2OH",
    each casRegistryNumber="107-21-1",
    each iupacName="Ethane-1,2-diol",
    each molarMass=0.062068);

  // Coefficients for evaluation of physical properties
  constant AixLib.Media.Antifreeze.BaseClasses.PropertyCoefficients proCoe(
    X_a_ref=0.308462,
    T_ref=Modelica.Units.Conversions.from_degC(31.728),
    nX_a=6,
    nT={4,4,4,3,2,1},
    nTot=18,
    a_d={1.034e3,-4.781e-1,-2.692e-3,4.725e-6,1.311e0,-6.876e-3,4.805e-5,
        1.690e-8,7.490e-5,7.855e-5,-3.995e-7,4.982e-9,-1.062e-4,1.229e-6,-1.153e-8,
        -9.623e-7,-7.221e-8,4.891e-8},
    a_eta={4.705e-1,-2.550e-2,1.782e-4,-7.669e-7,2.471e-2,-1.171e-4,1.052e-6,-1.634e-8,
        3.328e-6,-1.086e-6,-1.051e-8,-6.475e-10,1.695e-6,3.157e-9,4.063e-10,
        3.089e-8,1.831e-10,-1.865e-9},
    a_Tf={-1.525e1,-1.566e-6,-2.278e-7,2.169e-9,-8.080e-1,-1.339e-6,2.047e-08,-2.717e-11,
        -1.334e-2,6.332e-8,2.373e-10,-2.183e-12,-7.293e-5,-1.764e-9,-2.442e-11,
        1.006e-6,-7.662e-11,1.140e-9},
    a_cp={3.737e3,2.930e0,-4.675e-3,-1.389e-5,-1.799e1,1.046e-1,-4.147e-4,
        1.847e-7,-9.933e-2,3.516e-4,5.109e-6,-7.138e-8,2.610e-3,-1.189e-6,-1.643e-7,
        1.537e-5,-4.272e-7,-1.618e-6},
    a_lambda={4.720e-1,8.903e-4,-1.058e-6,-2.789e-9,-4.286e-3,-1.473e-5,
        1.059e-7,-1.142e-10,1.747e-5,6.814e-8,-3.612e-9,2.365e-12,3.017e-8,-2.412e-9,
        4.004e-11,-1.322e-09,2.555e-11,2.678e-11})
    "Coefficients for evaluation of thermo-physical properties";

  replaceable function density_TX_a
    "Evaluate density of antifreeze-water mixture"
    extends Modelica.Icons.Function;
    input Modelica.Units.SI.Temperature T
      "Temperature of antifreeze-water mixture";
    input Modelica.Units.SI.MassFraction X_a "Mass fraction of antifreeze";
    output Modelica.Units.SI.Density d "Density of antifreeze-water mixture";
  algorithm
    d :=polynomialProperty(
        X_a,
        T,
        proCoe.a_d)

  end density_TX_a;

  replaceable function dynamicViscosity_TX_a
    "Evaluate dynamic viscosity of antifreeze-water mixture"
      extends Modelica.Icons.Function;
    input Modelica.Units.SI.Temperature T
      "Temperature of antifreeze-water mixture";
    input Modelica.Units.SI.MassFraction X_a "Mass fraction of antifreeze";
    output Modelica.Units.SI.DynamicViscosity eta
      "Dynamic Viscosity of antifreeze-water mixture";
  algorithm
    eta :=1e-3*exp(polynomialProperty(
        X_a,
        T,
        proCoe.a_eta));
  end dynamicViscosity_TX_a;

  replaceable function fusionTemperature_TX_a
    "Evaluate temperature of fusion of antifreeze-water mixture"
      extends Modelica.Icons.Function;
    input Modelica.Units.SI.Temperature T
      "Temperature of antifreeze-water mixture";
    input Modelica.Units.SI.MassFraction X_a "Mass fraction of antifreeze";
    output Modelica.Units.SI.Temperature Tf
      "Temperature of fusion of antifreeze-water mixture";
  algorithm
    Tf :=Modelica.Units.Conversions.from_degC(polynomialProperty(
        X_a,
        T,
        proCoe.a_Tf));
  end fusionTemperature_TX_a;

  replaceable function polynomialProperty
    "Evaluates thermophysical property from 2-variable polynomial"
    extends Modelica.Icons.Function;

    input Real x "First independent variable";
    input Real y "Second independent variable";
    input Real a[sum(proCoe.nT)] "Polynomial coefficients";

    output Real f "Value of thermophysical property";

  protected
    Real dx;
    Real dy;
    Integer n;
  algorithm
    dx := 100*(x - proCoe.X_a_ref);
    dy := y - proCoe.T_ref;

    f := 0;
    n := 0;
    for i in 0:proCoe.nX_a - 1 loop
      for j in 0:proCoe.nT[i+1] - 1 loop
        n := n + 1;
        f := f + a[n]*dx^i*dy^j;
      end for;
    end for;
  end polynomialProperty;

  replaceable function specificHeatCapacityCp_TX_a
    "Evaluate specific heat capacity of antifreeze-water mixture"
      extends Modelica.Icons.Function;
    input Modelica.Units.SI.Temperature T
      "Temperature of antifreeze-water mixture";
    input Modelica.Units.SI.MassFraction X_a "Mass fraction of antifreeze";
    output Modelica.Units.SI.SpecificHeatCapacity cp
      "Specific heat capacity of antifreeze-water mixture";
  algorithm
    cp :=polynomialProperty(
        X_a,
        T,
        proCoe.a_cp);
  end specificHeatCapacityCp_TX_a;

  replaceable function thermalConductivity_TX_a
    "Evaluate thermal conductivity of antifreeze-water mixture"
      extends Modelica.Icons.Function;
    input Modelica.Units.SI.Temperature T
      "Temperature of antifreeze-water mixture";
    input Modelica.Units.SI.MassFraction X_a "Mass fraction of antifreeze";
    output Modelica.Units.SI.ThermalConductivity lambda
      "Thermal conductivity of antifreeze-water mixture";
  algorithm
    lambda :=polynomialProperty(
        X_a,
        T,
        proCoe.a_lambda);
  end thermalConductivity_TX_a;
end EthyleneGlycolWater;


within AixLib.Media;
package Antifreeze "Medium packages of secondary working fluids"
  extends Modelica.Icons.Package;
end Antifreeze;


within AixLib.Media.Antifreeze;
package PropyleneGlycolWater
  "Package with model for propylene glycol - water with constant properties"
  extends Modelica.Media.Interfaces.PartialSimpleMedium(
    mediumName="PropyleneGlycolWater(X_a = " + String(X_a) + ", property_T = "
         + String(property_T) + ")",
    final cp_const=specificHeatCapacityCp_TX_a(T=property_T, X_a=X_a),
    final cv_const=cp_const,
    final d_const=density_TX_a(T=property_T, X_a=X_a),
    final eta_const=dynamicViscosity_TX_a(T=property_T, X_a=X_a),
    final lambda_const=thermalConductivity_TX_a(T=property_T, X_a=X_a),
    a_const=1484,
    final T_min=fusionTemperature_TX_a(T=property_T, X_a=X_a),
    T_max=Modelica.Units.Conversions.from_degC(100),
    T0=273.15,
    MM_const=(X_a/simplePropyleneGlycolWaterConstants[1].molarMass + (1 - X_a)/
        0.018015268)^(-1),
    fluidConstants=simplePropyleneGlycolWaterConstants,
    p_default=300000,
    reference_p=300000,
    reference_T=273.15,
    reference_X={1},
    AbsolutePressure(start=p_default),
    Temperature(start=T_default),
    Density(start=d_const));

  constant Modelica.Units.SI.Temperature property_T
    "Temperature for evaluation of constant fluid properties";
  constant Modelica.Units.SI.MassFraction X_a
    "Mass fraction of propylene glycol in water";

  redeclare model BaseProperties "Base properties"
    Temperature T(stateSelect=
      if preferredMediumStates then StateSelect.prefer else StateSelect.default)
      "Temperature of medium";

    InputAbsolutePressure p "Absolute pressure of medium";
    InputMassFraction[nXi] Xi=fill(0, 0)
      "Structurally independent mass fractions";
    InputSpecificEnthalpy h "Specific enthalpy of medium";
    Modelica.Units.SI.SpecificInternalEnergy u
      "Specific internal energy of medium";
    Modelica.Units.SI.Density d=d_const "Density of medium";
    Modelica.Units.SI.MassFraction[nX] X={1}
      "Mass fractions (= (component mass)/total mass  m_i/m)";
    final Modelica.Units.SI.SpecificHeatCapacity R_s=0
      "Gas constant (of mixture if applicable)";
    final Modelica.Units.SI.MolarMass MM=MM_const
      "Molar mass (of mixture or single fluid)";
    ThermodynamicState state
      "Thermodynamic state record for optional functions";
    parameter Boolean preferredMediumStates=false
      "= true if StateSelect.prefer shall be used for the independent property variables of the medium"
    final parameter Boolean standardOrderComponents=true
      "If true, and reducedX = true, the last element of X will be computed from the other ones";
    Modelica.Units.NonSI.Temperature_degC T_degC=
        Modelica.Units.Conversions.to_degC(T) "Temperature of medium in [degC]";
    Modelica.Units.NonSI.Pressure_bar p_bar=Modelica.Units.Conversions.to_bar(p)
      "Absolute pressure of medium in [bar]";

    // Local connector definition, used for equation balancing check
    connector InputAbsolutePressure = input Modelica.Units.SI.AbsolutePressure
      "Pressure as input signal connector";
    connector InputSpecificEnthalpy = input Modelica.Units.SI.SpecificEnthalpy
      "Specific enthalpy as input signal connector";
    connector InputMassFraction = input Modelica.Units.SI.MassFraction
      "Mass fraction as input signal connector";

  equation
  assert(T >= T_min, "
In "   + getInstanceName() + ": Temperature T exceeded its minimum allowed value of " + String(T_min-273.15)
    + " degC (" + String(T_min) + " Kelvin)
as required from medium model \"" + mediumName + "\".");
  assert(T <= T_max, "
In "   + getInstanceName() + ": Temperature T exceeded its maximum allowed value of " + String(T_max-273.15)
    + " degC (" + String(T_max) + " Kelvin)
as required from medium model \"" + mediumName + "\".");

  assert(X_a >= X_a_min, "
In "   + getInstanceName() + ": Mass fraction x_a exceeded its minimum allowed value of " + String(X_a_min) + "
as required from medium model \"" + mediumName + "\".");
  assert(X_a <= X_a_max, "
In "   + getInstanceName() + ": Mass fraction x_a exceeded its maximum allowed value of " + String(X_a_max) + "
as required from medium model \"" + mediumName + "\".");

    h = cp_const*(T-reference_T);
    u = h;
    state.T = T;
    state.p = p;
  end BaseProperties;
protected
  constant Modelica.Units.SI.MassFraction X_a_min=0.
    "Minimum allowed mass fraction of propylene glycol in water";
  constant Modelica.Units.SI.MassFraction X_a_max=0.6
    "Maximum allowed mass fraction of propylene glycol in water";

  // Fluid constants based on pure Propylene Glycol
  constant Modelica.Media.Interfaces.Types.Basic.FluidConstants[1]
    simplePropyleneGlycolWaterConstants(
    each chemicalFormula="C3H8O2",
    each structureFormula="CH3CH(OH)CH2OH",
    each casRegistryNumber="57-55-6",
    each iupacName="1,2-Propylene glycol",
    each molarMass=0.07609);

  // Coefficients for evaluation of physical properties
  constant AixLib.Media.Antifreeze.BaseClasses.PropertyCoefficients proCoe(
    X_a_ref=0.307031,
    T_ref=Modelica.Units.Conversions.from_degC(32.7083),
    nX_a=6,
    nT={4,4,4,3,2,1},
    nTot=18,
    a_d={1.018e3,-5.406e-1,-2.666e-3,1.347e-5,7.604e-1,-9.450e-3,5.541e-5,-1.343e-7,
        -2.498e-3,2.700e-5,-4.018e-7,3.376e-9,-1.550e-4,2.829e-6,-7.175e-9,-1.131e-6,
        -2.221e-8,2.342e-8},
    a_eta={6.837e-1,-3.045e-2,2.525e-4,-1.399e-6,3.328e-2,-3.984e-4,4.332e-6,-1.860e-8,
        5.453e-5,-8.600e-8,-1.593e-8,-4.465e-11,-3.900e-6,1.054e-7,-1.589e-9,-1.587e-8,
        4.475e-10,3.564e-9},
    a_Tf={-1.325e1,-3.820e-5,7.865e-7,-1.733e-9,-6.631e-1,6.774e-6,-6.242e-8,-7.819e-10,
        -1.094e-2,5.332e-8,-4.169e-9,3.288e-11,-2.283e-4,-1.131e-8,1.918e-10,-3.409e-6,
        8.035e-11,1.465e-8},
    a_cp={3.882e3,2.699e0,-1.659e-3,-1.032e-5,-1.304e1,5.070e-2,-4.752e-5,
        1.522e-6,-1.598e-1,9.534e-5,1.167e-5,-4.870e-8,3.539e-4,3.102e-5,-2.950e-7,
        5.000e-5,-7.135e-7,-4.959e-7},
    a_lambda={4.513e-1,7.955e-4,3.482e-8,-5.966e-9,-4.795e-3,-1.678e-5,8.941e-8,
        1.493e-10,2.076e-5,1.563e-7,-4.615e-9,9.897e-12,-9.083e-8,-2.518e-9,
        6.543e-11,-5.952e-10,-3.605e-11,2.104e-11})
    "Coefficients for evaluation of thermo-physical properties";

  replaceable function density_TX_a
    "Evaluate density of antifreeze-water mixture"
    extends Modelica.Icons.Function;
    input Modelica.Units.SI.Temperature T
      "Temperature of antifreeze-water mixture";
    input Modelica.Units.SI.MassFraction X_a "Mass fraction of antifreeze";
    output Modelica.Units.SI.Density d "Density of antifreeze-water mixture";
  algorithm
    d :=polynomialProperty(
        X_a,
        T,
        proCoe.a_d)

  end density_TX_a;

  replaceable function dynamicViscosity_TX_a
    "Evaluate dynamic viscosity of antifreeze-water mixture"
      extends Modelica.Icons.Function;
    input Modelica.Units.SI.Temperature T
      "Temperature of antifreeze-water mixture";
    input Modelica.Units.SI.MassFraction X_a "Mass fraction of antifreeze";
    output Modelica.Units.SI.DynamicViscosity eta
      "Dynamic Viscosity of antifreeze-water mixture";
  algorithm
    eta :=1e-3*exp(polynomialProperty(
        X_a,
        T,
        proCoe.a_eta));
  end dynamicViscosity_TX_a;

  replaceable function fusionTemperature_TX_a
    "Evaluate temperature of fusion of antifreeze-water mixture"
      extends Modelica.Icons.Function;
    input Modelica.Units.SI.Temperature T
      "Temperature of antifreeze-water mixture";
    input Modelica.Units.SI.MassFraction X_a "Mass fraction of antifreeze";
    output Modelica.Units.SI.Temperature Tf
      "Temperature of fusion of antifreeze-water mixture";
  algorithm
    Tf :=Modelica.Units.Conversions.from_degC(polynomialProperty(
        X_a,
        T,
        proCoe.a_Tf));
  end fusionTemperature_TX_a;

  replaceable function polynomialProperty
    "Evaluates thermophysical property from 2-variable polynomial"
    extends Modelica.Icons.Function;

    input Real x "First independent variable";
    input Real y "Second independent variable";
    input Real a[sum(proCoe.nT)] "Polynomial coefficients";

    output Real f "Value of thermophysical property";

  protected
    Real dx;
    Real dy;
    Integer n;
  algorithm
    dx := 100*(x - proCoe.X_a_ref);
    dy := y - proCoe.T_ref;

    f := 0;
    n := 0;
    for i in 0:proCoe.nX_a - 1 loop
      for j in 0:proCoe.nT[i+1] - 1 loop
        n := n + 1;
        f := f + a[n]*dx^i*dy^j;
      end for;
    end for;
  end polynomialProperty;

  replaceable function specificHeatCapacityCp_TX_a
    "Evaluate specific heat capacity of antifreeze-water mixture"
      extends Modelica.Icons.Function;
    input Modelica.Units.SI.Temperature T
      "Temperature of antifreeze-water mixture";
    input Modelica.Units.SI.MassFraction X_a "Mass fraction of antifreeze";
    output Modelica.Units.SI.SpecificHeatCapacity cp
      "Specific heat capacity of antifreeze-water mixture";
  algorithm
    cp :=polynomialProperty(
        X_a,
        T,
        proCoe.a_cp);
  end specificHeatCapacityCp_TX_a;

  replaceable function thermalConductivity_TX_a
    "Evaluate thermal conductivity of antifreeze-water mixture"
      extends Modelica.Icons.Function;
    input Modelica.Units.SI.Temperature T
      "Temperature of antifreeze-water mixture";
    input Modelica.Units.SI.MassFraction X_a "Mass fraction of antifreeze";
    output Modelica.Units.SI.ThermalConductivity lambda
      "Thermal conductivity of antifreeze-water mixture";
  algorithm
    lambda :=polynomialProperty(
        X_a,
        T,
        proCoe.a_lambda);
  end thermalConductivity_TX_a;
end PropyleneGlycolWater;


within AixLib.Media.Antifreeze;
package BaseClasses "Base classes for secondary working fluid media packages"
extends Modelica.Icons.BasesPackage;
end BaseClasses;


within AixLib.Media.Antifreeze.Validation;
model EthyleneGlycolWater
  "Model that tests the implementation of ethylene glycol-water properties"
  extends Modelica.Icons.Example;
  extends AixLib.Media.Antifreeze.Validation.BaseClasses.FluidProperties(
    redeclare package Medium =
        AixLib.Media.Antifreeze.Validation.BaseClasses.EthyleneGlycolWater (
          property_T=300,
          X_a=0.05),
    nX_a=7,
    X_a={0.05,0.10,0.20,0.30,0.40,0.50,0.60},
    T_min=223.15,
    T_max=373.15);
end EthyleneGlycolWater;


within AixLib.Media.Antifreeze;
package Validation "Validation cases for fluid property evaluations"
extends Modelica.Icons.ExamplesPackage;
end Validation;


within AixLib.Media.Antifreeze.Validation;
model PropyleneGlycolWater
  "Model that tests the implementation of propylene glycol-water properties"
  extends Modelica.Icons.Example;
  extends AixLib.Media.Antifreeze.Validation.BaseClasses.FluidProperties(
    redeclare package Medium =
        AixLib.Media.Antifreeze.Validation.BaseClasses.PropyleneGlycolWater (
          property_T=300,
          X_a=0.05),
    nX_a=7,
    X_a={0.05,0.10,0.20,0.30,0.40,0.50,0.60},
    T_min=223.15,
    T_max=373.15);
end PropyleneGlycolWater;


within AixLib.Media.Antifreeze.Validation.BaseClasses;
package EthyleneGlycolWater
  "EthyleneGlycolWater with publicly accessible medium functions"
  extends AixLib.Media.Antifreeze.EthyleneGlycolWater;

    replaceable function testDensity_TX_a
    "Evaluate density of antifreeze-water mixture"
    extends Modelica.Icons.Function;
    input Modelica.Units.SI.Temperature T
      "Temperature of antifreeze-water mixture";
    input Modelica.Units.SI.MassFraction X_a "Mass fraction of antifreeze";
    output Modelica.Units.SI.Density d "Density of antifreeze-water mixture";
    algorithm
    d := density_TX_a(T = T, X_a = X_a);
    end testDensity_TX_a;

  function testDynamicViscosity_TX_a
    "Evaluate dynamic viscosity of antifreeze-water mixture"
      extends Modelica.Icons.Function;
    input Modelica.Units.SI.Temperature T
      "Temperature of antifreeze-water mixture";
    input Modelica.Units.SI.MassFraction X_a "Mass fraction of antifreeze";
    output Modelica.Units.SI.DynamicViscosity eta
      "Dynamic Viscosity of antifreeze-water mixture";
  algorithm
    eta := dynamicViscosity_TX_a(T = T, X_a = X_a);
  end testDynamicViscosity_TX_a;

  function testFusionTemperature_TX_a
    "Evaluate temperature of fusion of antifreeze-water mixture"
      extends Modelica.Icons.Function;
    input Modelica.Units.SI.Temperature T
      "Temperature of antifreeze-water mixture";
    input Modelica.Units.SI.MassFraction X_a "Mass fraction of antifreeze";
    output Modelica.Units.SI.Temperature Tf
      "Temperature of fusion of antifreeze-water mixture";
  algorithm
    Tf := fusionTemperature_TX_a(T = T, X_a = X_a);
  end testFusionTemperature_TX_a;

  function testSpecificHeatCapacityCp_TX_a
    "Evaluate specific heat capacity of antifreeze-water mixture"
      extends Modelica.Icons.Function;
    input Modelica.Units.SI.Temperature T
      "Temperature of antifreeze-water mixture";
    input Modelica.Units.SI.MassFraction X_a "Mass fraction of antifreeze";
    output Modelica.Units.SI.SpecificHeatCapacity cp
      "Specific heat capacity of antifreeze-water mixture";
  algorithm
    cp := specificHeatCapacityCp_TX_a(T = T, X_a = X_a);
  end testSpecificHeatCapacityCp_TX_a;

  function testThermalConductivity_TX_a
    "Evaluate thermal conductivity of antifreeze-water mixture"
      extends Modelica.Icons.Function;
    input Modelica.Units.SI.Temperature T
      "Temperature of antifreeze-water mixture";
    input Modelica.Units.SI.MassFraction X_a "Mass fraction of antifreeze";
    output Modelica.Units.SI.ThermalConductivity lambda
      "Thermal conductivity of antifreeze-water mixture";
  algorithm
    lambda := thermalConductivity_TX_a(T = T, X_a = X_a);
  end testThermalConductivity_TX_a;
end EthyleneGlycolWater;


within AixLib.Media.Antifreeze.Validation.BaseClasses;
partial model FluidProperties
  "Partial model that tests the implementation of temperature- and concentration-dependent fluid properties"

  replaceable package Medium =
      AixLib.Media.Antifreeze.Validation.BaseClasses.PropyleneGlycolWater
    "Medium package";

  parameter Integer nX_a
    "Number of mass fractions to evaluate fluid properties";
  parameter Modelica.Units.SI.MassFraction X_a[nX_a]
    "Mass fraction of additive";
  parameter Modelica.Units.SI.Temperature T_min
    "Minimum temperature of mixture";
  parameter Modelica.Units.SI.Temperature T_max
    "Maximum temperature of mixture";
  parameter Modelica.Units.SI.Temperature reference_T=293.15
    "Reference temperature";
  Modelica.Units.SI.Temperature Tf[nX_a] "Fluid temperature";
  Modelica.Units.SI.Density d[nX_a] "Density of fluid mixture";
  Modelica.Units.SI.SpecificHeatCapacity cp[nX_a]
    "Specific heat capacity of fluid mixture";
  Modelica.Units.SI.ThermalConductivity lambda[nX_a] "Density of fluid mixture";
  Modelica.Units.SI.DynamicViscosity eta[nX_a]
    "Dynamic viscosity of fluid mixture";
  Modelica.Units.SI.Temperature T "Temperature of fluid mixture";
  Modelica.Units.NonSI.Temperature_degC T_degC "Celsius temperature";

protected
  parameter Modelica.Units.SI.Time dt=1 "Simulation length";
  parameter Real convT(unit="K/s") = (T_max-T_min)/dt
    "Rate of temperature change";

equation
  T = T_min + convT*time;
  T_degC =Modelica.Units.Conversions.to_degC(T);
  for i in 1:nX_a loop
    Tf[i] =Medium.testFusionTemperature_TX_a(T=T, X_a=X_a[i]);
    d[i] =if T >= Tf[i] then Medium.testDensity_TX_a(T=T, X_a=X_a[i]) else 0.;
    cp[i] =if T >= Tf[i] then Medium.testSpecificHeatCapacityCp_TX_a(T=T, X_a=X_a[i])
       else 0.;
    lambda[i] =if T >= Tf[i] then Medium.testThermalConductivity_TX_a(T=T, X_a=X_a[i]) else 0.;
    eta[i] =if T >= Tf[i] then Medium.testDynamicViscosity_TX_a(T=T, X_a=X_a[i])
       else 0.;
  end for;
end FluidProperties;


within AixLib.Media.Antifreeze.Validation;
package BaseClasses "Package with base classes for AixLib.Media.Antifreeze.Validation"
extends Modelica.Icons.BasesPackage;
end BaseClasses;


within AixLib.Media.Antifreeze.Validation.BaseClasses;
package PropyleneGlycolWater
  "PropyleneGlycolWater with publicly accessible medium functions"
  extends AixLib.Media.Antifreeze.PropyleneGlycolWater;

    replaceable function testDensity_TX_a
    "Evaluate density of antifreeze-water mixture"
    extends Modelica.Icons.Function;
    input Modelica.Units.SI.Temperature T
      "Temperature of antifreeze-water mixture";
    input Modelica.Units.SI.MassFraction X_a "Mass fraction of antifreeze";
    output Modelica.Units.SI.Density d "Density of antifreeze-water mixture";
    algorithm
    d := density_TX_a(T = T, X_a = X_a);
    end testDensity_TX_a;

  function testDynamicViscosity_TX_a
    "Evaluate dynamic viscosity of antifreeze-water mixture"
      extends Modelica.Icons.Function;
    input Modelica.Units.SI.Temperature T
      "Temperature of antifreeze-water mixture";
    input Modelica.Units.SI.MassFraction X_a "Mass fraction of antifreeze";
    output Modelica.Units.SI.DynamicViscosity eta
      "Dynamic Viscosity of antifreeze-water mixture";
  algorithm
    eta := dynamicViscosity_TX_a(T = T, X_a = X_a);
  end testDynamicViscosity_TX_a;

  function testFusionTemperature_TX_a
    "Evaluate temperature of fusion of antifreeze-water mixture"
      extends Modelica.Icons.Function;
    input Modelica.Units.SI.Temperature T
      "Temperature of antifreeze-water mixture";
    input Modelica.Units.SI.MassFraction X_a "Mass fraction of antifreeze";
    output Modelica.Units.SI.Temperature Tf
      "Temperature of fusion of antifreeze-water mixture";
  algorithm
    Tf := fusionTemperature_TX_a(T = T, X_a = X_a);
  end testFusionTemperature_TX_a;

  function testSpecificHeatCapacityCp_TX_a
    "Evaluate specific heat capacity of antifreeze-water mixture"
      extends Modelica.Icons.Function;
    input Modelica.Units.SI.Temperature T
      "Temperature of antifreeze-water mixture";
    input Modelica.Units.SI.MassFraction X_a "Mass fraction of antifreeze";
    output Modelica.Units.SI.SpecificHeatCapacity cp
      "Specific heat capacity of antifreeze-water mixture";
  algorithm
    cp := specificHeatCapacityCp_TX_a(T = T, X_a = X_a);
  end testSpecificHeatCapacityCp_TX_a;

  function testThermalConductivity_TX_a
    "Evaluate thermal conductivity of antifreeze-water mixture"
      extends Modelica.Icons.Function;
    input Modelica.Units.SI.Temperature T
      "Temperature of antifreeze-water mixture";
    input Modelica.Units.SI.MassFraction X_a "Mass fraction of antifreeze";
    output Modelica.Units.SI.ThermalConductivity lambda
      "Thermal conductivity of antifreeze-water mixture";
  algorithm
    lambda := thermalConductivity_TX_a(T = T, X_a = X_a);
  end testThermalConductivity_TX_a;
end PropyleneGlycolWater;


within AixLib.Media.Examples;
model AirDerivativeCheck "Model that tests the derivative implementation"
  extends Modelica.Icons.Example;

   package Medium = AixLib.Media.Air;
  Modelica.Units.SI.Temperature T "Temperature";
  Modelica.Units.SI.MassFraction X[1] "Water vapor mass fraction";

  Modelica.Units.SI.SpecificEnthalpy hLiqSym "Liquid phase enthalpy";
  Modelica.Units.SI.SpecificEnthalpy hLiqCod "Liquid phase enthalpy";
  Modelica.Units.SI.SpecificEnthalpy hSteSym "Water vapor enthalpy";
  Modelica.Units.SI.SpecificEnthalpy hSteCod "Water vapor enthalpy";
  Modelica.Units.SI.SpecificEnthalpy hAirSym "Dry air enthalpy";
  Modelica.Units.SI.SpecificEnthalpy hAirCod "Dry air enthalpy";
  Modelica.Units.SI.SpecificHeatCapacity cpSym "Specific heat capacity";
  Modelica.Units.SI.SpecificHeatCapacity cpCod "Specific heat capacity";
  Modelica.Units.SI.SpecificHeatCapacity cvSym "Specific heat capacity";
  Modelica.Units.SI.SpecificHeatCapacity cvCod "Specific heat capacity";
    constant Real convT(unit="K/s3") = 270
    "Conversion factor to satisfy unit check";
    constant Real convX(unit="1/s3") = 0.01
    "Conversion factor to satisfy unit check";
initial equation
     hLiqSym = hLiqCod;
     hSteSym = hSteCod;
     hAirSym = hAirCod;
     cpSym   = cpCod;
     cvSym   = cvCod;
equation
    T = 273.15+convT*time^3;
    X = {0.001}+convX*time^3*{1};
    hLiqCod=Medium.enthalpyOfLiquid(T);
    der(hLiqCod)=der(hLiqSym);
    assert(abs(hLiqCod-hLiqSym) < 1E-2, "Model has an error");

    hSteCod=Medium.enthalpyOfCondensingGas(T);
    der(hSteCod)=der(hSteSym);
    assert(abs(hSteCod-hSteSym) < 1E-2, "Model has an error");

    hAirCod=Medium.enthalpyOfNonCondensingGas(T);
    der(hAirCod)=der(hAirSym);
    assert(abs(hAirCod-hAirSym) < 1E-2, "Model has an error");

    cpCod=Medium.specificHeatCapacityCp(
      Medium.setState_pTX(
         p=1e5,
         T=T,
         X=X));
    der(cpCod)=der(cpSym);
    assert(abs(cpCod-cpSym) < 1E-2, "Model has an error");

     cvCod=Medium.specificHeatCapacityCv(
      Medium.setState_pTX(
         p=1e5,
         T=T,
         X=X));
    der(cvCod)=der(cvSym);
    assert(abs(cvCod-cvSym) < 1E-2, "Model has an error");
end AirDerivativeCheck;


within AixLib.Media.Examples;
model AirProperties
  "Model that tests the implementation of the fluid properties"
  extends Modelica.Icons.Example;
  extends AixLib.Media.Examples.BaseClasses.FluidProperties(
    redeclare package Medium = AixLib.Media.Air,
    TMin=273.15-30,
    TMax=273.15+60);

  Modelica.Units.SI.SpecificEnthalpy hLiq "Specific enthalpy of liquid";

equation
  // Check the implementation of the base properties
  basPro.state.p=p;
  basPro.state.T=T;
  basPro.state.X[1]=X[1];

  hLiq = Medium.enthalpyOfLiquid(T);
  if Medium.nX == 1 then
    assert(abs(h-hLiq) < 1e-8, "Error in enthalpy computation.");
  end if;
end AirProperties;


within AixLib.Media.Examples;
model AirTemperatureEnthalpyInversion
  "Model to check computation of h(T) and its inverse"
  extends Modelica.Icons.Example;
  extends AixLib.Media.Examples.BaseClasses.TestTemperatureEnthalpyInversion(
    redeclare package Medium = AixLib.Media.Air);
end AirTemperatureEnthalpyInversion;


within AixLib.Media;
package Examples "Collection of models that test the media models"
  extends Modelica.Icons.ExamplesPackage;
end Examples;


within AixLib.Media.Examples;
model PropyleneGlycolWaterDerivativeCheck
  "Model that tests the derivative implementation"
  extends Modelica.Icons.Example;

   package Medium = AixLib.Media.Antifreeze.PropyleneGlycolWater (
      X_a=0.60,
      property_T=293.15);

  Modelica.Units.SI.Temperature T "Temperature";
  Modelica.Units.SI.SpecificEnthalpy hLiqSym "Liquid phase enthalpy";
  Modelica.Units.SI.SpecificEnthalpy hLiqCod "Liquid phase enthalpy";
  Modelica.Units.SI.SpecificHeatCapacity cpSym "Specific heat capacity";
  Modelica.Units.SI.SpecificHeatCapacity cpCod "Specific heat capacity";
  Modelica.Units.SI.SpecificHeatCapacity cvSym "Specific heat capacity";
  Modelica.Units.SI.SpecificHeatCapacity cvCod "Specific heat capacity";
    constant Real convT(unit="K/s3") = 100
      "Conversion factor to satisfy unit check";
initial equation
     hLiqSym = hLiqCod;
     cpSym   = cpCod;
     cvSym   = cvCod;
equation
    T = 273.15+convT*time^3;
    hLiqCod=Medium.cp_const*(T-Medium.reference_T);
    der(hLiqCod)=der(hLiqSym);
    assert(abs(hLiqCod-hLiqSym) < 1E-2, "Model has an error");

    cpCod=Medium.specificHeatCapacityCp(
      Medium.setState_pTX(
         p=1e5,
         T=T,
         X=Medium.X_default));
    der(cpCod)=der(cpSym);
    assert(abs(cpCod-cpSym) < 1E-2, "Model has an error");

     cvCod=Medium.specificHeatCapacityCv(
      Medium.setState_pTX(
         p=1e5,
         T=T,
         X=Medium.X_default));
    der(cvCod)=der(cvSym);
    assert(abs(cvCod-cvSym) < 1E-2, "Model has an error");
end PropyleneGlycolWaterDerivativeCheck;


within AixLib.Media.Examples;
model PropyleneGlycolWaterProperties
  "Model that tests the implementation of the fluid properties"
  extends Modelica.Icons.Example;
  extends AixLib.Media.Examples.BaseClasses.FluidProperties(
    redeclare package Medium = AixLib.Media.Antifreeze.PropyleneGlycolWater (
      X_a=0.60,
      property_T=293.15),
    TMin=273.15,
    TMax=373.15);
equation
  // Check the implementation of the base properties
  basPro.state.p=p;
  basPro.state.T=T;
end PropyleneGlycolWaterProperties;


within AixLib.Media.Examples;
model PropyleneGlycolWaterTemperatureEnthalpyInversion
  "Model to check computation of h(T) and its inverse"
  extends Modelica.Icons.Example;
  extends AixLib.Media.Examples.BaseClasses.TestTemperatureEnthalpyInversion(
    redeclare package Medium = AixLib.Media.Antifreeze.PropyleneGlycolWater (
      X_a=0.60,
      property_T=293.15));
end PropyleneGlycolWaterTemperatureEnthalpyInversion;


within AixLib.Media.Examples;
model SteamDerivativeCheck "Model that tests the derivative implementation"
  extends Modelica.Icons.Example;

   package Medium = AixLib.Media.Steam "Medim model";

  Modelica.Units.SI.Temperature T "Temperature";
  Modelica.Units.SI.SpecificEnthalpy hVapSym "Vapor phase specific enthalpy";
  Modelica.Units.SI.SpecificEnthalpy hVapCod "Vapor phase specific enthalpy";
  Modelica.Units.SI.SpecificHeatCapacity cpSym "Specific heat capacity";
  Modelica.Units.SI.SpecificHeatCapacity cpCod "Specific heat capacity";
  Modelica.Units.SI.SpecificHeatCapacity cvSym "Specific heat capacity";
  Modelica.Units.SI.SpecificHeatCapacity cvCod "Specific heat capacity";
    constant Real convT(unit="K/s3") = 270
    "Conversion factor to satisfy unit check";
initial equation
     hVapSym = hVapCod;
     cpSym   = cpCod;
     cvSym   = cvCod;
equation
    T = 273.15+110+convT*time^3;
    hVapCod=Medium.specificEnthalpy(
      Medium.setState_pTX(
         p=1e5,
         T=T,
         X=Medium.X_default));
    assert(abs(hVapCod-hVapSym) < 1E-4 * (1+abs(hVapCod)), "Model has an error");
    der(hVapCod)=der(hVapSym);

    cpCod=Medium.specificHeatCapacityCp(
      Medium.setState_pTX(
         p=1e5,
         T=T,
         X=Medium.X_default));
    der(cpCod)=der(cpSym);
    assert(abs(cpCod-cpSym) < 1E-4 * (1+abs(cpCod)), "Model has an error");

     cvCod=Medium.specificHeatCapacityCv(
      Medium.setState_pTX(
         p=1e5,
         T=T,
         X=Medium.X_default));
    der(cvCod)=der(cvSym);
    assert(abs(cvCod-cvSym) < 1E-4 * (1+abs(cvCod)), "Model has an error");
end SteamDerivativeCheck;


within AixLib.Media.Examples;
model SteamProperties
  "Model that tests the implementation of the steam superheated properties"
  extends Modelica.Icons.Example;
  extends AixLib.Media.Examples.BaseClasses.PartialProperties(
    redeclare package Medium = AixLib.Media.Steam (
      p_default=200000),
    TMin=273.15 + 100,
    TMax=273.15 + 160,
    p=200000);

  Medium.ThermodynamicState state_phX "Medium state";
  Medium.ThermodynamicState state_psX "Medium state";

  Modelica.Media.Interfaces.Types.DerDensityByEnthalpy ddhp
    "Density derivative w.r.t. enthalpy";
  Modelica.Media.Interfaces.Types.DerDensityByPressure ddph
    "Density derivative w.r.t. pressure";

equation

  // Check setting the states
  state_pTX = Medium.setState_pTX(p=p, T=T, X=X);
  state_phX = Medium.setState_phX(p=p, h=h, X=X);
  state_psX = Medium.setState_psX(p=p, s=s, X=X);
  checkState(state_pTX, state_phX, errAbs, "state_phX");
  checkState(state_pTX, state_psX, errAbs, "state_psX");

  // Check the implementation of the functions
  ddhp = Medium.density_derh_p(state_pTX);
  ddph = Medium.density_derp_h(state_pTX);

  // Check the implementation of the base properties
  basPro.state.p=p;
  basPro.state.T=T;
end SteamProperties;


within AixLib.Media.Examples;
model SteamSaturationConsistencyCheck
  "Model that checks the consistency of saturated property functions"
  extends Modelica.Icons.Example;

  package MediumSte = AixLib.Media.Steam "Steam medium model";
  package MediumWat = AixLib.Media.Water "Liquid water medium model";

  parameter Modelica.Units.SI.Temperature TMin=273.15 + 100
    "Minimum temperature for the simulation";
  parameter Modelica.Units.SI.Temperature TMax=273.15 + 179.886
    "Maximum temperature for the simulation";
  parameter Real tol = 1E-8 "Numerical tolerance";

  MediumSte.ThermodynamicState sat "Saturation state";
  Modelica.Units.SI.Pressure pSat "Saturation pressure";
  Modelica.Units.SI.Temperature TSat0 "Starting saturation temperature";
  Modelica.Units.SI.Temperature TSat "Saturation temperature";
  Modelica.Units.NonSI.Temperature_degC TSat_degC
    "Celsius saturation temperature";
  Modelica.Units.SI.SpecificEnthalpy hlvIF97
    "Enthalpy of vaporization, IF97 formulation";
  Modelica.Units.SI.SpecificEnthalpy hlvWatSte
    "Enthalpy of vaporization, water and steam medium models";
  Modelica.Units.SI.SpecificEnthalpy hlIF97
    "Enthalpy of saturated liquid, IF97";
  Modelica.Units.SI.SpecificEnthalpy hlWat
    "Enthalpy of saturated liquid, water medium";
  Modelica.Units.SI.SpecificEnthalpy hvIF97 "Enthalpy of saturated vapor, IF97";
  Modelica.Units.SI.SpecificEnthalpy hvSte
    "Enthalpy of saturated vapor, steam medium";

  Real hlvErr "Enthalpy of vaporization percent error";
  Real hlErr "Enthalpy of saturated liquid percent error";
  Real hvErr "Enthalpy of saturated vapor percent error";

protected
  constant Real conv(unit="1/s") = 1 "Conversion factor to satisfy unit check";

function enthalpyOfSaturatedLiquid
  "Return enthalpy of saturated liquid"
    extends Modelica.Icons.Function;
    input Modelica.Units.SI.AbsolutePressure p "Pressure";
    output Modelica.Units.SI.SpecificEnthalpy hl "Enthalpy of saturated liquid";
algorithm
  hl := Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.hl_p(p);
end enthalpyOfSaturatedLiquid;

function enthalpyOfSaturatedVapor
  "Return enthalpy of saturated liquid"
    extends Modelica.Icons.Function;
    input Modelica.Units.SI.AbsolutePressure p "Pressure";
    output Modelica.Units.SI.SpecificEnthalpy hv "Enthalpy of saturated liquid";
algorithm
  hv := Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.hv_p(p);
end enthalpyOfSaturatedVapor;

function enthalpyOfVaporization
  "Return enthalpy of vaporization"
    extends Modelica.Icons.Function;
    input Modelica.Units.SI.AbsolutePressure p "Pressure";
    output Modelica.Units.SI.SpecificEnthalpy r0 "Vaporization enthalpy";
algorithm
  r0 := Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.hv_p(p) -
    Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.hl_p(p);
end enthalpyOfVaporization;

equation
  // Compute temperatures that are used as input to the functions
  TSat0 = TMin + conv*time * (TMax-TMin);

  // Set saturation states
  pSat = MediumSte.saturationPressure(TSat0);
  TSat = MediumSte.saturationTemperature(pSat);
  if (time>0.1) then
  assert(abs(TSat-TSat0)<tol, "Error in implementation of functions.\n"
     + "   TSat0 = " + String(TSat0) + "\n"
     + "   TSat  = " + String(TSat) + "\n"
     + "   Absolute error: " + String(abs(TSat-TSat0)) + " K");
  end if;
  TSat_degC =Modelica.Units.Conversions.to_degC(TSat);
  sat = MediumSte.setState_pTX(p=pSat, T=TSat, X=MediumSte.X_default);

  hlvIF97 = enthalpyOfVaporization(pSat);
  hlvWatSte = MediumSte.specificEnthalpy(sat) - MediumWat.specificEnthalpy(sat);
  hlIF97 = enthalpyOfSaturatedLiquid(pSat);
  hlWat = MediumWat.specificEnthalpy(sat);
  hvIF97 = enthalpyOfSaturatedVapor(pSat);
  hvSte = MediumSte.specificEnthalpy(sat);

  hlvErr = abs(hlvIF97 - hlvWatSte)/hlvIF97*100;
  hlErr = abs(hlIF97 - hlWat)/hlIF97*100;
  hvErr = abs(hvIF97 - hvSte)/hvIF97*100;
end SteamSaturationConsistencyCheck;


within AixLib.Media.Examples;
model SteamTemperatureEnthalpyInversion
  "Model to check computation of h(T) and its inverse"
  extends Modelica.Icons.Example;
  extends AixLib.Media.Examples.BaseClasses.TestTemperatureEnthalpyInversion(
    redeclare package Medium = AixLib.Media.Steam,
    T0=273.15 + 300);
end SteamTemperatureEnthalpyInversion;


within AixLib.Media.Examples;
model WaterDerivativeCheck "Model that tests the derivative implementation"
  extends Modelica.Icons.Example;

   package Medium = AixLib.Media.Water;

  Modelica.Units.SI.Temperature T "Temperature";
  Modelica.Units.SI.SpecificEnthalpy hLiqSym "Liquid phase enthalpy";
  Modelica.Units.SI.SpecificEnthalpy hLiqCod "Liquid phase enthalpy";
  Modelica.Units.SI.SpecificHeatCapacity cpSym "Specific heat capacity";
  Modelica.Units.SI.SpecificHeatCapacity cpCod "Specific heat capacity";
  Modelica.Units.SI.SpecificHeatCapacity cvSym "Specific heat capacity";
  Modelica.Units.SI.SpecificHeatCapacity cvCod "Specific heat capacity";
    constant Real convT(unit="K/s3") = 270
    "Conversion factor to satisfy unit check";
initial equation
     hLiqSym = hLiqCod;
     cpSym   = cpCod;
     cvSym   = cvCod;
equation
    T = 273.15+convT*time^3;
    hLiqCod=Medium.enthalpyOfLiquid(T);
    der(hLiqCod)=der(hLiqSym);
    assert(abs(hLiqCod-hLiqSym) < 1E-2, "Model has an error");

    cpCod=Medium.specificHeatCapacityCp(
      Medium.setState_pTX(
         p=1e5,
         T=T,
         X=Medium.X_default));
    der(cpCod)=der(cpSym);
    assert(abs(cpCod-cpSym) < 1E-2, "Model has an error");

     cvCod=Medium.specificHeatCapacityCv(
      Medium.setState_pTX(
         p=1e5,
         T=T,
         X=Medium.X_default));
    der(cvCod)=der(cvSym);
    assert(abs(cvCod-cvSym) < 1E-2, "Model has an error");
end WaterDerivativeCheck;


within AixLib.Media.Examples;
model WaterProperties
  "Model that tests the implementation of the fluid properties"
  extends Modelica.Icons.Example;
  extends AixLib.Media.Examples.BaseClasses.FluidProperties(
    redeclare package Medium = AixLib.Media.Water,
    TMin=273.15,
    TMax=373.15);
equation
  // Check the implementation of the base properties
  basPro.state.p=p;
  basPro.state.T=T;
end WaterProperties;


within AixLib.Media.Examples;
model WaterTemperatureEnthalpyInversion
  "Model to check computation of h(T) and its inverse"
  extends Modelica.Icons.Example;
  extends AixLib.Media.Examples.BaseClasses.TestTemperatureEnthalpyInversion(
    redeclare package Medium = AixLib.Media.Water);
end WaterTemperatureEnthalpyInversion;


Model that tests the implementation of the fluid properties. This example checks thermophysical properties of the medium.

within AixLib.Media.Examples.BaseClasses;
partial model FluidProperties
  "Model that tests the implementation of the fluid properties"
  extends PartialProperties;

  Medium.ThermodynamicState state_phX "Medium state";
  Medium.ThermodynamicState state_psX "Medium state";

  Modelica.Media.Interfaces.Types.DerDensityByPressure ddpT
    "Density derivative w.r.t. pressure";
  Modelica.Media.Interfaces.Types.DerDensityByTemperature ddTp
    "Density derivative w.r.t. temperature";
  Modelica.Units.SI.Density[Medium.nX] dddX
    "Density derivative w.r.t. mass fraction";

equation

   // Check setting the states
    state_pTX = Medium.setState_pTX(p=p, T=T, X=X);
    state_phX = Medium.setState_phX(p=p, h=h, X=X);
    state_psX = Medium.setState_psX(p=p, s=s, X=X);
    checkState(state_pTX, state_phX, errAbs, "state_phX");
    checkState(state_pTX, state_psX, errAbs, "state_psX");

    // Check the implementation of the functions
    ddpT = Medium.density_derp_T(state_pTX);
    ddTp = Medium.density_derT_p(state_pTX);
    dddX   = Medium.density_derX(state_pTX);
end FluidProperties;


within AixLib.Media.Examples;
package BaseClasses "Package with base classes for AixLib.Media.Examples"
  extends Modelica.Icons.BasesPackage;
end BaseClasses;


within AixLib.Media.Examples.BaseClasses;
partial model PartialProperties
  "Partial model that contains common parameters of the fluid properties"

  replaceable package Medium = Modelica.Media.Interfaces.PartialMedium;

  parameter Modelica.Units.SI.Temperature TMin
    "Minimum temperature for the simulation";
  parameter Modelica.Units.SI.Temperature TMax
    "Maximum temperature for the simulation";
  parameter Modelica.Units.SI.Pressure p=Medium.p_default "Pressure";
  parameter Modelica.Units.SI.MassFraction X[Medium.nX]=Medium.X_default
    "Mass fraction";
  parameter Real errAbs=1E-8 "Absolute error used in the check of the state calculations";
  Medium.Temperature T "Temperature";
  Modelica.Units.NonSI.Temperature_degC T_degC "Celsius temperature";

  Medium.ThermodynamicState state_pTX "Medium state";

  Modelica.Units.SI.Density d "Density";
  Modelica.Units.SI.DynamicViscosity eta "Dynamic viscosity";
  Modelica.Units.SI.SpecificEnthalpy h "Specific enthalpy";
  Modelica.Units.SI.SpecificInternalEnergy u "Specific internal energy";
  Modelica.Units.SI.SpecificEntropy s "Specific entropy";
  Modelica.Units.SI.SpecificEnergy g "Specific Gibbs energy";
  Modelica.Units.SI.SpecificEnergy f "Specific Helmholtz energy";

  Modelica.Units.SI.SpecificEnthalpy hIse "Isentropic enthalpy";

  Modelica.Media.Interfaces.Types.IsobaricExpansionCoefficient beta
    "Isobaric expansion coefficient";
  Modelica.Units.SI.IsothermalCompressibility kappa
    "Isothermal compressibility";

  Modelica.Units.SI.SpecificHeatCapacity cp "Specific heat capacity";
  Modelica.Units.SI.SpecificHeatCapacity cv "Specific heat capacity";
  Modelica.Units.SI.ThermalConductivity lambda "Thermal conductivity";

  Modelica.Units.SI.AbsolutePressure pMed "Pressure";
  Medium.Temperature TMed "Temperature";
  Modelica.Units.SI.MolarMass MM "Mixture molar mass";

  Medium.BaseProperties basPro "Medium base properties";
protected
  constant Real conv(unit="1/s") = 1 "Conversion factor to satisfy unit check";

  function checkState "This function checks the absolute error in the state calculations"
    extends Modelica.Icons.Function;
    input Medium.ThermodynamicState state1 "Medium state";
    input Medium.ThermodynamicState state2 "Medium state";
    input Real errAbs "Absolute error threshold";
    input String message "Message for error reporting";

  protected
              Real TErrAbs=abs(Medium.temperature(state1)-Medium.temperature(state2))
      "Absolute error in temperature";
  protected
              Real pErrAbs=abs(Medium.pressure(state1)-Medium.pressure(state2))
      "Absolute error in pressure";
  algorithm
    assert(TErrAbs < errAbs, "Absolute temperature error: " + String(TErrAbs) +
       " K. Error in temperature of " + message);
    assert(pErrAbs < errAbs, "Absolute pressure error: " + String(pErrAbs) +
       " Pa. Error in pressure of " + message);
  end checkState;

equation
    // Compute temperatures that are used as input to the functions
    T = TMin + conv*time * (TMax-TMin);
    T_degC =Modelica.Units.Conversions.to_degC(T);

    // Check the implementation of the functions
    d = Medium.density(state_pTX);
    eta = Medium.dynamicViscosity(state_pTX);
    h = Medium.specificEnthalpy(state_pTX);

    u = Medium.specificInternalEnergy(state_pTX);
    s = Medium.specificEntropy(state_pTX);
    g = Medium.specificGibbsEnergy(state_pTX);
    f = Medium.specificHelmholtzEnergy(state_pTX);
    hIse = Medium.isentropicEnthalpy(p, state_pTX);
    beta = Medium.isobaricExpansionCoefficient(state_pTX);
    kappa = Medium.isothermalCompressibility(state_pTX);

    cp = Medium.specificHeatCapacityCp(state_pTX);
    cv = Medium.specificHeatCapacityCv(state_pTX);
    lambda = Medium.thermalConductivity(state_pTX);
    pMed = Medium.pressure(state_pTX);
    assert(abs(p-pMed) < errAbs, "Error in pressure computation.");
    TMed = Medium.temperature(state_pTX);
    assert(abs(T-TMed) < errAbs, "Error in temperature computation.");
    MM = Medium.molarMass(state_pTX);
    // Check the implementation of the base properties
    assert(abs(h-basPro.h) < errAbs, "Error in enthalpy computation in BaseProperties.");
    assert(abs(u-basPro.u) < errAbs, "Error in internal energy computation in BaseProperties.");
end PartialProperties;


within AixLib.Media.Examples.BaseClasses;
partial model TestTemperatureEnthalpyInversion
  "Model to check computation of h(T) and its inverse with a controlleable tolerance"
   replaceable package Medium =
        Modelica.Media.Interfaces.PartialMedium;
  parameter Modelica.Units.SI.Temperature T0=273.15 + 20 "Temperature";
     parameter Real tol = 1E-8 "Numerical tolerance";
  Modelica.Units.SI.Temperature T "Temperature";
  Modelica.Units.SI.SpecificEnthalpy h "Enthalpy";
     Medium.MassFraction Xi[:] = Medium.reference_X "Mass fraction";
equation
    h = Medium.specificEnthalpy_pTX(p=101325, T=T0, X=Xi);
    T = Medium.temperature_phX(p=101325, h=h,  X=Xi);
    if (time>=0.1) then
    assert(abs(T-T0)<tol, "Error in implementation of functions.\n"
       + "   T0 = " + String(T0) + "\n"
       + "   T  = " + String(T) + "\n"
       + "   Absolute error: " + String(abs(T-T0)) + " K");
    end if;
end TestTemperatureEnthalpyInversion;


within AixLib.Media;
package Refrigerants "Package with functions for refrigerant properties"
  extends Modelica.Icons.Package;
end Refrigerants;


within AixLib.Media.Refrigerants.Examples;
model BranchingDynamicPipes
  "Example model to test dynamic mass and energy equations"
  extends Modelica.Fluid.Examples.BranchingDynamicPipes(
    redeclare package Medium =
        AixLib.Media.Refrigerants.R134a.R134a_IIR_P1_395_T233_455_Horner,
        system(energyDynamics=Modelica.Fluid.Types.Dynamics.FixedInitial));
end BranchingDynamicPipes;


within AixLib.Media.Refrigerants;
package Examples "Packages with example models for testing refrigerent models"
  extends Modelica.Icons.ExamplesPackage;
end Examples;


within AixLib.Media.Refrigerants.Examples;
model RefrigerantProperties
  "Model that tests the implementation of the refrigerant properties"
  extends Modelica.Icons.Example;

  // Define the refrigerant that shall be tested
  //
  package Medium =
      AixLib.Media.Refrigerants.R134a.R134a_IIR_P1_395_T233_455_Horner
      "Internal medium model";

  // Define way of calculating pressure and temperature
  //
  parameter Boolean wayOfCalc = true
    "true = Slowly raise pressure and change temperature | false = Slowly raise
    temperature and change pressure"

  // Define the fluid limits of the medium that shall be tested
  //
  parameter Modelica.Units.SI.SpecificEnthalpy h_min=145e3
    "Fluid limit: Minimum specific enthalpy"
  parameter Modelica.Units.SI.SpecificEnthalpy h_max=480e3
    "Fluid limit: Maximum specific enthalpy"
  parameter Modelica.Units.SI.Density d_min=2 "Fluid limit: Minimum density"
  parameter Modelica.Units.SI.Density d_max=1325 "Fluid limit: Maximum density"
  parameter Modelica.Units.SI.AbsolutePressure p_min=1e5
    "Fluid limit: Minimum absolute pressure"
  parameter Modelica.Units.SI.AbsolutePressure p_max=39e5
    "Fluid limit: Maximum absolute pressure"
  parameter Modelica.Units.SI.Temperature T_min=233.15
    "Fluid limit: Minimum temperature"
  parameter Modelica.Units.SI.Temperature T_max=455.15
    "Fluid limit: Maximum temperature"

  // Define the conversion factor for the test
  //
  Real convT(start = (T_max-T_min)/80)
    "Conversion factor in K/s for temperature to satisfy unit check";
  Real convP(start = (p_max-p_min)/(80*80))
    "Conversion factor in Pa/s for pressure to satisfy unit check";

  // Define variables that shall be tested
  //
  Modelica.Units.SI.Temperature T(start=T_min) "Actual temperature";
  Modelica.Units.SI.AbsolutePressure p(start=p_min) "Actual absolute presure";
  Modelica.Units.SI.Density d(start=d_min) "Actual density";
  Modelica.Units.SI.SpecificEnthalpy h(start=h_min) "Actual specific enthalpy";
  Modelica.Units.SI.SpecificEntropy s "Actual specific entropy";
  Modelica.Units.SI.SpecificInternalEnergy u "Actual specific internal energy";
  Modelica.Units.SI.SpecificEnergy g "Actual specific Gibbs energy";
  Modelica.Units.SI.SpecificEnergy f "Actual specific Helmholtz energy";

  Medium.SaturationProperties satT
    "Actual saturation properties calculated with temperature";
  Medium.SaturationProperties satP
    "Actual saturation properties calculated with pressure";

  Medium.ThermodynamicState bubbleState
    "Actual bubble state";
  Medium.ThermodynamicState dewState
    "Actual dew state";
  Medium.ThermodynamicState state_pT
    "Actual state calculated by p and T";
  Medium.ThermodynamicState state_dT
    "Actual state calculated by d and T";
  Medium.ThermodynamicState state_ph
    "Actual state calculated by p and h";
  Medium.ThermodynamicState state_ps
    "Actual state calculated by p and s";

  // Define records to summarise further variables that shall be tested
  //
  record ThermodynamicProperties
    "Records that contains furhter thermodynamic properties"
    Medium.SpecificHeatCapacity cp
      "Actual specific heat capacity at constant pressure";
    Medium.SpecificHeatCapacity cv
      "Actual specific heat capacity at constant volume";
    Medium.VelocityOfSound w
      "Actual velocity of sound";
    Medium.IsobaricExpansionCoefficient betta
      "Actual isobaric expansion coefficient";
    Modelica.Units.SI.IsothermalCompressibility kappa
      "Actual isothermal compressibility";
    Modelica.Units.SI.IsentropicExponent gamma "Actual isentropic coefficient";
    Real delta_T(unit= "J/(Pa.kg)")
      "Actual isothermal throttling coefficient";
    Real my(unit="K/Pa")
      "Actual joule Thomson Coefficient";
    Medium.DynamicViscosity eta
      "Actual dynamic viscosity";
    Medium.ThermalConductivity lambda
      "Actual thermal conductivity";
    Medium.SurfaceTension sigma
      "Acutal surface tension";
  end ThermodynamicProperties;

  record StateErrors
    "Record that contains errors occuring using the different
    setState functions"
    extends Modelica.Icons.Record;

    Real errorTemperature_dTMax
      "Error of temperature_dT compared to T";
    Real errorPressure_dTMax
      "Error of pressure_dT compared to p";
    Real errorDensity_dTMax
      "Error of density_dT compared to density_pT";
    Real errorSpecificEnthalpy_dTMax
      "Error of specificEnthalpy_dT compared to specificEnthalpy_pT";
    Real errorTemperature_phMax
      "Error of temperature_ph compared to T";
    Real errorPressure_phMax
      "Error of pressure_ph compared to p";
    Real errorDensity_phMax
      "Error of density_ph compared to density_pT";
    Real errorSpecificEnthalpy_phMax
      "Error of specificEnthalpy_ph compared to specificEnthalpy_pT";
    Real errorTemperature_psMax
      "Error of temperature_ps compared to T";
    Real errorPressure_psMax
      "Error of pressure_ps compared to p";
    Real errorDensity_psMax
      "Error of density_ps compared to density_pT";
    Real errorSpecificEnthalpy_psMax
      "Error of specificEnthalpy_ps compared to specificEnthalpy_pT";
    Real relErrorTemperature_dTMax
     "Relative error of temperature_dT compared to T";
    Real relErrorPressure_dTMax
     "Relative error of pressure_dT compared to p";
    Real relErrorDensity_dTMax
     "Relative error of density_dT compared to density_pT";
    Real relErrorSpecificEnthalpy_dTMax
     "Relative error of specificEnthalpy_dT compared to specificEnthalpy_pT";
    Real relErrorTemperature_phMax
     "Relative error of temperature_ph compared to T";
    Real relErrorPressure_phMax
     "Relative error of pressure_ph compared to p";
    Real relErrorDensity_phMax
     "Relative error of density_ph compared to density_pT";
    Real relErrorSpecificEnthalpy_phMax
     "Relative error of specificEnthalpy_ph compared to specificEnthalpy_pT";
    Real relErrorTemperature_psMax
     "Relative error of temperature_ps compared to T";
    Real relErrorPressure_psMax
     "Relative error of pressure_ps compared to p";
    Real relErrorDensity_psMax
     "Relative error of density_ps compared to density_pT";
    Real relErrorSpecificEnthalpy_psMax
     "Relative error of specificEnthalpy_ps compared to specificEnthalpy_pT";
  end StateErrors;

  ThermodynamicProperties thermodynamicProperties
    "Record that contains further thermodynamic properties calculated during
    the test";
  StateErrors stateErros
    "Record that contains errors occuring using the different
    setState functions";

protected
  Modelica.Units.SI.Time convChange(start=0)
    "Time to reset calculation of actual temperature or pressure";
  Modelica.Units.SI.Time convChangeTmp(start=0)
    "Temporary time to reset calculation of actual temperature or pressure";

algorithm
  if wayOfCalc then
    convT := (T_max - T_min)/80;
    convP := (p_max - p_min)/(80*80);
    convChange := if noEvent(delay(T,1)) >=
      T_max-convT then time else convChangeTmp;
  else
    convT := (T_max - T_min)/(80*80);
    convP := (p_max - p_min)/80;
    convChange := if noEvent(delay(p,1)) >=
      p_max-convP then time else convChangeTmp;
  end if;

equation

  // Change correction factors for temperature and pressure calculation
  //
  convChangeTmp = convChange;

  // Change independent thermodynamic state properties acording to time
  //
  if wayOfCalc then
    T =  min((T_min + convT * (time - convChange)),T_max);
    p =  min((p_min + convP * time),p_max);
  else
    T =  min((T_min + convT * time),T_max);
    p =  min((p_min + convP * (time - convChange)),p_max);
  end if;

  // Calculate furhter thermodynamic state properties
  //
  d = Medium.density(state_pT);
  h = Medium.specificEnthalpy(state_pT);
  s = Medium.specificEntropy(state_pT);
  u = h - p/d;
  g = h - T*s;
  f = h - p/d -T*s;

  // Calculate and check saturation properties
  //
  satT = Medium.setSat_T(min(max(243.15,T),
    Medium.fluidConstants[1].criticalTemperature-3));
  satP = Medium.setSat_p(satT.psat);

  // Calculate and check state functions
  //
  bubbleState = Medium.setBubbleState(satT,1);
  dewState = Medium.setDewState(satT,1);
  state_pT = Medium.setState_pT(p,T);
  state_dT = Medium.setState_dT(d,T);
  state_ph = Medium.setState_ph(p,h);
  state_ps = Medium.setState_ps(p,s);

  // Calculate further properties
  //
  thermodynamicProperties.cp = Medium.specificHeatCapacityCp(state_pT);
  thermodynamicProperties.cv = Medium.specificHeatCapacityCv(state_pT);
  thermodynamicProperties.w = Medium.velocityOfSound(state_pT);
  thermodynamicProperties.betta =
    Medium.isobaricExpansionCoefficient(state_pT);
  thermodynamicProperties.kappa = Medium.isothermalCompressibility(state_pT);
  thermodynamicProperties.gamma = Medium.isentropicExponent(state_pT);
  thermodynamicProperties.delta_T =
    Medium.isothermalThrottlingCoefficient(state_pT);
  thermodynamicProperties.my = Medium.jouleThomsonCoefficient(state_pT);
  thermodynamicProperties.eta = Medium.dynamicViscosity(state_pT);
  thermodynamicProperties.lambda = Medium.thermalConductivity(state_pT);
  thermodynamicProperties.sigma = Medium.surfaceTension(satT);

  // Calculate errors of thermodynamic state properties
  //
  stateErros.errorTemperature_dTMax =  abs(state_dT.T - state_pT.T);
  stateErros.errorPressure_dTMax =  abs(state_dT.p - state_pT.p);
  stateErros.errorDensity_dTMax = abs(state_dT.d - state_pT.d);
  stateErros.errorSpecificEnthalpy_dTMax = abs(state_dT.h - state_pT.h);
  stateErros.errorTemperature_phMax = abs(state_ph.T - state_pT.T);
  stateErros.errorPressure_phMax = abs(state_ph.p - state_pT.p);
  stateErros.errorDensity_phMax = abs(state_ph.d - state_pT.d);
  stateErros.errorSpecificEnthalpy_phMax = abs(state_ph.h - state_pT.h);
  stateErros.errorTemperature_psMax = abs(state_ps.T - state_pT.T);
  stateErros.errorPressure_psMax = abs(state_ps.p - state_pT.p);
  stateErros.errorDensity_psMax = abs(state_ps.d - state_pT.d);
  stateErros.errorSpecificEnthalpy_psMax = abs(state_ps.h - state_pT.h);

  stateErros.relErrorTemperature_dTMax =  abs(state_dT.T - state_pT.T) /
    abs(state_pT.T)*100;
  stateErros.relErrorPressure_dTMax =  abs(state_dT.p - state_pT.p) /
    abs(state_pT.p)*100;
  stateErros.relErrorDensity_dTMax = abs(state_dT.d - state_pT.d) /
    abs(state_pT.d)*100;
  stateErros.relErrorSpecificEnthalpy_dTMax = abs(state_dT.h - state_pT.h) /
    abs(state_pT.h)*100;
  stateErros.relErrorTemperature_phMax = abs(state_ph.T - state_pT.T) /
    abs(state_pT.T)*100;
  stateErros.relErrorPressure_phMax = abs(state_ph.p - state_pT.p) /
    abs(state_pT.p)*100;
  stateErros.relErrorDensity_phMax = abs(state_ph.d - state_pT.d) /
    abs(state_pT.d)*100;
  stateErros.relErrorSpecificEnthalpy_phMax = abs(state_ph.h - state_pT.h) /
    abs(state_pT.h)*100;
  stateErros.relErrorTemperature_psMax = abs(state_ps.T - state_pT.T) /
    abs(state_pT.T)*100;
  stateErros.relErrorPressure_psMax = abs(state_ps.p - state_pT.p) /
    abs(state_pT.p)*100;
  stateErros.relErrorDensity_psMax = abs(state_ps.d - state_pT.d) /
    abs(state_pT.d)*100;
  stateErros.relErrorSpecificEnthalpy_psMax = abs(state_ps.h - state_pT.h) /
    abs(state_pT.h)*100;
end RefrigerantProperties;


within AixLib.Media.Refrigerants.Examples;
model RefrigerantTestImplementation
  "Model to test the refrigerant implementation"
  extends Modelica.Icons.Example;
  extends Modelica.Media.Examples.Tests.Components.PartialTestModel2(
    redeclare package Medium =
        AixLib.Media.Refrigerants.R410A_HEoS.R410a_IIR_P1_48_T233_340_Record,
    h_start=151000,
    p_start=150000,
    T_start=333.15,
    fixedMassFlowRate(use_T_ambient=true),
    volume(use_T_start=true),
    ambient(use_T_ambient=true));
end RefrigerantTestImplementation;


Types, constants to define menu choices

within AixLib.Media.Refrigerants.Interfaces;
package Choices
  "Types, constants to define menu choices"
  extends Modelica.Media.Interfaces.Choices;

  type InputChoice = enumeration(
      pT "(p,T) as inputs",
      dT "(d,T) as inputs",
      ph "(p,h) as inputs",
      ps "(p,s) as inputs")
     "Enumeration to define input choice of calculating thermodynamic state"
end Choices;


within AixLib.Media.Refrigerants;
package Interfaces "Package with interfaces for refrigerant models"
  extends Modelica.Icons.InterfacesPackage;
end Interfaces;