Displays the curve of the Euler number's correlation. This validation model plots and compares out the original correlation function
of Euler number and its polynomial approximation.

within AixLib.Fluid.Movers.BaseClasses.Validation;
model EulerCurve "Displays the curve of the Euler number's correlation"
  extends Modelica.Icons.Example;
  Real x "log10(Eu/Eu_peak)";
  Real etaApp "eta/eta_peak from polynomial approximation";
  Real etaOri "eta/eta_peak from original correlation";

function correlation
  input Real x "log10(Eu/Eu_peak)";
  output Real y "eta/eta_peak";
  protected
  constant Real a=-2.732094, b=2.273014, c=0.196344, d=5.267518;
  Real Z1, Z2, Z3;
algorithm
  Z1:=(x-a)/b;
  Z2:=((exp(c*x)*d*x)-a)/b;
  Z3:=-a/b;
  y:=(exp(-0.5*Z1^2)*(1+sign(Z2)*Modelica.Math.Special.erf(u=abs(Z2)/sqrt(2))))
    /(exp(-0.5*Z3^2)*(1+Modelica.Math.Special.erf(u=Z3/sqrt(2))));
end correlation;

initial equation
  x = -4;
equation
  der(x)=1;
  etaApp = AixLib.Fluid.Movers.BaseClasses.Euler.correlation(x);
  etaOri = correlation(x);
end EulerCurve;


Validates the Euler number method at reduced mover speed. Similar to

AixLib.Fluid.Movers.BaseClasses.Validation.EulerComparison,
this model compares the power computed from the Euler number method with measured
values. The power data at speeds N=4100, 3400, and 2500 RPM from the power map of

AixLib.Fluid.Movers.Data.Fans.Greenheck.BIDW13
(shown below) was used.
Note that the pressure curves in the figure do not seem to be independently
measured but rather simply scaled from the nominal curve.
However, because the Euler number method also does not account for the efficiency
degradation along any curve Δp=kV̇2,
using the Euler number method has equivalent accuracy to using such power maps.

within AixLib.Fluid.Movers.BaseClasses.Validation;
model EulerReducedSpeed
  "Validates the Euler number method at reduced mover speed"
  extends Modelica.Icons.Example;

  parameter Integer nOri(min=1)=size(per1.power.V_flow,1)
    "Number of data points for pressure curve"
  parameter Modelica.Units.SI.Density rhoCon=1.2
    "Constant density";

  parameter AixLib.Fluid.Movers.Data.Fans.Greenheck.BIDW13 per1(
    final etaHydMet=
            AixLib.Fluid.Movers.BaseClasses.Types.HydraulicEfficiencyMethod.EulerNumber,
    final etaMotMet=
            AixLib.Fluid.Movers.BaseClasses.Types.MotorEfficiencyMethod.NotProvided)
    "Mover performance curves with flow rate, pressure rise, and power";
  parameter AixLib.Fluid.Movers.Data.Generic per2(
    power(V_flow={0.939939939939939,1.88588588588588,2.83183183183181,
         3.77177177177175,4.46546546546544}, P={4332.517,5801.546,6651.644,
         6800.784,6502.504}),
    pressure(V_flow={0.939939939939939,1.88588588588588,2.83183183183181,
            3.77177177177175,4.46546546546544}, dp={2081.78137651821,
            2008.90688259109,1474.4939271255,704.453441295546,0}))
    "Mover performance curves at reduced speed N=3400";
  parameter AixLib.Fluid.Movers.Data.Generic per3(
    power(V_flow={0.939939939939939,1.88588588588588,2.83183183183181,
         3.28228228228228}, P={1998.476,2535.38,2714.348,2550.294}),
    pressure(V_flow={0.939939939939939,1.88588588588588,2.83183183183181,
            3.28228228228228}, dp={1127.12550607287,903.643724696356,
            340.080971659919,0}))
    "Mover performance curves at reduced speed N=2500";

  Modelica.Units.SI.Power pow1=
    AixLib.Utilities.Math.Functions.smoothInterpolation(
      x=m1_flow.y/rhoCon,
      xSup=per1.power.V_flow,
      ySup=per1.power.P,
      ensureMonotonicity=false) "Measured power";
  Modelica.Units.SI.Power pow2=
    AixLib.Utilities.Math.Functions.smoothInterpolation(
      x=m2_flow.y/rhoCon,
      xSup=per2.power.V_flow,
      ySup=per2.power.P,
      ensureMonotonicity=false) "Measured power";
  Modelica.Units.SI.Power pow3=
    AixLib.Utilities.Math.Functions.smoothInterpolation(
      x=m3_flow.y/rhoCon,
      xSup=per3.power.V_flow,
      ySup=per3.power.P,
      ensureMonotonicity=false) "Measured power";

  AixLib.Fluid.Movers.BaseClasses.FlowMachineInterface eff1(
    per=per1,
    rho_default=rhoCon,
    nOri=nOri,
    computePowerUsingSimilarityLaws=false)
    "Flow machine interface using power characteristic"
  AixLib.Fluid.Movers.BaseClasses.FlowMachineInterface eff2(
    per=per1,
    rho_default=rhoCon,
    nOri=nOri,
    computePowerUsingSimilarityLaws=false)
    "Flow machine interface using power Euler correlation"
  AixLib.Fluid.Movers.BaseClasses.FlowMachineInterface eff3(
    per=per1,
    rho_default=rhoCon,
    nOri=nOri,
    computePowerUsingSimilarityLaws=false)
    "Flow machine interface using power Euler correlation"

  Modelica.Blocks.Sources.Constant y1(k=1) "Control signal"
  Modelica.Blocks.Sources.Constant rho(k=rhoCon) "Density"
  Modelica.Blocks.Sources.Constant y2(k=3400/4100)
    "Reduced speed y = 3400/4100 = 0.829"
  Modelica.Blocks.Sources.Constant y3(k=2500/4100)
    "Reduced speed y = 2500/4100 = 0.610"

  Modelica.Blocks.Sources.Ramp m1_flow(
    height=0.98*max(per1.pressure.V_flow)*rhoCon,
    duration=1,
    offset=0.01*max(per1.pressure.V_flow)*rhoCon)
    "Mass flow rate"
  Modelica.Blocks.Sources.Ramp m2_flow(
    height=0.98*max(per2.pressure.V_flow)*rhoCon,
    duration=1,
    offset=0.01*max(per2.pressure.V_flow)*rhoCon) "Mass flow rate"
  Modelica.Blocks.Sources.Ramp m3_flow(
    height=0.98*max(per3.pressure.V_flow)*rhoCon,
    duration=1,
    offset=0.01*max(per3.pressure.V_flow)*rhoCon) "Mass flow rate"

equation
  connect(eff1.rho, rho.y)
  connect(y1.y, eff1.y_in)
  connect(m1_flow.y, eff1.m_flow)
  connect(rho.y, eff2.rho)
  connect(y2.y, eff2.y_in)
  connect(m2_flow.y, eff2.m_flow)
  connect(y3.y, eff3.y_in)
  connect(m3_flow.y, eff3.m_flow)
  connect(rho.y, eff3.rho)
end EulerReducedSpeed;


Simple model to validate FlowMachineInterface. Simple validation model for the flow machine interface model.

within AixLib.Fluid.Movers.BaseClasses.Validation;
model FlowMachineInterface "Simple model to validate FlowMachineInterface"
  extends Modelica.Icons.Example;
  AixLib.Fluid.Movers.BaseClasses.FlowMachineInterface eff(
    per(pressure(V_flow={0,1}, dp={1000,0})),
    rho_default=1.2,
    nOri=2,
    preVar=AixLib.Fluid.Movers.BaseClasses.Types.PrescribedVariable.Speed,
    computePowerUsingSimilarityLaws=true) "Flow machine interface model"
  Modelica.Blocks.Sources.Constant y(k=1) "Control signal"
  Modelica.Blocks.Sources.Constant rho(k=1.2) "Density"
  Modelica.Blocks.Sources.Ramp m_flow(height=1.2, duration=1) "Mass flow rate"
equation
  connect(eff.rho, rho.y)
  connect(m_flow.y, eff.m_flow)
  connect(y.y, eff.y_in)
end FlowMachineInterface;


Validation model for different hydraulic efficiency options. This is a simple validation model for

AixLib.Fluid.Movers.BaseClasses.FlowMachineInterface
where its hydraulic efficiency ηhyd is specified with
different methods defined in

AixLib.Fluid.Movers.BaseClasses.Types.HydraulicEfficiencyMethod.

