within AixLib.Fluid.Movers.Compressors;
package Utilities "Package that contains further functions needed to compute the compressor models"
  extends Modelica.Icons.UtilitiesPackage;
end Utilities;


Types, constants to define menu choices

within AixLib.Fluid.Movers.Compressors.Utilities;
package Types
  "Types, constants to define menu choices"
  extends Modelica.Icons.TypesPackage;

  type EnginePolynomialModels = enumeration(
      JahningEtAl2000
      "JahningEtAl2000 - Function of inlet pressure",
      KinarbEtAl2010
      "KinarbEtAl2010 - Function of pressure ratio",
      DurprezEtAl2007
      "DurprezEtAl2007 - Function of pressure ratio",
      Engelpracht2017
      "Engelpracht2017 - Function of pressure ratio and rotational speed")
    "Enumeration to define polynomial models for calculating engine efficiency"
  type EnginePowerModels = enumeration(
      MendozaMirandaEtAl2016
      "MendozaMirandaEtAl2016 - Function of various properties")
    "Enumeration to define polynomial models for calculating engine efficiency"
  type IsentropicPolynomialModels = enumeration(
      DarrAndCrawford1992
      "DarrAndCrawford1992 - Function of rotational speed and densities",
      Karlsson2007
      "Karlsson2007 - Function of pressure ratio and rotational speed",
      Engelpracht2017
      "Engelpracht2017 - Function of pressure ratio and rotational speed")
    "Enumeration to define polynomial models for calculating isentropic efficiency"
  type IsentropicPowerModels = enumeration(
      MendozaMirandaEtAl2016
      "MendozaMirandaEtAl2016 - Function of various properties")
    "Enumeration to define polynomial models for calculating isentropic efficiency"
  type VolumetricPolynomialModels = enumeration(
      DarrAndCrawford1992
      "DarrAndCrawford1992 - Function of rotational speed and densities",
      Karlsson2007
      "Karlsson2007 - Function of pressure ratio and rotational speed",
      KinarbEtAl2010
      "KinarbEtAl2010 - Function of pressure ratio",
      ZhouEtAl2010
      "ZhouEtAl2010 - Function of pressure ratio and isentropic exponent",
      Li2013
      "Li2013 - Function of rotational speed and reference rotational speed",
      HongtaoLaughmannEtAl2017
      "HongtaoLaughmannEtAl2017 - Function of pressures and rotational speed",
      Koerner2017
      "Koerner2017 - Function of pressure ratio",
      Engelpracht2017
      "Engelpracht2017 - Function of pressure ratio and rotational speed")
    "Enumeration to define polynomial models for calculating volumetric efficiency"
  type VolumetricPowerModels = enumeration(
      MendozaMirandaEtAl2016
      "MendozaMirandaEtAl2016 - Function of various properties")
    "Enumeration to define polynomial models for calculating volumetric efficiency"
  type HeatTransferModels = enumeration(
      Simplified
      "Calculation of heat transfer using simplified temperature difference")
    "Enumeration to define heat transfer models for calculations of heat losses"
  type SimpleCompressor = enumeration(
      Default
      "Default value used for partial compressor",
      RotaryCompressor
      "Simple rotary compressor",
      RotaryCompressorPressureLosses
      "Simple rotary compressor with pressure losses",
      RotaryCompressorPressureHeatLosses
      "Simple rotary compressor with pressure and heat losses")
    "Enumeration to define simple compressor model"
end Types;


within AixLib.Fluid.Movers.Compressors.Utilities;
package EngineEfficiency "Package that contains models describing different engine efficiencies"
  extends Modelica.Icons.Package;
end EngineEfficiency;


Based model used by all models describing engine efficiencies. This is a base model for overall engine efficiency models that are
  required for various compressor models. It defines some basic inputs
  and outputs that are commonly used by efficiency models and these
  inputs and outputs are summarised below:<br/>

within AixLib.Fluid.Movers.Compressors.Utilities.EngineEfficiency;
partial model PartialEngineEfficiency
  "Based model used by all models describing engine efficiencies"
  extends BaseClasses.PartialEfficiency;

  // Definition of parameters
  //
  parameter Boolean useIseWor = false
    "= true, if isentropic work is used to compute compressor's power
    consumption";

  // Definition of outputs
  //
  output Modelica.Units.SI.Efficiency etaEng(
    min=0,
    max=1,
    nominal=0.9) "Overall engine efficiency";
end PartialEngineEfficiency;


Model describing engine efficiency based on polynomial approach. This model contains a calculation procedure for engine efficiency
  models (for more information, please check out
  AixLib.Fluid.Movers.Compressors.BaseClasses.PartialCompression).
  The calculation procedures based on a polynomial approach are
  presented below.

within AixLib.Fluid.Movers.Compressors.Utilities.EngineEfficiency;
model PolynomialEngineEfficiency
  "Model describing engine efficiency based on polynomial approach"
  extends PartialEngineEfficiency;

  // Definition of parameters describing polynomial approaches in general
  //
  parameter Types.EnginePolynomialModels polyMod=Types.EnginePolynomialModels.DurprezEtAl2007
    "Chose predefined polynomial model for flow coefficient"
  parameter Real a[:]
    "Multiplication factors for each summand"
  parameter Real b[:]
    "Exponents for each summand"
  parameter Integer nT = size(a,1)
    "Number of terms used for the calculation procedure"

  // Definition of coefficients
  //
  Real p[nT]
    "Array that contains all coefficients used for the calculation procedure";
  Real corFac[2]
    "Array of correction factors used if efficiency model proposed in literature
    differs from efficiency model defined in PartialCompressor model";

equation
  // Calculation of coefficients
  //
  if (polyMod == Types.EnginePolynomialModels.JahningEtAl2000) then
    /*Polynomial approach presented by Jahning et al. (2000):
      etaEng = a1 + a2*exp(pInl)^b2
    */
    p[1] = 1
      "Dummy value for usage of simple coefficient";
    p[2] = exp(Medium.pressure(staInl))
      "Inlet pressure";

  elseif (polyMod == Types.EnginePolynomialModels.DurprezEtAl2007) then
    /*Polynomial approach presented by Durprez et al. (2007):
      etaEng = a1 + a2*piPre + a3*piPre^2 + a4*piPre^3 + a5*piPre^4 +
               a6*piPre^5 + a7*piPre^6
    */
    p[1] = 1
      "Dummy value for usage of simple coefficient";
    p[2] = piPre
      "Pressure ratio";
    p[3] = piPre^2
      "Quadratic pressure ratio";
    p[4] = piPre^3
      "Cubic pressure ratio";
    p[5] = piPre^4
      "Biquadratic pressure ratio";
    p[6] = piPre^5
      "Quintic pressure ratio";
    p[7] = piPre^6
      "Bicubic pressure ratio";

    corFac = {1,1}
      "No correction factors are needed";

  elseif (polyMod == Types.EnginePolynomialModels.KinarbEtAl2010) then
    /*Polynomial approach presented by Kinab et al. (2010):
      etaEng = a1 + a2*piPre + a3*piPre^2
    */
    p[1] = 1
      "Dummy value for usage of simple coefficient";
    p[2] = piPre
      "Pressure ratio";
    p[3] = piPre^3
      "Quadratic pressure ratio";

    corFac = {1,1}
      "No correction factors are needed";

  elseif (polyMod == Types.EnginePolynomialModels.Engelpracht2017) then
    /*Polynomial approach presented by Engelpracht (2017):
      etaEng = a1 + a2*piPre + a3*rotSpe + a4*piPre^2 +
               a5*rotSpe*piPre + a6*rotSpe^2 + a7*piPre^2*rotSpe +
               a8*piPre*rotSpe^2 + a9*rotSpe^3 + a10*rotSpe^2*piPre^2 +
               a11*rotSpe^3*piPre + a12*rotSpe^4
    */
    p[1] = 1
      "First coefficient";
    p[2] = piPre
      "Second coefficient";
    p[3] = rotSpe
      "Third coefficient";
    p[4] = piPre^2
      "Fourth coefficient";
    p[5] = rotSpe*piPre
      "Fifth coefficient";
    p[6] = rotSpe^2
      "Sixth coefficient";
    p[7] = piPre^2*rotSpe
      "Seventh coefficient";
    p[8] = piPre*rotSpe^2
      "Eighth coefficient";
    p[9] = rotSpe^3
      "Ninth coefficient";
    p[10] = rotSpe^2*piPre^2
      "Tenth coefficient";
    p[11] = rotSpe^3*piPre
      "Eleventh coefficient";
    p[12] = rotSpe^4
      "Twelfth coefficient";

    corFac = {1,1}
      "No correction factors are needed";

  else
    assert(false, "Invalid choice of polynomial approach");
  end if;

  // Calculationg of flow coefficient
  //
  etaEng = min(1, corFac[1] *
    sum(a[i]*p[i]^b[i] for i in 1:nT)^corFac[2])
    "Calculation procedure of generic polynomial";
end PolynomialEngineEfficiency;


Model describing flow engine efficiency on power approach. This model contains a calculation procedure for engine efficiency
  models (for more information, please check out
  AixLib.Fluid.Movers.Compressors.BaseClasses.PartialCompression).
  The calculation procedures based on a power approach are presented
  below.

within AixLib.Fluid.Movers.Compressors.Utilities.EngineEfficiency;
model PowerEngineEfficiency
  "Model describing flow engine efficiency on power approach"
  extends PartialEngineEfficiency;

  // Definition of parameters
  //
  parameter Types.EnginePowerModels powMod=Types.EnginePowerModels.MendozaMirandaEtAl2016
    "Chose predefined power model for flow coefficient"
  parameter Real a
    "Multiplication factor for generic power approach"
  parameter Real b[:]
    "Exponents for each multiplier"
  parameter Integer nT = size(b,1)
    "Number of terms used for the calculation procedure"

  // Definition of further parameters required for special approaches
  //
  parameter Modelica.Units.SI.MolarMass MRef=0.1 "Reference molar wheight"
  parameter Modelica.Units.SI.Frequency rotSpeRef=9.334
    "Reference rotational speed"

  // Definition of coefficients
  //
  Real p[nT]
    "Array that contains all coefficients used for the calculation procedure";
  Real corFac[2]
    "Array of correction factors used if efficiency model proposed in literature
    differs from efficiency model defined in PartialCompressor model";

equation
  // Calculation of coefficients
  //
  if (powMod == Types.EnginePowerModels.MendozaMirandaEtAl2016) then
    /*Power approach presented by Mendoza et al. (2016):
      etaEng = piPre^b1 * (rotSpeRef/rotSpe)^b2 * (1/((TInl+TOutISe)/2-TOut))^b3
               * (MRef/M)^b4

      Caution with parameters - Uses isentropic specific enthalpy difference
    */
    p[1] = piPre
      "Pressure ratio";
    p[2] = rotSpeRef/rotSpe
      "Rotational Speed";
    p[3] = 1/((Medium.temperature(staInl)+Medium.temperature(
      Medium.setState_psX(s=Medium.specificEntropy(staInl),
      p=Medium.pressure(staOut))))/2-TAmb)
      "Temperature difference isentropic compression and ambient";
    p[4] = MRef/Medium.fluidConstants[1].molarMass
      "Molar Mass";

    corFac = {1,1}
      "No correction factors are needed";

  else
    assert(false, "Invalid choice of power approach");
  end if;

  // Calculationg of flow coefficient
  //
  etaEng = min(1, corFac[1] * a *
    product(abs(p[i])^b[i] for i in 1:nT)^corFac[2])
    "Calculation procedure of generic power approach";
end PowerEngineEfficiency;


Reciporating/Rotary/Scroll Compressor - R134a, R450a, R1234yf, R1234ze(e) - Similitude - Power. This model contains a calculation procedure for the engine efficiency
  presented by Mendoza-Miranda et al. (2016).<br/>

within AixLib.Fluid.Movers.Compressors.Utilities.EngineEfficiency.SpecifiedEfficiencies;
model Buck_R134aR450aR1234yfR1234zee_VarDisVol_ReciprocatingRotaryScroll
  "Reciporating/Rotary/Scroll Compressor - R134a, R450a, R1234yf, R1234ze(e) - Similitude - Power"
  extends PowerEngineEfficiency(
    final useIseWor=true,
    final MRef=0.102032,
    final rotSpeRef=9.334,
    final powMod=Types.EnginePowerModels.MendozaMirandaEtAl2016,
    final a=1,
    final b={-0.1642,0.2050,0.0659,07669});
end Buck_R134aR450aR1234yfR1234zee_VarDisVol_ReciprocatingRotaryScroll;


General model that describes a constant overall engine efficiency. This model contains a simple calculation procedure for engine
  efficiency models (for more information, please check out
  AixLib.Fluid.Movers.Compressors.BaseClasses.PartialCompression).
  The model provides a constant overall engine efficiency and is the
  most basic engine efficiency model.

within AixLib.Fluid.Movers.Compressors.Utilities.EngineEfficiency.SpecifiedEfficiencies;
model ConstantEfficiency
  "General model that describes a constant overall engine efficiency"
  extends PartialEngineEfficiency(
    final useIseWor=false);

  // Definition of parameters
  //
  parameter Modelica.Units.SI.Efficiency etaEngCon=0.9
    "Constant overall engine efficiency";

equation
  // Calculate overall engine efficiency
  //
  etaEng = etaEngCon "Allocation of constant overall engine efficiency";
end ConstantEfficiency;


