within Buildings.Fluid.CHPs.OrganicRankine.Validation;
model VariableSource
  "ORC with waste heat stream with variable flow rate and temperature"
  extends Modelica.Icons.Example;

  package MediumHot = Buildings.Media.Air "Evaporator hot fluid";
  package MediumCol = Buildings.Media.Water "Condenser cold fluid";

  parameter Buildings.Fluid.CHPs.OrganicRankine.Data.WorkingFluids.R245fa pro
    "Property record of the working fluid"
  parameter Modelica.Units.SI.MassFlowRate mHot_flow_nominal = 1
    "Nominal mass flow rate of evaporator hot fluid";
  parameter Modelica.Units.SI.MassFlowRate mCol_flow_nominal = 1
    "Nominal mass flow rate of condenser cold fluid";

  Buildings.Fluid.CHPs.OrganicRankine.Cycle orc(
    redeclare package Medium1 = MediumHot,
    redeclare package Medium2 = MediumCol,
    pro=pro,
    tau1=0,
    tau2=0,
    energyDynamics=Modelica.Fluid.Types.Dynamics.SteadyState,
    T1_start(displayUnit="K") = 350,
    T2_start(displayUnit="K") = 290,
    dpHot_nominal = 0,
    dpCol_nominal = 0,
    mHot_flow_nominal=mHot_flow_nominal,
    mCol_flow_nominal=mCol_flow_nominal,
    mWor_flow_max =
      3E4 / (
        Buildings.Utilities.Math.Functions.smoothInterpolation(
          x = orc.TWorEva,
          xSup = pro.T,
          ySup = pro.hSatVap) -
        Buildings.Utilities.Math.Functions.smoothInterpolation(
          x = 300,
          xSup = pro.T,
          ySup = pro.hSatLiq)),
    mWor_flow_min = orc.mWor_flow_max * 0.2,
    TWorEva=350,
    etaExp=0.7,
    etaPum=0.7) "Organic Rankine cycle"
  Buildings.Fluid.Sources.MassFlowSource_T souHot(
    redeclare final package Medium = MediumHot,
    m_flow=mHot_flow_nominal,
    T=orc.TWorEva + 20,
    nPorts=1,
    use_m_flow_in=true,
    use_T_in=true) "Evaporator hot fluid source"
  Buildings.Fluid.Sources.Boundary_pT sinHot(
    redeclare final package Medium = MediumHot,
    nPorts=1) "Evaporator hot fluid sink"
  Buildings.Fluid.Sources.MassFlowSource_T souCol(
    redeclare final package Medium = MediumCol,
    m_flow=mCol_flow_nominal,
    nPorts=1) "Condenser cold fluid source"
  Buildings.Fluid.Sources.Boundary_pT sinCol(
    redeclare final package Medium = MediumCol,
    nPorts=1) "Condenser cold fluid sink"
  Buildings.Fluid.Sensors.TemperatureTwoPort THotOut(
    redeclare final package Medium = MediumHot,
    final m_flow_nominal=mHot_flow_nominal,
    tau=0) "Outgoing temperature of evaporator hot fluid"
  Buildings.Fluid.Sensors.TemperatureTwoPort TColOut(
    redeclare final package Medium = MediumCol,
    final m_flow_nominal=mCol_flow_nominal,
    tau=0) "Outgoing temperature of condenser cold fluid"

  Modelica.Blocks.Sources.BooleanConstant tru(k=true) "Constant true"

  Modelica.Blocks.Sources.TimeTable mHot_flow_set(table=[
    0,0;
    20,0;
    50,mHot_flow_nominal*1.5;
    250,mHot_flow_nominal*1.5;
    280,0;
    300,0])
    "Sets the hot fluid flow rate in the evaporator"
  Modelica.Blocks.Sources.TimeTable THotIn_set(table=[
    0,orc.TWorEva + 20;
    100,orc.TWorEva + 20;
    150,orc.TWorEva - 5;
    200,orc.TWorEva + 20;
    300,orc.TWorEva + 20])
    "Sets the hot fluid incoming temperature in the evaporator"
equation
  connect(souHot.ports[1],orc. port_a1)
  connect(souCol.ports[1],orc. port_a2)
  connect(sinHot.ports[1],THotOut. port_b)
  connect(THotOut.port_a,orc. port_b1)
  connect(TColOut.port_a,orc. port_b2)
  connect(sinCol.ports[1], TColOut.port_b)
  connect(tru.y, orc.ena)
  connect(mHot_flow_set.y, souHot.m_flow_in)
  connect(THotIn_set.y, souHot.T_in)
end VariableSource;


Validate model ElectricalFollowing

within Buildings.Fluid.CHPs.Validation;
model ElectricalFollowing "Validate model ElectricalFollowing"
  extends Modelica.Icons.Example;

  package Medium = Buildings.Media.Water;

  Buildings.Fluid.CHPs.ThermalElectricalFollowing eleFol(
    redeclare package Medium = Medium,
    redeclare Data.ValidationData3 per,
    m_flow_nominal=0.4,
    energyDynamics=Modelica.Fluid.Types.Dynamics.SteadyState,
    switchThermalElectricalFollowing=false,
    TEngIni=273.15 + 69.55,
    waitTime=0) "CHP unit with the electricity demand priority"

  Modelica.Blocks.Sources.BooleanTable avaSig(
    startValue=true,
    table={172800})
    "Plant availability signal"
  Buildings.Fluid.Sources.Boundary_pT sin(
    redeclare package Medium = Medium,
    p(displayUnit="Pa"),
    nPorts=1) "Cooling water sink"
  Buildings.Fluid.Sources.MassFlowSource_T cooWat(
    redeclare package Medium = Medium,
    use_m_flow_in=true,
    use_T_in=true,
    nPorts=1) "Cooling water source"
  Buildings.Controls.OBC.CDL.Reals.Subtract dPEleNet
    "Absolute error for electric power generaton"
  Buildings.Controls.OBC.CDL.Reals.Subtract dQGen "Absolute error for heat generaton"
  Buildings.Controls.OBC.CDL.Reals.Subtract dQWat
    "Absolute error for heat transfer to water control volume"
  Buildings.Controls.OBC.CDL.Reals.Subtract dQLos
    "Absolute error for heat loss to the surroundings"
  Buildings.Controls.OBC.CDL.Reals.Subtract dTWatOut
    "Absolute error for water outlet temperature"
  Buildings.Controls.OBC.CDL.Reals.Subtract dTEng
    "Absolute error for engine temperature"
  Modelica.Blocks.Sources.RealExpression PEleNet(
    final y=eleFol.PEleNet)
    "Electric power generation"
  Modelica.Blocks.Sources.RealExpression QGen(final y=eleFol.eneCon.QGen_flow)
    "Heat generation"
  Modelica.Blocks.Sources.RealExpression QWat(
    final y=eleFol.QWat_flow)
    "Heat transfer to the water control volume"
  Modelica.Blocks.Sources.RealExpression QLos(
    final y=eleFol.QLos.Q_flow)
    "Heat loss to the surrounding"
  Modelica.Blocks.Sources.RealExpression TWatOut(
    final y=eleFol.vol.T)
    "Water outlet temperature"
  Modelica.Blocks.Sources.RealExpression TEng(
    final y=eleFol.eng.TEng)
    "Engine temperature"
  Buildings.HeatTransfer.Sources.PrescribedTemperature preTem
    "Variable temperature boundary condition in Kelvin"
  Modelica.Blocks.Sources.CombiTimeTable valDat(
    tableOnFile=true,
    tableName="tab1",
    extrapolation=Modelica.Blocks.Types.Extrapolation.Periodic,
    y(unit={"W", "kg/s", "degC", "degC", "W", "W", "W", "W", "W", "degC", "degC", "degC"}),
    offset={0,0,0,0,0,0,0,0,0,0,0,0},
    columns={2,3,4,5,6,7,8,9,10,11,12,13},
    smoothness=Modelica.Blocks.Types.Smoothness.MonotoneContinuousDerivative1,
    fileName=ModelicaServices.ExternalReferences.loadResource(
        "modelica://Buildings/Resources/Data/Fluid/CHPs/Validation/MicroCogeneration.mos"))
    "Validation data from EnergyPlus simulation"
  Buildings.Controls.OBC.UnitConversions.From_degC TWatIn
    "Convert cooling water inlet temperature from degC to kelvin"
  Buildings.Controls.OBC.UnitConversions.From_degC TRoo
    "Convert zone temperature from degC to kelvin"
  Buildings.Controls.OBC.UnitConversions.From_degC TWatOutVal
    "Convert cooling water outplet temperature from degC to kelvin"
  Buildings.Controls.OBC.UnitConversions.From_degC TEngVal
    "Convert engine temperature from degC to kelvin"
  Modelica.Blocks.Routing.RealPassThrough PEleNetVal
    "Validation data for power output"
  Modelica.Blocks.Routing.RealPassThrough QGenVal_flow
    "Validation data for heat generation rate"
  Modelica.Blocks.Routing.RealPassThrough QWatVal_flow
    "Validation data for heat flow rate to water"
  Modelica.Blocks.Routing.RealPassThrough QLosVal_flow
    "Validation data for heat flow rate to ambient"
  Modelica.Blocks.Continuous.Integrator EEle(y(unit="J"))
    "Electrical energy generated"
  Modelica.Blocks.Continuous.Integrator EThe(y(unit="J"))
    "Thermal energy recovered"
  Modelica.Blocks.Continuous.Integrator EEleVal(y(unit="J"))
    "Validation data for electrical energy generated"
  Modelica.Blocks.Continuous.Integrator ETheVal(y(unit="J"))
    "Validation data for thermal energy recovered"
equation
  connect(eleFol.port_b, sin.ports[1])
  connect(avaSig.y, eleFol.avaSig)
  connect(cooWat.ports[1], eleFol.port_a)
  connect(PEleNet.y, dPEleNet.u1)
  connect(QGen.y, dQGen.u1)
  connect(QWat.y, dQWat.u1)
  connect(QLos.y, dQLos.u1)
  connect(TWatOut.y, dTWatOut.u1)
  connect(dTEng.u1, TEng.y)
  connect(preTem.port, eleFol.TRoo)
  connect(valDat.y[2], cooWat.m_flow_in)
  connect(valDat.y[3], TWatIn.u)
  connect(TWatIn.y, cooWat.T_in)
  connect(valDat.y[4], TRoo.u)
  connect(TRoo.y, preTem.T)
  connect(valDat.y[10], TWatOutVal.u)
  connect(valDat.y[11], TEngVal.u)
  connect(TWatOutVal.y, dTWatOut.u2)
  connect(TEngVal.y, dTEng.u2)
  connect(valDat.y[1], eleFol.PEleDem)
  connect(QGenVal_flow.y, dQGen.u2)
  connect(PEleNetVal.y, dPEleNet.u2)
  connect(valDat.y[5], PEleNetVal.u)
  connect(valDat.y[7], QGenVal_flow.u)
  connect(QWatVal_flow.y, dQWat.u2)
  connect(valDat.y[8], QWatVal_flow.u)
  connect(QLosVal_flow.y, dQLos.u2)
  connect(valDat.y[9], QLosVal_flow.u)
  connect(eleFol.PEleNet, EEle.u)
  connect(eleFol.QWat_flow, EThe.u)
  connect(QWatVal_flow.y, ETheVal.u)
  connect(PEleNetVal.y, EEleVal.u)
end ElectricalFollowing;


Validation of the main model

within Buildings.Fluid.CHPs;
package Validation "Validation of the main model"
  extends Modelica.Icons.ExamplesPackage;
end Validation;


within Buildings.Fluid.CHPs.Validation;
model ThermalFollowing "Validate model ThermalElectricalFollowing"
  extends Modelica.Icons.Example;

  package Medium = Buildings.Media.Water;

  Buildings.Fluid.CHPs.ThermalElectricalFollowing theFol(
    redeclare package Medium = Medium,
    m_flow_nominal=0.4,
    redeclare Data.Senertech5_5kW per,
    energyDynamics=Modelica.Fluid.Types.Dynamics.SteadyState,
    TEngIni=273.15 + 69.55,
    waitTime=0) "CHP unit with the thermal demand priority"
  Modelica.Blocks.Sources.BooleanTable avaSig(
    startValue=true,
    table={172800})
    "Plant availability signal"
  Buildings.Fluid.Sources.Boundary_pT sin(
    redeclare package Medium = Medium,
    p(displayUnit="Pa"),
    nPorts=2)
    "Cooling water sink"
  Buildings.Fluid.Sources.MassFlowSource_T cooWat(
    redeclare package Medium = Medium,
    use_m_flow_in=true,
    use_T_in=true,
    nPorts=1) "Cooling water source"
  Buildings.Controls.OBC.CDL.Reals.Subtract dPEleNet
    "Absolute error for electric power generaton"
  Buildings.Controls.OBC.CDL.Reals.Subtract dQWat
    "Absolute error for heat transfer to water control volume"
  Buildings.Controls.OBC.CDL.Reals.Subtract dTWatOut
    "Absolute error for water outlet temperature"
  Modelica.Blocks.Sources.RealExpression PEleNet(
    final y=theFol.PEleNet)
    "Electric power generation"
  Modelica.Blocks.Sources.RealExpression QWat(
    final y=theFol.QWat_flow)
    "Heat transfer to the water control volume"
  Modelica.Blocks.Sources.RealExpression TWatOut(final y=theFol.TWatOut.T)
    "Water outlet temperature"
  HeatTransfer.Sources.PrescribedTemperature preTem
    "Variable temperature boundary condition in Kelvin"
  Buildings.Controls.OBC.CDL.Reals.Subtract dTEng
    "Absolute error for engine temperature"
  Modelica.Blocks.Sources.RealExpression TEng(
    final y=theFol.eng.TEng)
    "Engine temperature"
  Buildings.Controls.OBC.CDL.Reals.Subtract dQLos
    "Absolute error for heat loss to the surroundings"
  Modelica.Blocks.Sources.RealExpression QLos(
    final y=theFol.QLos.Q_flow)
    "Heat loss to the surrounding"
  Buildings.Controls.OBC.CDL.Reals.Subtract dQGen
    "Absolute error for heat generaton"
  Modelica.Blocks.Sources.RealExpression QGen(
    final y=theFol.eneCon.QGen_flow)
    "Heat generation"
  Modelica.Blocks.Sources.CombiTimeTable valDat(
    tableOnFile=true,
    tableName="tab1",
    extrapolation=Modelica.Blocks.Types.Extrapolation.Periodic,
    y(unit={"W","kg/s","degC","degC","W","W","W","W","W","degC","degC","degC"}),
    offset={0,0,0,0,0,0,0,0,0,0,0,0},
    columns={2,3,4,5,6,7,8,9,10,11,12,13},
    smoothness=Modelica.Blocks.Types.Smoothness.MonotoneContinuousDerivative1,
    fileName=ModelicaServices.ExternalReferences.loadResource("modelica://Buildings/Resources/Data/Fluid/CHPs/Validation/MicroCogeneration.mos"))
    "Validation data from EnergyPlus simulation"
  Buildings.Controls.OBC.UnitConversions.From_degC TRoo
    "Convert zone temperature from degC to kelvin"
  Buildings.Controls.OBC.UnitConversions.From_degC TWatIn
    "Convert cooling water inlet temperature from degC to kelvin"
  Buildings.Controls.OBC.UnitConversions.From_degC TWatOutSet
    "Convert outlet water setpoint temperature from degC to kelvin "
  Buildings.Controls.OBC.UnitConversions.From_degC TEngVal
    "Convert engine temperature from degC to kelvin"
  Buildings.Controls.OBC.UnitConversions.From_degC TWatOutVal
    "Convert cooling water outplet temperature from degC to kelvin"
  Sources.MassFlowSource_T cooWatNeg(
    redeclare package Medium = Medium,
    use_m_flow_in=true,
    use_T_in=true,
    nPorts=1) "Cooling water source"
  ThermalElectricalFollowing theFolNeg(
    redeclare package Medium = Medium,
    m_flow_nominal=0.4,
    redeclare Data.Senertech5_5kW per,
    energyDynamics=Modelica.Fluid.Types.Dynamics.SteadyState,
    TEngIni=273.15 + 69.55,
    waitTime=0)
    "CHP unit with the thermal demand priority and negative water mass flow rate"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant mWat_flow_negative(
    final k=-1)
    "Negative water mass flow rate for validation only"
  Modelica.Blocks.Routing.RealPassThrough PEleNetVal
    "Validation data for power output"
  Modelica.Blocks.Routing.RealPassThrough QGenVal_flow
    "Validation data for heat generation rate"
  Modelica.Blocks.Routing.RealPassThrough QWatVal_flow
    "Validation data for heat flow rate to water"
  Modelica.Blocks.Routing.RealPassThrough QLosVal_flow
    "Validation data for heat flow rate to ambient"
  Modelica.Blocks.Continuous.Integrator EEle(y(unit="J"))
    "Electrical energy generated"
  Modelica.Blocks.Continuous.Integrator EThe(y(unit="J"))
    "Thermal energy recovered"
  Modelica.Blocks.Continuous.Integrator EEleVal(y(unit="J"))
    "Validation data for electrical energy generated"
  Modelica.Blocks.Continuous.Integrator ETheVal(y(unit="J"))
    "Validation data for thermal energy recovered"