within AixLib.Fluid.Movers.BaseClasses.Validation;
model HydraulicEfficiencyMethods
  "Validation model for different hydraulic efficiency options"
  extends Modelica.Icons.Example;

  AixLib.Fluid.Movers.Data.Generic per(
    powerOrEfficiencyIsHydraulic=true,
    final pressure(V_flow={0,1}, dp={1000,0}),
    final etaMotMet=AixLib.Fluid.Movers.BaseClasses.Types.MotorEfficiencyMethod.NotProvided)
    "Performance record";
  parameter Modelica.Units.SI.Density rhoFlu=1.2 "Fluid density";

  AixLib.Fluid.Movers.BaseClasses.FlowMachineInterface eff1(
    per(
      powerOrEfficiencyIsHydraulic=per.powerOrEfficiencyIsHydraulic,
      pressure=per.pressure,
      etaMotMet=per.etaMotMet,
      etaHydMet=AixLib.Fluid.Movers.BaseClasses.Types.HydraulicEfficiencyMethod.NotProvided),
    rho_default=rhoFlu,
    nOri=2,
    preVar=AixLib.Fluid.Movers.BaseClasses.Types.PrescribedVariable.Speed,
    computePowerUsingSimilarityLaws=true)
    "FlowMachineInterface with per.etaHydMet=.NotProvided"
  AixLib.Fluid.Movers.BaseClasses.FlowMachineInterface eff2(
    per(
      powerOrEfficiencyIsHydraulic=per.powerOrEfficiencyIsHydraulic,
      pressure=per.pressure,
      etaMotMet=per.etaMotMet,
      etaHydMet=AixLib.Fluid.Movers.BaseClasses.Types.HydraulicEfficiencyMethod.Efficiency_VolumeFlowRate,
      efficiency(V_flow={0,0.3,0.6,0.8,1}, eta={0,0.5,0.7,0.5,0})),
    rho_default=rhoFlu,
    nOri=2,
    preVar=AixLib.Fluid.Movers.BaseClasses.Types.PrescribedVariable.Speed,
    computePowerUsingSimilarityLaws=true)
    "FlowMachineInterface with per.etaHydMet=.Efficiency_VolumeFlowRate"
  AixLib.Fluid.Movers.BaseClasses.FlowMachineInterface eff3(
    per(
      powerOrEfficiencyIsHydraulic=per.powerOrEfficiencyIsHydraulic,
      pressure=per.pressure,
      etaMotMet=per.etaMotMet,
      etaHydMet=AixLib.Fluid.Movers.BaseClasses.Types.HydraulicEfficiencyMethod.Power_VolumeFlowRate,
      power(V_flow={0,0.25,0.5,0.75,1}, P={480,540,510,550,710})),
    rho_default=rhoFlu,
    nOri=2,
    preVar=AixLib.Fluid.Movers.BaseClasses.Types.PrescribedVariable.Speed,
    computePowerUsingSimilarityLaws=true)
    "FlowMachineInterface with per.etaHydMet=.Power_VolumeFlowRate"
  AixLib.Fluid.Movers.BaseClasses.FlowMachineInterface eff4(
    per(
      powerOrEfficiencyIsHydraulic=per.powerOrEfficiencyIsHydraulic,
      pressure=per.pressure,
      etaMotMet=per.etaMotMet,
      etaHydMet=AixLib.Fluid.Movers.BaseClasses.Types.HydraulicEfficiencyMethod.EulerNumber,
      peak(
        V_flow=0.5,
        dp=500,
        eta=0.7)),
    rho_default=rhoFlu,
    nOri=2,
    preVar=AixLib.Fluid.Movers.BaseClasses.Types.PrescribedVariable.Speed,
    computePowerUsingSimilarityLaws=true)
    "FlowMachineInterface with per.etaHydMet=.EulerNumber"

  Modelica.Blocks.Sources.Constant y(k=1) "Relative speed"
  Modelica.Blocks.Sources.Ramp m_flow(height=rho.k, duration=1) "Mass flow rate"
  Modelica.Blocks.Sources.Constant rho(k=rhoFlu) "Density"

equation
  connect(eff3.rho, rho.y)
  connect(rho.y,eff4. rho)
  connect(m_flow.y,eff3. m_flow)
  connect(m_flow.y,eff4. m_flow)
  connect(m_flow.y, eff1.m_flow)
  connect(m_flow.y, eff2.m_flow)
  connect(rho.y, eff2.rho)
  connect(rho.y, eff1.rho)
  connect(y.y, eff1.y_in)
  connect(y.y, eff2.y_in)
  connect(y.y, eff3.y_in)
  connect(y.y, eff4.y_in)
end HydraulicEfficiencyMethods;


Validation model for different motor efficiency options. This is a simple validation model for

AixLib.Fluid.Movers.BaseClasses.FlowMachineInterface
where its motor efficiency ηmot is specified with
different methods defined in

AixLib.Fluid.Movers.BaseClasses.Types.MotorEfficiencyMethod.
The instance eff4 specifies ηmot as
a function of motor PLR by finding a generic curve with the maximum motor
efficiency and rated motor input power. The generic curve is generated by

AixLib.Fluid.Movers.BaseClasses.Characteristics.motorEfficiencyCurve.

within AixLib.Fluid.Movers.BaseClasses.Validation;
model MotorEfficiencyMethods
  "Validation model for different motor efficiency options"
  extends Modelica.Icons.Example;

  AixLib.Fluid.Movers.Data.Generic per(
    final pressure(V_flow={0,1}, dp={1000,0}),
    final etaHydMet=AixLib.Fluid.Movers.BaseClasses.Types.HydraulicEfficiencyMethod.NotProvided)
    "Performance record";
  parameter Modelica.Units.SI.Density rhoFlu=1.2 "Fluid density";

  AixLib.Fluid.Movers.BaseClasses.FlowMachineInterface eff1(
    per(
      pressure=per.pressure,
      etaHydMet=per.etaHydMet,
      etaMotMet=AixLib.Fluid.Movers.BaseClasses.Types.MotorEfficiencyMethod.NotProvided),
    rho_default=rhoFlu,
    nOri=2,
    preVar=AixLib.Fluid.Movers.BaseClasses.Types.PrescribedVariable.Speed,
    computePowerUsingSimilarityLaws=true)
    "FlowMachineInterface with per.etaMotMet=.NotProvided"
  AixLib.Fluid.Movers.BaseClasses.FlowMachineInterface eff2(
    per(
      pressure=per.pressure,
      etaHydMet=per.etaHydMet,
      etaMotMet=AixLib.Fluid.Movers.BaseClasses.Types.MotorEfficiencyMethod.Efficiency_VolumeFlowRate,
      motorEfficiency(V_flow={0,0.3,0.6,1}, eta={0,0.4,0.6,0.7})),
    rho_default=rhoFlu,
    nOri=2,
    preVar=AixLib.Fluid.Movers.BaseClasses.Types.PrescribedVariable.Speed,
    computePowerUsingSimilarityLaws=true)
    "FlowMachineInterface with per.etaMotMet=.Efficiency_VolumeFlowRate"

  AixLib.Fluid.Movers.BaseClasses.FlowMachineInterface eff3(
    per(
      pressure=per.pressure,
      etaHydMet=per.etaHydMet,
      etaMotMet=AixLib.Fluid.Movers.BaseClasses.Types.MotorEfficiencyMethod.Efficiency_MotorPartLoadRatio,
      motorEfficiency_yMot(y={0,0.25,0.5,1}, eta={0,0.56,0.7,0.7}),
      WMot_nominal=500),
    rho_default=rhoFlu,
    nOri=2,
    preVar=AixLib.Fluid.Movers.BaseClasses.Types.PrescribedVariable.Speed,
    computePowerUsingSimilarityLaws=true)
    "FlowMachineInterface with per.etaMotMet=.Efficiency_MotorPartLoadRatio"
  AixLib.Fluid.Movers.BaseClasses.FlowMachineInterface eff4(
    per(
      pressure=per.pressure,
      etaHydMet=per.etaHydMet,
      etaMotMet=AixLib.Fluid.Movers.BaseClasses.Types.MotorEfficiencyMethod.GenericCurve,
      etaMot_max=0.7,
      WMot_nominal=500),
    rho_default=rhoFlu,
    nOri=2,
    preVar=AixLib.Fluid.Movers.BaseClasses.Types.PrescribedVariable.Speed,
    computePowerUsingSimilarityLaws=true)
    "FlowMachineInterface with per.etaMotMet=.GenericCurve"

  Modelica.Blocks.Sources.Constant y(k=1) "Relative speed"
  Modelica.Blocks.Sources.Ramp m_flow(height=1*rhoFlu, duration=1) "Mass flow rate"
  Modelica.Blocks.Sources.Constant rho(k=rhoFlu) "Density"

equation
  connect(eff3.rho, rho.y)
  connect(rho.y,eff4. rho)
  connect(m_flow.y,eff3. m_flow)
  connect(m_flow.y,eff4. m_flow)
  connect(m_flow.y, eff1.m_flow)
  connect(m_flow.y, eff2.m_flow)
  connect(rho.y, eff2.rho)
  connect(rho.y, eff1.rho)
  connect(y.y, eff1.y_in)
  connect(y.y, eff2.y_in)
  connect(y.y, eff3.y_in)
  connect(y.y, eff4.y_in)
end MotorEfficiencyMethods;


within AixLib.Fluid.Movers.BaseClasses.Validation;
model NegativePressureOrFlow
  "A validation model that tests the mover behaviour when the pressure rise or flow is negative"
  extends Modelica.Icons.Example;

  package Medium = AixLib.Media.Air;

  parameter Modelica.Units.SI.MassFlowRate m_flow_nominal=0.1
    "Nominal mass flow rate";
  parameter Modelica.Units.SI.PressureDifference dp_nominal=10000
    "Nominal pressure difference";
  parameter Modelica.Units.SI.Density rho_default=1.2
    "Fluid density at medium default state";

  AixLib.Fluid.Movers.BaseClasses.FlowMachineInterface eff(
    per(pressure(V_flow=m_flow_nominal/rho_default*{0,2},
                 dp=dp_nominal*{2,0}),
        etaHydMet=AixLib.Fluid.Movers.BaseClasses.Types.HydraulicEfficiencyMethod.NotProvided,
        etaMotMet=AixLib.Fluid.Movers.BaseClasses.Types.MotorEfficiencyMethod.NotProvided),
    preVar=AixLib.Fluid.Movers.BaseClasses.Types.PrescribedVariable.PressureDifference,
    computePowerUsingSimilarityLaws=true,
    rho_default=rho_default,
    nOri=2)
    "FlowMachineInterface model with prescribed pressure"
  Modelica.Blocks.Sources.Constant rho(k=rho_default) "Density"
  Modelica.Blocks.Sources.Ramp m_flow(
    height=2*m_flow_nominal,
    duration=3600,
    offset=-0.5*m_flow_nominal) "Mass flow rate"
  Modelica.Blocks.Sources.Ramp dp(
    height=-2*dp_nominal,
    duration=3600,
    offset=1.5*dp_nominal) "Pressure rise"