Generic overall engine efficiency based on literature review for
  various compressors. This model contains a calculation procedure for the engine efficiency
  presented by Engelpracht (2017). However, this approach is just
  fitted to various experimental data obtained by a literature review
  and, therefore, to use with caution.<br/>

within AixLib.Fluid.Movers.Compressors.Utilities.EngineEfficiency.SpecifiedEfficiencies;
model Generic_VarRef_VarDisVol_RotaryScroll "Generic overall engine efficiency based on literature review for
  various compressors"
  extends PolynomialEngineEfficiency(
    final useIseWor=false,
    final polyMod=Types.EnginePolynomialModels.Engelpracht2017,
    final a={0.2199,-0.0193,0.02503,-0.001345,8.817e-5,-0.0003382,1.584e-5,
             -1.083e-6,1.976e-6,-5.321e-8,4.053e-9,-4.329e-9},
    final b={1,1,1,1,1,1,1,1,1,1,1,1});
end Generic_VarRef_VarDisVol_RotaryScroll;


within AixLib.Fluid.Movers.Compressors.Utilities.EngineEfficiency;
package SpecifiedEfficiencies "Package that engine efficiencies that are specifiied"
extends Modelica.Icons.VariantsPackage;
end SpecifiedEfficiencies;


within AixLib.Fluid.Movers.Compressors.Utilities;
package HeatTransfer "Package that contains models to compute heat transfers"
  extends Modelica.Icons.Package;
end HeatTransfer;


Model of a simple fictitious wall to compute compressor's heat losses. This is a model of a fictitious wall that describes the shell of the
  compressor. It consists of four heat ports, i.e. for the inlet and
  outlet of the compressor as well as for the ambient and compression
  chamber. It is assumed that the wall consists of a time invariante
  heat capacity; additionally, it is assumed that the thermal
  conductance for the calculation of the heat flow between ambient and
  fictitious wall is also time invariante.

within AixLib.Fluid.Movers.Compressors.Utilities.HeatTransfer;
model SimpleFictitiousWall
  "Model of a simple fictitious wall to compute compressor's heat losses"

  // Definition of parameters describing the fictitious wall
  //
  parameter Modelica.Units.SI.Mass mWal=2.5 "Mass of the fictitious wall"
  parameter Modelica.Units.SI.SpecificHeatCapacity cpWal=450
    "Specific heat capacity of the fictitious wall"
  parameter Modelica.Units.SI.ThermalConductance kAMeaAmb=10 "Effective mean thermal conductance coefficient between fictitious wall
    and ambient"

  // Definition of parameters describing advanced options
  //
  parameter Boolean iniTWal0 = true
    "= true, if wall is initialised at fixed temperature; Otherwise, steady state
    initialisation"
  parameter Modelica.Units.SI.Temperature TWal0=343.15
    "Temperature of wall at initialisation"

  // Definition of submodels and connectors
  //
  Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a heaPorComInl
    "Heart port for compressor's inlet"
  Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a heaPorCom
    "Heart port for compresso's engine (compression chamber)"
  Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a heaPorComOut
    "Heart port for compressor's outlet"
  Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b heaPorAmb
    "Heart port for ambient"

  // Definition of parameters
  //
  Modelica.Units.SI.Temperature TWal "Temperature of fictitious wall";

protected
  Modelica.Units.SI.Power Q_flow_amb
    "Heat flow between ambient and fictitious wall";

initial equation
  if iniTWal0 then
    TWal=TWal0;
  else
    der(TWal)=0;
  end if;

equation
  // Calculation of energy balance
  //
  mWal*cpWal*der(TWal) = heaPorComInl.Q_flow + heaPorCom.Q_flow +
    heaPorComOut.Q_flow - Q_flow_amb
    "Energy balance of fictitious wall";
  heaPorComInl.T = TWal "Connect temperature with heat port";
  heaPorCom.T = heaPorAmb.T "Connect temperature with heat port";
  heaPorComOut.T = TWal "Connect temperature with heat port";

  // Calculation of heat flow between ambient and fictious wall
  //
  Q_flow_amb =kAMeaAmb*(TWal - heaPorAmb.T) "Calculation of heat flow";
  heaPorAmb.Q_flow = -Q_flow_amb "Connect heat flow with heat port";

  /*It is assumed that the heat flow flows out of the system*/
end SimpleFictitiousWall;


within AixLib.Fluid.Movers.Compressors.Utilities.HeatTransfer;
model SimpleHeatTransfer
  "Model of a simple 1-dimensional heat transfer for compressor's
  inlet and outlet"

  // Definition of parameters describing heat transfer
  //
  parameter Types.HeatTransferModels heaTraMod=
    Types.HeatTransferModels.Simplified
    "Choose heat transfer model"
  parameter Modelica.Units.SI.ThermalConductance kAMea=25
    "Effective mean thermal conductance between medium and fictitious wall"

  // Extensions and parameter propagation
  //
  extends AixLib.Fluid.Interfaces.PartialTwoPortTransport(
    redeclare replaceable package Medium=Modelica.Media.R134a.R134a_ph,
    final dp_start=0,
    m_flow_start=0.5*m_flow_nominal,
    m_flow_small=1e-6*m_flow_nominal,
    show_T=false,
    show_V_flow=false);

  // Definition of parameters describing advanced options
  //
  parameter Modelica.Units.SI.MassFlowRate m_flow_nominal=0.1
    "Nominal mass flow rate"

  // Definition of submodels and connectors
  //
  Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b heatPort
    "Heat port to calculate heat losses"

protected
  Medium.ThermodynamicState staInl
    "Thermodynamic state at inlet";
  Medium.ThermodynamicState staOut
    "Thermodynamic state at outlet";

  Modelica.Units.SI.TemperatureDifference effTemDif
    "Effective temperature difference between medium and wall";
  Modelica.Units.SI.Power Q_flow
    "Heat flow exchanged between medium and heat port";

equation
  // Calculation of thermodynamic states
  //
  staInl = Medium.setState_phX(p=port_a.p, h=actualStream(port_a.h_outflow))
    "Thermodynamic state at inlet";
  staOut = Medium.setState_phX(p=port_b.p, h=actualStream(port_b.h_outflow))
    "Thermodynamic state at outlet";

  // Calculation of heat flow
  //
  if heaTraMod == Types.HeatTransferModels.Simplified then
    effTemDif = (Medium.temperature(staOut)+Medium.temperature(staInl))/2-
      heatPort.T
      "Effective temperature difference between medium and fictitious wall";
    Q_flow = kAMea*effTemDif "Simplified calculation of heat transfer";

    /*It is assumed that the heat flow flows out of the system and, thus, a
      heat flow flowing out of the system has a positive algebraic sign.
    */
  else
    assert(false, "Invalid choice of heat transfer model");
  end if;

  // Calculation of boundary conditions
  //
  port_a.h_outflow = inStream(port_b.h_outflow)-Q_flow/port_a.m_flow
    "Heat exchange with fictitious wall";
  port_b.h_outflow = inStream(port_a.h_outflow)-Q_flow/port_a.m_flow
    "Heat exchange with fictitious wall";
  dp = 0 "Assuming no pressure loss";

  heatPort.Q_flow = -Q_flow "Connect heat flow with heat port";
end SimpleHeatTransfer;


within AixLib.Fluid.Movers.Compressors.Utilities;
package IsentropicEfficiency "Package that contains models describing different isentropic efficiencies"
  extends Modelica.Icons.Package;
end IsentropicEfficiency;


Based model used by all models describing isentropic efficiencies. This is a base model for overall isentropic efficiency models that
  are required for various compressor models. It defines some basic
  inputs and outputs that are commonly used by efficiency models and
  these inputs and outputs are summarised below:<br/>

within AixLib.Fluid.Movers.Compressors.Utilities.IsentropicEfficiency;
partial model PartialIsentropicEfficiency
  "Based model used by all models describing isentropic efficiencies"
  extends BaseClasses.PartialEfficiency;

  // Definition of outputs
  //
  output Modelica.Units.SI.Efficiency etaIse(
    min=0,
    max=1,
    nominal=0.9) "Overall isentropic efficiency";
end PartialIsentropicEfficiency;


Model describing isentropic efficiency based on polynomial approach. This model contains a calculation procedure for isentropic efficiency
  models (for more information, please check out
  AixLib.Fluid.Movers.Compressors.BaseClasses.PartialCompression).
  The calculation procedures based on a polynomial approach are
  presented below.

within AixLib.Fluid.Movers.Compressors.Utilities.IsentropicEfficiency;
model PolynomialIsentropicEfficiency
  "Model describing isentropic efficiency based on polynomial approach"
  extends PartialIsentropicEfficiency;

  // Definition of parameters describing polynomial approaches in general
  //
  parameter Types.IsentropicPolynomialModels polyMod=Types.IsentropicPolynomialModels.Karlsson2007
    "Chose predefined polynomial model for flow coefficient"
  parameter Real a[:]
    "Multiplication factors for each summand"
  parameter Real b[:]
    "Exponents for each summand"
  parameter Integer nT = size(a,1)
    "Number of terms used for the calculation procedure"

  // Definition of parameters describing specific approaches
  //
  parameter Real c[:] = {1}
    "Coefficients used for correction factors if needed"
  parameter Modelica.Units.SI.Frequency rotSpeRef=9.334
    "Reference rotational speed"

  // Definition of coefficients
  //
  Real p[nT]
    "Array that contains all coefficients used for the calculation procedure";
  Real corFac[2]
    "Array of correction factors used if efficiency model proposed in literature
    differs from efficiency model defined in PartialCompressor model";

equation
  // Calculation of coefficients
  //
  if (polyMod == Types.IsentropicPolynomialModels.DarrAndCrawford1992) then
    /*Polynomial approach presented by Dar and Crawford (1992):
      etaIse = a1 + a2*rotSpe +a3/dInl

      Caution with units - In the following, none S.I units are presented:
      Density:           in lb/ft^3
      Rotational Speed:  in rpm
      Volume flow:       in ft^3/min
    */
    p[1] = 1
      "Dummy value for usage of simple coefficcient";
    p[2] = rotSpe*60
      "Rotational speed";
    p[3] = 1/(Medium.density(staInl)*0.3048^3/0.453592)
      "Effect of clearance";

    corFac = {1,1}
      "No correction factors are needed";

  elseif (polyMod == Types.IsentropicPolynomialModels.Karlsson2007) then
    /*Polynomial approach presented by Karlsson (2007):
      etaIse = a1 + a2*piPre + a3*piPre^2 + a4*rotSpe + a5*rotSpe^2

      Caution with units - In the following, none S.I units are presented:
      Pressure:            in bar
    */
    p[1] = 1
      "Usage of dummy value for simple coefficient";
    p[2] = piPre
      "Pressure ratio";
    p[3] = piPre^2
      "Quadratic pressure ratio";
    p[4] = rotSpe
      "Rotational speed";
    p[5] = rotSpe^2
      "Quadratic rotational speed";

    corFac = {1,1}
      "No correction factors are needed";

  elseif (polyMod == Types.IsentropicPolynomialModels.Engelpracht2017) then
    /*Polynomial approach presented by Engelpracht (2017):
      etaIse = a1 + a2*rotSpe + a3*rotSpe^3 + piPre*y^2
    */
    p[1] = 1
      "Dummy value for usage of simple coefficient";
    p[2] = rotSpe
      "Rotational speed";
    p[3] = rotSpe^3
      "Cubic rotational speed";
    p[4] = piPre^2
      "Quadratic pressure ratio";

    corFac = {1,1}
      "No correction factors are needed";

  else
    assert(false, "Invalid choice of polynomial approach");
  end if;

  // Calculationg of flow coefficient
  //
  etaIse = min(1, corFac[1] *
    sum(a[i]*p[i]^b[i] for i in 1:nT)^corFac[2])
    "Calculation procedure of general polynomial";
end PolynomialIsentropicEfficiency;


Model describing flow isentropic efficiency on power approach. This model contains a calculation procedure for isentropic efficiency
  models (for more information, please check out
  AixLib.Fluid.Movers.Compressors.BaseClasses.PartialCompression).
  The calculation procedures based on a power approach are presented
  below.

within AixLib.Fluid.Movers.Compressors.Utilities.IsentropicEfficiency;
model PowerIsentropicEfficiency
  "Model describing flow isentropic efficiency on power approach"
  extends PartialIsentropicEfficiency;

  // Definition of parameters
  //
  parameter Types.IsentropicPowerModels powMod=Types.IsentropicPowerModels.MendozaMirandaEtAl2016
    "Chose predefined power model for flow coefficient"
  parameter Real a
    "Multiplication factor for generic power approach"
  parameter Real b[:]
    "Exponents for each multiplier"
  parameter Integer nT = size(b,1)
    "Number of terms used for the calculation procedure"

  // Definition of further parameters required for special approaches
  //
  parameter Modelica.Units.SI.MolarMass MRef=0.1 "Reference molar wheight"
  parameter Modelica.Units.SI.Frequency rotSpeRef=9.334
    "Reference rotational speed"

  // Definition of coefficients
  //
  Real p[nT]
    "Array that contains all coefficients used for the calculation procedure";
  Real corFac[2]
    "Array of correction factors used if efficiency model proposed in literature
    differs from efficiency model defined in PartialCompressor model";

