within Buildings.DHC.Loads.BaseClasses;
model FlowDistribution
  "Model of a building hydraulic distribution system"
  extends Buildings.Fluid.Interfaces.PartialTwoPortInterface(
    redeclare replaceable package Medium=Buildings.Media.Water,
    allowFlowReversal=false);
  import Type_dis=Buildings.DHC.Loads.BaseClasses.Types.DistributionType
    "Types of distribution system";
  import Type_ctr=Buildings.DHC.Loads.BaseClasses.Types.PumpControlType
    "Types of distribution pump control";
  parameter Integer nPorts_a1=0
    "Number of terminal units return ports"
  parameter Integer nPorts_b1=0
    "Number of terminal units supply ports"
  final parameter Integer nUni=nPorts_a1
    "Number of served units"
  parameter Boolean have_pum=false
    "Set to true if the system has a pump"
  parameter Boolean have_val=false
    "Set to true if the system has a mixing valve"
  parameter Type_dis typDis=Type_dis.HeatingWater
    "Type of distribution system"
  parameter Type_ctr typCtr=Type_ctr.ConstantHead
    "Type of distribution pump control"
  parameter Real spePum_nominal(
    final unit="1",
    final min=0,
    final max=1)=1
    "Pump speed at nominal conditions"
  parameter Modelica.Units.SI.PressureDifference dp_nominal(final min=0,
      displayUnit="Pa") "Pressure drop at nominal conditions"
  final parameter Modelica.Units.SI.PressureDifference dpVal_nominal(
    final min=0,
    displayUnit="Pa") = if have_val then 0.1*dp_nominal else 0
    "Mixing valve pressure drop at nominal conditions"
  parameter Modelica.Units.SI.PressureDifference dpDis_nominal[:](
    each final min=0,
    each displayUnit="Pa") = if nUni == 1 then {1/2*(dp_nominal - dpVal_nominal
     - dpMin)} else 1/2 .* cat(
    1,
    {(dp_nominal - dpVal_nominal - dpMin)*0.2},
    fill((dp_nominal - dpVal_nominal - dpMin)*0.8/(nUni - 1), nUni - 1)) "Pressure drop between each connected unit at nominal conditions (supply line):
    use zero for each connection downstream the differential pressure sensor"
  parameter Modelica.Units.SI.PressureDifference dpMin(
    final min=0,
    displayUnit="Pa") = dp_nominal/2
    "Pressure difference set point for ConstantDp or at zero flow for LinearHead"
  parameter Modelica.Units.SI.MassFlowRate mUni_flow_nominal[:](each final min=
        0) = fill(m_flow_nominal/nUni, nUni)
    "Mass flow rate of each connected unit at nominal conditions"
  parameter Modelica.Fluid.Types.Dynamics energyDynamics=Modelica.Fluid.Types.Dynamics.FixedInitial
    "Type of energy balance (except for the pump always modeled in steady state)"
  final parameter Modelica.Fluid.Types.Dynamics massDynamics=energyDynamics
    "Type of mass balance (except for the pump always modeled in steady state)"
  parameter Modelica.Units.SI.Time tau=120
    "Time constant of fluid temperature variation at nominal flow rate"
  // IO CONNECTORS
  Modelica.Fluid.Interfaces.FluidPorts_a ports_a1[nPorts_a1](
    redeclare each final package Medium=Medium,
    each m_flow(
      min=
        if allowFlowReversal then
          -Modelica.Constants.inf
        else
          0),
    each h_outflow(
      start=Medium.h_default,
      nominal=Medium.h_default))
    "Terminal units return ports"
  Modelica.Fluid.Interfaces.FluidPorts_b ports_b1[nPorts_b1](
    redeclare each final package Medium=Medium,
    each m_flow(
      max=
        if allowFlowReversal then
          +Modelica.Constants.inf
        else
          0),
    each h_outflow(
      start=Medium.h_default,
      nominal=Medium.h_default))
    "Terminal units supply ports"
  Modelica.Blocks.Interfaces.RealInput mReq_flow[nUni](
    each final quantity="MassFlowRate")
    "Heating or chilled water flow rate required to meet the load"
  Modelica.Blocks.Interfaces.IntegerInput modChaOve if have_val and typDis == Type_dis.ChangeOver
    "Operating mode in change-over (1 for heating, 2 for cooling)"
  Modelica.Blocks.Interfaces.RealInput TSupSet(
    final quantity="ThermodynamicTemperature",
    final unit="K",
    displayUnit="degC") if have_val
    "Supply temperature set point"
  Modelica.Blocks.Interfaces.RealOutput mReqTot_flow(
    final quantity="MassFlowRate",
    final unit="kg/s")
    "Total heating or chilled water flow rate required to meet the loads"
  Modelica.Blocks.Interfaces.RealOutput QActTot_flow(
    final quantity="HeatFlowRate",
    final unit="W")
    "Total heat flow rate transferred to the loads (>=0 for heating)"
  Modelica.Blocks.Interfaces.RealOutput PPum(
    final quantity="Power",
    final unit="W") if have_pum
    "Power drawn by pump motor"
  // COMPONENTS
  Buildings.Controls.OBC.CDL.Reals.MultiSum sumMasFloReq(
    final k=fill(
      1,
      nUni),
    final nin=nUni)
    "Total required mass flow rate"
  Buildings.Fluid.Sources.MassFlowSource_T sou_m_flow[nUni](
    redeclare each final package Medium=Medium,
    each final use_m_flow_in=true,
    each final use_T_in=true,
    each final nPorts=1)
    "Source for terminal units supplied flow rate"
  Buildings.Fluid.Sources.Boundary_pT sin(
    redeclare final package Medium=Medium,
    final nPorts=nUni)
    "Sink for terminal units return flow rate"
  Buildings.Controls.OBC.CDL.Reals.MultiSum Q_flowSum(
    final nin=nUni)
    "Total heat flow rate"
  Modelica.Blocks.Sources.RealExpression mAct_flow[nUni](
    final y(
      each final unit="kg/s")=
      if have_pum then
        mReq_flow
      else
        mReq_flow .* senMasFlo.m_flow/Buildings.Utilities.Math.Functions.smoothLimit(
          x=mReqTot_flow,
          l=m_flow_small,
          u=senMasFlo.m_flow,
          deltaX=m_flow_small))
    "Actual supplied mass flow rate"
  Modelica.Blocks.Sources.RealExpression QAct_flow[nUni](
    final y(
      each final unit="W")=mAct_flow.y .*(ports_b1.h_outflow-inStream(
      ports_a1.h_outflow)))
    "Actual heat flow rate transferred to each load"
  Buildings.Fluid.Actuators.Valves.ThreeWayEqualPercentageLinear val(
    redeclare final package Medium = Medium,
    final portFlowDirection_1=if allowFlowReversal then Modelica.Fluid.Types.PortFlowDirection.Bidirectional
         else Modelica.Fluid.Types.PortFlowDirection.Entering,
    final portFlowDirection_2=if allowFlowReversal then Modelica.Fluid.Types.PortFlowDirection.Bidirectional
         else Modelica.Fluid.Types.PortFlowDirection.Leaving,
    final portFlowDirection_3=if allowFlowReversal then Modelica.Fluid.Types.PortFlowDirection.Bidirectional
         else Modelica.Fluid.Types.PortFlowDirection.Entering,
    final dpValve_nominal=dpVal_nominal,
    final use_strokeTime=false,
    final m_flow_nominal=m_flow_nominal,
    final linearized={true,true},
    energyDynamics=Modelica.Fluid.Types.Dynamics.FixedInitial) if have_val
    "Mixing valve"
  Buildings.Fluid.Movers.BaseClasses.IdealSource pipPre(
    redeclare final package Medium=Medium,
    final dp_start=dp_nominal-dpVal_nominal,
    final m_flow_start=m_flow_nominal,
    final show_T=false,
    final show_V_flow=false,
    final control_m_flow=typCtr == Type_ctr.ConstantSpeed,
    final control_dp=typCtr <> Type_ctr.ConstantSpeed,
    final allowFlowReversal=allowFlowReversal,
    final m_flow_small=m_flow_small)
    "Fictitious pipe used to prescribe pump head or flow rate"
  Buildings.Fluid.HeatExchangers.HeaterCooler_u heaCoo(
    redeclare final package Medium=Medium,
    final dp_nominal=0,
    final m_flow_nominal=m_flow_nominal,
    final Q_flow_nominal=-1,
    final allowFlowReversal=allowFlowReversal,
    final energyDynamics=energyDynamics,
    final tau=tau)
    "Heat transfer from the terminal units to the distribution system"
  Buildings.Fluid.FixedResistances.Junction spl(
    redeclare final package Medium=Medium,
    final portFlowDirection_1=
      if allowFlowReversal then
        Modelica.Fluid.Types.PortFlowDirection.Bidirectional
      else
        Modelica.Fluid.Types.PortFlowDirection.Entering,
    final portFlowDirection_2=
      if allowFlowReversal then
        Modelica.Fluid.Types.PortFlowDirection.Bidirectional
      else
        Modelica.Fluid.Types.PortFlowDirection.Leaving,
    final portFlowDirection_3=
      if allowFlowReversal then
        Modelica.Fluid.Types.PortFlowDirection.Bidirectional
      else
        Modelica.Fluid.Types.PortFlowDirection.Leaving,
    final m_flow_nominal=m_flow_nominal*{1,1,1},
    final dp_nominal=0*{1,1,1},
    energyDynamics=Modelica.Fluid.Types.Dynamics.FixedInitial) if have_val
    "Flow splitter"
  Buildings.Fluid.Sensors.MassFlowRate senMasFlo(
    redeclare final package Medium=Medium,
    final allowFlowReversal=allowFlowReversal)
    "Supply mass flow rate sensor"
  Buildings.Controls.OBC.CDL.Routing.RealScalarReplicator reaRep(
    final nout=nUni)
    "Repeat input to output an array"
  Buildings.DHC.Loads.BaseClasses.Controls.MixingValveControl conVal(
    final typDis=typDis) if have_val
    "Mixing valve controller"
  Modelica.Blocks.Sources.RealExpression dpNetVal(
    final y(
      final unit="Pa")=dpPum-dpVal_nominal)
    "Pressure drop over the distribution network (excluding mixing valve)"
  Modelica.Blocks.Sources.RealExpression masFloPum(
    final y(
      final unit="kg/s")=mPum_flow)
    "Pump mass flow rate value"
  Modelica.Blocks.Sources.RealExpression spePum(
    final y(
      final unit="1")=spePum_nominal)
    "Pump speed (fractional)"
  Buildings.Fluid.Movers.Preconfigured.FlowControlled_m_flow pumFlo(
    redeclare final package Medium=Medium,
    final m_flow_nominal=m_flow_nominal,
    final dp_nominal=dp_nominal,
    final allowFlowReversal=allowFlowReversal,
    addPowerToMedium=false,
    use_riseTime=false,
    energyDynamics=Modelica.Fluid.Types.Dynamics.SteadyState) if have_pum and typCtr <> Type_ctr.ConstantSpeed
    "Distribution pump with prescribed mass flow rate"
  Buildings.Fluid.Movers.Preconfigured.SpeedControlled_y pumSpe(
    redeclare final package Medium = Medium,
    final m_flow_nominal=m_flow_nominal,
    final dp_nominal=dp_nominal,
    final allowFlowReversal=allowFlowReversal,
    addPowerToMedium=false,
    use_riseTime=false,
    energyDynamics=Modelica.Fluid.Types.Dynamics.SteadyState)
    if have_pum and typCtr == Type_ctr.ConstantSpeed
    "Distribution pump with prescribed speed (fractional)"
  Fluid.Sensors.TemperatureTwoPort senTSup(
    redeclare final package Medium=Medium,
    final allowFlowReversal=allowFlowReversal,
    final m_flow_nominal=m_flow_nominal,
    initType=Modelica.Blocks.Types.Init.InitialState)
    "Supply temperature"
protected
  final parameter Modelica.Units.SI.MassFlowRate mDis_flow_nominal[nUni]={sum(
      mUni_flow_nominal[i:nUni]) for i in 1:nUni}
    "Distribution flow rate between each connected unit at nominal conditions";
  final parameter Real kDis[nUni]={
    if dpDis_nominal[i] > Modelica.Constants.eps then
      mDis_flow_nominal[i]/sqrt(dpDis_nominal[i])
    else
      Modelica.Constants.inf for i in 1:nUni}
    "Flow coefficient between each connected unit at nominal conditions";
  Modelica.Units.SI.MassFlowRate mDis_flow[nUni]={sum(mReq_flow[i:nUni]) for i in
          1:nUni} "Distribution flow rate between each connected unit";
  Modelica.Units.SI.PressureDifference dpDis[nUni]=(mDis_flow ./ kDis) .^ 2
    "Pressure drop between each connected unit (supply line)";
  Modelica.Units.SI.PressureDifference dpPum(displayUnit="Pa") = if typCtr ==
    Type_ctr.LinearHead then dpMin + mPum_flow/m_flow_nominal*dp_nominal
     elseif typCtr == Type_ctr.ConstantDp then 2*sum(dpDis) + dpMin +
    dpVal_nominal else dp_nominal "Pump head";
  Modelica.Units.SI.MassFlowRate mPum_flow=if typCtr == Type_ctr.ConstantFlow
       then m_flow_nominal else sum(mReq_flow) "Pump mass flow rate";
  parameter Medium.ThermodynamicState sta_default=Medium.setState_pTX(
    T=Medium.T_default,
    p=Medium.p_default,
    X=Medium.X_default);
  parameter Modelica.Units.SI.Density rho_default=Medium.density(sta_default)
    "Density, used to compute fluid volume";
initial equation
  assert(
    nPorts_a1 == nPorts_b1,
    "In "+getInstanceName()+": The numbers of terminal units return ports ("+String(
      nPorts_a1)+") and supply ports ("+String(
      nPorts_b1)+") must be equal.");
  assert(
    if have_val then
      have_pum
    else
      true,
    "In "+getInstanceName()+": The configuration where have_val is true and have_pum is false is not allowed.");