equation

  connect(eff.m_flow, m_flow.y)
  connect(rho.y, eff.rho)
  connect(dp.y, eff.dp_in)
end NegativePressureOrFlow;


Collection of validation models

within AixLib.Fluid.Movers.BaseClasses;
package Validation "Collection of validation models"
  extends Modelica.Icons.ExamplesPackage;
end Validation;


Simple model to validate PowerInterface. Simple validation model for the power interface model.

within AixLib.Fluid.Movers.BaseClasses.Validation;
model PowerInterface "Simple model to validate PowerInterface"
  extends Modelica.Icons.Example;
  AixLib.Fluid.Movers.BaseClasses.PowerInterface powCoo(
    motorCooledByFluid=true,
    delta_V_flow=0.05) "Power interface model"
  Modelica.Blocks.Sources.Constant WFlo(k=1*1000) "Flow work"
  Modelica.Blocks.Sources.Ramp V_flow(
    duration=1,
    height=1) "Volume flow rate"
  Modelica.Blocks.Sources.Constant WHyd(k=1250) "Hydraulic work"
  Modelica.Blocks.Sources.Constant PEle(k=1*1000*4) "Electrical work"
  AixLib.Fluid.Movers.BaseClasses.PowerInterface powNonCoo(
    motorCooledByFluid=false,
    delta_V_flow=0.05) "Power interface model"
equation
  connect(V_flow.y, powCoo.V_flow)
  connect(powCoo.WFlo, WFlo.y)
  connect(PEle.y, powCoo.PEle)
  connect(V_flow.y, powNonCoo.V_flow)
  connect(powNonCoo.WFlo, WFlo.y)
  connect(PEle.y, powNonCoo.PEle)
  connect(WHyd.y, powCoo.WHyd)
  connect(WHyd.y, powNonCoo.WHyd)
end PowerInterface;


Validation model for total efficiency specified via hydraulic efficiency options. This model is the same as

AixLib.Fluid.Movers.BaseClasses.Validation.HydraulicEfficiencyMethods
except that the enumeration is used for total efficiency η
via the parameter per.powerOrEfficiencyIsHydraulic.

within AixLib.Fluid.Movers.BaseClasses.Validation;
model TotalEfficiencyMethods
  "Validation model for total efficiency specified via hydraulic efficiency options"
  extends HydraulicEfficiencyMethods(
    per(powerOrEfficiencyIsHydraulic=false),
    eff2(per(efficiency(eta={0,0.35,0.49,0.35,0}))),
    eff3(per(power(P={680,771,730,780,1010}))),
    eff4(per(peak(eta=0.49))));
end TotalEfficiencyMethods;


within AixLib.Fluid.Movers;
package Compressors "Package that contains models of different compressor types"
  extends Modelica.Icons.Package;
end Compressors;


within AixLib.Fluid.Movers.Compressors;
package BaseClasses "Package that contains base classes used for the compressor models"
  extends Modelica.Icons.BasesPackage;
end BaseClasses;


