within Buildings.Fluid.Storage.Validation;
model HeatExchangerLocation
  "Test model for heat exchanger with hHex_a and hHex_b interchanged"
  extends Modelica.Icons.Example;

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

  parameter Modelica.Units.SI.HeatFlowRate QHex_flow_nominal=6000
    "Design heat flow rate of heat exchanger";
  parameter Modelica.Units.SI.MassFlowRate m_flow_nominal=QHex_flow_nominal/
      4200/4;

  Buildings.Fluid.Sources.Boundary_pT watInTan(
    redeclare package Medium = Medium,
    use_T_in=false,
    nPorts=2,
    T=273.15 + 30,
    p(displayUnit="Pa")) "Boundary condition for water in the tank"
  Buildings.Fluid.Sources.MassFlowSource_T mHex_flow1(
    redeclare package Medium = Medium,
    nPorts=2,
    m_flow=m_flow_nominal/100,
    T=273.15 + 60) "Mass flow rate through the heat exchanger"
  model Tank = StratifiedEnhancedInternalHex (
    redeclare final package Medium = Medium,
    redeclare final package MediumHex = Medium,
    final VTan=0.3,
    final kIns=0.034,
    final dIns=0.04,
    final hTan=1.2,
    final m_flow_nominal=m_flow_nominal,
    final mHex_flow_nominal=m_flow_nominal,
    final nSeg=12,
    final hexSegMult=2,
    final Q_flow_nominal=QHex_flow_nominal,
    final TTan_nominal=293.15,
    final THex_nominal=273.15+60,
    final computeFlowResistance=false,
    final energyDynamicsHex=Modelica.Fluid.Types.Dynamics.FixedInitial)
    "Tank";

  Tank tan_aTop(
    hHex_a=0.3,
    hHex_b=0.1)
    "Tank with heat exchanger inlet above its outlet"

  Tank tan_bTop(
    hHex_a=0.1,
    hHex_b=0.3)
    "Tank with heat exchanger outlet above its inlet"

  Buildings.Fluid.Sources.Boundary_pT sin(
    redeclare package Medium = Medium,
    T=273.15 + 30,
    p(displayUnit="Pa"),
    nPorts=2) "Sink boundary condition"

  Buildings.Fluid.Sensors.TemperatureTwoPort senTan_aTop(
    redeclare package Medium = Medium,
    m_flow_nominal=m_flow_nominal,
    tau=0) "Temperature sensor at tank outlet"

  Buildings.Fluid.Sensors.TemperatureTwoPort senTan_bTop(
    redeclare package Medium = Medium,
    m_flow_nominal=m_flow_nominal,
    tau=0) "Temperature sensor at tank outlet"
  Buildings.Fluid.Sources.MassFlowSource_T mWatTanSte_flow(
    redeclare package Medium = Medium,
    nPorts=1) "Mass flow rate through the tank"
  Buildings.Fluid.Sources.MassFlowSource_T mWatTanDyn_flow(
    redeclare package Medium = Medium,
    nPorts=1) "Mass flow rate through the tank"
equation
  connect(mHex_flow1.ports[1], tan_aTop.portHex_a)
  connect(senTan_aTop.port_a, tan_aTop.portHex_b)
  connect(senTan_aTop.port_b, sin.ports[1])
  connect(senTan_bTop.port_b, sin.ports[2])
  connect(senTan_bTop.port_a, tan_bTop.portHex_b)
  connect(tan_bTop.portHex_a, mHex_flow1.ports[2])
  connect(tan_aTop.port_a, watInTan.ports[1])
  connect(tan_bTop.port_a, watInTan.ports[2])
  connect(mWatTanDyn_flow.ports[1], tan_aTop.port_b)
  connect(tan_bTop.port_b, mWatTanSte_flow.ports[1])
end HeatExchangerLocation;


within Buildings.Fluid.Storage;
package Validation "Collection of models that validate the storage models"
extends Modelica.Icons.ExamplesPackage;
end Validation;


Test model for stratified tank

within Buildings.Fluid.Storage.Validation;
model StratifiedLoadingUnloading "Test model for stratified tank"
  extends Modelica.Icons.Example;

 package Medium = Buildings.Media.Water "Medium model";
 constant Integer nSeg = 7 "Number of segments in tank";

  parameter Modelica.Units.SI.MassFlowRate m_flow_nominal=1*1000/3600/4;

  Buildings.Fluid.Sources.Boundary_pT sou_1(
    p=300000 + 5000,
    T=273.15 + 40,
    redeclare package Medium = Medium,
    use_T_in=false,
    nPorts=2)
  Buildings.Fluid.Sources.MassFlowSource_T sin_1(
    redeclare package Medium = Medium,
    T=273.15 + 20,
    m_flow=-0.028,
    use_m_flow_in=true,
    nPorts=1)
  Buildings.Fluid.Storage.StratifiedEnhanced tanEnh(
    redeclare package Medium = Medium,
    hTan=3,
    dIns=0.3,
    VTan=0.1,
    nSeg=nSeg,
    show_T=true,
    m_flow_nominal=m_flow_nominal) "Tank"

  Buildings.Fluid.Sources.MassFlowSource_T sin_2(
    redeclare package Medium = Medium,
    T=273.15 + 20,
    m_flow=-0.028,
    use_m_flow_in=true,
    nPorts=1)
  Buildings.Fluid.Storage.Stratified tan(
    redeclare package Medium = Medium,
    hTan=3,
    dIns=0.3,
    VTan=0.1,
    nSeg=nSeg,
    show_T=true,
    m_flow_nominal=m_flow_nominal) "Tank"

  Modelica.Blocks.Sources.Pulse pulse(
    amplitude=2*m_flow_nominal,
    offset=-m_flow_nominal,
    period=7200)
  Buildings.Fluid.Sensors.EnthalpyFlowRate HIn_flow(redeclare package Medium =
        Medium, m_flow_nominal=m_flow_nominal) "Enthalpy flow rate"
  Buildings.Fluid.Sensors.EnthalpyFlowRate HOut_flow(redeclare package Medium =
        Medium, m_flow_nominal=m_flow_nominal) "Enthalpy flow rate"
  Buildings.Fluid.Sensors.EnthalpyFlowRate HInEnh_flow(redeclare package Medium =
        Medium, m_flow_nominal=m_flow_nominal) "Enthalpy flow rate"
  Buildings.Fluid.Sensors.EnthalpyFlowRate HOutEnh_flow(redeclare package
      Medium = Medium, m_flow_nominal=m_flow_nominal) "Enthalpy flow rate"
  Modelica.Blocks.Math.Add add(k2=-1)
  Modelica.Blocks.Continuous.Integrator dHTanEnh
    "Difference in enthalpy (should be zero at steady-state)"
  Modelica.Blocks.Math.Add add1(
                               k2=-1)
  Modelica.Blocks.Continuous.Integrator dHTan
    "Difference in enthalpy (should be zero at steady-state)"
equation

  connect(sou_1.ports[1], HIn_flow.port_a)
  connect(HIn_flow.port_b, tan.port_a)
  connect(tan.port_b, HOut_flow.port_a)
  connect(HOut_flow.port_b, sin_2.ports[1])
  connect(sou_1.ports[2], HInEnh_flow.port_a)
  connect(HInEnh_flow.port_b, tanEnh.port_a)
  connect(tanEnh.port_b, HOutEnh_flow.port_a)
  connect(HOutEnh_flow.port_b, sin_1.ports[1])
  connect(HInEnh_flow.H_flow, add.u1)
  connect(HOutEnh_flow.H_flow, add.u2)
  connect(add.y, dHTanEnh.u)
  connect(HIn_flow.H_flow, add1.u1)
  connect(HOut_flow.H_flow, add1.u2)
  connect(add1.y, dHTan.u)
  connect(pulse.y, sin_1.m_flow_in)
  connect(pulse.y, sin_2.m_flow_in)
end StratifiedLoadingUnloading;


within Buildings.Fluid.Storage.Validation;
model StratifiedNonUniformInitial
  "Test model for stratified tank with non-uniform initial temperature"
  extends Modelica.Icons.Example;

  package Medium = Buildings.Media.Water "Medium model";
  constant Integer nSeg = 7 "Number of segments in tank";

  parameter Modelica.Units.SI.MassFlowRate m_flow_nominal=1*1000/3600/4;

  Buildings.Fluid.Sources.Boundary_pT sou_1(
    p=300000 + 5000,
    T=273.15 + 40,
    redeclare package Medium = Medium,
    use_T_in=false,
    nPorts=2)
  Buildings.Fluid.Sources.MassFlowSource_T sin_1(
    redeclare package Medium = Medium,
    T=273.15 + 20,
    m_flow=-m_flow_nominal,
    nPorts=1)
    "Mass flow source"
  Buildings.Fluid.Storage.Stratified heaTan(
    redeclare package Medium = Medium,
    hTan=3,
    dIns=0.3,
    VTan=0.1,
    nSeg=nSeg,
    show_T=true,
    m_flow_nominal=m_flow_nominal,
    TFlu_start={313.15,312.15,311.15,310.15,309.15,308.15,307.15})
    "Tank that will be heated up"
  Buildings.Fluid.Sources.MassFlowSource_T sin_2(
    redeclare package Medium = Medium,
    T=273.15 + 20,
    m_flow=m_flow_nominal,
    nPorts=1)
    "Mass flow source"
  Buildings.Fluid.Storage.Stratified cooTan(
    redeclare package Medium = Medium,
    hTan=3,
    dIns=0.3,
    VTan=0.1,
    nSeg=nSeg,
    show_T=true,
    m_flow_nominal=m_flow_nominal,
    TFlu_start={313.15,312.15,311.15,310.15,309.15,308.15,307.15})
    "Tank that will be cooled down"

  Buildings.Fluid.Sensors.EnthalpyFlowRate HIn_flow(
    redeclare package Medium = Medium,
    m_flow_nominal=m_flow_nominal) "Enthalpy flow rate"
  Buildings.Fluid.Sensors.EnthalpyFlowRate HOut_flow(
    redeclare package Medium = Medium,
    m_flow_nominal=m_flow_nominal) "Enthalpy flow rate"
  Buildings.Fluid.Sensors.EnthalpyFlowRate HInEnh_flow(
    redeclare package Medium = Medium,
    m_flow_nominal=m_flow_nominal) "Enthalpy flow rate"
  Buildings.Fluid.Sensors.EnthalpyFlowRate HOutEnh_flow(
    redeclare package Medium = Medium,
    m_flow_nominal=m_flow_nominal) "Enthalpy flow rate"
  Modelica.Blocks.Math.Add add(k2=-1) "Adder for enthalpy difference"
  Modelica.Blocks.Continuous.Integrator dHTanEnh
    "Difference in enthalpy (should be zero at steady-state)"
  Modelica.Blocks.Math.Add add1(k2=-1) "Adder for enthalpy difference"
  Modelica.Blocks.Continuous.Integrator dHTan
    "Difference in enthalpy (should be zero at steady-state)"

equation
  connect(HIn_flow.port_b, cooTan.port_a)
  connect(cooTan.port_b, HOut_flow.port_a)
  connect(HOut_flow.port_b, sin_2.ports[1])
  connect(HOutEnh_flow.port_b, sin_1.ports[1])
  connect(HInEnh_flow.H_flow, add.u1)
  connect(HOutEnh_flow.H_flow, add.u2)
  connect(add.y, dHTanEnh.u)
  connect(HIn_flow.H_flow, add1.u1)
  connect(HOut_flow.H_flow, add1.u2)
  connect(add1.y, dHTan.u)
  connect(HInEnh_flow.port_b, heaTan.port_a)
  connect(heaTan.port_b, HOutEnh_flow.port_a)
  connect(sou_1.ports[1], HInEnh_flow.port_a)
  connect(sou_1.ports[2], HIn_flow.port_a)
end StratifiedNonUniformInitial;


Package with utility functions

within Buildings.Fluid;
package Utilities "Package with utility functions"
  extends Modelica.Icons.Package;
end Utilities;


within Buildings.Fluid.Utilities;
package BaseClasses "Package with base classes for Buildings.Fluid.Utilities"
  extends Modelica.Icons.BasesPackage;
end BaseClasses;


Polynomial coefficients. This example checks whether the function derivative
is implemented correctly. If the derivative implementation
is not correct, the model will stop with an assert statement.

within Buildings.Fluid.Utilities.Examples;
model ExtendedPolynomialDerivativeCheck
  extends Modelica.Icons.Example;

  parameter Real[:] c={0.1162,1.5404,-1.4825,0.7664,-0.1971}
    "Polynomial coefficients";
  parameter Real xMin=1 "Minimum x value for polynomial";
  parameter Real xMax=2 "Maximum x value for polynomial";

  Real x;
  Real y;
initial equation
   y=x;
equation
  x=Buildings.Fluid.Utilities.extendedPolynomial(
      x=time, c=c, xMin=xMin, xMax=xMax);
  der(y)=der(x);
  assert(abs(x-y) < 1E-2, "Model has an error");
end ExtendedPolynomialDerivativeCheck;


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


Package with heat transfer models

within Buildings;
package HeatTransfer "Package with heat transfer models"
  extends Modelica.Icons.Package;
end HeatTransfer;


User's Guide

within Buildings.HeatTransfer;
package UsersGuide "User's Guide"
  extends Modelica.Icons.Information;
  Buildings.HeatTransfer.Data.Solids.Concrete concrete(x=0.2, nStaRef=4);

Here, we selected to use four state variables for each material layer.

Next, we define the construction. In the room model, the convention is that the first material
layer faces the outside, and the last material layer faces the room-side.
Therefore, the declaration for an exterior wall with insulation at the outside is

  Buildings.HeatTransfer.Data.OpaqueConstructions.Generic
     wall(nLay=2, material={insulation,concrete});

(Note that nLay must be set to the number of layers to allow
a Modelica translator to know how many layers there are prior to translating
the model.)