equation
  // Calculation of coefficients
  //
  if (powMod == Types.IsentropicPowerModels.MendozaMirandaEtAl2016) then
    /*Power approach presented by Mendoza et al. (2016):
      etaIse = piPre^b1 * (rotSpeRef/rotSpe)^b2 * (rotSpe^3*VDis/dhISe^1.5)^b3
               * (1/((TInl+TOutISe)/2-TOut))^b4
    */
    p[1] = piPre
      "Pressure ratio";
    p[2] = rotSpeRef/rotSpe
      "Rotational Speed";
    p[3] = rotSpe^3*VDis/(Medium.specificEnthalpy(Medium.setState_psX(s=
      Medium.specificEntropy(staInl),p=Medium.pressure(staOut))))^1.5
      "Isentropic specific enthalpy difference";
    p[4] = MRef/Medium.fluidConstants[1].molarMass
      "Molar Mass";

    corFac = {1,1}
      "No correction factors are needed";

  else
    assert(false, "Invalid choice of power approach");
  end if;

  // Calculationg of flow coefficient
  //
  etaIse = min(1, corFac[1] * a *
    product(p[i]^b[i] for i in 1:nT)^corFac[2])
    "Calculation procedure of generic power approach";
end PowerIsentropicEfficiency;


Reciporating Compressor - R134a, R450a, R1234yf, R1234ze(e) - Similitude - Power. This model contains a calculation procedure for the isentropic
  efficiency presented by Mendoza-Miranda et al. (2016).<br/>

within AixLib.Fluid.Movers.Compressors.Utilities.IsentropicEfficiency.SpecifiedEfficiencies;
model Buck_R134aR450aR1234yfR1234zee_VarDisVol_Reciprocating
  "Reciporating Compressor - R134a, R450a, R1234yf, R1234ze(e) - Similitude - Power"
  extends PowerIsentropicEfficiency(
    final MRef=0.102032,
    final rotSpeRef=9.334,
    final powMod=Types.IsentropicPowerModels.MendozaMirandaEtAl2016,
    final a=1,
    final b={0.0753,0.2183,0.0015,0.0972});
end Buck_R134aR450aR1234yfR1234zee_VarDisVol_Reciprocating;


Rotary Compressor - R134a, R450a, R1234yf, R1234ze(e) - Similitude - Power. This model contains a calculation procedure for the isentropic
  efficiency presented by Mendoza-Miranda et al. (2016).<br/>

within AixLib.Fluid.Movers.Compressors.Utilities.IsentropicEfficiency.SpecifiedEfficiencies;
model Buck_R134aR450aR1234yfR1234zee_VarDisVol_Rotary
  "Rotary Compressor - R134a, R450a, R1234yf, R1234ze(e) - Similitude - Power"
  extends PowerIsentropicEfficiency(
    final MRef=0.102032,
    final rotSpeRef=9.334,
    final powMod=Types.IsentropicPowerModels.MendozaMirandaEtAl2016,
    final a=0.85,
    final b={0.0753,0.2183,0.0015,0.0972});
end Buck_R134aR450aR1234yfR1234zee_VarDisVol_Rotary;


Scroll Compressor - R134a, R450a, R1234yf, R1234ze(e) - Similutude - Power. This model contains a calculation procedure for the isentropic
  efficiency presented by Mendoza-Miranda et al. (2016).<br/>

within AixLib.Fluid.Movers.Compressors.Utilities.IsentropicEfficiency.SpecifiedEfficiencies;
model Buck_R134aR450aR1234yfR1234zee_VarDisVol_Scroll
  "Scroll Compressor - R134a, R450a, R1234yf, R1234ze(e) - Similutude - Power"
  extends PowerIsentropicEfficiency(
    final MRef=0.102032,
    final rotSpeRef=9.334,
    final powMod=Types.IsentropicPowerModels.MendozaMirandaEtAl2016,
    final a=1,
    final b={0.0753,0.2183,0.0015,0.0972});
end Buck_R134aR450aR1234yfR1234zee_VarDisVol_Scroll;


General model that describes a constant overall isentropic efficiency. This model contains a simple calculation procedure for isentropic
  efficiency models (for more information, please check out
  AixLib.Fluid.Movers.Compressors.BaseClasses.PartialCompression).
  The model provides a constant overall isentropic efficiency and is
  the most basic engine efficiency model.

within AixLib.Fluid.Movers.Compressors.Utilities.IsentropicEfficiency.SpecifiedEfficiencies;
model ConstantEfficiency
  "General model that describes a constant overall isentropic efficiency"
  extends PartialIsentropicEfficiency;

  // Definition of parameters
  //
  parameter Modelica.Units.SI.Efficiency etaIseCon=0.9
    "Constant overall isentropic efficiency";

equation
  // Calculate overall isentropic efficiency
  //
  etaIse = etaIseCon "Allocation of constant overall isentropic efficiency";
end ConstantEfficiency;


Generic overall isentropic efficiency based on literature review for
  various compressors. This model contains a calculation procedure for the isentropic
  efficiency presented by Engelpracht (2017). However, this approach is
  just fitted to various experimental data obtained by a literature
  review and, therefore, to use with caution.<br/>

within AixLib.Fluid.Movers.Compressors.Utilities.IsentropicEfficiency.SpecifiedEfficiencies;
model Generic_VarRef_VarDisVol_RotaryScroll
  "Generic overall isentropic efficiency based on literature review for
  various compressors"
  extends PolynomialIsentropicEfficiency(
    final polyMod=Types.IsentropicPolynomialModels.Engelpracht2017,
    final a={0.5816, 0.002604,-1.515e-7,-0.00473},
    final b={1,1,1,1});
end Generic_VarRef_VarDisVol_RotaryScroll;


within AixLib.Fluid.Movers.Compressors.Utilities.IsentropicEfficiency;
package SpecifiedEfficiencies "Package that engine efficiencies that are specifiied"
  extends Modelica.Icons.VariantsPackage;
end SpecifiedEfficiencies;


Reciporating Compressor - R134a - 169 cm³ - Polynomial. This model contains a calculation procedure for the isentropic
  efficiency presented by Darr and Crawford (1992).<br/>

within AixLib.Fluid.Movers.Compressors.Utilities.IsentropicEfficiency.SpecifiedEfficiencies;
model Poly_R134a_169_Reciprocating
  "Reciporating Compressor - R134a - 169 cm³ - Polynomial"
  extends PolynomialIsentropicEfficiency(
    final polyMod=Types.IsentropicPolynomialModels.DarrAndCrawford1992,
    final a={0.8405,-4.8711*1e-5,-0.1105},
    final b={1,1,1});
end Poly_R134a_169_Reciprocating;


Scroll Compressor - R407C - Unknown displacement volume - Polynomial. This model contains a calculation procedure for the isentropic
  efficiency presented by Karlsson (2007).<br/>

within AixLib.Fluid.Movers.Compressors.Utilities.IsentropicEfficiency.SpecifiedEfficiencies;
model Poly_R407C_Unknown_Scroll
  "Scroll Compressor - R407C - Unknown displacement volume - Polynomial"
  extends PolynomialIsentropicEfficiency(
    final polyMod=Types.IsentropicPolynomialModels.Karlsson2007,
    final a={0.926,-0.0823,0.00352,0.00294,-0.000022},
    final b={1,1,1,1,1});
end Poly_R407C_Unknown_Scroll;


within AixLib.Fluid.Movers.Compressors.Utilities;
package VolumetricEfficiency "Package that contains models describing different volumetric efficiencies"
  extends Modelica.Icons.Package;
end VolumetricEfficiency;


Based model used by all models describing volumetric efficiencies. This is a base model for overall volumetric efficiency models that
  are required for various compressor models. It defines some basic
  inputs and outputs that are commonly used by efficiency models and
  these inputs and outputs are summarised below:<br/>

within AixLib.Fluid.Movers.Compressors.Utilities.VolumetricEfficiency;
partial model PartialVolumetricEfficiency
  "Based model used by all models describing volumetric efficiencies"
  extends BaseClasses.PartialEfficiency;

  // Definition of outputs
  //
  output Modelica.Units.SI.Efficiency lamH(
    min=0,
    max=1,
    nominal=0.9) "Overall volumetric efficiency";
end PartialVolumetricEfficiency;


Model describing volumetric efficiency based on polynomial approach. This model contains a calculation procedure for volumetric efficiency
  models (for more information, please check out
  AixLib.Fluid.Movers.Compressors.BaseClasses.PartialCompression).
  The calculation procedures based on a polynomial approach are
  presented below.

within AixLib.Fluid.Movers.Compressors.Utilities.VolumetricEfficiency;
model PolynomialVolumetricEfficiency
  "Model describing volumetric efficiency based on polynomial approach"
  extends PartialVolumetricEfficiency;

  // Definition of parameters describing polynomial approaches in general
  //
  parameter Types.VolumetricPolynomialModels polyMod=Types.VolumetricPolynomialModels.Karlsson2007
    "Chose predefined polynomial model for flow coefficient"
  parameter Real a[:]
    "Multiplication factors for each summand"
  parameter Real b[:]
    "Exponents for each summand"
  parameter Integer nT = size(a,1)
    "Number of terms used for the calculation procedure"

  // Definition of parameters describing specific approaches
  //
  parameter Real c[:] = {1}
    "Coefficients used for correction factors if needed"
  parameter Modelica.Units.SI.Frequency rotSpeRef=9.334
    "Reference rotational speed"

  // Definition of coefficients
  //
  Real p[nT]
    "Array that contains all coefficients used for the calculation procedure";
  Real corFac[2]
    "Array of correction factors used if efficiency model proposed in literature
    differs from efficiency model defined in PartialCompressor model";