equation
  // Connect statements involving conditionally removed components are
  // removed at translation time by Modelica specification.
  // Only obsolete statements corresponding to the default model structure need
  // to be programmatically removed.
  if not have_val then
    connect(heaCoo.port_b,port_b)
    connect(port_a,pumFlo.port_a)
    connect(port_a,pumSpe.port_a)
  end if;
  if not have_pum then
    connect(port_a,senTSup.port_a)
  end if;
  connect(sumMasFloReq.y,mReqTot_flow)
  connect(mReq_flow,sumMasFloReq.u)
  connect(mAct_flow.y,sou_m_flow.m_flow_in)
  connect(ports_a1,sin.ports)
  connect(sou_m_flow.ports[1],ports_b1)
  connect(senMasFlo.port_b,heaCoo.port_a)
  connect(Q_flowSum.y,QActTot_flow)
  connect(QAct_flow.y,Q_flowSum.u)
  connect(Q_flowSum.y,heaCoo.u)
  connect(reaRep.y,sou_m_flow.T_in)
  connect(port_a,val.port_1)
  connect(heaCoo.port_b,spl.port_1)
  connect(spl.port_2,port_b)
  connect(spl.port_3,val.port_3)
  connect(TSupSet,conVal.TSupSet)
  connect(conVal.yVal,val.y)
  connect(modChaOve,conVal.modChaOve)
  connect(val.port_2,pumFlo.port_a)
  connect(val.port_2,pumSpe.port_a)
  connect(pumFlo.P,PPum)
  connect(pumSpe.P,PPum)
  connect(dpNetVal.y,pipPre.dp_in)
  connect(masFloPum.y,pipPre.m_flow_in)
  connect(masFloPum.y,pumFlo.m_flow_in)
  connect(spePum.y,pumSpe.y)
  connect(pipPre.port_a,senTSup.port_b)
  connect(pumSpe.port_b,senTSup.port_a)
  connect(pumFlo.port_b,senTSup.port_a)
  connect(senTSup.T,reaRep.u)
  connect(senTSup.T,conVal.TSupMes)
  connect(pipPre.port_b,senMasFlo.port_a)
end FlowDistribution;


Function that reads the peak load from the load profile. This function implements
Modelica.Utilities.Streams.readLine
but declares it as a pure function, which is fine assuming a user is
not deliberately changing the file after the model is translated.

within Buildings.DHC.Loads.BaseClasses;
pure function getPeakLoad
  "Function that reads the peak load from the load profile"
  extends Modelica.Icons.Function;

  input String string
    "String that is written before the '=' sign";
  input String filNam
    "Name of data file with heating and cooling load"
  output Real number
    "Number that is read from the file";
protected
  String lin
    "Line that is used in parser";
  Integer iLin
    "Line number";
  Integer index=0
    "Index of string 'string'";
  Integer staInd
    "Start index used when parsing a real number";
  Integer nexInd
    "Next index used when parsing a real number";
  Boolean found
    "Flag, true if 'string' has been found";
  Boolean EOF
    "Flag, true if EOF has been reached";
  String del
    "Found delimiter";

  pure function pureReadLine "Read a line of text from a file and return it in a string"
    extends Modelica.Icons.Function;
    input String fileName "Name of the file that shall be read";
    input Integer lineNumber(min=1) "Number of line to read";
    output String string "Line of text";
    output Boolean endOfFile
      "If true, end-of-file was reached when trying to read line";
    external"C" string = ModelicaInternal_readLine(
        fileName,
        lineNumber,
        endOfFile)

  end pureReadLine;
algorithm
  // Get line that contains 'string'
  iLin := 0;
  EOF := false;
  while
       (not EOF) and
                    (index == 0) loop
    iLin := iLin+1;
    (lin,EOF) := pureReadLine(
      fileName=filNam,
      lineNumber=iLin);
    index := Modelica.Utilities.Strings.find(
      string=lin,
      searchString=string,
      startIndex=1,
      caseSensitive=true);
  end while;
  assert(
    not EOF,
    "Error: Did not find '"+string+"' when scanning '"+filNam+"'."+"\n   Check for correct file syntax.");
  // Search for the equality sign
  (del,nexInd) := Modelica.Utilities.Strings.scanDelimiter(
    string=lin,
    startIndex=Modelica.Utilities.Strings.length(string)+1,
    requiredDelimiters={"="},
    message="Failed to find '=' when reading peak load in '"+filNam+"'.");
  // Read the value behind it.
  number := Modelica.Utilities.Strings.scanReal(
    string=lin,
    startIndex=nexInd,
    message="Failed to read double value when reading peak load in '"+filNam+"'.");
end getPeakLoad;


Package with base classes

within Buildings.DHC.Loads;
package BaseClasses "Package with base classes"
  extends Modelica.Icons.BasesPackage;
end BaseClasses;


Partial class for building model

within Buildings.DHC.Loads.BaseClasses;
partial model PartialBuilding
  "Partial class for building model"
  replaceable package Medium=Buildings.Media.Water
    constrainedby Modelica.Media.Interfaces.PartialMedium
    "Medium in the building distribution system";
  parameter Integer nPorts_aHeaWat=0
    "Number of heating water inlet ports"
  parameter Integer nPorts_bHeaWat=0
    "Number of heating water outlet ports"
  parameter Integer nPorts_aChiWat=0
    "Number of chilled water inlet ports"
  parameter Integer nPorts_bChiWat=0
    "Number of chilled water outlet ports"
  parameter Boolean have_heaWat=false
    "Set to true if the building has heating water system"
  parameter Boolean have_chiWat=false
    "Set to true if the building has chilled water system"
  parameter Boolean have_eleHea=false
    "Set to true if the building has decentralized electric heating system"
  parameter Boolean have_eleCoo=false
    "Set to true if the building has decentralized electric cooling system"
  parameter Boolean have_fan=false
    "Set to true if fan power is computed"
  parameter Boolean have_pum=false
    "Set to true if pump power is computed"
  parameter Boolean have_weaBus=false
    "Set to true to use a weather bus"
  parameter Real facMul(min=Modelica.Constants.eps)=1
    "Multiplier factor"
  parameter Boolean allowFlowReversal=false
    "= true to allow flow reversal, false restricts to design direction (port_a -> port_b)"
  final parameter Boolean have_heaLoa=have_heaWat or have_eleHea
    "Set to true if the building has heating loads"
  final parameter Boolean have_cooLoa=have_chiWat or have_eleCoo
    "Set to true if the building has cooling loads"
  // IO CONNECTORS
  Buildings.BoundaryConditions.WeatherData.Bus weaBus if have_weaBus
    "Weather data bus"
  Modelica.Fluid.Interfaces.FluidPorts_a ports_aHeaWat[nPorts_aHeaWat](
    redeclare each package Medium=Medium,
    each m_flow(
      min=
        if allowFlowReversal then
          -Modelica.Constants.inf
        else
          0),
    each h_outflow(
      start=Medium.h_default,
      nominal=Medium.h_default)) if have_heaWat
    "Heating water inlet ports"
  Modelica.Fluid.Interfaces.FluidPorts_b ports_bHeaWat[nPorts_bHeaWat](
    redeclare each package Medium=Medium,
    each m_flow(
      max=
        if allowFlowReversal then
          +Modelica.Constants.inf
        else
          0),
    each h_outflow(
      start=Medium.h_default,
      nominal=Medium.h_default)) if have_heaWat
    "Heating water outlet ports"
  Modelica.Fluid.Interfaces.FluidPorts_a ports_aChiWat[nPorts_aChiWat](
    redeclare each package Medium=Medium,
    each m_flow(
      min=
        if allowFlowReversal then
          -Modelica.Constants.inf
        else
          0),
    each h_outflow(
      start=Medium.h_default,
      nominal=Medium.h_default)) if have_chiWat
    "Chilled water inlet ports"
  Modelica.Fluid.Interfaces.FluidPorts_b ports_bChiWat[nPorts_bChiWat](
    redeclare each package Medium=Medium,
    each m_flow(
      max=
        if allowFlowReversal then
          +Modelica.Constants.inf
        else
          0),
    each h_outflow(
      start=Medium.h_default,
      nominal=Medium.h_default)) if have_chiWat
    "Chilled water outlet ports"
  Modelica.Blocks.Interfaces.RealOutput QHea_flow(
    final unit="W") if have_heaLoa
    "Total heating heat flow rate transferred to the loads (>=0)"
  Modelica.Blocks.Interfaces.RealOutput QCoo_flow(
    final unit="W") if have_cooLoa
    "Total cooling heat flow rate transferred to the loads (<=0)"
  Modelica.Blocks.Interfaces.RealOutput PHea(
    final unit="W") if have_eleHea
    "Power drawn by decentralized heating system"
  Modelica.Blocks.Interfaces.RealOutput PCoo(
    final unit="W") if have_eleCoo
    "Power drawn by decentralized cooling system"
  Modelica.Blocks.Interfaces.RealOutput PFan(
    final quantity="Power",
    final unit="W") if have_fan
    "Power drawn by fan motors"
  Modelica.Blocks.Interfaces.RealOutput PPum(
    final quantity="Power",
    final unit="W") if have_pum
    "Power drawn by pump motors"
  Fluid.BaseClasses.MassFlowRateMultiplier mulHeaWatInl[nPorts_aHeaWat](
    redeclare each final package Medium = Medium,
    each final k=1/facMul,
    each final allowFlowReversal=allowFlowReversal) if have_heaWat
    "Mass flow rate multiplier"
  Fluid.BaseClasses.MassFlowRateMultiplier mulChiWatInl[nPorts_aChiWat](
    redeclare each final package Medium = Medium,
    each final k=1/facMul,
    each final allowFlowReversal=allowFlowReversal) if have_chiWat
    "Mass flow rate multiplier"
  Fluid.BaseClasses.MassFlowRateMultiplier mulHeaWatOut[nPorts_bHeaWat](
    redeclare each final package Medium = Medium,
    each final k=facMul,
    each final allowFlowReversal=allowFlowReversal) if have_heaWat
    "Mass flow rate multiplier"
  Fluid.BaseClasses.MassFlowRateMultiplier mulChiWatOut[nPorts_bChiWat](
    redeclare each final package Medium = Medium,
    each final k=facMul,
    each final allowFlowReversal=allowFlowReversal) if have_chiWat
    "Mass flow rate multiplier"
  Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter mulQHea_flow(u(
        final unit="W"), final k=facMul) if have_heaLoa "Scaling"
  Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter mulQCoo_flow(u(
        final unit="W"), final k=facMul) if have_cooLoa "Scaling"
  Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter mulPHea(u(final
        unit="W"), final k=facMul) if have_eleHea "Scaling"
  Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter mulPCoo(u(final
        unit="W"), final k=facMul) if have_eleCoo "Scaling"
  Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter mulPFan(u(final
        unit="W"), final k=facMul) if have_fan "Scaling"
  Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter mulPPum(u(final
        unit="W"), final k=facMul) if have_pum "Scaling"
protected
  final parameter Modelica.Units.SI.SpecificHeatCapacity cp_default=
      Medium.specificHeatCapacityCp(Medium.setState_pTX(
      p=Medium.p_default,
      T=Medium.T_default,
      X=Medium.X_default))
    "Specific heat capacity of medium at default medium state";
initial equation
  assert(
    nPorts_aHeaWat == nPorts_bHeaWat,
    "In "+getInstanceName()+": The numbers of heating water inlet ports ("+String(
      nPorts_aHeaWat)+") and outlet ports ("+String(
      nPorts_bHeaWat)+") must be equal.");
  assert(
    nPorts_aChiWat == nPorts_bChiWat,
    "In "+getInstanceName()+": The numbers of chilled water inlet ports ("+String(
      nPorts_aChiWat)+") and outlet ports ("+String(
      nPorts_bChiWat)+") must be equal.");
equation
  connect(mulQHea_flow.y, QHea_flow)
  connect(mulQCoo_flow.y, QCoo_flow)
  connect(mulPHea.y, PHea)
  connect(mulPCoo.y, PCoo)
  connect(mulPFan.y, PFan)
  connect(mulPPum.y, PPum)
  connect(ports_aChiWat,mulChiWatInl. port_a)
  connect(ports_aHeaWat,mulHeaWatInl. port_a)
  connect(mulHeaWatOut.port_b, ports_bHeaWat)
  connect(mulChiWatOut.port_b, ports_bChiWat)
end PartialBuilding;