within AixLib.Fluid.Movers.Compressors.BaseClasses;
partial model PartialCompression
  "Partial model for compression that contains basic definitions used in
  various compressor models"

  // Definition of parameters describing the geometry
  //
  parameter Modelica.Units.SI.Volume VDis(min=0) = 13e-6
    "Displacement volume of the compressor"
  parameter Modelica.Units.SI.Efficiency epsRef(
    min=0,
    max=1,
    nominal=0.05) = 0.04 "Ratio of the real and the ideal displacement volume"

  parameter Modelica.Units.SI.Frequency rotSpeMax(min=0) = 120
    "Maximal rotational speed executable by the compressor"
  parameter Real
    piPreMax(min=1, unit="1") = 15
    "Maximal pressure ratio executable by the compressor"

  parameter Boolean useInpFil = true
    "= true, if transient behaviour of rotational speed is computed"
  parameter Modelica.Units.SI.Time risTim=0.5
    "Time until rotational speed reaches 99.6 % of its set value"

  // Definition of models describing efficiencies
  //
  replaceable model EngineEfficiency =
    Utilities.EngineEfficiency.SpecifiedEfficiencies.ConstantEfficiency
    constrainedby Utilities.EngineEfficiency.PartialEngineEfficiency
    "Model that describes the calculation of the overall mechanic efficiency"
  replaceable model VolumetricEfficiency =
    Utilities.VolumetricEfficiency.SpecifiedEfficiencies.ConstantEfficiency
    constrainedby Utilities.VolumetricEfficiency.PartialVolumetricEfficiency
    "Model that describes the calculation of the overall volumetric efficiency"
  replaceable model IsentropicEfficiency =
    Utilities.IsentropicEfficiency.SpecifiedEfficiencies.ConstantEfficiency
    constrainedby Utilities.IsentropicEfficiency.PartialIsentropicEfficiency
    "Model that describes the calculation of the overall isentropic efficiency"

  // Definition of parameters describing the efficiencies
  //
  parameter Boolean useIseWor = oveEngEff.useIseWor
    "= true, if overal machanic efficiency is related to isentropic compressor
    work"

  // Extensions and parameter propagation
  //
  extends AixLib.Fluid.Interfaces.PartialTwoPortTransport(
    redeclare replaceable package Medium =
        Modelica.Media.R134a.R134a_ph,
    dp_start=-20e5,
    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 nominal conditions
  //
  parameter Modelica.Units.SI.MassFlowRate m_flow_nominal=0.1
    "Nominal mass flow rate"

  // Definition of parameters describing diagnostics
  //
  parameter Boolean show_staEff = false
    "= true, if thermodynamic states and efficiencies are computed"
  parameter Boolean show_qua = false
    "= true, if vapour qualities are computed"

  // Definition of parameters used for initialisation
  //
  parameter Modelica.Units.SI.Frequency rotSpe0=60
    "Compressor's rotational spped at initialisation"
  parameter Modelica.Units.SI.AbsolutePressure pInl0=3e5
    "Pressure at compressor's inlet at initialisation"
  parameter Modelica.Units.SI.Temperature TInl0=283.15
    "Temperature at compressor's inlet at initialisation"
  parameter Modelica.Units.SI.Density dInl0=Medium.density(Medium.setState_pTX(
      p=pInl0, T=TInl0)) "Density at compressor's inlet at initialisation"
  parameter Modelica.Units.SI.SpecificEnthalpy hInl0=Medium.specificEnthalpy(
      Medium.setState_pTX(p=pInl0, T=TInl0))
    "Specific enthalpy at compressor's inlet at initialisation"

  // Definition of connectors and submodels
  //
  Modelica.Blocks.Interfaces.RealInput
    manVarCom(start=rotSpe0, quantity = "Velocity", unit = ("1/s"))
    "Prescribed compressor's rotational speed"
  Modelica.Blocks.Interfaces.RealOutput
    curManVarCom(quantity="Velocity", unit=("1/s"))
    "Current compressor's rotational speed"
  Modelica.Blocks.Continuous.Filter filRotSpe(
    final analogFilter=Modelica.Blocks.Types.AnalogFilter.CriticalDamping,
    final filterType=Modelica.Blocks.Types.FilterType.LowPass,
    final order=2,
    final f_cut=5/(2*Modelica.Constants.pi*risTim),
    final x(each stateSelect=StateSelect.always)) if useInpFil
    "Second order filter to approximate change of compressor's rotational speed"
  Modelica.Blocks.Routing.RealPassThrough rotSpeThr
    "Dummy passing through of compressor's rotational speed to allow usage of filter"
  Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b heatPort
    "Heat port connector to calculate heat losses to ambient"

  // Definition of models
  //
  EngineEfficiency oveEngEff(
    redeclare package Medium=Medium,
    epsRef=epsRef,
    VDis=VDis,
    rotSpe=rotSpe,
    piPre=piPre,
    staInl=staInl,
    staOut=staOut,
    TAmb=heatPort.T)
    "Instance of model 'engine efficiency'";
  VolumetricEfficiency oveVolEff(
    redeclare package Medium=Medium,
    epsRef=epsRef,
    VDis=VDis,
    rotSpe=rotSpe,
    piPre=piPre,
    staInl=staInl,
    staOut=staOut,
    TAmb=heatPort.T)
    "Instance of model 'volumetric efficiency'";
  IsentropicEfficiency oveIseEff(
    redeclare package Medium=Medium,
    epsRef=epsRef,
    VDis=VDis,
    rotSpe=rotSpe,
    piPre=piPre,
    staInl=staInl,
    staOut=staOut,
    TAmb=heatPort.T)
    "Instance of model 'isentropic efficiency'";

  // Definition of records containing detailed results if computed
  //
  record CompressorStates
    "Record that contains compressor's thermodynamic states at inlet and outlet"
    Medium.ThermodynamicState staInl
      "Thermodynamic state at inlet conditions";
    Medium.ThermodynamicState staOut
      "Thermodynamic state at outlet conditions";

    Modelica.Units.SI.SpecificEntropy sInl
      "Specific entropy at inlet conditions";
    Modelica.Units.SI.SpecificEntropy sOut
      "Specific entropy at outlet conditions";

    Modelica.Units.SI.Efficiency etaEng "Overall engine efficiency";
    Modelica.Units.SI.Efficiency etaVol "Overall volumetric efficiency";
    Modelica.Units.SI.Efficiency etaIse "Overall isentropic efficiency";
  end CompressorStates;

  record CompressorQualities
    "Record that contains compressor's qualities at inlet and outlet"
     Medium.SaturationProperties satProInl
      "Saturation properties at inlet conditions";
     Medium.SaturationProperties satProOut
      "Saturation properties at outlet conditions";

    Real pTriCriInl(min=0)
      "Trigger to check medium exceeds critical pressure at inlet";
    Real pTriCriOut(min=0)
      "Trigger to check medium exceeds critical pressure at inlet";
    Real quaInl(min=0, max=1, unit="1")
      "Vapour quality at inlet conditions";
    Real quaOut(min=0, max=1, unit="1")
      "Vapour quality at outlet conditions";

    Modelica.Units.SI.SpecificEnthalpy hLiqInl "Liquid enthalpy at inlet";
    Modelica.Units.SI.SpecificEnthalpy hVapInl "Vapour enthalpy at inlet";
    Modelica.Units.SI.SpecificEnthalpy hLiqOut "Liquid enthalpy at outlet";
    Modelica.Units.SI.SpecificEnthalpy hVapOut "Vapour enthalpy at outlet";
  end CompressorQualities;

  CompressorStates comSta(
    staInl=staInl,
    staOut=staOut,
    sInl=Medium.specificEntropy(staInl),
    sOut=Medium.specificEntropy(staOut),
    etaEng=oveEngEff.etaEng,
    etaVol=oveVolEff.lamH,
    etaIse=oveIseEff.etaIse) if show_staEff
    "Record containing compressor's thermodynamic states and efficiencies";

  CompressorQualities comQua(
    satProInl=Medium.setSat_p(pInl),
    satProOut=Medium.setSat_p(pOut),
    pTriCriInl=pInl/Medium.fluidConstants[1].criticalPressure,
    pTriCriOut=pOut/Medium.fluidConstants[1].criticalPressure,
    hLiqInl=Medium.bubbleEnthalpy(Medium.setSat_p(pInl)),
    hVapInl=Medium.dewEnthalpy(Medium.setSat_p(pInl)),
    hLiqOut=Medium.bubbleEnthalpy(Medium.setSat_p(pOut)),
    hVapOut=Medium.dewEnthalpy(Medium.setSat_p(pOut)),
    quaInl=noEvent(if ((pInl/Medium.fluidConstants[1].criticalPressure)<1 and
             hInl<Medium.bubbleEnthalpy(Medium.setSat_p(pInl))) then 0
             else if ((pInl/Medium.fluidConstants[1].criticalPressure)<1 and
             hInl>Medium.bubbleEnthalpy(Medium.setSat_p(pInl)) and
             hInl<Medium.dewEnthalpy(Medium.setSat_p(pInl))) then
             (hInl - Medium.bubbleEnthalpy(Medium.setSat_p(pInl)))/
             max(Medium.dewEnthalpy(Medium.setSat_p(pInl)) -
             Medium.bubbleEnthalpy(Medium.setSat_p(pInl)), 1e-6) else 1.0),
    quaOut=noEvent(if ((pOut/Medium.fluidConstants[1].criticalPressure)<1 and
             hOut<Medium.bubbleEnthalpy(Medium.setSat_p(pOut))) then 0
             else if ((pOut/Medium.fluidConstants[1].criticalPressure)<1 and
             hOut>Medium.bubbleEnthalpy(Medium.setSat_p(pOut)) and
             hOut<Medium.dewEnthalpy(Medium.setSat_p(pOut))) then
             (hOut - Medium.bubbleEnthalpy(Medium.setSat_p(pOut)))/
             max(Medium.dewEnthalpy(Medium.setSat_p(pOut)) -
             Medium.bubbleEnthalpy(Medium.setSat_p(pOut)), 1e-6) else 1.0))
 if show_qua
    "Record containing compressor's vapour qualities";

  // Definition of variables
  //
  Modelica.Units.SI.Power PEle
    "Compressor's current electrical power consumption";
  Modelica.Units.SI.Power Q_flow_ref
    "Current power transferred to reffrigerant";

  Modelica.Units.SI.Frequency rotSpe(min=0, max=rotSpeMax)
    "Compressor's current rotational speed";
  Real piPre(min=0, max=piPreMax, unit="1")
    "Ratio of compressor's outlet and inlet pressure";

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

  Modelica.Units.SI.AbsolutePressure pInl(start=pInl0)
    "Pressure at inlet conditions";
  Modelica.Units.SI.SpecificEnthalpy hInl(start=hInl0)
    "Specific enthalpy at inlet conditions";
  Modelica.Units.SI.Density dInl "Density at inlet conditions";

  Modelica.Units.SI.AbsolutePressure pOut(start=pInl0 - dp_start)
    "Pressure at outlet conditions";
  Modelica.Units.SI.SpecificEnthalpy hOut
    "Specific enthalpy at outlet conditions";

  Modelica.Units.SI.SpecificEnthalpy hOutIse
    "Specific isentropic enthalpy at outlet conditions";
  Modelica.Units.SI.SpecificEnthalpy dh
    "Specific enthalpy difference: hOut - hInl";
  Modelica.Units.SI.SpecificEnthalpy dhIse
    "Specific isentropic enthalpy difference: hOutIse - hInl";

equation
  // Provide assertions to check physical correctness
  //
  assert(piPre<=piPreMax, "Pressure ratio is greater than maximum pressure
    ratio allowed! Please check boundary condtions!",
    level = AssertionLevel.warning);
  assert(
    curManVarCom <= rotSpeMax,
    "Rotational speed is greater than maximum
  rotational speed allowed! Please check boundary condtions!",
    level=AssertionLevel.warning);
  assert(oveEngEff.etaEng<0.9999,
    "Overall engine efficiency is greater than one!
    Please check efficiency model!",
    level = AssertionLevel.warning);
  assert(oveVolEff.lamH<0.9999,
    "Overall volumetric efficiency is greater than one!
    Please check efficiency model!",
    level = AssertionLevel.warning);
  assert(oveIseEff.etaIse<0.9999,
    "Overall isentropic efficiency is greater than one!
    Please check efficiency model!",
    level = AssertionLevel.warning);

  // Calculation of thermodynamic state at inlet conditions
  //
  staInl = Medium.setState_phX(p=pInl,h=hInl) "Thermodynamic state at inlet";
  dInl = Medium.density(staInl) "Density at inlet";

  // Calculation of thermodynamic state at outlet conditions
  //
  staOut = Medium.setState_phX(p=pOut,h=hOut) "Thermodynamic state at outlet";

  // Calculation of characteristics of the compressor
  //
  piPre = abs(pOut/pInl) "Ratio between outlet and inlet pressure";

  // Calculation of compressor's rotational speed
  //
  connect(filRotSpe.u, manVarCom);
  if useInpFil then
    connect(rotSpeThr.u, filRotSpe.y)
      "Transient behaviour of change of rotational speed";
  else
    connect(rotSpeThr.u, manVarCom)
      "No transient behaiviour of change of rotational speed";
  end if;
  rotSpe = smooth(1, noEvent(if rotSpeThr.y>0 then
                  rotSpeThr.y else 1e-12))
    "Passing through internal variable";
  curManVarCom = rotSpe "Current rotational speed";
end PartialCompression;


within AixLib.Fluid.Movers.Compressors.BaseClasses;
partial model PartialCompressor
  "Partial model for compressor that contains basic definitions used in
  various compressor models"

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

  // Definition of parameters describing general options
  //
  parameter Modelica.Units.SI.Volume VDis(min=0) = 13e-6
    "Displacement volume of the compressor"
  parameter Modelica.Units.SI.Efficiency epsRef(
    min=0,
    max=1,
    nominal=0.05) = 0.04 "Ratio of the real and the ideal displacement volume"
  parameter Modelica.Units.SI.Diameter diameterInl(min=0) = 12e-3
    "Diameter of the pipe at compressor's inlet"
  parameter Modelica.Units.SI.Diameter diameterOut(min=0) = 8e-3
    "Diameter of the pipe at compressor's outlet"

  parameter Modelica.Units.SI.Frequency rotSpeMax(min=0) = 120
    "Maximal rotational speed executable by the compressor"
  parameter Real
    piPreMax(min=1, unit="1") = 15
    "Maximal pressure ratio executable by the compressor"

  parameter Boolean useInpFil = true
    "= true, if transient behaviour of rotational speed is computed"
  parameter Modelica.Units.SI.Time risTim=0.5
    "Time until rotational speed reaches 99.6 % of its set value"

  // Definition of models describing efficiencies
  //
  replaceable model EngineEfficiency =
    Utilities.EngineEfficiency.SpecifiedEfficiencies.ConstantEfficiency
    constrainedby Utilities.EngineEfficiency.PartialEngineEfficiency
    "Model that describes the calculation of the overall mechanic efficiency"
  replaceable model VolumetricEfficiency =
    Utilities.VolumetricEfficiency.SpecifiedEfficiencies.ConstantEfficiency
    constrainedby Utilities.VolumetricEfficiency.PartialVolumetricEfficiency
    "Model that describes the calculation of the overall volumetric efficiency"
  replaceable model IsentropicEfficiency =
    AixLib.Fluid.Movers.Compressors.Utilities.IsentropicEfficiency.SpecifiedEfficiencies.ConstantEfficiency
    constrainedby Utilities.IsentropicEfficiency.PartialIsentropicEfficiency
    "Model that describes the calculation of the overall isentropic efficiency"

  // Definition of parameters describing pressure losses
  //
  parameter Real zetInl=
    ((1/0.59-1)^2+(1-(diameterInl/0.066)^2))*(1-(diameterInl/0.066)^2)
    "Pressure loss factor at compressor's inlet for flow of port_a -> port_b"
  parameter Real zetOut=
    ((1/0.59-1)^2+(1-(diameterOut/0.1122)^2))*(1-(diameterOut/0.1122)^2)
    "Pressure loss factor at compressor's outlet for flow of port_a -> port_b"

  parameter Boolean from_dp=false
    "= true, use m_flow = f(dp) else dp = f(m_flow)"
  parameter Boolean homotopyInitialization=true
    "= true, use homotopy method  for initialisation"
  parameter Boolean linearized=false
    "= true, use linear relation between m_flow and dp for any flow rate"

  // Definition of parameters describing heat losses
  //
  parameter Utilities.Types.HeatTransferModels
    heaTraMod=Utilities.Types.HeatTransferModels.Simplified
    "Choose heat transfer model for heat losses at compressor's inlet
    and outlet"
  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 kAMeaInl=25 "Effective mean thermal conductance between medium and fictitious wall
    at inlet"
  parameter Modelica.Units.SI.ThermalConductance kAMeaOut=35 "Effective mean thermal conductance between medium and fictitious wall
    at outlet"
  parameter Modelica.Units.SI.ThermalConductance kAMeaAmb=5 "Effective mean thermal conductance coefficient between fictitious wall
    and ambient"
  parameter Boolean iniTWal0=true
    "= true, if wall is initialised at fixed temperature; Otherwise, steady state
    initialisation"
  parameter Modelica.Units.SI.Temperature TWal0=293.15
    "Temperature of wall at initialisation"

  // Definition of parameters deschribing assumptions
  //
  parameter Boolean allowFlowReversal = true
    "= false to simplify equations, assuming, but not enforcing, no flow reversal"
  parameter Utilities.Types.SimpleCompressor simCom=
    Utilities.Types.SimpleCompressor.Default
    "Parameter used to activate or deactivate menue choices"

  // Definition of parameters describing advanced options
  //
  parameter Modelica.Units.SI.PressureDifference dp_start(displayUnit="Pa") = -20e5
    "Guess value of compressor's dp = port_a.p - port_b.p"
  parameter Medium.MassFlowRate m_flow_start = 0.5*m_flow_nominal
    "Guess value of compressor's m_flow = port_a.m_flowr"
  parameter Medium.MassFlowRate m_flow_small = 1e-6*m_flow_nominal
    "Small mass flow rate for regularization of compressor's zero flow"
  parameter Modelica.Units.SI.MassFlowRate m_flow_nominal=0.1
    "Nominal mass flow rate"

  // Definition of parameters describing diagnostics
  //
  parameter Boolean show_T = false
    "= true, if compressor's temperatures at port_a and port_b are computed"
  parameter Boolean show_V_flow = false
    "= true, if compressor's volume flow rate at inflowing port is computed"
  parameter Boolean show_staEff = false
    "= true, if thermodynamic states and efficiencies are computed"
  parameter Boolean show_qua = false
    "= true, if vapour qualities are computed"

  // Definition of parameters used for initialisation
  //
  parameter Modelica.Units.SI.Frequency rotSpe0=60
    "Compressor's rotational spped at initialisation"
  parameter Modelica.Units.SI.AbsolutePressure pInl0=3e5
    "Pressure at compressor's inlet at initialisation"
  parameter Modelica.Units.SI.Temperature TInl0=283.15
    "Temperature at compressor's inlet at initialisation"

  // Definition of submodels
  //
  replaceable model CompressionProcess =
    SimpleCompressors.CompressionProcesses.RotaryCompression
    constrainedby PartialCompression
    "Model of the compression process"

  CompressionProcess comPro(
    redeclare final package Medium = Medium,
    final VDis=VDis,
    final epsRef=epsRef,
    final rotSpeMax=rotSpeMax,
    final piPreMax=piPreMax,
    final useInpFil=useInpFil,
    final risTim=risTim,
    redeclare final model EngineEfficiency = EngineEfficiency,
    redeclare final model VolumetricEfficiency = VolumetricEfficiency,
    redeclare final model IsentropicEfficiency = IsentropicEfficiency,
    final allowFlowReversal=allowFlowReversal,
    final dp_start=dp_start,
    final m_flow_start=m_flow_start,
    final m_flow_small=m_flow_small,
    final show_T=show_T,
    final show_V_flow=show_V_flow,
    final m_flow_nominal=m_flow_nominal,
    final show_staEff=show_staEff,
    final show_qua=show_qua,
    final rotSpe0=rotSpe0,
    final pInl0=pInl0,
    final TInl0=TInl0)
    "Model describing compression process"

  /*To enable propagation of parameters, the compression process is introduced
    as a replaceable model and its instance propagates all parameters
    required.
  */

  // Definition of connectors
  //
  Modelica.Fluid.Interfaces.FluidPort_a port_a(
    redeclare final package Medium=Medium,
     m_flow(min=if allowFlowReversal then -Modelica.Constants.inf else 0),
     h_outflow(start=Medium.h_default))
    "Fluid connector a (positive design flow direction is from port_a to port_b)"
  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))

  Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b heatPort
    "Heat port connector to calculate heat losses to ambient"
  Modelica.Blocks.Interfaces.RealInput
    manVarCom(start=rotSpe0, quantity = "Velocity", unit = ("1/s"))
    "Prescribed compressor's rotational speed"
  Modelica.Blocks.Interfaces.RealOutput
    curManVarCom(quantity="Velocity", unit=("1/s"))
    "Current compressor's rotational speed"