protected
  Modelica.Blocks.Sources.BooleanExpression theFolSig(
    final y=true)
    "Signal for thermal following, set to false if electrical following"
equation
  connect(theFol.port_b, sin.ports[1])
  connect(avaSig.y,theFol. avaSig)
  connect(cooWat.ports[1],theFol. port_a)
  connect(PEleNet.y, dPEleNet.u1)
  connect(QWat.y, dQWat.u1)
  connect(theFolSig.y,theFol. theFol)
  connect(preTem.port, theFol.TRoo)
  connect(QLos.y,dQLos. u1)
  connect(QGen.y,dQGen. u1)
  connect(valDat.y[2], cooWat.m_flow_in)
  connect(valDat.y[3], TWatIn.u)
  connect(TWatIn.y, cooWat.T_in)
  connect(valDat.y[4], TRoo.u)
  connect(TRoo.y, preTem.T)
  connect(valDat.y[12], TWatOutSet.u)
  connect(TWatOutSet.y,theFol. TWatOutSet)
  connect(TWatOutVal.y, dTWatOut.u2)
  connect(TWatOut.y, dTWatOut.u1)
  connect(TEng.y, dTEng.u1)
  connect(TEngVal.y, dTEng.u2)
  connect(valDat.y[10], TWatOutVal.u)
  connect(valDat.y[11], TEngVal.u)
  connect(valDat.y[1],theFol. PEleDem)
  connect(cooWatNeg.ports[1], theFolNeg.port_a)
  connect(theFolNeg.port_b, sin.ports[2])
  connect(mWat_flow_negative.y, cooWatNeg.m_flow_in)
  connect(avaSig.y, theFolNeg.avaSig)
  connect(theFolSig.y, theFolNeg.theFol)
  connect(valDat.y[1], theFolNeg.PEleDem)
  connect(TWatOutSet.y, theFolNeg.TWatOutSet)
  connect(TWatIn.y, cooWatNeg.T_in)
  connect(valDat.y[5], PEleNetVal.u)
  connect(PEleNetVal.y, dPEleNet.u2)
  connect(valDat.y[7], QGenVal_flow.u)
  connect(QGenVal_flow.y, dQGen.u2)
  connect(valDat.y[8], QWatVal_flow.u)
  connect(QWatVal_flow.y, dQWat.u2)
  connect(valDat.y[9], QLosVal_flow.u)
  connect(QLosVal_flow.y, dQLos.u2)
  connect(PEleNetVal.y, EEleVal.u)
  connect(QWatVal_flow.y, ETheVal.u)
  connect(theFol.PEleNet, EEle.u)
  connect(theFol.QWat_flow, EThe.u)
end ThermalFollowing;


Package with properties of fuels

within Buildings.Fluid.Data;
package Fuels "Package with properties of fuels"
    extends Modelica.Icons.MaterialPropertiesPackage;

  record NaturalGasLowerHeatingValue = Buildings.Fluid.Data.Fuels.Generic (
      h=50E6,
      d=0.84,
      mCO2=2.23) "Natural gas, lower heating value"

  record NaturalGasHigherHeatingValue = NaturalGasLowerHeatingValue (
      h=55.5E6) "Natural gas, higher heating value"

  record HeatingOilLowerHeatingValue = Buildings.Fluid.Data.Fuels.Generic (
      h=42.6E6,
      d=845,
      mCO2=3.136) "Heating oil, lower heating value"

  record HeatingOilHigherHeatingValue = HeatingOilLowerHeatingValue (
      h=45.4E6) "Heating oil, higher heating value"

  record WoodAirDriedLowerHeatingValue = Buildings.Fluid.Data.Fuels.Generic (
      h=14.6E6,
      d=700,
      mCO2=0) "Wood, air-dried, lower heating value"

  record Generic "Generic record of fuel properties"
    extends Modelica.Icons.Record;
    parameter Modelica.Units.SI.SpecificEnthalpy h
      "Heating value (lower or upper, depending on fuel)";
    parameter Modelica.Units.SI.Density d "Mass density";
    parameter Real mCO2(final min=0) "CO2 emission at combustion, in kg/kg fuel";
  end Generic;
end Fuels;


Data for fluid models

within Buildings.Fluid;
package Data "Data for fluid models"
    extends Modelica.Icons.MaterialPropertiesPackage;
end Data;


Package with properties of pipes

within Buildings.Fluid.Data;
package Pipes "Package with properties of pipes"
    extends Modelica.Icons.MaterialPropertiesPackage;

  record PEX_DN_6 = Buildings.Fluid.Data.Pipes.PEX_RADTEST (
      dOut = 8E-3,
      dIn =  6E-3) "PEX DN 6"

  record PEX_DN_8 = Buildings.Fluid.Data.Pipes.PEX_RADTEST (
      dOut = 10E-3,
      dIn =  8E-3) "PEX DN 8"

  record PEX_DN_10 = Buildings.Fluid.Data.Pipes.PEX_RADTEST (
      dOut = 13E-3,
      dIn =  10E-3) "PEX DN 10"

  record PEX_DN_15 = Buildings.Fluid.Data.Pipes.PEX_RADTEST (
      dOut = 19E-3,
      dIn =  16E-3) "PEX DN 15"

  record PEX_DN_20 = Buildings.Fluid.Data.Pipes.PEX_RADTEST (
      dOut = 23E-3,
      dIn =  20E-3) "PEX DN 20"

  record PEX_DN_25 = Buildings.Fluid.Data.Pipes.PEX_RADTEST (
      dOut = 29E-3,
      dIn =  26E-3) "PEX DN 25"

  record PEX_DN_32 = Buildings.Fluid.Data.Pipes.PEX_RADTEST (
      dOut = 35E-3,
      dIn =  32E-3) "PEX DN 32"

  record PEX_DN_40 = Buildings.Fluid.Data.Pipes.PEX_RADTEST (
      dOut = 41E-3,
      dIn =  38E-3) "PEX DN 40"

  record PEX_DN_50 = Buildings.Fluid.Data.Pipes.PEX_RADTEST (
      dOut = 53E-3,
      dIn =  50E-3) "PEX DN 50"

  record PEX_DN_65 = Buildings.Fluid.Data.Pipes.PEX_RADTEST (
      dOut = 70E-3,
      dIn =  66E-3) "PEX DN 65"

  record PEX_DN_80 = Buildings.Fluid.Data.Pipes.PEX_RADTEST (
      dOut = 85E-3,
      dIn =  81E-3) "PEX DN 80"

  record PEX_DN_100 = Buildings.Fluid.Data.Pipes.PEX_RADTEST (
      dOut = 104E-3,
      dIn =  100E-3) "PEX DN 100"

  record PEX_DN_125 = Buildings.Fluid.Data.Pipes.PEX_RADTEST (
      dOut = 129E-3,
      dIn =  125E-3) "PEX DN 125"

  record PEX_DN_150 = Buildings.Fluid.Data.Pipes.PEX_RADTEST (
      dOut = 154E-3,
      dIn =  150E-3) "PEX DN 150"

  record PEX_DN_200 = Buildings.Fluid.Data.Pipes.PEX_RADTEST (
      dOut = 204E-3,
      dIn =  200E-3) "PEX DN 200"

  record PEX_RADTEST = Buildings.Fluid.Data.Pipes.Generic (
      dOut =      0.025,
      dIn =        0.020,
      roughness = 0.007E-3,
      d =         983,
      k =         0.35) "PEX from RADTEST Validation Suite"

  record Generic "Generic record for pipes"
    extends Modelica.Icons.Record;
    parameter Modelica.Units.SI.Length dOut(min=0) "Outer diameter";
    parameter Modelica.Units.SI.Length dIn(min=0) "Inner diameter";
    final parameter Modelica.Units.SI.Length s(min=0) = (dOut - dIn)/2
      "Wall thickness";
    parameter Modelica.Units.SI.Length roughness(min=0) "Roughness";
    parameter Modelica.Units.SI.Density d "Mass density";
    parameter Modelica.Units.SI.ThermalConductivity k "Thermal conductivity";
  end Generic;
end Pipes;


Delay element, approximated by a first order differential equation. This model approximates a transport delay using first order differential equations.

within Buildings.Fluid.Delays;
model DelayFirstOrder
  "Delay element, approximated by a first order differential equation"
  extends Buildings.Fluid.MixingVolumes.MixingVolume(
    final V=V_nominal,
    final massDynamics=energyDynamics,
    final mSenFac=1);

  parameter Modelica.Units.SI.Time tau=60 "Time constant at nominal flow"

protected
  parameter Modelica.Units.SI.Volume V_nominal=m_flow_nominal*tau/rho_default
    "Volume of delay element";
end DelayFirstOrder;


Package with delay models

within Buildings.Fluid;
package Delays "Package with delay models"
  extends Modelica.Icons.VariantsPackage;
end Delays;


within Buildings.Fluid.Delays.Examples;
model Delay
  extends Modelica.Icons.Example;
// We set X_default to a small enough value to avoid saturation at the medium temperature
// that is used in this model.
 package Medium = Buildings.Media.Air(X_default={0.001, 0.999});

    Modelica.Blocks.Sources.Constant PAtm(k=101325)
    Modelica.Blocks.Sources.Ramp P(
      duration=1,
    height=20,
    offset=101315)
  Buildings.Fluid.FixedResistances.PressureDrop res1(
    from_dp=true,
    m_flow_nominal=5,
    dp_nominal=5,
    redeclare package Medium = Medium)
  Buildings.Fluid.Sources.Boundary_pT sou(
                T=293.15, redeclare package Medium = Medium,
    use_p_in=true,
    nPorts=1)
  Buildings.Fluid.Sources.Boundary_pT sin(
                T=283.15, redeclare package Medium = Medium,
    use_p_in=true,
    nPorts=1)
  Buildings.Fluid.FixedResistances.PressureDrop res2(
    from_dp=true,
    m_flow_nominal=5,
    dp_nominal=5,
    redeclare package Medium = Medium)
  Buildings.Fluid.Delays.DelayFirstOrder del(         m_flow_nominal=5, redeclare
      package Medium = Medium,
    nPorts=2,
    energyDynamics=Modelica.Fluid.Types.Dynamics.FixedInitial,
    T_start=283.15)
    "Fluid volume that is a first order approximation of the transport delay"

equation
  connect(P.y, sou.p_in)
  connect(PAtm.y, sin.p_in)
  connect(sou.ports[1], res1.port_a)
  connect(sin.ports[1], res2.port_b)
  connect(res1.port_b, del.ports[1])
  connect(res2.port_a, del.ports[2])
end Delay;


within Buildings.Fluid.Delays;
package Examples "Collection of models that illustrate model use and test models"
  extends Modelica.Icons.ExamplesPackage;
end Examples;


within Buildings.Fluid;
package DXSystems "DX(Direct Expansion) cooling coil models"
  extends Modelica.Icons.VariantsPackage;
end DXSystems;


Calculates cooling capacity at given temperature and flow fraction for air source coils. This model calculates cooling capacity and EIR for air source DX coils in off-designed conditions based on
performance modifers calculated in partial model

Buildings.Fluid.DXSystems.Cooling.BaseClasses.PartialCapacity.

within Buildings.Fluid.DXSystems.BaseClasses;
block CapacityAirSource
  "Calculates cooling capacity at given temperature and flow fraction for air source coils"
  extends Buildings.Fluid.DXSystems.Cooling.BaseClasses.PartialCapacity(
    use_mCon_flow=false);

equation
 if stage > 0 then
    for iSta in 1:nSta loop
      Q_flow[iSta] = corFac[iSta]*cap_T[iSta]*cap_FF[iSta]*sta[iSta].nomVal.Q_flow_nominal;
      EIR[iSta]    = corFac[iSta]*EIR_T[iSta]*EIR_FF[iSta]/sta[iSta].nomVal.COP_nominal;
    end for;
 else //cooling coil off
   Q_flow = fill(0, nSta);
   EIR    = fill(0, nSta);
  end if;
end CapacityAirSource;


Calculates dry coil condition

within Buildings.Fluid.DXSystems.BaseClasses;
model DryCoil "Calculates dry coil condition"
 extends
    Buildings.Fluid.DXSystems.Cooling.BaseClasses.PartialCoilCondition;
  replaceable package Medium =
      Modelica.Media.Interfaces.PartialCondensingGases "Medium model"
equation

  connect(TEvaIn,coiCap.TEvaIn)
  connect(mCon_flow,coiCap.mCon_flow)
end DryCoil;