equation
  // Calculation of coefficients
  //
  if (polyMod == Types.VolumetricPolynomialModels.DarrAndCrawford1992) then
    /*Polynomial approach presented by Dar and Crawford (1992):
      lamH = a1 + a2*rotSpe - a3*epsRef*(dInlIse/dInl-1) -
      a4*rotSpe*(dInlIse/dInl-1)

      Caution with units - In the following, none S.I units are presented:
      Density:           in lb/ft^3
      Rotational Speed:  in rpm
      Volume flow:       in ft^3/min
    */
    p[1] = 1
      "Dummy value for usage of simple coefficcient";
    p[2] = rotSpe*60
      "Rotational speed";
    p[3] = -(epsRef)*(Medium.density(Medium.setState_psX(s=
      Medium.specificEntropy(staInl),p=Medium.pressure(staOut)))/
      Medium.density(staInl)-1)
      "Effect of clearance";
    p[4] = -rotSpe*60*(Medium.density(Medium.setState_psX(s=
      Medium.specificEntropy(staInl),p=Medium.pressure(staOut)))/
      Medium.density(staInl)-1)
      "Effect of clearance";

    corFac = {1,1}
      "No correction factors are needed";

  elseif (polyMod == Types.VolumetricPolynomialModels.Karlsson2007) then
    /*Polynomial approach presented by Karlsson (2007):
      lamH = a1*TInl*piPre + a2*piPre + a3 + a4*TInl + a5*rotSpe + a6*rotSpe^2

      Caution with units - In the following, none S.I units are presented:
      Temperature:         in °C
    */
    p[1] = (Medium.temperature(staInl)-273.15)*piPre
      "Inlet temperature times pressure ratio";
    p[2] = piPre
      "Pressure ratio";
    p[3] = 1
      "Dummy value for usage of simple coefficcient";
    p[4] = (Medium.temperature(staInl)-273.15)
      "Inlet temperature";
    p[5] = rotSpe
      "Rotational speed";
    p[6] = rotSpe^2
      "Quadratic rotational speed";

    corFac = {1,1}
      "No correction factors are needed";

  elseif (polyMod == Types.VolumetricPolynomialModels.KinarbEtAl2010) then
    /*Polynomial approach presented by Kinab et al. (2010):
      etaEng = a1 + a2*piPre
    */
    p[1] = 1
      "Dummy value for usage of simple coefficient";
    p[2] = piPre
      "Pressure ratio";

    corFac = {1,1}
      "No correction factors are needed";

  elseif (polyMod == Types.VolumetricPolynomialModels.ZhouEtAl2010) then
    /*Polynomial approach presented by Zhou et al. (2010):
    etaEng = 1 + a1 - a2*piPre^(1/kapMean)
    */
    p[1] = 1
      "Dummy value for usage of simple coefficient";
    p[2] = 1
      "Dummy value for usage of simple coefficient";
    p[3] = -piPre^(2/(Medium.isentropicExponent(staInl)+
      Medium.isentropicExponent(staOut)))
      "Pressure ratio";

    corFac = {1,1}
      "No correction factors are needed";

  elseif (polyMod == Types.VolumetricPolynomialModels.Li2013) then
    /*Polynomial approach presented by Li (2013):
      lamH = lamHRef * (a1 + a2*(rotSpe/rotSpeRef) + a3*(rotSpe/rotSpeRef)^2)
        with  lamHRef = c1 + c2*((pOut/(pInl*(1-c3))^(1/kapMea))

      Caution with units - In the following, none S.I units are presented:
      Pressure:            in kPa
      Temperature:         in °C
      Specific enthalpy:   in kJ/kg
      Rotational speed:    in rpm
    */
    p[1] = 1
      "Dummy value for usage of simple coefficient";
    p[2] = (rotSpe/rotSpeRef)
      "Rotational speed";
    p[3] = (rotSpe/rotSpeRef)^2
      "Quadratic rotational speed";

    corFac[1] = c[1] + c[2]*((Medium.pressure(staOut)/(Medium.pressure(staInl)*
      (1-c[3]*1e-3)))^(2/(Medium.isentropicExponent(staInl)+
      Medium.isentropicExponent(staOut))))
      "Reference volumetric efficiency";
    corFac[2] = 1
      "No correction factor is needed";

  elseif (polyMod == Types.VolumetricPolynomialModels.HongtaoLaughmannEtAl2017) then
    /*Polynomial approach presented by Hongtao et al. (2013):
      lamH = a1 + a2*omega + a3*omega^2 +
             a4*piPre + a5*omega*piPre + a6*omega^2*piPre +
             a7*piPre^2 + a8*omega*piPre^2 + a9*omega^2*piPre^2 +
             a10*pOut + a11*omega*pOut + a12*omega^2*pOut -
             a13*pInl - a14*omega*pInl - a15*omega^2*pInl +
             a16*pInl*pOut + a17*omega*pInl*pOut + a18*omega^2*pInl*pOut +
             a19*omega^3*pInl*pOut + a20*omega^4*pInl*pOut -
             a21*pInl^2 - a22*omega*pInl^2 - a23*omega^2*pInl^2 -
             a24*omega^3*pInl^2 - a25*omega^4*pInl^2

      with omega = rotSpe/rotSpeRef
    */
    p[1] = 1
      "First coefficient";
    p[2] = (rotSpe/rotSpeRef)
      "Second coefficient";
    p[3] = (rotSpe/rotSpeRef)^2
      "Third coefficient";
    p[4] = piPre
      "Fourth coefficient";
    p[5] = piPre*(rotSpe/rotSpeRef)
      "Fifth coefficient";
    p[6] = piPre*(rotSpe/rotSpeRef)^2
      "Sixth coefficient";
    p[7] = piPre^2
      "Seventh coefficient";
    p[8] = piPre^2*(rotSpe/rotSpeRef)
      "Eighth coefficient";
    p[9] = piPre^2*(rotSpe/rotSpeRef)^2
      "Ninth coefficient";
    p[10] = Medium.pressure(staOut)
      "Tenth coefficient";
    p[11] = Medium.pressure(staOut)*(rotSpe/rotSpeRef)
      "Eleventh coefficient";
    p[12] = Medium.pressure(staOut)*(rotSpe/rotSpeRef)^2
      "Twelfth coefficient";
    p[13] = -Medium.pressure(staInl)
      "Thirteenth coefficient";
    p[14] = -Medium.pressure(staInl)*(rotSpe/rotSpeRef)
      "Fourteenth coefficient";
    p[15] = -Medium.pressure(staInl)*(rotSpe/rotSpeRef)^2
      "Fifteenth coefficient";
    p[16] = Medium.pressure(staInl)*Medium.pressure(staOut)
      "Sixteenth coefficient";
    p[17] = Medium.pressure(staInl)*Medium.pressure(staOut)*(rotSpe/rotSpeRef)
      "Seventeenth coefficient";
    p[18] = Medium.pressure(staInl)*Medium.pressure(staOut)*(rotSpe/rotSpeRef)^2
      "Eighteenth coefficient";
    p[19] = Medium.pressure(staInl)*Medium.pressure(staOut)*(rotSpe/rotSpeRef)^3
      "Nineteenth coefficient";
    p[20] = Medium.pressure(staInl)*Medium.pressure(staOut)*(rotSpe/rotSpeRef)^4
      "Twentieth coefficient";
    p[21] = -Medium.pressure(staInl)^2
      "Twenty-first coefficient";
    p[22] = -Medium.pressure(staInl)^2*(rotSpe/rotSpeRef)^2
      "Twenty-second coefficient";
    p[23] = -Medium.pressure(staInl)^2*(rotSpe/rotSpeRef)^3
      "Twenty-third coefficient";
    p[24] = -Medium.pressure(staInl)^2*(rotSpe/rotSpeRef)^4
      "Twenty-fourth coefficient";
    p[25] = -Medium.pressure(staInl)^2*(rotSpe/rotSpeRef)^5
      "Twenty-fifth coefficient";

    corFac = {1,1}
      "No correction factors are needed";

  elseif (polyMod == Types.VolumetricPolynomialModels.Koerner2017) then
    /*Polynomial approach presented by Körner et al.(2017):
      lamH = a1*piPre^b1
    */
    p[1] = piPre
      "Pressure ratio";

    corFac = {1,1}
      "No correction factors are needed";

  elseif (polyMod == Types.VolumetricPolynomialModels.Engelpracht2017) then
    /*Polynomial approach presented by Engelpracht (2017):
      lamH = a1 + a2*((piPre-c1)/c2) + a3*((TInl-c3)/c4)*((piPre-c1)/c2) +
             a4*((TInl-c3)/c4) + a5*((rotSpe-c5)/c6) + a6*((rotSpe-c5)/c6)^2
    */
    p[1] = 1
      "Dummy value for usage of simple coefficient";
    p[2] = ((piPre-c[1])/c[2])
      "Pressure ratio";
    p[3] = ((Medium.temperature(staInl)-c[3])/c[4])*((piPre-c[1])/c[2])
      "Pressure ratio times inlet temperature";
    p[4] = ((Medium.temperature(staInl)-c[3])/c[4])
      "Inlet temperature";
    p[5] = ((rotSpe-c[5])/c[6])
      "Rotational speed";
    p[6] = ((rotSpe-c[5])/c[6])^2
      "Quadratic rotational speed";

    corFac = {1,1}
      "No correction factors are needed";

  else
    assert(false, "Invalid choice of polynomial approach");
  end if;

  // Calculationg of flow coefficient
  //
  lamH = min(1, corFac[1] *
    sum(a[i]*p[i]^b[i] for i in 1:nT)^corFac[2])
    "Calculation procedure of general polynomial";
end PolynomialVolumetricEfficiency;


Model describing flow volumetric efficiency on power approach. This model contains a calculation procedure for volumetric efficiency
  models (for more information, please check out
  AixLib.Fluid.Movers.Compressors.BaseClasses.PartialCompression).
  The calculation procedures based on a power approach are presented
  below.

within AixLib.Fluid.Movers.Compressors.Utilities.VolumetricEfficiency;
model PowerVolumetricEfficiency
  "Model describing flow volumetric efficiency on power approach"
  extends PartialVolumetricEfficiency;

  // Definition of parameters
  //
  parameter Types.VolumetricPowerModels powMod=Types.VolumetricPowerModels.MendozaMirandaEtAl2016
    "Chose predefined power model for flow coefficient"
  parameter Real a
    "Multiplication factor for generic power approach"
  parameter Real b[:]
    "Exponents for each multiplier"
  parameter Integer nT = size(b,1)
    "Number of terms used for the calculation procedure"

  // Definition of further parameters required for special approaches
  //
  parameter Modelica.Units.SI.MolarMass MRef=0.1 "Reference molar wheight"
  parameter Modelica.Units.SI.Frequency rotSpeRef=9.334
    "Reference rotational speed"

  // Definition of coefficients
  //
  Real p[nT]
    "Array that contains all coefficients used for the calculation procedure";
  Real corFac[2]
    "Array of correction factors used if efficiency model proposed in literature
    differs from efficiency model defined in PartialCompressor model";

equation
  // Calculation of coefficients
  //
  if (powMod == Types.VolumetricPowerModels.MendozaMirandaEtAl2016) then
    /*Power approach presented by Mendoza et al. (2005):
      lamH = piPre^b1 * (piPre^1.5*rotSpe^3*VDis)^b2 * (MRef/M)^b3
    */
    p[1] = piPre
      "Pressure ratio";
    p[2] = piPre^1.5*rotSpe^3*VDis
      "Rotational Speed";
    p[3] = MRef/Medium.fluidConstants[1].molarMass
      "Molar Mass";

    corFac = {1,1}
      "No correction factors are needed";

  else
    assert(false, "Invalid choice of power approach");
  end if;

  // Calculationg of flow coefficient
  //
  lamH = min(1, corFac[1] * a *
    product(abs(p[i])^b[i] for i in 1:nT)^corFac[2])
    "Calculation procedure of generic power approach";
end PowerVolumetricEfficiency;


within AixLib.Fluid.Movers.Compressors.Utilities.VolumetricEfficiency.SpecifiedEfficiencies;
model Buck_R134aR450aR1234yfR1234zee_VarDisVol_Reciprocating
  "Reciporating Compressor - R134a, R450a, R1234yf, R1234ze(e) - Similitude - Power"
  extends PowerVolumetricEfficiency(
    final MRef=0.102032,
    final rotSpeRef=9.334,
    final powMod=Types.VolumetricPowerModels.MendozaMirandaEtAl2016,
    final a=1,
    final b={-0.2678,-0.0106,0.7195});
end Buck_R134aR450aR1234yfR1234zee_VarDisVol_Reciprocating;


within AixLib.Fluid.Movers.Compressors.Utilities.VolumetricEfficiency.SpecifiedEfficiencies;
model Buck_R134aR450aR1234yfR1234zee_VarDisVol_Rotary
  "Rotary Compressor - R134a, R450a, R1234yf, R1234ze(e) - Similitude - Power"
  extends PowerVolumetricEfficiency(
    final MRef=0.102032,
    final rotSpeRef=9.334,
    final powMod=Types.VolumetricPowerModels.MendozaMirandaEtAl2016,
    final a=1.2,
    final b={-0.2678,-0.0106,0.7195});
end Buck_R134aR450aR1234yfR1234zee_VarDisVol_Rotary;


Scroll Compressor - R134a, R450a, R1234yf, R1234ze(e) - Similitude - Power. This model contains a calculation procedure for the isentropic
  efficiency presented by Mendoza-Miranda et al. (2016).<br/>

within AixLib.Fluid.Movers.Compressors.Utilities.VolumetricEfficiency.SpecifiedEfficiencies;
model Buck_R134aR450aR1234yfR1234zee_VarDisVol_Scroll
  "Scroll Compressor - R134a, R450a, R1234yf, R1234ze(e) - Similitude - Power"
  extends PowerVolumetricEfficiency(
    final MRef=0.102032,
    final rotSpeRef=9.334,
    final powMod=Types.VolumetricPowerModels.MendozaMirandaEtAl2016,
    final a=1.35,
    final b={-0.2678,-0.0106,0.7195});
end Buck_R134aR450aR1234yfR1234zee_VarDisVol_Scroll;


General model that describes a constant overall volumetric efficiency. This model contains a simple calculation procedure for volumetric
  efficiency models (for more information, please check out
  AixLib.Fluid.Movers.Compressors.BaseClasses.PartialCompression).
  The model provides a constant overall volumetric efficiency and is
  the most basic engine efficiency model.

within AixLib.Fluid.Movers.Compressors.Utilities.VolumetricEfficiency.SpecifiedEfficiencies;
model ConstantEfficiency
  "General model that describes a constant overall volumetric efficiency"
  extends PartialVolumetricEfficiency;

  // Definition of parameters
  //
  parameter Modelica.Units.SI.Efficiency lamHCon=0.9
    "Constant overall volumetric efficiency";

equation
  // Calculate overall volumetric efficiency
  //
  lamH = lamHCon "Allocation of constant overall volumetric efficiency";
end ConstantEfficiency;


Generic overall volumetric efficiency based on literature review for various compressors. This model contains a calculation procedure for the isentropic
  efficiency presented by Engelpracht (2017). However, this approach is
  just fitted to various experimental data obtained by a literature
  review and, therefore, to use with caution.<br/>

within AixLib.Fluid.Movers.Compressors.Utilities.VolumetricEfficiency.SpecifiedEfficiencies;
model Generic_VarRef_VarDisVol_RotaryScroll
  "Generic overall volumetric efficiency based on literature review for various compressors"
  extends PolynomialVolumetricEfficiency(
    final polyMod=Types.VolumetricPolynomialModels.Engelpracht2017,
    final a={0.801790164842882, -0.0521044823322188, 3.216164809959999e-04,
             -0.00493895583430215, 0.049805496348618, -0.021900176265525},
    final b={1,1,1,1,1,1},
    final c={4.54069854496490, 1.63495326341915, 263.864279610770,
             8.43796869242862, 64.4107142857143, 20.8137823859887});
end Generic_VarRef_VarDisVol_RotaryScroll;


within AixLib.Fluid.Movers.Compressors.Utilities.VolumetricEfficiency;
package SpecifiedEfficiencies "Package that engine efficiencies that are specifiied"
  extends Modelica.Icons.VariantsPackage;
end SpecifiedEfficiencies;


within AixLib.Fluid.Movers.Compressors.Utilities.VolumetricEfficiency.SpecifiedEfficiencies;
model Poly_R134a_169_Reciprocating
  "Reciporating Compressor - R134a - 169 cm³ - Polynomial"
  extends PolynomialVolumetricEfficiency(
    final polyMod=Types.VolumetricPolynomialModels.DarrAndCrawford1992,
    final a={0.8889,-1.0025*1e-4,0.8889,-1.0025*1e-4},
    final b={1,1,1,1});
end Poly_R134a_169_Reciprocating;


Reciporating Compressor - R134a - 170 cm³ - Polynomial. This model contains a calculation procedure for the isentropic
  efficiency presented by Li (2013).<br/>

within AixLib.Fluid.Movers.Compressors.Utilities.VolumetricEfficiency.SpecifiedEfficiencies;
model Poly_R134a_170_Reciprocating
  "Reciporating Compressor - R134a - 170 cm³ - Polynomial"
  extends PolynomialVolumetricEfficiency(
    final polyMod=Types.VolumetricPolynomialModels.Li2013,
    final rotSpeRef=2000/60,
    final a={1.223,-0.206,-0.017},
    final b={1,1,1},
    final c={0.779,-0.036,0});
end Poly_R134a_170_Reciprocating;