equation
  // Connection of control signals
  //
  connect(manVarCom,comPro. manVarCom)
  connect(comPro.curManVarCom, curManVarCom)
end PartialCompressor;


within AixLib.Fluid.Movers.Compressors.BaseClasses;
partial model PartialEfficiency
  "Base model that is used to define all further efficiencies"

  // Definition of the medium used for calculations
  //
  replaceable package Medium =
    Modelica.Media.R134a.R134a_ph
    constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium
    "Medium of the model";

  // Definition of inputs
  //
  input Modelica.Units.SI.Efficiency epsRef(
    min=0,
    max=1,
    nominal=0.05) "Ratio of the real and the ideal displacement volume";
  input Modelica.Units.SI.Volume VDis(min=0) "Displacement volume";
  input Real piPre(min=0, unit="1")
    "Ratio of compressor's outlet and inlet pressure";
  input Modelica.Units.SI.Frequency rotSpe(min=0)
    "Compressor's current rotational speed";
  input Medium.ThermodynamicState staInl
    "Thermodynamic state at compressor's inlet";
  input Medium.ThermodynamicState staOut
    "Thermodynamic state at compressor's outlet";
  input Modelica.Units.SI.Temperature TAmb "Ambient temperature";
end PartialEfficiency;


within AixLib.Fluid.Movers.Compressors.BaseClasses;
partial model PartialModularCompressors
  "Base model for all modular compressor models"

  // Definition of the medium
  //
  replaceable package Medium = Modelica.Media.R134a.R134a_ph
      constrainedby Modelica.Media.Interfaces.PartialMedium
      "Medium in the component"

  // Definition of parameters describing the modular approach in general
  //
  parameter Integer nCom = 1
    "Number of compressors in parallel"

  // Definition of replaceable compressor models
  //
  replaceable model SimpleCompressor =
    SimpleCompressors.RotaryCompressors.RotaryCompressor
    constrainedby PartialCompressor
    "Model of the simple compressor in parallel"

  SimpleCompressor modCom[nCom](
    redeclare final package Medium=Medium,
    final VDis=VDis,
    final epsRef=epsRef,
    final diameterInl=diameterInl,
    final diameterOut=diameterOut,
    final rotSpeMax=rotSpeMax,
    final piPreMax=piPreMax,
    final useInpFil=useInpFil,
    final risTim=risTim,
    redeclare final model EngineEfficiency=EngineEfficiency,
    redeclare final model VolumetricEfficiency=VolumetricEfficiency,
    redeclare final model IsentropicEfficiency=IsentropicEfficiency,
    final zetInl=zetInl,
    final zetOut=zetOut,
    final from_dp=from_dp,
    final homotopyInitialization=homotopyInitialization,
    final linearized=linearized,
    final heaTraMod=heaTraMod,
    final mWal=mWal,
    final cpWal=cpWal,
    final kAMeaInl=kAMeaInl,
    final kAMeaOut=kAMeaOut,
    final kAMeaAmb=kAMeaAmb,
    final iniTWal0=iniTWal0,
    final TWal0=TWal0,
    each final allowFlowReversal=allowFlowReversal,
    each final dp_start=dp_start,
    each final m_flow_start=m_flow_start,
    each final m_flow_small=m_flow_small,
    each final m_flow_nominal=m_flow_nominal,
    each final show_T=show_T,
    each final show_V_flow=show_V_flow,
    each final show_staEff=show_staEff,
    each final show_qua=show_qua,
    final rotSpe0=rotSpe0,
    final pInl0=pInl0,
    final TInl0=TInl0)
    "Array of compressor models in parallel"

  /*To enable propagation of parameters, the simple compressor is introduced
    as a replaceable model and its instance propagates all parameters
    required.
  */

  // Definition of parameters describing general options
  //
  parameter Modelica.Units.SI.Volume VDis[nCom](min=0) = fill(13e-6, nCom)
    "Displacement volume of the compressor"
  parameter Modelica.Units.SI.Efficiency epsRef[nCom](
    min=0,
    max=1,
    nominal=0.05) = fill(0.04, nCom)
    "Ratio of the real and the ideal displacement volume"
  parameter Modelica.Units.SI.Diameter diameterInl[nCom](min=0) = fill(12e-3,
    nCom) "Diameter of the pipe at compressor's inlet"
  parameter Modelica.Units.SI.Diameter diameterOut[nCom](min=0) = fill(8e-3,
    nCom) "Diameter of the pipe at compressor's outlet"

  parameter Modelica.Units.SI.Frequency rotSpeMax[nCom](min=0) = fill(120, nCom)
    "Maximal rotational speed executable by the compressor"
  parameter Real
    piPreMax[nCom](min=1, unit="1") = fill(15, nCom)
    "Maximal pressure ratio executable by the compressor"

  parameter Boolean useInpFil[nCom] = fill(true, nCom)
    "= true, if transient behaviour of rotational speed is computed"
  parameter Modelica.Units.SI.Time risTim[nCom]=fill(0.5, nCom)
    "Time until rotational speed reaches 99.6 % of its set value"

  // Definition of models describing efficiencies
  //
  replaceable model EngineEfficiency =
    Utilities.EngineEfficiency.SpecifiedEfficiencies.ConstantEfficiency
    constrainedby Utilities.EngineEfficiency.PartialEngineEfficiency
    "Model that describes the calculation of the overall mechanic efficiency"
  replaceable model VolumetricEfficiency =
    Utilities.VolumetricEfficiency.SpecifiedEfficiencies.ConstantEfficiency
    constrainedby Utilities.VolumetricEfficiency.PartialVolumetricEfficiency
    "Model that describes the calculation of the overall volumetric efficiency"
  replaceable model IsentropicEfficiency =
    AixLib.Fluid.Movers.Compressors.Utilities.IsentropicEfficiency.SpecifiedEfficiencies.ConstantEfficiency
    constrainedby Utilities.IsentropicEfficiency.PartialIsentropicEfficiency
    "Model that describes the calculation of the overall isentropic efficiency"

  // Definition of replaceable controller model
  //
  replaceable model ModularController =
    Controls.HeatPump.ModularHeatPumps.ModularCompressorController
    constrainedby Controls.HeatPump.ModularHeatPumps.BaseClasses.PartialModularController
    "Model of the modular controller"

  ModularController modCon(
    final nCom=nCom,
    final useExt=useExt,
    final controllerType=controllerType,
    final reverseAction=reverseAction,
    final reset=reset,
    final k=k,
    final Ti=Ti,
    final Ni=Ni,
    final Td=Td,
    final Nd=Nd,
    final wp=wp,
    final wd=wd,
    final yMax=yMax,
    final yMin=yMin,
    final initType=initType,
    final xi_start=xi_start,
    final xd_start=xd_start,
    final y_start=y_start)
    "Model of internal controller"

  /*To enable propagation of parameters, the modular compressor is introduced
    as a replaceable model and its instance propagates all parameters
    required.
  */

  // Definition of parameters describing the expansion valve controller
  //
  parameter Boolean useExt = true
    "= true, if external signal is used instead of internal controllers"
  parameter Modelica.Blocks.Types.SimpleController controllerType[nCom]=
    fill(Modelica.Blocks.Types.SimpleController.PID, nCom)
    "Type of controller"
  parameter Boolean reverseAction[nCom] = fill(false, nCom)
    "= true, if medium flow rate is throttled through cooling coil controller"
  parameter AixLib.Types.Reset reset[nCom]=
    fill(AixLib.Types.Reset.Disabled, nCom)
    "Type of controller output reset"

  parameter Real k[nCom] = fill(1, nCom)
    "Gain of controller"
  parameter Modelica.Units.SI.Time Ti[nCom]=fill(0.5, nCom)
    "Time constant of integrator block"
  parameter Real Ni[nCom] = fill(0.9, nCom)
    "Ni*Ti is time constant of anti-windup compensation"
  parameter Modelica.Units.SI.Time Td[nCom]=fill(0.1, nCom)
    "Time constant of derivative block"
  parameter Real Nd[nCom] = fill(10, nCom)
    "The higher Nd, the more ideal the derivative block"

  parameter Real wp[nCom] = fill(1, nCom)
    "Set-point weight for Proportional block (0..1)"
  parameter Real wd[nCom] = fill(0, nCom)
    "Set-point weight for Derivative block (0..1)"
  parameter Real yMax[nCom] = fill(1, nCom)
    "Upper limit of output"
  parameter Real yMin[nCom] = fill(0, nCom)
    "Lower limit of output"

  /*Parameters presented above are used to define each element of the
    compressor controller. Therefore, the parameters are identically to the
    parameters of the controller aside from the fact that the
    parameters are introduced as arraies
  */

  // Definition of parameters describing pressure losses
  //
  parameter Real zetInl[nCom]=
    {((1/0.59-1)^2+(1-(diameterInl[i]/0.066)^2))*(1-(diameterInl[i]/0.066)^2)
    for i in 1:nCom}
    "Pressure loss factor at compressor's inlet for flow of port_a -> port_b"
  parameter Real zetOut[nCom]=
    {((1/0.59-1)^2+(1-(diameterOut[i]/0.1122)^2))*(1-(diameterOut[i]/0.1122)^2)
    for i in 1:nCom}
    "Pressure loss factor at compressor's outlet for flow of port_a -> port_b"

  parameter Boolean from_dp[nCom] = fill(false, nCom)
    "= true, use m_flow = f(dp) else dp = f(m_flow)"
  parameter Boolean homotopyInitialization[nCom] = fill(true, nCom)
    "= true, use homotopy method  for initialisation"
  parameter Boolean linearized[nCom] = fill(false, nCom)
    "= true, use linear relation between m_flow and dp for any flow rate"

  // Definition of parameters describing heat losses
  //
  parameter Utilities.Types.HeatTransferModels
    heaTraMod[nCom] = fill(Utilities.Types.HeatTransferModels.Simplified, nCom)
    "Choose heat transfer model for heat losses at compressor's inlet
    and outlet"
  parameter Modelica.Units.SI.Mass mWal[nCom]=fill(2.5, nCom)
    "Mass of the fictitious wall"
  parameter Modelica.Units.SI.SpecificHeatCapacity cpWal[nCom]=fill(450, nCom)
    "Specific heat capacity of the fictitious wall"
  parameter Modelica.Units.SI.ThermalConductance kAMeaInl[nCom]=fill(25, nCom) "Effective mean thermal conductance between medium and fictitious wall
    at inlet"
  parameter Modelica.Units.SI.ThermalConductance kAMeaOut[nCom]=fill(35, nCom) "Effective mean thermal conductance between medium and fictitious wall
    at outlet"
  parameter Modelica.Units.SI.ThermalConductance kAMeaAmb[nCom]=fill(10, nCom) "Effective mean thermal conductance coefficient between fictitious wall
    and ambient"
  parameter Boolean iniTWal0[nCom] = fill(true, nCom)
    "= true, if wall is initialised at fixed temperature; Otherwise, steady state
    initialisation"
  parameter Modelica.Units.SI.Temperature TWal0[nCom]=fill(293.15, nCom)
    "Temperature of wall at initialisation"

  // Definition of parameters describing advanced options
  //
  parameter Modelica.Units.SI.PressureDifference dp_start(displayUnit="Pa") = -20e5
    "Guess value of compressor's dp = port_a.p - port_b.p"
  parameter Medium.MassFlowRate m_flow_start = 0.5*m_flow_nominal
    "Guess value of compressor's m_flow = port_a.m_flowr"
  parameter Medium.MassFlowRate m_flow_small = 1e-6*m_flow_nominal
    "Small mass flow rate for regularization of compressor's zero flow"
  parameter Modelica.Units.SI.MassFlowRate m_flow_nominal=0.1
    "Nominal mass flow rate"

  // Definition of parameters describing diagnostics
  //
  parameter Boolean show_T = false
    "= true, if compressor's temperatures at port_a and port_b are computed"
  parameter Boolean show_V_flow = false
    "= true, if compressor's volume flow rate at inflowing port is computed"
  parameter Boolean show_staEff = false
    "= true, if thermodynamic states and efficiencies are computed"
  parameter Boolean show_qua = false
    "= true, if vapour qualities are computed"
  parameter Boolean show_parCom = true
    "= true, if compressors' input parameters are shown in results"
  parameter Boolean show_parCon = true
    "= true, if controller's input parameters are shown in results"

  // Definition of parameters used for initialisation
  //
  parameter Modelica.Units.SI.Frequency rotSpe0[nCom]=fill(60, nCom)
    "Compressor's rotational spped at initialisation"
  parameter Modelica.Units.SI.AbsolutePressure pInl0[nCom]=fill(3e5, nCom)
    "Pressure at compressor's inlet at initialisation"
  parameter Modelica.Units.SI.Temperature TInl0[nCom]=fill(283.15, nCom)
    "Temperature at compressor's inlet at initialisation"
  parameter Modelica.Blocks.Types.Init initType[nCom]=fill(Modelica.Blocks.Types.Init.InitialState,
      nCom)
    "Init: (1: no init, 2: steady state, 3: initial state, 4: initial output)"
  parameter Real xi_start[nCom]=fill(0, nCom)
    "Initial or guess value value for integrator output (= integrator state)"
  parameter Real xd_start[nCom]=fill(0, nCom)
    "Initial or guess value for state of derivative block"
  parameter Real y_start[nCom]=fill(0, nCom)
    "Initial value of output"

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

  // Definition of connectors
  //
  Modelica.Fluid.Interfaces.FluidPort_a port_a(
    redeclare final package Medium = Medium,
     m_flow(min=if allowFlowReversal then -Modelica.Constants.inf else 0),
     h_outflow(start = Medium.h_default))
    "Fluid connector a (positive design flow direction is from port_a to port_b)"
  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.Thermal.HeatTransfer.Interfaces.HeatPort_b heatPort[nCom]
    "Heat port for compressors' heat losses"
  Controls.Interfaces.ModularHeatPumpControlBus dataBus(
    final nCom=nCom)
    "Connector that contains all relevant control signals"