within Buildings.Fluid.DXSystems;
package BaseClasses "Package with base classes for DX cooling coil model"
  extends Modelica.Icons.BasesPackage;
end BaseClasses;


Test model for CapacityAirSource

within Buildings.Fluid.DXSystems.BaseClasses.Examples;
model CapacityAirSource "Test model for CapacityAirSource"
  extends Modelica.Icons.Example;
  package Medium = Buildings.Media.Air;
  Buildings.Fluid.DXSystems.BaseClasses.CapacityAirSource
    cooCap(sta={sta}, nSta=1) "Cooling capacity calculation"
  Modelica.Blocks.Sources.Ramp m_flow(
    duration=2400,
    startTime=600,
    height=sta.nomVal.m_flow_nominal,
    offset=0) "Mass flow rate of air"
  Modelica.Blocks.Sources.Ramp TWetBulIn(
    duration=2400,
    startTime=600,
    height=10,
    offset=273.15 + 19.4) "Air wet bulb temperature entering the coil"
  Modelica.Blocks.Sources.IntegerStep onOff(startTime=600)
    "Compressor on-off signal"
  Modelica.Blocks.Sources.Ramp TConIn(
    duration=2400,
    startTime=600,
    height=5,
    offset=273.15 + 30)
    "Condenser inlet temperature (Outside drybulb temperature)"
  parameter Buildings.Fluid.DXSystems.Cooling.AirSource.Data.Generic.BaseClasses.Stage sta(
    nomVal(Q_flow_nominal=-21000,COP_nominal=3,
      SHR_nominal=0.8,m_flow_nominal=1.5),
   perCur = Buildings.Fluid.DXSystems.Cooling.BaseClasses.Examples.PerformanceCurves.Curve_III_AirCooled(),
    spe=188.49555921539) "Performance data"
equation
  connect(TConIn.y, cooCap.TConIn)
  connect(m_flow.y, cooCap.m_flow)
  connect(onOff.y, cooCap.stage)
  connect(TWetBulIn.y, cooCap.TEvaIn)
end CapacityAirSource;


Test model for DryCoil

within Buildings.Fluid.DXSystems.BaseClasses.Examples;
model DryCoil "Test model for DryCoil"
extends Modelica.Icons.Example;
  package Medium = Buildings.Media.Air;
  Modelica.Blocks.Sources.Constant TConIn(
    k=273.15 + 35) "Condenser inlet air temperature"
  Buildings.Fluid.DXSystems.BaseClasses.DryCoil dryCoi(
    redeclare package Medium = Medium,
    datCoi=datCoi,
    variableSpeedCoil=true,
    redeclare
      Buildings.Fluid.DXSystems.BaseClasses.CapacityAirSource
      coiCap,
    use_mCon_flow=false) "Performs calculation for dry coil condition"
  Modelica.Blocks.Sources.IntegerStep onOff(
    startTime=1200) "Compressor on-off signal"
  Modelica.Blocks.Sources.Ramp m_flow(
    startTime=1200,
    duration=600,
    height=1.5) "Mass flow rate of air"
  Modelica.Blocks.Sources.Ramp TEvaIn(
    duration=600,
    startTime=2400,
    height=-4,
    offset=273.15 + 29) "Dry bulb temperature of air entering the coil"
  Modelica.Blocks.Sources.TimeTable speRat(table=[0.0,0.0; 900,0.25; 1800,0.50;
        2700,0.75]) "Speed ratio "

  parameter Buildings.Fluid.DXSystems.Cooling.AirSource.Data.Generic.DXCoil datCoi(
    sta={
      Buildings.Fluid.DXSystems.Cooling.AirSource.Data.Generic.BaseClasses.Stage(
        spe=900/60,
        nomVal=
          Buildings.Fluid.DXSystems.Cooling.AirSource.Data.Generic.BaseClasses.NominalValues(
          Q_flow_nominal=-12000,
          COP_nominal=3,
          SHR_nominal=0.8,
          m_flow_nominal=0.9),
        perCur=
          Buildings.Fluid.DXSystems.Cooling.BaseClasses.Examples.PerformanceCurves.Curve_I_AirCooled()),
      Buildings.Fluid.DXSystems.Cooling.AirSource.Data.Generic.BaseClasses.Stage(
        spe=1200/60,
        nomVal=
          Buildings.Fluid.DXSystems.Cooling.AirSource.Data.Generic.BaseClasses.NominalValues(
          Q_flow_nominal=-18000,
          COP_nominal=3,
          SHR_nominal=0.8,
          m_flow_nominal=1.2),
        perCur=
          Buildings.Fluid.DXSystems.Cooling.BaseClasses.Examples.PerformanceCurves.Curve_I_AirCooled()),
      Buildings.Fluid.DXSystems.Cooling.AirSource.Data.Generic.BaseClasses.Stage(
        spe=1800/60,
        nomVal=
          Buildings.Fluid.DXSystems.Cooling.AirSource.Data.Generic.BaseClasses.NominalValues(
          Q_flow_nominal=-21000,
          COP_nominal=3,
          SHR_nominal=0.8,
          m_flow_nominal=1.5),
        perCur=
          Buildings.Fluid.DXSystems.Cooling.BaseClasses.Examples.PerformanceCurves.Curve_II_AirCooled()),
      Buildings.Fluid.DXSystems.Cooling.AirSource.Data.Generic.BaseClasses.Stage(
        spe=2400/60,
        nomVal=
          Buildings.Fluid.DXSystems.Cooling.AirSource.Data.Generic.BaseClasses.NominalValues(
          Q_flow_nominal=-30000,
          COP_nominal=3,
          SHR_nominal=0.8,
          m_flow_nominal=1.8),
        perCur=
          Buildings.Fluid.DXSystems.Cooling.BaseClasses.Examples.PerformanceCurves.Curve_III_AirCooled())},
      nSta=4)
    "Coil data"
equation
  connect(TConIn.y, dryCoi.TConIn)
  connect(m_flow.y, dryCoi.m_flow)
  connect(TEvaIn.y, dryCoi.TEvaIn)
  connect(speRat.y, dryCoi.speRat)
  connect(onOff.y, dryCoi.stage)
end DryCoil;


within Buildings.Fluid.DXSystems.BaseClasses;
package Examples "Package with examples of base class components for DX cooling coil model"
  extends Modelica.Icons.ExamplesPackage;
end Examples;


Package with DX cooling coil models

within Buildings.Fluid.DXSystems;
package Cooling "Package with DX cooling coil models"
end Cooling;


User's Guide

within Buildings.Fluid.DXSystems.Cooling;
package UsersGuide "User's Guide"
  extends Modelica.Icons.Information;
end UsersGuide;


Multi-stage DX cooling coil. This model can be used to simulate an air source DX cooling coil with multiple
operating stages. Depending on the used performance curves, each
stage could be a different compressor speed, or a different mode
of operation, such as with or without hot gas reheat.

within Buildings.Fluid.DXSystems.Cooling.AirSource;
model MultiStage
  "Multi-stage DX cooling coil"
  extends
    Buildings.Fluid.DXSystems.Cooling.BaseClasses.PartialDXCoolingCoil(
    dxCoi(
      final variableSpeedCoil=false,
      wetCoi(redeclare
          Buildings.Fluid.DXSystems.BaseClasses.CapacityAirSource
          coiCap),
      dryCoi(redeclare
          Buildings.Fluid.DXSystems.BaseClasses.CapacityAirSource
          coiCap)),
    use_mCon_flow=false);

  Modelica.Blocks.Interfaces.IntegerInput stage
    "Stage of cooling coil (0: off, 1: first stage, 2: second stage...)"

  Buildings.Fluid.DXSystems.Cooling.BaseClasses.SpeedSelect speSel(
    final nSta=datCoi.nSta, speSet=datCoi.sta.spe)
    "Normalize the speed signal based on the compressor stage input"

  Modelica.Blocks.Math.IntegerToBoolean onSwi(
    final threshold=1)
    "On/off switch"

equation
  connect(onSwi.y, watVapEva.on)
  connect(onSwi.u, stage)
  connect(stage, speSel.stage)
  connect(speSel.speRat,dxCoi.speRat)
  connect(stage,dxCoi.stage)
end MultiStage;


Air source DX coils

within Buildings.Fluid.DXSystems.Cooling;
package AirSource "Air source DX coils"
end AirSource;


Single speed DX cooling coil. This model can be used to simulate an air source DX cooling coil with single speed compressor.

within Buildings.Fluid.DXSystems.Cooling.AirSource;
model SingleSpeed "Single speed DX cooling coil"
  extends
    Buildings.Fluid.DXSystems.Cooling.BaseClasses.PartialDXCoolingCoil(
    dxCoi(
      final variableSpeedCoil=false,
      wetCoi(redeclare
          Buildings.Fluid.DXSystems.BaseClasses.CapacityAirSource
          coiCap),
      dryCoi(redeclare
          Buildings.Fluid.DXSystems.BaseClasses.CapacityAirSource
          coiCap)),
    use_mCon_flow=false);

  Modelica.Blocks.Sources.Constant speRat(
    final k=1)
    "Speed ratio"

  Modelica.Blocks.Interfaces.BooleanInput on
    "Set to true to enable compressor, or false to disable compressor"

protected
  Modelica.Blocks.Math.BooleanToInteger onSwi(
    final integerTrue=1,
    final integerFalse=0)
    "On/off switch"

initial equation
  assert(datCoi.nSta == 1, "Must have one stage only for single speed performance data");

equation
  connect(speRat.y,dxCoi.speRat)
  connect(watVapEva.on, on)
  connect(on, onSwi.u)
  connect(onSwi.y,dxCoi.stage)
end SingleSpeed;


Variable speed DX cooling coil. This model can be used to simulate an air source DX cooling coil with continuously
variable speed compressors.
The control input is the speed ratio.
The coil will switch off if the speed ratio is below a minimum value.

within Buildings.Fluid.DXSystems.Cooling.AirSource;
model VariableSpeed "Variable speed DX cooling coil"
  extends
    Buildings.Fluid.DXSystems.Cooling.BaseClasses.PartialDXCoolingCoil(
    dxCoi(
      final variableSpeedCoil=true,
      wetCoi(redeclare
          Buildings.Fluid.DXSystems.BaseClasses.CapacityAirSource
          coiCap),
      dryCoi(redeclare
          Buildings.Fluid.DXSystems.BaseClasses.CapacityAirSource
          coiCap)),
    use_mCon_flow=false);

  parameter Real minSpeRat(
    final min=0,
    final max=1)
    "Minimum speed ratio";

  parameter Real speRatDeaBan= 0.05
    "Deadband for minimum speed ratio";

  Modelica.Blocks.Interfaces.RealInput speRat(
    final unit="1",
    displayUnit="1")
    "Speed ratio"

protected
  Modelica.Blocks.Logical.Hysteresis deaBan(
    final uLow=minSpeRat - speRatDeaBan/2,
    final uHigh=minSpeRat + speRatDeaBan/2)
    "Speed ratio deadband"

  Modelica.Blocks.Math.BooleanToInteger onSwi(
    final integerTrue=1,
    final integerFalse=0)
    "On/off switch"

equation
  connect(speRat,dxCoi.speRat)
  connect(speRat, deaBan.u)
  connect(deaBan.y, watVapEva.on)
  connect(onSwi.y,dxCoi.stage)
  connect(deaBan.y, onSwi.u)
end VariableSpeed;


within Buildings.Fluid.DXSystems.Cooling.AirSource;
package Data "Package with performance data for DX cooling coils"
  extends Modelica.Icons.MaterialPropertiesPackage;
end Data;


within Buildings.Fluid.DXSystems.Cooling.AirSource.Data;
package DoubleSpeed "Performance data for DoubleSpeed DXCoils"
  extends Modelica.Icons.MaterialPropertiesPackage;
end DoubleSpeed;


Performance record for a DX Cooling DXCoil with one or multiple stages. This record declares the performance data for the air source DX cooling coil model.
The performance data are structured as follows:

within Buildings.Fluid.DXSystems.Cooling.AirSource.Data.Generic;
record DXCoil
  "Performance record for a DX Cooling DXCoil with one or multiple stages"
  extends Modelica.Icons.Record;

  final parameter Boolean sinStaOpe = nSta == 1
    "The data record is used for single speed operation"

  parameter Integer nSta(
    final min=1)
    "Number of stages"

  parameter Real minSpeRat(
    final min=0,
    final max=1)=0.2
    "Minimum speed ratio"

  replaceable parameter
    Buildings.Fluid.DXSystems.Cooling.AirSource.Data.Generic.BaseClasses.Stage sta[nSta]
    "Data record for coil performance at each stage";

  parameter Modelica.Units.SI.MassFlowRate m_flow_small=0.0001*sta[nSta].nomVal.m_flow_nominal
    "Small mass flow rate for regularization near zero flow"

  /////////////////////////////////////////////////////////////////////////////////////
  // Parameter added for type compatibility, but not used for calculations in cooling coils
  final parameter Buildings.Fluid.DXSystems.Heating.BaseClasses.Types.DefrostOperation
    defOpe=Buildings.Fluid.DXSystems.Heating.BaseClasses.Types.DefrostOperation.resistive
    "Defrost operation type"

  final parameter Buildings.Fluid.DXSystems.Heating.BaseClasses.Types.DefrostTimeMethods
    defTri=Buildings.Fluid.DXSystems.Heating.BaseClasses.Types.DefrostTimeMethods.timed
    "Type of method used to calculate defrost time fraction"

  final parameter Real tDefRun(
    final unit="1",
    displayUnit="1")=0
    "Time period fraction for which defrost cycle is run"

  final parameter Modelica.Units.SI.ThermodynamicTemperature TDefLim=273.65
    "Maximum temperature at which defrost operation is activated"

  final parameter Modelica.Units.SI.HeatFlowRate QDefResCap(min=0) = 0
    "Heating capacity of resistive defrost element"

  final parameter Modelica.Units.SI.HeatFlowRate QCraCap(min=0) = 0
    "Crankcase heater capacity"
//-----------------------------Performance curves-----------------------------//
  final parameter Real defEIRFunT[6] = fill(0,6)
    "Biquadratic coefficients for defrost capacity function of temperature"

  final parameter Real PLFraFunPLR[:] = {1}
    "Quadratic/cubic equation for part load fraction as a function of part-load ratio"
end DXCoil;


Package with generic performance curves

within Buildings.Fluid.DXSystems.Cooling.AirSource.Data;
package Generic "Package with generic performance curves"
  extends Modelica.Icons.MaterialPropertiesPackage;
end Generic;


within Buildings.Fluid.DXSystems.Cooling.AirSource.Data.Generic;
package BaseClasses "Package with base classes for performance data"
  extends Modelica.Icons.BasesPackage;
end BaseClasses;


Generic data record for a stage of a air source DX coil. This is the base record for air source DX coil model at a particular compressor
  speed.
See the information section of