Alternatively, to model the insulation in steady-state, we can set its heat capacity to zero by declaring

  Buildings.HeatTransfer.Data.Solids.InsulationBoard insulation(c=0, x=0.1, nStaRef=4);

Instead of specifying a material with specific heat capacity and setting c=0,
materials from the library

Buildings.HeatTransfer.Data.Resistances can be used.
For example, for a floor with carpet, the declaration would be

  Buildings.HeatTransfer.Data.Resistances.Carpet carpet;
  Buildings.HeatTransfer.Data.Solids.Concrete    concrete(x=0.2, nStaRef=4);
  Buildings.HeatTransfer.Data.OpaqueConstructions.Generic
       floor(nLay=2, material={concrete, carpet});

To change the thermal resistance, we could have written

  Buildings.HeatTransfer.Data.Resistances.Carpet carpet(R=0.3);

or

  Buildings.HeatTransfer.Data.Resistances.Generic carpet(R=0.3);

Both definitions are identical.

"));

end UsersGuide;


Model for heat conductance through a solid with multiple material layers. This is a model of a heat conductor with multiple material layers and energy storage.
The construction has at least one material layer, and each layer has
at least one temperature node. The layers are modeled using an instance of

Buildings.HeatTransfer.Conduction.SingleLayer.
See this model for an explanation of the equations that are applied to
each material layer.

within Buildings.HeatTransfer.Conduction;
model MultiLayer
  "Model for heat conductance through a solid with multiple material layers"
  extends Buildings.HeatTransfer.Conduction.BaseClasses.PartialConductor(
   final R=sum(lay[i].R for i in 1:nLay));
  Modelica.Units.SI.Temperature T[sum(layers.nSta)](each nominal=300)
    "Temperature at the states";
  Modelica.Units.SI.HeatFlowRate Q_flow[sum(layers.nSta) + nLay]
    "Heat flow rate from state i to i+1";
  extends Buildings.HeatTransfer.Conduction.BaseClasses.PartialConstruction;

  parameter Boolean stateAtSurface_a=true
    "=true, a state will be at the surface a"
  parameter Boolean stateAtSurface_b=true
    "=true, a state will be at the surface b"

protected
  Buildings.HeatTransfer.Conduction.SingleLayer[nLay] lay(
   final nSta2={layers.nSta[i] for i in 1:nLay},
   each final A=A,
   final stateAtSurface_a = {if i == 1 then stateAtSurface_a else false for i in 1:nLay},
   final stateAtSurface_b = {if i == nLay then stateAtSurface_b else false for i in 1:nLay},
   material = {layers.material[i] for i in 1:size(layers.material, 1)},
   T_a_start = { T_b_start+(T_a_start-T_b_start) * 1/R *
    sum(layers.material[k].R for k in i:size(layers.material, 1)) for i in 1:size(layers.material, 1)},
   T_b_start = { T_a_start+(T_b_start-T_a_start) * 1/R *
    sum(layers.material[k].R for k in 1:i) for i in 1:size(layers.material, 1)},
   each steadyStateInitial = steadyStateInitial) "Material layer"

equation
  // This section assigns the temperatures and heat flow rates of the layer models to
  // an array that makes plotting the results easier.
  for i in 1:nLay loop
    for j in 1:layers.nSta[i] loop
      T[sum(layers.nSta[k] for k in 1:(i-1)) +j] = lay[i].T[j];
    end for;
    for j in 1:layers.nSta[i]+1 loop
      Q_flow[sum(layers.nSta[k] for k in 1:i-1)+(i-1)+j] = lay[i].Q_flow[j];
    end for;
  end for;
  connect(port_a, lay[1].port_a)
  for i in 1:nLay-1 loop
  connect(lay[i].port_b, lay[i+1].port_a)
  end for;
  connect(lay[nLay].port_b, port_b)

Assign the instance of the material to the instance of the heat transfer
model as shown in

Buildings.HeatTransfer.Examples.ConductorMultiLayer.

The parameters stateAtSurface_a and
stateAtSurface_b
determine whether there is a state variable at these surfaces,
as described above.
Note that if stateAtSurface_a = true,
then there is temperature state on the surface a with prescribed
value, as determined by the differential equation of the heat conduction.
Hence, in this situation, it is not possible to
connect a temperature boundary condition such as

Buildings.HeatTransfer.Sources.FixedTemperature as this would
yield to specifying the same temperature twice.
To avoid this, either set stateAtSurface_a = false,
or place a thermal resistance
between the boundary condition and the surface of this model.
The same applies for surface b.
See the examples in

Buildings.HeatTransfer.Examples.

", revisions="

October 16, 2017, by Michael Wetter:

Corrected wrong result variable R and UA.
These variables are only used for reporting.
All other calculations were not affected by this error.

January 05, 2017, by Thierry S. Nouidui:

Removed parameter nSta2.

November 17, 2016, by Thierry S. Nouidui:

Added parameter nSta2 to avoid translation error
in Dymola 2107. This is a work-around for a bug in Dymola
which will be addressed in future releases.

October 29, 2016, by Michael Wetter:

Added option to place a state at the surface.

This is for
issue 565.

September 24, 2015 by Michael Wetter:

Set the start value of T.
This is for
issue 426.

March 18, 2015, by Michael Wetter:

Replaced nLay in the sum() of the parameter assignment
with size(layers.material, 1) to avoid incorrect results in OpenModelica.
See github note.

March 13, 2015, by Michael Wetter:

Changed assignment of nLay to avoid a translation error
in OpenModelica.

October 15, 2014, by Michael Wetter:

Changed assignment of R to be in the extends statement
to avoid a division by zero in OpenModelica.

September 9, 2014, by Michael Wetter:

Reverted change from March 1 2013 as this causes an error during model check
in Dymola 2015 FD01 beta1.

August 12, 2014, by Michael Wetter:

Reformulated the protected elements and the model instantiation to avoid
a warning in the OpenModelica parser.

March 1, 2013, by Michael Wetter:

Removed initial equation section and assigned the protected parameters
_T_a_start and _T_b_start directly to avoid a warning during
translation.

March 6 2010, by Michael Wetter:

First implementation.

"));
end MultiLayer;


Package with models for heat conduction

within Buildings.HeatTransfer;
package Conduction "Package with models for heat conduction"
  extends Modelica.Icons.VariantsPackage;

  constant Integer nSupPCM = 6
    "Number of support points to approximate u(T) releation, used only for phase change material";
end Conduction;


Model for single layer heat conductance. This is a model of a heat conductor for a single layer of homogeneous material
that computes transient or steady-state heat conduction.

within Buildings.HeatTransfer.Conduction;
model SingleLayer "Model for single layer heat conductance"
  extends Buildings.HeatTransfer.Conduction.BaseClasses.PartialConductor(
   final R=if (material.R < Modelica.Constants.eps) then material.x/material.k/A else material.R/A);
   // if material.R == 0, then the material specifies material.k, and this model specifies x
   // For resistances, material.k need not be specified, and hence we use material.R

  // The value T[:].start is used by the solver when finding initial states
  // that satisfy dT/dt=0, which requires solving a system of nonlinear equations
  // if the convection coefficient is a function of temperature.
  Modelica.Units.SI.Temperature T[nSta](start=if stateAtSurface_a then cat(
        1,
        {T_a_start},
        {(T_a_start + (T_b_start - T_a_start)*UA*sum(RNod[k] for k in 1:i - 1))
          for i in 2:nSta}) else {(T_a_start + (T_b_start - T_a_start)*UA*sum(
        RNod[k] for k in 1:i)) for i in 1:nSta}, each nominal=300)
    "Temperature at the states";

  Modelica.Units.SI.HeatFlowRate Q_flow[nSta + 1](each start=0)
    "Heat flow rates to each state";
  Modelica.Units.SI.SpecificInternalEnergy u[nSta](each start=2.7E5, each
      nominal=2.7E5) "Definition of specific internal energy";

  parameter Boolean stateAtSurface_a=true
    "=true, a state will be at the surface a"
  parameter Boolean stateAtSurface_b=true
    "=true, a state will be at the surface b"

  replaceable parameter Data.BaseClasses.Material material
    "Material from Data.Solids, Data.SolidsPCM or Data.Resistances"

  parameter Boolean steadyStateInitial=false
    "=true initializes dT(0)/dt=0, false initializes T(0) at fixed temperature using T_a_start and T_b_start"
  parameter Modelica.Units.SI.Temperature T_a_start=293.15
    "Initial temperature at port_a, used if steadyStateInitial = false"
  parameter Modelica.Units.SI.Temperature T_b_start=293.15
    "Initial temperature at port_b, used if steadyStateInitial = false"
  parameter Integer nSta2=material.nSta
  "Number of states in a material (do not overwrite, used to work around Dymola 2017 bug)"
protected
  final parameter Integer nSta=
    max(nSta2,
        if stateAtSurface_a or stateAtSurface_b then 2 else 1)
    "Number of state variables";
  final parameter Integer nR=nSta+1 "Number of thermal resistances";
  parameter Modelica.Units.SI.ThermalResistance RNod[nR]=if (stateAtSurface_a
       and stateAtSurface_b) then if (nSta == 2) then {(if i == 1 or i == nR
       then 0 else R/(nSta - 1)) for i in 1:nR} else {(if i == 1 or i == nR
       then 0 elseif i == 2 or i == nR - 1 then R/(2*(nSta - 2)) else R/(nSta
       - 2)) for i in 1:nR} elseif (stateAtSurface_a and (not stateAtSurface_b))
       then {(if i == 1 then 0 elseif i == 2 or i == nR then R/(2*(nSta - 1))
       else R/(nSta - 1)) for i in 1:nR} elseif (stateAtSurface_b and (not
      stateAtSurface_a)) then {(if i == nR then 0 elseif i == 1 or i == nR - 1
       then R/(2*(nSta - 1)) else R/(nSta - 1)) for i in 1:nR} else {R/(if i
       == 1 or i == nR then (2*nSta) else nSta) for i in 1:nR}
    "Thermal resistance";

  parameter Modelica.Units.SI.Mass m[nSta]=(A*material.x*material.d)*(if (
      stateAtSurface_a and stateAtSurface_b) then if (nSta == 2) then {1/(2*(
      nSta - 1)) for i in 1:nSta} elseif (nSta == 3) then {1/(if i == 1 or i
       == nSta then (2*(nSta - 1)) else (nSta - 1)) for i in 1:nSta} else {1/(
      if i == 1 or i == nSta or i == 2 or i == nSta - 1 then (2*(nSta - 2))
       else (nSta - 2)) for i in 1:nSta} elseif (stateAtSurface_a and (not
      stateAtSurface_b)) then {1/(if i == 1 or i == 2 then (2*(nSta - 1)) else
      (nSta - 1)) for i in 1:nSta} elseif (stateAtSurface_b and (not
      stateAtSurface_a)) then {1/(if i == nSta or i == nSta - 1 then (2*(nSta
       - 1)) else (nSta - 1)) for i in 1:nSta} else {1/(nSta) for i in 1:nSta})
    "Mass associated with the temperature state";

  final parameter Real mInv[nSta]=
    if material.steadyState then zeros(nSta) else {1/m[i] for i in 1:nSta}
    "Inverse of the mass associated with the temperature state";

  final parameter Modelica.Units.SI.HeatCapacity C[nSta]=m*material.c
    "Heat capacity associated with the temperature state";
  final parameter Real CInv[nSta]=
    if material.steadyState then zeros(nSta) else {1/C[i] for i in 1:nSta}
    "Inverse of heat capacity associated with the temperature state";

  parameter Modelica.Units.SI.SpecificInternalEnergy ud[Buildings.HeatTransfer.Conduction.nSupPCM]
    (each fixed=false) "Support points for derivatives (used for PCM)";
  parameter Modelica.Units.SI.Temperature Td[Buildings.HeatTransfer.Conduction.nSupPCM]
    (each fixed=false) "Support points for derivatives (used for PCM)";
  parameter Real dT_du[Buildings.HeatTransfer.Conduction.nSupPCM](
    each fixed=false,
    each unit="kg.K2/J")
    "Derivatives dT/du at the support points (used for PCM)";

initial equation
  // The initialization is only done for materials that store energy.
    if not material.steadyState then
      if steadyStateInitial then
        if material.phasechange then
          der(u) = zeros(nSta);
        else
          der(T) = zeros(nSta);
        end if;
      else
        if stateAtSurface_a then
          T[1] = T_a_start;
          for i in 2:nSta loop
            T[i] =T_a_start + (T_b_start - T_a_start)*UA*sum(RNod[k] for k in 1:i-1);
          end for;
        else // stateAtSurface_a == false
          for i in 1:nSta loop
            T[i] = T_a_start + (T_b_start - T_a_start)*UA*sum(RNod[k] for k in 1:i);
          end for;
        end if;
      end if;
    end if;

   if material.phasechange then
     (ud, Td, dT_du) = Buildings.HeatTransfer.Conduction.BaseClasses.der_temperature_u(
       c =  material.c,
       TSol=material.TSol,
       TLiq=material.TLiq,
       LHea=material.LHea,
       ensureMonotonicity=material.ensureMonotonicity);
   else
     ud    = zeros(Buildings.HeatTransfer.Conduction.nSupPCM);
     Td    = zeros(Buildings.HeatTransfer.Conduction.nSupPCM);
     dT_du = zeros(Buildings.HeatTransfer.Conduction.nSupPCM);
   end if;