protected
  parameter Utilities.Types.SimpleCompressor simCom = modCom[1].simCom
    "Parameter used to activate or deactivate menue choices";

equation
  // Connect port_a with inlet ports of expansion valves and connect heat ports
  //
  for i in 1:nCom loop
    connect(port_a,modCom[i].port_a);
  end for;
  connect(heatPort,modCom.heatPort);

  // Connect data bus and further control signals
  //
  connect(modCon.dataBus, dataBus)
  connect(modCon.manVar, modCom.manVarCom)
  connect(modCom.curManVarCom, modCon.curManVar)
end PartialModularCompressors;


within AixLib.Fluid.Movers.Compressors.Examples;
model ModularRotaryCompressor
  "Example model to test modular rotary compressors"
  extends Modelica.Icons.Example;

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

  parameter Integer nCom = 2
    "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 SimpleCompressor =
        SimpleCompressors.RotaryCompressors.RotaryCompressor,
    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,
    redeclare model ModularController =
        Controls.HeatPump.ModularHeatPumps.ModularCompressorController,
    useExt=false,
    show_parCom=false,
    show_parCon=false,
    VDis={5e-6,14e-6},
    useInpFil={true,true},
    risTim={0.25,0.5},
    yMax={120,120})
    "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(
    f=1,
    amplitude=50,
    offset=50) "Input signal to prediscribe compressors' rotational speeds"
  Modelica.Blocks.Routing.Replicator repRotSpe(nout=nCom)
    "Replicating the compressors' rotational speedsl"
  Modelica.Blocks.Routing.Replicator repInt(nout=nCom)
    "Replicating the internal set signal"
  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, repRotSpe.u)
  connect(rotSpe.y, repInt.u)
  connect(repInt.y, dataBus.comBus.intSetPoiCom)
  connect(repRotSpe.y, dataBus.comBus.extManVarCom)
  connect(repMea.y, dataBus.comBus.meaConVarCom)