Scroll Compressor - R134a - 54.24 cm³ - Polynomial . This model contains a calculation procedure for the isentropic
  efficiency presented by Li (2013).<br/>

within AixLib.Fluid.Movers.Compressors.Utilities.VolumetricEfficiency.SpecifiedEfficiencies;
model Poly_R134a_54_Scroll
  "Scroll Compressor - R134a - 54.24 cm³ - Polynomial "
  extends PolynomialVolumetricEfficiency(
    final polyMod=Types.VolumetricPolynomialModels.Li2013,
    final rotSpeRef=50,
    final a={0.693,0.543,-0.236},
    final b={1,1,1},
    final c={1.047,-0.051,0});
end Poly_R134a_54_Scroll;


Rotary Compressor - R22 - 20.7 cm³ - Polynomial. This model contains a calculation procedure for the isentropic
  efficiency presented by Li (2013).<br/>

within AixLib.Fluid.Movers.Compressors.Utilities.VolumetricEfficiency.SpecifiedEfficiencies;
model Poly_R22_20_Rotary "Rotary Compressor - R22 - 20.7 cm³ - Polynomial"
  extends PolynomialVolumetricEfficiency(
    final polyMod=Types.VolumetricPolynomialModels.Li2013,
    final rotSpeRef=60,
    final a={0.709,0.416,-0.125},
    final b={1,1,1},
    final c={1.083,-0.077,0});
end Poly_R22_20_Rotary;


Scroll Compressor - R407C - Unknown displacement volume - Polynomial. This model contains a calculation procedure for the isentropic
  efficiency presented by Karlsson (2017).<br/>

within AixLib.Fluid.Movers.Compressors.Utilities.VolumetricEfficiency.SpecifiedEfficiencies;
model Poly_R407C_Unknown_Scroll
  "Scroll Compressor - R407C - Unknown displacement volume - Polynomial"
  extends PolynomialVolumetricEfficiency(
    final polyMod=Types.VolumetricPolynomialModels.Karlsson2007,
    final a={0.0012,-0.088,1.1262,-0.0045,0.0039,-0.000025},
    final b={1,1,1,1,1,1});
end Poly_R407C_Unknown_Scroll;


Rotary Compressor - R410a - 130 cm³ - Polynomial. This model contains a calculation procedure for the isentropic
  efficiency presented by Körner (2017).<br/>

within AixLib.Fluid.Movers.Compressors.Utilities.VolumetricEfficiency.SpecifiedEfficiencies;
model Poly_R410a_130_Rotary "Rotary Compressor - R410a - 130 cm³ - Polynomial"
  extends PolynomialVolumetricEfficiency(
    final polyMod=Types.VolumetricPolynomialModels.Koerner2017,
    final a={1.108},
    final b={-0.165});
end Poly_R410a_130_Rotary;


within AixLib.Fluid.Movers.Compressors.Validation;
model EfficiencyModels
  "Validation model to check efficiencies calculated with respect to different
  prescribed conditions"
  extends Modelica.Icons.Example;

  // Define medium and parameters
  //
  package Medium =
   Modelica.Media.R134a.R134a_ph
   "Actual medium of the compressor";

  parameter Modelica.Units.SI.MassFlowRate m_flow_nominal=0.1
    "Nominal mass flow rate";

  // Definition of variables
  //
  Modelica.Units.SI.AbsolutePressure pInl=Medium.pressure(Medium.setBubbleState(
      Medium.setSat_T(preInp.y[2] - 1))) "Actual pressure at inlet conditions";
  Modelica.Units.SI.AbsolutePressure pOut=Medium.pressure(Medium.setDewState(
      Medium.setSat_T(preInp.y[3] - 1)))
    "Actual set point of the compressor's outlet pressure";

  // Definition of models
  //
  Modelica.Blocks.Sources.CombiTimeTable preInp(
    tableOnFile=true,
    tableName="Internals",
    fileName=Modelica.Utilities.Files.loadResource(
      "modelica://AixLib/Resources/Fluid/Movers/Compressors/efficiencyValidation.txt"),
    columns=2:5,
    extrapolation=Modelica.Blocks.Types.Extrapolation.NoExtrapolation,
    smoothness=Modelica.Blocks.Types.Smoothness.ContinuousDerivative)
    "Prescribed inputs to check efficiencies calculated by efficiency models"
  Modelica.Thermal.HeatTransfer.Sources.PrescribedTemperature fixTem
    "Fixed ambient temperature"
  Modelica.Blocks.Sources.RealExpression pInlDum(y=pInl)
    "Dummy to succeed pedantic check"
  Modelica.Blocks.Sources.RealExpression pOutDum(y=pOut)
    "Dummy to succeed pedantic check"

  Sources.Boundary_pT source(
    redeclare package Medium = Medium,
    nPorts=1,
    use_T_in=true,
    use_p_in=true) "Source of constant pressure and temperature"
  replaceable SimpleCompressors.RotaryCompressors.RotaryCompressor rotCom(
    redeclare package Medium = Medium,
    show_staEff=true,
    show_qua=true,
    useInpFil=false,
    redeclare model EngineEfficiency =
        Utilities.EngineEfficiency.SpecifiedEfficiencies.Generic_VarRef_VarDisVol_RotaryScroll,
    redeclare model VolumetricEfficiency =
        Utilities.VolumetricEfficiency.SpecifiedEfficiencies.Generic_VarRef_VarDisVol_RotaryScroll,
    redeclare model IsentropicEfficiency =
        AixLib.Fluid.Movers.Compressors.Utilities.IsentropicEfficiency.SpecifiedEfficiencies.Generic_VarRef_VarDisVol_RotaryScroll)
    "Model of a rotary compressor"
  Sources.Boundary_pT sink(
    redeclare package Medium = Medium,
    use_T_in=true,
    use_p_in=true,
    nPorts=1) "Sink with constant pressure and temperature"

equation
  // Connection of components
  //
  connect(source.ports[1],rotCom. port_a)
  connect(fixTem.port,rotCom. heatPort)
  connect(rotCom.port_b, sink.ports[1])
  connect(preInp.y[1], fixTem.T)
  connect(preInp.y[2], source.T_in)
  connect(preInp.y[3], sink.T_in)
  connect(preInp.y[4],rotCom. manVarCom)
  connect(pOutDum.y, sink.p_in)
  connect(pInlDum.y, source.p_in)
end EfficiencyModels;


within AixLib.Fluid.Movers.Compressors.Validation;
model ModularInactiveCompressors
  "Validation model to test modular compressors if not all compressors are active"
  extends Modelica.Icons.Example;

  // Define medium and parameters
  //
  package Medium =
   Modelica.Media.R134a.R134a_ph
   "Medium of the compressor";

  parameter Integer nCom = 3
    "Number of compressors";
  parameter Modelica.Units.SI.AbsolutePressure pInl=Medium.pressure(
      Medium.setBubbleState(Medium.setSat_T(TInl + 1)))
    "Current pressure at inlet conditions";
  parameter Modelica.Units.SI.Temperature TInl=283.15
    "Current temperature at inlet conditions";
  parameter Modelica.Units.SI.AbsolutePressure pOut=Medium.pressure(
      Medium.setDewState(Medium.setSat_T(TOut - 5)))
    "Current set point of the compressor's outlet pressure";
  parameter Modelica.Units.SI.Temperature TOut=333.15
    "Current temperature at outlet conditions";

  // Definition of models
  //
  Sources.Boundary_pT   source(
    redeclare package Medium = Medium,
    p=pInl,
    T=TOut,
    nPorts=1) "Source with constant pressure and temperature"
  Modelica.Thermal.HeatTransfer.Sources.FixedTemperature fixTem[nCom](
    each T=283.15)
    "Fixed ambient temperature"
  replaceable ModularCompressors.ModularCompressors modCom(
    nCom=nCom,
    redeclare package Medium = Medium,
    redeclare model EngineEfficiency =
        Utilities.EngineEfficiency.SpecifiedEfficiencies.Generic_VarRef_VarDisVol_RotaryScroll,
    redeclare model VolumetricEfficiency =
        Utilities.VolumetricEfficiency.SpecifiedEfficiencies.Buck_R134aR450aR1234yfR1234zee_VarDisVol_Rotary,
    redeclare model IsentropicEfficiency =
        AixLib.Fluid.Movers.Compressors.Utilities.IsentropicEfficiency.SpecifiedEfficiencies.Buck_R134aR450aR1234yfR1234zee_VarDisVol_Rotary,
    useExt=true,
    show_parCom=false,
    show_parCon=false,
    redeclare model SimpleCompressor =
        SimpleCompressors.RotaryCompressors.RotaryCompressor,
    redeclare model ModularController =
        Controls.HeatPump.ModularHeatPumps.ModularCompressorController)
    "Model of modular compressors in parallel"
  Modelica.Blocks.Sources.Sine valOpe(
    offset=0.5,
    amplitude=0.3,
    f=1) "Prescribed valve's opening"
  Obsolete.Year2021.Fluid.Actuators.Valves.SimpleValve simVal(
    redeclare package Medium = Medium,
    m_flow_start=0.025,
    m_flow_small=1e-6,
    Kvs=1.4) "Model of a simple valve to simulate pressure losses"
  Sources.Boundary_pT   sink(
    redeclare package Medium = Medium,
    nPorts=1,
    p=pInl,
    T=TInl) "Sink with constant pressure and temperature"

  Controls.Interfaces.ModularHeatPumpControlBus dataBus(
    nCom=nCom) "Connector that contains all control signals"

  Modelica.Blocks.Sources.Sine rotSpe[nCom](
    each f=1,
    amplitude={50,20,0},
    offset={50,20,0})
    "Input signal to prediscribe compressors' rotational speeds"
  Modelica.Blocks.Routing.Replicator repMea(nout=nCom)
    "Replicating the current value of the controlled variables"
  Modelica.Blocks.Sources.Ramp ramMea(
    duration=1,
    height=60,
    offset=40)
    "Ramp to fake current value sof the controlled variables"

equation
  // Connection of main components
  //
  connect(source.ports[1], modCom.port_a)
  connect(fixTem.port, modCom.heatPort)
  connect(modCom.port_b, simVal.port_a)
  connect(simVal.port_b, sink.ports[1])

  // Connection of control signals
  //
  connect(valOpe.y, simVal.opening)

  connect(dataBus, modCom.dataBus)
  connect(ramMea.y, repMea.u)
  connect(rotSpe.y, dataBus.comBus.extManVarCom)
  connect(rotSpe.y, dataBus.comBus.intSetPoiCom)
  connect(repMea.y, dataBus.comBus.meaConVarCom)
end ModularInactiveCompressors;


within AixLib.Fluid.Movers.Compressors;
package Validation "Package that contains validations models to test compressors' functionalities"
  extends Modelica.Icons.ExamplesPackage;
end Validation;


within AixLib.Fluid.Movers.Compressors.Validation;
model SimpleHeatTransfer
  "Validation model to check the implementation of the simple heat transfer"
  extends Modelica.Icons.Example;

  // Define medium and parameters
  //
  package Medium =
   Modelica.Media.R134a.R134a_ph
   "Medium of the compressor";

  parameter Modelica.Units.SI.AbsolutePressure pInl=Medium.pressure(
      Medium.setBubbleState(Medium.setSat_T(TInl + 2)))
    "Current pressure at inlet conditions";
  parameter Modelica.Units.SI.Temperature TInl=283.15
    "Current temperature at inlet conditions";
  parameter Modelica.Units.SI.AbsolutePressure pOut=Medium.pressure(
      Medium.setDewState(Medium.setSat_T(TOut - 5)))
    "Current set point of the compressor's outlet pressure";
  parameter Modelica.Units.SI.Temperature TOut=333.15
    "Current temperature at outlet conditions";

  // Definition of submodels and connectors
  //
  Sources.MassFlowSource_T source(
    redeclare package Medium = Medium,
    nPorts=1,
    m_flow=0.1,
    T=TInl) "Source of constant temperature and mass flow rate"
  Modelica.Thermal.HeatTransfer.Sources.FixedTemperature fixTem(T=263.15)
    "Fixed ambient temperature"
  Utilities.HeatTransfer.SimpleHeatTransfer simheaTra(
    redeclare package Medium = Medium)
    "Model of simple one-dimensional heat transfer"
  MixingVolumes.MixingVolume sink(
    redeclare package Medium = Medium,
    nPorts=1,
    V=10e-3,
    m_flow_nominal=0.1,
    energyDynamics=Modelica.Fluid.Types.Dynamics.DynamicFreeInitial,
    massDynamics=Modelica.Fluid.Types.Dynamics.DynamicFreeInitial,
    p_start=pInl,
    T_start=TInl) "Sink that allows storage of mass and energy"

equation
  // Connection of main components
  //
  connect(fixTem.port, simheaTra.heatPort)
  connect(source.ports[1], simheaTra.port_a)
  connect(simheaTra.port_b, sink.ports[1])
end SimpleHeatTransfer;


Base model to test compressors using static boundaries