equation
    port_a.Q_flow = +Q_flow[1];
    port_b.Q_flow = -Q_flow[end];

    port_a.T-T[1]    = if stateAtSurface_a then 0 else Q_flow[1]*RNod[1];
    T[nSta]-port_b.T = if stateAtSurface_b then 0 else Q_flow[end]*RNod[end];

    for i in 1:nSta-1 loop
       // Q_flow[i+1] is heat flowing from (i) to (i+1)
       // because T[1] has Q_flow[1] and Q_flow[2] acting on it.
       T[i]-T[i+1] = Q_flow[i+1]*RNod[i+1];
    end for;

    // Steady-state heat balance
    if material.steadyState then
      for i in 2:nSta+1 loop
        Q_flow[i] = port_a.Q_flow;
      end for;

      for i in 1:nSta loop
        if material.phasechange then
          // Phase change material
          T[i]=Buildings.HeatTransfer.Conduction.BaseClasses.temperature_u(
                    ud=ud,
                    Td=Td,
                    dT_du=dT_du,
                    u=u[i]);
        else
          // Regular material
          u[i]=0; // u is not required in this case
        end if;
      end for;
    else
      // Transient heat conduction
      if material.phasechange then
        // Phase change material
        for i in 1:nSta loop
          der(u[i]) = (Q_flow[i]-Q_flow[i+1])*mInv[i];
          // Recalculation of temperature based on specific internal energy
          T[i]=Buildings.HeatTransfer.Conduction.BaseClasses.temperature_u(
                    ud=ud,
                    Td=Td,
                    dT_du=dT_du,
                    u=u[i]);
        end for;
      else
        // Regular material
        for i in 1:nSta loop
          der(T[i]) = (Q_flow[i]-Q_flow[i+1])*CInv[i];
        end for;
        for i in 1:nSta loop
          u[i]=0; // u is not required in this case
        end for;
      end if;
    end if;
end SingleLayer;


Heat conduction in a cylinder.

within Buildings.HeatTransfer.Conduction;
model SingleLayerCylinder "Heat conduction in a cylinder"
  replaceable parameter Buildings.HeatTransfer.Data.Soil.Generic material
    "Material thermal properties"

  parameter Modelica.Units.SI.Height h "Height of the cylinder";
  parameter Modelica.Units.SI.Radius r_a "Internal radius";
  parameter Modelica.Units.SI.Radius r_b "External radius";
  parameter Integer nSta(min=1) "Number of state variables";
  parameter Modelica.Units.SI.Temperature TInt_start=293.15
    "Initial temperature at port_a, used if steadyStateInitial = false"
  parameter Modelica.Units.SI.Temperature TExt_start=293.15
    "Initial temperature at port_b, used if steadyStateInitial = false"
  parameter Boolean steadyStateInitial=false
    "true initializes dT(0)/dt=0, false initializes T(0) at fixed temperature using T_a_start and T_b_start"

  parameter Real griFac(min=1) = 2 "Grid factor for spacing";

  Modelica.Units.SI.TemperatureDifference dT "port_a.T - port_b.T";

  Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a port_a
    "Heat port at surface a"
  Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b port_b
    "Heat port at surface b"

  Modelica.Units.SI.Temperature T[nSta](start={TInt_start + (TExt_start -
        TInt_start)/Modelica.Math.log(r_b/r_a)*Modelica.Math.log((r_a + (r_b -
        r_a)/(nSta)*(i - 0.5))/r_a) for i in 1:nSta})
    "Temperature of the states";
  Modelica.Units.SI.HeatFlowRate Q_flow[nSta + 1]
    "Heat flow rate from state i to i+1";

//  Modelica.Units.SI.TemperatureSlope der_T[nSta]
//    "Time derivative of temperature (= der(T))";
protected
  parameter Modelica.Units.SI.Radius r[nSta + 1](each fixed=false)
    "Radius to the boundary of the i-th domain";
  parameter Modelica.Units.SI.Radius rC[nSta](each fixed=false)
    "Radius to the center of the i-th domain";

  final parameter Modelica.Units.SI.SpecificHeatCapacity c=material.c
    "Specific heat capacity";
  final parameter Modelica.Units.SI.ThermalConductivity k=material.k
    "Thermal conductivity of the material";
  final parameter Modelica.Units.SI.Density d=material.d
    "Density of the material";

  parameter Modelica.Units.SI.ThermalConductance G[nSta + 1](each fixed=false)
    "Heat conductance between the temperature nodes";
  parameter Modelica.Units.SI.HeatCapacity C[nSta](each fixed=false)
    "Heat capacity of each state";

initial equation
  assert(r_a < r_b, "Error: Model requires r_a < r_b.");
  assert(0 < r_a,   "Error: Model requires 0 < r_a.");
  r[1] = r_a;
  for i in 2:nSta+1 loop
     r[i]= r[i-1] + ( r_b - r_a)  * (1-griFac)/(1-griFac^(nSta)) * griFac^(i-2);
  end for;

  // Radii to the center of the domain
  for i in 1:nSta loop
    rC[i] = (r[i]+r[i+1])/2;
  end for;
  // Conductance between nodes (which are in the center of the domain)
  G[1]      = 2*Modelica.Constants.pi*k*h/Modelica.Math.log(rC[1]/r_a);
  G[nSta+1] = 2*Modelica.Constants.pi*k*h/Modelica.Math.log(r_b/rC[nSta]);
  for i in 2:nSta loop
    G[i]      = 2*Modelica.Constants.pi*k*h/Modelica.Math.log(rC[i]/rC[i-1]);
  end for;

  // Heat capacity of each segment
  for i in 1:nSta loop
   C[i] = (d*Modelica.Constants.pi*c*h*((r[i+1])^2-(r[i])^2));
  end for;
  // The initialization is only done for materials that store energy.
  if not material.steadyState then
    if steadyStateInitial then
      der(T) = zeros(nSta);
    else
      for i in 1:nSta loop
        T[i]=TInt_start+ (TExt_start-TInt_start)/Modelica.Math.log(r_b/r_a) * Modelica.Math.log(rC[i]/r_a);
      end for;
    end if;
  end if;
equation
  dT = port_a.T - port_b.T;
  port_a.Q_flow = +Q_flow[1];
  port_b.Q_flow = -Q_flow[nSta+1];
  Q_flow[1]      = G[1]      * (port_a.T-T[1]);
  Q_flow[nSta+1] = G[nSta+1] * (T[nSta]-port_b.T);
  for i in 2:nSta loop
    Q_flow[i]=G[i]*(T[i-1]-T[i]);
    // Q_flow[i] represents the heat flowing between two nodes
  end for;
  if material.steadyState then
    for i in 2:nSta+1 loop
      Q_flow[i]=Q_flow[1];
    end for;
  else
    for i in 1:nSta loop
        der(T[i])= (Q_flow[i]-Q_flow[i+1])/C[i];
    end for;
  end if;
end SingleLayerCylinder;


Computes the derivative of the temperature of a phase change material with respect to specific internal energy. This function computes at the support points Td the derivatives
dT/du of the cubic hermite spline approximation to the
temperature vs. specific internal energy relation.
These derivatives are then used by the function

Buildings.HeatTransfer.Conduction.BaseClasses.temperature_u
to compute for a given specific internal energy the temperature.

within Buildings.HeatTransfer.Conduction.BaseClasses;
function der_temperature_u
  "Computes the derivative of the temperature of a phase change material with respect to specific internal energy"
  input Modelica.Units.SI.SpecificHeatCapacity c "Specific heat capacity";
  input Modelica.Units.SI.Temperature TSol
    "Solidus temperature, used only for PCM.";
  input Modelica.Units.SI.Temperature TLiq
    "Liquidus temperature, used only for PCM";
  input Modelica.Units.SI.SpecificInternalEnergy LHea
    "Latent heat of phase change";
  input Boolean ensureMonotonicity = false
    "Set to true to force derivatives dT/du to be monotone";

  output Modelica.Units.SI.SpecificInternalEnergy ud[Buildings.HeatTransfer.Conduction.nSupPCM]
    "Support points for derivatives";
  output Modelica.Units.SI.Temperature Td[Buildings.HeatTransfer.Conduction.nSupPCM]
    "Support points for derivatives";
  output Real dT_du[Buildings.HeatTransfer.Conduction.nSupPCM](
    each fixed=false,
    each unit="kg.K2/J")
    "Derivatives dT/du at the support points";
protected
  parameter Real scale=0.999 "Used to place points on the phase transition";
  Modelica.Units.SI.Temperature Tm1=TSol + (1 - scale)*(TLiq - TSol)
    "Support point";
  Modelica.Units.SI.Temperature Tm2=TSol + scale*(TLiq - TSol)
    "Support point";
algorithm
  assert(Buildings.HeatTransfer.Conduction.nSupPCM == 6,
    "The material must have exactly 6 support points for the u(T) relation.");
  assert(TLiq > TSol, "TLiq has to be larger than TSol.");
  // Get the derivative values at the support points
  ud:={c*scale*TSol,
       c*TSol,
       c*Tm1 + LHea*(Tm1 - TSol)/(TLiq - TSol),
       c*Tm2 + LHea*(Tm2 - TSol)/(TLiq - TSol),
       c*TLiq + LHea,
       c*(TLiq + TSol*(1 - scale)) + LHea};
  Td:={scale*TSol,
       TSol,
       Tm1,
       Tm2,
       TLiq,
       TLiq + TSol*(1 - scale)};
  dT_du := Buildings.Utilities.Math.Functions.splineDerivatives(
      x=ud,
      y=Td,
      ensureMonotonicity=ensureMonotonicity);
end der_temperature_u;


within Buildings.HeatTransfer.Conduction;
package BaseClasses "Package with base classes for Buildings.HeatTransfer.Conduction"
  extends Modelica.Icons.BasesPackage;
end BaseClasses;


Partial model for heat conductor.

within Buildings.HeatTransfer.Conduction.BaseClasses;
partial model PartialConductor "Partial model for heat conductor"
  extends Buildings.BaseClasses.BaseIcon;
  parameter Modelica.Units.SI.Area A "Heat transfer area";
  final parameter Modelica.Units.SI.CoefficientOfHeatTransfer U=UA/A
    "U-value (without surface heat transfer coefficients)";
  final parameter Modelica.Units.SI.ThermalConductance UA=1/R
    "Thermal conductance of construction (without surface heat transfer coefficients)";
  parameter Modelica.Units.SI.ThermalResistance R
    "Thermal resistance of construction";

  Modelica.Units.SI.TemperatureDifference dT "port_a.T - port_b.T";
  Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a port_a
    "Heat port at surface a"
  Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b port_b
    "Heat port at surface b"
equation
  dT = port_a.T - port_b.T;
end PartialConductor;


Partial model for multi-layer constructions.

within Buildings.HeatTransfer.Conduction.BaseClasses;
model PartialConstruction "Partial model for multi-layer constructions"
  extends Buildings.BaseClasses.BaseIcon;

  replaceable parameter Buildings.HeatTransfer.Data.OpaqueConstructions.Generic
    layers "Construction definition from Data.OpaqueConstructions"

  final parameter Integer nLay(min=1, fixed=true) = size(layers.material, 1)
    "Number of layers";
  final parameter Integer nSta[nLay](each min=1)={layers.material[i].nSta for i in 1:nLay}
    "Number of states"
  parameter Boolean steadyStateInitial=false
    "=true initializes dT(0)/dt=0, false initializes T(0) at fixed temperature using T_a_start and T_b_start"
  parameter Modelica.Units.SI.Temperature T_a_start=293.15
    "Initial temperature at port_a, used if steadyStateInitial = false"
  parameter Modelica.Units.SI.Temperature T_b_start=293.15
    "Initial temperature at port_b, used if steadyStateInitial = false"
end PartialConstruction;


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


Approximation of specific internal energy versus temperature curve with cubic hermite cubic spline. This example tests and demonstrates the implementation of the specific internal
energy versus temperature T(u) relationship for phase-change problems.
Cubic hermite interpolation and linear extrapolation is used to approximate
the piece-wise linear T(u) relationship.
A piece-wise linear T(u) relationship is assumed in all three characteristic regions (solid, mushy and liquid).
The example uses the functions

Buildings.HeatTransfer.Conduction.BaseClasses.der_temperature_u
and

Buildings.HeatTransfer.Conduction.BaseClasses.temperature_u.
The first function is used to compute
the derivatives at the support points,
and the second function computes the temperature
for a given specific internal energy.

within Buildings.HeatTransfer.Conduction.BaseClasses.Examples;
model Temperature_u
  "Approximation of specific internal energy versus temperature curve with cubic hermite cubic spline"
  extends Modelica.Icons.Example;
  // Phase-change properties
  parameter Buildings.HeatTransfer.Data.SolidsPCM.Generic
      materialMonotone(
               TSol=273.15+30.9,
               TLiq=273.15+40.0,
               LHea=1000000,
               c=920,
               ensureMonotonicity=true,
               d=1000,
               k=1,
               x=0.2) "Phase change material with monotone u-T relation";
  parameter Buildings.HeatTransfer.Data.SolidsPCM.Generic
      materialNonMonotone(TSol=273.15+30.9,
               TLiq=273.15+40.0,
               LHea=1000000,
               c=920,
               ensureMonotonicity=false,
               d=1000,
               k=1,
               x=0.2) "Phase change material with non-monotone u-T relation";
  parameter Modelica.Units.SI.SpecificInternalEnergy ud[Buildings.HeatTransfer.Conduction.nSupPCM]
    (each fixed=false) "Support points";
  parameter Modelica.Units.SI.SpecificInternalEnergy udMonotone[Buildings.HeatTransfer.Conduction.nSupPCM]
    (each fixed=false) "Support points";
  parameter Modelica.Units.SI.Temperature Td[Buildings.HeatTransfer.Conduction.nSupPCM]
    (each fixed=false) "Support points";
  parameter Modelica.Units.SI.Temperature TdMonotone[Buildings.HeatTransfer.Conduction.nSupPCM]
    (each fixed=false) "Support points";
  parameter Real dT_du[Buildings.HeatTransfer.Conduction.nSupPCM](each fixed=false, each unit="kg.K2/J")
    "Derivatives at the support points - non-monotone, default in Modelica PCM";
  parameter Real dT_duMonotone[Buildings.HeatTransfer.Conduction.nSupPCM](each fixed=false, each unit="kg.K2/J")
    "Derivatives at the support points for monotone increasing cubic splines";
  Modelica.Units.SI.SpecificInternalEnergy u "Specific internal energy";
  Modelica.Units.SI.Temperature T
    "Temperature for given u without monotone interpolation";
  Modelica.Units.SI.Temperature TMonotone
    "Temperature for given u with monotone interpolation";
  Modelica.Units.SI.Temperature TExa "Exact value of temperature";
  Real errMonotone
    "Relative temperature error between calculated value with monotone interpolation and exact temperature";
  Real errNonMonotone
    "Relative temperature error between calculated value with non-monotone interpolation and exact temperature";

  parameter Modelica.Units.SI.TemperatureDifference dTCha=materialMonotone.TSol
       + materialMonotone.TLiq
    "Characteristic temperature difference of the problem";