end ModularRotaryCompressor;


Package that contains example models

within AixLib.Fluid.Movers.Compressors;
package Examples "Package that contains example models"
  extends Modelica.Icons.ExamplesPackage;
end Examples;


within AixLib.Fluid.Movers.Compressors.Examples;
model RotaryCompressor
  "Example model to test simple rotary compressors"
  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 + 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,
    nPorts=1,
    p=pInl,
    T=TOut) "Source with constant pressure and temperature"
  Modelica.Blocks.Sources.Sine rotSpe(
    amplitude=40,
    offset=80,
    f=1) "Prescribed compressor's rotational speed"
  Modelica.Thermal.HeatTransfer.Sources.FixedTemperature fixTem(T=283.15)
    "Fixed ambient temperature"
  SimpleCompressors.RotaryCompressors.RotaryCompressor rotCom(
    redeclare package Medium = Medium,
    show_staEff=true,
    show_qua=true,
    useInpFil=true,
    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"

  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"

equation
  // Connection of components
  //
  connect(source.ports[1], rotCom.port_a)
  connect(rotCom.port_b, simVal.port_a)
  connect(simVal.port_b, sink.ports[1])
  connect(rotSpe.y, rotCom.manVarCom)
  connect(valOpe.y, simVal.opening)
  connect(fixTem.port, rotCom.heatPort)
end RotaryCompressor;


within AixLib.Fluid.Movers.Compressors.Examples;
model RotaryCompressorPressureHeatLosses
  "Example model to test simple rotary compressors with pressure and heat losses"
  extends Modelica.Icons.Example;
  extends Modelica.Icons.UnderConstruction;

  // 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 + 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,
    nPorts=1,
    p=pInl,
    T=TOut) "Source with constant pressure and temperature"
  Modelica.Blocks.Sources.Sine rotSpe(
    amplitude=40,
    offset=80,
    f=1) "Prescribed compressor's rotational speed"
  Modelica.Thermal.HeatTransfer.Sources.FixedTemperature fixTem(T=283.15)
    "Fixed ambient temperature"
  SimpleCompressors.RotaryCompressors.RotaryCompressorPressureHeatLosses rotCom(
    redeclare package Medium = Medium,
    show_staEff=true,
    show_qua=true,
    useInpFil=true,
    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,
    kAMeaInl=5,
    kAMeaOut=15,
    kAMeaAmb=3) "Model of a rotary compressor"

  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"
  MixingVolumes.MixingVolume sink(
    redeclare package Medium = Medium,
    V=10e-3,
    m_flow_nominal=0.1,
    energyDynamics=Modelica.Fluid.Types.Dynamics.DynamicFreeInitial,
    massDynamics=Modelica.Fluid.Types.Dynamics.DynamicFreeInitial,
    nPorts=1) "Sink with constant pressure and temperature"

equation
  // Connection of components
  //
  connect(source.ports[1], rotCom.port_a)
  connect(rotCom.port_b, simVal.port_a)
  connect(simVal.port_b, sink.ports[1])
  connect(rotSpe.y, rotCom.manVarCom)
  connect(valOpe.y, simVal.opening)
  connect(fixTem.port, rotCom.heatPort)
end RotaryCompressorPressureHeatLosses;