within Buildings.DHC.Loads.BaseClasses;
partial model PartialBuildingWithPartialETS
  "Partial model of a building with an energy transfer station"
  import TypDisSys=Buildings.DHC.Types.DistrictSystemType
    "District system type enumeration";
  replaceable package MediumSer=Buildings.Media.Water
    constrainedby Modelica.Media.Interfaces.PartialMedium
    "Service side medium";
  replaceable package MediumSerHea_a=Buildings.Media.Water
    constrainedby Modelica.Media.Interfaces.PartialMedium
    "Service side medium at heating inlet"
  replaceable package MediumBui=Buildings.Media.Water
    constrainedby Modelica.Media.Interfaces.PartialMedium
    "Building side medium";
  parameter Integer nPorts_heaWat=0
    "Number of heating water fluid ports"
  parameter Integer nPorts_chiWat=0
    "Number of chilled water fluid ports"
  parameter Real facMul = 1
    "Multiplier factor"
  parameter Boolean allowFlowReversalSer=false
    "Set to true to allow flow reversal on service side"
  parameter Boolean allowFlowReversalBui=false
    "Set to true to allow flow reversal on building side"
  // The following parameters are propagated up from building and ETS components.
  final parameter TypDisSys typ=ets.typ
    "Type of district system"
  final parameter Boolean have_heaWat=ets.have_heaWat
    "Set to true if the ETS supplies heating water"
  final parameter Boolean have_hotWat=ets.have_hotWat
    "Set to true if the ETS supplies domestic hot water"
  final parameter Boolean have_chiWat=ets.have_chiWat
    "Set to true if the ETS supplies chilled water"
  final parameter Boolean have_eleHea=bui.have_eleHea or ets.have_eleHea
    "Set to true if the building or ETS has electric heating system"
  final parameter Integer nFue=ets.nFue
    "Number of fuel types (0 means no combustion system)"
  final parameter Boolean have_eleCoo=bui.have_eleCoo or ets.have_eleCoo
    "Set to true if the building or ETS has electric cooling system"
  final parameter Boolean have_fan=bui.have_fan or ets.have_fan
    "Set to true if fan power is computed"
  final parameter Boolean have_pum=bui.have_pum or ets.have_pum
    "Set to true if pump power is computed"
  final parameter Boolean have_weaBus=bui.have_weaBus or ets.have_weaBus
    "Set to true to use a weather bus"
  final parameter Modelica.Units.SI.HeatFlowRate QHeaWat_flow_nominal(min=0)=
    ets.QHeaWat_flow_nominal "Nominal capacity of heating system (>=0)"
  final parameter Modelica.Units.SI.HeatFlowRate QHotWat_flow_nominal(min=0)=
    ets.QHotWat_flow_nominal
    "Nominal capacity of hot water production system (>=0)"
  final parameter Modelica.Units.SI.HeatFlowRate QChiWat_flow_nominal(max=0)=
    ets.QChiWat_flow_nominal "Nominal capacity of cooling system (<=0)"
  // Parameters for connect clauses.
  final parameter Integer idxPHeaETS=max(
    Modelica.Math.BooleanVectors.countTrue(
      {bui.have_eleHea,ets.have_eleHea}),
    1)
    "Index for connecting the ETS output connector"
  final parameter Integer idxPCooETS=max(
    Modelica.Math.BooleanVectors.countTrue(
      {bui.have_eleCoo,ets.have_eleCoo}),
    1)
    "Index for connecting the ETS output connector"
  final parameter Integer idxPFanETS=max(
    Modelica.Math.BooleanVectors.countTrue(
      {bui.have_fan,ets.have_fan}),
    1)
    "Index for connecting the ETS output connector"
  final parameter Integer idxPPumETS=max(
    Modelica.Math.BooleanVectors.countTrue(
      {bui.have_pum,ets.have_pum}),
    1)
    "Index for connecting the ETS output connector"
  // IO CONNECTORS
  Modelica.Fluid.Interfaces.FluidPort_a port_aSerAmb(
    redeclare package Medium = MediumSer,
    m_flow(min=if allowFlowReversalSer then -Modelica.Constants.inf else 0),
    h_outflow(start=MediumSer.h_default, nominal=MediumSer.h_default))
 if typ == Buildings.DHC.Types.DistrictSystemType.CombinedGeneration5
    "Fluid connector for ambient water service supply line"
  Modelica.Fluid.Interfaces.FluidPort_b port_bSerAmb(
    redeclare package Medium = MediumSer,
    m_flow(max=if allowFlowReversalSer then +Modelica.Constants.inf else 0),
    h_outflow(start=MediumSer.h_default, nominal=MediumSer.h_default))
 if typ == Buildings.DHC.Types.DistrictSystemType.CombinedGeneration5
    "Fluid connector for ambient water service return line"
  Modelica.Fluid.Interfaces.FluidPort_a port_aSerHea(
    redeclare package Medium = MediumSerHea_a,
    m_flow(min=if allowFlowReversalSer then -Modelica.Constants.inf else 0),
    h_outflow(start=MediumSerHea_a.h_default, nominal=MediumSerHea_a.h_default))
 if typ <> Buildings.DHC.Types.DistrictSystemType.Cooling and
    typ <> Buildings.DHC.Types.DistrictSystemType.CombinedGeneration5
    "Fluid connector for heating service supply line"
  Modelica.Fluid.Interfaces.FluidPort_b port_bSerHea(
    redeclare package Medium = MediumSer,
    m_flow(max=if allowFlowReversalSer then +Modelica.Constants.inf else 0),
    h_outflow(start=MediumSer.h_default, nominal=MediumSer.h_default))
 if typ <> Buildings.DHC.Types.DistrictSystemType.Cooling and
    typ <> Buildings.DHC.Types.DistrictSystemType.CombinedGeneration5
    "Fluid connector for heating service return line"
  Modelica.Fluid.Interfaces.FluidPort_a port_aSerCoo(
    redeclare package Medium = MediumSer,
    m_flow(min=if allowFlowReversalSer then -Modelica.Constants.inf else 0),
    h_outflow(start=MediumSer.h_default, nominal=MediumSer.h_default))
 if typ == Buildings.DHC.Types.DistrictSystemType.CombinedGeneration1 or
    typ == Buildings.DHC.Types.DistrictSystemType.CombinedGeneration2to4 or
    typ == Buildings.DHC.Types.DistrictSystemType.Cooling
    "Fluid connector for cooling service supply line"
  Modelica.Fluid.Interfaces.FluidPort_b port_bSerCoo(
    redeclare package Medium = MediumSer,
    m_flow(max=if allowFlowReversalSer then +Modelica.Constants.inf else 0),
    h_outflow(start=MediumSer.h_default, nominal=MediumSer.h_default))
 if typ == Buildings.DHC.Types.DistrictSystemType.CombinedGeneration1 or
    typ == Buildings.DHC.Types.DistrictSystemType.CombinedGeneration2to4 or
    typ == Buildings.DHC.Types.DistrictSystemType.Cooling
    "Fluid connector for cooling service return line"
  BoundaryConditions.WeatherData.Bus weaBus if have_weaBus
    "Weather data bus"
  Buildings.Controls.OBC.CDL.Interfaces.RealOutput QHea_flow(
    final unit="W") if bui.have_heaLoa
    "Total heating heat flow rate transferred to the loads (>=0)"
  Buildings.Controls.OBC.CDL.Interfaces.RealOutput QCoo_flow(
    final unit="W") if bui.have_cooLoa
    "Total cooling heat flow rate transferred to the loads (<=0)"
  Buildings.Controls.OBC.CDL.Interfaces.RealOutput PHea(
    final unit="W") if have_eleHea
    "Power drawn by heating system"
  Buildings.Controls.OBC.CDL.Interfaces.RealOutput PCoo(
    final unit="W") if have_eleCoo
    "Power drawn by cooling system"
  Buildings.Controls.OBC.CDL.Interfaces.RealOutput PFan(
    final unit="W") if have_fan
    "Power drawn by fan motors"
  Buildings.Controls.OBC.CDL.Interfaces.RealOutput PPum(
    final unit="W") if have_pum
    "Power drawn by pump motors"
  Buildings.Controls.OBC.CDL.Interfaces.RealOutput QFue_flow[nFue](
    each final unit="W") if nFue>0
    "Fuel energy input rate"
  // COMPONENTS
  replaceable Buildings.DHC.Loads.BaseClasses.PartialBuilding bui(
    redeclare final package Medium=MediumBui,
    final nPorts_aHeaWat=nPorts_heaWat,
    final nPorts_bHeaWat=nPorts_heaWat,
    final nPorts_aChiWat=nPorts_chiWat,
    final nPorts_bChiWat=nPorts_chiWat,
    final allowFlowReversal=allowFlowReversalBui)
    "Building model "
  replaceable Buildings.DHC.ETS.BaseClasses.PartialETS ets(
    redeclare final package MediumBui=MediumBui,
    redeclare final package MediumSer=MediumSer,
    redeclare final package MediumSerHea_a=MediumSerHea_a,
    final nPorts_aHeaWat=nPorts_heaWat,
    final nPorts_bHeaWat=nPorts_heaWat,
    final nPorts_aChiWat=nPorts_chiWat,
    final nPorts_bChiWat=nPorts_chiWat,
    final allowFlowReversalSer=allowFlowReversalSer,
    final allowFlowReversalBui=allowFlowReversalBui)
    "Energy transfer station model"
  Buildings.Controls.OBC.CDL.Reals.MultiSum totPHea(
    final nin=Modelica.Math.BooleanVectors.countTrue(
      {bui.have_eleHea,ets.have_eleHea}))
    "Total power drawn by heating system"
  Buildings.Controls.OBC.CDL.Reals.MultiSum totPCoo(
    final nin=Modelica.Math.BooleanVectors.countTrue(
      {bui.have_eleCoo,ets.have_eleCoo}))
    "Total power drawn by cooling system"
  Buildings.Controls.OBC.CDL.Reals.MultiSum totPFan(
    final nin=Modelica.Math.BooleanVectors.countTrue(
      {bui.have_fan,ets.have_fan}))
    "Total power drawn by fan motors"
  Buildings.Controls.OBC.CDL.Reals.MultiSum totPPum(
    final nin=Modelica.Math.BooleanVectors.countTrue(
      {bui.have_pum,ets.have_pum})) if have_pum
    "Total power drawn by pump motors"
  Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter mulQHea_flow(u(
        final unit="W"), final k=facMul) if bui.have_heaLoa "Scaling"
  Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter mulQCoo_flow(u(
        final unit="W"), final k=facMul) if bui.have_cooLoa "Scaling"
  Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter mulPHea(u(final
        unit="W"), final k=facMul) if have_eleHea "Scaling"
  Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter mulPCoo(u(final
        unit="W"), final k=facMul) if have_eleCoo "Scaling"
  Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter mulPFan(u(final
        unit="W"), final k=facMul) if have_fan "Scaling"
  Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter mulPPum(u(final
        unit="W"), final k=facMul) if have_pum "Scaling"
  Fluid.BaseClasses.MassFlowRateMultiplier mulSerAmbInl(
    redeclare final package Medium = MediumSer,
    final k=1/facMul,
    final allowFlowReversal=allowFlowReversalSer)
 if typ == Buildings.DHC.Types.DistrictSystemType.CombinedGeneration5 "Mass flow rate multiplier"
  Fluid.BaseClasses.MassFlowRateMultiplier mulSerAmbOut(
    redeclare final package Medium = MediumSer,
    final k=facMul,
    final allowFlowReversal=allowFlowReversalSer)
 if typ == Buildings.DHC.Types.DistrictSystemType.CombinedGeneration5 "Mass flow rate multiplier"
  Fluid.BaseClasses.MassFlowRateMultiplier mulSerHeaInl(
    redeclare final package Medium = MediumSerHea_a,
    final k=1/facMul,
    final allowFlowReversal=allowFlowReversalSer)
 if typ <> Buildings.DHC.Types.DistrictSystemType.Cooling and
    typ <> Buildings.DHC.Types.DistrictSystemType.CombinedGeneration5 "Mass flow rate multiplier"
  Fluid.BaseClasses.MassFlowRateMultiplier mulSerHeaOut(
    redeclare final package Medium = MediumSer,
    final k=facMul,
    final allowFlowReversal=allowFlowReversalSer)
 if typ <> Buildings.DHC.Types.DistrictSystemType.Cooling and
    typ <> Buildings.DHC.Types.DistrictSystemType.CombinedGeneration5 "Mass flow rate multiplier"
  Fluid.BaseClasses.MassFlowRateMultiplier mulSerCooInl(
    redeclare final package Medium = MediumSer,
    final k=1/facMul,
    final allowFlowReversal=allowFlowReversalSer)
 if typ == Buildings.DHC.Types.DistrictSystemType.CombinedGeneration1 or
    typ == Buildings.DHC.Types.DistrictSystemType.CombinedGeneration2to4 or
    typ == Buildings.DHC.Types.DistrictSystemType.Cooling "Mass flow rate multiplier"
  Fluid.BaseClasses.MassFlowRateMultiplier mulSerCooOut(
    redeclare final package Medium = MediumSer,
    final k=facMul,
    final allowFlowReversal=allowFlowReversalSer)
 if typ == Buildings.DHC.Types.DistrictSystemType.CombinedGeneration1 or
    typ == Buildings.DHC.Types.DistrictSystemType.CombinedGeneration2to4 or
    typ == Buildings.DHC.Types.DistrictSystemType.Cooling "Mass flow rate multiplier"
  Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter mulQFue_flow[nFue](
      u(each final unit="W"), each final k=facMul) if nFue > 0 "Scaling"