protected
  function relativeError "Relative error"
    input Modelica.Units.SI.Temperature T "Approximated temperature";
    input Modelica.Units.SI.Temperature TExa "Exact temperature";
    input Modelica.Units.SI.TemperatureDifference dTCha
      "Characteristic temperature difference";
    output Real relErr "Relative error";
  algorithm
    relErr :=(T - TExa)/dTCha;
  end relativeError;

  constant Real conFac(unit="1/s") = 1
    "Conversion factor to satisfy unit check";
initial equation
  // Calculate derivatives at support points (non-monotone)
  (ud, Td, dT_du) =
    Buildings.HeatTransfer.Conduction.BaseClasses.der_temperature_u(
      c =  materialNonMonotone.c,
      TSol=materialNonMonotone.TSol,
      TLiq=materialNonMonotone.TLiq,
      LHea=materialNonMonotone.LHea,
      ensureMonotonicity=materialNonMonotone.ensureMonotonicity);
  // Calculate derivatives at support points (monotone);
 (udMonotone, TdMonotone, dT_duMonotone) =
    Buildings.HeatTransfer.Conduction.BaseClasses.der_temperature_u(
      c =  materialMonotone.c,
      TSol=materialMonotone.TSol,
      TLiq=materialMonotone.TLiq,
      LHea=materialMonotone.LHea,
      ensureMonotonicity=materialMonotone.ensureMonotonicity);
equation
  u =  2.5e5+time*(1.5*materialMonotone.c*(materialMonotone.TLiq-273.15)+materialMonotone.LHea)*conFac;

  // Calculate T based on non-monotone interpolation
  T = Buildings.HeatTransfer.Conduction.BaseClasses.temperature_u(
       ud=ud,
       Td=Td,
       dT_du=dT_du,
       u=u);
  // Calculate T based on monotone interpolation
  TMonotone = Buildings.HeatTransfer.Conduction.BaseClasses.temperature_u(
       ud=udMonotone,
       Td=TdMonotone,
       dT_du=dT_duMonotone,
       u=u);
  //Relative errors of obtained temperatures by using monotone and non-monotone
  //interpolation against exact values of tempratures taken from the T(u) curve
  if time>=1.e-05 then
    if u <= materialMonotone.c*materialMonotone.TSol then
      // Solid region
      TExa           = u/materialMonotone.c;
    elseif u >= materialMonotone.c*materialMonotone.TLiq+materialMonotone.LHea then
      // Liquid region
      TExa           = (u-materialMonotone.LHea)/materialMonotone.c;
   else
      // Region of phase transition
      TExa=((u + materialMonotone.LHea*materialMonotone.TSol/(materialMonotone.TLiq
         - materialMonotone.TSol))/(materialMonotone.c + materialMonotone.LHea/(
        materialMonotone.TLiq - materialMonotone.TSol)));
    end if;
  else
    TExa =T;
  end if;
  errNonMonotone = relativeError(T=T,         TExa=TExa, dTCha = dTCha);
  errMonotone    = relativeError(T=TMonotone, TExa=TExa, dTCha = dTCha);
end Temperature_u;


Model for a exterior (outside) convective heat transfer. This is a model for a convective heat transfer for exterior, outside-facing surfaces.
The parameter conMod determines the model that is used to compute
the heat transfer coefficient:

within Buildings.HeatTransfer.Convection;
model Exterior "Model for a exterior (outside) convective heat transfer"
  extends Buildings.HeatTransfer.Convection.BaseClasses.PartialConvection;

  parameter Buildings.HeatTransfer.Types.ExteriorConvection conMod=
    Buildings.HeatTransfer.Types.ExteriorConvection.TemperatureWind
    "Convective heat transfer model"

  parameter Modelica.Units.SI.CoefficientOfHeatTransfer hFixed=3
    "Constant convection coefficient"

  parameter Buildings.HeatTransfer.Types.SurfaceRoughness roughness=
    Buildings.HeatTransfer.Types.SurfaceRoughness.Medium "Surface roughness"
  parameter Modelica.Units.SI.Angle azi "Surface azimuth";

  parameter Modelica.Units.SI.Angle til(displayUnit="deg") "Surface tilt"

  Modelica.Blocks.Interfaces.RealInput v(unit="m/s") "Wind speed"
  Modelica.Blocks.Interfaces.RealInput dir(unit="rad", displayUnit="deg",
     min=0, max=2*Modelica.Constants.pi) "Wind direction (0=wind from North)"
  Modelica.Units.SI.CoefficientOfHeatTransfer hF
    "Convective heat transfer coefficient due to forced convection";
  Modelica.Units.SI.HeatFlux qN_flow
    "Convective heat flux from solid -> fluid due to natural convection";
  Modelica.Units.SI.HeatFlux qF_flow
    "Convective heat flux from solid -> fluid due to forced convection";
protected
  constant Modelica.Units.SI.Velocity v_small=0.5
    "Small value for wind velocity below which equations are regularized";
  final parameter Real cosTil=Modelica.Math.cos(til) "Cosine of window tilt";
  final parameter Real sinTil=Modelica.Math.sin(til) "Sine of window tilt";
  final parameter Boolean is_ceiling = abs(sinTil) < 10E-10 and cosTil > 0
    "Flag, true if the surface is a ceiling";
  final parameter Boolean is_floor = abs(sinTil) < 10E-10 and cosTil < 0
    "Flag, true if the surface is a floor";

  parameter Real R(fixed=false) "Surface roughness";

  Real W(min=0.5, max=1) "Wind direction modifier";

initial equation
  if (roughness == Buildings.HeatTransfer.Types.SurfaceRoughness.VeryRough) then
    R=2.17;
  elseif (roughness == Buildings.HeatTransfer.Types.SurfaceRoughness.Rough) then
    R=1.67;
  elseif (roughness == Buildings.HeatTransfer.Types.SurfaceRoughness.Medium) then
    R=1.52;
  elseif (roughness == Buildings.HeatTransfer.Types.SurfaceRoughness.MediumSmooth) then
    R=1.13;
  elseif (roughness == Buildings.HeatTransfer.Types.SurfaceRoughness.Smooth) then
    R=1.11;
  elseif (roughness == Buildings.HeatTransfer.Types.SurfaceRoughness.VerySmooth) then
    R=1.00;
  else
    R=0;
  end if;
equation
  if (conMod == Buildings.HeatTransfer.Types.ExteriorConvection.Fixed) then
    qN_flow = hFixed * dT;
    W = 1;
    hF = 0;
    qF_flow = 0;
  else
    // Even if hCon is a step function with a step at zero,
    // the product hCon*dT is differentiable at zero with
    // a continuous first derivative
    if is_ceiling then
       qN_flow = Buildings.HeatTransfer.Convection.Functions.HeatFlux.ceiling(dT=dT);
    elseif is_floor then
       qN_flow = Buildings.HeatTransfer.Convection.Functions.HeatFlux.floor(dT=dT);
    else
       qN_flow = Buildings.HeatTransfer.Convection.Functions.HeatFlux.wall(dT=dT);
    end if;
    // Forced convection
    W = Buildings.Utilities.Math.Functions.regStep(
          x = v-v_small/2,
          y1 = Buildings.HeatTransfer.Convection.Functions.windDirectionModifier(
            azi=azi,
            dir=dir),
          y2 = 0.75,
          x_small=v_small/4);
    hF = 2.537 * W * R * 2 / A^(0.25) *
       Buildings.Utilities.Math.Functions.regNonZeroPower(
           x=v,
           n=0.5,
           delta=v_small);
    qF_flow = hF*dT;
  end if;
  q_flow = qN_flow + qF_flow;
end Exterior;


Model for a interior (room-side) convective heat transfer. This is a model for a convective heat transfer for interior, room-facing surfaces.
The parameter conMod determines the model that is used to compute
the heat transfer coefficient:

within Buildings.HeatTransfer.Convection;
model Interior "Model for a interior (room-side) convective heat transfer"
  extends Buildings.HeatTransfer.Convection.BaseClasses.PartialConvection;

  constant Boolean homotopyInitialization = true "= true, use homotopy method"

  parameter Buildings.HeatTransfer.Types.InteriorConvection conMod=
    Buildings.HeatTransfer.Types.InteriorConvection.Fixed
    "Convective heat transfer model"

  parameter Modelica.Units.SI.CoefficientOfHeatTransfer hFixed=3
    "Constant convection coefficient"

  parameter Modelica.Units.SI.Angle til(displayUnit="deg") "Surface tilt"

protected
  constant Modelica.Units.SI.Temperature dT0=2
    "Initial temperature used in homotopy method";

  final parameter Real cosTil=Modelica.Math.cos(til) "Cosine of window tilt";
  final parameter Real sinTil=Modelica.Math.sin(til) "Sine of window tilt";
  final parameter Boolean is_ceiling = abs(sinTil) < 10E-10 and cosTil > 0
    "Flag, true if the surface is a ceiling";
  final parameter Boolean is_floor = abs(sinTil) < 10E-10 and cosTil < 0
    "Flag, true if the surface is a floor";

initial equation
  assert(homotopyInitialization, "In " + getInstanceName() +
    ": The constant homotopyInitialization has been modified from its default value. This constant will be removed in future releases.",
    level = AssertionLevel.warning);

equation
  if (conMod == Buildings.HeatTransfer.Types.InteriorConvection.Fixed) then
    q_flow = hFixed * dT;
  else
    // Even if hCon is a step function with a step at zero,
    // the product hCon*dT is differentiable at zero with
    // a continuous first derivative
    if homotopyInitialization then
      if is_ceiling then
         q_flow = homotopy(actual=Buildings.HeatTransfer.Convection.Functions.HeatFlux.ceiling(dT=dT),
                    simplified=dT/dT0*Buildings.HeatTransfer.Convection.Functions.HeatFlux.ceiling(dT=dT0));
      elseif is_floor then
         q_flow = homotopy(actual=Buildings.HeatTransfer.Convection.Functions.HeatFlux.floor(dT=dT),
                    simplified=dT/dT0*Buildings.HeatTransfer.Convection.Functions.HeatFlux.floor(dT=dT0));
      else
         q_flow = homotopy(actual=Buildings.HeatTransfer.Convection.Functions.HeatFlux.wall(dT=dT),
                    simplified=dT/dT0*Buildings.HeatTransfer.Convection.Functions.HeatFlux.wall(dT=dT0));
      end if;
    else
      if is_ceiling then
         q_flow = Buildings.HeatTransfer.Convection.Functions.HeatFlux.ceiling(dT=dT);
      elseif is_floor then
         q_flow = Buildings.HeatTransfer.Convection.Functions.HeatFlux.floor(dT=dT);
      else
         q_flow = Buildings.HeatTransfer.Convection.Functions.HeatFlux.wall(dT=dT);
      end if;
    end if;

  end if;
end Interior;


within Buildings.HeatTransfer;
package Convection "Package with models for convective heat transfer"
  extends Modelica.Icons.VariantsPackage;
end Convection;


within Buildings.HeatTransfer.Convection;
package BaseClasses "Package with base classes for Buildings.HeatTransfer.Convection"
  extends Modelica.Icons.BasesPackage;
end BaseClasses;


Partial model for heat convection.

within Buildings.HeatTransfer.Convection.BaseClasses;
partial model PartialConvection "Partial model for heat convection"
  extends Buildings.BaseClasses.BaseIcon;
  parameter Modelica.Units.SI.Area A "Heat transfer area";

  Modelica.Units.SI.HeatFlowRate Q_flow "Heat flow rate from solid -> fluid";
  Modelica.Units.SI.HeatFlux q_flow "Convective heat flux from solid -> fluid";
  Modelica.Units.SI.TemperatureDifference dT(start=0) "= solid.T - fluid.T";
  Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a solid
  Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b fluid

equation
  dT = solid.T - fluid.T;
  solid.Q_flow = Q_flow;
  fluid.Q_flow = -Q_flow;
  Q_flow = A*q_flow;
end PartialConvection;


Test model for exterior heat transfer coefficients.