Buildings.Fluid.DXSystems.Cooling.AirSource.Data.Generic.DXCoil for a description of the data.

within Buildings.Fluid.DXSystems.Cooling.AirSource.Data.Generic.BaseClasses;
record Stage "Generic data record for a stage of a air source DX coil"
  extends Modelica.Icons.Record;

  parameter Modelica.Units.SI.AngularVelocity spe(displayUnit="1/min")
    "Rotational speed";

  replaceable parameter
    Buildings.Fluid.DXSystems.Cooling.AirSource.Data.Generic.BaseClasses.NominalValues
    nomVal "Nominal values"

  replaceable parameter
    Buildings.Fluid.DXSystems.Cooling.AirSource.Data.Generic.BaseClasses.PerformanceCurve
    perCur "Performance curves for this stage"
end Stage;


within Buildings.Fluid.DXSystems.Cooling.AirSource.Data;
package SingleSpeed "Performance data for SingleSpeed DXCoils"
  extends Modelica.Icons.MaterialPropertiesPackage;
end SingleSpeed;


within Buildings.Fluid.DXSystems.Cooling.AirSource.Examples;
model MultiStage
  "Test model for multi stage DX cooling coil"
  extends Modelica.Icons.Example;
  package Medium = Buildings.Media.Air
    "Fluid medium for the model";

  parameter Modelica.Units.SI.MassFlowRate m_flow_nominal=datCoi.sta[datCoi.nSta].nomVal.m_flow_nominal
    "Nominal mass flow rate";

  parameter Modelica.Units.SI.PressureDifference dp_nominal=1000
    "Pressure drop at m_flow_nominal";

  Buildings.Fluid.DXSystems.Cooling.AirSource.MultiStage mulStaDX(
    redeclare package Medium = Medium,
    final dp_nominal=dp_nominal,
    final datCoi=datCoi,
    final T_start=datCoi.sta[1].nomVal.TEvaIn_nominal,
    final show_T=true,
    final from_dp=true,
    final energyDynamics=Modelica.Fluid.Types.Dynamics.FixedInitial)
    "Multispeed DX coil"

  Buildings.Fluid.Sources.Boundary_pT sin(
    redeclare package Medium = Medium,
    final nPorts=1,
    final p(displayUnit="Pa") = 101325,
    final T=293.15)
    "Sink"

  Buildings.Fluid.Sources.Boundary_pT sou(
    redeclare package Medium = Medium,
    final nPorts=1,
    final p(displayUnit="Pa") = 101325 + dp_nominal,
    final use_T_in=true,
    final use_p_in=true,
    final T=299.85)
    "Source"

  Modelica.Blocks.Sources.Ramp TEvaIn(
    final duration=600,
    final startTime=2400,
    final height=-5,
    final offset=273.15 + 23)
    "Temperature"

  Modelica.Blocks.Sources.Ramp p(
    final duration=600,
    final startTime=600,
    final height=dp_nominal,
    final offset=101325)
    "Pressure"

  parameter
    Buildings.Fluid.DXSystems.Cooling.AirSource.Data.Generic.DXCoil
    datCoi(
      nSta=4,
      sta={Buildings.Fluid.DXSystems.Cooling.AirSource.Data.Generic.BaseClasses.Stage(
        spe=900/60,
        nomVal=Buildings.Fluid.DXSystems.Cooling.AirSource.Data.Generic.BaseClasses.NominalValues(
          Q_flow_nominal=-12000,
          COP_nominal=3,
          SHR_nominal=0.8,
          m_flow_nominal=0.9),
        perCur=Buildings.Fluid.DXSystems.Cooling.AirSource.Examples.PerformanceCurves.Curve_I()),
      Buildings.Fluid.DXSystems.Cooling.AirSource.Data.Generic.BaseClasses.Stage(
        spe=1200/60,
        nomVal=Buildings.Fluid.DXSystems.Cooling.AirSource.Data.Generic.BaseClasses.NominalValues(
          Q_flow_nominal=-18000,
          COP_nominal=3,
          SHR_nominal=0.8,
          m_flow_nominal=1.2),
        perCur=Buildings.Fluid.DXSystems.Cooling.AirSource.Examples.PerformanceCurves.Curve_I()),
      Buildings.Fluid.DXSystems.Cooling.AirSource.Data.Generic.BaseClasses.Stage(
        spe=1800/60,
        nomVal=Buildings.Fluid.DXSystems.Cooling.AirSource.Data.Generic.BaseClasses.NominalValues(
          Q_flow_nominal=-21000,
          COP_nominal=3,
          SHR_nominal=0.8,
          m_flow_nominal=1.5),
        perCur=Buildings.Fluid.DXSystems.Cooling.AirSource.Examples.PerformanceCurves.Curve_II()),
      Buildings.Fluid.DXSystems.Cooling.AirSource.Data.Generic.BaseClasses.Stage(
        spe=2400/60,
        nomVal=Buildings.Fluid.DXSystems.Cooling.AirSource.Data.Generic.BaseClasses.NominalValues(
          Q_flow_nominal=-30000,
          COP_nominal=3,
          SHR_nominal=0.8,
          m_flow_nominal=1.8),
        perCur=Buildings.Fluid.DXSystems.Cooling.AirSource.Examples.PerformanceCurves.Curve_III())})
    "Coil data"

  Modelica.Blocks.Sources.IntegerTable speRat(
    final table=[0.0,0.0;
                 900,1;
                 1800,4;
                 2700,3;
                 3600,2])
    "Speed ratio "

  Modelica.Blocks.Sources.Constant TConIn(
    final k=273.15 + 25)
    "Condenser inlet temperature"

equation
  connect(sou.ports[1], mulStaDX.port_a)
  connect(mulStaDX.port_b, sin.ports[1])
  connect(TEvaIn.y, sou.T_in)
  connect(p.y, sou.p_in)
  connect(speRat.y, mulStaDX.stage)
  connect(TConIn.y, mulStaDX.TOut)
end MultiStage;


within Buildings.Fluid.DXSystems.Cooling.AirSource;
package Examples "Package with example of DX cooling coil models"
  extends Modelica.Icons.ExamplesPackage;
end Examples;


within Buildings.Fluid.DXSystems.Cooling.AirSource.Examples;
model SingleSpeed
  "Test model for single speed cooling DX coil"
  extends Modelica.Icons.Example;

  package Medium = Buildings.Media.Air
    "Fluid medium for the model";

  parameter Modelica.Units.SI.MassFlowRate m_flow_nominal=datCoi.sta[datCoi.nSta].nomVal.m_flow_nominal
    "Nominal mass flow rate";

  parameter Modelica.Units.SI.PressureDifference dp_nominal=1000
    "Pressure drop at m_flow_nominal";

  parameter Buildings.Fluid.DXSystems.Cooling.AirSource.Data.Generic.DXCoil
    datCoi(
    sta={
      Buildings.Fluid.DXSystems.Cooling.AirSource.Data.Generic.BaseClasses.Stage(
        spe=1800/60,
        nomVal=
          Buildings.Fluid.DXSystems.Cooling.AirSource.Data.Generic.BaseClasses.NominalValues(
          Q_flow_nominal=-21000,
          COP_nominal=3,
          SHR_nominal=0.8,
          m_flow_nominal=1.5),
        perCur=
          Buildings.Fluid.DXSystems.Cooling.AirSource.Examples.PerformanceCurves.Curve_II())},
    nSta=1)
    "Coil data"

  Buildings.Fluid.DXSystems.Cooling.AirSource.SingleSpeed
    sinSpeDX(
    redeclare package Medium = Medium,
    final dp_nominal=dp_nominal,
    final datCoi=datCoi,
    final T_start=datCoi.sta[1].nomVal.TEvaIn_nominal,
    final show_T=true,
    final from_dp=true,
    final energyDynamics=Modelica.Fluid.Types.Dynamics.FixedInitial)
    "Single speed DX coil"

  Buildings.Fluid.Sources.Boundary_pT sin(
    redeclare package Medium = Medium,
    final p(displayUnit="Pa") = 101325,
    final nPorts=1,
    final T=303.15)
    "Sink"

  Buildings.Fluid.Sources.Boundary_pT sou(
    redeclare package Medium = Medium,
    p(displayUnit="Pa") = 101325 + dp_nominal,
    final use_T_in=true,
    final nPorts=1,
    final use_p_in=true,
    final T=299.85)
    "Source"

  Modelica.Blocks.Sources.BooleanStep onOff(
    final startTime=600)
    "Compressor on-off signal"

  Modelica.Blocks.Sources.Ramp TEvaIn(
    final duration=600,
    final startTime=2400,
    final height=-5,
    final offset=273.15 + 23)
    "Temperature"

  Modelica.Blocks.Sources.Ramp p(
    final duration=600,
    final startTime=600,
    final height=dp_nominal,
    final offset=101325)
    "Pressure"

  Modelica.Blocks.Sources.Constant TConIn(
    final k=273.15 + 25)
    "Condenser inlet temperature"

equation
  connect(TEvaIn.y, sou.T_in)
  connect(onOff.y, sinSpeDX.on)
  connect(sou.ports[1], sinSpeDX.port_a)
  connect(sinSpeDX.port_b, sin.ports[1])
  connect(p.y, sou.p_in)
  connect(TConIn.y, sinSpeDX.TOut)
end SingleSpeed;


Space cooling with DX coils