initial equation
  assert(ets.have_heaWat == bui.have_heaWat,
    "In "+getInstanceName()+": The ETS component is configured with have_heaWat="+
    String(ets.have_heaWat)+" whereas the building is configured with have_heaWat="+
    String(bui.have_heaWat));
  assert(ets.have_chiWat == bui.have_chiWat,
    "In "+getInstanceName()+": The ETS component is configured with have_chiWat="+
    String(ets.have_chiWat)+" whereas the building is configured with have_chiWat="+
    String(bui.have_chiWat));
  if have_heaWat then
    assert(nPorts_heaWat > 0,
    "In "+getInstanceName()+": The ETS component is configured with have_heaWat="+
    String(ets.have_heaWat)+" but the number of fluid ports for chilled water
    (nPorts_heaWat) is zero.");
  end if;
  if have_chiWat then
    assert(nPorts_chiWat > 0,
    "In "+getInstanceName()+": The ETS component is configured with have_chiWat="+
    String(ets.have_chiWat)+" but the number of fluid ports for chilled water
    (nPorts_chiWat) is zero.");
  end if;
equation
  connect(bui.ports_bHeaWat,ets.ports_aHeaWat)
  connect(ets.ports_bHeaWat,bui.ports_aHeaWat)
  connect(bui.ports_bChiWat,ets.ports_aChiWat)
  connect(ets.ports_bChiWat,bui.ports_aChiWat)
  connect(weaBus,bui.weaBus)
  connect(weaBus,ets.weaBus)
  connect(bui.PHea,totPHea.u[1])
  connect(ets.PHea,totPHea.u[idxPHeaETS])
  connect(bui.PCoo,totPCoo.u[1])
  connect(ets.PCoo,totPCoo.u[idxPCooETS])
  connect(bui.PFan,totPFan.u[1])
  connect(ets.PFan,totPFan.u[idxPFanETS])
  connect(bui.PPum,totPPum.u[1])
  connect(ets.PPum,totPPum.u[idxPPumETS])
  connect(bui.QHea_flow, mulQHea_flow.u)
  connect(mulQHea_flow.y, QHea_flow)
  connect(bui.QCoo_flow, mulQCoo_flow.u)
  connect(mulQCoo_flow.y, QCoo_flow)
  connect(totPHea.y, mulPHea.u)
  connect(mulPHea.y, PHea)
  connect(totPCoo.y, mulPCoo.u)
  connect(mulPCoo.y, PCoo)
  connect(totPFan.y, mulPFan.u)
  connect(mulPFan.y, PFan)
  connect(totPPum.y, mulPPum.u)
  connect(mulPPum.y, PPum)
  connect(port_aSerCoo,mulSerCooInl. port_a)
  connect(mulSerCooInl.port_b, ets.port_aSerCoo)
  connect(mulSerCooOut.port_b, port_bSerCoo)
  connect(ets.port_bSerCoo,mulSerCooOut. port_a)
  connect(port_aSerHea,mulSerHeaInl. port_a)
  connect(mulSerHeaInl.port_b, ets.port_aSerHea)
  connect(port_aSerAmb,mulSerAmbInl. port_a)
  connect(mulSerAmbInl.port_b, ets.port_aSerAmb)
  connect(ets.port_bSerHea,mulSerHeaOut. port_a)
  connect(mulSerHeaOut.port_b, port_bSerHea)
  connect(ets.port_bSerAmb,mulSerAmbOut. port_a)
  connect(mulSerAmbOut.port_b, port_bSerAmb)
  connect(mulQFue_flow.y, QFue_flow)
  connect(ets.QFue_flow, mulQFue_flow.u)
end PartialBuildingWithPartialETS;


within Buildings.DHC.Loads.BaseClasses;
partial model PartialFanCoil4Pipe
  "Partial model of a sensible only four-pipe fan coil unit computing a required water mass flow rate"
  extends Buildings.DHC.Loads.BaseClasses.PartialTerminalUnit(
    redeclare package Medium1=Buildings.Media.Water,
    redeclare package Medium2=Buildings.Media.Air,
    final have_heaWat=true,
    final have_chiWat=true,
    final have_fan=true,
    final allowFlowReversal=false,
    final allowFlowReversalLoa=true,
    final have_chaOve=false,
    final have_eleHea=false,
    final have_eleCoo=false,
    final have_QReq_flow=false,
    final have_weaBus=false,
    final have_pum=false,
    final mHeaWat_flow_nominal=abs(
      QHea_flow_nominal/cpHeaWat_nominal/(T_aHeaWat_nominal-T_bHeaWat_nominal)),
    final mChiWat_flow_nominal=abs(
      QCoo_flow_nominal/cpChiWat_nominal/(T_aChiWat_nominal-T_bChiWat_nominal)));
  import hexConfiguration=Buildings.Fluid.Types.HeatExchangerConfiguration;
  final parameter hexConfiguration hexConHea=hexConfiguration.CounterFlow
    "Heating heat exchanger configuration";
  final parameter hexConfiguration hexConCoo=hexConfiguration.CounterFlow
    "Cooling heat exchanger configuration";
  Buildings.Controls.OBC.CDL.Reals.PID conHea(
    Ti=10,
    yMax=1,
    controllerType=Buildings.Controls.OBC.CDL.Types.SimpleController.PI,
    reverseActing=true,
    yMin=0)
    "PI controller for heating"
  Buildings.Fluid.Movers.FlowControlled_m_flow fan(
    redeclare final package Medium = Medium2,
    final m_flow_nominal=max({mLoaHea_flow_nominal,mLoaCoo_flow_nominal}),
    redeclare final Fluid.Movers.Data.Generic per,
    nominalValuesDefineDefaultPressureCurve=true,
    energyDynamics=Modelica.Fluid.Types.Dynamics.SteadyState,
    use_riseTime=false,
    dp_nominal=400,
    final allowFlowReversal=allowFlowReversalLoa)
  Buildings.Fluid.HeatExchangers.DryCoilEffectivenessNTU hexHea(
    redeclare final package Medium1=Medium1,
    redeclare final package Medium2=Medium2,
    final configuration=hexConHea,
    final m1_flow_nominal=mHeaWat_flow_nominal,
    final m2_flow_nominal=mLoaHea_flow_nominal,
    final dp1_nominal=0,
    dp2_nominal=200,
    final Q_flow_nominal=QHea_flow_nominal,
    final T_a1_nominal=T_aHeaWat_nominal,
    final T_a2_nominal=T_aLoaHea_nominal,
    final allowFlowReversal1=allowFlowReversal,
    final allowFlowReversal2=allowFlowReversalLoa)
  Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter gaiHeaFloNom(k=
        mHeaWat_flow_nominal)
  Modelica.Blocks.Sources.RealExpression Q_flowHea(
    y=hexHea.Q2_flow)
  Fluid.HeatExchangers.WetCoilEffectivenessNTU hexWetNtu(
    redeclare final package Medium1=Medium1,
    redeclare final package Medium2=Medium2,
    final configuration=hexConCoo,
    final m1_flow_nominal=mChiWat_flow_nominal,
    final m2_flow_nominal=mLoaCoo_flow_nominal,
    final dp1_nominal=0,
    dp2_nominal=200,
    use_Q_flow_nominal=true,
    final Q_flow_nominal=QCoo_flow_nominal,
    final T_a1_nominal=T_aChiWat_nominal,
    final T_a2_nominal=T_aLoaCoo_nominal,
    final allowFlowReversal1=allowFlowReversal,
    final allowFlowReversal2=allowFlowReversalLoa,
    final w_a2_nominal=w_aLoaCoo_nominal)
  Modelica.Blocks.Sources.RealExpression Q_flowCoo(y=hexWetNtu.Q2_flow)
  Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter gaiFloNom2(k=max({
        mLoaHea_flow_nominal,mLoaCoo_flow_nominal}))
  Buildings.Controls.OBC.CDL.Reals.PID conCoo(
    Ti=10,
    yMax=1,
    controllerType=Buildings.Controls.OBC.CDL.Types.SimpleController.PI,
    reverseActing=false,
    yMin=0)
    "PI controller for cooling"
  Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter gaiCooFloNom(k=
        mChiWat_flow_nominal) "Scaling"
  Utilities.Math.SmoothMax smoothMax(
    deltaX=1E-2)
    "C1 maximum"
equation
  connect(hexWetNtu.port_b2, hexHea.port_a2)
  connect(fan.port_b, hexWetNtu.port_a2)
  connect(gaiFloNom2.y,fan.m_flow_in)
  connect(conHea.y,gaiHeaFloNom.u)
  connect(conCoo.y,gaiCooFloNom.u)
  connect(gaiHeaFloNom.y,mulMasFloReqHeaWat.u)
  connect(gaiCooFloNom.y,mulMasFloReqChiWat.u)
  connect(fan.P,mulPFan.u)
  connect(Q_flowHea.y,mulQActHea_flow.u)
  connect(Q_flowCoo.y,mulQActCoo_flow.u)
  connect(TSetCoo,conCoo.u_s)
  connect(TSetHea,conHea.u_s)
  connect(smoothMax.y,gaiFloNom2.u)
  connect(conHea.y,smoothMax.u1)
  connect(conCoo.y,smoothMax.u2)
  connect(mulChiWatFloInl.port_b, hexWetNtu.port_a1)
  connect(hexWetNtu.port_b1, mulChiWatFloOut.port_a)
  connect(hexHea.port_b1,mulHeaWatFloOut.port_a)
  connect(mulHeaWatFloInl.port_b,hexHea.port_a1)
end PartialFanCoil4Pipe;


Partial model for HVAC terminal unit

within Buildings.DHC.Loads.BaseClasses;
partial model PartialTerminalUnit
  "Partial model for HVAC terminal unit"
  replaceable package Medium1=Buildings.Media.Water
    constrainedby Modelica.Media.Interfaces.PartialMedium
    "Medium in the building distribution system";
  replaceable package Medium2=Buildings.Media.Air
    constrainedby Modelica.Media.Interfaces.PartialMedium
    "Load side medium";
  parameter Boolean allowFlowReversal=false
    "Set to true to allow flow reversal in building distribution system"
  parameter Boolean allowFlowReversalLoa=true
    "Set to true to allow flow reversal on the load side"
  parameter Real facMul(min=Modelica.Constants.eps)=1
    "Multiplier factor"
   parameter Real facMulZon(min=Modelica.Constants.eps)=1
    "Zone multiplier factor"
  parameter Boolean have_heaWat=false
    "Set to true if the system uses heating water"
  parameter Boolean have_chiWat=false
    "Set to true if the system uses chilled water"
  parameter Boolean have_chaOve=false
    "Set to true if the chilled water based heat exchanger operates in change-over"
  parameter Boolean have_eleHea=false
    "Set to true if the system has electric heating system"
  parameter Boolean have_eleCoo=false
    "Set to true if the system has electric cooling system"
  parameter Boolean have_heaPor=false
    "Set to true for heat ports on the load side"
  parameter Boolean have_fluPor=false
    "Set to true for fluid ports on the load side"
  parameter Boolean have_TSen=false
    "Set to true for measured temperature as an input"
  parameter Boolean have_QReq_flow=false
    "Set to true for required heat flow rate as an input"
  parameter Boolean have_weaBus=false
    "Set to true to use a weather bus"
  parameter Boolean have_fan=false
    "Set to true if fan power is computed"
  parameter Boolean have_pum=false
    "Set to true if pump power is computed"
  parameter Modelica.Units.SI.HeatFlowRate QHea_flow_nominal(min=0) = 0
    "Nominal heating capacity (>=0)"
  parameter Modelica.Units.SI.HeatFlowRate QCoo_flow_nominal(max=0) = 0
    "Nominal cooling capacity (<=0)"
  parameter Modelica.Units.SI.MassFlowRate mHeaWat_flow_nominal(min=0) = 0
    "Heating water mass flow rate at nominal conditions"
  parameter Modelica.Units.SI.MassFlowRate mChiWat_flow_nominal(min=0) = 0
    "Chilled water mass flow rate at nominal conditions"
  parameter Modelica.Units.SI.MassFlowRate mLoaHea_flow_nominal(min=0) = 0
    "Load side mass flow rate at nominal conditions in heating mode"
  parameter Modelica.Units.SI.MassFlowRate mLoaCoo_flow_nominal(min=0) = 0
    "Load side mass flow rate at nominal conditions in cooling mode"
  // AHRI 440 Standard Heating
  parameter Modelica.Units.SI.Temperature T_aHeaWat_nominal=273.15 + 60
    "Heating water inlet temperature at nominal conditions"
  parameter Modelica.Units.SI.Temperature T_bHeaWat_nominal(
    min=273.15,
    displayUnit="degC") = T_aHeaWat_nominal - 22.2
    "Heating water outlet temperature at nominal conditions"
  // AHRI 440 Standard Cooling
  parameter Modelica.Units.SI.Temperature T_aChiWat_nominal=273.15 + 7.2
    "Chilled water inlet temperature at nominal conditions "
  parameter Modelica.Units.SI.Temperature T_bChiWat_nominal(
    min=273.15,
    displayUnit="degC") = T_aChiWat_nominal + 5.6
    "Chilled water outlet temperature at nominal conditions"
  parameter Modelica.Units.SI.Temperature T_aLoaHea_nominal=273.15 + 21.1
    "Load side inlet temperature at nominal conditions in heating mode"
  parameter Modelica.Units.SI.Temperature T_aLoaCoo_nominal=273.15 + 26.7
    "Load side inlet temperature at nominal conditions in cooling mode"

  parameter Modelica.Units.SI.MassFraction w_aLoaCoo_nominal=0.011
    "Load side inlet humidity ratio at nominal conditions in cooling mode"
  // IO connectors
  Modelica.Blocks.Interfaces.RealInput TSen(
    final quantity="ThermodynamicTemperature",
    final unit="K",
    displayUnit="degC") if have_TSen
    "Temperature (measured)"
  Modelica.Blocks.Interfaces.RealInput TSetHea(
    quantity="ThermodynamicTemperature",
    final unit="K",
    displayUnit="degC") if have_heaWat or have_chaOve or have_eleHea
    "Heating set point"
  Modelica.Blocks.Interfaces.RealInput TSetCoo(
    final quantity="ThermodynamicTemperature",
    final unit="K",
    displayUnit="degC") if have_chiWat or have_eleCoo
    "Cooling set point"
  Modelica.Blocks.Interfaces.RealInput QReqHea_flow(
    final quantity="HeatFlowRate",
    final unit="W") if have_QReq_flow and (have_heaWat or have_chaOve or have_eleHea)
    "Required heat flow rate to meet heating set point (>=0)"
  Modelica.Blocks.Interfaces.RealInput QReqCoo_flow(
    final quantity="HeatFlowRate",
    final unit="W") if have_QReq_flow and (have_chiWat or have_eleCoo)
    "Required heat flow rate to meet cooling set point (<=0)"
  Modelica.Blocks.Interfaces.RealOutput QActHea_flow(
    final quantity="HeatFlowRate",
    final unit="W") if have_heaWat or have_chaOve or have_eleHea
    "Heating heat flow rate transferred to the load (>=0)"
  Modelica.Blocks.Interfaces.RealOutput QActCoo_flow(
    final quantity="HeatFlowRate",
    final unit="W") if have_chiWat or have_eleCoo
    "Cooling heat flow rate transferred to the load (<=0)"
  Modelica.Blocks.Interfaces.RealOutput PHea(
    final quantity="Power",
    final unit="W") if have_eleHea
    "Power drawn by heating system"
  Modelica.Blocks.Interfaces.RealOutput PCoo(
    final quantity="Power",
    final unit="W") if have_eleCoo
    "Power drawn by cooling system"
  Modelica.Blocks.Interfaces.RealOutput PFan(
    final quantity="Power",
    final unit="W") if have_fan
    "Power drawn by fans motors"
  Modelica.Blocks.Interfaces.RealOutput PPum(
    final quantity="Power",
    final unit="W") if have_pum
    "Power drawn by pumps motors"
  Modelica.Blocks.Interfaces.RealOutput mReqHeaWat_flow(
    final quantity="MassFlowRate",
    final unit="kg/s") if have_heaWat
    "Required heating water flow rate to meet heating set point"
  Modelica.Blocks.Interfaces.RealOutput mReqChiWat_flow(
    final quantity="MassFlowRate",
    final unit="kg/s") if have_chiWat
    "Required chilled water flow rate to meet cooling set point"
  Modelica.Fluid.Interfaces.FluidPort_a port_aLoa(
    redeclare final package Medium=Medium2,
    p(start=Medium2.p_default),
    m_flow(
      min=
        if allowFlowReversalLoa then
          -Modelica.Constants.inf
        else
          0),
    h_outflow(
      start=Medium2.h_default,
      nominal=Medium2.h_default)) if have_fluPor
    "Fluid stream inlet port on the load side"
  Modelica.Fluid.Interfaces.FluidPort_b port_bLoa(
    redeclare final package Medium=Medium2,
    p(start=Medium2.p_default),
    m_flow(
      max=
        if allowFlowReversalLoa then
          +Modelica.Constants.inf
        else
          0),
    h_outflow(
      start=Medium2.h_default,
      nominal=Medium2.h_default)) if have_fluPor
    "Fluid stream outlet port on the load side"
  Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b heaPorCon if have_heaPor
    "Heat port transferring convective heat to the load"
  Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b heaPorRad if have_heaPor
    "Heat port transferring radiative heat to the load"
  BoundaryConditions.WeatherData.Bus weaBus if have_weaBus
    "Weather data bus"
  Modelica.Fluid.Interfaces.FluidPort_a port_aHeaWat(
    p(start=Medium1.p_default),
    redeclare final package Medium=Medium1,
    m_flow(
      min=
        if allowFlowReversal then
          -Modelica.Constants.inf
        else
          0),
    h_outflow(
      start=Medium1.h_default,
      nominal=Medium1.h_default)) if have_heaWat
    "Heating water inlet port"
  Modelica.Fluid.Interfaces.FluidPort_a port_aChiWat(
    p(start=Medium1.p_default),
    redeclare final package Medium=Medium1,
    m_flow(
      min=
        if allowFlowReversal then
          -Modelica.Constants.inf
        else
          0),
    h_outflow(
      start=Medium1.h_default,
      nominal=Medium1.h_default)) if have_chiWat
    "Chilled water inlet port"
  Modelica.Fluid.Interfaces.FluidPort_b port_bHeaWat(
    p(start=Medium1.p_default),
    redeclare final package Medium=Medium1,
    m_flow(
      max=
        if allowFlowReversal then
          +Modelica.Constants.inf
        else
          0),
    h_outflow(
      start=Medium1.h_default,
      nominal=Medium1.h_default)) if have_heaWat
    "Heating water outlet port"
  Modelica.Fluid.Interfaces.FluidPort_b port_bChiWat(
    p(start=Medium1.p_default),
    redeclare final package Medium=Medium1,
    m_flow(
      max=
        if allowFlowReversal then
          +Modelica.Constants.inf
        else
          0),
    h_outflow(
      start=Medium1.h_default,
      nominal=Medium1.h_default)) if have_chiWat
    "Chilled water outlet port"
  // COMPONENTS
  Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter mulQReqHea_flow(u(
        final unit="W"), final k=1/facMul)
    if have_QReq_flow and (have_heaWat or have_chaOve or have_eleHea) "Scaling"
  Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter mulQReqCoo_flow(u(
        final unit="W"), final k=1/facMul)
    if have_QReq_flow and (have_chiWat or have_eleCoo) "Scaling"
  Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter mulQActHea_flow(u(
        final unit="W"), final k=facMul*facMulZon)
    if have_heaWat or have_chaOve or have_eleHea "Scaling"
  Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter mulQActCoo_flow(u(
        final unit="W"), final k=facMul*facMulZon) if have_chiWat or
    have_eleCoo "Scaling"
  Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter mulPHea(u(final
        unit="W"), final k=facMul*facMulZon) if have_eleHea "Scaling"
  Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter mulPCoo(u(final
        unit="W"), final k=facMul*facMulZon) if have_eleCoo "Scaling"
  Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter mulPFan(u(final
        unit="W"), final k=facMul*facMulZon) if have_fan "Scaling"
  Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter mulPPum(u(final
        unit="W"), final k=facMul*facMulZon) if have_pum "Scaling"
  Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter mulMasFloReqHeaWat(
      u(final unit="kg/s"), final k=facMul*facMulZon) if have_heaWat "Scaling"
  Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter mulMasFloReqChiWat(
      u(final unit="kg/s"), final k=facMul*facMulZon) if have_chiWat "Scaling"
  Fluid.BaseClasses.MassFlowRateMultiplier mulHeaWatFloInl(
    redeclare final package Medium=Medium1,
    final k=1/facMul/facMulZon,
    final allowFlowReversal=allowFlowReversal) if have_heaWat
    "Mass flow rate multiplier"
  Fluid.BaseClasses.MassFlowRateMultiplier mulHeaWatFloOut(
    redeclare final package Medium=Medium1,
    final k=facMul*facMulZon,
    final allowFlowReversal=allowFlowReversal) if have_heaWat
    "Mass flow rate multiplier"
  Fluid.BaseClasses.MassFlowRateMultiplier mulChiWatFloInl(
    redeclare final package Medium=Medium1,
    final k=1/facMul/facMulZon,
    final allowFlowReversal=allowFlowReversal) if have_chiWat
    "Mass flow rate multiplier"
  Fluid.BaseClasses.MassFlowRateMultiplier mulChiWatFloOut(
    redeclare final package Medium=Medium1,
    final k=facMul*facMulZon,
    final allowFlowReversal=allowFlowReversal) if have_chiWat
    "Mass flow rate multiplier"
  Fluid.BaseClasses.MassFlowRateMultiplier mulLoaMasFloOut(
    redeclare final package Medium=Medium2,
    final k=facMul,
    final allowFlowReversal=allowFlowReversalLoa) if have_fluPor
    "Load side mass flow rate multiplier"
  Fluid.BaseClasses.MassFlowRateMultiplier mulLoaMasFloInl(
    redeclare final package Medium=Medium2,
    final k=1/facMul,
    final allowFlowReversal=allowFlowReversalLoa) if have_fluPor
    "Load side mass flow rate multiplier"
  Fluid.HeatExchangers.RadiantSlabs.BaseClasses.HeatFlowRateMultiplier mulHeaFloCon(final k=
        facMul)     if have_heaPor "Convective heat flow rate multiplier"
  Fluid.HeatExchangers.RadiantSlabs.BaseClasses.HeatFlowRateMultiplier mulHeaFloRad(final k=
        facMul)     if have_heaPor "Radiative heat flow rate multiplier"
protected
  parameter Modelica.Units.SI.SpecificHeatCapacity cpHeaWat_nominal=
      Medium1.specificHeatCapacityCp(Medium1.setState_pTX(Medium1.p_default,
      T_aHeaWat_nominal))
    "Heating water specific heat capacity at nominal conditions";
  parameter Modelica.Units.SI.SpecificHeatCapacity cpChiWat_nominal=
      Medium1.specificHeatCapacityCp(Medium1.setState_pTX(Medium1.p_default,
      T_aChiWat_nominal))
    "Chilled water specific heat capacity at nominal conditions";
  parameter Modelica.Units.SI.SpecificHeatCapacity cpLoaHea_nominal=
      Medium2.specificHeatCapacityCp(Medium2.setState_pTX(Medium2.p_default,
      T_aLoaHea_nominal))
    "Load side fluid specific heat capacity at nominal conditions in heating mode";
  parameter Modelica.Units.SI.SpecificHeatCapacity cpLoaCoo_nominal=
      Medium2.specificHeatCapacityCp(Medium2.setState_pTX(Medium2.p_default,
      T_aLoaCoo_nominal))
    "Load side fluid specific heat capacity at nominal conditions in cooling mode";
equation
  connect(QReqHea_flow,mulQReqHea_flow.u)
  connect(QReqCoo_flow,mulQReqCoo_flow.u)
  connect(mulQActHea_flow.y,QActHea_flow)
  connect(mulQActCoo_flow.y,QActCoo_flow)
  connect(mulPHea.y,PHea)
  connect(mulPCoo.y,PCoo)
  connect(mulPFan.y,PFan)
  connect(mulPPum.y,PPum)
  connect(mulMasFloReqHeaWat.y,mReqHeaWat_flow)
  connect(mulMasFloReqChiWat.y,mReqChiWat_flow)
  connect(port_aHeaWat,mulHeaWatFloInl.port_a)
  connect(mulHeaWatFloOut.port_b,port_bHeaWat)
  connect(port_aChiWat,mulChiWatFloInl.port_a)
  connect(mulChiWatFloOut.port_b,port_bChiWat)
  connect(mulLoaMasFloOut.port_b,port_bLoa)
  connect(port_aLoa,mulLoaMasFloInl.port_a)
  connect(mulHeaFloCon.port_b,heaPorCon)
  connect(mulHeaFloRad.port_b,heaPorRad)
end PartialTerminalUnit;


Simplified model for assessing room air temperature variations around a set point. This is a first order ODE model assessing the indoor air temperature variations
around a set point, based on the difference between the required and actual
heating or cooling heat flow rate and a minimum set of parameters at nominal conditions.

within Buildings.DHC.Loads.BaseClasses;
model SimpleRoomODE
  "Simplified model for assessing room air temperature variations around a set point"
  extends Modelica.Blocks.Icons.Block;
  parameter Modelica.Units.SI.TemperatureDifference dTEnv_nominal
    "Design temperature difference at which envelope heat loss is QEnv_flow_nominal"
  parameter Modelica.Units.SI.Temperature TAir_start(displayUnit="degC")
    "Initial air temperature"
  parameter Modelica.Units.SI.HeatFlowRate QEnv_flow_nominal(min=0)
    "Envelope heat loss at temperature difference of dTEnv_nominal (with no internal gains, no solar radiation)"
  parameter Boolean steadyStateInitial=false
    "true initializes T with dT(0)/dt=0, false initializes T with T(0)=TIndHea_nominal"
  parameter Modelica.Units.SI.Time tau=1800
    "Time constant of the indoor temperature";
  Modelica.Blocks.Interfaces.RealInput TSet(
    final quantity="ThermodynamicTemperature",
    final unit="K",
    displayUnit="degC")
    "Temperature set point for heating or cooling"
  Modelica.Blocks.Interfaces.RealInput QReq_flow(
    final quantity="HeatFlowRate",
    final unit="W")
    "Required heat flow rate to meet temperature set point (>=0 for heating)"
  Modelica.Blocks.Interfaces.RealInput QAct_flow(
    final quantity="HeatFlowRate",
    final unit="W")
    "Actual heating or cooling heat flow rate (>=0 for heating)"
  Modelica.Blocks.Interfaces.RealOutput TAir(
    final quantity="ThermodynamicTemperature",
    final unit="K",
    displayUnit="degC")
    "Room air temperature"
protected
  parameter Modelica.Units.SI.ThermalConductance G=abs(QEnv_flow_nominal/dTEnv_nominal)
    "Lumped thermal conductance representing all temperature dependent heat transfer mechanisms";
initial equation
  if steadyStateInitial then
    der(
      TAir)=0;
  else
    TAir=TAir_start;
  end if;
equation
  der(
    TAir)*tau=(QAct_flow-QReq_flow)/G+TSet-TAir;
  assert(
    TAir >= 273.15,
    "In "+getInstanceName()+": The computed indoor temperature is below 0°C.");
end SimpleRoomODE;


Package with type definitions

within Buildings.DHC.Loads.BaseClasses;
package Types
  "Package with type definitions"
  extends Modelica.Icons.TypesPackage;
  type DistributionType = enumeration(
      HeatingWater
    "Heating water distribution system",
      ChilledWater
    "Chilled water distribution system",
      ChangeOver
    "Change-over distribution system")
    "Enumeration for the type of distribution system"
  type PumpControlType = enumeration(
      ConstantSpeed
    "Constant speed",
      ConstantFlow
    "Constant flow rate (three-way valves)",
      ConstantHead
    "Constant pump head",
      LinearHead
    "Linear relationship between pump head and mass flow rate",
      ConstantDp
    "Constant pressure difference at given location")
    "Enumeration for the type of distribution pump control"
end Types;


Mixing valve controller.

within Buildings.DHC.Loads.BaseClasses.Controls;
block MixingValveControl
  "Mixing valve controller"
  extends Modelica.Blocks.Icons.Block;
  import Type_dis=Buildings.DHC.Loads.BaseClasses.Types.DistributionType
    "Types of distribution system";
  parameter Type_dis typDis=Type_dis.HeatingWater
    "Type of distribution system"
  parameter Real k(
    final min=0,
    final unit="1")=0.1
    "Gain of controller";
  parameter Modelica.Units.SI.Time Ti(final min=Modelica.Constants.small) = 10
    "Time constant of integrator block";
  // IO CONNECTORS
  Modelica.Blocks.Interfaces.RealInput TSupSet(
    final unit="K",
    displayUnit="degC")
    "Supply temperature set point"
  Modelica.Blocks.Interfaces.IntegerInput modChaOve if typDis == Type_dis.ChangeOver
    "Operating mode in change-over (1 for heating, 2 for cooling)"
  Modelica.Blocks.Interfaces.RealInput TSupMes(
    final unit="K",
    displayUnit="degC")
    "Supply temperature (measured)"
  Modelica.Blocks.Interfaces.RealOutput yVal(
    final unit="1")
    "Valve control signal"
  // COMPONENTS
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant zer(
    k=0)
    "Zero constant"
  Modelica.Blocks.Math.IntegerToBoolean toBoo(
    threshold=2) if typDis == Type_dis.ChangeOver
    "Conversion to boolean (true if cooling mode)"
  Buildings.Controls.OBC.CDL.Reals.PIDWithReset resConTSup(
    controllerType=Buildings.Controls.OBC.CDL.Types.SimpleController.PI,
    final k=k,
    final Ti=Ti,
    final yMax=1,
    final yMin=-1,
    final reverseActing=true,
    final y_reset=0) if typDis == Type_dis.ChangeOver
    "PI controller tracking supply temperature"
  Buildings.Controls.OBC.CDL.Reals.PID conTSup(
    controllerType=Buildings.Controls.OBC.CDL.Types.SimpleController.PI,
    final k=k,
    final Ti=Ti,
    final yMax=1,
    final yMin=-1,
    final reverseActing=true) if typDis <> Type_dis.ChangeOver
    "PI controller tracking supply temperature"
  Buildings.Controls.OBC.CDL.Reals.Min negPar
    "Negative part of control signal"
  Buildings.Controls.OBC.CDL.Reals.Max posPar
    "Positive part of control signal"
  Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter opp(k=-1)
    "Opposite value"
  Buildings.Controls.OBC.CDL.Reals.Switch swi
    "Logical switch"
  Modelica.Blocks.Sources.BooleanExpression fixMod(
    final y=typDis == Type_dis.ChilledWater) if typDis <> Type_dis.ChangeOver
    "Fixed operating mode"
  Buildings.Controls.OBC.CDL.Integers.Change cha if typDis == Type_dis.ChangeOver
    "Evaluate the integer input u to check if its value changes"
equation
  connect(modChaOve,toBoo.u)
  connect(toBoo.y,swi.u2)
  connect(fixMod.y,swi.u2)
  connect(resConTSup.y,posPar.u2)
  connect(zer.y,posPar.u1)
  connect(zer.y,negPar.u1)
  connect(resConTSup.y,negPar.u2)
  connect(negPar.y,opp.u)
  connect(resConTSup.u_s,TSupSet)
  connect(TSupMes,resConTSup.u_m)
  connect(swi.y,yVal)
  connect(modChaOve,cha.u)
  connect(cha.y,resConTSup.trigger)
  connect(opp.y,swi.u1)
  connect(posPar.y,swi.u3)
  connect(TSupSet,conTSup.u_s)
  connect(TSupMes,conTSup.u_m)
  connect(conTSup.y,negPar.u2)
  connect(conTSup.y,posPar.u2)
end MixingValveControl;


within Buildings.DHC.Loads.BaseClasses;
package Controls "Package of control sequences for DHC systems"
  extends Modelica.Icons.VariantsPackage;
end Controls;


within Buildings.DHC.Loads.BaseClasses.Controls.Validation;
model MixingValveControl
  "Validation of mixing valve control in change-over mode"
  extends Modelica.Icons.Example;
  package Medium=Buildings.Media.Water
    "Source side medium";
  parameter Modelica.Units.SI.MassFlowRate m_flow_nominal=1
    "Mass flow rate at nominal conditions";
  Buildings.DHC.Loads.BaseClasses.FlowDistribution disFlo(
    redeclare package Medium=Medium,
    m_flow_nominal=m_flow_nominal,
    typDis=Buildings.DHC.Loads.BaseClasses.Types.DistributionType.ChangeOver,
    have_pum=true,
    have_val=true,
    dp_nominal=100000,
    nPorts_a1=1,
    nPorts_b1=1)
    "Secondary distribution system"
  Buildings.Fluid.Sources.Boundary_pT souPri(
    redeclare package Medium=Medium,
    use_T_in=true,
    nPorts=1)
    "Primary supply stream"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant TPriHea(
    k=313.15,
    y(final unit="K",
      displayUnit="degC"))
    "Heating water primary supply temperature"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant TPriChi(
    k=280.15,
    y(final unit="K",
      displayUnit="degC"))
    "Chilled water primary supply temperature"
  Buildings.Controls.OBC.CDL.Reals.Switch TPri(
    y(final unit="K",
      displayUnit="degC"))
    "Actual primary supply temperature"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant TSetSecHea(
    k=303.15,
    y(final unit="K",
      displayUnit="degC"))
    "Heating water secondary supply temperature set point"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant TSetSecChi(
    k=291.15)
    "Chilled water secondary supply temperature set point"
  Buildings.Controls.OBC.CDL.Reals.Switch TSetSecAct(
    y(final unit="K",
      displayUnit="degC"))
    "Actual secondary supply temperature set point"
  Buildings.Fluid.Sources.MassFlowSource_T souSec(
    use_m_flow_in=true,
    redeclare package Medium=Medium,
    use_T_in=true,
    nPorts=1)
    "Secondary return stream"
  Buildings.Fluid.Sources.Boundary_pT sinSec(
    redeclare package Medium=Medium,
    nPorts=1)
    "Sink for secondary stream"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant dTSecHea(
    k=-5)
    "Secondary temperature difference between supply and return"
  Buildings.Fluid.Sensors.TemperatureTwoPort senTSecSup(
    redeclare package Medium=Medium,
    m_flow_nominal=m_flow_nominal)
    "Secondary supply temperature (measured)"
  Buildings.Fluid.Sensors.TemperatureTwoPort senTSecRet(
    redeclare package Medium=Medium,
    m_flow_nominal=m_flow_nominal)
    "Secondary return temperature (measured)"
  Buildings.Fluid.Sources.Boundary_pT sinPri(
    redeclare package Medium=Medium,
    nPorts=1)
    "Sink for primary stream"
  Buildings.Controls.OBC.CDL.Reals.Sources.Pulse mSec_flow(
    amplitude=m_flow_nominal,
    period=200,
    offset=0)
    "Secondary mass flow rate"
  Buildings.Controls.OBC.CDL.Reals.Add add
    "Computation of secondary return temperature"
  Buildings.Fluid.Sensors.TemperatureTwoPort senTPriSup(
    redeclare package Medium=Medium,
    m_flow_nominal=m_flow_nominal)
    "Primary supply temperature (measured)"
  Buildings.Controls.OBC.CDL.Reals.Switch dTSec(
    y(final unit="K",
      displayUnit="degC"))
    "Actual secondary delta T"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant dTSecCoo(
    k=5)
    "Secondary temperature difference between supply and return"
  Buildings.Controls.OBC.CDL.Conversions.BooleanToInteger modInd(
    final integerTrue=1,
    final integerFalse=2)
    "Mode index, 1 for heating, 2 for cooling"
  Buildings.Controls.OBC.CDL.Logical.Sources.Pulse modCha(
    period=1000)
    "Boolean pulse for changing mode"
  Buildings.Controls.OBC.CDL.Logical.Not mod
    "Operating mode, true for heating, false for cooling"
equation
  connect(TPri.y,souPri.T_in)
  connect(TSetSecAct.y,disFlo.TSupSet)
  connect(disFlo.ports_b1[1],senTSecSup.port_a)
  connect(souSec.ports[1],senTSecRet.port_a)
  connect(senTSecRet.port_b,disFlo.ports_a1[1])
  connect(disFlo.port_b,sinPri.ports[1])
  connect(senTSecSup.port_b,sinSec.ports[1])
  connect(mSec_flow.y,disFlo.mReq_flow[1])
  connect(mSec_flow.y,souSec.m_flow_in)
  connect(add.y,souSec.T_in)
  connect(souPri.ports[1],senTPriSup.port_a)
  connect(senTPriSup.port_b,disFlo.port_a)
  connect(TSetSecChi.y,TSetSecAct.u3)
  connect(TSetSecHea.y,TSetSecAct.u1)
  connect(TPriChi.y,TPri.u3)
  connect(TPriHea.y,TPri.u1)
  connect(TSetSecAct.y,add.u1)
  connect(dTSec.y,add.u2)
  connect(dTSecHea.y,dTSec.u1)
  connect(dTSecCoo.y,dTSec.u3)
  connect(modCha.y,mod.u)
  connect(mod.y,TPri.u2)
  connect(mod.y,TSetSecAct.u2)
  connect(mod.y,modInd.u)
  connect(modInd.y,disFlo.modChaOve)
  connect(mod.y,dTSec.u2)
end MixingValveControl;


Collection of validation models

within Buildings.DHC.Loads.BaseClasses.Controls;
package Validation "Collection of validation models"
  extends Modelica.Icons.ExamplesPackage;
end Validation;


within Buildings.DHC.Loads.BaseClasses.Examples;
model CouplingRCZ1Valve
  "Example illustrating the coupling of a building model to heating water and chilled water loops"
  extends Modelica.Icons.Example;
  Buildings.BoundaryConditions.WeatherData.ReaderTMY3 weaDat(
    calTSky=Buildings.BoundaryConditions.Types.SkyTemperatureCalculation.HorizontalRadiation,
    computeWetBulbTemperature=false,
    filNam=Modelica.Utilities.Files.loadResource(
      "modelica://Buildings/Resources/weatherdata/USA_CA_San.Francisco.Intl.AP.724940_TMY3.mos"))
    "Weather data reader"
  package Medium1=Buildings.Media.Water
    "Source side medium";
  Buildings.DHC.Loads.BaseClasses.BuildingRCZ1Valve bui(
    nPorts_aHeaWat=1,
    nPorts_aChiWat=1,
    nPorts_bHeaWat=1,
    nPorts_bChiWat=1)
    "Building"
  Buildings.Fluid.Sources.Boundary_pT sinHeaWat(
    redeclare final package Medium=Medium1,
    nPorts=1)
    "Sink for heating water"
  Modelica.Blocks.Sources.RealExpression THeaWatSup(
    y=bui.terUni.T_aHeaWat_nominal)
    "Heating water supply temperature"
  Modelica.Blocks.Sources.RealExpression TChiWatSup(
    y=bui.terUni.T_aChiWat_nominal)
    "Chilled water supply temperature"
  Buildings.Fluid.Sources.Boundary_pT sinChiWat(
    redeclare final package Medium=Medium1,
    nPorts=1)
    "Sink for chilled water"
  Buildings.Fluid.Sources.Boundary_pT supHeaWat(
    redeclare package Medium=Medium1,
    use_T_in=true,
    nPorts=1)
    "Heating water supply"
  Buildings.Fluid.Sources.Boundary_pT supChiWat(
    redeclare package Medium=Medium1,
    use_T_in=true,
    nPorts=1)
    "Chilled water supply"
equation
  connect(weaDat.weaBus,bui.weaBus)
  connect(supHeaWat.T_in,THeaWatSup.y)
  connect(TChiWatSup.y,supChiWat.T_in)
  connect(supHeaWat.ports[1],bui.ports_aHeaWat[1])
  connect(supChiWat.ports[1],bui.ports_aChiWat[1])
  connect(bui.ports_bHeaWat[1],sinHeaWat.ports[1])
  connect(bui.ports_bChiWat[1],sinChiWat.ports[1])
end CouplingRCZ1Valve;


within Buildings.DHC.Loads.BaseClasses.Examples;
model CouplingRCZ6
  "Example illustrating the coupling of a building model to heating water and chilled water loops"
  extends Modelica.Icons.Example;
  package Medium1=Buildings.Media.Water
    "Fluid in the pipes";
  Buildings.BoundaryConditions.WeatherData.ReaderTMY3 weaDat(
    calTSky=Buildings.BoundaryConditions.Types.SkyTemperatureCalculation.HorizontalRadiation,
    computeWetBulbTemperature=false,
    filNam=Modelica.Utilities.Files.loadResource(
      "modelica://Buildings/Resources/weatherdata/USA_CA_San.Francisco.Intl.AP.724940_TMY3.mos"))
    "Weather data reader"
  Buildings.DHC.Loads.BaseClasses.BuildingRCZ6 bui(
    nPorts_aHeaWat=1,
    nPorts_aChiWat=1,
    nPorts_bHeaWat=1,
    nPorts_bChiWat=1)
    "Building"
  Buildings.Fluid.Sources.Boundary_pT sinHeaWat(
    redeclare final package Medium=Medium1,
    nPorts=1)
    "Sink for heating water"
  Buildings.Fluid.Sources.Boundary_pT sinChilWat(
    redeclare final package Medium=Medium1,
    nPorts=1)
    "Sink for chilled water"
  Modelica.Blocks.Sources.RealExpression THeaWatSup(
    y=max(
      bui.terUni.T_aHeaWat_nominal))
    "Heating water supply temperature"
  Modelica.Blocks.Sources.RealExpression TChiWatSup(
    y=min(
      bui.terUni.T_aChiWat_nominal))
    "Chilled water supply temperature"
  Fluid.Sources.Boundary_pT supHeaWat(
    redeclare package Medium=Medium1,
    use_T_in=true,
    nPorts=1)
    "Heating water supply"
  Fluid.Sources.Boundary_pT supChiWat(
    redeclare package Medium=Medium1,
    use_T_in=true,
    nPorts=1)
    "Chilled water supply"
equation
  connect(weaDat.weaBus,bui.weaBus)
  connect(supHeaWat.T_in,THeaWatSup.y)
  connect(TChiWatSup.y,supChiWat.T_in)
  connect(supHeaWat.ports[1],bui.ports_aHeaWat[1])
  connect(supChiWat.ports[1],bui.ports_aChiWat[1])
  connect(bui.ports_bHeaWat[1],sinHeaWat.ports[1])
  connect(bui.ports_bChiWat[1],sinChilWat.ports[1])
end CouplingRCZ6;


within Buildings.DHC.Loads.BaseClasses.Examples;
model CouplingSpawnZ1
  "Example illustrating the coupling of a building model to heating water and chilled water loops"
  extends Modelica.Icons.Example;
  package Medium1=Buildings.Media.Water
    "Source side medium";
  Buildings.DHC.Loads.BaseClasses.BuildingSpawnZ1 bui(
    nPorts_aHeaWat=1,
    nPorts_aChiWat=1,
    nPorts_bHeaWat=1,
    nPorts_bChiWat=1)
    "Building"
  Buildings.Fluid.Sources.MassFlowSource_T supHeaWat(
    use_m_flow_in=true,
    redeclare final package Medium=Medium1,
    use_T_in=true,
    nPorts=1)
    "Heating water supply"
  Modelica.Blocks.Sources.RealExpression THeaWatSup(
    y=bui.terUni.T_aHeaWat_nominal)
    "Heating water supply temperature"
  Modelica.Blocks.Sources.RealExpression mHeaWat_flow(
    y=bui.disFloHea.mReqTot_flow)
    "Heating water flow rate"
  Buildings.Fluid.Sources.MassFlowSource_T supChiWat(
    use_m_flow_in=true,
    redeclare final package Medium=Medium1,
    use_T_in=true,
    nPorts=1)
    "Chilled water supply"
  Modelica.Blocks.Sources.RealExpression TChiWatSup(
    y=bui.terUni.T_aChiWat_nominal)
    "Chilled water supply temperature"
  Modelica.Blocks.Sources.RealExpression mChiWat_flow(
    y=bui.disFloCoo.mReqTot_flow)
    "Chilled water flow rate"
  Buildings.Fluid.Sources.Boundary_pT sinHeaWat(
    redeclare package Medium=Medium1,
    nPorts=1)
    "Sink for heating water"
  Buildings.Fluid.Sources.Boundary_pT sinChiWat(
    redeclare package Medium=Medium1,
    nPorts=1)
    "Sink for chilled water"
equation
  connect(THeaWatSup.y,supHeaWat.T_in)
  connect(mHeaWat_flow.y,supHeaWat.m_flow_in)
  connect(TChiWatSup.y,supChiWat.T_in)
  connect(mChiWat_flow.y,supChiWat.m_flow_in)
  connect(supHeaWat.ports[1],bui.ports_aHeaWat[1])
  connect(supChiWat.ports[1],bui.ports_aChiWat[1])
  connect(bui.ports_bHeaWat[1],sinHeaWat.ports[1])
  connect(bui.ports_bChiWat[1],sinChiWat.ports[1])
end CouplingSpawnZ1;


within Buildings.DHC.Loads.BaseClasses.Examples;
model CouplingSpawnZ6
  "Example illustrating the coupling of a building model to heating water and chilled water loops"
  extends Modelica.Icons.Example;
  package Medium1=Buildings.Media.Water
    "Source side medium";
  Buildings.DHC.Loads.BaseClasses.BuildingSpawnZ6 bui(
    nPorts_aHeaWat=1,
    nPorts_aChiWat=1,
    nPorts_bHeaWat=1,
    nPorts_bChiWat=1)
    "Building"
  Buildings.Fluid.Sources.Boundary_pT sinHeaWat(
    redeclare final package Medium=Medium1,
    nPorts=1)
    "Sink for heating water"
  Buildings.Fluid.Sources.Boundary_pT sinChiWat(
    redeclare final package Medium=Medium1,
    nPorts=1)
    "Sink for chilled water"
  Modelica.Blocks.Sources.RealExpression THeaWatSup(
    y=max(
      bui.terUni.T_aHeaWat_nominal))
    "Heating water supply temperature"
  Modelica.Blocks.Sources.RealExpression TChiWatSup(
    y=min(
      bui.terUni.T_aChiWat_nominal))
    "Chilled water supply temperature"
  Fluid.Sources.Boundary_pT supHeaWat(
    redeclare final package Medium=Medium1,
    use_T_in=true,
    nPorts=1)
    "Heating water supply"
  Fluid.Sources.Boundary_pT supChiWat(
    redeclare final package Medium=Medium1,
    use_T_in=true,
    nPorts=1)
    "Chilled water supply"
equation
  connect(supHeaWat.T_in,THeaWatSup.y)
  connect(TChiWatSup.y,supChiWat.T_in)
  connect(supHeaWat.ports[1],bui.ports_aHeaWat[1])
  connect(supChiWat.ports[1],bui.ports_aChiWat[1])
  connect(bui.ports_bHeaWat[1],sinHeaWat.ports[1])
  connect(sinChiWat.ports[1],bui.ports_bChiWat[1])
end CouplingSpawnZ6;


within Buildings.DHC.Loads.BaseClasses.Examples;
model CouplingTimeSeries
  "Example illustrating the coupling of a building model to heating water and chilled water loops"
  extends Modelica.Icons.Example;
  package Medium1=Buildings.Media.Water
    "Source side medium";
  parameter Modelica.Units.SI.Time perAve=600
    "Period for time averaged variables";
  Buildings.DHC.Loads.BaseClasses.BuildingTimeSeries bui(
    filNam="modelica://Buildings/Resources/Data/DHC/Loads/Examples/SwissResidential_20190916.mos",
    nPorts_aHeaWat=1,
    nPorts_aChiWat=1,
    nPorts_bHeaWat=1,
    nPorts_bChiWat=1)
    "Building"
  Buildings.Fluid.Sources.Boundary_pT sinHeaWat(
    redeclare package Medium=Medium1,
    nPorts=1)
    "Sink for heating water"
  Buildings.Fluid.Sources.Boundary_pT sinChiWat(
    redeclare package Medium=Medium1,
    nPorts=1)
    "Sink for chilled water"
  Modelica.Blocks.Sources.RealExpression THeaWatSup(
    y=bui.T_aHeaWat_nominal)
    "Heating water supply temperature"
  Modelica.Blocks.Sources.RealExpression TChiWatSup(
    y=bui.T_aChiWat_nominal)
    "Chilled water supply temperature"
  Fluid.Sources.Boundary_pT supHeaWat(
    redeclare package Medium=Medium1,
    use_T_in=true,
    nPorts=1)
    "Heating water supply"
  Fluid.Sources.Boundary_pT supChiWat(
    redeclare package Medium=Medium1,
    use_T_in=true,
    nPorts=1)
    "Chilled water supply"
  Modelica.Blocks.Continuous.Integrator EHeaReq(
    y(unit="J"))
    "Time integral of heating load"
  Modelica.Blocks.Continuous.Integrator EHeaAct(
    y(unit="J"))
    "Actual energy used for heating"
  Modelica.Blocks.Continuous.Integrator ECooReq(
    y(unit="J"))
    "Time integral of cooling load"
  Modelica.Blocks.Continuous.Integrator ECooAct(
    y(unit="J"))
    "Actual energy used for cooling"
  Buildings.Controls.OBC.CDL.Reals.MovingAverage QAveHeaReq_flow(y(unit=
          "W"), final delta=perAve) "Time average of heating load"
  Buildings.Controls.OBC.CDL.Reals.MovingAverage QAveHeaAct_flow(y(unit=
          "W"), final delta=perAve) "Time average of heating heat flow rate"
  Buildings.Controls.OBC.CDL.Reals.MovingAverage QAveCooReq_flow(y(unit=
          "W"), final delta=perAve) "Time average of cooling load"
  Buildings.Controls.OBC.CDL.Reals.MovingAverage QAveCooAct_flow(y(unit=
          "W"), final delta=perAve) "Time average of cooling heat flow rate"
equation
  connect(supHeaWat.T_in,THeaWatSup.y)
  connect(TChiWatSup.y,supChiWat.T_in)
  connect(supHeaWat.ports[1],bui.ports_aHeaWat[1])
  connect(supChiWat.ports[1],bui.ports_aChiWat[1])
  connect(bui.ports_bHeaWat[1],sinHeaWat.ports[1])
  connect(sinChiWat.ports[1],bui.ports_bChiWat[1])
  connect(bui.QHea_flow,EHeaAct.u)
  connect(bui.QReqHea_flow,EHeaReq.u)
  connect(bui.QReqCoo_flow,ECooReq.u)
  connect(bui.QCoo_flow,ECooAct.u)
  connect(bui.QReqHea_flow,QAveHeaReq_flow.u)
  connect(bui.QHea_flow,QAveHeaAct_flow.u)
  connect(bui.QReqCoo_flow,QAveCooReq_flow.u)
  connect(bui.QCoo_flow,QAveCooAct_flow.u)
end CouplingTimeSeries;


within Buildings.DHC.Loads.BaseClasses.Examples;
model CouplingTimeSeriesSingleLoop
  "Example illustrating the coupling of a building model to heating water or chilled water loops"
  extends Modelica.Icons.Example;
  package Medium1=Buildings.Media.Water
    "Source side medium";
  parameter Modelica.Units.SI.Time perAve=600
    "Period for time averaged variables";
  Buildings.DHC.Loads.BaseClasses.BuildingTimeSeries buiCoo(
    have_heaWat=false,
    filNam="modelica://Buildings/Resources/Data/DHC/Loads/Examples/SwissResidential_20190916.mos",
    nPorts_aChiWat=1,
    nPorts_bChiWat=1)
    "Building wint cooling only"
  Buildings.Fluid.Sources.Boundary_pT sinChiWat(
    redeclare package Medium=Medium1,
    nPorts=1)
    "Sink for chilled water"
  Modelica.Blocks.Sources.RealExpression TChiWatSup(
    y=buiCoo.T_aChiWat_nominal)
    "Chilled water supply temperature"
  Fluid.Sources.Boundary_pT supChiWat(
    redeclare package Medium=Medium1,
    use_T_in=true,
    nPorts=1)
    "Chilled water supply"
  Modelica.Blocks.Continuous.Integrator ECooReq(
    y(unit="J"))
    "Time integral of cooling load"
  Buildings.Controls.OBC.CDL.Reals.MovingAverage QAveCooReq_flow(y(unit=
          "W"), final delta=perAve) "Time average of cooling load"
  Buildings.Controls.OBC.CDL.Reals.MovingAverage QAveCooAct_flow(y(unit=
          "W"), final delta=perAve) "Time average of cooling heat flow rate"
  Modelica.Blocks.Continuous.Integrator ECooAct(
    y(unit="J"))
    "Actual energy used for cooling"
  Buildings.DHC.Loads.BaseClasses.BuildingTimeSeries buiHea(
    have_chiWat=false,
    filNam="modelica://Buildings/Resources/Data/DHC/Loads/Examples/SwissResidential_20190916.mos",
    nPorts_aChiWat=1,
    nPorts_bChiWat=1,
    nPorts_aHeaWat=1,
    nPorts_bHeaWat=1)
    "Building with heating only"
  Modelica.Blocks.Sources.RealExpression THeaWatSup(
    y=buiHea.T_aHeaWat_nominal)
    "Heating water supply temperature"
  Fluid.Sources.Boundary_pT supHeaWat(
    redeclare package Medium=Medium1,
    use_T_in=true,
    nPorts=1)
    "Heating water supply"
  Fluid.Sources.Boundary_pT sinHeaWat(
    redeclare package Medium=Medium1,
    nPorts=1)
    "Sink for heating water"
  Buildings.Controls.OBC.CDL.Reals.MovingAverage QAveHeaReq_flow(y(unit=
          "W"), final delta=perAve) "Time average of heating load"
  Modelica.Blocks.Continuous.Integrator EHeaReq(
    y(unit="J"))
    "Time integral of heating load"
  Modelica.Blocks.Continuous.Integrator EHeaAct(
    y(unit="J"))
    "Actual energy used for heating"
  Buildings.Controls.OBC.CDL.Reals.MovingAverage QAveHeaAct_flow(y(unit=
          "W"), final delta=perAve) "Time average of heating heat flow rate"
equation
  connect(TChiWatSup.y,supChiWat.T_in)
  connect(supChiWat.ports[1],buiCoo.ports_aChiWat[1])
  connect(sinChiWat.ports[1],buiCoo.ports_bChiWat[1])
  connect(buiCoo.QReqCoo_flow,ECooReq.u)
  connect(buiCoo.QReqCoo_flow,QAveCooReq_flow.u)
  connect(buiCoo.QCoo_flow,ECooAct.u)
  connect(buiCoo.QCoo_flow,QAveCooAct_flow.u)
  connect(THeaWatSup.y,supHeaWat.T_in)
  connect(supHeaWat.ports[1],buiHea.ports_aHeaWat[1])
  connect(buiHea.ports_bHeaWat[1],sinHeaWat.ports[1])
  connect(buiHea.QReqHea_flow,EHeaReq.u)
  connect(buiHea.QReqHea_flow,QAveHeaReq_flow.u)
  connect(buiHea.QHea_flow,EHeaAct.u)
  connect(buiHea.QHea_flow,QAveHeaAct_flow.u)
end CouplingTimeSeriesSingleLoop;


within Buildings.DHC.Loads.BaseClasses;
package Examples "Example models integrating multiple components"
  extends Modelica.Icons.ExamplesPackage;
end Examples;


Package with base classes

within Buildings.DHC.Loads.BaseClasses.Examples;
package BaseClasses "Package with base classes"
  extends Modelica.Icons.BasesPackage;
end BaseClasses;


Package with RC building zone models

within Buildings.DHC.Loads.BaseClasses.Examples.BaseClasses;
package GeojsonExportRC "Package with RC building zone models"
  extends Modelica.Icons.Package;
end GeojsonExportRC;


within Buildings.DHC.Loads.BaseClasses.Examples.BaseClasses.GeojsonExportRC.OfficeBuilding;
model Floor
  "This is the simulation model of Floor within building OfficeBuilding"
  Buildings.BoundaryConditions.SolarIrradiation.DiffusePerez HDifTil[6](
    each outSkyCon=true,
    each outGroCon=true,
    til={1.5707963267949,1.5707963267949,1.5707963267949,1.5707963267949,0,0},
    azi={3.1415926535898,0,1.5707963267949,-1.5707963267949,0,0})
    "Calculates diffuse solar radiation on titled surface for all directions"
  Buildings.BoundaryConditions.SolarIrradiation.DirectTiltedSurface HDirTil[6](til={
        1.5707963267949,1.5707963267949,1.5707963267949,1.5707963267949,0,0},
      azi={3.1415926535898,0,1.5707963267949,-1.5707963267949,0,0})
    "Calculates direct solar radiation on titled surface for all directions"
  Buildings.ThermalZones.ReducedOrder.SolarGain.CorrectionGDoublePane corGDoublePane(
    n=6,
    UWin=1.8936557576825381)
    "Correction factor for solar transmission"
  Buildings.ThermalZones.ReducedOrder.RC.TwoElements thermalZoneTwoElements(
    redeclare package Medium=Buildings.Media.Air,
    VAir=3261.7921338576007,
    hConExt=2.0490178828959134,
    hConWin=2.7000000000000006,
    gWin=0.6699999999999999,
    ratioWinConRad=0.029999999999999995,
    nExt=1,
    RExt={2.3174831586466932e-05},
    CExt={408244783.5430907},
    hRad=5.0,
    AInt=5119.003369012401,
    hConInt=2.3902922093005254,
    nInt=1,
    RInt={1.3425684356446266e-05},
    CInt={573809361.8851968},
    RWin=0.002198739011727672,
    RExtRem=0.0012526070384860479,
    energyDynamics=Modelica.Fluid.Types.Dynamics.FixedInitial,
    extWallRC(
      thermCapExt(
        each der_T(
          fixed=true))),
    intWallRC(
      thermCapInt(
        each der_T(
          fixed=true))),
    nOrientations=6,
    AWin={74.54769655777831,74.54769655777831,6.910119334253305,6.910119334253305,0.0,0.0},
    ATransparent={74.54769655777831,74.54769655777831,6.910119334253305,6.910119334253305,0.0,0.0},
    AExt={223.64308967333497,223.64308967333497,20.730358002759914,20.730358002759914,455.8011269000001,455.8011269000001})
    "Thermal zone"
  Buildings.ThermalZones.ReducedOrder.EquivalentAirTemperature.VDI6007WithWindow eqAirTemp(
    n=6,
    wfGro=0.3626976838332763,
    wfWall={0.15582361279765053,0.15582361279765053,0.014443903825944522,0.014443903825944522,0.2967672829195336,0.0},
    wfWin={0.4575846758314001,0.4575846758314001,0.04241532416859994,0.04241532416859994,0.0,0.0},
    withLongwave=true,
    aExt=0.5,
    hConWallOut=20.0,
    hRad=5.0,
    hConWinOut=20.0,
    TGro=286.15)
    "Computes equivalent air temperature"
  Modelica.Blocks.Math.Add solRad[6]
    "Sums up solar radiation of both directions"
  Modelica.Thermal.HeatTransfer.Sources.PrescribedTemperature prescribedTemperature
    "Prescribed temperature for exterior walls outdoor surface temperature"
  Modelica.Thermal.HeatTransfer.Sources.PrescribedTemperature prescribedTemperature1
    "Prescribed temperature for windows outdoor surface temperature"
  Modelica.Thermal.HeatTransfer.Components.Convection thermalConductorWin
    "Outdoor convective heat transfer of windows"
  Modelica.Thermal.HeatTransfer.Components.Convection thermalConductorWall
    "Outdoor convective heat transfer of walls"
  Modelica.Blocks.Sources.Constant const[6](
    each k=0)
    "Sets sunblind signal to zero (open)"
  Buildings.BoundaryConditions.WeatherData.Bus weaBus
    "Weather data bus"
  Modelica.Blocks.Sources.Constant hConWall(
    k=25.0*1400.34914915219)
    "Outdoor coefficient of heat transfer for walls"
  Modelica.Blocks.Sources.Constant hConWin(
    k=25.0*162.91563178406324)
    "Outdoor coefficient of heat transfer for windows"
  Modelica.Thermal.HeatTransfer.Sources.PrescribedHeatFlow personsRad
    "Radiative heat flow of persons"
  Modelica.Thermal.HeatTransfer.Sources.PrescribedHeatFlow personsConv
    "Convective heat flow of persons"
  Modelica.Thermal.HeatTransfer.Sources.PrescribedHeatFlow machinesConv
    "Convective heat flow of machines"
  Modelica.Blocks.Sources.CombiTimeTable internalGains(
    tableOnFile=true,
    extrapolation=Modelica.Blocks.Types.Extrapolation.Periodic,
    tableName="Internals",
    fileName=Modelica.Utilities.Files.loadResource(
      "modelica://Buildings/Resources/Data/DHC/Loads/Examples/BaseClasses/GeojsonExportRC/OfficeBuilding/InternalGains_Floor.txt"),
    columns={2,3,4})
    "Table with profiles for persons (radiative and convective) and machines (convective)"
  Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a port_a
    "Heat port for sensible convective gains"
  Buildings.Controls.OBC.CDL.Interfaces.RealOutput TAir(
    quantity="ThermodynamicTemperature",
    unit="K",
    displayUnit="degC")
    "Room air temperature"
equation
  connect(eqAirTemp.TEqAirWin,prescribedTemperature1.T)
  connect(eqAirTemp.TEqAir,prescribedTemperature.T)
  connect(weaBus.TDryBul,eqAirTemp.TDryBul)
  connect(internalGains.y[1],personsRad.Q_flow)
  connect(internalGains.y[2],personsConv.Q_flow)
  connect(internalGains.y[3],machinesConv.Q_flow)
  connect(const.y,eqAirTemp.sunblind)
  connect(HDifTil.HSkyDifTil,corGDoublePane.HSkyDifTil)
  connect(HDirTil.H,corGDoublePane.HDirTil)
  connect(HDirTil.H,solRad.u1)
  connect(HDirTil.inc,corGDoublePane.inc)
  connect(HDifTil.H,solRad.u2)
  connect(HDifTil.HGroDifTil,corGDoublePane.HGroDifTil)
  connect(solRad.y,eqAirTemp.HSol)
  connect(weaBus,HDifTil[1].weaBus)
  connect(weaBus,HDirTil[1].weaBus)
  connect(weaBus,HDifTil[2].weaBus)
  connect(weaBus,HDirTil[2].weaBus)
  connect(weaBus,HDifTil[3].weaBus)
  connect(weaBus,HDirTil[3].weaBus)
  connect(weaBus,HDifTil[4].weaBus)
  connect(weaBus,HDirTil[4].weaBus)
  connect(weaBus,HDifTil[5].weaBus)
  connect(weaBus,HDirTil[5].weaBus)
  connect(weaBus,HDifTil[6].weaBus)
  connect(weaBus,HDirTil[6].weaBus)
  connect(personsRad.port,thermalZoneTwoElements.intGainsRad)
  connect(thermalConductorWin.solid,thermalZoneTwoElements.window)
  connect(prescribedTemperature1.port,thermalConductorWin.fluid)
  connect(thermalZoneTwoElements.extWall,thermalConductorWall.solid)
  connect(thermalConductorWall.fluid,prescribedTemperature.port)
  connect(hConWall.y,thermalConductorWall.Gc)
  connect(hConWin.y,thermalConductorWin.Gc)
  connect(weaBus.TBlaSky,eqAirTemp.TBlaSky)
  connect(machinesConv.port,thermalZoneTwoElements.intGainsConv)
  connect(personsConv.port,thermalZoneTwoElements.intGainsConv)
  connect(corGDoublePane.solarRadWinTrans,thermalZoneTwoElements.solRad)
  connect(port_a,thermalZoneTwoElements.intGainsConv)
  connect(thermalZoneTwoElements.TAir,TAir)
end Floor;


within Buildings.DHC.Loads.BaseClasses.Examples.BaseClasses.GeojsonExportRC.OfficeBuilding;
model ICT
  "This is the simulation model of ICT within building OfficeBuilding"
  Buildings.BoundaryConditions.SolarIrradiation.DiffusePerez HDifTil[6](
    each outSkyCon=true,
    each outGroCon=true,
    til={1.5707963267949,1.5707963267949,1.5707963267949,1.5707963267949,0,0},
    azi={3.1415926535898,0,1.5707963267949,-1.5707963267949,0,0})
    "Calculates diffuse solar radiation on titled surface for all directions"
  Buildings.BoundaryConditions.SolarIrradiation.DirectTiltedSurface HDirTil[6](til={
        1.5707963267949,1.5707963267949,1.5707963267949,1.5707963267949,0,0},
      azi={3.1415926535898,0,1.5707963267949,-1.5707963267949,0,0})
    "Calculates direct solar radiation on titled surface for all directions"
  Buildings.ThermalZones.ReducedOrder.SolarGain.CorrectionGDoublePane corGDoublePane(
    n=6,
    UWin=1.8936557576825384)
    "Correction factor for solar transmission"
  Buildings.ThermalZones.ReducedOrder.RC.TwoElements thermalZoneTwoElements(
    redeclare package Medium=Buildings.Media.Air,
    VAir=260.9433707086081,
    hConExt=2.0490178828959125,
    hConWin=2.7000000000000006,
    gWin=0.6700000000000002,
    ratioWinConRad=0.030000000000000002,
    nExt=1,
    RExt={0.00028968539483083646},
    CExt={32659582.683447275},
    hRad=5.000000000000001,
    AInt=257.303303274304,
    hConInt=2.207073495341845,
    nInt=1,
    RInt={0.0002111894006425288},
    CInt={37115084.57178593},
    RWin=0.027484237646595907,
    RExtRem=0.015657587981075596,
    energyDynamics=Modelica.Fluid.Types.Dynamics.FixedInitial,
    extWallRC(
      thermCapExt(
        each der_T(
          fixed=true))),
    intWallRC(
      thermCapInt(
        each der_T(
          fixed=true))),
    nOrientations=6,
    AWin={5.963815724622265,5.963815724622265,0.5528095467402644,0.5528095467402644,0.0,0.0},
    ATransparent={5.963815724622265,5.963815724622265,0.5528095467402644,0.5528095467402644,0.0,0.0},
    AExt={17.891447173866798,17.891447173866798,1.658428640220793,1.658428640220793,36.46409015200001,36.46409015200001})
    "Thermal zone"
  Buildings.ThermalZones.ReducedOrder.EquivalentAirTemperature.VDI6007WithWindow eqAirTemp(
    n=6,
    wfGro=0.3626976838332763,
    wfWall={0.15582361279765056,0.15582361279765056,0.014443903825944524,0.014443903825944524,0.2967672829195336,0.0},
    wfWin={0.45758467583140006,0.45758467583140006,0.04241532416859994,0.04241532416859994,0.0,0.0},
    withLongwave=true,
    aExt=0.5,
    hConWallOut=20.0,
    hRad=5.0,
    hConWinOut=20.0,
    TGro=286.15)
    "Computes equivalent air temperature"
  Modelica.Blocks.Math.Add solRad[6]
    "Sums up solar radiation of both directions"
  Modelica.Thermal.HeatTransfer.Sources.PrescribedTemperature prescribedTemperature
    "Prescribed temperature for exterior walls outdoor surface temperature"
  Modelica.Thermal.HeatTransfer.Sources.PrescribedTemperature prescribedTemperature1
    "Prescribed temperature for windows outdoor surface temperature"
  Modelica.Thermal.HeatTransfer.Components.Convection thermalConductorWin
    "Outdoor convective heat transfer of windows"
  Modelica.Thermal.HeatTransfer.Components.Convection thermalConductorWall
    "Outdoor convective heat transfer of walls"
  Modelica.Blocks.Sources.Constant const[6](
    each k=0)
    "Sets sunblind signal to zero (open)"
  Buildings.BoundaryConditions.WeatherData.Bus weaBus
    "Weather data bus"
  Modelica.Blocks.Sources.Constant hConWall(
    k=25.000000000000004*112.0279319321752)
    "Outdoor coefficient of heat transfer for walls"
  Modelica.Blocks.Sources.Constant hConWin(
    k=24.999999999999996*13.033250542725057)
    "Outdoor coefficient of heat transfer for windows"
  Modelica.Thermal.HeatTransfer.Sources.PrescribedHeatFlow personsRad
    "Radiative heat flow of persons"
  Modelica.Thermal.HeatTransfer.Sources.PrescribedHeatFlow personsConv
    "Convective heat flow of persons"
  Modelica.Thermal.HeatTransfer.Sources.PrescribedHeatFlow machinesConv
    "Convective heat flow of machines"
  Modelica.Blocks.Sources.CombiTimeTable internalGains(
    tableOnFile=true,
    extrapolation=Modelica.Blocks.Types.Extrapolation.Periodic,
    tableName="Internals",
    fileName=Modelica.Utilities.Files.loadResource(
      "modelica://Buildings/Resources/Data/DHC/Loads/Examples/BaseClasses/GeojsonExportRC/OfficeBuilding/InternalGains_ICT.txt"),
    columns={2,3,4})
    "Table with profiles for persons (radiative and convective) and machines (convective)"
  Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a port_a
    "Heat port for sensible convective gains"
  Buildings.Controls.OBC.CDL.Interfaces.RealOutput TAir(
    quantity="ThermodynamicTemperature",
    unit="K",
    displayUnit="degC")
    "Room air temperature"
equation
  connect(eqAirTemp.TEqAirWin,prescribedTemperature1.T)
  connect(eqAirTemp.TEqAir,prescribedTemperature.T)
  connect(weaBus.TDryBul,eqAirTemp.TDryBul)
  connect(internalGains.y[1],personsRad.Q_flow)
  connect(internalGains.y[2],personsConv.Q_flow)
  connect(internalGains.y[3],machinesConv.Q_flow)
  connect(const.y,eqAirTemp.sunblind)
  connect(HDifTil.HSkyDifTil,corGDoublePane.HSkyDifTil)
  connect(HDirTil.H,corGDoublePane.HDirTil)
  connect(HDirTil.H,solRad.u1)
  connect(HDirTil.inc,corGDoublePane.inc)
  connect(HDifTil.H,solRad.u2)
  connect(HDifTil.HGroDifTil,corGDoublePane.HGroDifTil)
  connect(solRad.y,eqAirTemp.HSol)
  connect(weaBus,HDifTil[1].weaBus)
  connect(weaBus,HDirTil[1].weaBus)
  connect(weaBus,HDifTil[2].weaBus)
  connect(weaBus,HDirTil[2].weaBus)
  connect(weaBus,HDifTil[3].weaBus)
  connect(weaBus,HDirTil[3].weaBus)
  connect(weaBus,HDifTil[4].weaBus)
  connect(weaBus,HDirTil[4].weaBus)
  connect(weaBus,HDifTil[5].weaBus)
  connect(weaBus,HDirTil[5].weaBus)
  connect(weaBus,HDifTil[6].weaBus)
  connect(weaBus,HDirTil[6].weaBus)
  connect(personsRad.port,thermalZoneTwoElements.intGainsRad)
  connect(thermalConductorWin.solid,thermalZoneTwoElements.window)
  connect(prescribedTemperature1.port,thermalConductorWin.fluid)
  connect(thermalZoneTwoElements.extWall,thermalConductorWall.solid)
  connect(thermalConductorWall.fluid,prescribedTemperature.port)
  connect(hConWall.y,thermalConductorWall.Gc)
  connect(hConWin.y,thermalConductorWin.Gc)
  connect(weaBus.TBlaSky,eqAirTemp.TBlaSky)
  connect(machinesConv.port,thermalZoneTwoElements.intGainsConv)
  connect(personsConv.port,thermalZoneTwoElements.intGainsConv)
  connect(corGDoublePane.solarRadWinTrans,thermalZoneTwoElements.solRad)
  connect(port_a,thermalZoneTwoElements.intGainsConv)
  connect(thermalZoneTwoElements.TAir,TAir)
end ICT;