within Buildings.HeatTransfer.Convection.Examples;
model Exterior "Test model for exterior heat transfer coefficients"
  extends Modelica.Icons.Example;
  Modelica.Blocks.Sources.Constant T1(k=290.15)
  Buildings.HeatTransfer.Sources.FixedTemperature TB(T=293.15)
  Buildings.HeatTransfer.Convection.Exterior nor(
    A=1,
    azi=Buildings.Types.Azimuth.N,
    til=Buildings.Types.Tilt.Wall,
    conMod=Buildings.HeatTransfer.Types.ExteriorConvection.TemperatureWind)
    "North-facing wall"
  Buildings.HeatTransfer.Convection.Exterior wes(
    A=1,
    azi=Buildings.Types.Azimuth.W,
    til=Buildings.Types.Tilt.Wall,
    conMod=Buildings.HeatTransfer.Types.ExteriorConvection.TemperatureWind)
    "West facing wall"
  Buildings.HeatTransfer.Sources.PrescribedTemperature TA1
  Buildings.HeatTransfer.Sources.PrescribedTemperature TA2
  Buildings.HeatTransfer.Sources.PrescribedTemperature TA3
  Buildings.HeatTransfer.Sources.PrescribedTemperature TA4
  Buildings.HeatTransfer.Convection.Exterior sou(
    A=1,
    azi=Buildings.Types.Azimuth.S,
    til=Buildings.Types.Tilt.Wall,
    conMod=Buildings.HeatTransfer.Types.ExteriorConvection.TemperatureWind)
    "South facing wall"
  Buildings.HeatTransfer.Convection.Exterior eas(
    A=1,
    azi=Buildings.Types.Azimuth.E,
    til=Buildings.Types.Tilt.Wall,
    conMod=Buildings.HeatTransfer.Types.ExteriorConvection.TemperatureWind)
    "East facing wall"
  Buildings.HeatTransfer.Sources.FixedTemperature TB1(T=293.15)
  Buildings.HeatTransfer.Sources.FixedTemperature TB2(T=293.15)
  Buildings.HeatTransfer.Sources.FixedTemperature TB3(T=293.15)
  Modelica.Blocks.Sources.Ramp direction(duration=3600, height=2*3.14159)
    "Wind direction (0=from north)"
  Modelica.Blocks.Sources.Constant vWin(k=2) "Wind speed"
equation
  connect(T1.y, TA4.T)
  connect(T1.y, TA3.T)
  connect(T1.y, TA2.T)
  connect(T1.y, TA1.T)
  connect(TA1.port, nor.solid)
  connect(TA2.port, wes.solid)
  connect(TA3.port, sou.solid)
  connect(TA4.port, eas.solid)
  connect(nor.fluid, TB.port)
  connect(wes.fluid, TB1.port)
  connect(eas.fluid, TB2.port)
  connect(sou.fluid, TB3.port)
  connect(vWin.y, wes.v)
  connect(vWin.y, nor.v)
  connect(vWin.y, eas.v)
  connect(vWin.y, sou.v)
  connect(direction.y, nor.dir)
  connect(direction.y, sou.dir)
  connect(direction.y, wes.dir)
  connect(direction.y, eas.dir)
end Exterior;


Test model for convective heat transfer coefficients.

within Buildings.HeatTransfer.Convection.Examples;
model Interior "Test model for convective heat transfer coefficients"
  extends Modelica.Icons.Example;
  Modelica.Blocks.Sources.Ramp step(
    duration=1,
    startTime=0,
    height=10,
    offset=293.15 - 5)
  Buildings.HeatTransfer.Sources.FixedTemperature TB(T=293.15)
  Buildings.HeatTransfer.Convection.Interior conCon(
                                           A=1,
  til=Buildings.Types.Tilt.Wall)
  Buildings.HeatTransfer.Convection.Interior conVer(
                                           A=1,
  til=Buildings.Types.Tilt.Wall,
  conMod=Buildings.HeatTransfer.Types.InteriorConvection.Temperature)
  Buildings.HeatTransfer.Sources.PrescribedTemperature TA1
  Buildings.HeatTransfer.Sources.PrescribedTemperature TA2
  Buildings.HeatTransfer.Sources.PrescribedTemperature TA3
  Buildings.HeatTransfer.Sources.PrescribedTemperature TA4
  Buildings.HeatTransfer.Convection.Interior conHorFluTop(
    A=1,
    til=Buildings.Types.Tilt.Floor,
    conMod=Buildings.HeatTransfer.Types.InteriorConvection.Temperature)
    "Convection model with fluid on top"
  Buildings.HeatTransfer.Convection.Interior conHorSolTop(
    A=1,
    til=Buildings.Types.Tilt.Ceiling,
    conMod=Buildings.HeatTransfer.Types.InteriorConvection.Temperature)
    "Convection model with solid on top"
  Buildings.HeatTransfer.Sources.FixedTemperature TB1(T=293.15)
  Buildings.HeatTransfer.Sources.FixedTemperature TB2(T=293.15)
  Buildings.HeatTransfer.Sources.FixedTemperature TB3(T=293.15)
equation
  connect(conCon.solid, TB.port)
  connect(step.y, TA4.T)
  connect(step.y, TA3.T)
  connect(step.y, TA2.T)
  connect(step.y, TA1.T)
  connect(TA1.port, conCon.fluid)
  connect(TA2.port, conVer.fluid)
  connect(TA3.port, conHorFluTop.fluid)
  connect(TA4.port, conHorSolTop.fluid)
  connect(TB1.port, conVer.solid)
  connect(TB2.port, conHorFluTop.solid)
  connect(TB3.port, conHorSolTop.solid)
end Interior;


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


Functions for convective heat transfer

within Buildings.HeatTransfer.Convection;
package Functions "Functions for convective heat transfer"
end Functions;


Correlations for convective heat flux

within Buildings.HeatTransfer.Convection.Functions;
package HeatFlux "Correlations for convective heat flux"
end HeatFlux;


within Buildings.HeatTransfer.Convection.Functions.HeatFlux;
package BaseClasses "Base classes for convective heat transfer coefficients"
  extends Modelica.Icons.BasesPackage;
end BaseClasses;


Collection of validation models

within Buildings.HeatTransfer.Convection;
package Validation "Collection of validation models"
  extends Modelica.Icons.ExamplesPackage;
end Validation;


Validation model for zero wind speed. This example tests the convective heat transfer models for exterior surfaces if the wind speed is zero.
From <i>t=0...3600</i> seconds, the wind traverses from North to West to South to East and back to
North. The plot validates that there is no influence of the wind direction on the forced convection
coefficient for wall surfaces that face North, West, East and South if the wind speed is zero.

within Buildings.HeatTransfer.Convection.Validation;
model ZeroWindSpeed "Validation model for zero wind speed"
  extends Buildings.HeatTransfer.Convection.Examples.Exterior(vWin(k=0));
end ZeroWindSpeed;


Base classes for package Data

within Buildings.HeatTransfer.Data;
package BaseClasses "Base classes for package Data"
  extends Modelica.Icons.BasesPackage;
  record Material "Thermal properties of materials w/o storage"
    extends Modelica.Icons.Record;
    parameter Modelica.Units.SI.Length x "Material thickness";
    parameter Modelica.Units.SI.ThermalConductivity k "Thermal conductivity";
    parameter Modelica.Units.SI.SpecificHeatCapacity c "Specific heat capacity";
    parameter Modelica.Units.SI.Density d(displayUnit="kg/m3") "Mass density";
    parameter Real R(unit="m2.K/W")
      "Thermal resistance of a unit area of material";
    parameter Integer nStaRef(min=0) = 3
      "Number of state variables in a reference material of 0.2 m concrete";
    parameter Integer nSta(min=1)=max(1, integer(ceil(nStaReal)))
      "Actual number of state variables in material"
    parameter Boolean steadyState= (c < Modelica.Constants.eps or d < Modelica.Constants.eps)
      "Flag, if true, then material is computed using steady-state heat conduction"
    parameter Real piRef=331.4
      "Ratio x/sqrt(alpha) for reference material of 0.2 m concrete"
    parameter Real piMat=if steadyState then piRef else x*sqrt(c*d/k)
      "Ratio x/sqrt(alpha)"
    parameter Real nStaReal(min=0) = nStaRef*piMat/piRef
      "Number of states as a real number"

    parameter Modelica.Units.SI.Temperature TSol
      "Solidus temperature, used only for PCM."
    parameter Modelica.Units.SI.Temperature TLiq
      "Liquidus temperature, used only for PCM"
    parameter Modelica.Units.SI.SpecificInternalEnergy LHea
      "Latent heat of phase change"

    constant Boolean ensureMonotonicity = false
      "Set to true to force derivatives dT/du to be monotone";

    constant Boolean phasechange = false
      "Flag, true if the material is a phase change material"
  end Material;

  record ThermalProperties "Thermal properties of materials with storage"
    extends Modelica.Icons.Record;
    parameter Modelica.Units.SI.ThermalConductivity k "Thermal conductivity";
    parameter Modelica.Units.SI.SpecificHeatCapacity c "Specific heat capacity";
    parameter Modelica.Units.SI.Density d(displayUnit="kg/m3") "Mass density";
    parameter Boolean steadyState= (c < Modelica.Constants.eps or d < Modelica.Constants.eps)
      "Flag, if true, then material is computed using steady-state heat conduction"
  end ThermalProperties;
end BaseClasses;


within Buildings.HeatTransfer.Data;
package BoreholeFillings
  "Package with materials for borehole fillings"
    extends Modelica.Icons.MaterialPropertiesPackage;

  record Generic =
      Buildings.HeatTransfer.Data.BaseClasses.ThermalProperties
    "Generic filling material"

  record Bentonite =
      Buildings.HeatTransfer.Data.BoreholeFillings.Generic (
      k=1.15,
      d=1600,
      c=800) "Bentonite (k=1.15)"

  record Concrete =
      Buildings.HeatTransfer.Data.BoreholeFillings.Generic (
      k=3.1,
      d=2000,
      c=840) "Concrete (k=3.1)"
end BoreholeFillings;


within Buildings.HeatTransfer.Data;
package Gases "Package with thermophysical properties for window fill gases"
    extends Modelica.Icons.MaterialPropertiesPackage;

  record Generic "Thermal properties of fill gas for windows"
      extends Modelica.Icons.Record;
    parameter Modelica.Units.SI.Length x "Gas layer thickness";
    parameter Modelica.Units.SI.ThermalConductivity a_k
      "Constant coefficient for thermal conductivity";
      parameter Real b_k(unit="W/(m.K2)")
      "Temperature dependent coefficient for thermal conductivity";
    parameter Modelica.Units.SI.DynamicViscosity a_mu
      "Constant coefficient for dynamic viscosity";
      parameter Real b_mu(unit="N.s/(m2.K)")
      "Temperature dependent coefficient for dynamic viscosity";
    parameter Modelica.Units.SI.SpecificHeatCapacity a_c
      "Constant coefficient for specific heat capacity";
      parameter Real b_c(unit="J/(kg.K2)")
      "Temperature dependent coefficient for specific heat capacity";

    parameter Modelica.Units.SI.MolarMass MM
      "Molar mass (of mixture or single fluid)";

    parameter Modelica.Units.SI.Pressure P0=101325 "Normal pressure";
  end Generic;

  record Air = Generic(a_k= 2.873E-3, b_k= 7.760E-5,
                       a_mu=3.723E-6, b_mu=4.940E-8,
                       a_c=1002.737,  b_c= 1.2324E-2,
                       MM=28.97E-3) "Thermophysical properties for air"

  record Argon = Generic(a_k= 2.285E-3, b_k= 5.149E-5,
                         a_mu=3.379E-6, b_mu=6.451E-8,
                         a_c=521.9285,  b_c= 0,
                         MM=39.948E-3) "Thermophysical properties for argon"

  record Krypton = Generic(a_k= 9.443E-4, b_k= 2.826E-5,
                           a_mu=2.213E-6, b_mu=7.777E-8,
                           a_c=248.0907,  b_c= 0,
                           MM=83.80E-3) "Thermophysical properties for krypton"

  record Xenon = Generic(a_k= 4.538E-4, b_k= 1.723E-5,
                         a_mu=1.069E-6, b_mu=7.414E-8,
                         a_c=158.3397,  b_c= 0,
                         MM=131.3E-3) "Thermophysical properties for krypton"

 function thermalConductivity
    "Function to compute the thermal conductivity of gases"
  input Buildings.HeatTransfer.Data.Gases.Generic gas "Record of gas data";
    input Modelica.Units.SI.Temperature T "Gas temperature";
    output Modelica.Units.SI.ThermalConductivity k "Thermal conductivity";
 algorithm
  k := gas.a_k + gas.b_k*T;
 end thermalConductivity;

function density "Function to compute the mass density"
  input Buildings.HeatTransfer.Data.Gases.Generic gas "Record of gas data";
    input Modelica.Units.SI.Temperature T "Gas temperature";
    output Modelica.Units.SI.Density rho "Mass density";
algorithm
    rho := gas.P0*gas.MM/Modelica.Constants.R/T;
end density;

function dynamicViscosity "Function to compute the dynamic viscosity for gases"
  input Buildings.HeatTransfer.Data.Gases.Generic gas "Record of gas data";
    input Modelica.Units.SI.Temperature T "Gas temperature";
    output Modelica.Units.SI.DynamicViscosity mu "Dynamic viscosity";
algorithm
    mu := gas.a_mu + gas.b_mu*T;
end dynamicViscosity;

function specificHeatCapacity
    "Function to compute the specific heat capacity for gases"
  input Buildings.HeatTransfer.Data.Gases.Generic gas "Record of gas data";
    input Modelica.Units.SI.Temperature T "Gas temperature";
    output Modelica.Units.SI.SpecificHeatCapacity c_p "Specific heat capacity";
algorithm
  c_p := gas.a_c + gas.b_c*T;
end specificHeatCapacity;
end Gases;