within Buildings.Fluid.DXSystems.Cooling.AirSource.Examples;
model SpaceCooling "Space cooling with DX coils"
  extends Modelica.Icons.Example;
  replaceable package Medium = Buildings.Media.Air
    "Fluid medium for the model";

  parameter Modelica.Units.SI.Volume V=6*10*3
    "Room volume";
  //////////////////////////////////////////////////////////
  // Heat recovery effectiveness
  parameter Real eps = 0.8
    "Heat recovery effectiveness";

  /////////////////////////////////////////////////////////
  // Air temperatures at design conditions
  parameter Modelica.Units.SI.Temperature TASup_nominal=273.15 + 18
    "Nominal air temperature supplied to room";

  parameter Modelica.Units.SI.Temperature TRooSet=273.15 + 24
    "Nominal room air temperature";

  parameter Modelica.Units.SI.Temperature TOut_nominal=273.15 + 30
    "Design outlet air temperature";

  parameter Modelica.Units.SI.Temperature THeaRecLvg=TOut_nominal - eps*(
      TOut_nominal - TRooSet) "Air temperature leaving the heat recovery";

  /////////////////////////////////////////////////////////
  // Cooling loads and air mass flow rates
  parameter Modelica.Units.SI.HeatFlowRate QRooInt_flow=1000
    "Internal heat gains of the room";

  parameter Modelica.Units.SI.HeatFlowRate QRooC_flow_nominal=
     -QRooInt_flow - 10E3/30*(TOut_nominal - TRooSet)
    "Nominal cooling load of the room";
  parameter Modelica.Units.SI.MassFlowRate mA_flow_nominal=
     1.3*QRooC_flow_nominal/1006/(TASup_nominal - TRooSet)
    "Nominal air mass flow rate, increased by factor 1.3 to allow for recovery after temperature setback";

  parameter Modelica.Units.SI.TemperatureDifference dTFan=2
    "Estimated temperature raise across fan that needs to be made up by the cooling coil";

  parameter Modelica.Units.SI.HeatFlowRate QCoiC_flow_nominal=
    (QRooC_flow_nominal + mA_flow_nominal*(TASup_nominal - THeaRecLvg - dTFan)*1006)
    "Cooling load of coil, taking into account economizer, and increased due to latent heat removal";

  parameter
    Buildings.Fluid.DXSystems.Cooling.AirSource.Data.Generic.DXCoil
    datCoi(
      sta={Buildings.Fluid.DXSystems.Cooling.AirSource.Data.Generic.BaseClasses.Stage(
        spe=1800/60,
        nomVal=Buildings.Fluid.DXSystems.Cooling.AirSource.Data.Generic.BaseClasses.NominalValues(
          Q_flow_nominal=QCoiC_flow_nominal,
          COP_nominal=3,
          SHR_nominal=0.7,
          m_flow_nominal=mA_flow_nominal),
        perCur=Buildings.Fluid.DXSystems.Cooling.AirSource.Examples.PerformanceCurves.Curve_I())},
      nSta=1)
    "Data record for single-speed coil"

  parameter
    Buildings.Fluid.DXSystems.Cooling.AirSource.Data.Generic.DXCoil
    datCoiMulSpe(
      nSta=2,
      sta={
      Buildings.Fluid.DXSystems.Cooling.AirSource.Data.Generic.BaseClasses.Stage(
        spe=900/60,
        nomVal=
        Buildings.Fluid.DXSystems.Cooling.AirSource.Data.Generic.BaseClasses.NominalValues(
          Q_flow_nominal=QCoiC_flow_nominal*900/2400,
          COP_nominal=3,
          SHR_nominal=0.7,
          m_flow_nominal=mA_flow_nominal*900/2400),
        perCur=
        Buildings.Fluid.DXSystems.Cooling.AirSource.Examples.PerformanceCurves.Curve_I()),
      Buildings.Fluid.DXSystems.Cooling.AirSource.Data.Generic.BaseClasses.Stage(
        spe=2400/60,
        nomVal=
        Buildings.Fluid.DXSystems.Cooling.AirSource.Data.Generic.BaseClasses.NominalValues(
          Q_flow_nominal=QCoiC_flow_nominal,
          COP_nominal=3,
          SHR_nominal=0.7,
          m_flow_nominal=mA_flow_nominal),
        perCur=
        Buildings.Fluid.DXSystems.Cooling.AirSource.Examples.PerformanceCurves.Curve_I())})
    "Coil data multi-stage and variable speed cooling coils"

  Buildings.Fluid.Movers.FlowControlled_m_flow fan(
    redeclare package Medium = Medium,
    final m_flow_nominal=mA_flow_nominal,
    final energyDynamics=Modelica.Fluid.Types.Dynamics.SteadyState)
    "Supply air fan"

  Buildings.Fluid.HeatExchangers.ConstantEffectiveness hex(
    redeclare package Medium1 = Medium,
    redeclare package Medium2 = Medium,
    final m1_flow_nominal=mA_flow_nominal,
    final m2_flow_nominal=mA_flow_nominal,
    final dp1_nominal=200,
    final dp2_nominal=200,
    final eps=eps)
    "Heat recovery"

  Buildings.Fluid.Sources.Outside out(
    final nPorts=6,
    redeclare package Medium = Medium)
    "Source for outdoor air"

  BoundaryConditions.WeatherData.ReaderTMY3 weaDat(
    final pAtmSou=Buildings.BoundaryConditions.Types.DataSource.Parameter,
    final TDryBul=TOut_nominal,
    final filNam=Modelica.Utilities.Files.loadResource("modelica://Buildings/Resources/weatherdata/USA_IL_Chicago-OHare.Intl.AP.725300_TMY3.mos"),
    final TDryBulSou=Buildings.BoundaryConditions.Types.DataSource.File)
    "Weather data reader"

  BoundaryConditions.WeatherData.Bus weaBus
    "Weather bus"

  Modelica.Blocks.Sources.Constant mAir_flow(
    final k=mA_flow_nominal)
    "Fan air flow rate"

  Buildings.Fluid.Sensors.TemperatureTwoPort senTemHXEvaOut(
    redeclare package Medium = Medium,
    final m_flow_nominal=mA_flow_nominal)
    "Temperature sensor for heat recovery outlet on supply side"

  Buildings.Fluid.Sensors.TemperatureTwoPort senTemSupAir(
    redeclare package Medium = Medium,
    final m_flow_nominal=mA_flow_nominal)
    "Temperature sensor for supply air"

  Modelica.Blocks.Logical.OnOffController con(
    final bandwidth=1,
    final pre_y_start=true)
    "Controller to enable component when measurement falls below setpoint"

  Modelica.Blocks.Sources.Constant TRooSetPoi(
    final k=TRooSet)
    "Room temperature set point"

  Buildings.Fluid.DXSystems.Cooling.AirSource.SingleSpeed
    sinSpeDX(
    redeclare package Medium = Medium,
    final datCoi=datCoi,
    final dp_nominal=400,
    final energyDynamics=Modelica.Fluid.Types.Dynamics.FixedInitial)
    "Single-speed DX cooling coil"

  SimpleRoom rooSinSpe(
    redeclare package Medium = Medium,
    final nPorts=2,
    final QRooInt_flow=QRooInt_flow,
    final mA_flow_nominal=mA_flow_nominal)
    "Room model connected to single speed coil"

  Buildings.Fluid.Movers.FlowControlled_m_flow fan1(
    redeclare package Medium = Medium,
    final m_flow_nominal=mA_flow_nominal,
    final energyDynamics=Modelica.Fluid.Types.Dynamics.SteadyState)
    "Supply air fan"

  Buildings.Fluid.HeatExchangers.ConstantEffectiveness hex1(
    redeclare package Medium1 = Medium,
    redeclare package Medium2 = Medium,
    final m1_flow_nominal=mA_flow_nominal,
    final m2_flow_nominal=mA_flow_nominal,
    final dp1_nominal=200,
    final dp2_nominal=200,
    final eps=eps)
    "Heat recovery"

  Buildings.Fluid.Sensors.TemperatureTwoPort senTemHXEvaOut1(
    redeclare package Medium = Medium,
    final m_flow_nominal=mA_flow_nominal)
    "Temperature sensor for heat recovery outlet on supply side"

  Buildings.Fluid.Sensors.TemperatureTwoPort senTemSupAir1(
    redeclare package Medium = Medium,
    final m_flow_nominal=mA_flow_nominal)
    "Temperature sensor for supply air"

  Buildings.Fluid.DXSystems.Cooling.AirSource.MultiStage mulStaDX(
    redeclare package Medium = Medium,
    final dp_nominal=400,
    final datCoi=datCoiMulSpe,
    final energyDynamics=Modelica.Fluid.Types.Dynamics.FixedInitial)
    "Multi-speed DX coil"

  SimpleRoom rooMulSpe(
    redeclare package Medium = Medium,
    final nPorts=2,
    final QRooInt_flow=QRooInt_flow,
    final mA_flow_nominal=mA_flow_nominal)
    "Room model connected to multi stage coil"

  ControllerTwoStage
    mulSpeCon
    "Controller for multi-stage coil"

  SimpleRoom rooVarSpe(
    redeclare package Medium = Medium,
    final nPorts=2,
    final QRooInt_flow=QRooInt_flow,
    final mA_flow_nominal=mA_flow_nominal)
    "Room model connected to variable speed coil"

  Buildings.Fluid.Movers.FlowControlled_m_flow fan2(
    redeclare package Medium = Medium,
    final m_flow_nominal=mA_flow_nominal,
    final energyDynamics=Modelica.Fluid.Types.Dynamics.SteadyState)
    "Supply air fan"

  Buildings.Fluid.Sensors.TemperatureTwoPort senTemSupAir2(
    redeclare package Medium = Medium,
    final m_flow_nominal=mA_flow_nominal)
    "Temperature sensor for supply air"

  Buildings.Fluid.DXSystems.Cooling.AirSource.VariableSpeed
    varSpeDX(
    redeclare package Medium = Medium,
    final dp_nominal=400,
    final datCoi=datCoiMulSpe,
    final minSpeRat=0.2,
    final energyDynamics=Modelica.Fluid.Types.Dynamics.FixedInitial)
    "Variable-speed DX coil"

  Buildings.Fluid.Sensors.TemperatureTwoPort senTemHXEvaOut2(
    redeclare package Medium = Medium,
    final m_flow_nominal=mA_flow_nominal)
    "Temperature sensor for heat recovery outlet on supply side"

  Buildings.Fluid.HeatExchangers.ConstantEffectiveness hex2(
    redeclare package Medium1 = Medium,
    redeclare package Medium2 = Medium,
    final m1_flow_nominal=mA_flow_nominal,
    final m2_flow_nominal=mA_flow_nominal,
    final dp1_nominal=200,
    final dp2_nominal=200,
    final eps=eps)
    "Heat recovery"

  Modelica.Blocks.Continuous.Integrator sinSpePow(
    y(final unit="J"))
    "Power consumed by single speed coil"

  Modelica.Blocks.Continuous.Integrator mulSpePow(
    y(final unit="J"))
    "Power consumed by multi-stage coil"

  Modelica.Blocks.Continuous.Integrator varSpePow(
    y(final unit="J"))
    "Power consumed by multi-stage coil"

  Modelica.Blocks.Logical.Not not1
    "Turn on DX coil when measured temperature is above setpoint"

  Buildings.Controls.Continuous.LimPID conVarSpe(
    final controllerType=Modelica.Blocks.Types.SimpleController.P,
    final Ti=1,
    final Td=1,
    final reverseActing=false)
    "Controller for variable speed DX coil"

equation
  connect(out.ports[1], hex.port_a1)
  connect(out.ports[2], hex.port_b2)

  connect(weaDat.weaBus, out.weaBus)
  connect(weaDat.weaBus, weaBus)
  connect(fan.m_flow_in, mAir_flow.y)
  connect(hex.port_b1, senTemHXEvaOut.port_a)
  connect(senTemSupAir.port_b, fan.port_a)
  connect(senTemHXEvaOut.port_b, sinSpeDX.port_a)
  connect(sinSpeDX.port_b, senTemSupAir.port_a)

public
  model SimpleRoom
    "Simple model of a room"

    replaceable package Medium = Modelica.Media.Interfaces.PartialMedium
      "Medium in the room"

    parameter Integer nPorts=0
      "Number of ports"

    final parameter Modelica.Units.SI.Volume V=6*10*3
      "Room volume";

    parameter Modelica.Units.SI.HeatFlowRate QRooInt_flow
      "Internal heat gains of the room";

    parameter Modelica.Units.SI.MassFlowRate mA_flow_nominal
      "Nominal air mass flow rate";

    Modelica.Blocks.Interfaces.RealInput TOutDryBul
      "Outdoor drybulb temperature"

    Modelica.Blocks.Interfaces.RealOutput TRoo(
      final unit="K")
      "Room temperature"

    Modelica.Fluid.Vessels.BaseClasses.VesselFluidPorts_b ports[nPorts](
      redeclare each package Medium = Medium)
      "Port for inlet air into and exhaust air from the zone"

    Buildings.Fluid.MixingVolumes.MixingVolume vol(
      redeclare package Medium = Medium,
      final m_flow_nominal=mA_flow_nominal,
      final V=V,
      final nPorts=2,
      final energyDynamics=Modelica.Fluid.Types.Dynamics.FixedInitial)
      "Mixed air volume representing air in the zone"

    Modelica.Thermal.HeatTransfer.Components.ThermalConductor theCon(
      final G=10000/30,
      final port_a(T(start=Medium.T_default)))
      "Thermal conductance with the ambient"

    Modelica.Thermal.HeatTransfer.Sources.PrescribedTemperature TOut(
      port(
        T(final start=Medium.T_default)))
      "Outside temperature"

    Modelica.Thermal.HeatTransfer.Sources.FixedHeatFlow preHea(
      final Q_flow=QRooInt_flow)
      "Prescribed heat flow"

    Modelica.Thermal.HeatTransfer.Sensors.TemperatureSensor senTemRoo
      "Room temperature sensor"

    Modelica.Thermal.HeatTransfer.Components.HeatCapacitor heaCap(
      final C=2*V*1.2*1006)
      "Heat capacity for furniture and walls"

  equation
    connect(theCon.port_b,vol. heatPort)
    connect(preHea.port,vol. heatPort)
    connect(TOut.port,theCon. port_a)
    connect(vol.heatPort,senTemRoo. port)
    connect(heaCap.port,vol. heatPort)
    connect(TRoo, senTemRoo.T)
    connect(ports, vol.ports)
    connect(TOut.T, TOutDryBul)
  end SimpleRoom;
equation

  connect(sinSpeDX.TOut, weaBus.TDryBul)
  connect(fan.port_b, rooSinSpe.ports[1])
  connect(rooSinSpe.ports[2], hex.port_a2)

  connect(hex1.port_b1, senTemHXEvaOut1.port_a)
  connect(senTemSupAir1.port_b, fan1.port_a)
  connect(senTemHXEvaOut1.port_b, mulStaDX.port_a)
  connect(mulStaDX.port_b, senTemSupAir1.port_a)
  connect(mulStaDX.TOut, weaBus.TDryBul)

  connect(fan1.port_b, rooMulSpe.ports[1])
  connect(rooMulSpe.ports[2], hex1.port_a2)

  connect(rooMulSpe.TOutDryBul, weaBus.TDryBul)

public
  model ControllerTwoStage
    "Controller for two stage coil"
    extends Buildings.BaseClasses.BaseIcon;

    parameter Real bandwidth=1
      "Bandwidth around reference signal";

    Modelica.Blocks.Logical.OnOffController con1(
      final bandwidth=bandwidth/2,
      final pre_y_start=true)
      "Controller for second stage"

    Modelica.Blocks.Logical.OnOffController con2(
      final bandwidth=bandwidth/2,
      final pre_y_start=true)
      "Controller for first stage"

    Modelica.Blocks.Interfaces.RealInput u
      "Measured signal"

    Modelica.Blocks.Interfaces.RealInput reference
      "Connector of Real input signal used as reference signal"

    Modelica.Blocks.Math.Add add(
      final k2=-1)
      "Calculate value to turn on the second stage"

    Modelica.Blocks.Sources.Constant const(
      final k=bandwidth/2)
      "Constant bandwidth-value source"

    Modelica.Blocks.Math.Add add1
      "Calculate value to turn on the first stage"

    Modelica.Blocks.MathInteger.MultiSwitch multiSwitch1(
      final expr={2,1},
      final y_default=0,
      final use_pre_as_default=false,
      final nu=2)
      "Switch on appropriate stage based on Boolean signals received"

    Modelica.Blocks.Interfaces.IntegerOutput stage
      "Coil stage control signal"

    Modelica.Blocks.Logical.Not not1
      "Turn on second stage when measurement exceeds higher temperature limit"

    Modelica.Blocks.Logical.Not not2
      "Enable first stage when measurement exceeds lower temperature limit"

  equation
    connect(con1.reference, reference)
    connect(const.y, add.u2)
    connect(const.y, add1.u1)
    connect(add.u1, u)
    connect(add1.u2, u)
    connect(add.y, con1.u)
    connect(add1.y, con2.u)
    connect(reference, con2.reference)
    connect(multiSwitch1.y, stage)
    connect(not2.y, multiSwitch1.u[1])
    connect(not1.y, multiSwitch1.u[2])
    connect(con1.y, not1.u)
    connect(con2.y, not2.u)
  end ControllerTwoStage;
equation
  connect(mulSpeCon.stage, mulStaDX.stage)
  connect(rooVarSpe.TOutDryBul, weaBus.TDryBul)
  connect(senTemSupAir2.port_b,fan2. port_a)
  connect(varSpeDX.port_b, senTemSupAir2.port_a)
  connect(senTemHXEvaOut2.port_b, varSpeDX.port_a)
  connect(varSpeDX.TOut, weaBus.TDryBul)
  connect(hex2.port_b1,senTemHXEvaOut2. port_a)
  connect(out.ports[3], hex1.port_a1)
  connect(out.ports[4], hex1.port_b2)
  connect(out.ports[5], hex2.port_a1)
  connect(out.ports[6], hex2.port_b2)
  connect(fan2.port_b, rooVarSpe.ports[1])
  connect(rooVarSpe.ports[2], hex2.port_a2)

  connect(mAir_flow.y, fan1.m_flow_in)
  connect(mAir_flow.y, fan2.m_flow_in)
  connect(rooSinSpe.TOutDryBul, weaBus.TDryBul)
  connect(sinSpePow.u, sinSpeDX.P)
  connect(mulSpePow.u, mulStaDX.P)
  connect(varSpeDX.P, varSpePow.u)
  connect(TRooSetPoi.y, con.reference)
  connect(rooSinSpe.TRoo, con.u)

  connect(not1.u, con.y)
  connect(not1.y, sinSpeDX.on)
  connect(mulSpeCon.reference, TRooSetPoi.y)
  connect(rooMulSpe.TRoo, mulSpeCon.u)
  connect(TRooSetPoi.y, conVarSpe.u_s)
  connect(conVarSpe.u_m, rooVarSpe.TRoo)

  connect(conVarSpe.y, varSpeDX.speRat)
end SpaceCooling;


Test model for variable speed DX coil