within AixLib.Fluid.Movers.Compressors.Examples;
model RotaryCompressorPressureLosses
  "Example model to test simple rotary compressors with pressure losses"
  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 + 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,
    nPorts=1,
    p=pInl,
    T=TOut) "Source with constant pressure and temperature"
  Modelica.Blocks.Sources.Sine rotSpe(
    amplitude=40,
    offset=80,
    f=1) "Prescribed compressor's rotational speed"
  Modelica.Thermal.HeatTransfer.Sources.FixedTemperature fixTem(T=283.15)
    "Fixed ambient temperature"
  SimpleCompressors.RotaryCompressors.RotaryCompressorPressureLosses rotCom(
    redeclare package Medium = Medium,
    show_staEff=true,
    show_qua=true,
    useInpFil=true,
    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"

  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"

equation
  // Connection of components
  //
  connect(source.ports[1], rotCom.port_a)
  connect(rotCom.port_b, simVal.port_a)
  connect(simVal.port_b, sink.ports[1])
  connect(rotSpe.y, rotCom.manVarCom)
  connect(valOpe.y, simVal.opening)
  connect(fixTem.port, rotCom.heatPort)
end RotaryCompressorPressureLosses;


Model of simple modular compressors. This is a model of modular compressors that are used, for example, in
  close-loop systems like heat pumps or chillers.

  It consists of nCom compressors in parallel and also
  nCom PID conrollers if no external controller is used.

within AixLib.Fluid.Movers.Compressors.ModularCompressors;
model ModularCompressors
  "Model of simple modular compressors"
  extends BaseClasses.PartialModularCompressors;

equation
  // Connect port_b with compressors' port_b
  //
  for i in 1:nCom loop
    connect(modCom[i].port_b,port_b);
  end for;
end ModularCompressors;


within AixLib.Fluid.Movers.Compressors.ModularCompressors;
model ModularCompressorsSensors
  "Model of simple modular compressors with sensors at each compressor's outlet"
  extends BaseClasses.PartialModularCompressors;

  // Definition of parameters
  //
  parameter Modelica.Units.SI.Time tau=1 "Time constant at nominal flow rate"

  parameter Boolean transferHeat = false
    "if true, temperature T converges towards TAmb when no flow"
  parameter Modelica.Units.SI.Temperature TAmb=Medium.T_default
    "Fixed ambient temperature for heat transfer"
  parameter Modelica.Units.SI.Time tauHeaTra=1200
    "Time constant for heat transfer, default 20 minutes"

  parameter Modelica.Blocks.Types.Init initTypeSen=
    Modelica.Blocks.Types.Init.InitialState
    "Type of initialization (InitialState and InitialOutput are identical)"
  parameter Modelica.Units.SI.Temperature T_start=Medium.T_default
    "Initial or guess value of output (= state)"
  parameter Modelica.Units.SI.SpecificEnthalpy h_out_start=
      Medium.specificEnthalpy_pTX(
      p=Medium.p_default,
      T=Medium.T_default,
      X=Medium.X_default) "Initial or guess value of output (= state)"

  parameter Boolean show_parSen = false
    "= true, if sensors' input parameters are shown in results"

  // Definition of submodels and connectors
  //
  Sensors.ModularSensors modSen(
    redeclare final package Medium = Medium,
    final nPorts=nCom,
    final tau=tau,
    final transferHeat=transferHeat,
    final TAmb=TAmb,
    final tauHeaTra=tauHeaTra,
    final initType=initTypeSen,
    final T_start=T_start,
    final h_out_start=h_out_start,
    final m_flow_nominal=m_flow_nominal,
    final m_flow_small=1e-6*m_flow_nominal)
    "Model that contains different sensors located behind compressors"

equation
  // Connect compressors' port_b with sensors and sensors with port_b
  //
  for i in 1:nCom loop
    connect(modCom[i].port_b,modSen.ports_a[i]);
    connect(modSen.ports_b[i],port_b);
  end for;

  // Connect sensors
  //
  connect(modSen.meaPre, dataBus.senBus.meaPreCom)
  connect(modSen.meaTem, dataBus.senBus.meaTemCom)
  connect(modSen.meaMasFlo, dataBus.senBus.meaMasFloCom)
  connect(modSen.meaQua, dataBus.senBus.meaPhaCom)
end ModularCompressorsSensors;


within AixLib.Fluid.Movers.Compressors;
package ModularCompressors "Package that contains modular compressor models based on simple compressors"
  extends Modelica.Icons.VariantsPackage;
end ModularCompressors;


within AixLib.Fluid.Movers.Compressors;
package SimpleCompressors "Package that contains models of simple compressors"
  extends Modelica.Icons.VariantsPackage;
end SimpleCompressors;


within AixLib.Fluid.Movers.Compressors.SimpleCompressors;
package CompressionProcesses "Package that contains different compression models"
  extends Modelica.Icons.InternalPackage;
end CompressionProcesses;


Model that describes the compression process of a rotary compressor. This is a model describing the compression process of a rolling
  piston type rotary (i.e. rotary) compressor. The model is based on a
  grey-box approach and, therefore, it inherits from
  AixLib.Fluid.Movers.Compressors.BaseClasses.PartialCompression.
  Consequently, the model uses three efficiencies that must be
  redefined by the User:

within AixLib.Fluid.Movers.Compressors.SimpleCompressors.CompressionProcesses;
model RotaryCompression
  "Model that describes the compression process of a rotary compressor"
  extends BaseClasses.PartialCompression;

equation
  // Calculation of mass flow
  //
  m_flow = homotopy(rotSpe*oveVolEff.lamH*VDis*dInl,
                    rotSpe*oveVolEff.lamH*VDis*dInl0)
    "This covers initialisation case as well as shut-down case";

  // Calculation of energy balances
  //
  hOutIse = Medium.specificEnthalpy(Medium.setState_psX(p=pOut,
    s=Medium.specificEntropy(staInl)))
    "Isentropic specific enthalpy at outlet";
  oveIseEff.etaIse*dh = dhIse "Specific enthalpy difference";
  dhIse = (hOutIse - hInl) "Isentropic specific enthalpy difference";

  Q_flow_ref = m_flow *dh "Power absorbed by refrigerant";
  if not useIseWor then
    oveEngEff.etaEng*PEle = Q_flow_ref "Compressor's power consumption";
  else
    oveEngEff.etaEng*PEle = m_flow *dhIse "Compressor's power consumption";
  end if;
  /*Some efficiency models calculate the compressor's power consumptions based
    on the compressors isentropic work. Therefore, a distinction is made above.
  */

  // Calculate pressures at inlet and outlet of compressor
  //
  pInl = port_a.p "Pressure at inlet";
  pOut = port_b.p "Pressure at outlet";

  // Calculate specific enthalpies
  //
  hInl = actualStream(port_a.h_outflow) "Specific enthalpy at inlet";
  hOut = actualStream(port_b.h_outflow) "Specific enthalpy at outlet";

  port_a.h_outflow = inStream(port_a.h_outflow)
    "Compressor behaves as perfect valve if flow is reserved";
  port_b.h_outflow = smooth(1,noEvent(if m_flow > 0
    then hInl + dh else inStream(port_a.h_outflow)))
    "Compressor behaves as perfect valve if flow is reserved";
  /*It is assumed that the compressor works as perfectly closed valve if the
    mass flow is reserved. Hence, specific enthalpies flowing out of the system
    will meet the specific enthalpies flowing into the system.
  */

  // Connect heat port with internal variables
  //
  heatPort.Q_flow = Q_flow_ref-PEle;
end RotaryCompression;


within AixLib.Fluid.Movers.Compressors.SimpleCompressors;
package RotaryCompressors "Package that contains different models of rotary compressors"
  extends Modelica.Icons.VariantsPackage;
end RotaryCompressors;


Model that describes a simple rotary compressor. This is a model of a simple rotary compressor that is used, for
  example, in close-loop systems like heat pumps or chillers. It
  inherits from PartialCompressor which inherits from
  PartialCompression. Therefore, please checkout these sub-models for
  further information of underlying modeling approaches and
  parameterisation:

within AixLib.Fluid.Movers.Compressors.SimpleCompressors.RotaryCompressors;
model RotaryCompressor
  "Model that describes a simple rotary compressor"
  extends BaseClasses.PartialCompressor(
    redeclare final model CompressionProcess =
    SimpleCompressors.CompressionProcesses.RotaryCompression,
    final simCom = Utilities.Types.SimpleCompressor.RotaryCompressor);

equation
  // Conncections of main components
  //
  connect(port_a,comPro.port_a)
  connect(comPro.port_b, port_b)
  connect(heatPort,comPro.heatPort)
end RotaryCompressor;


within AixLib.Fluid.Movers.Compressors.SimpleCompressors.RotaryCompressors;
model RotaryCompressorPressureHeatLosses
  "Model that describes a simple rotary compressor with pressure and heat losses"
  extends BaseClasses.PartialCompressor(
    redeclare final model CompressionProcess =
    SimpleCompressors.CompressionProcesses.RotaryCompression,
    final simCom = Utilities.Types.SimpleCompressor.RotaryCompressorPressureHeatLosses);
  extends Modelica.Icons.UnderConstruction;

  // Definition of submodels and connectors
  //
  FixedResistances.HydraulicResistance hydResInl(
    redeclare final package Medium=Medium,
    final zeta=zetInl,
    final diameter=diameterInl,
    final m_flow_nominal=m_flow_nominal,
    final allowFlowReversal=allowFlowReversal,
    final show_T=false,
    final from_dp=from_dp,
    final linearized=linearized,
    final dp_start=(1/40)*dp_start,
    final m_flow_start=m_flow_start)
    "Calculation of pressure drop at inlet of compressor"

  Utilities.HeatTransfer.SimpleHeatTransfer heaTraInl(
    redeclare final package Medium=Medium,
    final allowFlowReversal=allowFlowReversal,
    final show_T=show_T,
    final show_V_flow=show_V_flow,
    final heaTraMod=heaTraMod,
    final kAMea=kAMeaInl,
    final m_flow_nominal=m_flow_nominal)
    "Model to calculate heat transfer at inlet of compressor"

  Utilities.HeatTransfer.SimpleHeatTransfer heaTraOut(
    redeclare final package Medium=Medium,
    final allowFlowReversal=allowFlowReversal,
    final show_T=show_T,
    final show_V_flow=show_V_flow,
    final heaTraMod=heaTraMod,
    final kAMea=kAMeaOut,
    final m_flow_nominal=m_flow_nominal)
    "Model to calculate heat transfer at outlet of compressor"
  FixedResistances.HydraulicResistance hydResOut(
    redeclare final package Medium=Medium,
    final zeta=zetOut,
    final diameter=diameterOut,
    final m_flow_nominal=m_flow_nominal,
    final allowFlowReversal=allowFlowReversal,
    final show_T=false,
    final from_dp=from_dp,
    final linearized=linearized,
    final dp_start=(1/40)*dp_start,
    final m_flow_start=m_flow_start)
    "Calculation of pressure drop at outlet of compressor"

  Utilities.HeatTransfer.SimpleFictitiousWall ficWal(
    final mWal=mWal,
    final cpWal=cpWal,
    final kAMeaAmb=kAMeaAmb,
    final TWal0=TWal0,
    final iniTWal0=iniTWal0)
    "Simple fictitious wall to calculate heat losses at compressor's inlet
    and outlet"

equation
  // Connection of main components
  //
  connect(port_a, hydResInl.port_a)
  connect(hydResInl.port_b, heaTraInl.port_a)
  connect(heaTraInl.port_b,comPro.port_a)
  connect(comPro.port_b, heaTraOut.port_a)
  connect(heaTraOut.port_b, hydResOut.port_a)
  connect(hydResOut.port_b, port_b)

  // Connection of heat ports
  //
  connect(heaTraInl.heatPort, ficWal.heaPorComInl)
  connect(comPro.heatPort, ficWal.heaPorCom)
  connect(heaTraOut.heatPort, ficWal.heaPorComOut)
  connect(ficWal.heaPorAmb, heatPort)
end RotaryCompressorPressureHeatLosses;


within AixLib.Fluid.Movers.Compressors.SimpleCompressors.RotaryCompressors;
model RotaryCompressorPressureLosses
  "Model that describes a simple rotary compressor with pressure losses"
  extends BaseClasses.PartialCompressor(
    redeclare final model CompressionProcess =
    SimpleCompressors.CompressionProcesses.RotaryCompression,
    final simCom = Utilities.Types.SimpleCompressor.RotaryCompressorPressureLosses);

  // Definition of submodels and connectors
  //
  FixedResistances.HydraulicResistance hydResInl(
    redeclare final package Medium=Medium,
    final zeta=zetInl,
    final diameter=diameterInl,
    final m_flow_nominal=m_flow_nominal,
    final allowFlowReversal=allowFlowReversal,
    final show_T=false,
    final from_dp=from_dp,
    final linearized=linearized,
    final dp_start=(1/40)*dp_start,
    final m_flow_start=m_flow_start)
    "Calculation of pressure drop at inlet of compressor"

  FixedResistances.HydraulicResistance hydResOut(
    redeclare final package Medium=Medium,
    final zeta=zetOut,
    final diameter=diameterOut,
    final m_flow_nominal=m_flow_nominal,
    final allowFlowReversal=allowFlowReversal,
    final show_T=false,
    final from_dp=from_dp,
    final linearized=linearized,
    final dp_start=(1/40)*dp_start,
    final m_flow_start=m_flow_start)
    "Calculation of pressure drop at outlet of compressor"

equation
  // Connections of main components
  //
  connect(port_a, hydResInl.port_a)
  connect(hydResInl.port_b,comPro.port_a)
  connect(comPro.port_b, hydResOut.port_a)
  connect(hydResOut.port_b, port_b)

  // Connection of further components
  //
  connect(comPro.heatPort, heatPort)
end RotaryCompressorPressureLosses;


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;