within Buildings.HeatTransfer.Data;
package Glasses "Package with thermophysical properties for window glas"
    extends Modelica.Icons.MaterialPropertiesPackage;
  record Generic "Thermal properties of window glass"
      extends Modelica.Icons.Record;
    parameter Modelica.Units.SI.Length x=0.003 "Thickness";
    parameter Modelica.Units.SI.ThermalConductivity k=1 "Thermal conductivity";
    parameter Modelica.Units.SI.TransmissionCoefficient tauSol[:]={0.6}
      "Solar transmittance";
    parameter Modelica.Units.SI.ReflectionCoefficient rhoSol_a[:]={0.075}
      "Solar reflectance of surface a (usually outside-facing surface)";
    parameter Modelica.Units.SI.ReflectionCoefficient rhoSol_b[:]={0.075}
      "Solar reflectance of surface b (usually room-facing surface)";
    parameter Modelica.Units.SI.TransmissionCoefficient tauIR=0
      "Infrared transmissivity of glass";
    parameter Modelica.Units.SI.Emissivity absIR_a=0.84
      "Infrared absorptivity of surface a (usually outside-facing surface)";
    parameter Modelica.Units.SI.Emissivity absIR_b=0.84
      "Infrared absorptivity of surface b (usually room-facing surface)";
  end Generic;

  record ID100 = Buildings.HeatTransfer.Data.Glasses.Generic (
      x=0.0031,
      k=1.0,
      tauSol={0.646},
      rhoSol_a={0.062},
      rhoSol_b={0.063},
      tauIR=0,
      absIR_a=0.84,
      absIR_b=0.84) "Generic Bronze Glass 3.1mm. Manufacturer: Generic."

  record ID101 = Buildings.HeatTransfer.Data.Glasses.Generic (
      x=0.0057,
      k=1.0,
      tauSol={0.486},
      rhoSol_a={0.053},
      rhoSol_b={0.053},
      tauIR=0,
      absIR_a=0.84,
      absIR_b=0.84) "Generic Bronze Glass 5.7mm. Manufacturer: Generic."

  record ID102 = Buildings.HeatTransfer.Data.Glasses.Generic (
      x=0.003,
      k=1.0,
      tauSol={0.834},
      rhoSol_a={0.075},
      rhoSol_b={0.075},
      tauIR=0,
      absIR_a=0.84,
      absIR_b=0.84) "Generic Clear Glass 3.048mm. Manufacturer: Generic."

  record ID103 = Buildings.HeatTransfer.Data.Glasses.Generic (
      x=0.0057,
      k=1.0,
      tauSol={0.771},
      rhoSol_a={0.070},
      rhoSol_b={0.070},
      tauIR=0,
      absIR_a=0.84,
      absIR_b=0.84) "Generic Clear Glass 5.7mm. Manufacturer: Generic."

  record Electrochromic = Buildings.HeatTransfer.Data.Glasses.Generic (
      x=0.006,
      k=0.9,
      tauSol={0.814, 0.111},
      rhoSol_a={0.086, 0.179},
      rhoSol_b={0.086, 0.179},
      tauIR=0,
      absIR_a=0.84,
      absIR_b=0.84) "Electrochromic Glass 6mm. Manufacturer: Generic."
end Glasses;


within Buildings.HeatTransfer.Data;
package GlazingSystems
  "Package with thermophysical properties for glazing systems"
    extends Modelica.Icons.MaterialPropertiesPackage;
  record Generic "Thermal properties of glazing systems"
      extends Modelica.Icons.Record;
  //  parameter Integer nLay(min=1, fixed=true) "Number of glass layers"
  //
    parameter Boolean haveExteriorShade = false
      "Set to true if window has an exterior shade (at surface a)"
    parameter Boolean haveInteriorShade = false
      "Set to true if window has an interior shade (at surface b)"

    parameter Glasses.Generic glass[:]
      "Layer by layer declaration of glass layers, starting from outside to room-side"
    // Zero array sizes are not supported in Dymola. Therefore, we assign
    // a dummy layer. The model for heat conduction in gases will
    // write an assert if the thickness is negative.
    // Therefore, we ensure that any model overwrites this default setting.
    parameter Gases.Generic gas[:] = {Buildings.HeatTransfer.Data.Gases.Air(x=-1)}
      "Layer by layer declaration of glass layers, starting from outside to room-side"
    parameter Shades.Generic shade "Shade"
    parameter Modelica.Units.SI.CoefficientOfHeatTransfer UFra
      "U-value of frame";
    parameter Modelica.Units.SI.Emissivity absIRFra=0.8
      "Infrared absorptivity of window frame";
    parameter Modelica.Units.SI.Emissivity absSolFra=0.5
      "Solar absorptivity of window frame";
    final parameter Boolean haveShade = haveInteriorShade or haveExteriorShade
      "Parameter that is true if the construction has a shade";
    final parameter Boolean haveControllableWindow=
      Modelica.Math.BooleanVectors.anyTrue(
        {size(glass[iGla].tauSol, 1) > 1 for iGla in 1:size(glass,1)})
      "Flag, true if the window allows multiple states, such as for electrochromic windows"
  end Generic;

  record SingleClear3 =
      Buildings.HeatTransfer.Data.GlazingSystems.Generic (
         glass={Glasses.ID102()},
         UFra=3) "Single pane, clear glass 3mm"

  record DoubleClearAir13Clear =
      Buildings.HeatTransfer.Data.GlazingSystems.Generic (
      final glass={Glasses.ID102(), Glasses.ID102()},
      final gas={Gases.Air(x=0.0127)},
      UFra=1.4) "Double pane, clear glass 3mm, air 12.7, clear glass 3mm"

  record DoubleElectrochromicAir13Clear =
      Buildings.HeatTransfer.Data.GlazingSystems.Generic (
      final glass={Glasses.Electrochromic(),
                   Buildings.HeatTransfer.Data.Glasses.Generic(
                     x=0.006,
                     k=0.9,
                     tauSol={0.775, 0.775},
                     rhoSol_a={0.071, 0.071},
                     rhoSol_b={0.071, 0.071},
                     tauIR=0,
                     absIR_a=0.84,
                     absIR_b=0.84)},
      final gas={Gases.Air(x=0.0127)},
      UFra=1.4) "Double pane, electrochromic 6mm, air 12.7, clear glass 6mm"

  record TripleClearAir13ClearAir13Clear =
      Buildings.HeatTransfer.Data.GlazingSystems.Generic (
      final glass={Glasses.ID102(),Glasses.ID102(),Glasses.ID102()},
      final gas={Gases.Air(x=0.0127),Gases.Air(x=0.0127)},
      UFra=1.4)
    "Triple pane, clear glass 3mm, air 12.7, clear glass 3mm, air 12.7, clear glass 3mm"

end GlazingSystems;


within Buildings.HeatTransfer.Data;
package OpaqueConstructions
  "Package with opaque constructions for floors, walls, etc."
    extends Modelica.Icons.MaterialPropertiesPackage;
  record Generic "Thermal properties of opaque constructions"

   parameter Integer nLay(min=1) "Number of layers";

   parameter Buildings.HeatTransfer.Data.BaseClasses.Material material[nLay]
      "Layer by layer declaration of material, starting from outside to room-side"
   final parameter Real R(unit="m2.K/W")=sum(material[i].R for i in 1:nLay)
      "Thermal resistance per unit area";
   final parameter Integer nSta[nLay](each min=1) = {material[i].nSta for i in 1:nLay}
      "Number of states in each layer"
    parameter Modelica.Units.SI.Emissivity absIR_a=0.9
      "Infrared absorptivity of surface a (usually outside-facing surface)";
    parameter Modelica.Units.SI.Emissivity absIR_b=0.9
      "Infrared absorptivity of surface b (usually room-facing surface)";
    parameter Modelica.Units.SI.Emissivity absSol_a=0.5
      "Solar absorptivity of surface a (usually outside-facing surface)";
    parameter Modelica.Units.SI.Emissivity absSol_b=0.5
      "Solar absorptivity of surface b (usually room-facing surface)";
   parameter Buildings.HeatTransfer.Types.SurfaceRoughness roughness_a=
      Buildings.HeatTransfer.Types.SurfaceRoughness.Medium
      "Exterior surface roughness";

  end Generic;

  record Insulation100Concrete200 =
      Buildings.HeatTransfer.Data.OpaqueConstructions.Generic (
        material={Solids.InsulationBoard(x=0.1),
                  Solids.Concrete(x=0.2)},
                  final nLay=2)
    "Construction with 100 mm insulation and 200 mm concrete"

  record Brick120 =
      Buildings.HeatTransfer.Data.OpaqueConstructions.Generic (
        material={Solids.Brick(x=0.12)},
        final nLay=1) "Construction with 120mm brick"

  record Concrete200 =
      Buildings.HeatTransfer.Data.OpaqueConstructions.Generic (
        material={Solids.Concrete(x=0.2)},
        final nLay=1) "Construction with 200mm concrete"

end OpaqueConstructions;


within Buildings.HeatTransfer.Data;
package OpaqueSurfaces
  "Package with thermophysical properties for opaque surfaces"
    extends Modelica.Icons.MaterialPropertiesPackage;

  record Generic "Thermal properties of opaque surfaces"
      extends Modelica.Icons.Record;
    parameter Modelica.Units.SI.Area A "Area";
    parameter Modelica.Units.SI.Angle til
      "Surface tilt (0: ceiling, pi/2: wall, pi: floor";
    parameter Modelica.Units.SI.Emissivity absIR=0.84 "Infrared absorptivity";
    parameter Modelica.Units.SI.Emissivity absSol=0.84 "Solar absorptivity";
   final parameter Boolean is_floor=til > 2.74889125 and til < 3.53428875
      "Flag, true if construction is a floor"
  end Generic;

  record Black=Buildings.HeatTransfer.Data.OpaqueSurfaces.Generic (absIR=1.0,
        absSol=1.0) "Black surface with absIR=1.0, absSol=1.0"

  record Gray=Buildings.HeatTransfer.Data.OpaqueSurfaces.Generic (absIR=0.5,
        absSol=0.5) "Gray surface with absIR=0.5, absSol=0.5"

  record White=Buildings.HeatTransfer.Data.OpaqueSurfaces.Generic (absIR=0.0,
        absSol=0.0) "White surface with absIR=0.0, absSol=0.0"
end OpaqueSurfaces;


Data for heat transfer models

within Buildings.HeatTransfer;
package Data "Data for heat transfer models"
    extends Modelica.Icons.MaterialPropertiesPackage;
end Data;


Package with thermal resistances

within Buildings.HeatTransfer.Data;
package Resistances "Package with thermal resistances"
    extends Modelica.Icons.MaterialPropertiesPackage;
  record Generic "Thermal properties of heat resistances"
      extends Buildings.HeatTransfer.Data.BaseClasses.Material(
      final c=0,
      final d=0,
      final k=0,
      final x=0,
      final nStaRef=0,
      final nSta=1,
      final steadyState=true,
      final TSol=293.15,
      final TLiq=293.15,
      final LHea=0,
      final phasechange=false);
  end Generic;

  record Carpet = Buildings.HeatTransfer.Data.Resistances.Generic (R=0.2165) "Carpet"
end Resistances;


within Buildings.HeatTransfer.Data;
package Shades "Package with thermophysical properties for window shades"
    extends Modelica.Icons.MaterialPropertiesPackage;
  record Generic "Thermal properties of window shades"
      extends Modelica.Icons.Record;
    parameter Modelica.Units.SI.TransmissionCoefficient tauSol_a=0.1
      "Solar transmissivity of shade surface a (surface that faces the outside or the room)";
    parameter Modelica.Units.SI.TransmissionCoefficient tauSol_b=0.1
      "Solar transmissivity of shade surface b (surface that faces the glass)";
    parameter Modelica.Units.SI.ReflectionCoefficient rhoSol_a=0.8
      "Solar reflection coefficient of shade surface a (surface that faces the outside or the room)";
    parameter Modelica.Units.SI.ReflectionCoefficient rhoSol_b=0.8
      "Solar reflection coefficient of shade surface b (surface that faces the glass)";
    parameter Modelica.Units.SI.Emissivity absIR_a=0.84
      "Infrared absorptivity of surface a (surface that faces the outside or the room)";
    parameter Modelica.Units.SI.Emissivity absIR_b=0.84
      "Infrared absorptivity of surface b (surface that faces the glass)";
    parameter Modelica.Units.SI.TransmissionCoefficient tauIR_a=0
      "Infrared transmissivity of surface a (surface that faces the outside or the room)";
    parameter Modelica.Units.SI.TransmissionCoefficient tauIR_b=0
      "Infrared transmissivity of surface b (surface that faces the glass)";
  end Generic;

  record Gray=Buildings.HeatTransfer.Data.Shades.Generic (
      tauSol_a = 0.25,
      tauSol_b = 0.25,
      rhoSol_a = 0.25,
      rhoSol_b = 0.25,
      absIR_a = 0.25,
      absIR_b = 0.25) "Gray"
end Shades;


within Buildings.HeatTransfer.Data;
package Soil
  "Package with solid material for soil, characterized by thermal conductance, density and specific heat capacity"
    extends Modelica.Icons.MaterialPropertiesPackage;
  record Generic "Thermal properties of solids with heat storage"
      extends Buildings.HeatTransfer.Data.BaseClasses.ThermalProperties;
  end Generic;

  record Granite = Buildings.HeatTransfer.Data.Soil.Generic (
      k=1.9,
      d=1920,
      c=790) "Granite (k=1.9)"

  record Concrete = Buildings.HeatTransfer.Data.Soil.Generic (
      k=3.1,
      d=2000,
      c=840) "Concrete (k=3.1)"

  record Basalt =
      Buildings.HeatTransfer.Data.Soil.Generic (
      k=2.3,
      d=1140,
      c=1200) "Basalt (k=2.3)"

  record Marble =
      Buildings.HeatTransfer.Data.Soil.Generic (
      k=2.7,
      d=2500,
      c=1090) "Marble (k=2.7)"

  record Sandstone = Buildings.HeatTransfer.Data.Soil.Generic (
      k=2.8,
      d=540,
      c=1210) "Sandstone (k=2.8)"
end Soil;