within AixLib.Fluid.Movers.Compressors.Validation.StaticHeatPumpBoundaries;
model BaseModelStaticHeatPump
  "Base model to test compressors using static heat pump boundaries"

  // Definition of medium
  //
  replaceable package Medium =
    Modelica.Media.R134a.R134a_ph
    constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium
    "Medium of the compressor"

  // Definition of parameters describing compressors
  //
  parameter Integer nCom = 1
    "Numer of compressors in parallel"

  // Definition of parameters describing boundary conditions
  //
  parameter Modelica.Units.SI.TemperatureDifference dTPinEva=5
    "Pinch temperature at evaporator's outlet"
  parameter Modelica.Units.SI.TemperatureDifference dTSupHea=1
    "Superheating of working fluid"

  parameter Modelica.Units.SI.TemperatureDifference dTPinCon=2.5
    "Pinch temperature at evaporator's outlet"
  parameter Modelica.Units.SI.TemperatureDifference dTSubCool=8
    "Supercooling of working fluid"

  parameter Modelica.Units.SI.Density dSec=1000
    "Constant density of secondary fluid"
  parameter Modelica.Units.SI.SpecificHeatCapacity cpSec=4.1813e3
    "Constant specific heat capacity of secondary fluid"
  parameter Modelica.Units.SI.VolumeFlowRate V_flowSec=(0.776 + 0.781 + 0.44)/3
      /3600 "Constant volume flow of secondary fluid"

  // Definition of variables describing boundary conditions
  //
  Modelica.Blocks.Sources.CombiTimeTable inpDat(
    extrapolation=Modelica.Blocks.Types.Extrapolation.NoExtrapolation,
    columns=2:7,
    timeScale=1,
    smoothness=Modelica.Blocks.Types.Smoothness.ConstantSegments,
    table=[0,64,285.15,5180,308.15,900,5.755555556; 1,64,283.15,4920,308.15,910,
        5.406593407; 2,63,280.15,4370,308.15,930,4.698924731; 3,64,285.15,4980,318.15,
        1140,4.368421053; 4,64,283.15,4730,318.15,1140,4.149122807; 5,55,285.15,
        4180,328.15,1240,3.370967742; 6,64,283.15,4650,328.15,1380,3.369565217;
        7,63,280.15,4160,318.15,1610,2.583850932; 8,55,275.15,2800,308.15,790,3.544303797;
        9,106,258.15,3760,308.15,1570,2.394904459; 10,115,266.15,4850,308.15,1940,
        2.5; 11,55,275.15,2640,318.15,960,2.75; 12,111,258.15,4150,318.15,2120,1.95754717;
        13,107,270.15,4780,318.15,2210,2.162895928; 14,113,266.15,4560,318.15,2290,
        1.991266376; 15,100,266.15,3880,328.15,2240,1.732142857; 16,63,275.15,3280,
        328.15,1330,2.466165414; 17,63,280.15,4080,328.15,1400,2.914285714])
    "Static boundaries of compressor model"

  Modelica.Blocks.Sources.RealExpression inpRotSpe(y=inpDat.y[1])
    "Expressions describing rotational speed"
  Modelica.Blocks.Sources.RealExpression inpAmbTemp(y=inpDat.y[2])
    "Expressions describing ambient temperature"
  Modelica.Blocks.Sources.RealExpression inpHeaCap(y=inpDat.y[3])
    "Expressions describing heat capacity"
  Modelica.Blocks.Sources.RealExpression inpTRetFlo(y=inpDat.y[4] - 10)
    "Expressions describing return flow temperature at heat capacity"

  // Definition of subcomponents
  //
  Modelica.Thermal.HeatTransfer.Sources.PrescribedTemperature ambTemp
    "Source that prescribes boundary ambient temperature"
  Modelica.Thermal.HeatTransfer.Components.ThermalCollector thrCol(m=nCom)
    "Model to split the ambient temperature"
  StaticEvaporator eva(
    redeclare final package Medium = Medium,
    final dTPin=dTPinEva,
    final dTSupHea=dTSupHea)
    "Model that describes a simple static evaporator"

  Modelica.Blocks.Routing.Replicator repMea(nout=nCom)
    "Replicating the current value of the manipulated variables"
  ModularCompressors.ModularCompressorsSensors modCom(
    nCom=nCom,
    redeclare package Medium = Medium,
    redeclare model SimpleCompressor =
        SimpleCompressors.RotaryCompressors.RotaryCompressor,
    show_staEff=true,
    show_qua=true,
    m_flow_start=0.05,
    VDis=fill(13.2e-6,nCom),
    useInpFil=fill(false,nCom),
    h_out_start=400e3,
    redeclare replaceable model EngineEfficiency =
        Utilities.EngineEfficiency.SpecifiedEfficiencies.Generic_VarRef_VarDisVol_RotaryScroll,
    redeclare replaceable model VolumetricEfficiency =
        Utilities.VolumetricEfficiency.SpecifiedEfficiencies.Generic_VarRef_VarDisVol_RotaryScroll,
    redeclare replaceable model IsentropicEfficiency =
        Utilities.IsentropicEfficiency.SpecifiedEfficiencies.Generic_VarRef_VarDisVol_RotaryScroll)
    "Model that describes modular compressors in parallel"

  StaticCondenser con(
    redeclare package Medium = Medium,
    dSec=dSec,
    cpSec=cpSec,
    V_flowSec=V_flowSec,
    dTSubCool=dTSubCool,
    dTPin=dTPinCon)
    "Model that describes a simple static condenser"

  Controls.Interfaces.ModularHeatPumpControlBus dataBus(
    nCom=nCom) "Connector that contains all control signals"

  // Definition of further variables
  //
  Modelica.Blocks.Interaction.Show.RealValue COP(
    use_numberPort=false, number=con.Q_flow/modCom.modCom[1].comPro.PEle/nCom)
    "Real value describing current COP"
  Modelica.Blocks.Interaction.Show.RealValue dCOPRel(use_numberPort=false,
      number=(COP.number - inpDat.y[6])/inpDat.y[6]*100)
    "Realative difference of current COP"
  Modelica.Blocks.Interaction.Show.RealValue PEle(
    use_numberPort=false, number=modCom.modCom[1].comPro.PEle)
    "Real value describing current power consumption"
  Modelica.Blocks.Interaction.Show.RealValue dPEleRel(use_numberPort=false,
      number=(PEle.number - inpDat.y[5])/inpDat.y[5]*100)
    "Real difference of current power consumption"
  Real inpTime = time
    "Simulation time";

protected
  model StaticEvaporator
    "Static evaporator assuming constant pinch point at evaporator's outlet"

    // Definition of medium
    //
    replaceable package Medium = Modelica.Media.R134a.R134a_ph
      constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium
      "Medium of the compressor"

    // Definition of parameters describing evaporator
    //
    parameter Modelica.Units.SI.TemperatureDifference dTPin=5
      "Pinch temperature at evaporator's outlet"
    parameter Modelica.Units.SI.TemperatureDifference dTSupHea=1
      "Superheating of working fluid"

    // Definition of parameters describing assumptions
    //
    parameter Boolean allowFlowReversal = false
      "= false to simplify equations, assuming, but not enforcing, no flow reversal"

    // Definition of connecotrs
    //
    Modelica.Fluid.Interfaces.FluidPort_b port_b(
      redeclare final package Medium = Medium,
      m_flow(max=if allowFlowReversal then +Modelica.Constants.inf else 0),
       h_outflow(start = Medium.h_default))
      "Fluid connector b (positive design flow direction is from port_a to port_b)"
    Modelica.Blocks.Interfaces.RealInput inpTAmb
      "Input of ambient temperature"

    // Definition of submodels
    //
    Modelica.Blocks.Sources.RealExpression outPEva(y=pSat)
      "Expressions describing saturation pressure at evaporator's outlet"
    Modelica.Blocks.Sources.RealExpression outTEva(y=TOut)
      "Expressions describing temperature at evaporator's outlet"

    Sources.Boundary_pT source(
      redeclare package Medium = Medium,
      use_p_in=true,
      use_T_in=true,
      nPorts=1)
      "Source with constant pressure and temperature"

    // Definition of variables describing evaporator
    //
    Medium.SaturationProperties satEva
      "Saturation properties of the evaporator's working fluid"
    Medium.ThermodynamicState staOut
      "Thermodynamic state of the working fluid  at evaporator's outlet"

    Modelica.Units.SI.AbsolutePressure pSat
      "Absolute pressure at evaporator's outlet";
    Modelica.Units.SI.Temperature TSat "Saturation temperature";
    Modelica.Units.SI.Temperature TOut "Temperature at evaporator's outlet";

    Modelica.Units.SI.Temperature TAmb "Temperature of ambient";

  equation
    // Connection of ports
    //
    connect(outPEva.y, source.p_in)
    connect(outTEva.y, source.T_in)
    connect(source.ports[1], port_b)

    TAmb = inpTAmb
      "Temperature of ambient";

    // Calculation of state properties of working fluid
    //
    satEva = Medium.setSat_T(T=TSat)
      "Saturation properties";
    staOut = Medium.setState_pT(p=pSat,T=TOut)
      "Thermodynamic state of the working fluid at evaporator's outlet";

    pSat = Medium.saturationPressure(satEva.Tsat)
      "Absolute pressure at evaporator's outlet";
    TSat = TOut - dTSupHea
      "Saturation temperature";
    TOut = TAmb - dTPin
      "Temperature at evaporator's outlet";
  end StaticEvaporator;

  model StaticCondenser
    "Static condenser assuming constant pinch point at condenser's outlet"

    // Definition of medium
    //
    replaceable package Medium = Modelica.Media.R134a.R134a_ph
      constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium
      "Medium of the compressor"

    // Definition of parameters describing condenser
    //
    parameter Modelica.Units.SI.TemperatureDifference dTPin=2.5
      "Supercooling of working fluid"
    parameter Modelica.Units.SI.TemperatureDifference dTSubCool=8
      "Supercooling of working fluid"

    parameter Modelica.Units.SI.Density dSec=1000
      "Constant density of secondary fluid"
    parameter Modelica.Units.SI.SpecificHeatCapacity cpSec=4.1813e3
      "Constant specific heat capacity of secondary fluid"
    parameter Modelica.Units.SI.VolumeFlowRate V_flowSec=(0.776 + 0.781 + 0.44)
        /3/3600 "Constant volume flow of secondary fluid"

    // Definition of parameters describing assumptions
    //
    parameter Boolean allowFlowReversal = false
      "= false to simplify equations, assuming, but not enforcing, no flow reversal"

    // Definition of connecotrs
    //
    Modelica.Fluid.Interfaces.FluidPort_a port_a(
      redeclare final package Medium = Medium,
      m_flow(max=if allowFlowReversal then +Modelica.Constants.inf else 0),
       h_outflow(start = Medium.h_default))
      "Fluid connector b (positive design flow direction is from port_a to port_b)"

    Modelica.Blocks.Interfaces.RealInput inpTRetFlo
      "Temperature return flow at heat capacity"

    // Definition of variables describing condenser
    //
    Modelica.Units.SI.AbsolutePressure pSat
      "Absolute pressure at condenser's outlet";
    Modelica.Units.SI.Temperature TSat "Saturation temperature";

    Modelica.Units.SI.Temperature TInl "Temperature at condenser's inlet";
    Modelica.Units.SI.Temperature TOut "Temperature at condenser's outlet";
    Modelica.Units.SI.SpecificEnthalpy hInl
      "Specific enthalpy at condenser's inlet";
    Modelica.Units.SI.SpecificEnthalpy hOut
      "Specific enthalpy at condenser's outlet";

    Modelica.Units.SI.MassFlowRate m_flow "Mass flow rate";
    Modelica.Units.SI.HeatFlowRate Q_flow "Heat capacity";

    Modelica.Units.SI.MassFlowRate m_flowSec
      "Mass flow rate of secondary fluid";
    Modelica.Units.SI.Temperature TFlo "Temperature flow at heat capacity";
    Modelica.Units.SI.Temperature TRetFlo
      "Temperature return flow at heat capacity";

  equation
    // Connection of ports
    //
    port_a.h_outflow = inStream(port_a.h_outflow)
      "No flow reversal";
    port_a.p = pSat
      "Pressure at inlet is equal to saturation pressure";

    m_flow = port_a.m_flow
      "Mass flow rate at condenser's inlet";
    hInl = inStream(port_a.h_outflow)
      "Specific enthalpy at condenser's inlet";

    TRetFlo =inpTRetFlo
      "Temperature return flow at heat capacity";

    // Secondary side
    //
    m_flowSec = dSec*V_flowSec
      "Mass flow rate of secondary fluid";
    TFlo = TRetFlo + Q_flow/(m_flowSec*cpSec)
      "Temperature return flow at heat capacity";

    // Calculation of state properties of working fluid
    //
    TOut = TRetFlo + dTPin
      "Temperature at condenser's outlet";
    TSat = TOut + dTSubCool
      "Saturation temperature";
    pSat = Medium.saturationPressure(T=TSat)
      "Absolute pressure at condenser's outlet";

    hOut = Medium.specificEnthalpy_pT(p=pSat,T=TOut)
      "Specific enthalpy at condenser's outlet";
    hOut = hInl - Q_flow/m_flow
      "Specific enthalpy at condenser's outlet";

    TInl = Medium.temperature_ph(p=pSat,h=hInl)
      "Temperature at condenser's inlet";
  end StaticCondenser;

equation
  // Connection of main components
  //
  connect(eva.port_b, modCom.port_a)
  connect(modCom.port_b, con.port_a)
  connect(ambTemp.port, thrCol.port_b)
  connect(thrCol.port_a, modCom.heatPort)

  // Connection of signals
  //
  connect(modCom.dataBus, dataBus)
  connect(inpAmbTemp.y, ambTemp.T)
  connect(inpRotSpe.y, repMea.u)
  connect(repMea.y, dataBus.comBus.extManVarCom)
  connect(inpAmbTemp.y, eva.inpTAmb)
  connect(inpTRetFlo.y, con.inpTRetFlo)