within Buildings.Fluid.DXSystems.Cooling.AirSource.Examples;
model VariableSpeed
  "Test model for variable speed DX coil"
  extends Modelica.Icons.Example;

  package Medium = Buildings.Media.Air
    "Medium model";

  parameter Modelica.Units.SI.MassFlowRate m_flow_nominal=datCoi.sta[datCoi.nSta].nomVal.m_flow_nominal
    "Nominal mass flow rate";

  parameter Modelica.Units.SI.PressureDifference dp_nominal=1000
    "Pressure drop at m_flow_nominal";

  parameter
    Buildings.Fluid.DXSystems.Cooling.AirSource.Data.Generic.DXCoil
    datCoi(
      nSta=4,
      sta={Buildings.Fluid.DXSystems.Cooling.AirSource.Data.Generic.BaseClasses.Stage(
        spe=900/60,
        nomVal=
        Buildings.Fluid.DXSystems.Cooling.AirSource.Data.Generic.BaseClasses.NominalValues(
          Q_flow_nominal=-12000,
          COP_nominal=3,
          SHR_nominal=0.8,
          m_flow_nominal=0.9),
        perCur=
        Buildings.Fluid.DXSystems.Cooling.AirSource.Examples.PerformanceCurves.Curve_I()),
      Buildings.Fluid.DXSystems.Cooling.AirSource.Data.Generic.BaseClasses.Stage(
        spe=1200/60,
        nomVal=
        Buildings.Fluid.DXSystems.Cooling.AirSource.Data.Generic.BaseClasses.NominalValues(
          Q_flow_nominal=-18000,
          COP_nominal=3,
          SHR_nominal=0.8,
          m_flow_nominal=1.2),
        perCur=
        Buildings.Fluid.DXSystems.Cooling.AirSource.Examples.PerformanceCurves.Curve_I()),
      Buildings.Fluid.DXSystems.Cooling.AirSource.Data.Generic.BaseClasses.Stage(
        spe=1800/60,
        nomVal=
        Buildings.Fluid.DXSystems.Cooling.AirSource.Data.Generic.BaseClasses.NominalValues(
          Q_flow_nominal=-21000,
          COP_nominal=3,
          SHR_nominal=0.8,
          m_flow_nominal=1.5),
        perCur=
        Buildings.Fluid.DXSystems.Cooling.AirSource.Examples.PerformanceCurves.Curve_II()),
      Buildings.Fluid.DXSystems.Cooling.AirSource.Data.Generic.BaseClasses.Stage(
        spe=2400/60,
        nomVal=
        Buildings.Fluid.DXSystems.Cooling.AirSource.Data.Generic.BaseClasses.NominalValues(
          Q_flow_nominal=-30000,
          COP_nominal=3,
          SHR_nominal=0.8,
          m_flow_nominal=1.8),
        perCur=
        Buildings.Fluid.DXSystems.Cooling.AirSource.Examples.PerformanceCurves.Curve_III())})
    "Coil data"

  Buildings.Fluid.DXSystems.Cooling.AirSource.VariableSpeed
    varSpeDX(
    redeclare package Medium = Medium,
    final dp_nominal=dp_nominal,
    final datCoi=datCoi,
    final minSpeRat=datCoi.minSpeRat,
    final T_start=datCoi.sta[1].nomVal.TEvaIn_nominal,
    final from_dp=true,
    final energyDynamics=Modelica.Fluid.Types.Dynamics.FixedInitial)
    "Variable speed DX coil"

  Buildings.Fluid.Sources.Boundary_pT sin(
    redeclare package Medium = Medium,
    final nPorts=1,
    final p = 101325,
    final T=293.15)
    "Sink"

  Buildings.Fluid.Sources.Boundary_pT sou(
    redeclare package Medium = Medium,
    final nPorts=1,
    final p = 101325 + dp_nominal,
    final use_T_in=true,
    final use_p_in=true,
    final T=299.85)
    "Source"

  Modelica.Blocks.Sources.Ramp TEvaIn(
    final duration=600,
    final startTime=900,
    final height=5,
    final offset=273.15 + 20)
    "Evaporator coil inlet air temperature"

  Modelica.Blocks.Sources.TimeTable speRat(
    final table=[0.0,0.0;
                 100,0.0;
                 900,0.2;
                 1800,0.8;
                 2700,0.75;
                 3600,0.75])
    "Speed ratio "

  Modelica.Blocks.Sources.Ramp p(
    final duration=600,
    final height=dp_nominal,
    final offset=101325,
    final startTime=100)
    "Pressure of inlet air"

  Modelica.Blocks.Sources.Constant TConIn(
    final k=273.15 + 25)
    "Condenser inlet temperature"

equation
  connect(sou.ports[1], varSpeDX.port_a)
  connect(varSpeDX.port_b, sin.ports[1])
  connect(TEvaIn.y, sou.T_in)
  connect(speRat.y, varSpeDX.speRat)
  connect(p.y, sou.p_in)
  connect(varSpeDX.TOut, TConIn.y)
end VariableSpeed;


Package with several performance curves

within Buildings.Fluid.DXSystems.Cooling.AirSource.Examples;
package PerformanceCurves "Package with several performance curves"
  extends Modelica.Icons.MaterialPropertiesPackage;
end PerformanceCurves;


Collection of validation models

within Buildings.Fluid.DXSystems.Cooling.AirSource;
package Validation "Collection of validation models"
  extends Modelica.Icons.ExamplesPackage;
end Validation;


within Buildings.Fluid.DXSystems.Cooling.AirSource.Validation;
model SingleSpeed
  "Validation model for single speed DX coil with PLR=1"
  extends Modelica.Icons.Example;

  package Medium = Buildings.Media.Air
    "Medium model";

  parameter Modelica.Units.SI.Power Q_flow_nominal=datCoi.sta[1].nomVal.Q_flow_nominal
    "Nominal power";

  parameter Modelica.Units.SI.MassFlowRate m_flow_nominal=datCoi.sta[1].nomVal.m_flow_nominal
    "Nominal mass flow rate";

  parameter Modelica.Units.SI.PressureDifference dp_nominal=1141
    "Pressure drop at m_flow_nominal";

  parameter
    Buildings.Fluid.DXSystems.Cooling.AirSource.Data.Generic.DXCoil
    datCoi(nSta=1, sta={
        Buildings.Fluid.DXSystems.Cooling.AirSource.Data.Generic.BaseClasses.Stage(
        spe=1800/60,
        nomVal=
          Buildings.Fluid.DXSystems.Cooling.AirSource.Data.Generic.BaseClasses.NominalValues(
          Q_flow_nominal=-10500,
          COP_nominal=3,
          SHR_nominal=0.798655,
          m_flow_nominal=1.72),
        perCur=
          Buildings.Fluid.DXSystems.Cooling.AirSource.Examples.PerformanceCurves.Curve_II())})
    "Coil data"

  Buildings.Fluid.Sources.Boundary_pT sin(
    redeclare package Medium = Medium,
    final p(displayUnit="Pa") = 101325,
    final nPorts=1,
    final T=303.15)
    "Sink"

  Buildings.Fluid.Sources.Boundary_pT sou(
    redeclare package Medium = Medium,
    final p(displayUnit="Pa") = 101325 + dp_nominal,
    final use_T_in=true,
    final nPorts=1,
    final use_p_in=true,
    final use_X_in=true,
    final T=299.85)
    "Source"

  Buildings.Fluid.DXSystems.Cooling.AirSource.SingleSpeed
    sinSpeDX(
    redeclare package Medium = Medium,
    final dp_nominal=dp_nominal,
    final datCoi=datCoi,
    final T_start=datCoi.sta[1].nomVal.TEvaIn_nominal,
    final from_dp=true,
    final energyDynamics=Modelica.Fluid.Types.Dynamics.FixedInitial)
    "Single speed DX coil"

  Modelica.Blocks.Sources.TimeTable plr_onOff(final table=[0,0; 3600,0; 3600,0; 7200,0;
        7200,0; 10800,0; 10800,0; 14400,0; 14400,0; 18000,0; 18000,0; 21600,0; 21600,
        0; 25200,0; 25200,1; 28800,1; 28800,1; 32400,1; 32400,1; 36000,1; 36000,
        1; 39600,1; 39600,1; 43200,1; 43200,1; 46800,1; 46800,1; 50400,1; 50400,
        1; 54000,1; 54000,1; 57600,1; 57600,1; 61200,1; 61200,0; 64800,0; 64800,
        0; 68400,0; 68400,0; 72000,0; 72000,0; 75600,0; 75600,0; 79200,0; 79200,
        0; 82800,0; 82800,0; 86400,0])
    "EnergyPlus PLR converted into on-off signal for this model"

  Modelica.Blocks.Sources.TimeTable TCIn(final table=[0,21.1; 3600,21.1; 3600,
        20.80833333; 7200,20.80833333; 7200,20.89166667; 10800,20.89166667;
        10800,21.1; 14400,21.1; 14400,20.80833333; 18000,20.80833333; 18000,
        20.6; 21600,20.6; 21600,20.89166667; 25200,20.89166667; 25200,21.45;
        28800,21.45; 28800,22.63333333; 32400,22.63333333; 32400,23.3; 36000,
        23.3; 36000,25.575; 39600,25.575; 39600,28.19166667; 43200,28.19166667;
        43200,27.90833333; 46800,27.90833333; 46800,26.90833333; 50400,
        26.90833333; 50400,26.7; 54000,26.7; 54000,26.05833333; 57600,
        26.05833333; 57600,24.60833333; 61200,24.60833333; 61200,23.55; 64800,
        23.55; 64800,23.3; 68400,23.3; 68400,23.00833333; 72000,23.00833333;
        72000,22.8; 75600,22.8; 75600,22.15833333; 79200,22.15833333; 79200,
        21.35; 82800,21.35; 82800,21.1; 86400,21.1])
    "Condenser inlet temperature"

  Modelica.Blocks.Sources.TimeTable TEvaIn(final table=[0,31.29534707; 3600,31.29534707;
        3600,30.89999423; 7200,30.89999423; 7200,30.58355581; 10800,30.58355581;
        10800,30.30108174; 14400,30.30108174; 14400,30.01393253; 18000,30.01393253;
        18000,29.75672215; 21600,29.75672215; 21600,29.66076742; 25200,29.66076742;
        25200,25.29138892; 28800,25.29138892; 28800,25.91180176; 32400,25.91180176;
        32400,26.79831523; 36000,26.79831523; 36000,27.40611604; 39600,27.40611604;
        39600,28.22402981; 43200,28.22402981; 43200,28.69183674; 46800,28.69183674;
        46800,29.0211012; 50400,29.0211012; 50400,29.3698004; 54000,29.3698004;
        54000,29.52289127; 57600,29.52289127; 57600,29.41955159; 61200,29.41955159;
        61200,38.68278429; 64800,38.68278429; 64800,35.75595795; 68400,35.75595795;
        68400,33.29770237; 72000,33.29770237; 72000,32.78839302; 75600,32.78839302;
        75600,32.3989099; 79200,32.3989099; 79200,32.00270417; 82800,32.00270417;
        82800,31.66453096; 86400,31.66453096])
    "Coil inlet temperature"

  Modelica.Blocks.Sources.TimeTable XEvaIn(final table=[0,0.010526598; 3600,0.010526598;
        3600,0.010526598; 7200,0.010526598; 7200,0.010526598; 10800,0.010526598;
        10800,0.010526598; 14400,0.010526598; 14400,0.010526598; 18000,
        0.010526598; 18000,0.010526598; 21600,0.010526598; 21600,0.010631087;
        25200,0.010631087; 25200,0.010396485; 28800,0.010396485; 28800,
        0.009496633; 32400,0.009496633; 32400,0.009521406; 36000,0.009521406;
        36000,0.009576525; 39600,0.009576525; 39600,0.009574467; 43200,
        0.009574467; 43200,0.009610872; 46800,0.009610872; 46800,0.009792709;
        50400,0.009792709; 50400,0.010022684; 54000,0.010022684; 54000,
        0.010213791; 57600,0.010213791; 57600,0.010384401; 61200,0.010384401;
        61200,0.010396282; 64800,0.010396282; 64800,0.010537993; 68400,
        0.010537993; 68400,0.010537961; 72000,0.010537961; 72000,0.010537961;
        75600,0.010537961; 75600,0.010537961; 79200,0.010537961; 79200,
        0.010537961; 82800,0.010537961; 82800,0.010537961; 86400,0.010537961])
    "Water fraction of moist air"

  Modelica.Blocks.Math.RealToBoolean onOff
    "Enable the DX coil when input is greater than 0.5"

  Modelica.Blocks.Routing.Multiplex2 mux
    "Converts in an array"

  Buildings.Utilities.IO.BCVTB.From_degC TCIn_K
    "Converts degC to K"

  Buildings.Utilities.IO.BCVTB.From_degC TEvaIn_K
    "Converts degC to K"

  Modelica.Blocks.Math.Mean TOutMea(
    final f=1/3600)
    "Average out value over one hour"

  Buildings.Utilities.IO.BCVTB.To_degC TOutDegC
    "Convert to degree Celsius"

  Modelica.Blocks.Sources.RealExpression TOut(
    final y=sinSpeDX.vol.T)
    "Measured outlet air temperature from model"

  Modelica.Blocks.Math.Mean XEvaOutMea(
    final f=1/3600)
    "Average out value over one hour"

  Modelica.Blocks.Sources.RealExpression XEvaOut(
    final y=sum(sinSpeDX.vol.Xi))
    "Measured outlet air humidity ratio (total air)"

  Modelica.Blocks.Math.Mean Q_flowMea(
    final f=1/3600)
    "Mean of cooling rate"

  Modelica.Blocks.Math.Mean Q_flowSenMea(
    final f=1/3600)
    "Mean of sensible cooling rate"

  Modelica.Blocks.Math.Mean PMea(
    final f=1/3600)
    "Mean of power"

  Modelica.Blocks.Math.Add add(
    final k1=-1)
    "Convert humidity ratio (dry air) to humidity ratio (total air)"

  Modelica.Blocks.Sources.Constant XEvaInMoiAir(
    final k=1.0)
    "Moist air fraction = 1"

  Modelica.Blocks.Sources.TimeTable TOutEPlu(final table=[0,31.29534707; 3600,31.29534707;
        3600,30.89999423; 7200,30.89999423; 7200,30.58355581; 10800,30.58355581;
        10800,30.30108174; 14400,30.30108174; 14400,30.01393253; 18000,30.01393253;
        18000,29.75672215; 21600,29.75672215; 21600,29.66076742; 25200,29.66076742;
        25200,20.31734137; 28800,20.31734137; 28800,20.48740189; 32400,20.48740189;
        32400,21.17362815; 36000,21.17362815; 36000,21.67091874; 39600,21.67091874;
        39600,22.31588652; 43200,22.31588652; 43200,22.67802681; 46800,22.67802681;
        46800,22.97615397; 50400,22.97615397; 50400,23.31283949; 54000,23.31283949;
        54000,23.48357346; 57600,23.48357346; 57600,23.44857837; 61200,23.44857837;
        61200,38.68278429; 64800,38.68278429; 64800,35.75595795; 68400,35.75595795;
        68400,33.29770237; 72000,33.29770237; 72000,32.78839302; 75600,32.78839302;
        75600,32.3989099; 79200,32.3989099; 79200,32.00270417; 82800,32.00270417;
        82800,31.66453096; 86400,31.66453096])
    "EnergyPlus result: outlet temperature"

  Modelica.Blocks.Sources.TimeTable Q_flowEPlu(final table=[0,-1e-07; 3600,-1e-07; 3600,
        -1e-07; 7200,-1e-07; 7200,-1e-07; 10800,-1e-07; 10800,-1e-07; 14400,-1e-07;
        14400,-1e-07; 18000,-1e-07; 18000,-1e-07; 21600,-1e-07; 21600,-1e-07; 25200,
        -1e-07; 25200,-10983.1144101; 28800,-10983.1144101; 28800,-10855.9768001;
        32400,-10855.9768001; 32400,-10903.5304201; 36000,-10903.5304201; 36000,
        -10877.5678501; 39600,-10877.5678501; 39600,-10822.2172001; 43200,-10822.2172001;
        43200,-10878.2459001; 46800,-10878.2459001; 46800,-10981.5365901; 50400,
        -10981.5365901; 50400,-11055.6112701; 54000,-11055.6112701; 54000,-11121.6278701;
        57600,-11121.6278701; 57600,-11185.7466001; 61200,-11185.7466001; 61200,
        -1e-07; 64800,-1e-07; 64800,-1e-07; 68400,-1e-07; 68400,-1e-07; 72000,-1e-07;
        72000,-1e-07; 75600,-1e-07; 75600,-1e-07; 79200,-1e-07; 79200,-1e-07; 82800,
        -1e-07; 82800,-1e-07; 86400,-1e-07])
    "EnergyPlus result: heat flow"

  Modelica.Blocks.Sources.TimeTable Q_flowSenEPlu(final table=[0,0; 3600,0; 3600,0; 7200,
        0; 7200,0; 10800,0; 10800,0; 14400,0; 14400,0; 18000,0; 18000,0; 21600,0;
        21600,0; 25200,0; 25200,-8537.795206; 28800,-8537.795206; 28800,-9298.755552;
        32400,-9298.755552; 32400,-9643.742602; 36000,-9643.742602; 36000,-9835.115234;
        39600,-9835.115234; 39600,-10133.17939; 43200,-10133.17939; 43200,-10315.64445;
        46800,-10315.64445; 46800,-10372.27848; 50400,-10372.27848; 50400,-10397.02013;
        54000,-10397.02013; 54000,-10369.92204; 57600,-10369.92204; 57600,-10254.97156;
        61200,-10254.97156; 61200,0; 64800,0; 64800,0; 68400,0; 68400,0; 72000,0;
        72000,0; 75600,0; 75600,0; 79200,0; 79200,0; 82800,0; 82800,0; 86400,0])
    "EnergyPlus result: sensible heat flow "

  Modelica.Blocks.Math.Division shrEPlu
    "EnergyPlus result: SHR"

  Modelica.Blocks.Sources.TimeTable XEvaOutEPlu(final table=[0,0.010526598; 3600,0.010526598;
        3600,0.010526598; 7200,0.010526598; 7200,0.010526598; 10800,0.010526598;
        10800,0.010526598; 14400,0.010526598; 14400,0.010526598; 18000,0.010526598;
        18000,0.010526598; 21600,0.010526598; 21600,0.010631087; 25200,0.010631087;
        25200,0.009824324; 28800,0.009824324; 28800,0.009132468; 32400,0.009132468;
        32400,0.009227012; 36000,0.009227012; 36000,0.009333022; 39600,0.009333022;
        39600,0.009413613; 43200,0.009413613; 43200,0.009479582; 46800,0.009479582;
        46800,0.009650565; 50400,0.009650565; 50400,0.009869069; 54000,0.009869069;
        54000,0.010038477; 57600,0.010038477; 57600,0.010167307; 61200,0.010167307;
        61200,0.010396282; 64800,0.010396282; 64800,0.010537993; 68400,0.010537993;
        68400,0.010537961; 72000,0.010537961; 72000,0.010537961; 75600,0.010537961;
        75600,0.010537961; 79200,0.010537961; 79200,0.010537961; 82800,0.010537961;
        82800,0.010537961; 86400,0.010537961])
    "EnergyPlus result: outlet water mass fraction"

  Modelica.Blocks.Sources.TimeTable PEPlu(final table=[0,0; 3600,0; 3600,0; 7200,0; 7200,
        0; 10800,0; 10800,0; 14400,0; 14400,0; 18000,0; 18000,0; 21600,0; 21600,
        0; 25200,0; 25200,2947.546668; 28800,2947.546668; 28800,2966.686535; 32400,
        2966.686535; 32400,2999.864072; 36000,2999.864072; 36000,3087.801241; 39600,
        3087.801241; 39600,3195.082124; 43200,3195.082124; 43200,3188.668029; 46800,
        3188.668029; 46800,3156.065892; 50400,3156.065892; 50400,3155.199826; 54000,
        3155.199826; 54000,3136.04256; 57600,3136.04256; 57600,3087.770321; 61200,
        3087.770321; 61200,0; 64800,0; 64800,0; 68400,0; 68400,0; 72000,0; 72000,
        0; 75600,0; 75600,0; 79200,0; 79200,0; 82800,0; 82800,0; 86400,0])
    "EnergyPlus result: electric power"

  Modelica.Blocks.Sources.Pulse p(
    final nperiod=1,
    final offset=101325,
    final amplitude=1141,
    final width=100,
    final period=36000,
    final startTime=25200)
    "Pressure"

  Modelica.Blocks.Sources.RealExpression XEvaInMod(
    final y=XEvaIn.y/(1 + XEvaIn.y))
    "Modified XEvaIn"

  Modelica.Blocks.Sources.RealExpression XEvaOutEPluMod(
    final y=XEvaOutEPlu.y/(1 + XEvaOutEPlu.y))
    "Modified XEvaOut of energyPlus to comapre with the model results"

  Modelica.Blocks.Math.Add QCoo_flow
    "Total cooling heat flow rate"