within Buildings.HeatTransfer.Data;
package Solids
  "Package with solid material, characterized by thermal conductance, density and specific heat capacity"
    extends Modelica.Icons.MaterialPropertiesPackage;

  record Generic "Thermal properties of solids with heat storage"
      extends Buildings.HeatTransfer.Data.BaseClasses.Material(final R=x/k,
                                                               final TSol=293.15,
                                                               final TLiq=293.15,
                                                               final LHea=0,
                                                               final phasechange=false);
  end Generic;

  record Brick = Buildings.HeatTransfer.Data.Solids.Generic (
      k=0.89,
      d=1920,
      c=790) "Brick (k=0.89)"

  record Concrete = Buildings.HeatTransfer.Data.Solids.Generic (
      k=1.4,
      d=2240,
      c=840) "Concrete (k=1.4)"

  record InsulationBoard = Buildings.HeatTransfer.Data.Solids.Generic (
      k=0.03,
      d=40,
      c=1200) "Insulation board (k=0.03)"

  record Glass = Buildings.HeatTransfer.Data.Solids.Generic (
      k=1.0,
      d=2500,
      c=700) "Glass"

  record GypsumBoard = Buildings.HeatTransfer.Data.Solids.Generic (
      k=0.16,
      d=800,
      c=1090) "Gypsum board (k=0.58)"

  record Plywood = Buildings.HeatTransfer.Data.Solids.Generic (
      k=0.12,
      d=540,
      c=1210) "Plywood (k=0.12)"

  record Steel = Buildings.HeatTransfer.Data.Solids.Generic (
      k=50.2,
      d=7850,
      c=450,
      steadyState=true) "Steel (k=50.2)"
end Solids;


within Buildings.HeatTransfer.Data;
package SolidsPCM
  "Package with solid material, characterized by thermal conductance, density and specific heat capacity"
    extends Modelica.Icons.MaterialPropertiesPackage;

  record Generic "Thermal properties of solids with heat storage"
      extends Buildings.HeatTransfer.Data.BaseClasses.Material(final R=x/k,
                                                               final phasechange=true);

  end Generic;

  record PCM020 =Buildings.HeatTransfer.Data.SolidsPCM.Generic (
      k=0.204,
      d=800,
      c=1341,
      TSol=273.15+23,
      TLiq=273.15+27,
      LHea=38900) "Wallboard with 20% of microencapsulated paraffin"

  record PCM030 =Buildings.HeatTransfer.Data.SolidsPCM.Generic (
      k=0.232,
      d=998,
      c=1467,
      TSol=273.15+24,
      TLiq=273.15+26,
      LHea=58300) "Wallboard with 30% of microencapsulated paraffin"

  record MicronalSmartBoard23 =
    Buildings.HeatTransfer.Data.SolidsPCM.Generic (
      k=0.18,
      d=767,
      c=1200,
      TSol=273.15+22.99,
      TLiq=273.15+23.01,
      LHea=28696) "Micronal PCM SmartBoard 23"

  record MicronalSmartBoard26 =
    Buildings.HeatTransfer.Data.SolidsPCM.Generic (
      k=0.18,
      d=767,
      c=1200,
      TSol=273.15+25.99,
      TLiq=273.15+26.01,
      LHea=28696) "Micronal PCM SmartBoard 26"
end SolidsPCM;


Test model for heat conductor initialization. This example illustrates how to initialize heat conductors in steady state and with
predefined temperatures.

within Buildings.HeatTransfer.Examples;
model ConductorInitialization "Test model for heat conductor initialization"
  extends Modelica.Icons.Example;
  Buildings.HeatTransfer.Sources.FixedTemperature TB(T=303.15)
  Buildings.HeatTransfer.Sources.PrescribedTemperature TA

  parameter Buildings.HeatTransfer.Data.Solids.Brick brick(x=0.18, nStaRef=3,
    nSta=5)
  parameter Buildings.HeatTransfer.Data.Solids.InsulationBoard insulation(x=0.05, nStaRef=2,
    nSta=5)
  parameter Buildings.HeatTransfer.Data.OpaqueConstructions.Generic compositeWall(
      material={insulation,brick}, nLay=2)
    "Composite wall consisting of insulation and material"

  Buildings.HeatTransfer.Conduction.MultiLayer conS1(
    A=2,
    steadyStateInitial=true,
    layers=compositeWall,
    stateAtSurface_a=false,
    stateAtSurface_b=false)

  Modelica.Blocks.Sources.Step step(
    height=10,
    offset=283.15,
    startTime=43200)

equation
  connect(step.y, TA.T)
  connect(conS1.port_b, TB.port)
  connect(TA.port, conS1.port_a)
end ConductorInitialization;


Test model for heat conductor. This example illustrates how to use a solid material, set its heat capacity to zero,
and then use this material in a multi-layer construction.
The plot window shows that the insulation is computed in steady state, where
as the brick is computed using transient heat conduction.

within Buildings.HeatTransfer.Examples;
model ConductorMultiLayer "Test model for heat conductor"
  extends Modelica.Icons.Example;
  Buildings.HeatTransfer.Sources.FixedTemperature TB(T=293.15)
  Buildings.HeatTransfer.Sources.PrescribedTemperature TA
  Modelica.Blocks.Sources.Step step(
    height=10,
    offset=293.15,
    startTime=43200)
  Buildings.HeatTransfer.Conduction.MultiLayer con(
    steadyStateInitial=false,
    redeclare
      Buildings.HeatTransfer.Data.OpaqueConstructions.Insulation100Concrete200
      layers,
    A=0.1,
    stateAtSurface_b=false)
  Buildings.HeatTransfer.Convection.Interior conv(
    A=0.1,
    til=Buildings.Types.Tilt.Wall)
    "Convective heat transfer"
equation
  connect(step.y, TA.T)
  connect(con.port_b, TB.port)
  connect(conv.fluid, TA.port)
  connect(conv.solid, con.port_a)
end ConductorMultiLayer;


Test model for multi layer heat conductor with one
  state added at the surface a of the construction. This example is similar to
Buildings.HeatTransfer.Examples.ConductorMultiLayer. The main difference
is that a state is added at the surface a of the construction.

within Buildings.HeatTransfer.Examples;
model ConductorMultiLayer2
  "Test model for multi layer heat conductor with one
  state added at the surface a of the construction"
  extends ConductorMultiLayer;
end ConductorMultiLayer2;


Test model for multi layer heat conductor with one
  state added at the surfaces a and b of the construction. This example is similar to
Buildings.HeatTransfer.Examples.ConductorMultiLayer. The main difference
is that a state is added at the surfaces a and b of the construction.

within Buildings.HeatTransfer.Examples;
model ConductorMultiLayer3
  "Test model for multi layer heat conductor with one
  state added at the surfaces a and b of the construction"
  extends ConductorMultiLayer;
end ConductorMultiLayer3;


Test model for heat conductor. This example tests if two conductors in series computes the same heat transfer
as one conductor with twice the thickness.

within Buildings.HeatTransfer.Examples;
model ConductorSingleLayer "Test model for heat conductor"
  extends Modelica.Icons.Example;
  Buildings.HeatTransfer.Conduction.SingleLayer con(A=1, material=concrete200,
    stateAtSurface_b=true)
  Buildings.HeatTransfer.Sources.FixedTemperature TB(T=293.15)
  Buildings.HeatTransfer.Sources.PrescribedTemperature TA
  Modelica.Blocks.Sources.Step step(
    height=10,
    offset=293.15,
    startTime=3600)
  Buildings.HeatTransfer.Conduction.SingleLayer con1(
    A=1, material=concrete100,
    stateAtSurface_b=false)
  Buildings.HeatTransfer.Sources.FixedTemperature TB1(      T=293.15)
  Buildings.HeatTransfer.Sources.PrescribedTemperature TA1
  Buildings.HeatTransfer.Conduction.SingleLayer con2(
    A=1, material=concrete100,
    stateAtSurface_a=false,
    stateAtSurface_b=true)
  Modelica.Thermal.HeatTransfer.Sensors.HeatFlowSensor heaFlo2
  Modelica.Thermal.HeatTransfer.Sensors.HeatFlowSensor heaFlo1
  parameter Buildings.HeatTransfer.Data.Solids.Concrete concrete200(x=0.2, nSta=4)
  parameter Buildings.HeatTransfer.Data.Solids.Concrete concrete100(x=0.1, nSta=2)
  Buildings.HeatTransfer.Convection.Interior conv1(      A=1, til=Buildings.Types.Tilt.Wall)
    "Convective heat transfer"
  Buildings.HeatTransfer.Convection.Interior conv2(      A=1, til=Buildings.Types.Tilt.Wall)
    "Convective heat transfer"
  Modelica.Blocks.Math.Add cheEqu(k2=-1) "Checks for equality of the results"
equation
  connect(con.port_b, TB.port)
  connect(step.y, TA.T)
  connect(step.y, TA1.T)
  connect(con1.port_b, con2.port_a)
  connect(con2.port_b, TB1.port)
  connect(heaFlo2.port_b, con1.port_a)
  connect(heaFlo1.port_b, con.port_a)
  connect(TA.port, conv1.fluid)
  connect(TA1.port, conv2.fluid)
  connect(conv2.solid, heaFlo2.port_a)
  connect(conv1.solid, heaFlo1.port_a)
  connect(heaFlo1.Q_flow, cheEqu.u1)
  connect(heaFlo2.Q_flow, cheEqu.u2)
end ConductorSingleLayer;


Test model for single layer heat conductor without
  states added at the surfaces of the construction. This example is similar to
Buildings.HeatTransfer.Examples.ConductorSingleLayer. The main difference
is that there are no states at the surfaces of the construction.

within Buildings.HeatTransfer.Examples;
model ConductorSingleLayer2
    "Test model for single layer heat conductor without
  states added at the surfaces of the construction"
  extends ConductorSingleLayer(
    con(stateAtSurface_a=false, stateAtSurface_b=false),
    con1(stateAtSurface_a=false, stateAtSurface_b=false),
    con2(stateAtSurface_a=false, stateAtSurface_b=false));
end ConductorSingleLayer2;


Test model for heat conduction in a cylinder. This example tests a circular conductor with a constant temperature at his boundary.

within Buildings.HeatTransfer.Examples;
model ConductorSingleLayerCylinder
  "Test model for heat conduction in a cylinder"
  extends Modelica.Icons.Example;
  parameter Modelica.Units.SI.HeatFlowRate Q_flow=50;
  Buildings.HeatTransfer.Conduction.SingleLayerCylinder
                     con( material=concrete,
                     steadyStateInitial=false,
                     final nSta=8,
                     r_a=0.1,
                     r_b=3,
    h=10,
    TInt_start=293.15,
    TExt_start=293.15)
  Buildings.HeatTransfer.Sources.PrescribedHeatFlow Qa
  parameter Buildings.HeatTransfer.Data.Soil.Concrete concrete
 Modelica.Blocks.Sources.Step step(
    offset=0,
    height=Q_flow,
    startTime=3600)
  Buildings.HeatTransfer.Sources.FixedTemperature TBou(T=293.15)
    "Boundary condition"
equation
  connect(Qa.port, con.port_a)
  connect(step.y, Qa.Q_flow)
  connect(TBou.port, con.port_b)
end ConductorSingleLayerCylinder;


Test model for heat conductor. This example tests the implementation of the phase-change material (PCM) model.

within Buildings.HeatTransfer.Examples;
model ConductorSingleLayerPCM "Test model for heat conductor"
  extends Modelica.Icons.Example;
  Buildings.HeatTransfer.Sources.PrescribedTemperature TA
    "Temperature boundary condition"
  Modelica.Blocks.Sources.Step step(
    height=10,
    offset=293.15,
    startTime=360)
  Buildings.HeatTransfer.Sources.PrescribedTemperature TA1
    "Temperature boundary condition"
  Modelica.Thermal.HeatTransfer.Sensors.HeatFlowSensor heaFlo2
    "Heat flow sensor"
  Modelica.Thermal.HeatTransfer.Sensors.HeatFlowSensor heaFlo1
    "Heat flow sensor"
  Modelica.Blocks.Math.Add cheEqu(k2=-1) "Checks for equality of the results"
  parameter Buildings.HeatTransfer.Data.Solids.Concrete concrete100(x=0.1, nStaRef=4)
    "Non-PCM material"
  Buildings.HeatTransfer.Convection.Interior conv1(      A=1, til=Buildings.Types.Tilt.Wall)
    "Convective heat transfer"
  Buildings.HeatTransfer.Convection.Interior conv2(      A=1, til=Buildings.Types.Tilt.Wall)
    "Convective heat transfer"
  Buildings.HeatTransfer.Conduction.SingleLayer conPCM(
    A=1,
    material=matPCM,
    stateAtSurface_b=true)
                     "Construction with phase change around 40 degC"
  Buildings.HeatTransfer.Conduction.SingleLayer con1(
    A=1, material=concrete100,
    stateAtSurface_b=false)    "Construction without PCM"
  Buildings.HeatTransfer.Conduction.SingleLayer con2(
    A=1, material=concrete100,
    stateAtSurface_a=false,
    stateAtSurface_b=true)     "Construction without PCM"
  parameter Buildings.HeatTransfer.Data.SolidsPCM.Generic matPCM(
    x=0.2,
    k=1.4,
    c=840,
    d=2240,
    nSta=4,
    TSol=273.15 + 40.49,
    TLiq=273.15 + 40.51,
    LHea=100000) "PCM material with phase change near 40 degC"
  Buildings.HeatTransfer.Sources.PrescribedTemperature TA2
    "Temperature boundary condition"
  Buildings.HeatTransfer.Convection.Interior conv3(      A=1, til=Buildings.Types.Tilt.Wall)
    "Convective heat transfer"
  Buildings.HeatTransfer.Conduction.SingleLayer conPCM2(
    A=1,
    material=matPCM2,
    stateAtSurface_b=false)
                      "Construction with phase change near room temperature"
  parameter Buildings.HeatTransfer.Data.SolidsPCM.Generic matPCM2(
    x=0.2,
    k=1.4,
    c=840,
    d=2240,
    nSta=4,
    TSol=273.15 + 20.49,
    TLiq=273.15 + 20.51,
    LHea=100000) "PCM material with phase change near room temperature"