end BaseModelStaticHeatPump;


within AixLib.Fluid.Movers.Compressors.Validation.StaticHeatPumpBoundaries;
model BaseModelStaticHeatPumpController
  "Base model to test compressors using static heat pump boundaries"

  // Definition of medium
  //
  replaceable package Medium =
    Modelica.Media.R134a.R134a_ph
    constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium
    "Medium of the compressor"

  // Definition of parameters describing compressors
  //
  parameter Integer nCom = 1
    "Numer of compressors in parallel"

  // Definition of parameters describing boundary conditions
  //
  parameter Modelica.Units.SI.TemperatureDifference dTPinEva=5
    "Pinch temperature at evaporator's outlet"
  parameter Modelica.Units.SI.TemperatureDifference dTSupHea=1
    "Superheating of working fluid"

  parameter Modelica.Units.SI.TemperatureDifference dTPinCon=2.5
    "Pinch temperature at evaporator's outlet"
  parameter Modelica.Units.SI.TemperatureDifference dTSubCool=8
    "Supercooling of working fluid"

  parameter Modelica.Units.SI.Density dSec=1000
    "Constant density of secondary fluid"
  parameter Modelica.Units.SI.SpecificHeatCapacity cpSec=4.1813e3
    "Constant specific heat capacity of secondary fluid"
  parameter Modelica.Units.SI.VolumeFlowRate V_flowSec=(0.776 + 0.781 + 0.44)/3
      /3600 "Constant volume flow of secondary fluid"

  // Definition of variables describing boundary conditions
  //
  Modelica.Blocks.Sources.CombiTimeTable inpDat(
    extrapolation=Modelica.Blocks.Types.Extrapolation.NoExtrapolation,
    columns=2:7,
    timeScale=1,
    smoothness=Modelica.Blocks.Types.Smoothness.ConstantSegments,
    table=[0,64,285.15,5180,308.15,900,5.755555556; 1,64,283.15,4920,308.15,910,
        5.406593407; 2,63,280.15,4370,308.15,930,4.698924731; 3,64,285.15,4980,318.15,
        1140,4.368421053; 4,64,283.15,4730,318.15,1140,4.149122807; 5,55,285.15,
        4180,328.15,1240,3.370967742; 6,64,283.15,4650,328.15,1380,3.369565217;
        7,63,280.15,4160,318.15,1610,2.583850932; 8,55,275.15,2800,308.15,790,3.544303797;
        9,106,258.15,3760,308.15,1570,2.394904459; 10,115,266.15,4850,308.15,1940,
        2.5; 11,55,275.15,2640,318.15,960,2.75; 12,111,258.15,4150,318.15,2120,1.95754717;
        13,107,270.15,4780,318.15,2210,2.162895928; 14,113,266.15,4560,318.15,2290,
        1.991266376; 15,100,266.15,3880,328.15,2240,1.732142857; 16,63,275.15,3280,
        328.15,1330,2.466165414; 17,63,280.15,4080,328.15,1400,2.914285714])
    "Static boundaries of compressor model"

  Modelica.Blocks.Sources.RealExpression inpRotSpe(y=inpDat.y[1])
    "Expressions describing rotational speed"
  Modelica.Blocks.Sources.RealExpression inpAmbTemp(y=inpDat.y[2])
    "Expressions describing ambient temperature"
  Modelica.Blocks.Sources.RealExpression inpHeaCap(y=inpDat.y[3])
    "Expressions describing heat capacity"
  Modelica.Blocks.Sources.RealExpression inpTRetFlo(y=inpDat.y[4] - 10)
    "Expressions describing return flow temperature at heat capacity"

  // Definition of subcomponents
  //
  Modelica.Thermal.HeatTransfer.Sources.PrescribedTemperature ambTemp
    "Source that prescribes boundary ambient temperature"
  Modelica.Thermal.HeatTransfer.Components.ThermalCollector thrCol(m=nCom)
    "Model to split the ambient temperature"
  StaticEvaporator eva(
    redeclare final package Medium = Medium,
    final dTPin=dTPinEva,
    final dTSupHea=dTSupHea)
    "Model that describes a simple static evaporator"

  Modelica.Blocks.Continuous.LimPID PID(
    controllerType=Modelica.Blocks.Types.SimpleController.P,
    yMax=120,
    yMin=30) "Controller of the compressor's rotational speeds"
  Modelica.Blocks.Routing.Replicator repMea(nout=nCom)
    "Replicating the current value of the manipulated variables"
  ModularCompressors.ModularCompressorsSensors modCom(
    nCom=nCom,
    redeclare package Medium = Medium,
    redeclare model SimpleCompressor =
        SimpleCompressors.RotaryCompressors.RotaryCompressor,
    show_staEff=true,
    show_qua=true,
    m_flow_start=0.05,
    VDis=fill(13.2e-6,nCom),
    useInpFil=fill(false,nCom),
    h_out_start=400e3,
    redeclare replaceable model EngineEfficiency =
        Utilities.EngineEfficiency.SpecifiedEfficiencies.Generic_VarRef_VarDisVol_RotaryScroll,
    redeclare replaceable model VolumetricEfficiency =
        Utilities.VolumetricEfficiency.SpecifiedEfficiencies.Generic_VarRef_VarDisVol_RotaryScroll,
    redeclare replaceable model IsentropicEfficiency =
        Utilities.IsentropicEfficiency.SpecifiedEfficiencies.Generic_VarRef_VarDisVol_RotaryScroll)
    "Model that describes modular compressors in parallel"

  StaticCondenser con(
    redeclare package Medium = Medium,
    dSec=dSec,
    cpSec=cpSec,
    V_flowSec=V_flowSec,
    dTSubCool=dTSubCool,
    dTPin=dTPinCon)
    "Model that describes a simple static condenser"

  Controls.Interfaces.ModularHeatPumpControlBus dataBus(
    nCom=nCom) "Connector that contains all control signals"

  // Definition of further variables
  //
  Modelica.Blocks.Interaction.Show.RealValue COP(
    use_numberPort=false, number=con.Q_flow/modCom.modCom[1].comPro.PEle/nCom)
    "Real value describing current COP"
  Modelica.Blocks.Interaction.Show.RealValue dCOPRel(use_numberPort=false,
      number=(COP.number - inpDat.y[6])/inpDat.y[6]*100)
    "Realative difference of current COP"
  Modelica.Blocks.Interaction.Show.RealValue PEle(
    use_numberPort=false, number=modCom.modCom[1].comPro.PEle)
    "Real value describing current power consumption"
  Modelica.Blocks.Interaction.Show.RealValue dPEleRel(use_numberPort=false,
      number=(PEle.number - inpDat.y[5])/inpDat.y[5]*100)
    "Real difference of current power consumption"
  Real inpTime = time
    "Simulation time";

protected
  model StaticEvaporator
    "Static evaporator assuming constant pinch point at evaporator's outlet"

    // Definition of medium
    //
    replaceable package Medium = Modelica.Media.R134a.R134a_ph
      constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium
      "Medium of the compressor"

    // Definition of parameters describing evaporator
    //
    parameter Modelica.Units.SI.TemperatureDifference dTPin=5
      "Pinch temperature at evaporator's outlet"
    parameter Modelica.Units.SI.TemperatureDifference dTSupHea=1
      "Superheating of working fluid"

    // Definition of parameters describing assumptions
    //
    parameter Boolean allowFlowReversal = false
      "= false to simplify equations, assuming, but not enforcing, no flow reversal"

    // Definition of connecotrs
    //
    Modelica.Fluid.Interfaces.FluidPort_b port_b(
      redeclare final package Medium = Medium,
      m_flow(max=if allowFlowReversal then +Modelica.Constants.inf else 0),
       h_outflow(start = Medium.h_default))
      "Fluid connector b (positive design flow direction is from port_a to port_b)"
    Modelica.Blocks.Interfaces.RealInput inpTAmb
      "Input of ambient temperature"

    // Definition of submodels
    //
    Modelica.Blocks.Sources.RealExpression outPEva(y=pSat)
      "Expressions describing saturation pressure at evaporator's outlet"
    Modelica.Blocks.Sources.RealExpression outTEva(y=TOut)
      "Expressions describing temperature at evaporator's outlet"

    Sources.Boundary_pT source(
      redeclare package Medium = Medium,
      use_p_in=true,
      use_T_in=true,
      nPorts=1)
      "Source with constant pressure and temperature"

    // Definition of variables describing evaporator
    //
    Medium.SaturationProperties satEva
      "Saturation properties of the evaporator's working fluid"
    Medium.ThermodynamicState staOut
      "Thermodynamic state of the working fluid  at evaporator's outlet"

    Modelica.Units.SI.AbsolutePressure pSat
      "Absolute pressure at evaporator's outlet";
    Modelica.Units.SI.Temperature TSat "Saturation temperature";
    Modelica.Units.SI.Temperature TOut "Temperature at evaporator's outlet";

    Modelica.Units.SI.Temperature TAmb "Temperature of ambient";

  equation
    // Connection of ports
    //
    connect(outPEva.y, source.p_in)
    connect(outTEva.y, source.T_in)
    connect(source.ports[1], port_b)

    TAmb = inpTAmb
      "Temperature of ambient";

    // Calculation of state properties of working fluid
    //
    satEva = Medium.setSat_T(T=TSat)
      "Saturation properties";
    staOut = Medium.setState_pT(p=pSat,T=TOut)
      "Thermodynamic state of the working fluid at evaporator's outlet";

    pSat = Medium.saturationPressure(satEva.Tsat)
      "Absolute pressure at evaporator's outlet";
    TSat = TOut - dTSupHea
      "Saturation temperature";
    TOut = TAmb - dTPin
      "Temperature at evaporator's outlet";
  end StaticEvaporator;

  model StaticCondenser
    "Static condenser assuming constant pinch point at condenser's outlet"

    // Definition of medium
    //
    replaceable package Medium = Modelica.Media.R134a.R134a_ph
      constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium
      "Medium of the compressor"

    // Definition of parameters describing condenser
    //
    parameter Modelica.Units.SI.TemperatureDifference dTPin=2.5
      "Supercooling of working fluid"
    parameter Modelica.Units.SI.TemperatureDifference dTSubCool=8
      "Supercooling of working fluid"

    parameter Modelica.Units.SI.Density dSec=1000
      "Constant density of secondary fluid"
    parameter Modelica.Units.SI.SpecificHeatCapacity cpSec=4.1813e3
      "Constant specific heat capacity of secondary fluid"
    parameter Modelica.Units.SI.VolumeFlowRate V_flowSec=(0.776 + 0.781 + 0.44)
        /3/3600 "Constant volume flow of secondary fluid"

    // Definition of parameters describing assumptions
    //
    parameter Boolean allowFlowReversal = false
      "= false to simplify equations, assuming, but not enforcing, no flow reversal"

    // Definition of connecotrs
    //
    Modelica.Fluid.Interfaces.FluidPort_a port_a(
      redeclare final package Medium = Medium,
      m_flow(max=if allowFlowReversal then +Modelica.Constants.inf else 0),
       h_outflow(start = Medium.h_default))
      "Fluid connector b (positive design flow direction is from port_a to port_b)"

    Modelica.Blocks.Interfaces.RealInput inpTRetFlo
      "Temperature return flow at heat capacity"
    Modelica.Blocks.Interfaces.RealOutput outQFlo
      "Heat capacity"

    // Definition of variables describing condenser
    //
    Modelica.Units.SI.AbsolutePressure pSat
      "Absolute pressure at condenser's outlet";
    Modelica.Units.SI.Temperature TSat "Saturation temperature";

    Modelica.Units.SI.Temperature TInl "Temperature at condenser's inlet";
    Modelica.Units.SI.Temperature TOut "Temperature at condenser's outlet";
    Modelica.Units.SI.SpecificEnthalpy hInl
      "Specific enthalpy at condenser's inlet";
    Modelica.Units.SI.SpecificEnthalpy hOut
      "Specific enthalpy at condenser's outlet";

    Modelica.Units.SI.MassFlowRate m_flow "Mass flow rate";
    Modelica.Units.SI.HeatFlowRate Q_flow "Heat capacity";

    Modelica.Units.SI.MassFlowRate m_flowSec
      "Mass flow rate of secondary fluid";
    Modelica.Units.SI.Temperature TFlo "Temperature flow at heat capacity";
    Modelica.Units.SI.Temperature TRetFlo
      "Temperature return flow at heat capacity";

  equation
    // Connection of ports
    //
    port_a.h_outflow = inStream(port_a.h_outflow)
      "No flow reversal";
    port_a.p = pSat
      "Pressure at inlet is equal to saturation pressure";

    m_flow = port_a.m_flow
      "Mass flow rate at condenser's inlet";
    hInl = inStream(port_a.h_outflow)
      "Specific enthalpy at condenser's inlet";

    TRetFlo = inpTRetFlo
      "Temperature return flow at heat capacity";
    outQFlo = Q_flow
      "Heat capacity";

    // Secondary side
    //
    m_flowSec = dSec*V_flowSec
      "Mass flow rate of secondary fluid";
    TFlo = TRetFlo + Q_flow/(m_flowSec*cpSec)
      "Temperature return flow at heat capacity";

    // Calculation of state properties of working fluid
    //
    TOut = TRetFlo + dTPin
      "Temperature at condenser's outlet";
    TSat = TOut + dTSubCool
      "Saturation temperature";
    pSat = Medium.saturationPressure(T=TSat)
      "Absolute pressure at condenser's outlet";

    hOut = Medium.specificEnthalpy_pT(p=pSat,T=TOut)
      "Specific enthalpy at condenser's outlet";
    hOut = hInl - Q_flow/m_flow
      "Specific enthalpy at condenser's outlet";

    TInl = Medium.temperature_ph(p=pSat,h=hInl)
      "Temperature at condenser's inlet";
  end StaticCondenser;