equation
  connect(sou.ports[1], sinSpeDX.port_a)
  connect(sinSpeDX.port_b, sin.ports[1])
  connect(plr_onOff.y, onOff.u)
  connect(onOff.y, sinSpeDX.on)
  connect(mux.y, sou.X_in)
  connect(TCIn.y, TCIn_K.Celsius)
  connect(TCIn_K.Kelvin, sinSpeDX.TOut)
  connect(TEvaIn.y, TEvaIn_K.Celsius)
  connect(TEvaIn_K.Kelvin, sou.T_in)
  connect(TOut.y, TOutMea.u)
  connect(TOutMea.y, TOutDegC.Kelvin)
  connect(XEvaOut.y, XEvaOutMea.u)
  connect(XEvaInMoiAir.y, add.u2)
  connect(add.y, mux.u2[1])
  connect(Q_flowSenEPlu.y, shrEPlu.u1)
  connect(Q_flowEPlu.y, shrEPlu.u2)
  connect(sinSpeDX.P, PMea.u)
  connect(p.y, sou.p_in)
  connect(XEvaInMod.y, mux.u1[1])
  connect(XEvaInMod.y, add.u1)
  connect(sinSpeDX.QSen_flow, Q_flowSenMea.u)
  connect(QCoo_flow.y, Q_flowMea.u)
  connect(QCoo_flow.u1, sinSpeDX.QSen_flow)
  connect(sinSpeDX.QLat_flow, QCoo_flow.u2)
end SingleSpeed;


within Buildings.Fluid.DXSystems.Cooling.AirSource.Validation;
model SingleSpeedPLR
  "Validation model for single speed DX coil with PLR=1"
  extends Modelica.Icons.Example;

  package Medium = Buildings.Media.Air "Medium model";

  parameter Modelica.Units.SI.Power Q_flow_nominal=datCoi.sta[1].nomVal.Q_flow_nominal
    "Nominal power";

  parameter Modelica.Units.SI.MassFlowRate m_flow_nominal=datCoi.sta[1].nomVal.m_flow_nominal
    "Nominal mass flow rate";

  parameter Modelica.Units.SI.PressureDifference dp_nominal=1141
    "Pressure drop at m_flow_nominal";

  parameter Buildings.Fluid.DXSystems.Cooling.AirSource.Data.Generic.DXCoil
    datCoi(nSta=1,
    sta={
    Buildings.Fluid.DXSystems.Cooling.AirSource.Data.Generic.BaseClasses.Stage(
      spe=1800/60,
      nomVal=
      Buildings.Fluid.DXSystems.Cooling.AirSource.Data.Generic.BaseClasses.NominalValues(
        Q_flow_nominal=-25237.66,
        COP_nominal=3,
        SHR_nominal=0.775047,
        m_flow_nominal=1.72,
        tWet=1000,
        gamma=1.5),
      perCur=Buildings.Fluid.DXSystems.Cooling.AirSource.Examples.PerformanceCurves.Curve_II())})
    "Coil data"

  Buildings.Fluid.Sources.Boundary_pT sin(
    redeclare package Medium = Medium,
    final p(displayUnit="Pa") = 101325,
    final nPorts=1,
    final T=303.15)
    "Sink"

  Buildings.Fluid.Sources.Boundary_pT sou(
    redeclare package Medium = Medium,
    final p(displayUnit="Pa") = 101325 + dp_nominal,
    final use_T_in=true,
    final nPorts=1,
    final use_p_in=true,
    final use_X_in=true,
    final T=299.85)
    "Source"

  Buildings.Fluid.DXSystems.Cooling.AirSource.SingleSpeed
    sinSpeDX(
    redeclare package Medium = Medium,
    final dp_nominal=dp_nominal,
    final datCoi=datCoi,
    final T_start=datCoi.sta[1].nomVal.TEvaIn_nominal,
    final from_dp=true,
    final computeReevaporation=true,
    final energyDynamics=Modelica.Fluid.Types.Dynamics.FixedInitial)
    "Single speed DX coil"

  Modelica.Blocks.Routing.Multiplex2 mux
    "Converts in an array"

  Buildings.Utilities.IO.BCVTB.From_degC TCIn_K
    "Converts degC to K"

  Buildings.Utilities.IO.BCVTB.From_degC TEvaIn_K
    "Converts degC to K"

  Modelica.Blocks.Math.Mean TOutMea(
    final f=1/3600)
    "Average out value over one hour"

  Buildings.Utilities.IO.BCVTB.To_degC TOutDegC
    "Convert to degree Celsius"

  Modelica.Blocks.Sources.RealExpression TOut(
    final y=sinSpeDX.vol.T)
    "Measured outlet air temperature"

  Modelica.Blocks.Math.Mean XEvaOutMea(
    final f=1/3600)
    "Average out value over one hour"

  Modelica.Blocks.Sources.RealExpression XEvaOut(
    final y=sum(sinSpeDX.vol.Xi))
    "Measured outlet air humidity ratio (total air)"

  Modelica.Blocks.Math.Mean Q_flowMea(
    final f=1/3600)
    "Mean of cooling rate"

  Modelica.Blocks.Math.Mean Q_flowSenMea(
    final f=1/3600)
    "Mean of sensible cooling rate"

  Modelica.Blocks.Math.Mean PMea(
    final f=1/3600)
    "Mean of power"

  Modelica.Blocks.Math.Add add(
    final k1=-1)
    "Convert humidity ratio (dry air) to humidity ratio (total air)"

  Modelica.Blocks.Sources.Constant XEvaInMoiAir(
    final k=1.0)
    "Moist air fraction = 1"

  Modelica.Blocks.Math.Division shrEPlu
    "EnergyPlus result: SHR"

  Modelica.Blocks.Sources.Pulse p(
    final nperiod=1,
    final offset=101325,
    final width=100,
    final period=36000,
    final startTime=25200,
    final amplitude=1086)
    "Pressure"

  Modelica.Blocks.Sources.RealExpression XEvaInMod(
    final y=XEvaIn.y/(1 + XEvaIn.y))
    "Modified XEvaIn"

  Modelica.Blocks.Sources.RealExpression XEvaOutEPluMod(
    final y=XEvaOutEPlu.y/(1 + XEvaOutEPlu.y))
    "Modified XEvaOut of energyPlus to comapre with the model results"

  Modelica.Blocks.Sources.BooleanTable onOff(startValue=true,
    table={
      0,
      25200,
      26223.8694421458,
      28800,
      30457.5364262964,
      32400,
      34157.5093643325,
      36000,
      37915.2504828207,
      39600,
      41687.2390146012,
      43200,
      45363.3505825759,
      46800,
      49129.0477925565,
      50400,
      52764.5288886473,
      54000,
      56361.5689116996,
      57600,
      59868.3223307805})
    "EnergyPlus PLR converted into on-off signal for this model"

  Modelica.Blocks.Sources.TimeTable TCIn(final table=[0,21.1; 3600,21.1; 3600,
        20.80833333; 7200,20.80833333; 7200,20.89166667; 10800,20.89166667;
        10800,21.1; 14400,21.1; 14400,20.80833333; 18000,20.80833333; 18000,
        20.6; 21600,20.6; 21600,20.89166667; 25200,20.89166667; 25200,21.45;
        28800,21.45; 28800,22.63333333; 32400,22.63333333; 32400,23.3; 36000,
        23.3; 36000,25.575; 39600,25.575; 39600,28.19166667; 43200,28.19166667;
        43200,27.90833333; 46800,27.90833333; 46800,26.90833333; 50400,
        26.90833333; 50400,26.7; 54000,26.7; 54000,26.05833333; 57600,
        26.05833333; 57600,24.60833333; 61200,24.60833333; 61200,23.55; 64800,
        23.55; 64800,23.3; 68400,23.3; 68400,23.00833333; 72000,23.00833333;
        72000,22.8; 75600,22.8; 75600,22.15833333; 79200,22.15833333; 79200,
        21.35; 82800,21.35; 82800,21.1; 86400,21.1])
    "Condenser inlet temperature"

  Modelica.Blocks.Sources.TimeTable TEvaIn(
    final table=[
      0,29.34948133;
      3600,29.34948133;
      3600,29.01814876;
      7200,29.01814876;
      7200,28.76345897;
      10800,28.76345897;
      10800,28.53396626;
      14400,28.53396626;
      14400,28.29506697;
      18000,28.29506697;
      18000,28.08827214;
      21600,28.08827214;
      21600,28.04639166;
      25200,28.04639166;
      25200,24.08651629;
      28800,24.08651629;
      28800,24.09243025;
      32400,24.09243025;
      32400,24.20516777;
      36000,24.20516777;
      36000,24.37566383;
      39600,24.37566383;
      39600,24.56160617;
      43200,24.56160617;
      43200,24.52393669;
      46800,24.52393669;
      46800,24.39077471;
      50400,24.39077471;
      50400,24.33155125;
      54000,24.33155125;
      54000,24.27362306;
      57600,24.27362306;
      57600,24.16566121;
      61200,24.16566121;
      61200,35.62393274;
      64800,35.62393274;
      64800,32.89683519;
      68400,32.89683519;
      68400,31.14979083;
      72000,31.14979083;
      72000,30.65928154;
      75600,30.65928154;
      75600,30.28912721;
      79200,30.28912721;
      79200,29.91867206;
      82800,29.91867206;
      82800,29.61490681;
      86400,29.61490681])
    "Coil inlet temperature"

  Modelica.Blocks.Sources.TimeTable XEvaIn(
    final table=[
      0,0.00946;
      3600,0.00946;
      3600,0.00946;
      7200,0.00946;
      7200,0.00946;
      10800,0.00946;
      10800,0.00946;
      14400,0.00946;
      14400,0.00946;
      18000,0.00946;
      18000,0.00946;
      21600,0.00946;
      21600,0.00955;
      25200,0.00955;
      25200,0.0103;
      28800,0.0103;
      28800,0.0109;
      32400,0.0109;
      32400,0.0108;
      36000,0.0108;
      36000,0.0105;
      39600,0.0105;
      39600,0.01;
      43200,0.01;
      43200,0.00969;
      46800,0.00969;
      46800,0.00947;
      50400,0.00947;
      50400,0.00926;
      54000,0.00926;
      54000,0.00923;
      57600,0.00923;
      57600,0.00937;
      61200,0.00937;
      61200,0.00936;
      64800,0.00936;
      64800,0.00946;
      68400,0.00946;
      68400,0.00946;
      72000,0.00946;
      72000,0.00946;
      75600,0.00946;
      75600,0.00946;
      79200,0.00946;
      79200,0.00946;
      82800,0.00946;
      82800,0.00946;
      86400,0.00946])
    "Water fraction of moist air"

  Modelica.Blocks.Sources.TimeTable TOutEPlu_ori(
    final table=[0,29.34948133; 3600,29.34948133;
        3600,29.01814876; 7200,29.01814876; 7200,28.76345897; 10800,28.76345897;
        10800,28.53396626; 14400,28.53396626; 14400,28.29506697; 18000,28.29506697;
        18000,28.08827214; 21600,28.08827214; 21600,28.04639166; 25200,28.04639166;
        25200,19.79102221; 28800,19.79102221; 28800,17.58304653; 32400,17.58304653;
        32400,17.35471965; 36000,17.35471965; 36000,16.95320861; 39600,16.95320861;
        39600,16.4388043; 43200,16.4388043; 43200,16.03301122; 46800,16.03301122;
        46800,15.41071946; 50400,15.41071946; 50400,15.15437515; 54000,15.15437515;
        54000,15.09543443; 57600,15.09543443; 57600,15.3159498; 61200,15.3159498;
        61200,35.62393274; 64800,35.62393274; 64800,32.89683519; 68400,32.89683519;
        68400,31.14979083; 72000,31.14979083; 72000,30.65928154; 75600,30.65928154;
        75600,30.28912721; 79200,30.28912721; 79200,29.91867206; 82800,29.91867206;
        82800,29.61490681; 86400,29.61490681])
    "EnergyPlus result: outlet temperature"

  Modelica.Blocks.Sources.TimeTable PEPlu_ori(
    final table=[0,0; 3600,0; 3600,0; 7200,
        0; 7200,0; 10800,0; 10800,0; 14400,0; 14400,0; 18000,0; 18000,0; 21600,
        0; 21600,0; 25200,0; 25200,2221.47212; 28800,2221.47212; 28800,
        3595.947729; 32400,3595.947729; 32400,3819.11052; 36000,3819.11052;
        36000,4235.566014; 39600,4235.566014; 39600,4714.070326; 43200,
        4714.070326; 43200,4835.805362; 46800,4835.805362; 46800,5089.357992;
        50400,5089.357992; 50400,5132.912713; 54000,5132.912713; 54000,
        5082.720823; 57600,5082.720823; 57600,4820.015593; 61200,4820.015593;
        61200,0; 64800,0; 64800,0; 68400,0; 68400,0; 72000,0; 72000,0; 75600,0;
        75600,0; 79200,0; 79200,0; 82800,0; 82800,0; 86400,0])
    "EnergyPlus result: electric power"

  Modelica.Blocks.Sources.TimeTable XEvaOutEPlu_ori(
    final table=[0,0.009460927; 3600,0.009460927;
        3600,0.009460927; 7200,0.009460927; 7200,0.009460927; 10800,0.009460927;
        10800,0.009460927; 14400,0.009460927; 14400,0.009460927; 18000,0.009460927;
        18000,0.009460927; 21600,0.009460927; 21600,0.009553929; 25200,0.009553929;
        25200,0.010316263; 28800,0.010316263; 28800,0.010677981; 32400,0.010677981;
        32400,0.010521771; 36000,0.010521771; 36000,0.010225222; 39600,0.010225222;
        39600,0.009821415; 43200,0.009821415; 43200,0.009523837; 46800,0.009523837;
        46800,0.009220467; 50400,0.009220467; 50400,0.009042737; 54000,0.009042737;
        54000,0.009012184; 57600,0.009012184; 57600,0.009145645; 61200,0.009145645;
        61200,0.009361285; 64800,0.009361285; 64800,0.009459829; 68400,0.009459829;
        68400,0.009459801; 72000,0.009459801; 72000,0.009459801; 75600,0.009459801;
        75600,0.009459801; 79200,0.009459801; 79200,0.009459801; 82800,0.009459801;
        82800,0.009459801; 86400,0.009459801])
    "EnergyPlus result: outlet water mass fraction"

  Modelica.Blocks.Sources.TimeTable Q_flowSenEPlu_ori(
    final table=[0,0; 3600,0; 3600,0;
        7200,0; 7200,0; 10800,0; 10800,0; 14400,0; 14400,0; 18000,0; 18000,0; 21600,
        0; 21600,0; 25200,0; 25200,7378.442557; 28800,7378.442557; 28800,11190.03413;
        32400,11190.03413; 32400,11772.99874; 36000,11772.99874; 36000,12749.11676;
        39600,12749.11676; 39600,13941.844; 43200,13941.844; 43200,14565.84942;
        46800,14565.84942; 46800,15396.44898; 50400,15396.44898; 50400,15729.34223;
        54000,15729.34223; 54000,15730.20543; 57600,15730.20543; 57600,15170.91533;
        61200,15170.91533; 61200,0; 64800,0; 64800,0; 68400,0; 68400,0; 72000,0;
        72000,0; 75600,0; 75600,0; 79200,0; 79200,0; 82800,0; 82800,0; 86400,0])
    "EnergyPlus result: sensible heat flow "

  Modelica.Blocks.Sources.TimeTable Q_flowEPlu_ori(
    final table=[0,0; 3600,0; 3600,
        0; 7200,0; 7200,0; 10800,0; 10800,0; 14400,0; 14400,
        0; 18000,0; 18000,0; 21600,0; 21600,0; 25200,-1e-9;
        25200,-7464.76568; 28800,-7464.76568; 28800,-12134.51902; 32400,-12134.51902;
        32400,-12829.73888; 36000,-12829.73888; 36000,-13827.82263; 39600,-13827.82263;
        39600,-14802.70071; 43200,-14802.70071; 43200,-15271.18519; 46800,-15271.18519;
        46800,-16441.6341; 50400,-16441.6341; 50400,-16638.80981; 54000,-16638.80981;
        54000,-16649.7802; 57600,-16649.7802; 57600,-16109.92984; 61200,-16109.92984;
        61200,0; 64800,0; 64800,0; 68400,0; 68400,0; 72000,0;
        72000,0; 75600,0; 75600,0; 79200,0; 79200,0; 82800,0;
        82800,0; 86400,0])
    "EnergyPlus result: heat flow"

  Modelica.Blocks.Math.Add QCoo_flow
    "Total cooling heat flow rate"

  UnitDelay PEPlu(
    final samplePeriod=3600)
    "Delay input signal by one hour to match timestep with Modelica simulation"

  UnitDelay Q_flowSenEPlu(
    final samplePeriod=3600)
    "Delay input signal by one hour to match timestep with Modelica simulation"

  UnitDelay Q_flowEPlu(
    final samplePeriod=3600)
    "Delay input signal by one hour to match timestep with Modelica simulation"

  UnitDelay TOutEPlu(
    final samplePeriod=3600,
    final y_start=29.34948133)
    "Delay input signal by one hour to match timestep with Modelica simulation"

  UnitDelay XEvaOutEPlu(
    final samplePeriod=3600)
    "Delay input signal by one hour to match timestep with Modelica simulation"

  Modelica.Blocks.Math.MultiSum multiSum(
    final nu=2)
    "Add small value to measured value to avoid division by zero"

  Modelica.Blocks.Sources.Constant small(
    final k=-1e-9)
    "Small value to avoid division by zero"

  // The UnitDelay is reimplemented to avoid in Dymola 2016 the translation warning
  //   The initial conditions for variables of type Boolean are not fully specified.
  //   Dymola has selected default initial conditions.
  //   Assuming fixed default start value for the discrete non-states:
  //     PEPlu.firstTrigger(start = false)
  //     ...