equation
  connect(step.y, TA.T)
  connect(step.y, TA1.T)
  connect(cheEqu.u1, heaFlo2.Q_flow)
  connect(cheEqu.u2, heaFlo1.Q_flow)
  connect(TA.port, conv1.fluid)
  connect(TA1.port, conv2.fluid)
  connect(conv2.solid, heaFlo2.port_a)
  connect(conv1.solid, heaFlo1.port_a)
  connect(heaFlo1.port_b, conPCM.port_a)
  connect(heaFlo2.port_b, con1.port_a)
  connect(con1.port_b, con2.port_a)
  connect(step.y, TA2.T)
  connect(TA2.port, conv3.fluid)
  connect(conv3.solid, conPCM2.port_a)
end ConductorSingleLayerPCM;


Test model for heat conductor. This example illustrates modeling of multi-layer materials. It also tests if the
multi-layer material computes the same heat transfer with its boundary condition
as two instances of a single layer material.
The insulation is computed in steady-state, whereas the brick is computed using transient
heat conduction.

within Buildings.HeatTransfer.Examples;
model ConductorSteadyStateTransient "Test model for heat conductor"
  extends Modelica.Icons.Example;

  parameter Buildings.HeatTransfer.Data.Solids.Brick brick(x=0.12, nStaRef=4)
  parameter Buildings.HeatTransfer.Data.Solids.InsulationBoard insul(
    x=0.05,
    c=0,
    nStaRef=3) "Insulation"
  parameter Buildings.HeatTransfer.Data.OpaqueConstructions.Generic composite(nLay=2, material=
       {insul,brick})

  Buildings.HeatTransfer.Conduction.MultiLayer conMul(
    A=2, layers=composite,
    stateAtSurface_b=false)
  Buildings.HeatTransfer.Conduction.SingleLayer con(
    A=2, material=brick,
    stateAtSurface_a=false,
    stateAtSurface_b=false)

  Buildings.HeatTransfer.Sources.FixedTemperature TB(T=293.15)
  Buildings.HeatTransfer.Sources.PrescribedTemperature TA

  Modelica.Blocks.Sources.Step step(
    height=10,
    offset=293.15,
    startTime=3600)
  Buildings.HeatTransfer.Conduction.SingleLayer con1(
    A=2, material=insul,
    stateAtSurface_b=false)
  Buildings.HeatTransfer.Sources.FixedTemperature TB1(T=293.15)
  Buildings.HeatTransfer.Sources.PrescribedTemperature TA1
  Buildings.HeatTransfer.Conduction.SingleLayer con2(
    A=2, material=brick,
    stateAtSurface_b=false,
    stateAtSurface_a=false)
  Buildings.HeatTransfer.Sources.PrescribedTemperature TA2
  Buildings.HeatTransfer.Sources.FixedTemperature TB2(T=293.15)
  Modelica.Thermal.HeatTransfer.Sensors.HeatFlowSensor heaFlo1
  Modelica.Thermal.HeatTransfer.Sensors.HeatFlowSensor heaFlo2
  Modelica.Blocks.Math.Add cheEqu(k2=-1) "Check for equality"
  Buildings.HeatTransfer.Convection.Interior conv1(A=2, til=Buildings.Types.Tilt.Wall)
    "Convective heat transfer"
  Buildings.HeatTransfer.Convection.Interior conv2(A=2, til=Buildings.Types.Tilt.Wall)
    "Convective heat transfer"
equation
  connect(con.port_b, TB.port)
  connect(step.y, TA.T)
  connect(step.y, TA1.T)
  connect(con1.port_b, con2.port_a)
  connect(con2.port_b, TB1.port)
  connect(TA2.T, step.y)
  connect(heaFlo1.port_b, con1.port_a)
  connect(cheEqu.u1, heaFlo2.Q_flow)
  connect(cheEqu.u2, heaFlo1.Q_flow)
  connect(TA.port, con.port_a)
  connect(conMul.port_b, TB2.port)
  connect(conMul.port_a, heaFlo2.port_b)
  connect(TA1.port, conv1.fluid)
  connect(conv1.solid, heaFlo1.port_a)
  connect(TA2.port, conv2.fluid)
  connect(conv2.solid, heaFlo2.port_a)
end ConductorSteadyStateTransient;


Test model for heat conductor. This example illustrates modeling of multi-layer materials. It also tests if the
multi-layer material computes the same heat transfer with its boundary condition
as two instances of a single layer material.
The insulation and the brick are computed using transient heat conduction.

within Buildings.HeatTransfer.Examples;
model ConductorStepResponse "Test model for heat conductor"
  extends Modelica.Icons.Example;
  parameter Buildings.HeatTransfer.Data.Solids.Concrete concrete(x=0.12, nStaRef=4)
  parameter Buildings.HeatTransfer.Data.Resistances.Carpet carpet "carpet"
  parameter Buildings.HeatTransfer.Data.OpaqueConstructions.Generic composite(
      nLay=2,
      material={carpet,concrete})
  Buildings.HeatTransfer.Conduction.MultiLayer conMul(
    A=2, layers=composite,
    stateAtSurface_b=false)
  Buildings.HeatTransfer.Conduction.SingleLayer con(
    A=2, material=carpet,
    stateAtSurface_a=false,
    stateAtSurface_b=false)
  Buildings.HeatTransfer.Sources.FixedTemperature TB(T=293.15)
  Buildings.HeatTransfer.Sources.PrescribedTemperature TA
  Modelica.Blocks.Sources.Step step(
    height=10,
    offset=293.15,
    startTime=3600)
  Buildings.HeatTransfer.Conduction.SingleLayer con1(
    A=2, material=carpet,
    stateAtSurface_b=false)
  Buildings.HeatTransfer.Sources.FixedTemperature TB1(      T=293.15)
  Buildings.HeatTransfer.Sources.PrescribedTemperature TA1
  Buildings.HeatTransfer.Conduction.SingleLayer con2(
    A=2, material=concrete,
    stateAtSurface_b=false,
    stateAtSurface_a=false)
  Buildings.HeatTransfer.Sources.PrescribedTemperature TA2
  Buildings.HeatTransfer.Sources.FixedTemperature TB2(      T=293.15)
  Modelica.Thermal.HeatTransfer.Sensors.HeatFlowSensor heaFlo1
  Modelica.Thermal.HeatTransfer.Sensors.HeatFlowSensor heaFlo2
  Modelica.Blocks.Math.Add cheEqu(k2=-1) "Check for equality"
  Buildings.HeatTransfer.Convection.Interior conv1(
                                          A=2, til=Buildings.Types.Tilt.Wall)
    "Convective heat transfer"
  Buildings.HeatTransfer.Convection.Interior conv2(
                                          A=2, til=Buildings.Types.Tilt.Wall)
    "Convective heat transfer"
equation
  connect(con.port_b,TB. port)
  connect(step.y,TA. T)
  connect(step.y,TA1. T)
  connect(con1.port_b,con2. port_a)
  connect(con2.port_b,TB1. port)
  connect(TA2.T,step. y)
  connect(heaFlo1.port_b,con1. port_a)
  connect(cheEqu.u1, heaFlo2.Q_flow)
  connect(cheEqu.u2, heaFlo1.Q_flow)
  connect(TA.port,con. port_a)
  connect(conMul.port_b,TB2. port)
  connect(conMul.port_a,heaFlo2. port_b)
  connect(TA1.port, conv1.fluid)
  connect(conv1.solid, heaFlo1.port_a)
  connect(TA2.port, conv2.fluid)
  connect(conv2.solid, heaFlo2.port_a)
end ConductorStepResponse;


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


within Buildings.HeatTransfer;
package Interfaces "Package with interfaces for heat transfer models"
  extends Modelica.Icons.InterfacesPackage;
end Interfaces;


Generate constant radiosity signal. Constant radiosity source. This model requires <i>k ≥ 0</i>.

within Buildings.HeatTransfer.Radiosity;
block Constant "Generate constant radiosity signal"
  parameter Real k(min=0, start=0)
    "Radiosity that leaves this component (k ≥ 0)";
  extends Modelica.Blocks.Icons.Block;

  Interfaces.RadiosityOutflow JOut
equation
  JOut = k;
end Constant;


Model for indoor radiosity. Model for the indoor emissive power that hits a window.
The computation is according to TARCOG 2006.

within Buildings.HeatTransfer.Radiosity;
model IndoorRadiosity "Model for indoor radiosity"
  extends Buildings.HeatTransfer.Radiosity.BaseClasses.RadiosityOneSurface;
  extends Buildings.HeatTransfer.Radiosity.BaseClasses.ParametersOneSurface(
    final absIR=1,
    final tauIR=0,
    final rhoIR=0);
  Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a heatPort
    "Heat port of the surface"
protected
  final parameter Real T04(
    min=0,
    final unit="K4") = T0^4 "4th power of temperature T0";
  Real T4(
    min=1E8,
    start=293.15^4,
    nominal=1E10,
    final unit="K4") "4th power of temperature";
equation
  T4 = if linearize then 4*T03*heatPort.T - 3*T04 else heatPort.T^4;
  JOut = A*Modelica.Constants.sigma*T4;
  0 = heatPort.Q_flow + JIn - JOut;
end IndoorRadiosity;


Model for an opaque surface.

within Buildings.HeatTransfer.Radiosity;
model OpaqueSurface "Model for an opaque surface"
  extends Buildings.HeatTransfer.Radiosity.BaseClasses.RadiosityOneSurface;
  extends Buildings.HeatTransfer.Radiosity.BaseClasses.ParametersOneSurface(
      final tauIR=1 - rhoIR - absIR, final rhoIR=1 - absIR);

  Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a heatPort
    "Heat port of this surface"
protected
  final parameter Real T04(
    min=0,
    final unit="K4") = T0^4 "4th power of temperature T0";
  Real T4(
    min=1E8,
    start=293.15^4,
    nominal=1E10,
    final unit="K4") "4th power of temperature";

equation
  T4 = if linearize then 4*T03*heatPort.T - 3*T04 else heatPort.T^4;
  JOut = A*absIR*Modelica.Constants.sigma*T4 + rhoIR*JIn;
  0 = heatPort.Q_flow + JIn - JOut;
end OpaqueSurface;


Model for the outdoor radiosity that strikes the window. Model for the infrared radiosity balance of the outdoor environment.

within Buildings.HeatTransfer.Radiosity;
model OutdoorRadiosity
  "Model for the outdoor radiosity that strikes the window"
  parameter Modelica.Units.SI.Area A "Area of receiving surface";
  parameter Real vieFacSky(final min=0, final max=1)
    "View factor from receiving surface to sky (=1 for roofs)";
  parameter Boolean linearize=false "Set to true to linearize emissive power"
  parameter Modelica.Units.SI.Temperature T0=293.15
    "Temperature used to linearize radiative heat transfer"
  Real TRad4(unit="K4") "4th power of the mean outdoor temperature";
  Modelica.Units.SI.Temperature TRad "Mean radiant temperature";

  Modelica.Blocks.Interfaces.RealInput TOut(
    final quantity="ThermodynamicTemperature",
    final unit="K",
    min=0) "Outside temperature"
  Modelica.Blocks.Interfaces.RealInput TBlaSky(
    final quantity="ThermodynamicTemperature",
    final unit="K",
    min=0) "Black body sky temperature"
  Buildings.HeatTransfer.Interfaces.RadiosityOutflow JOut
    "Radiosity that flows out of component"
protected
  final parameter Real T03(
    min=0,
    final unit="K3") = T0^3 "3rd power of temperature T0";
  final parameter Real T04(
    min=0,
    final unit="K4") = T0^4 "4th power of temperature T0";
equation
  TRad4 = (vieFacSky*TBlaSky^4 + (1 - vieFacSky)*TOut^4);
  JOut = A*Modelica.Constants.sigma*TRad4;
  TRad = if linearize then (TRad4 + 3*T04)/(4*T03) else TRad4^(1/4);
end OutdoorRadiosity;


within Buildings.HeatTransfer;
package Radiosity "Package with models for radiosity transfer"
  extends Modelica.Icons.VariantsPackage;
end Radiosity;


Splits the incoming radiosity into two flows based on an input signal. This blocks splits the incoming radiosity into two fluxes according to

within Buildings.HeatTransfer.Radiosity;
block RadiositySplitter
  "Splits the incoming radiosity into two flows based on an input signal"
  extends Modelica.Blocks.Icons.Block;

  Interfaces.RadiosityInflow JIn "Inflowing radiosity"
  Modelica.Blocks.Interfaces.RealInput u(min=0, max=1)
    "u times incoming radiosity"
  Interfaces.RadiosityOutflow JOut_1 "u times incoming radiosity"

  Interfaces.RadiosityOutflow JOut_2 "(1-u) times incoming radiosity"
equation
  JOut_1 = u    * JIn;
  JOut_2 = (1-u)* JIn;
end RadiositySplitter;


within Buildings.HeatTransfer.Radiosity;
package BaseClasses "Package with base classes for Buildings.HeatTransfer.Radiosity"
  extends Modelica.Icons.BasesPackage;
end BaseClasses;


Parameters that are used to model one surface. Parameters that are used for classes with one surface.

within Buildings.HeatTransfer.Radiosity.BaseClasses;
model ParametersOneSurface "Parameters that are used to model one surface"
  parameter Modelica.Units.SI.Emissivity absIR "Infrared absorptivity";
  parameter Modelica.Units.SI.ReflectionCoefficient rhoIR
    "Infrared reflectivity";
  parameter Modelica.Units.SI.TransmissionCoefficient tauIR
    "Infrared transmissivity";
  parameter Boolean linearize=false "Set to true to linearize emissive power"
  parameter Modelica.Units.SI.Temperature T0=293.15
    "Temperature used to linearize radiative heat transfer"
protected
 final parameter Real T03(min=0, unit="K3")=T0^3 "3rd power of temperature T0";

initial equation
  assert(abs(1-absIR-rhoIR-tauIR) < 1E-8,
    "Absorptivity, reflectivity and transmissivity do not add up to one. Check parameters.");
end ParametersOneSurface;