equation
  // Connection of main components
  //
  connect(eva.port_b, modCom.port_a)
  connect(modCom.port_b, con.port_a)
  connect(ambTemp.port, thrCol.port_b)
  connect(thrCol.port_a, modCom.heatPort)

  // Connection of signals
  //
  connect(modCom.dataBus, dataBus)
  connect(inpAmbTemp.y, ambTemp.T)
  connect(repMea.y, dataBus.comBus.extManVarCom)
  connect(inpAmbTemp.y, eva.inpTAmb)
  connect(inpTRetFlo.y, con.inpTRetFlo)
  connect(PID.y, repMea.u)
  connect(con.outQFlo, PID.u_m)
  connect(PID.u_s, inpHeaCap.y)
end BaseModelStaticHeatPumpController;


within AixLib.Fluid.Movers.Compressors.Validation;
package StaticHeatPumpBoundaries "This package contains models to validate the comprosser models using
  static heat pump boundary conditions"
  extends Modelica.Icons.ExamplesPackage;
end StaticHeatPumpBoundaries;


within AixLib.Fluid.Movers.Compressors.Validation.StaticHeatPumpBoundaries;
package SpecifiedModels "Package that contains validation models of different static boundary models"
  extends Modelica.Icons.ExamplesPackage;
end SpecifiedModels;


within AixLib.Fluid.Movers.Compressors.Validation.StaticHeatPumpBoundaries.SpecifiedModels;
model RefrigerantR134aScrollCompressor
  "Static boundaries of a scroll-compressor using R134a"
  extends BaseModelStaticBoundaries(
    replaceable package Medium =
      Modelica.Media.R134a.R134a_ph,
    modCom(
      redeclare model EngineEfficiency =
        EngineEfficiency,
      redeclare model VolumetricEfficiency =
        VolumetricEfficiency,
      redeclare model IsentropicEfficiency =
        IsentropicEfficiency));
  extends Modelica.Icons.Example;

protected
  model EngineEfficiency
    "Fitted engine efficiency"
    extends Utilities.EngineEfficiency.PartialEngineEfficiency(
      useIseWor = false);
  equation
     etaEng = 0.8704+0.001295*rotSpe+0.05194*piPre-8.006e-06*rotSpe^2-
       0.0001272*rotSpe*piPre-0.01146*piPre^2+1.059e-06*rotSpe^2*piPre-
       2.265e-06*rotSpe*piPre^2+0.0008853*piPre^3;
  end EngineEfficiency;

  model VolumetricEfficiency
    "Fitted volumetric efficiency"
    extends Utilities.VolumetricEfficiency.PartialVolumetricEfficiency;
  equation
    lamH = 0.5828+0.0303*rotSpe-0.1727*piPre-0.000588*rotSpe^2+
      0.003072*rotSpe*piPre+0.01238*piPre^2+3.434e-06*rotSpe^3-
      1.496e-05*rotSpe^2*piPre -0.0001785*rotSpe*piPre^2;
  end VolumetricEfficiency;

  model IsentropicEfficiency
    "Fitted isentropic efficiency"
    extends Utilities.IsentropicEfficiency.PartialIsentropicEfficiency;
  equation
    etaIse = (-3.565 + 0.2464*rotSpe + 1.227*piPre - 0.007986*rotSpe^2+
    0.03947*rotSpe*piPre-0.9075*piPre^2+0.0001086*rotSpe^3-
     0.0006588*rotSpe^2*piPre +0.0001482*rotSpe*piPre^2 +
      0.1721*piPre^3-5.291e-07*rotSpe^4+3.353e-06*rotSpe^3*piPre+
      1.037e-05*rotSpe^2*piPre^2 - 0.0001854*rotSpe*piPre^3-0.01102*piPre^4)*1.05;
  end IsentropicEfficiency;
end RefrigerantR134aScrollCompressor;


within AixLib.Fluid.Movers.Compressors.Validation.StaticHeatPumpBoundaries.SpecifiedModels;
model RefrigerantR410aScrollCompressor
  "Static heat pump boundaries of a scroll-compressor using R410a"
  extends BaseModelStaticHeatPump(
    nCom = 1,
    replaceable package Medium =
      Modelica.Media.R134a.R134a_ph,
    modCom(
      redeclare model EngineEfficiency =
          Utilities.EngineEfficiency.SpecifiedEfficiencies.Generic_VarRef_VarDisVol_RotaryScroll,
      redeclare model VolumetricEfficiency =
          Utilities.VolumetricEfficiency.SpecifiedEfficiencies.Generic_VarRef_VarDisVol_RotaryScroll,
      redeclare model IsentropicEfficiency =
          Utilities.IsentropicEfficiency.SpecifiedEfficiencies.Generic_VarRef_VarDisVol_RotaryScroll),
    inpDat(smoothness=Modelica.Blocks.Types.Smoothness.ConstantSegments));
  extends Modelica.Icons.Example;
end RefrigerantR410aScrollCompressor;


within AixLib.Fluid.Movers.Compressors.Validation.StaticHeatPumpBoundaries.SpecifiedModels;
model RefrigerantR410aScrollCompressorController
  "Static boundaries of a scroll-compressor using R410a"
  extends BaseModelStaticHeatPumpController(
    nCom = 1,
    replaceable package Medium =
      Modelica.Media.R134a.R134a_ph,
    modCom(
      redeclare model EngineEfficiency =
          Utilities.EngineEfficiency.SpecifiedEfficiencies.Generic_VarRef_VarDisVol_RotaryScroll,
      redeclare model VolumetricEfficiency =
          Utilities.VolumetricEfficiency.SpecifiedEfficiencies.Generic_VarRef_VarDisVol_RotaryScroll,
      redeclare model IsentropicEfficiency =
          Utilities.IsentropicEfficiency.SpecifiedEfficiencies.Generic_VarRef_VarDisVol_RotaryScroll,
      useInpFil={true},
      risTim={0.1}),
    inpDat(smoothness=Modelica.Blocks.Types.Smoothness.ContinuousDerivative),
    PID(
      yMax=120,
      yMin=10,
      k=1));
  extends Modelica.Icons.Example;
end RefrigerantR410aScrollCompressorController;


Generic data record for movers

within AixLib.Fluid.Movers.Data;
record Generic "Generic data record for movers"
  extends Modelica.Icons.Record;

  // Pressure requires default values to avoid in Dymola the message
  // Failed to expand the variable pressure.V_flow.
  parameter AixLib.Fluid.Movers.BaseClasses.Characteristics.flowParameters pressure(
    V_flow = {0, 0},
    dp =     {0, 0}) "Volume flow rate vs. total pressure rise"
  final parameter Modelica.Units.SI.VolumeFlowRate V_flow_max=
    if havePressureCurve
      then (pressure.V_flow[end]
                -(pressure.V_flow[end] - pressure.V_flow[end - 1])
                /(pressure.dp[end] - pressure.dp[end - 1])
                * pressure.dp[end])
    else 0
      "Volume flow rate on the curve when pressure rise is zero";
  final parameter Modelica.Units.SI.PressureDifference dpMax(
    displayUnit="Pa")=
    if havePressureCurve
      then (pressure.dp[1]
                -(pressure.dp[1] - pressure.dp[2])
                /(pressure.V_flow[1] - pressure.V_flow[2])
                * pressure.V_flow[1])
    else 0
      "Pressure rise on the curve when flow rate is zero";

  // Efficiency computation choices
  parameter AixLib.Fluid.Movers.BaseClasses.Types.HydraulicEfficiencyMethod etaHydMet=
    if havePressureCurve
    then AixLib.Fluid.Movers.BaseClasses.Types.HydraulicEfficiencyMethod.EulerNumber
    else AixLib.Fluid.Movers.BaseClasses.Types.HydraulicEfficiencyMethod.NotProvided
    "Efficiency computation method for the hydraulic efficiency etaHyd"
  parameter AixLib.Fluid.Movers.BaseClasses.Types.MotorEfficiencyMethod etaMotMet=
    if powerOrEfficiencyIsHydraulic and havePressureCurve
    then AixLib.Fluid.Movers.BaseClasses.Types.MotorEfficiencyMethod.GenericCurve
    else AixLib.Fluid.Movers.BaseClasses.Types.MotorEfficiencyMethod.NotProvided
    "Efficiency computation method for the motor efficiency etaMot"

  parameter Boolean powerOrEfficiencyIsHydraulic=true
    "=true if hydraulic power or efficiency is provided, instead of total"

  // Arrays for efficiency values
  parameter
    AixLib.Fluid.Movers.BaseClasses.Characteristics.efficiencyParameters
    efficiency(
      V_flow={0},
      eta={0.7}) "Total or hydraulic efficiency vs. volumetric flow rate"
  parameter
    AixLib.Fluid.Movers.BaseClasses.Characteristics.efficiencyParameters
    motorEfficiency(
      V_flow={0},
      eta={0.7})
    "Motor efficiency vs. volumetric flow rate"
  parameter
    AixLib.Fluid.Movers.BaseClasses.Characteristics.efficiencyParameters_yMot
    motorEfficiency_yMot(y={0}, eta={0.7})
    "Motor efficiency vs. part load ratio yMot, where yMot = WHyd/WMot_nominal"

  // Power curve
  //   It requires default values to suppress Dymola message
  //   "Failed to expand the variable Power.V_flow"
  parameter AixLib.Fluid.Movers.BaseClasses.Characteristics.powerParameters power(
    V_flow={0},
    P={0})
    "Power (either consumed or hydraulic) vs. volumetric flow rate"

  // Peak condition
  parameter AixLib.Fluid.Movers.BaseClasses.Euler.peak peak(
    V_flow=peak_internal.V_flow,
    dp=peak_internal.dp,
    eta=peak_internal.eta)
    "Volume flow rate, pressure rise, and efficiency (either total or hydraulic) at peak condition"
  final parameter AixLib.Fluid.Movers.BaseClasses.Euler.peak peak_internal=
    AixLib.Fluid.Movers.BaseClasses.Euler.getPeak(pressure=pressure,power=power)
    "Internal peak variable";
  // The getPeak() function automatically handles the estimation of peak point
  //   when insufficient information is provided from the pressure curve.

  // Motor
  parameter Boolean motorCooledByFluid=true
    "If true, then motor heat is added to fluid stream"
  parameter Modelica.Units.SI.Power WMot_nominal=
    if max(power.P)>Modelica.Constants.eps
    then
      if powerOrEfficiencyIsHydraulic
        then max(power.P)*1.2
      else max(power.P)
    else
      if havePressureCurve
        then V_flow_max/2 * dpMax/2 /0.7*1.2
      else 0
    "Rated motor power"
  parameter Modelica.Units.SI.Efficiency etaMot_max(max=1)= 0.7
    "Maximum motor efficiency"
  final parameter
    AixLib.Fluid.Movers.BaseClasses.Characteristics.efficiencyParameters_yMot
      motorEfficiency_yMot_generic=
        AixLib.Fluid.Movers.BaseClasses.Characteristics.motorEfficiencyCurve(
          P_nominal=WMot_nominal,
          eta_max=etaMot_max)
    "Motor efficiency  vs. part load ratio"
  final parameter Boolean haveWMot_nominal=WMot_nominal > Modelica.Constants.eps
    "= true, if the rated motor power is provided";

  // Speed
  parameter Real speed_nominal(
    final min=0,
    final unit="1") = 1 "Nominal rotational speed for flow characteristic"

  parameter Real constantSpeed(final min=0, final unit="1") = 1
    "Normalized speed set point, used if inputType = AixLib.Fluid.Types.InputType.Constant"

  parameter Real[:] speeds(each final min = 0, each final unit="1") = {1}
    "Vector of normalized speed set points, used if inputType = AixLib.Fluid.Types.InputType.Stages"

  // Set a parameter in order for
  // (a) FlowControlled_m_flow and FlowControlled_dp to be able to set a reasonable
  //     default pressure curve if it is not specified here, and
  // (b) SpeedControlled_y to be able to issue an assert
  //     if no pressure curve is specified.
  final parameter Boolean havePressureCurve=
    sum(pressure.V_flow) > Modelica.Constants.eps and
    sum(pressure.dp) > Modelica.Constants.eps
    "= true, if default record values are being used";
end Generic;


within AixLib.Fluid.Movers;
package Data "Package containing data for real pumps/fans"
extends Modelica.Icons.MaterialPropertiesPackage;
end Data;


Package of fan performance data

within AixLib.Fluid.Movers.Data;
package Fans "Package of fan performance data"
  extends Modelica.Icons.Package;
end Fans;


within AixLib.Fluid.Movers.Data.Fans;
package Greenheck "Package with performance data for fans of Greenheck"
  extends Modelica.Icons.Package;
end Greenheck;


Package containing data for pumps

within AixLib.Fluid.Movers.Data;
package Pumps "Package containing data for pumps"
  extends Modelica.Icons.Package;
end Pumps;


within AixLib.Fluid.Movers.Data.Pumps;
package Wilo "Package with performance data for Wilo pumps"
  extends Modelica.Icons.Package;
end Wilo;