protected
  block UnitDelay
    extends Modelica.Blocks.Discrete.UnitDelay(
      firstTrigger(start=false, fixed=true));
  end UnitDelay;

equation
  connect(sou.ports[1], sinSpeDX.port_a)
  connect(sinSpeDX.port_b, sin.ports[1])
  connect(mux.y, sou.X_in)
  connect(TCIn_K.Kelvin, sinSpeDX.TOut)
  connect(TEvaIn_K.Kelvin, sou.T_in)
  connect(TOut.y, TOutMea.u)
  connect(TOutMea.y, TOutDegC.Kelvin)
  connect(XEvaOut.y, XEvaOutMea.u)
  connect(XEvaInMoiAir.y, add.u2)
  connect(add.y, mux.u2[1])
  connect(sinSpeDX.P, PMea.u)
  connect(p.y, sou.p_in)
  connect(XEvaInMod.y, mux.u1[1])
  connect(XEvaInMod.y, add.u1)
  connect(onOff.y, sinSpeDX.on)
  connect(TCIn.y, TCIn_K.Celsius)
  connect(TEvaIn.y, TEvaIn_K.Celsius)
  connect(sinSpeDX.QSen_flow, Q_flowSenMea.u)
  connect(QCoo_flow.y, Q_flowMea.u)
  connect(QCoo_flow.u1, sinSpeDX.QSen_flow)
  connect(sinSpeDX.QLat_flow, QCoo_flow.u2)
  connect(PEPlu_ori.y, PEPlu.u)
  connect(Q_flowSenEPlu_ori.y, Q_flowSenEPlu.u)
  connect(Q_flowSenEPlu.y, shrEPlu.u1)
  connect(Q_flowEPlu_ori.y, Q_flowEPlu.u)
  connect(TOutEPlu_ori.y, TOutEPlu.u)
  connect(XEvaOutEPlu_ori.y, XEvaOutEPlu.u)
  connect(multiSum.y, shrEPlu.u2)
  connect(small.y, multiSum.u[1])
  connect(Q_flowEPlu.y, multiSum.u[2])
end SingleSpeedPLR;


Calculates air properties at apparatus dew point. This blocks outputs the state of the moist air at the dew point of the coil.
The bypass factor of the coil and the resulting enthalpy difference is
computed by its base class

Buildings.Fluid.DXSystems.Cooling.BaseClasses.PartialSurfaceCondition.

within Buildings.Fluid.DXSystems.Cooling.BaseClasses;
block ApparatusDewPoint "Calculates air properties at apparatus dew point"
  extends
    Buildings.Fluid.DXSystems.Cooling.BaseClasses.PartialSurfaceCondition;
  Modelica.Blocks.Interfaces.RealOutput hADP(
    nominal=40000,
    quantity="SpecificEnergy",
    unit="J/kg") "Specific enthalpy of air at apparatus dew point"
  Modelica.Blocks.Interfaces.RealOutput XADP(
    min=0,
    max=1.0) "Humidity mass fraction of air at  apparatus dew point"
  Modelica.Blocks.Interfaces.RealOutput TADP(
    quantity="ThermodynamicTemperature",
    unit="K",
    displayUnit="degC",
    start=283.15,
    min=233.15,
    max=373.15) "Dry bulb temperature of air at apparatus dew point"
protected
  parameter Modelica.Units.SI.Temperature TSatMin=273.15 + 3
    "Minimum apparatus saturation temperature";
  parameter Modelica.Units.SI.MassFraction XSatMin=0.004667
    "Mass fraction at saturation of coil inlet conditions";
  parameter Modelica.Units.SI.SpecificEnthalpy hMin(fixed=false)
    "Minimum enthalpy of apparatus dew point";

initial equation
/*  XSatMin = Medium.Xsaturation(
        Medium.setState_pTX(p=p,
                            T=273.15+3,
                            X=cat(1,{XSatMin},{1-sum({XSatMin})})));
*/
  hMin = Medium.specificEnthalpy_pTX(
           p =  Medium.p_default,
           T =  TSatMin,
           X =  cat(1,{XSatMin},{1-sum({XSatMin})}));
equation
  hADP = Buildings.Utilities.Math.Functions.smoothMin(
    x1 = Buildings.Utilities.Math.Functions.smoothMax(
      x1=hEvaIn - delta_h,
      x2=hMin,
      deltaX=10),
    x2 = hEvaIn+100,
    deltaX=10);
  XADP = Buildings.Utilities.Psychrometrics.Functions.X_pW(p_w=Medium.saturationPressure(TADP), p=p);
  TADP= Medium.temperature(Medium.setState_phX(p=p, h=hADP, X=cat(1,{XADP},{1-sum({XADP})})));
end ApparatusDewPoint;


Calculates air properties at dry coil surface. This blocks outputs the state of the moist air at of the coil, assuming no condensation occurs.
The bypass factor of the coil and the resulting enthalpy difference is
computed by its base class

Buildings.Fluid.DXSystems.Cooling.BaseClasses.PartialSurfaceCondition.

within Buildings.Fluid.DXSystems.Cooling.BaseClasses;
block ApparatusDryPoint "Calculates air properties at dry coil surface"
  extends
    Buildings.Fluid.DXSystems.Cooling.BaseClasses.PartialSurfaceCondition;
  Modelica.Blocks.Interfaces.RealOutput TDry(
    quantity="ThermodynamicTemperature",
    unit="K",
    displayUnit="degC",
    min=253.15,
    max=373.15) "Dry bulb temperature of air at dry coil condition"
  output Modelica.Units.SI.SpecificEnthalpy hDry
    "Enthalpy of air at coil surface";
protected
  Modelica.Units.SI.MassFraction XEvaInVec[Medium.nX]
    "Mass fraction of air inlet condition";
  Modelica.Units.SI.Temperature TADP(start=283.15)
    "Apparatus dew point temperature";
  Modelica.Units.SI.SpecificEnthalpy hMin
    "Minimum enthalpy of apparatus dew point";
equation
  XEvaInVec =cat(1,{XEvaIn},{1-sum({XEvaIn})});

  XEvaIn = Buildings.Utilities.Psychrometrics.Functions.X_pW(
     p_w=Buildings.Utilities.Psychrometrics.Functions.saturationPressureLiquid(TADP), p=p);

  hMin = Medium.specificEnthalpy(Medium.setState_pTX(p=p, T=TADP, X=XEvaInVec));

  hDry = Buildings.Utilities.Math.Functions.smoothMin(
    x1 = Buildings.Utilities.Math.Functions.smoothMax(
      x1=hEvaIn - delta_h,
      x2=hMin,
      deltaX=10),
    x2 = hEvaIn+100,
    deltaX=10);

  TDry= Medium.temperature(Medium.setState_phX(p=p, h=hDry, X=XEvaInVec))
    "XEvaIn=XDry assumption for dry coil";
end ApparatusDryPoint;