Overriding final modifier for nZones

70 views
Skip to first unread message

Stefan Gemperle

unread,
Jan 9, 2017, 9:46:18 AM1/9/17
to Modelica-BuildingSystems
Hallo Zusammen,

Für meine Masterarbeit im Zusammenhang mit Fernwärmeverbünden prüfe ich im Moment verschiedene Bibliotheken als Grundlage für meine Simulationen.

Bei dem einfachen Versuch ein Gebäude aus Ihrer Bibliothek zu simulieren kommt immer der gleiche Fehler.  Könnt Ihr mir weiterhelfen an was dies liegen könnte?

Freundliche Grüsse
Stefan Gemperle
Fehlermeldung.PNG

Matthis Thorade

unread,
Jan 10, 2017, 3:37:39 AM1/10/17
to Modelica-BuildingSystems
Hallo Stefan,
die Beispiele in BuildingSystems.Buildings.Examples zeigen diesen Fehler nicht (eine Menge Warnings, aber man kann die Simulation startetn). Ich würde deshalb vermuten, dass es an Deinem Code liegt. Kannst Du ein möglichst kleines Beispiel hier posten, das genau diese Fehlermeldung erzeugt? Als Text, nicht als Bild.
Grüße,
Matthis

Stefan Gemperle

unread,
Jan 10, 2017, 7:57:15 AM1/10/17
to Modelica-BuildingSystems
Hallo Matthis

Habe noch ein paar Versuche gestartet, komme aber nicht weiter. Der Fehler entsteht in dem Moment, in dem ich die konstanten Quellen (TSetHeat, TSetCool, Airchange) neu anschließe. 

Hier der Modelica Text:

model Test

  BuildingSystems.Buildings.BuildingTemplates.Building1Zone0D buildingTest(
      nZones=1) annotation (Placement(transformation(extent={{16,14},{56,52}})));
  BuildingSystems.Buildings.Ambient ambient(nSurfaces=buildingTest.nSurfacesAmbient)
    annotation (Placement(transformation(extent={{-48,14},{-8,48}})));
  Modelica.Blocks.Sources.Constant const(k=293)
    annotation (Placement(transformation(extent={{100,54},{80,74}})));
  Modelica.Blocks.Sources.Constant const1(k=0.5)
    annotation (Placement(transformation(extent={{98,-6},{78,14}})));
  Modelica.Blocks.Sources.Constant const2(k=297)
    annotation (Placement(transformation(extent={{98,24},{78,44}})));
equation 
  connect(ambient.TAirRef, buildingTest.TAirAmb) annotation (Line(points={{-44.4,
          42.9},{-44.4,70},{48.4,70},{48.4,51.62}}, color={0,0,127}));
  connect(ambient.xAir, buildingTest.xAirAmb) annotation (Line(points={{-44.4,39.5},
          {-50,39.5},{-50,76},{-44,76},{52.8,76},{52.8,51.62}}, color={0,0,127}));
  connect(ambient.toSurfacePorts, buildingTest.toAmbientSurfacesPorts) 
    annotation (Line(points={{-12,37.8},{3,37.8},{3,40.6},{18,40.6}}, color={0,255,
          0}));
  connect(ambient.toAirPorts, buildingTest.toAmbientAirPorts) annotation (Line(
        points={{-12,24.2},{4,24.2},{4,25.4},{18,25.4}}, color={85,170,255}));
  connect(const.y, buildingTest.T_setHeating[1]) annotation (Line(points={{79,64},
          {68.5,64},{68.5,48.2},{55.6,48.2}}, color={0,0,127}));
  connect(const2.y, buildingTest.T_setCooling[1]) annotation (Line(points={{77,34},
          {68,34},{68,44.4},{55.6,44.4}}, color={0,0,127}));
  connect(const1.y, buildingTest.airchange[1]) annotation (Line(points={{77,4},{
          68,4},{68,40.6},{55.6,40.6}}, color={0,0,127}));
  annotation (uses(BuildingSystems(version="0.1"), Modelica(version="3.2.1")),
      Diagram(coordinateSystem(preserveAspectRatio=false, extent={{-100,-100},{100,
            100}})));
end Test;


und mit den Used Classes:

model Test

  BuildingSystems.Buildings.BuildingTemplates.Building1Zone0D buildingTest(
      nZones=1);
  BuildingSystems.Buildings.Ambient ambient(nSurfaces=buildingTest.nSurfacesAmbient);
  Modelica.Blocks.Sources.Constant const(k=293);
  Modelica.Blocks.Sources.Constant const1(k=0.5);
  Modelica.Blocks.Sources.Constant const2(k=297);
equation 
  connect(ambient.TAirRef, buildingTest.TAirAmb);
  connect(ambient.xAir, buildingTest.xAirAmb);
  connect(ambient.toSurfacePorts, buildingTest.toAmbientSurfacesPorts);
  connect(ambient.toAirPorts, buildingTest.toAmbientAirPorts);
  connect(const.y, buildingTest.T_setHeating[1]);
  connect(const2.y, buildingTest.T_setCooling[1]);
  connect(const1.y, buildingTest.airchange[1]);
end Test;
 
partial package Modelica.Icons.Package "Icon for standard packages"

end Package;
 
partial package Modelica.Icons.VariantsPackage 
  "Icon for package containing variants"
  extends Modelica.Icons.Package;
end VariantsPackage;
 
model BuildingSystems.Buildings.BuildingTemplates.Building1Zone0D 
  "Strong simplified building model with 3 thermal capacities"
  extends BuildingSystems.Buildings.BaseClasses.BuildingTemplate(
    final nZones = 1,
    final prescribedAirchange = true,
    final useAirPathes = false,
    final nAirpathes = 0,
    final calcHygroThermal = false,
    final convectionOnSurfaces=BuildingSystems.HAM.ConvectiveHeatTransfer.Types.Convection.const,
    final alphaConstant = alphaAmb,
    final nSurfacesSolid=1,
    surfacesToAmbient(nSurfaces=nWindows+1),
    surfacesToSolids(nSurfaces=nSurfacesSolid));
  parameter Integer nWindows = 1 "Number of windows";
  parameter Modelica.SIunits.Area AAmb = 1.0 
    "Surface area of the building constructions with air contact to the environment";
  parameter Modelica.SIunits.Area AInn = 1.0 
    "Surface area of both sides of the internal building constructions";
  parameter Modelica.SIunits.Area AGro = 1.0 
    "Surface area of the building constructions with contact to the ground";
  parameter Modelica.SIunits.Area AWin[nWindows] = {1.0} "Area of each window";
  parameter Modelica.SIunits.Conversions.NonSIunits.Angle_deg angleDegAziWin[nWindows] = fill(0.0,nWindows) 
    "Azimuth angle of each window";
  parameter Modelica.SIunits.Conversions.NonSIunits.Angle_deg angleDegTilWin[nWindows] = fill(90.0,nWindows) 
    "Tilt angle of each window";
  parameter Modelica.SIunits.Volume VAir = 1.0 
    "Inner (Air) volume of the building";
  parameter Modelica.SIunits.HeatCapacity CAmb = 1.0 
    "Total heat capacity of the building envelope";
  parameter Modelica.SIunits.HeatCapacity CInn = 1.0 
    "Total heat capacity of the internal building construction";
  parameter Modelica.SIunits.HeatCapacity CGro = 1.0 
    "Total heat capacity of the building groundplate";
  parameter Modelica.SIunits.CoefficientOfHeatTransfer UValAmb = 1.0 
    "Mean heat loss coefficient of the building envelope";
  parameter Modelica.SIunits.CoefficientOfHeatTransfer UValGro = 1.0 
    "Mean heat loss coefficient of the building groundplate";
  parameter Modelica.SIunits.CoefficientOfHeatTransfer UValInn = 1.0 
    "Mean heat loss coefficient of internal building construction";
  parameter Modelica.SIunits.CoefficientOfHeatTransfer UValWin[nWindows] = fill(1.0,nWindows) 
    "Heat loss coefficient of each window";
  BuildingSystems.Buildings.Zones.ZoneTemplateAirvolumeMixed zone(
    final prescribedAirchange = prescribedAirchange,
    final V=VAir,
    final calcIdealLoads=calcIdealLoads,
    final heatSources=heatSources,
    final nHeatSources=nHeatSources,
    nConstructions4=1,
    nConstructions1=1,
    nConstructions3=2,
    nConstructions2=nWindows);
  BuildingSystems.Buildings.Constructions.Walls.WallThermal1DNodes ambientConstructions(
    final abs_2 = 0.0,
    final epsilon_2 = 0.0,
    final width=1.0,
    final height=AAmb/ambientConstructions.width,
    nNodes={1},
    constructionData(
    final thickness =                {1.0}, material(
    final rho =                         {1000.0},
    final c =                         {CAmb/(ambientConstructions.constructionData.material[1].rho*AAmb*ambientConstructions.constructionData.thickness[1])},
    final lambda =                         {(1.0/(-1.0/alphaAmb-1.0/alphaIns+1.0/UValAmb)*ambientConstructions.constructionData.thickness[1])})));
  BuildingSystems.Buildings.Constructions.Walls.WallThermal1DNodes groundConstructions(
    final abs_2 = 0.0,
    final epsilon_2 = 0.0,
    final width=1.0,
    final height=AGro/groundConstructions.width,
    nNodes={1},
    constructionData(
    final thickness =                {1.0}, material(
    final rho =                         {1000.0},
    final c =                         {CGro/(groundConstructions.constructionData.material[1].rho*AGro*groundConstructions.constructionData.thickness[1])},
    final lambda =                         {(1.0/(-1.0/alphaIns-1.0/alphAGro+1.0/UValGro)*groundConstructions.constructionData.thickness[1])})));
  BuildingSystems.Buildings.Constructions.Walls.WallThermal1DNodes innerConstructions(
    final abs_2 = 0.0,
    final epsilon_2 = 0.0,
    final width=1.0,
    final height=AInn/innerConstructions.width,
    nNodes={1},
    constructionData(
    final thickness =                {1.0}, material(
    final rho =                         {1000.0},
    final c =                         {CInn/(innerConstructions.constructionData.material[1].rho*AInn*innerConstructions.constructionData.thickness[1])},
    final lambda =                         {(1.0/(-1.0/alphaIns-1.0/alphaIns+1.0/UValInn)*innerConstructions.constructionData.thickness[1])})));
  BuildingSystems.Buildings.Constructions.Windows.Window window[nWindows](
    final angleDegAzi= {angleDegAziWin[i] + angleDegAziBuilding for i in 1:nWindows},
    final angleDegTil = angleDegTilWin,
    UVal = UValWin,
    each width = 1.0,
    final height={AWin[i]/window[i].width for i in 1:nWindows});
  final parameter Modelica.SIunits.SurfaceCoefficientOfHeatTransfer alphaIns = 7.692 
    "Heat transfer coefficient (convection + radiation) inside of the building"; // after German DIN 4701 Teil2 tabular 16"
  final parameter Modelica.SIunits.SurfaceCoefficientOfHeatTransfer alphaAmb = 25.0 
    "Heat transfer coefficient (convection + radiation) outside of the building"; // after german DIN 4701 Teil2 tabular 16"
  final parameter Modelica.SIunits.SurfaceCoefficientOfHeatTransfer alphAGro = 100.0 
    "Heat transfer coefficient (conduction) to the ground";
equation 
  connect(zone.TAir, TAir[1]);

  // Building construction
  connect(ambientConstructions.toSurfacePort_1, zone.toConstructionPorts1[1]);
  connect(ambientConstructions.toSurfacePort_2, surfacesToAmbient.toConstructionPorts[nSurfacesAmbient]);
  connect(innerConstructions.toSurfacePort_1, zone.toConstructionPorts3[1]);
  connect(zone.toConstructionPorts3[2], innerConstructions.toSurfacePort_2);
  connect(window.toSurfacePort_1, zone.toConstructionPorts2);
  connect(window[1:nWindows].toSurfacePort_2, surfacesToAmbient.toConstructionPorts[1:nWindows]);
  connect(groundConstructions.toSurfacePort_2, surfacesToSolids.toConstructionPorts[1]);
  connect(groundConstructions.toSurfacePort_1, zone.toConstructionPorts4[1]);

  // Ideal heat load calculation - depends on boolean calcIdealLoads
    connect(zone.T_setCooling, T_setCooling[1]);
    connect(zone.T_setHeating, T_setHeating[1]);
    connect(zone.Q_flow_cooling, Q_flow_cooling[1]);
    connect(zone.Q_flow_heating, Q_flow_heating[1]);

  // Prescribed airchange - depends on boolean prescribedAirchange
    connect(zone.TAirAmb, TAirAmb);
    connect(zone.xAirAmb, xAirAmb);
    connect(zone.airchange, airchange[1]);

  // Ideal heat load calculation - depends on boolean heatSources
    connect(conHeatSourcesPorts, zone.conHeatSourcesPorts);
    connect(zone.radHeatSourcesPorts, radHeatSourcesPorts);

end Building1Zone0D;
 
model BuildingSystems.Buildings.Zones.ZoneTemplateAirvolumeMixed 
  "Template model for a thermal zone with fully mixed air volume"
  extends BuildingSystems.Buildings.BaseClasses.ZoneTemplateGeneral(
    redeclare final package Medium = BuildingSystems.Media.Air,
    nHeatSourcesTotal = if calcIdealLoads then nHeatSources + 2 else nHeatSources);
  parameter Modelica.SIunits.HeatFlowRate Q_flow_heatingMax = Modelica.Constants.inf 
    "Maximal power for ideal heating";
  parameter Modelica.SIunits.HeatFlowRate Q_flow_coolingMax = -Modelica.Constants.inf 
    "Maximal power for ideal cooling";
  parameter Real radiationportionIdealHeating = 0.5 
    "Radiation portion of the ideal heating";
  parameter Real radiationportionIdealCooling = 0.5 
    "Radiation portion of the ideal cooling";
  parameter Modelica.SIunits.Length heightAirpath[nAirpathes]=fill(0.0,nAirpathes) 
    "Vertical height of each air path in the zone";
  parameter Boolean heatSources = false 
    "True: heat sources present; false: no heat sources present";
  parameter Integer nHeatSources = 0 
    "Number of internal heat sources of the thermal zone";
  parameter Boolean moistureSources = false 
    "True: moisture source present; false: no moisture source present";
  parameter Boolean calcIdealLoads = true 
    "True: calculation of the ideal heating and cooling loads; false: no calculation";
  input BuildingSystems.Interfaces.Temp_KInput T_setHeating if calcIdealLoads 
    "Set air temperature for heating of the zone";
  input BuildingSystems.Interfaces.Temp_KInput T_setCooling if calcIdealLoads 
    "Set air temperature for cooling of the zone";
  parameter Modelica.SIunits.Temp_K T_start = 293.15 
    "Start air temperature of the zone";
  parameter Modelica.SIunits.MassFraction x_start = 0.005 
    "Start air moisture of the zone";
  BuildingSystems.Buildings.Airvolumes.AirvolumeCompressible0D airvolume(
    nSurfaces=nSurfaces,
    gridSurface=gridSurfaceZone,
    V=V,
    height=height,
    heightAirpath = heightAirpath,
    T_start=T_start,
    x_start=x_start,
    nHeatSources=nHeatSourcesTotal,
    nMoistureSources=nMoistureSources,
    nAirpathes=nAirpathes);
  BuildingSystems.Buildings.BaseClasses.RelationRadiationConvection relRadConHeating(
    radiationportion=radiationportionIdealHeating) if calcIdealLoads;
  Modelica.Blocks.Continuous.LimPID heatingLoad(
    controllerType=Modelica.Blocks.Types.SimpleController.PI,
    Ni = 0.25,
    k=V*500,
    yMin= 0.0,
    Ti=50.0,
    yMax=Q_flow_heatingMax) if calcIdealLoads;
  BuildingSystems.Buildings.BaseClasses.RelationRadiationConvection relRadConCooling(
    radiationportion=radiationportionIdealCooling) if calcIdealLoads;
  Modelica.Blocks.Continuous.LimPID coolingLoad(
    controllerType=Modelica.Blocks.Types.SimpleController.PI,
    Ni = 0.25,
    k=V*500,
    Ti=50.0,
    yMax=0.0,
    yMin=Q_flow_coolingMax) if  calcIdealLoads;
  output BuildingSystems.Interfaces.HeatFlowRateOutput Q_flow_heating if calcIdealLoads;
  output BuildingSystems.Interfaces.HeatFlowRateOutput Q_flow_cooling if calcIdealLoads;
  output BuildingSystems.Interfaces.Temp_KOutput TAir;
  output BuildingSystems.Interfaces.Moisture_absOutput xAir;
  output BuildingSystems.Interfaces.Temp_KOutput TOperative = (airvolume.T + radiationDistribution.TSurfMean) / 2.0;
  BuildingSystems.Interfaces.HeatPorts conHeatSourcesPorts[nHeatSources] if heatSources 
    "Heat ports of the convective heat sources";
  BuildingSystems.Interfaces.HeatPorts radHeatSourcesPorts[nHeatSources] if heatSources 
    "Heat ports of the long-wave radiation heat sources";
  BuildingSystems.Interfaces.MoisturePorts moistureSourcesPorts[nMoistureSources] if moistureSources 
    "Moisture ports of the moisture sources";
  Modelica.Thermal.HeatTransfer.Sources.PrescribedHeatFlow phfHeating if calcIdealLoads;
  Modelica.Thermal.HeatTransfer.Sources.PrescribedHeatFlow phfCooling if calcIdealLoads;
  input BuildingSystems.Interfaces.Temp_KInput TAirAmb if prescribedAirchange 
    "Air temperature of the building ambient";
  input BuildingSystems.Interfaces.Moisture_absInput xAirAmb if prescribedAirchange 
    "Absolute moisture of the building ambient";
  input BuildingSystems.Interfaces.AirchangeRateInput airchange if prescribedAirchange 
    "Air change rate of the thermal zone";
  Modelica.Blocks.Math.Gain ac2mf(k=-rho_nominal*airvolume.V/3600.0) if prescribedAirchange 
    "Transformation from air change in 1/h into air mass flow rate in kg/s";
  BuildingSystems.Buildings.Airpathes.AirpathPrescribedMassFlowRate airpathIn(
    use_m_flow_in=true,
    use_T_in=true,
    use_x_in=true) if prescribedAirchange 
    "Calculates the mass flow rate which is entering the zone";
  Airpathes.AirpathPrescribedMassFlowRate airpathOut(
    x = 0.005,
    use_m_flow_in = true,
    T = 293.15) if prescribedAirchange 
    "Calculates the mass flow rate which is leaving the zone";
  Modelica.Blocks.Math.Gain mult(
    k = -1.0) if prescribedAirchange "Changes the sign of mass flow";
equation 
  for i in 1:nConstructions1 loop
    connect(surfaces1.toAirPorts[i],airvolume.toSurfacePorts[i]);
  end for;
  for i in 1:nConstructions2 loop
    connect(surfaces2.toAirPorts[i],airvolume.toSurfacePorts[nConstructions1+i]);
  end for;
  for i in 1:nConstructions3 loop
    connect(surfaces3.toAirPorts[i],airvolume.toSurfacePorts[nConstructions1+nConstructions2+i]);
  end for;
  for i in 1:nConstructions4 loop
    connect(surfaces4.toAirPorts[i],airvolume.toSurfacePorts[nConstructions1+nConstructions2+nConstructions3+i]);
  end for;
  for i in 1:nConstructions5 loop
    connect(surfaces5.toAirPorts[i],airvolume.toSurfacePorts[nConstructions1+nConstructions2+nConstructions3+nConstructions4+i]);
  end for;
  for i in 1:nConstructions6 loop
    connect(surfaces6.toAirPorts[i],airvolume.toSurfacePorts[nConstructions1+nConstructions2+nConstructions3+nConstructions4+nConstructions5+i]);
  end for;
  if not prescribedAirchange then
    for i in 1:nAirpathes1 loop
      connect(airpathPorts1[i], airvolume.airpathPorts[i]);
    end for;
    for i in 1:nAirpathes2 loop
      connect(airpathPorts2[i], airvolume.airpathPorts[nAirpathes1+i]);
    end for;
    for i in 1:nAirpathes3 loop
      connect(airpathPorts3[i], airvolume.airpathPorts[nAirpathes1+nAirpathes2+i]);
    end for;
    for i in 1:nAirpathes4 loop
      connect(airpathPorts4[i], airvolume.airpathPorts[nAirpathes1+nAirpathes2+nAirpathes3+i]);
    end for;
    for i in 1:nAirpathes5 loop
      connect(airpathPorts5[i], airvolume.airpathPorts[nAirpathes1+nAirpathes2+nAirpathes3+nAirpathes4+i]);
    end for;
    for i in 1:nAirpathes6 loop
      connect(airpathPorts6[i], airvolume.airpathPorts[nAirpathes1+nAirpathes2+nAirpathes3+nAirpathes4+nAirpathes5+i]);
    end for;
  end if;
  // Internal heat sources
  for i in 1:nHeatSources loop
    connect(airvolume.heatSourcesPorts[i],conHeatSourcesPorts[i]);
    connect(radiationDistribution.heatSourcesPorts[i],radHeatSourcesPorts[i]);
  end for;
  // Internal moisture sources
  for i in 1:nMoistureSources loop
    connect(moistureSourcesPorts[i], airvolume.moistureSourcesPorts[i]);
  end for;
  // Ideal load calculation
  if calcIdealLoads then
    connect(airvolume.heatSourcesPorts[nHeatSources+1], relRadConHeating.heatPortCv);
    connect(airvolume.heatSourcesPorts[nHeatSources+2], relRadConCooling.heatPortCv);
    connect(airvolume.T, coolingLoad.u_m);
    connect(airvolume.T, heatingLoad.u_m);
    connect(relRadConHeating.heatPortLw, radiationDistribution.heatSourcesPorts[nHeatSources+1]);
    connect(relRadConCooling.heatPortLw, radiationDistribution.heatSourcesPorts[nHeatSources+2]);
    connect(T_setHeating, heatingLoad.u_s);
    connect(T_setCooling, coolingLoad.u_s);
    connect(phfHeating.port, relRadConHeating.heatPort);
    connect(heatingLoad.y, phfHeating.Q_flow);
    connect(phfCooling.port, relRadConCooling.heatPort);
    connect(phfCooling.Q_flow, coolingLoad.y);
    //Connect Outputs with ideal heating/cooling loads
    connect(Q_flow_heating, heatingLoad.y);
    connect(Q_flow_cooling, coolingLoad.y);
  end if;
  // Prescribed air change
  if prescribedAirchange then
    connect(ac2mf.u, airchange);
    connect(airpathIn.m_flow_in, ac2mf.y);
    connect(airpathIn.x_in, xAirAmb);
    connect(airpathIn.T_in, TAirAmb);
    connect(airpathOut.m_flow_in, mult.y);
    connect(mult.u, ac2mf.y);
    connect(airpathIn.airpathPort_1, airvolume.airpathPorts[1]);
    connect(airpathOut.airpathPort_1, airvolume.airpathPorts[2]);
  end if;
  connect(airvolume.T, TAir);
  connect(airvolume.x, xAir);

end ZoneTemplateAirvolumeMixed;
 
  final constant Real Modelica.Constants.inf=
                          ModelicaServices.Machine.inf 
  "Biggest Real number such that inf and -inf are representable on the machine";
 
  final constant Real ModelicaServices.Machine.inf=
                          1.e+60 
  "Biggest Real number such that inf and -inf are representable on the machine";
 
partial package Modelica.Icons.BasesPackage 
  "Icon for packages containing base classes"
  extends Modelica.Icons.Package;
end BasesPackage;
 
partial model BuildingSystems.Buildings.BaseClasses.ZoneTemplateGeneral 
  "Common template model for a thermal zone"

  replaceable package Medium = Modelica.Media.Interfaces.PartialMedium 
    "Medium in the air model of the zone";

  function indexM 
    "Mapping function from 2-dimensional surfaces to 1-dimensional array"
    input Integer I;
    input Integer J;
    input Integer K;
    input Integer gridSurface[:,2];
    output Integer m = 0;
  algorithm 
    for i in 1:I-1 loop
      m := m + gridSurface[i,1]*gridSurface[i,2];
    end for;
    m := m + (J-1)*gridSurface[I,2]+K;
  end indexM;

  function numberOfGridSurfaces 
    "Counting function for all 2-dimensional surfaces of the thermal zone"
    input Integer gridSurface[:,2];
    output Integer val;
  algorithm 
    val := 0;
    for i in 1:size(gridSurface,1) loop
      for j in 1:gridSurface[i,1] loop
        for k in 1:gridSurface[i,2] loop
          val := val + 1;
        end for;
      end for;
    end for;
  end numberOfGridSurfaces;

  parameter Modelica.SIunits.Volume V = 1.0 "Air volume of the zone";
  parameter Modelica.SIunits.Length height = 1.0 "Vertical height of the zone";
  parameter BuildingSystems.HAM.ConvectiveHeatTransfer.Types.Convection convectionOnSurfaces = BuildingSystems.HAM.ConvectiveHeatTransfer.Types.Convection.const 
    "Type of convection calculation of the zone surfaces";
  parameter Modelica.SIunits.SurfaceCoefficientOfHeatTransfer alphaConstant = 1.0 
    "Convective heat transfer coefficient for simplified calculations";
  parameter Integer nMoistureSources = 0 
    "Number of internal moisture sources of the thermal zone";
  parameter Integer gridSurface1[nConstructions1,2]=fill({1,1},nConstructions1) 
    "Grid in y and z dimension of each surface with orientation 1";
  parameter Integer gridSurface2[nConstructions2,2]=fill({1,1},nConstructions2) 
    "Grid in y and z dimension of each surface with orientation 2";
  parameter Integer gridSurface3[nConstructions3,2]=fill({1,1},nConstructions3) 
    "Grid in y and z dimension of each surface with orientation 3";
  parameter Integer gridSurface4[nConstructions4,2]=fill({1,1},nConstructions4) 
    "Grid in y and z dimension of each surface with orientation 4";
  parameter Integer gridSurface5[nConstructions5,2]=fill({1,1},nConstructions5) 
    "Grid in y and z dimension of each surface with orientation 5";
  parameter Integer gridSurface6[nConstructions6,2]=fill({1,1},nConstructions6) 
    "Grid in y and z dimension of each surface with orientation 6";
  parameter Integer nConstructions1 = 0 
    "Number of constructions with orientation 1";
  parameter Integer nConstructions2 = 0 
    "Number of constructions with orientation 2";
  parameter Integer nConstructions3 = 0 
    "Number of constructions with orientation 3";
  parameter Integer nConstructions4 = 0 
    "Number of constructions with orientation 4";
  parameter Integer nConstructions5 = 0 
    "Number of constructions with orientation 5";
  parameter Integer nConstructions6 = 0 "Number of constructions orientation 6";
  parameter Integer nAirpathes1 = 0 "Number of air pathes with orientation 1";
  parameter Integer nAirpathes2 = 0 "Number of air pathes with orientation 2";
  parameter Integer nAirpathes3 = 0 "Number of air pathes with orientation 3";
  parameter Integer nAirpathes4 = 0 "Number of air pathes with orientation 4";
  parameter Integer nAirpathes5 = 0 "Number of air pathes with orientation 5";
  parameter Integer nAirpathes6 = 0 "Number of air pathes with orientation 6";
  parameter Boolean prescribedAirchange = true 
    "True: zone air change rate is prescribed by zone ambient; false: air path calculation";
  parameter Boolean geometricViewFactors = false 
    "true: use of geometric view factors, false: use of surface area weighted view factors";
  parameter BuildingSystems.Types.ViewFactor ViewFac[nGridSurfaces,nGridSurfaces]=fill(fill(0.0,nGridSurfaces),nGridSurfaces) 
    "Geometric view factor matrix of the thermal zone";
  BuildingSystems.Buildings.BaseClasses.RadiationDistribution radiationDistribution(
    nSurfaces=nGridSurfaces,
    nHeatSources=nHeatSourcesTotal,
    geometricViewFactors=geometricViewFactors,
    ViewFac=ViewFac) 
    "Long-wave and short-wave radiation calculation of the zone";
  BuildingSystems.Buildings.Interfaces.SurfaceToConstructionPorts toConstructionPorts1[nConstructions1](
    nY=gridSurface1[:,1],
    nZ=gridSurface1[:,2],
    moisturePort(
    x(             each start = 0.005))) 
    "Interfaces of the zone to constructions with orientation 1";
  BuildingSystems.Buildings.Interfaces.SurfaceToConstructionPorts toConstructionPorts3[nConstructions3](
     nY=gridSurface3[:,1],
    nZ=gridSurface3[:,2],
    moisturePort(
    x(             each start = 0.005))) 
    "Interfaces of the zone to constructions with orientation 2";
  BuildingSystems.Buildings.Interfaces.SurfaceToConstructionPorts toConstructionPorts2[nConstructions2](
    nY=gridSurface2[:,1],
    nZ=gridSurface2[:,2],
    moisturePort(
    x(             each start = 0.005))) 
    "Interfaces of the zone to constructions with orientation 3";
  BuildingSystems.Buildings.Interfaces.SurfaceToConstructionPorts toConstructionPorts4[nConstructions4](
    nY=gridSurface4[:,1],
    nZ=gridSurface4[:,2],
    moisturePort(
    x(             each start = 0.005))) 
    "Interfaces of the zone to constructions with orientation 4";
  BuildingSystems.Buildings.Interfaces.SurfaceToConstructionPorts toConstructionPorts5[nConstructions5](
    nY=gridSurface5[:,1],
    nZ=gridSurface5[:,2],
    moisturePort(
    x(             each start = 0.005))) 
    "Interfaces of the zone to constructions with orientation 5";
  BuildingSystems.Buildings.Interfaces.SurfaceToConstructionPorts toConstructionPorts6[nConstructions6](
    nY=gridSurface6[:,1],
    nZ=gridSurface6[:,2],
    moisturePort(
    x(             each start = 0.005))) 
    "Interfaces of the zone to constructions with orientation 6";
  Modelica.Fluid.Vessels.BaseClasses.VesselFluidPorts_b airpathPorts1[nAirpathes1](
    redeclare each final package Medium = Medium) if not prescribedAirchange 
    "Interfaces of the zone to air pathes with orientation 1";
  Modelica.Fluid.Vessels.BaseClasses.VesselFluidPorts_b airpathPorts2[nAirpathes2](
    redeclare each final package Medium = Medium) if not prescribedAirchange 
    "Interfaces of the zone to air pathes with orientation 2";
  Modelica.Fluid.Vessels.BaseClasses.VesselFluidPorts_b airpathPorts3[nAirpathes3](
    redeclare each final package Medium = Medium) if not prescribedAirchange 
    "Interfaces of the zone to air pathes with orientation 3";
  Modelica.Fluid.Vessels.BaseClasses.VesselFluidPorts_b airpathPorts4[nAirpathes4](
    redeclare each final package Medium = Medium) if not prescribedAirchange 
    "Interfaces of the zone to air pathes with orientation 4";
  Modelica.Fluid.Vessels.BaseClasses.VesselFluidPorts_b airpathPorts5[nAirpathes5](
    redeclare each final package Medium = Medium) if not prescribedAirchange 
    "Interfaces of the zone to air pathes with orientation 5";
  Modelica.Fluid.Vessels.BaseClasses.VesselFluidPorts_b airpathPorts6[nAirpathes6](
    redeclare each final package Medium = Medium) if not prescribedAirchange 
    "Interfaces of the zone to air pathes with orientation 6";
  BuildingSystems.Buildings.Surfaces.SurfacesToAir surfaces1(
    nSurfaces=nConstructions1,
    gridSurface=gridSurface1,
    surface(
    each convectionOnSurface =         convectionOnSurfaces,
    each alphaConstant =         alphaConstant)) 
    "surface models of the zone with orientation 1";
  BuildingSystems.Buildings.Surfaces.SurfacesToAir surfaces2(
    nSurfaces=nConstructions2,
    gridSurface=gridSurface2,
    surface(
    each convectionOnSurface =         convectionOnSurfaces,
    each alphaConstant =         alphaConstant)) 
    "surface models of the zone with orientation 2";
  BuildingSystems.Buildings.Surfaces.SurfacesToAir surfaces3(
    nSurfaces=nConstructions3,
    gridSurface=gridSurface3,
    surface(
    each convectionOnSurface =         convectionOnSurfaces,
    each alphaConstant =         alphaConstant)) 
    "surface models of the zone with orientation 3";
  BuildingSystems.Buildings.Surfaces.SurfacesToAir surfaces4(
    nSurfaces=nConstructions4,
    gridSurface=gridSurface4,
    surface(
    each convectionOnSurface =         convectionOnSurfaces,
    each alphaConstant =         alphaConstant)) 
    "surface models of the zone with orientation 4";
  BuildingSystems.Buildings.Surfaces.SurfacesToAir surfaces5(
    nSurfaces=nConstructions5,
    gridSurface=gridSurface5,
    surface(
    each convectionOnSurface =         convectionOnSurfaces,
    each alphaConstant =         alphaConstant)) 
    "surface models of the zone with orientation 5";
  BuildingSystems.Buildings.Surfaces.SurfacesToAir surfaces6(
    nSurfaces=nConstructions6,
    gridSurface=gridSurface6,
    surface(
    each convectionOnSurface =         convectionOnSurfaces,
    each alphaConstant =         alphaConstant)) 
    "surface models of the zone with orientation 6";
  BuildingSystems.Interfaces.Temp_KOutput TSurfMean 
    "Mean surface temperature of the zone";
protected 
  parameter Integer nHeatSourcesTotal = 0 
    "Overall number of internal heat sources of the thermal zone";
  parameter Integer nGridSurfaces = numberOfGridSurfaces(gridSurface1) + numberOfGridSurfaces(gridSurface2) + numberOfGridSurfaces(gridSurface3)
    + numberOfGridSurfaces(gridSurface4)+ numberOfGridSurfaces(gridSurface5)+ numberOfGridSurfaces(gridSurface6) 
    "Overall number of all sub-surfaces";
 // Note, that with following three lines it is assumed, that there is always at least ONE construction!
  parameter Integer nSumConstructions = nConstructions1 + nConstructions2 + nConstructions3 + nConstructions4 + nConstructions5 + nConstructions6;
  parameter Integer gridSurfaceZone[nSurfaces,2] = if nSumConstructions > 0 then cat(1,gridSurface1,gridSurface2,gridSurface3,gridSurface4,gridSurface5,gridSurface6) else [1,1];
  parameter Integer nSurfaces = max(nSumConstructions,1) 
    "Overall number of surfaces of the zone";
  parameter Integer nAirpathes = if prescribedAirchange then 2 else + nAirpathes1 + nAirpathes2 + nAirpathes3 + nAirpathes4 + nAirpathes5 + nAirpathes6 
    "Overall number of air pathes of the zone";
  constant Modelica.SIunits.Density rho_nominal = 1.2 
    "Air density under nominal conditions";
equation 
  for i in 1:nConstructions1 loop
    connect(surfaces1.toConstructionPorts[i],toConstructionPorts1[i]);
    for j in 1:gridSurface1[i,1] loop
      for k in 1:gridSurface1[i,2] loop
        surfaces1.toSurfacesPorts[i].angleDegAzi = radiationDistribution.toSurfacePorts[indexM(i,j,k,gridSurface1)].angleDegAzi;
        surfaces1.toSurfacesPorts[i].angleDegTil = radiationDistribution.toSurfacePorts[indexM(i,j,k,gridSurface1)].angleDegTil;
        surfaces1.toSurfacesPorts[i].zMean = radiationDistribution.toSurfacePorts[indexM(i,j,k,gridSurface1)].zMean;
        surfaces1.toSurfacesPorts[i].A[j,k] = radiationDistribution.toSurfacePorts[indexM(i,j,k,gridSurface1)].A[1,1];
        surfaces1.toSurfacesPorts[i].epsilon[j,k] = radiationDistribution.toSurfacePorts[indexM(i,j,k,gridSurface1)].epsilon[1,1];
        surfaces1.toSurfacesPorts[i].abs[j,k] = radiationDistribution.toSurfacePorts[indexM(i,j,k,gridSurface1)].abs[1,1];
        connect(surfaces1.toSurfacesPorts[i].heatPortLw[j,k],radiationDistribution.toSurfacePorts[indexM(i,j,k,gridSurface1)].heatPortLw[1,1]);
        connect(surfaces1.toSurfacesPorts[i].heatPortSw[j,k],radiationDistribution.toSurfacePorts[indexM(i,j,k,gridSurface1)].heatPortSw[1,1]);
        connect(surfaces1.toSurfacesPorts[i].radiationPort_in[j,k],radiationDistribution.toSurfacePorts[indexM(i,j,k,gridSurface1)].radiationPort_in[1,1]);
        connect(surfaces1.toSurfacesPorts[i].radiationPort_out[j,k],radiationDistribution.toSurfacePorts[indexM(i,j,k,gridSurface1)].radiationPort_out[1,1]);
      end for;
    end for;
  end for;
  for i in 1:nConstructions2 loop
    connect(surfaces2.toConstructionPorts[i],toConstructionPorts2[i]);
    for j in 1:gridSurface2[i,1] loop
      for k in 1:gridSurface2[i,2] loop
        surfaces2.toSurfacesPorts[i].angleDegAzi = radiationDistribution.toSurfacePorts[numberOfGridSurfaces(gridSurface1)+indexM(i,j,k,gridSurface2)].angleDegAzi;
        surfaces2.toSurfacesPorts[i].angleDegTil = radiationDistribution.toSurfacePorts[numberOfGridSurfaces(gridSurface1)+indexM(i,j,k,gridSurface2)].angleDegTil;
        surfaces2.toSurfacesPorts[i].zMean = radiationDistribution.toSurfacePorts[numberOfGridSurfaces(gridSurface1)+indexM(i,j,k,gridSurface2)].zMean;
        surfaces2.toSurfacesPorts[i].A[j,k] = radiationDistribution.toSurfacePorts[numberOfGridSurfaces(gridSurface1)+indexM(i,j,k,gridSurface2)].A[1,1];
        surfaces2.toSurfacesPorts[i].epsilon[j,k] = radiationDistribution.toSurfacePorts[numberOfGridSurfaces(gridSurface1)+indexM(i,j,k,gridSurface2)].epsilon[1,1];
        surfaces2.toSurfacesPorts[i].abs[j,k] = radiationDistribution.toSurfacePorts[numberOfGridSurfaces(gridSurface1)+indexM(i,j,k,gridSurface2)].abs[1,1];
        connect(surfaces2.toSurfacesPorts[i].heatPortLw[j,k],radiationDistribution.toSurfacePorts[numberOfGridSurfaces(gridSurface1)+indexM(i,j,k,gridSurface2)].heatPortLw[1,1]);
        connect(surfaces2.toSurfacesPorts[i].heatPortSw[j,k],radiationDistribution.toSurfacePorts[numberOfGridSurfaces(gridSurface1)+indexM(i,j,k,gridSurface2)].heatPortSw[1,1]);
        connect(surfaces2.toSurfacesPorts[i].radiationPort_in[j,k],radiationDistribution.toSurfacePorts[numberOfGridSurfaces(gridSurface1)+indexM(i,j,k,gridSurface2)].radiationPort_in[1,1]);
        connect(surfaces2.toSurfacesPorts[i].radiationPort_out[j,k],radiationDistribution.toSurfacePorts[numberOfGridSurfaces(gridSurface1)+indexM(i,j,k,gridSurface2)].radiationPort_out[1,1]);
      end for;
    end for;
  end for;
  for i in 1:nConstructions3 loop
    connect(surfaces3.toConstructionPorts[i],toConstructionPorts3[i]);
    for j in 1:gridSurface3[i,1] loop
      for k in 1:gridSurface3[i,2] loop
        surfaces3.toSurfacesPorts[i].angleDegAzi = radiationDistribution.toSurfacePorts[numberOfGridSurfaces(gridSurface1)+numberOfGridSurfaces(gridSurface2)+indexM(i,j,k,gridSurface3)].angleDegAzi;
        surfaces3.toSurfacesPorts[i].angleDegTil = radiationDistribution.toSurfacePorts[numberOfGridSurfaces(gridSurface1)+numberOfGridSurfaces(gridSurface2)+indexM(i,j,k,gridSurface3)].angleDegTil;
        surfaces3.toSurfacesPorts[i].zMean = radiationDistribution.toSurfacePorts[numberOfGridSurfaces(gridSurface1)+numberOfGridSurfaces(gridSurface2)+indexM(i,j,k,gridSurface3)].zMean;
        surfaces3.toSurfacesPorts[i].A[j,k] = radiationDistribution.toSurfacePorts[numberOfGridSurfaces(gridSurface1)+numberOfGridSurfaces(gridSurface2)+indexM(i,j,k,gridSurface3)].A[1,1];
        surfaces3.toSurfacesPorts[i].epsilon[j,k] = radiationDistribution.toSurfacePorts[numberOfGridSurfaces(gridSurface1)+numberOfGridSurfaces(gridSurface2)+indexM(i,j,k,gridSurface3)].epsilon[1,1];
        surfaces3.toSurfacesPorts[i].abs[j,k] = radiationDistribution.toSurfacePorts[numberOfGridSurfaces(gridSurface1)+numberOfGridSurfaces(gridSurface2)+indexM(i,j,k,gridSurface3)].abs[1,1];
        connect(surfaces3.toSurfacesPorts[i].heatPortLw[j,k],radiationDistribution.toSurfacePorts[numberOfGridSurfaces(gridSurface1)+numberOfGridSurfaces(gridSurface2)+indexM(i,j,k,gridSurface3)].heatPortLw[1,1]);
        connect(surfaces3.toSurfacesPorts[i].heatPortSw[j,k],radiationDistribution.toSurfacePorts[numberOfGridSurfaces(gridSurface1)+numberOfGridSurfaces(gridSurface2)+indexM(i,j,k,gridSurface3)].heatPortSw[1,1]);
        connect(surfaces3.toSurfacesPorts[i].radiationPort_in[j,k],radiationDistribution.toSurfacePorts[numberOfGridSurfaces(gridSurface1)+numberOfGridSurfaces(gridSurface2)+indexM(i,j,k,gridSurface3)].radiationPort_in[1,1]);
        connect(surfaces3.toSurfacesPorts[i].radiationPort_out[j,k],radiationDistribution.toSurfacePorts[numberOfGridSurfaces(gridSurface1)+numberOfGridSurfaces(gridSurface2)+indexM(i,j,k,gridSurface3)].radiationPort_out[1,1]);
      end for;
    end for;
  end for;
  for i in 1:nConstructions4 loop
    connect(surfaces4.toConstructionPorts[i],toConstructionPorts4[i]);
     for j in 1:gridSurface4[i,1] loop
      for k in 1:gridSurface4[i,2] loop
        surfaces4.toSurfacesPorts[i].angleDegAzi = radiationDistribution.toSurfacePorts[numberOfGridSurfaces(gridSurface1)+numberOfGridSurfaces(gridSurface2)+numberOfGridSurfaces(gridSurface3)+indexM(i,j,k,gridSurface4)].angleDegAzi;
        surfaces4.toSurfacesPorts[i].angleDegTil = radiationDistribution.toSurfacePorts[numberOfGridSurfaces(gridSurface1)+numberOfGridSurfaces(gridSurface2)+numberOfGridSurfaces(gridSurface3)+indexM(i,j,k,gridSurface4)].angleDegTil;
        surfaces4.toSurfacesPorts[i].zMean = radiationDistribution.toSurfacePorts[numberOfGridSurfaces(gridSurface1)+numberOfGridSurfaces(gridSurface2)+numberOfGridSurfaces(gridSurface3)+indexM(i,j,k,gridSurface4)].zMean;
        surfaces4.toSurfacesPorts[i].A[j,k] = radiationDistribution.toSurfacePorts[numberOfGridSurfaces(gridSurface1)+numberOfGridSurfaces(gridSurface2)+numberOfGridSurfaces(gridSurface3)+indexM(i,j,k,gridSurface4)].A[1,1];
        surfaces4.toSurfacesPorts[i].epsilon[j,k] = radiationDistribution.toSurfacePorts[numberOfGridSurfaces(gridSurface1)+numberOfGridSurfaces(gridSurface2)+numberOfGridSurfaces(gridSurface3)+indexM(i,j,k,gridSurface4)].epsilon[1,1];
        surfaces4.toSurfacesPorts[i].abs[j,k] = radiationDistribution.toSurfacePorts[numberOfGridSurfaces(gridSurface1)+numberOfGridSurfaces(gridSurface2)+numberOfGridSurfaces(gridSurface3)+indexM(i,j,k,gridSurface4)].abs[1,1];
        connect(surfaces4.toSurfacesPorts[i].heatPortLw[j,k],radiationDistribution.toSurfacePorts[numberOfGridSurfaces(gridSurface1)+numberOfGridSurfaces(gridSurface2)+numberOfGridSurfaces(gridSurface3)+indexM(i,j,k,gridSurface4)].heatPortLw[1,1]);
        connect(surfaces4.toSurfacesPorts[i].heatPortSw[j,k],radiationDistribution.toSurfacePorts[numberOfGridSurfaces(gridSurface1)+numberOfGridSurfaces(gridSurface2)+numberOfGridSurfaces(gridSurface3)+indexM(i,j,k,gridSurface4)].heatPortSw[1,1]);
        connect(surfaces4.toSurfacesPorts[i].radiationPort_in[j,k],radiationDistribution.toSurfacePorts[numberOfGridSurfaces(gridSurface1)+numberOfGridSurfaces(gridSurface2)+numberOfGridSurfaces(gridSurface3)+indexM(i,j,k,gridSurface4)].radiationPort_in[1,1]);
        connect(surfaces4.toSurfacesPorts[i].radiationPort_out[j,k],radiationDistribution.toSurfacePorts[numberOfGridSurfaces(gridSurface1)+numberOfGridSurfaces(gridSurface2)+numberOfGridSurfaces(gridSurface3)+indexM(i,j,k,gridSurface4)].radiationPort_out[1,1]);
      end for;
    end for;
  end for;
  for i in 1:nConstructions5 loop
    connect(surfaces5.toConstructionPorts[i],toConstructionPorts5[i]);
    for j in 1:gridSurface5[i,1] loop
      for k in 1:gridSurface5[i,2] loop
        surfaces5.toSurfacesPorts[i].angleDegAzi = radiationDistribution.toSurfacePorts[numberOfGridSurfaces(gridSurface1)+numberOfGridSurfaces(gridSurface2)+numberOfGridSurfaces(gridSurface3)+numberOfGridSurfaces(gridSurface4)+indexM(i,j,k,gridSurface5)].angleDegAzi;
        surfaces5.toSurfacesPorts[i].angleDegTil = radiationDistribution.toSurfacePorts[numberOfGridSurfaces(gridSurface1)+numberOfGridSurfaces(gridSurface2)+numberOfGridSurfaces(gridSurface3)+numberOfGridSurfaces(gridSurface4)+indexM(i,j,k,gridSurface5)].angleDegTil;
        surfaces5.toSurfacesPorts[i].zMean = radiationDistribution.toSurfacePorts[numberOfGridSurfaces(gridSurface1)+numberOfGridSurfaces(gridSurface2)+numberOfGridSurfaces(gridSurface3)+numberOfGridSurfaces(gridSurface4)+indexM(i,j,k,gridSurface5)].zMean;
        surfaces5.toSurfacesPorts[i].A[j,k] = radiationDistribution.toSurfacePorts[numberOfGridSurfaces(gridSurface1)+numberOfGridSurfaces(gridSurface2)+numberOfGridSurfaces(gridSurface3)+numberOfGridSurfaces(gridSurface4)+indexM(i,j,k,gridSurface5)].A[1,1];
        surfaces5.toSurfacesPorts[i].epsilon[j,k] = radiationDistribution.toSurfacePorts[numberOfGridSurfaces(gridSurface1)+numberOfGridSurfaces(gridSurface2)+numberOfGridSurfaces(gridSurface3)+numberOfGridSurfaces(gridSurface4)+indexM(i,j,k,gridSurface5)].epsilon[1,1];
        surfaces5.toSurfacesPorts[i].abs[j,k] = radiationDistribution.toSurfacePorts[numberOfGridSurfaces(gridSurface1)+numberOfGridSurfaces(gridSurface2)+numberOfGridSurfaces(gridSurface3)+numberOfGridSurfaces(gridSurface4)+indexM(i,j,k,gridSurface5)].abs[1,1];
        connect(surfaces5.toSurfacesPorts[i].heatPortLw[j,k],radiationDistribution.toSurfacePorts[numberOfGridSurfaces(gridSurface1)+numberOfGridSurfaces(gridSurface2)+numberOfGridSurfaces(gridSurface3)+numberOfGridSurfaces(gridSurface4)+indexM(i,j,k,gridSurface5)].heatPortLw[1,1]);
        connect(surfaces5.toSurfacesPorts[i].heatPortSw[j,k],radiationDistribution.toSurfacePorts[numberOfGridSurfaces(gridSurface1)+numberOfGridSurfaces(gridSurface2)+numberOfGridSurfaces(gridSurface3)+numberOfGridSurfaces(gridSurface4)+indexM(i,j,k,gridSurface5)].heatPortSw[1,1]);
        connect(surfaces5.toSurfacesPorts[i].radiationPort_in[j,k],radiationDistribution.toSurfacePorts[numberOfGridSurfaces(gridSurface1)+numberOfGridSurfaces(gridSurface2)+numberOfGridSurfaces(gridSurface3)+numberOfGridSurfaces(gridSurface4)+indexM(i,j,k,gridSurface5)].radiationPort_in[1,1]);
        connect(surfaces5.toSurfacesPorts[i].radiationPort_out[j,k],radiationDistribution.toSurfacePorts[numberOfGridSurfaces(gridSurface1)+numberOfGridSurfaces(gridSurface2)+numberOfGridSurfaces(gridSurface3)+numberOfGridSurfaces(gridSurface4)+indexM(i,j,k,gridSurface5)].radiationPort_out[1,1]);
      end for;
    end for;
  end for;
  for i in 1:nConstructions6 loop
    connect(surfaces6.toConstructionPorts[i],toConstructionPorts6[i]);
     for j in 1:gridSurface6[i,1] loop
      for k in 1:gridSurface6[i,2] loop
        surfaces6.toSurfacesPorts[i].angleDegAzi = radiationDistribution.toSurfacePorts[numberOfGridSurfaces(gridSurface1)+numberOfGridSurfaces(gridSurface2)+numberOfGridSurfaces(gridSurface3)+numberOfGridSurfaces(gridSurface4)+numberOfGridSurfaces(gridSurface5)+ indexM(i,j,k,gridSurface6)].angleDegAzi;
        surfaces6.toSurfacesPorts[i].angleDegTil = radiationDistribution.toSurfacePorts[numberOfGridSurfaces(gridSurface1)+numberOfGridSurfaces(gridSurface2)+numberOfGridSurfaces(gridSurface3)+numberOfGridSurfaces(gridSurface4)+numberOfGridSurfaces(gridSurface5)+indexM(i,j,k,gridSurface6)].angleDegTil;
        surfaces6.toSurfacesPorts[i].zMean = radiationDistribution.toSurfacePorts[numberOfGridSurfaces(gridSurface1)+numberOfGridSurfaces(gridSurface2)+numberOfGridSurfaces(gridSurface3)+numberOfGridSurfaces(gridSurface4)+numberOfGridSurfaces(gridSurface5)+indexM(i,j,k,gridSurface6)].zMean;
        surfaces6.toSurfacesPorts[i].A[j,k] = radiationDistribution.toSurfacePorts[numberOfGridSurfaces(gridSurface1)+numberOfGridSurfaces(gridSurface2)+numberOfGridSurfaces(gridSurface3)+numberOfGridSurfaces(gridSurface4)+numberOfGridSurfaces(gridSurface5)+indexM(i,j,k,gridSurface6)].A[1,1];
        surfaces6.toSurfacesPorts[i].epsilon[j,k] = radiationDistribution.toSurfacePorts[numberOfGridSurfaces(gridSurface1)+numberOfGridSurfaces(gridSurface2)+numberOfGridSurfaces(gridSurface3)+numberOfGridSurfaces(gridSurface4)+numberOfGridSurfaces(gridSurface5)+indexM(i,j,k,gridSurface6)].epsilon[1,1];
        surfaces6.toSurfacesPorts[i].abs[j,k] = radiationDistribution.toSurfacePorts[numberOfGridSurfaces(gridSurface1)+numberOfGridSurfaces(gridSurface2)+numberOfGridSurfaces(gridSurface3)+numberOfGridSurfaces(gridSurface4)+numberOfGridSurfaces(gridSurface5)+indexM(i,j,k,gridSurface6)].abs[1,1];
        connect(surfaces6.toSurfacesPorts[i].heatPortLw[j,k],radiationDistribution.toSurfacePorts[numberOfGridSurfaces(gridSurface1)+numberOfGridSurfaces(gridSurface2)+numberOfGridSurfaces(gridSurface3)+numberOfGridSurfaces(gridSurface4)+numberOfGridSurfaces(gridSurface5)+indexM(i,j,k,gridSurface6)].heatPortLw[1,1]);
        connect(surfaces6.toSurfacesPorts[i].heatPortSw[j,k],radiationDistribution.toSurfacePorts[numberOfGridSurfaces(gridSurface1)+numberOfGridSurfaces(gridSurface2)+numberOfGridSurfaces(gridSurface3)+numberOfGridSurfaces(gridSurface4)+numberOfGridSurfaces(gridSurface5)+indexM(i,j,k,gridSurface6)].heatPortSw[1,1]);
        connect(surfaces6.toSurfacesPorts[i].radiationPort_in[j,k],radiationDistribution.toSurfacePorts[numberOfGridSurfaces(gridSurface1)+numberOfGridSurfaces(gridSurface2)+numberOfGridSurfaces(gridSurface3)+numberOfGridSurfaces(gridSurface4)+numberOfGridSurfaces(gridSurface5)+indexM(i,j,k,gridSurface6)].radiationPort_in[1,1]);
        connect(surfaces6.toSurfacesPorts[i].radiationPort_out[j,k],radiationDistribution.toSurfacePorts[numberOfGridSurfaces(gridSurface1)+numberOfGridSurfaces(gridSurface2)+numberOfGridSurfaces(gridSurface3)+numberOfGridSurfaces(gridSurface4)+numberOfGridSurfaces(gridSurface5)+indexM(i,j,k,gridSurface6)].radiationPort_out[1,1]);
      end for;
    end for;
  end for;

  connect(radiationDistribution.TSurfMean, TSurfMean);

end ZoneTemplateGeneral;
 
partial package Modelica.Icons.InterfacesPackage 
  "Icon for packages containing interfaces"
  extends Modelica.Icons.Package;
end InterfacesPackage;
 
partial package Modelica.Media.Interfaces.PartialMedium 
  "Partial medium properties (base package of all media packages)"
  extends Modelica.Media.Interfaces.Types;
  extends Modelica.Icons.MaterialPropertiesPackage;

  // Constants to be set in Medium
  constant Modelica.Media.Interfaces.Choices.IndependentVariables
    ThermoStates "Enumeration type for independent variables";
  constant String mediumName="unusablePartialMedium" "Name of the medium";
  constant String substanceNames[:]={mediumName} 
    "Names of the mixture substances. Set substanceNames={mediumName} if only one substance.";
  constant String extraPropertiesNames[:]=fill("", 0) 
    "Names of the additional (extra) transported properties. Set extraPropertiesNames=fill(\"\",0) if unused";
  constant Boolean singleState 
    "= true, if u and d are not a function of pressure";
  constant Boolean reducedX=true 
    "= true if medium contains the equation sum(X) = 1.0; set reducedX=true if only one substance (see docu for details)";
  constant Boolean fixedX=false 
    "= true if medium contains the equation X = reference_X";
  constant AbsolutePressure reference_p=101325 
    "Reference pressure of Medium: default 1 atmosphere";
  constant Temperature reference_T=298.15 
    "Reference temperature of Medium: default 25 deg Celsius";
  constant MassFraction reference_X[nX]=fill(1/nX, nX) 
    "Default mass fractions of medium";
  constant AbsolutePressure p_default=101325 
    "Default value for pressure of medium (for initialization)";
  constant Temperature T_default=Modelica.SIunits.Conversions.from_degC(20) 
    "Default value for temperature of medium (for initialization)";
  constant SpecificEnthalpy h_default=specificEnthalpy_pTX(
          p_default,
          T_default,
          X_default) 
    "Default value for specific enthalpy of medium (for initialization)";
  constant MassFraction X_default[nX]=reference_X 
    "Default value for mass fractions of medium (for initialization)";

  final constant Integer nS=size(substanceNames, 1) "Number of substances";
  constant Integer nX=nS "Number of mass fractions";
  constant Integer nXi=if fixedX then 0 else if reducedX then nS - 1 else nS 
    "Number of structurally independent mass fractions (see docu for details)";

  final constant Integer nC=size(extraPropertiesNames, 1) 
    "Number of extra (outside of standard mass-balance) transported properties";
  constant Real C_nominal[nC](min=fill(Modelica.Constants.eps, nC)) = 1.0e-6*
    ones(nC) "Default for the nominal values for the extra properties";
  replaceable record FluidConstants =
      Modelica.Media.Interfaces.Types.Basic.FluidConstants 
    "Critical, triple, molecular and other standard data of fluid";

  replaceable record ThermodynamicState 
    "Minimal variable set that is available as input argument to every medium function"
    extends Modelica.Icons.Record;
  end ThermodynamicState;

  replaceable partial model BaseProperties 
    "Base properties (p, d, T, h, u, R, MM and, if applicable, X and Xi) of a medium"
    InputAbsolutePressure p "Absolute pressure of medium";
    InputMassFraction[nXi] Xi(start=reference_X[1:nXi]) 
      "Structurally independent mass fractions";
    InputSpecificEnthalpy h "Specific enthalpy of medium";
    Density d "Density of medium";
    Temperature T "Temperature of medium";
    MassFraction[nX] X(start=reference_X) 
      "Mass fractions (= (component mass)/total mass  m_i/m)";
    SpecificInternalEnergy u "Specific internal energy of medium";
    SpecificHeatCapacity R "Gas constant (of mixture if applicable)";
    MolarMass MM "Molar mass (of mixture or single fluid)";
    ThermodynamicState state 
      "Thermodynamic state record for optional functions";
    parameter Boolean preferredMediumStates=false 
      "= true if StateSelect.prefer shall be used for the independent property variables of the medium";
    parameter Boolean standardOrderComponents=true 
      "If true, and reducedX = true, the last element of X will be computed from the other ones";
    SI.Conversions.NonSIunits.Temperature_degC T_degC=
        Modelica.SIunits.Conversions.to_degC(T) 
      "Temperature of medium in [degC]";
    SI.Conversions.NonSIunits.Pressure_bar p_bar=
        Modelica.SIunits.Conversions.to_bar(p) 
      "Absolute pressure of medium in [bar]";

    // Local connector definition, used for equation balancing check
    connector InputAbsolutePressure = input SI.AbsolutePressure 
      "Pressure as input signal connector";
    connector InputSpecificEnthalpy = input SI.SpecificEnthalpy 
      "Specific enthalpy as input signal connector";
    connector InputMassFraction = input SI.MassFraction 
      "Mass fraction as input signal connector";

  equation 
    if standardOrderComponents then
      Xi = X[1:nXi];

      if fixedX then
        X = reference_X;
      end if;
      if reducedX and not fixedX then
        X[nX] = 1 - sum(Xi);
      end if;
      for i in 1:nX loop
        assert(X[i] >= -1.e-5 and X[i] <= 1 + 1.e-5, "Mass fraction X[" +
          String(i) + "] = " + String(X[i]) + "of substance " +
          substanceNames[i] + "\nof medium " + mediumName +
          " is not in the range 0..1");
      end for;

    end if;

    assert(p >= 0.0, "Pressure (= " + String(p) + " Pa) of medium \"" +
      mediumName + "\" is negative\n(Temperature = " + String(T) + " K)");
  end BaseProperties;

  replaceable partial function setState_pTX 
    "Return thermodynamic state as function of p, T and composition X or Xi"
    extends Modelica.Icons.Function;
    input AbsolutePressure p "Pressure";
    input Temperature T "Temperature";
    input MassFraction X[:]=reference_X "Mass fractions";
    output ThermodynamicState state "Thermodynamic state record";
  end setState_pTX;

  replaceable partial function setState_phX 
    "Return thermodynamic state as function of p, h and composition X or Xi"
    extends Modelica.Icons.Function;
    input AbsolutePressure p "Pressure";
    input SpecificEnthalpy h "Specific enthalpy";
    input MassFraction X[:]=reference_X "Mass fractions";
    output ThermodynamicState state "Thermodynamic state record";
  end setState_phX;

  replaceable partial function setState_psX 
    "Return thermodynamic state as function of p, s and composition X or Xi"
    extends Modelica.Icons.Function;
    input AbsolutePressure p "Pressure";
    input SpecificEntropy s "Specific entropy";
    input MassFraction X[:]=reference_X "Mass fractions";
    output ThermodynamicState state "Thermodynamic state record";
  end setState_psX;

  replaceable partial function setState_dTX 
    "Return thermodynamic state as function of d, T and composition X or Xi"
    extends Modelica.Icons.Function;
    input Density d "Density";
    input Temperature T "Temperature";
    input MassFraction X[:]=reference_X "Mass fractions";
    output ThermodynamicState state "Thermodynamic state record";
  end setState_dTX;

  replaceable partial function setSmoothState 
    "Return thermodynamic state so that it smoothly approximates: if x > 0 then state_a else state_b"
    extends Modelica.Icons.Function;
    input Real x "m_flow or dp";
    input ThermodynamicState state_a "Thermodynamic state if x > 0";
    input ThermodynamicState state_b "Thermodynamic state if x < 0";
    input Real x_small(min=0) 
      "Smooth transition in the region -x_small < x < x_small";
    output ThermodynamicState state 
      "Smooth thermodynamic state for all x (continuous and differentiable)";
  end setSmoothState;

  replaceable partial function dynamicViscosity 
    "Return dynamic viscosity"
    extends Modelica.Icons.Function;
    input ThermodynamicState state "Thermodynamic state record";
    output DynamicViscosity eta "Dynamic viscosity";
  end dynamicViscosity;

  replaceable partial function thermalConductivity 
    "Return thermal conductivity"
    extends Modelica.Icons.Function;
    input ThermodynamicState state "Thermodynamic state record";
    output ThermalConductivity lambda "Thermal conductivity";
  end thermalConductivity;

  replaceable function prandtlNumber "Return the Prandtl number"
    extends Modelica.Icons.Function;
    input ThermodynamicState state "Thermodynamic state record";
    output PrandtlNumber Pr "Prandtl number";
  algorithm 
    Pr := dynamicViscosity(state)*specificHeatCapacityCp(state)/
      thermalConductivity(state);
  end prandtlNumber;

  replaceable partial function pressure "Return pressure"
    extends Modelica.Icons.Function;
    input ThermodynamicState state "Thermodynamic state record";
    output AbsolutePressure p "Pressure";
  end pressure;

  replaceable partial function temperature "Return temperature"
    extends Modelica.Icons.Function;
    input ThermodynamicState state "Thermodynamic state record";
    output Temperature T "Temperature";
  end temperature;

  replaceable partial function density "Return density"
    extends Modelica.Icons.Function;
    input ThermodynamicState state "Thermodynamic state record";
    output Density d "Density";
  end density;

  replaceable partial function specificEnthalpy 
    "Return specific enthalpy"
    extends Modelica.Icons.Function;
    input ThermodynamicState state "Thermodynamic state record";
    output SpecificEnthalpy h "Specific enthalpy";
  end specificEnthalpy;

  replaceable partial function specificInternalEnergy 
    "Return specific internal energy"
    extends Modelica.Icons.Function;
    input ThermodynamicState state "Thermodynamic state record";
    output SpecificEnergy u "Specific internal energy";
  end specificInternalEnergy;

  replaceable partial function specificEntropy 
    "Return specific entropy"
    extends Modelica.Icons.Function;
    input ThermodynamicState state "Thermodynamic state record";
    output SpecificEntropy s "Specific entropy";
  end specificEntropy;

  replaceable partial function specificGibbsEnergy 
    "Return specific Gibbs energy"
    extends Modelica.Icons.Function;
    input ThermodynamicState state "Thermodynamic state record";
    output SpecificEnergy g "Specific Gibbs energy";
  end specificGibbsEnergy;

  replaceable partial function specificHelmholtzEnergy 
    "Return specific Helmholtz energy"
    extends Modelica.Icons.Function;
    input ThermodynamicState state "Thermodynamic state record";
    output SpecificEnergy f "Specific Helmholtz energy";
  end specificHelmholtzEnergy;

  replaceable partial function specificHeatCapacityCp 
    "Return specific heat capacity at constant pressure"
    extends Modelica.Icons.Function;
    input ThermodynamicState state "Thermodynamic state record";
    output SpecificHeatCapacity cp 
      "Specific heat capacity at constant pressure";
  end specificHeatCapacityCp;

  function heatCapacity_cp = specificHeatCapacityCp "Alias for deprecated name";

  replaceable partial function specificHeatCapacityCv 
    "Return specific heat capacity at constant volume"
    extends Modelica.Icons.Function;
    input ThermodynamicState state "Thermodynamic state record";
    output SpecificHeatCapacity cv "Specific heat capacity at constant volume";
  end specificHeatCapacityCv;

  function heatCapacity_cv = specificHeatCapacityCv "Alias for deprecated name";

  replaceable partial function isentropicExponent 
    "Return isentropic exponent"
    extends Modelica.Icons.Function;
    input ThermodynamicState state "Thermodynamic state record";
    output IsentropicExponent gamma "Isentropic exponent";
  end isentropicExponent;

  replaceable partial function isentropicEnthalpy 
    "Return isentropic enthalpy"
    extends Modelica.Icons.Function;
    input AbsolutePressure p_downstream "Downstream pressure";
    input ThermodynamicState refState "Reference state for entropy";
    output SpecificEnthalpy h_is "Isentropic enthalpy";
  end isentropicEnthalpy;

  replaceable partial function velocityOfSound 
    "Return velocity of sound"
    extends Modelica.Icons.Function;
    input ThermodynamicState state "Thermodynamic state record";
    output VelocityOfSound a "Velocity of sound";
  end velocityOfSound;

  replaceable partial function isobaricExpansionCoefficient 
    "Return overall the isobaric expansion coefficient beta"
    extends Modelica.Icons.Function;
    input ThermodynamicState state "Thermodynamic state record";
    output IsobaricExpansionCoefficient beta "Isobaric expansion coefficient";
  end isobaricExpansionCoefficient;

  function beta = isobaricExpansionCoefficient 
    "Alias for isobaricExpansionCoefficient for user convenience";

  replaceable partial function isothermalCompressibility 
    "Return overall the isothermal compressibility factor"
    extends Modelica.Icons.Function;
    input ThermodynamicState state "Thermodynamic state record";
    output SI.IsothermalCompressibility kappa "Isothermal compressibility";
  end isothermalCompressibility;

  function kappa = isothermalCompressibility 
    "Alias of isothermalCompressibility for user convenience";

  // explicit derivative functions for finite element models
  replaceable partial function density_derp_h 
    "Return density derivative w.r.t. pressure at const specific enthalpy"
    extends Modelica.Icons.Function;
    input ThermodynamicState state "Thermodynamic state record";
    output DerDensityByPressure ddph "Density derivative w.r.t. pressure";
  end density_derp_h;

  replaceable partial function density_derh_p 
    "Return density derivative w.r.t. specific enthalpy at constant pressure"
    extends Modelica.Icons.Function;
    input ThermodynamicState state "Thermodynamic state record";
    output DerDensityByEnthalpy ddhp 
      "Density derivative w.r.t. specific enthalpy";
  end density_derh_p;

  replaceable partial function density_derp_T 
    "Return density derivative w.r.t. pressure at const temperature"
    extends Modelica.Icons.Function;
    input ThermodynamicState state "Thermodynamic state record";
    output DerDensityByPressure ddpT "Density derivative w.r.t. pressure";
  end density_derp_T;

  replaceable partial function density_derT_p 
    "Return density derivative w.r.t. temperature at constant pressure"
    extends Modelica.Icons.Function;
    input ThermodynamicState state "Thermodynamic state record";
    output DerDensityByTemperature ddTp "Density derivative w.r.t. temperature";
  end density_derT_p;

  replaceable partial function density_derX 
    "Return density derivative w.r.t. mass fraction"
    extends Modelica.Icons.Function;
    input ThermodynamicState state "Thermodynamic state record";
    output Density[nX] dddX "Derivative of density w.r.t. mass fraction";
  end density_derX;

  replaceable partial function molarMass 
    "Return the molar mass of the medium"
    extends Modelica.Icons.Function;
    input ThermodynamicState state "Thermodynamic state record";
    output MolarMass MM "Mixture molar mass";
  end molarMass;

  replaceable function specificEnthalpy_pTX 
    "Return specific enthalpy from p, T, and X or Xi"
    extends Modelica.Icons.Function;
    input AbsolutePressure p "Pressure";
    input Temperature T "Temperature";
    input MassFraction X[:]=reference_X "Mass fractions";
    output SpecificEnthalpy h "Specific enthalpy";
  algorithm 
    h := specificEnthalpy(setState_pTX(
            p,
            T,
            X));
  end specificEnthalpy_pTX;

  replaceable function specificEntropy_pTX 
    "Return specific enthalpy from p, T, and X or Xi"
    extends Modelica.Icons.Function;
    input AbsolutePressure p "Pressure";
    input Temperature T "Temperature";
    input MassFraction X[:]=reference_X "Mass fractions";
    output SpecificEntropy s "Specific entropy";
  algorithm 
    s := specificEntropy(setState_pTX(
            p,
            T,
            X));

  end specificEntropy_pTX;

  replaceable function density_pTX 
    "Return density from p, T, and X or Xi"
    extends Modelica.Icons.Function;
    input AbsolutePressure p "Pressure";
    input Temperature T "Temperature";
    input MassFraction X[:] "Mass fractions";
    output Density d "Density";
  algorithm 
    d := density(setState_pTX(
            p,
            T,
            X));
  end density_pTX;

  replaceable function temperature_phX 
    "Return temperature from p, h, and X or Xi"
    extends Modelica.Icons.Function;
    input AbsolutePressure p "Pressure";
    input SpecificEnthalpy h "Specific enthalpy";
    input MassFraction X[:]=reference_X "Mass fractions";
    output Temperature T "Temperature";
  algorithm 
    T := temperature(setState_phX(
            p,
            h,
            X));
  end temperature_phX;

  replaceable function density_phX 
    "Return density from p, h, and X or Xi"
    extends Modelica.Icons.Function;
    input AbsolutePressure p "Pressure";
    input SpecificEnthalpy h "Specific enthalpy";
    input MassFraction X[:]=reference_X "Mass fractions";
    output Density d "Density";
  algorithm 
    d := density(setState_phX(
            p,
            h,
            X));
  end density_phX;

  replaceable function temperature_psX 
    "Return temperature from p,s, and X or Xi"
    extends Modelica.Icons.Function;
    input AbsolutePressure p "Pressure";
    input SpecificEntropy s "Specific entropy";
    input MassFraction X[:]=reference_X "Mass fractions";
    output Temperature T "Temperature";
  algorithm 
    T := temperature(setState_psX(
            p,
            s,
            X));
  end temperature_psX;

  replaceable function density_psX 
    "Return density from p, s, and X or Xi"
    extends Modelica.Icons.Function;
    input AbsolutePressure p "Pressure";
    input SpecificEntropy s "Specific entropy";
    input MassFraction X[:]=reference_X "Mass fractions";
    output Density d "Density";
  algorithm 
    d := density(setState_psX(
            p,
            s,
            X));
  end density_psX;

  replaceable function specificEnthalpy_psX 
    "Return specific enthalpy from p, s, and X or Xi"
    extends Modelica.Icons.Function;
    input AbsolutePressure p "Pressure";
    input SpecificEntropy s "Specific entropy";
    input MassFraction X[:]=reference_X "Mass fractions";
    output SpecificEnthalpy h "Specific enthalpy";
  algorithm 
    h := specificEnthalpy(setState_psX(
            p,
            s,
            X));
  end specificEnthalpy_psX;

  type MassFlowRate = SI.MassFlowRate (
      quantity="MassFlowRate." + mediumName,
      min=-1.0e5,
      max=1.e5) "Type for mass flow rate with medium specific attributes";

  // Only for backwards compatibility to version 3.2 (
  // (do not use these definitions in new models, but use Modelica.Media.Interfaces.Choices instead)
  package Choices = Modelica.Media.Interfaces.Choices;

end PartialMedium;
 
  final constant Real Modelica.Constants.eps=
                          ModelicaServices.Machine.eps 
  "Biggest number such that 1.0 + eps = 1.0";
 
  final constant Real ModelicaServices.Machine.eps=
                          1.e-15 "Biggest number such that 1.0 + eps = 1.0";
 
record Modelica.Media.Interfaces.Types.Basic.FluidConstants 
  "Critical, triple, molecular and other standard data of fluid"
  extends Modelica.Icons.Record;
  String iupacName "Complete IUPAC name (or common name, if non-existent)";
  String casRegistryNumber 
    "Chemical abstracts sequencing number (if it exists)";
  String chemicalFormula 
    "Chemical formula, (brutto, nomenclature according to Hill";
  String structureFormula "Chemical structure formula";
  MolarMass molarMass "Molar mass";
end FluidConstants;
 
partial record Modelica.Icons.Record "Icon for records"

end Record;
 
type Modelica.SIunits.AbsolutePressure =
                        Pressure (min=0.0, nominal = 1e5);
 
type Modelica.SIunits.SpecificEnthalpy =
                        SpecificEnergy;
 
type Modelica.SIunits.MassFraction =
                    Real (final quantity="MassFraction", final unit="1",
                          min=0, max=1);
 
partial function Modelica.Icons.Function "Icon for functions"

end Function;
 
partial package Modelica.Icons.MaterialPropertiesPackage 
  "Icon for package containing property classes"
  extends Modelica.Icons.Package;
end MaterialPropertiesPackage;
 
partial package Modelica.Icons.TypesPackage 
  "Icon for packages containing type definitions"
  extends Modelica.Icons.Package;
end TypesPackage;
 
type BuildingSystems.HAM.ConvectiveHeatTransfer.Types.Convection = enumeration(
    free "Free convection",
    forced "Forced convection",
    const "Constant alpha value");
 
model BuildingSystems.Buildings.BaseClasses.RadiationDistribution 
  "Model for short-wave and long-wave radiation distribution within a thermal zone"
  parameter Integer nSurfaces = 0 "Number of surfaces of the thermal zone";
  parameter Integer nHeatSources = 0 
    "Number of internal heat sources of the thermal zone";
  parameter BuildingSystems.Types.ViewFactor F[nSurfaces,nSurfaces](
    fixed=false) "View factor matrix of the thermal zone";
  parameter BuildingSystems.Types.ViewFactor ViewFac[nSurfaces,nSurfaces]=fill(fill(0.0,nSurfaces),nSurfaces) 
    "Geometric view factor matrix of the thermal zone";
  parameter Boolean geometricViewFactors= false 
    "true: use of geometric view factors, false: use of surface area weighted view factors";
  Modelica.SIunits.Area ATotal "Total surface area of the thermal zone";
  BuildingSystems.Buildings.Interfaces.SurfaceToSurfacesPorts toSurfacePorts[nSurfaces](
    each nY=1,
    each nZ=1);
  BuildingSystems.Interfaces.HeatPorts heatSourcesPorts[nHeatSources];
  Modelica.SIunits.HeatFlowRate Q_flow_Sw 
    "Total short radiation gains of the thermal zone";
  BuildingSystems.Interfaces.Temp_KOutput TSurfMean 
    "Mean temperatures of all surfaces";
protected 
            Modelica.SIunits.HeatFlux J[nSurfaces](each start = 0.0) 
    "Radiosity of each surface";
initial equation 
  if not geometricViewFactors then
    for i in 1:nSurfaces loop
      for j in 1:nSurfaces loop
        F[i,j] = toSurfacePorts[j].A[1,1]/sum(toSurfacePorts[k].A[1,1] for k in 1:nSurfaces);
      end for;
    end for;
  else
    F=ViewFac;
  end if;
equation 
  ATotal = sum(toSurfacePorts[:].A[1,1]);
  // Total short-wave radiation gains of the zone
  Q_flow_Sw = sum({toSurfacePorts[i].radiationPort_out[1,1].IrrDir*toSurfacePorts[i].A[1,1] + toSurfacePorts[i].radiationPort_out[1,1].IrrDif*toSurfacePorts[i].A[1,1] for i in 1:nSurfaces});
  for i in 1:nSurfaces loop
    // Radiosity of each surface
    J[i] = toSurfacePorts[i].epsilon[1,1]*Modelica.Constants.sigma*toSurfacePorts[i].heatPortLw[1,1].T^4 + (1.0-toSurfacePorts[i].epsilon[1,1])*sum({F[i,j]*J[j] for j in 1:nSurfaces});
    // Netto heat flux rate of each surface
    toSurfacePorts[i].heatPortLw[1,1].Q_flow = toSurfacePorts[i].A[1,1]*toSurfacePorts[i].epsilon[1,1]/(1.0-toSurfacePorts[i].epsilon[1,1])*(Modelica.Constants.sigma*toSurfacePorts[i].heatPortLw[1,1].T^4-J[i])
      - toSurfacePorts[i].A[1,1]/ATotal * sum(heatSourcesPorts.Q_flow);
    // Area weighted short-wave radiation distribution on each surface
    toSurfacePorts[i].heatPortSw[1,1].Q_flow = - toSurfacePorts[i].abs[1,1] * toSurfacePorts[i].A[1,1] / ATotal * Q_flow_Sw;
    toSurfacePorts[i].radiationPort_in[1,1].IrrDir= 0.0;
    toSurfacePorts[i].radiationPort_in[1,1].IrrDif = - Q_flow_Sw / ATotal;
    toSurfacePorts[i].radiationPort_in[1,1].angleDegInc = 50.0;
  end for;
  // Mean surface temperature
  TSurfMean = sum({toSurfacePorts[i].heatPortLw[1,1].T * toSurfacePorts[i].A[1,1] for i in 1:nSurfaces}) / ATotal;
  for i in 1:nHeatSources loop
    heatSourcesPorts[i].T = TSurfMean;
  end for;
end RadiationDistribution;
 
connector BuildingSystems.Buildings.Interfaces.SurfaceToSurfacesPorts 
  "Port between a single surface and a group of surfaces, large icon to be used for vectors of SurfaceToSurfacesPorts (complex connector type)"
  extends SurfaceToSurfacesPortGeneral;
end SurfaceToSurfacesPorts;
 
connector BuildingSystems.Buildings.Interfaces.SurfaceToSurfacesPortGeneral 
  "Port between a single surface and a group of surfaces (complex connector type)"
  parameter Integer nY "Number of surface elements in the y dimension";
  parameter Integer nZ "Number of surface elements in the z dimension";
  BuildingSystems.Interfaces.HeatPort heatPortLw[nY,nZ] 
    "Heat port for long-wave radiation exchange";
  BuildingSystems.Interfaces.HeatPort heatPortSw[nY,nZ] 
    "Heat port for absorbed short-wave radiation";
  BuildingSystems.Interfaces.RadiationPort radiationPort_out[nY,nZ] 
    "Radiation port for outgoing short wave radiation";
  BuildingSystems.Interfaces.RadiationPort radiationPort_in[nY,nZ] 
    "Radiation port for incoming short wave radiation";
  Modelica.SIunits.Area A[nY,nZ] "Surface area";
  Modelica.SIunits.Conversions.NonSIunits.Angle_deg angleDegAzi 
    "Azimuth angle of the surface";
  Modelica.SIunits.Conversions.NonSIunits.Angle_deg angleDegTil 
    "Tilt angle of the surface";
  Modelica.SIunits.Length zMean "Mean vertical position of the surface";
  Modelica.SIunits.Emissivity epsilon[nY,nZ] 
    "Long-wave emittance of the surface";
  BuildingSystems.Types.Absorptance abs[nY,nZ] 
    "Short-wave absorptance of the surface";
end SurfaceToSurfacesPortGeneral;
 
connector BuildingSystems.Interfaces.HeatPort 
  "Port for heat transfer, small icon to be used for single HeatPort (base connector type)"
  extends Modelica.Thermal.HeatTransfer.Interfaces.HeatPort;
end HeatPort;
 
partial connector Modelica.Thermal.HeatTransfer.Interfaces.HeatPort 
  "Thermal port for 1-dim. heat transfer"
  Modelica.SIunits.Temperature T "Port temperature";
  flow Modelica.SIunits.HeatFlowRate Q_flow 
    "Heat flow rate (positive if flowing from outside into the component)";
end HeatPort;
 
connector BuildingSystems.Interfaces.RadiationPort 
  "Port for solar radiation transport, small icon to be used for single RadiationPort (base connector type)"
  extends BuildingSystems.Interfaces.RadiationPortGeneral;
end RadiationPort;
 
connector BuildingSystems.Interfaces.RadiationPortGeneral 
  "Port for solar radiation transport (base connector type)"
  Modelica.SIunits.RadiantEnergyFluenceRate IrrDir 
    "Area specific direct solar radiation";
  Modelica.SIunits.RadiantEnergyFluenceRate IrrDif 
    "Area specific diffuse solar radiation";
  Modelica.SIunits.Conversions.NonSIunits.Angle_deg angleDegInc 
    "Incident angle of the direct solar radiation";
end RadiationPortGeneral;
 
connector BuildingSystems.Interfaces.HeatPorts 
  "Port for heat transfer, large icon to be used for vectors of HeatPorts (base connector type)"
  extends Modelica.Thermal.HeatTransfer.Interfaces.HeatPort;
end HeatPorts;
 
connector BuildingSystems.Interfaces.Temp_KOutput =
                         Modelica.Blocks.Interfaces.RealOutput(final quantity="ThermodynamicTemperature",final unit="K",min = 0.0, displayUnit="degC");
 
connector Modelica.Blocks.Interfaces.RealOutput =
                       output Real "'output Real' as connector";
 
  final constant Real Modelica.Constants.sigma(
                            final unit="W/(m2.K4)") = 5.670400e-8 
  "Stefan-Boltzmann constant";
 
connector BuildingSystems.Buildings.Interfaces.SurfaceToConstructionPorts 
  "Port for heat and moisture transport between a surface and the adjacent construction, large icon to be used for vectors of SurfaceToConstructionPorts (complex connector type)"
  extends SurfaceToConstructionPortGeneral;
end SurfaceToConstructionPorts;
 
connector BuildingSystems.Buildings.Interfaces.SurfaceToConstructionPortGeneral
  "Port for heat and moisture transport between a surface and the adjacent construction (complex connector type)"
  BuildingSystems.Geometries.BaseClasses.GeometryRectangle geo 
    "3D geometry representation of the connected surface";
  parameter Integer nY "Number of surface elements in the y dimension";
  parameter Integer nZ "Number of surface elements in the z dimension";
  BuildingSystems.Interfaces.HeatPort heatPort[nY,nZ] "Port for heat transfer";
  BuildingSystems.Interfaces.MoisturePort moisturePort[nY,nZ] 
    "Port for moisture transfer";
  BuildingSystems.Interfaces.RadiationPort radiationPort_out[nY,nZ] 
    "Radiation port for outgoing short wave radiation";
  BuildingSystems.Interfaces.RadiationPort radiationPort_in[nY,nZ] 
    "Radiation port for incoming short wave radiation";
  Modelica.SIunits.Area A[nY,nZ] "Surface area";
  Modelica.SIunits.Emissivity epsilon[nY,nZ] 
    "Long-wave emittance of the surface";
  BuildingSystems.Types.Absorptance abs[nY,nZ] 
    "Short-wave absorptance of the surface";
end SurfaceToConstructionPortGeneral;
 
record BuildingSystems.Geometries.BaseClasses.GeometryRectangle 
  "3D representation of a rectangle"
  extends BuildingSystems.Geometries.BaseClasses.GeometryGeneral(
  nPoints=4);
  Modelica.SIunits.Length width "Width of the rectangle";
  Modelica.SIunits.Length height "Height of the rectangle";
  Modelica.SIunits.Length zMean "Mean vertical position";
  Modelica.SIunits.Conversions.NonSIunits.Angle_deg angleDegAzi 
    "Azimuth angle of the rectangle";
  Modelica.SIunits.Conversions.NonSIunits.Angle_deg angleDegTil 
    "Tilt angle of the rectangle";
end GeometryRectangle;
 
record BuildingSystems.Geometries.BaseClasses.GeometryGeneral 
  "Abstract 3D representation of a geometry"
  parameter Integer nPoints "Number of points, which represent the 3D geometry";
  BuildingSystems.Geometries.BaseClasses.Point point[nPoints] 
    "Individual points of a geometry";
end GeometryGeneral;
 
record BuildingSystems.Geometries.BaseClasses.Point 
  "3D representation of a point"
  Modelica.SIunits.Length x;
  Modelica.SIunits.Length y;
  Modelica.SIunits.Length z;
end Point;
 
connector BuildingSystems.Interfaces.MoisturePort 
  "Port for moisture transfer, small icon to be used for single MoisturePort (base connector type)"
  extends BuildingSystems.Interfaces.MoisturePortGeneral;
end MoisturePort;
 
connector BuildingSystems.Interfaces.MoisturePortGeneral 
  "Port for moisture transfer (base connector type)"
  Modelica.SIunits.MassFraction x(start = 0.01) "Absolute moisture";
                                                // start value is necessary for numerical reasons
  flow Modelica.SIunits.MassFlowRate m_flow "Mass flow rate water vapor";
end MoisturePortGeneral;
 
connector Modelica.Fluid.Vessels.BaseClasses.VesselFluidPorts_b 
  "Fluid connector with outlined, large icon to be used for horizontally aligned vectors of FluidPorts (vector dimensions must be added after dragging)"
  extends Interfaces.FluidPort;
end VesselFluidPorts_b;
 
connector Modelica.Fluid.Interfaces.FluidPort 
  "Interface for quasi one-dimensional fluid flow in a piping network (incompressible or compressible, one or more phases, one or more substances)"

  replaceable package Medium = Modelica.Media.Interfaces.PartialMedium 
    "Medium model";

  flow Medium.MassFlowRate m_flow 
    "Mass flow rate from the connection point into the component";
  Medium.AbsolutePressure p "Thermodynamic pressure in the connection point";
  stream Medium.SpecificEnthalpy h_outflow 
    "Specific thermodynamic enthalpy close to the connection point if m_flow < 0";
  stream Medium.MassFraction Xi_outflow[Medium.nXi] 
    "Independent mixture mass fractions m_i/m close to the connection point if m_flow < 0";
  stream Medium.ExtraProperty C_outflow[Medium.nC] 
    "Properties c_i/m close to the connection point if m_flow < 0";
end FluidPort;
 
model BuildingSystems.Buildings.Surfaces.SurfacesToAir 
  "Set of surfaces between a set of constructions and the air"
  parameter Integer nSurfaces=0 "Number of surfaces";
  parameter Integer gridSurface[nSurfaces,2]=fill({1,1},nSurfaces) 
    "Grid in y and z dimension of each surface";
  BuildingSystems.Buildings.Surfaces.SurfaceToAir surface[nSurfaces](
    nY=gridSurface[:, 1],
    nZ=gridSurface[:, 2]) "Set of surfaces";
  BuildingSystems.Buildings.Interfaces.SurfaceToConstructionPorts toConstructionPorts[nSurfaces](
    nY = gridSurface[:,1],
    nZ= gridSurface[:,2]) "Set of ports to the constructions";
  BuildingSystems.Buildings.Interfaces.SurfaceToSurfacesPorts toSurfacesPorts[nSurfaces](
    nY = gridSurface[:,1],
    nZ= gridSurface[:,2]) "Set of ports to other surfaces";
  BuildingSystems.Buildings.Interfaces.SurfaceToAirPorts toAirPorts[nSurfaces](
    nY = gridSurface[:,1],
    nZ= gridSurface[:,2]) "Set of ports to the air";
equation 
  for i in 1:nSurfaces loop
    connect(surface[i].toConstructionPort,toConstructionPorts[i]);
    connect(surface[i].toSurfacesPort,toSurfacesPorts[i]);
    connect(surface[i].toAirPort,toAirPorts[i]);
  end for;
end SurfacesToAir;
 
model BuildingSystems.Buildings.Surfaces.SurfaceToAir 
  "Surface model between a construction and the air"
  extends Buildings.BaseClasses.SurfaceGeneral;
  BuildingSystems.Buildings.Interfaces.SurfaceToAirPort toAirPort(
    nY=nY,
    nZ=nZ) "Port to the air";
  BuildingSystems.Buildings.Interfaces.SurfaceToSurfacesPort toSurfacesPort(
    nY=nY,
    nZ=nZ,
    epsilon=epsilon,
    abs=abs) "Port to other surfaces";
  Modelica.SIunits.SurfaceCoefficientOfHeatTransfer alpha[nY,nZ] 
    "Convective heat transfer coefficient";
  BuildingSystems.Types.MoistureTransferCoefficient beta[nY,nZ] 
    "Convective moisture transfer coefficient";
  Modelica.SIunits.Temp_K T[nY,nZ](
    each start=293.15) "Temperature";
  Modelica.SIunits.MassFraction x[nY,nZ](
    each start = 0.005) "Absolute moisture";
  Modelica.SIunits.Emissivity epsilon[nY,nZ] "Long-wave emittance";
  BuildingSystems.Types.Absorptance abs[nY,nZ] "Short-wave absorptance";
  parameter BuildingSystems.HAM.ConvectiveHeatTransfer.Types.Convection convectionOnSurface = BuildingSystems.HAM.ConvectiveHeatTransfer.Types.Convection.const 
    "Type of convection calculation of the surface";
  parameter Modelica.SIunits.SurfaceCoefficientOfHeatTransfer alphaConstant = 3.0 
    "Convective heat transfer coefficient for simplified calculations";
equation 
  toConstructionPort.abs = toSurfacesPort.abs;
  toConstructionPort.epsilon = toSurfacesPort.epsilon;
  toConstructionPort.geo.angleDegAzi = toSurfacesPort.angleDegAzi;
  toConstructionPort.geo.angleDegTil = toSurfacesPort.angleDegTil;
  toConstructionPort.geo.zMean = toSurfacesPort.zMean;
  for j in 1:nY loop
    for k in 1:nZ loop
      toAirPort.heatPort[j,k].Q_flow + toSurfacesPort.heatPortSw[j,k].Q_flow + toSurfacesPort.heatPortLw[j,k].Q_flow = - toConstructionPort.heatPort[j,k].Q_flow;
      // Free convection
      if convectionOnSurface == BuildingSystems.HAM.ConvectiveHeatTransfer.Types.Convection.free then
        alpha[j,k] = BuildingSystems.HAM.ConvectiveHeatTransfer.Surfaces.alphaPlateFree(
          toAirPort.heatPort[j, k].T - T[j, k],
          toConstructionPort.geo.height,
          toConstructionPort.geo.width,
          toConstructionPort.geo.angleDegTil);
      // Forced convection
      elseif convectionOnSurface == BuildingSystems.HAM.ConvectiveHeatTransfer.Types.Convection.forced then
        alpha[j,k] = BuildingSystems.HAM.ConvectiveHeatTransfer.Surfaces.alphaPlateForced(toAirPort.vAir[j,k]);
      // Simplified calculation with constant heat transfer coefficient
      else
        alpha[j,k] = alphaConstant;
      end if;
      beta[j,k] = alpha[j,k] * 1.0e-9;
      toAirPort.heatPort[j,k].Q_flow = alpha[j,k] * (toAirPort.heatPort[j,k].T - T[j,k]) * A[j,k];
      toAirPort.moisturePort[j,k].m_flow = - toConstructionPort.moisturePort[j,k].m_flow;
      toAirPort.moisturePort[j,k].m_flow = beta[j,k] * (toAirPort.moisturePort[j,k].x - x[j,k]) * BuildingSystems.Utilities.MoistAirFunctions.p(x[j,k],100000.0) * A[j,k];
      toSurfacesPort.heatPortSw[j,k].T = T[j,k];
      toSurfacesPort.heatPortLw[j,k].T = T[j,k];
      toConstructionPort.heatPort[j,k].T = T[j,k];
      toConstructionPort.moisturePort[j,k].x = x[j,k];
      toSurfacesPort.A[j,k] = A[j,k];
      connect(toConstructionPort.radiationPort_out,toSurfacesPort.radiationPort_out);
      connect(toConstructionPort.radiationPort_in,toSurfacesPort.radiationPort_in);
    end for;
  end for;
end SurfaceToAir;
 
connector BuildingSystems.Buildings.Interfaces.SurfaceToAirPort 
  "Port for heat and moisture transport between a surface and the adjacent air, small icon to be used for single SurfaceToAirPort (complex connector type)"
  extends SurfaceToAirPortGeneral;
end SurfaceToAirPort;
 
connector BuildingSystems.Buildings.Interfaces.SurfaceToAirPortGeneral 
  "Port for heat and moisture transport between a surface and the adjacent air (complex connector type)"
  parameter Integer nY "Number of surface elements in the y dimension";
  parameter Integer nZ "Number of surface elements in the z dimension";
  BuildingSystems.Interfaces.HeatPort heatPort[nY,nZ] "Port for heat transfer";
  BuildingSystems.Interfaces.MoisturePort moisturePort[nY,nZ] 
    "Port for moisture transfer";
  Modelica.SIunits.Velocity vAir[nY,nZ] "Air velocity";
  Modelica.SIunits.Conversions.NonSIunits.Angle_deg angleDegAir[nY,nZ] 
    "Direction of air motion (0 to 360 deg)";
end SurfaceToAirPortGeneral;
 
partial model BuildingSystems.Buildings.BaseClasses.SurfaceGeneral 
  "Generic surface model"
  parameter Integer nY = 1 "Number of surface elements in the y dimension";
  parameter Integer nZ = 1 "Number of surface elements in the z dimension";
  Buildings.Interfaces.SurfaceToConstructionPort toConstructionPort(
    nY=nY,
    nZ=nZ) "Port to the construction";
  Modelica.SIunits.Area A[nY,nZ] "Surface area";
equation 
  for j in 1:nY loop
    for k in 1:nZ loop
      toConstructionPort.A[j,k] = A[j,k];
    end for;
  end for;

end SurfaceGeneral;
 
connector BuildingSystems.Buildings.Interfaces.SurfaceToConstructionPort 
  "Port for heat and moisture transport between a surface and the adjacent construction, small icon to be used for single SurfaceToConstructionPort (complex connector type)"
  extends SurfaceToConstructionPortGeneral;
end SurfaceToConstructionPort;
 
connector BuildingSystems.Buildings.Interfaces.SurfaceToSurfacesPort 
  "Port between a single surface and a group of surfaces, small icon to be used for single SurfaceToSurfacesPort (complex connector type)"
  extends SurfaceToSurfacesPortGeneral;
end SurfaceToSurfacesPort;
 
connector BuildingSystems.Buildings.Interfaces.SurfaceToAirPorts 
  "Port for heat and moisture transport between a surface and the adjacent air, large icon to be used for vectors of SurfaceToAirPorts (complex connector type)"
  extends SurfaceToAirPortGeneral;
end SurfaceToAirPorts;
 
connector BuildingSystems.Interfaces.Temp_KInput =
                        Modelica.Blocks.Interfaces.RealInput(final quantity="ThermodynamicTemperature",final unit="K",min = 0.0, displayUnit="degC");
 
connector Modelica.Blocks.Interfaces.RealInput =
                      input Real "'input Real' as connector";
 
model BuildingSystems.Buildings.Airvolumes.AirvolumeCompressible0D 
  "Compressible ideal-mixed air volume model for moist air"
  extends BuildingSystems.Buildings.BaseClasses.AirvolumeGeneral(
  redeclare final package Medium = BuildingSystems.Media.Air);
  parameter Integer nAirpathes = 0 "Number of air pathes";
  parameter Integer nHeatSources = 0 "Number of heat convective sources";
  parameter Integer nMoistureSources = 0 "Number of moisture sources";
  parameter Modelica.SIunits.Length heightAirpath[nAirpathes] 
    "Vertical height of each air path";
  parameter Modelica.SIunits.Length height = 1.0 
    "Vertical height of the air volume";
  BuildingSystems.Types.RelativeHumidity phi "Relative humidity of the air";
  Modelica.SIunits.Mass m(
    start = V * rho_nominal) "Mass of dry air";
  Modelica.SIunits.Mass mH2OAir(
    start = x_start * V * rho_nominal) "Mass of water vapor in the air";
  Modelica.SIunits.Mass mH2OLiq(
    start = mH2OLiq_start) "Mass of liquid water";
  Modelica.SIunits.Pressure pMean "Mean air pressure in the air volume";
  Modelica.SIunits.EnthalpyFlowRate H_flow_airpath[nAirpathes] 
    "Enthalpy flow rate through each air path";
  Modelica.SIunits.EnthalpyFlowRate H_flow_moistureSource[nMoistureSources] 
    "Enthalpy flow rate by each moisture source";
  Modelica.SIunits.MassFlowRate m_flow_H2O_airpath[nAirpathes] 
    "Mass flow rate of water vapour through each air path";
  Modelica.Fluid.Vessels.BaseClasses.VesselFluidPorts_b airpathPorts[nAirpathes](
    redeclare each final package Medium=Medium) "Flow ports of the air pathes";
  BuildingSystems.Interfaces.HeatPorts heatSourcesPorts[nHeatSources] 
    "Heat ports of the convective heat sources";
  BuildingSystems.Interfaces.MoisturePorts moistureSourcesPorts[nMoistureSources] 
    "Moisture ports of the moisture sources";
protected 
  Modelica.SIunits.InternalEnergy U(
    start=((rho_nominal * V * BuildingSystems.Utilities.Psychrometrics.Constants.cpAir
      + rho_nominal * V * x_start * BuildingSystems.Utilities.Psychrometrics.Constants.cpSte
      + mH2OLiq_start * BuildingSystems.Utilities.Psychrometrics.Constants.cpWatLiq) * T_start
      + rH2O * rho_nominal * V * x_start)) "Internal energy of the air volume";
  constant Modelica.SIunits.Velocity vAir_constant = 0.0 "Air velocity";
  constant Modelica.SIunits.Conversions.NonSIunits.Angle_deg angleDegAir_constant = 0.0 
    "Direction of the air flow";
  constant Modelica.SIunits.Density rho_nominal = 1.2 
    "Air density under nominal conditions";
  constant Modelica.SIunits.Temp_K T_nominal = 293.15 
    "Air temperature under nominal conditions";
  constant BuildingSystems.Types.WaterVapourGasConstant R = 461.4 
    "Gas constant for water vapor";
  constant BuildingSystems.Types.WaterVapourEnthalpy rH2O = Medium.enthalpyOfVaporization(T_nominal) 
    "Enthalpy of vaporization for water";
equation 
  // Energy balance of the moist air inclusive the liquid water
  U = (BuildingSystems.Utilities.Psychrometrics.Constants.cpAir * m
    + BuildingSystems.Utilities.Psychrometrics.Constants.cpSte * mH2OAir
    + mH2OLiq * BuildingSystems.Utilities.Psychrometrics.Constants.cpWatLiq) * T + rH2O * mH2OAir;
  der(U) = sum(toSurfacePorts.heatPort.Q_flow) + sum(heatSourcesPorts.Q_flow) + sum(H_flow_airpath) + sum(H_flow_moistureSource);

  // Boundary conditions for heat sources of the air volume
  for i in 1:nHeatSources loop
    heatSourcesPorts[i].T = T;
  end for;

  // Boundary conditions for moisture sources of the air volume
  for i in 1:nMoistureSources loop
    moistureSourcesPorts[i].x = x;
  end for;

  // Boundary conditions for all surfaces of the air volume
  for i in 1:nSurfaces loop
    for j in 1:gridSurface[i,1] loop
      for k in 1:gridSurface[i,2] loop
        toSurfacePorts[i].heatPort[j,k].T = T;
        toSurfacePorts[i].moisturePort[j,k].x = x;
        toSurfacePorts[i].angleDegAir[j,k] = angleDegAir_constant;
        toSurfacePorts[i].vAir[j,k] = vAir_constant;
      end for;
    end for;
  end for;

  // Ideal gas law
  pMean * V = (0.622 + x) * m * R * T;

  // Mass balance of dry air
  der(m) = sum(airpathPorts.m_flow);

  //Mass balance of water vapor in the air
  der(mH2OAir) = sum(toSurfacePorts.moisturePort.m_flow)
    + sum(m_flow_H2O_airpath)
    + (-0.5 * Modelica.Math.tanh(100.0*(phi-1.0)) + 0.5) * sum(moistureSourcesPorts.m_flow)
    + BuildingSystems.Utilities.SmoothFunctions.softcut(1.0-phi,0.0,1.0,0.001) * mH2OLiq;
                                                         // water vaper from moisture transfer of surfaces
                              // water vapor within air mass flows through air pathes       // water vapor from moisture sources
                                                                                          // evaporated water from liquid reservoir

  mH2OAir = x * m;

  phi = BuildingSystems.Utilities.Psychrometrics.Functions.phi_pTX(100000,T,x);

  // Mass balance of liquid water
  der(mH2OLiq) = (1.0 - (-0.5 * Modelica.Math.tanh(100.0*(phi-1.0)) + 0.5)) * sum(moistureSourcesPorts.m_flow)
    - BuildingSystems.Utilities.SmoothFunctions.softcut(1.0-phi,0.0,1.0,0.001) * mH2OLiq;                      // water vapor surplus from moisture sources if relative moisture becomes close to 1
                                                                                          // evaporated water which leaves the liquid reservoir

  for i in 1:nAirpathes loop
    // Enthalpy flow through each air path
    airpathPorts[i].h_outflow = Medium.specificEnthalpy_pTX(p=100000, T=T, X={x,1-x});
    H_flow_airpath[i] = airpathPorts[i].m_flow * actualStream(airpathPorts[i].h_outflow);

    // Vertical pressure at each air path
    airpathPorts[i].p = pMean - Modelica.Constants.g_n * (heightAirpath[i] - 0.5 * height) * rho_nominal * T_nominal / T;

    // Mass flow rate of water vapour through each air path
    m_flow_H2O_airpath[i] = airpathPorts[i].m_flow * actualStream(airpathPorts[i].Xi_outflow[1]);
    airpathPorts[i].Xi_outflow[1] = x;
  end for;
  // Enthalpy flow by each moisture source
  for i in 1:nMoistureSources loop
    H_flow_moistureSource = rH2O * moistureSourcesPorts.m_flow;
  end for;

end AirvolumeCompressible0D;
 
partial model BuildingSystems.Buildings.BaseClasses.AirvolumeGeneral 
  "Generic air volume model"
  replaceable package Medium = Modelica.Media.Interfaces.PartialMedium 
    "Medium in the air volume";
  parameter Modelica.SIunits.Volume V = 1.0 "Air volume";
  parameter Integer nSurfaces(min=1) = 1 
    "Number of surfaces, which enclose the air volume";
  parameter Integer gridSurface[nSurfaces,2]=fill({1,1},nSurfaces) 
    "Grid in y and z dimension of each surface";
  parameter Modelica.SIunits.Temp_K T_start = 293.15 "Start air temperature";
  parameter Modelica.SIunits.MassFraction x_start = 0.005 "Start air moisture";
  parameter Modelica.SIunits.Mass mH2OLiq_start = 0.0 "Start liquid water mass";
  BuildingSystems.Buildings.Interfaces.SurfaceToAirPorts toSurfacePorts[nSurfaces](
    nY = gridSurface[:,1],
    nZ= gridSurface[:,2]);
  output BuildingSystems.Interfaces.Temp_KOutput T "Air temperature";
  output BuildingSystems.Interfaces.Moisture_absOutput x 
    "Absolute air moisture";

end AirvolumeGeneral;
 
connector BuildingSystems.Interfaces.Moisture_absOutput =
                               Modelica.Blocks.Interfaces.RealOutput(final quantity="Moisture_abs",final unit="kg/kg", displayUnit="kg/kg");
 
connector BuildingSystems.Interfaces.MoisturePorts 
  "Port for moisture transfer, large icon to be used for vectors of MoisturePorts (base connector type)"
  extends BuildingSystems.Interfaces.MoisturePortGeneral;
end MoisturePorts;
 
  constant Modelica.SIunits.SpecificHeatCapacity BuildingSystems.Utilities.Psychrometrics.Constants.cpAir=
                                                       1006 
  "Specific heat capacity of air";
 
  constant Modelica.SIunits.SpecificHeatCapacity BuildingSystems.Utilities.Psychrometrics.Constants.cpSte=
                                                       1860 
  "Specific heat capacity of water vapor";
 
  constant Modelica.SIunits.SpecificHeatCapacity BuildingSystems.Utilities.Psychrometrics.Constants.cpWatLiq=
                                                            4184 
  "Specific heat capacity of liquid water";
 
  final constant SI.Acceleration Modelica.Constants.g_n=
                                     9.80665 
  "Standard acceleration of gravity on earth";
 
package BuildingSystems.Media.Air 
  "Package with moist air model that decouples pressure and temperature"
  extends Modelica.Media.Interfaces.PartialCondensingGases(
     mediumName="Air",
     final substanceNames={"water", "air"},
     final reducedX=true,
     final singleState = false,
     reference_X={0.01,0.99},
     final fluidConstants = {Modelica.Media.IdealGases.Common.FluidData.H2O,
                             Modelica.Media.IdealGases.Common.FluidData.N2},
     reference_T=273.15,
     reference_p=101325,
     AbsolutePressure(start=p_default),
     Temperature(start=T_default));
  extends Modelica.Icons.Package;

  constant Integer Water=1 
    "Index of water (in substanceNames, massFractions X, etc.)";
  constant Integer Air=2 
    "Index of air (in substanceNames, massFractions X, etc.)";

  constant AbsolutePressure pStp = reference_p 
    "Pressure for which fluid density is defined";
  constant Density dStp = 1.2 "Fluid density at pressure pStp";

  // Redeclare ThermodynamicState to avoid the warning
  // "Base class ThermodynamicState is replaceable"
  // during model check
  redeclare record extends ThermodynamicState 
    "ThermodynamicState record for moist air"
  end ThermodynamicState;

  // There must not be any stateSelect=StateSelect.prefer for
  // the pressure.
  // Otherwise, translateModel("Buildings.Fluid.FMI.ExportContainers.Examples.FMUs.ResistanceVolume")
  // will fail as Dymola does an index reduction and outputs
  //   Differentiated the equation
  //   vol.dynBal.medium.p+res.dp-inlet.p = 0.0;
  //   giving
  //   der(vol.dynBal.medium.p)+der(res.dp) = der(inlet.p);
  //
  //   The model requires derivatives of some inputs as listed below:
  //   1 inlet.m_flow
  //   1 inlet.p
  // Therefore, the statement
  //   p(stateSelect=if preferredMediumStates then StateSelect.prefer else StateSelect.default)
  // has been removed.
  redeclare replaceable model extends BaseProperties(
    Xi(each stateSelect=if preferredMediumStates then StateSelect.prefer else StateSelect.default),
    T(stateSelect=if preferredMediumStates then StateSelect.prefer else StateSelect.default),
    final standardOrderComponents=true) "Base properties"

  protected 
    constant Modelica.SIunits.MolarMass[2] MMX = {steam.MM,dryair.MM} 
      "Molar masses of components";

    MassFraction X_steam "Mass fraction of steam water";
    MassFraction X_air "Mass fraction of air";
    Modelica.SIunits.TemperatureDifference dT 
      "Temperature difference used to compute enthalpy";
  equation 
    assert(T >= 200.0 and T <= 423.15, "
Temperature T is not in the allowed range
200.0 K <= (T ="
               + String(T) + " K) <= 423.15 K
required from medium model \""     + mediumName + "\".");

    MM = 1/(Xi[Water]/MMX[Water]+(1.0-Xi[Water])/MMX[Air]);

    X_steam  = Xi[Water]; // There is no liquid in this medium model
    X_air    = 1-Xi[Water];

    dT = T - reference_T;
    h = dT*dryair.cp * X_air +
       (dT * steam.cp + h_fg) * X_steam;
    R = dryair.R*X_air + steam.R*X_steam;

    // Equation for ideal gas, from h=u+p*v and R*T=p*v, from which follows that  u = h-R*T.
    // u = h-R*T;
    // However, in this medium, the gas law is d/dStp=p/pStp, from which follows using h=u+pv that
    // u= h-p*v = h-p/d = h-pStp/dStp
    u = h-pStp/dStp;

    // In this medium model, the density depends only
    // on temperature, but not on pressure.
    //  d = p/(R*T);
    d/dStp = p/pStp;

    state.p = p;
    state.T = T;
    state.X = X;
  end BaseProperties;

redeclare function density "Gas density"
  extends Modelica.Icons.Function;
  input ThermodynamicState state;
  output Density d "Density";
algorithm 
  d :=state.p*dStp/pStp;
end density;

redeclare function extends dynamicViscosity 
    "Return the dynamic viscosity of dry air"
algorithm 
  eta := 4.89493640395e-08 * state.T + 3.88335940547e-06;
end dynamicViscosity;

redeclare function enthalpyOfCondensingGas 
    "Enthalpy of steam per unit mass of steam"
  extends Modelica.Icons.Function;

  input Temperature T "temperature";
  output SpecificEnthalpy h "steam enthalpy";
algorithm 
  h := (T-reference_T) * steam.cp + h_fg;
end enthalpyOfCondensingGas;

redeclare replaceable function extends enthalpyOfGas 
    "Enthalpy of gas mixture per unit mass of gas mixture"
algorithm 
  h := enthalpyOfCondensingGas(T)*X[Water]
       + enthalpyOfDryAir(T)*(1.0-X[Water]);
end enthalpyOfGas;

redeclare replaceable function extends enthalpyOfLiquid 
    "Enthalpy of liquid (per unit mass of liquid) which is linear in the temperature"
algorithm 
  h := (T - reference_T)*cpWatLiq;
end enthalpyOfLiquid;

redeclare function enthalpyOfNonCondensingGas 
    "Enthalpy of non-condensing gas per unit mass of steam"
  extends Modelica.Icons.Function;

  input Temperature T "temperature";
  output SpecificEnthalpy h "enthalpy";
algorithm 
  h := enthalpyOfDryAir(T);
end enthalpyOfNonCondensingGas;

redeclare function extends enthalpyOfVaporization 
    "Enthalpy of vaporization of water"
algorithm 
  r0 := h_fg;
end enthalpyOfVaporization;

redeclare function extends gasConstant 
    "Return ideal gas constant as a function from thermodynamic state, only valid for phi<1"

algorithm 
    R := dryair.R*(1 - state.X[Water]) + steam.R*state.X[Water];
end gasConstant;

redeclare function extends pressure 
    "Returns pressure of ideal gas as a function of the thermodynamic state record"

algorithm 
  p := state.p;
end pressure;

redeclare function extends isobaricExpansionCoefficient 
    "Isobaric expansion coefficient beta"
algorithm 
  beta := 0;
end isobaricExpansionCoefficient;

redeclare function extends isothermalCompressibility 
    "Isothermal compressibility factor"
algorithm 
  kappa := -1/state.p;
end isothermalCompressibility;

redeclare function extends saturationPressure 
    "Saturation curve valid for 223.16 <= T <= 373.16 (and slightly outside with less accuracy)"

algorithm 
  psat := BuildingSystems.Utilities.Psychrometrics.Functions.saturationPressure(Tsat);
end saturationPressure;

redeclare function extends specificEntropy 
    "Return the specific entropy, only valid for phi<1"

  protected 
    Modelica.SIunits.MoleFraction[2] Y "Molar fraction";
algorithm 
    Y := massToMoleFractions(
         state.X, {steam.MM,dryair.MM});
    s := specificHeatCapacityCp(state) * Modelica.Math.log(state.T/reference_T)
         - Modelica.Constants.R *
         sum(state.X[i]/MMX[i]*
             Modelica.Math.log(max(Y[i], Modelica.Constants.eps)*state.p/reference_p) for i in 1:2);
end specificEntropy;

redeclare function extends density_derp_T 
    "Return the partial derivative of density with respect to pressure at constant temperature"
algorithm 
  ddpT := dStp/pStp;
end density_derp_T;

redeclare function extends density_derT_p 
    "Return the partial derivative of density with respect to temperature at constant pressure"
algorithm 
  ddTp := 0;

end density_derT_p;

redeclare function extends density_derX 
    "Return the partial derivative of density with respect to mass fractions at constant pressure and temperature"
algorithm 
  dddX := fill(0, nX);
end density_derX;

redeclare replaceable function extends specificHeatCapacityCp 
    "Specific heat capacity of gas mixture at constant pressure"
algorithm 
  cp := dryair.cp*(1-state.X[Water]) +steam.cp*state.X[Water];
end specificHeatCapacityCp;

redeclare replaceable function extends specificHeatCapacityCv 
    "Specific heat capacity of gas mixture at constant volume"
algorithm 
  cv:= dryair.cv*(1-state.X[Water]) +steam.cv*state.X[Water];
end specificHeatCapacityCv;

redeclare function setState_dTX 
    "Return thermodynamic state as function of density d, temperature T and composition X"
  extends Modelica.Icons.Function;
  input Density d "Density";
  input Temperature T "Temperature";
  input MassFraction X[:]=reference_X "Mass fractions";
  output ThermodynamicState state "Thermodynamic state";

algorithm 
    // Note that d/dStp = p/pStp, hence p = d*pStp/dStp
    state := if size(X, 1) == nX then 
               ThermodynamicState(p=d*pStp/dStp, T=T, X=X)
             else 
               ThermodynamicState(p=d*pStp/dStp,
                                  T=T,
                                  X=cat(1, X, {1 - sum(X)}));
end setState_dTX;

redeclare function extends setState_phX 
    "Return thermodynamic state as function of pressure p, specific enthalpy h and composition X"
algorithm 
  state := if size(X, 1) == nX then 
    ThermodynamicState(p=p, T=temperature_phX(p, h, X), X=X)
 else 
    ThermodynamicState(p=p, T=temperature_phX(p, h, X), X=cat(1, X, {1 - sum(X)}));
end setState_phX;

redeclare function extends setState_pTX 
    "Return thermodynamic state as function of p, T and composition X or Xi"
algorithm 
    state := if size(X, 1) == nX then 
                ThermodynamicState(p=p, T=T, X=X)
             else 
                ThermodynamicState(p=p, T=T, X=cat(1, X, {1 - sum(X)}));
end setState_pTX;

redeclare function extends setState_psX 
    "Return the thermodynamic state as function of p, s and composition X or Xi"
  protected 
    Modelica.SIunits.MassFraction[2] X_int=
      if size(X, 1) == nX then X else cat(1, X, {1 - sum(X)}) "Mass fraction";
    Modelica.SIunits.MoleFraction[2] Y "Molar fraction";
    Modelica.SIunits.Temperature T "Temperature";
algorithm 
   Y := massToMoleFractions(
         X_int, {steam.MM,dryair.MM});
    // The next line is obtained from symbolic solving the
    // specificEntropy function for T.
    // In this formulation, we can set T to any value when calling
    // specificHeatCapacityCp as cp does not depend on T.
    T := 273.15 * Modelica.Math.exp((s + Modelica.Constants.R *
           sum(X_int[i]/MMX[i]*
             Modelica.Math.log(max(Y[i], Modelica.Constants.eps)) for i in 1:2))
             / specificHeatCapacityCp(setState_pTX(p=p,
                                                   T=273.15,
                                                   X=X_int)));

    state := ThermodynamicState(p=p,
                                T=T,
                                X=X_int);

end setState_psX;

redeclare replaceable function extends specificEnthalpy 
    "Compute specific enthalpy from pressure, temperature and mass fraction"
algorithm 
  h := (state.T - reference_T)*dryair.cp * (1 - state.X[Water]) +
       ((state.T-reference_T) * steam.cp + h_fg) * state.X[Water];
end specificEnthalpy;

redeclare replaceable function specificEnthalpy_pTX 
    "Specific enthalpy"
  extends Modelica.Icons.Function;
  input Modelica.SIunits.Pressure p "Pressure";
  input Modelica.SIunits.Temperature T "Temperature";
  input Modelica.SIunits.MassFraction X[:] "Mass fractions of moist air";
  output Modelica.SIunits.SpecificEnthalpy h "Specific enthalpy at p, T, X";

algorithm 
  h := specificEnthalpy(setState_pTX(p, T, X));
end specificEnthalpy_pTX;

redeclare replaceable function extends specificGibbsEnergy 
    "Specific Gibbs energy"
algorithm 
  g := specificEnthalpy(state) - state.T*specificEntropy(state);
end specificGibbsEnergy;

redeclare replaceable function extends specificHelmholtzEnergy 
    "Specific Helmholtz energy"
algorithm 
  f := specificEnthalpy(state) - gasConstant(state)*state.T - state.T*specificEntropy(state);
end specificHelmholtzEnergy;

redeclare function extends isentropicEnthalpy 
    "Return the isentropic enthalpy"
algorithm 
  h_is := specificEnthalpy(setState_psX(
            p=p_downstream,
            s=specificEntropy(refState),
            X=refState.X));
end isentropicEnthalpy;

redeclare function extends specificInternalEnergy 
    "Specific internal energy"
  extends Modelica.Icons.Function;
algorithm 
  u := specificEnthalpy(state) - pStp/dStp;
end specificInternalEnergy;

redeclare function extends temperature 
    "Return temperature of ideal gas as a function of the thermodynamic state record"
algorithm 
  T := state.T;
end temperature;

redeclare function extends molarMass "Return the molar mass"
algorithm 
    MM := 1/(state.X[Water]/MMX[Water]+(1.0-state.X[Water])/MMX[Air]);
end molarMass;

redeclare replaceable function temperature_phX 
    "Compute temperature from specific enthalpy and mass fraction"
    extends Modelica.Icons.Function;
  input AbsolutePressure p "Pressure";
  input SpecificEnthalpy h "specific enthalpy";
  input MassFraction[:] X "mass fractions of composition";
  output Temperature T "temperature";
algorithm 
  T := reference_T + (h - h_fg * X[Water])
       /((1 - X[Water])*dryair.cp + X[Water] * steam.cp);
end temperature_phX;

redeclare function extends thermalConductivity 
    "Thermal conductivity of dry air as a polynomial in the temperature"
algorithm 
  lambda := Modelica.Media.Incompressible.TableBased.Polynomials_Temp.evaluate(
      {(-4.8737307422969E-008), 7.67803133753502E-005, 0.0241814385504202},
   Modelica.SIunits.Conversions.to_degC(state.T));
end thermalConductivity;

//////////////////////////////////////////////////////////////////////
// Protected classes.
// These classes are only of use within this medium model.
// Models generally have no need to access them.
// Therefore, they are made protected. This also allows to redeclare the
// medium model with another medium model that does not provide an
// implementation of these classes.
protected 
  record GasProperties 
    "Coefficient data record for properties of perfect gases"
    extends Modelica.Icons.Record;

    Modelica.SIunits.MolarMass MM "Molar mass";
    Modelica.SIunits.SpecificHeatCapacity R "Gas constant";
    Modelica.SIunits.SpecificHeatCapacity cp 
      "Specific heat capacity at constant pressure";
    Modelica.SIunits.SpecificHeatCapacity cv = cp-R 
      "Specific heat capacity at constant volume";
  end GasProperties;

  // In the assignments below, we compute cv as OpenModelica
  // cannot evaluate cv=cp-R as defined in GasProperties.
  constant GasProperties dryair(
    R =    Modelica.Media.IdealGases.Common.SingleGasesData.Air.R,
    cp =   BuildingSystems.Utilities.Psychrometrics.Constants.cpAir,
    cv =   BuildingSystems.Utilities.Psychrometrics.Constants.cpAir
             -Modelica.Media.IdealGases.Common.SingleGasesData.Air.R) 
    "Dry air properties";
  constant GasProperties steam(
    R =    Modelica.Media.IdealGases.Common.SingleGasesData.H2O.R,
    cp =   BuildingSystems.Utilities.Psychrometrics.Constants.cpSte,
    cv =   BuildingSystems.Utilities.Psychrometrics.Constants.cpSte
             -Modelica.Media.IdealGases.Common.SingleGasesData.H2O.R) 
    "Steam properties";

  constant Real k_mair =  steam.MM/dryair.MM "Ratio of molar weights";

  constant Modelica.SIunits.MolarMass[2] MMX={steam.MM,dryair.MM} 
    "Molar masses of components";

  constant Modelica.SIunits.SpecificEnergy h_fg=
    BuildingSystems.Utilities.Psychrometrics.Constants.h_fg 
    "Latent heat of evaporation of water";
  constant Modelica.SIunits.SpecificHeatCapacity cpWatLiq=
    BuildingSystems.Utilities.Psychrometrics.Constants.cpWatLiq 
    "Specific heat capacity of liquid water";

replaceable function der_enthalpyOfLiquid 
    "Temperature derivative of enthalpy of liquid per unit mass of liquid"
  extends Modelica.Icons.Function;
  input Temperature T "Temperature";
  input Real der_T "Temperature derivative";
  output Real der_h "Derivative of liquid enthalpy";
algorithm 
  der_h := cpWatLiq*der_T;
end der_enthalpyOfLiquid;

function der_enthalpyOfCondensingGas 
    "Derivative of enthalpy of steam per unit mass of steam"
  extends Modelica.Icons.Function;
  input Temperature T "Temperature";
  input Real der_T "Temperature derivative";
  output Real der_h "Derivative of steam enthalpy";
algorithm 
  der_h := steam.cp*der_T;
end der_enthalpyOfCondensingGas;

replaceable function enthalpyOfDryAir 
    "Enthalpy of dry air per unit mass of dry air"
  extends Modelica.Icons.Function;

  input Temperature T "Temperature";
  output SpecificEnthalpy h "Dry air enthalpy";
algorithm 
  h := (T - reference_T)*dryair.cp;
end enthalpyOfDryAir;

replaceable function der_enthalpyOfDryAir 
    "Derivative of enthalpy of dry air per unit mass of dry air"
  extends Modelica.Icons.Function;
  input Temperature T "Temperature";
  input Real der_T "Temperature derivative";
  output Real der_h "Derivative of dry air enthalpy";
algorithm 
  der_h := dryair.cp*der_T;
end der_enthalpyOfDryAir;

replaceable function der_enthalpyOfNonCondensingGas 
    "Derivative of enthalpy of non-condensing gas per unit mass of steam"
  extends Modelica.Icons.Function;
  input Temperature T "Temperature";
  input Real der_T "Temperature derivative";
  output Real der_h "Derivative of steam enthalpy";
algorithm 
  der_h := der_enthalpyOfDryAir(T, der_T);
end der_enthalpyOfNonCondensingGas;

replaceable function der_specificHeatCapacityCp 
    "Derivative of specific heat capacity of gas mixture at constant pressure"
  extends Modelica.Icons.Function;
    input ThermodynamicState state "Thermodynamic state";
    input ThermodynamicState der_state "Derivative of thermodynamic state";
    output Real der_cp(unit="J/(kg.K.s)") 
      "Derivative of specific heat capacity";
algorithm 
  der_cp := (steam.cp-dryair.cp)*der_state.X[Water];
end der_specificHeatCapacityCp;

replaceable function der_specificHeatCapacityCv 
    "Derivative of specific heat capacity of gas mixture at constant volume"
  extends Modelica.Icons.Function;
    input ThermodynamicState state "Thermodynamic state";
    input ThermodynamicState der_state "Derivative of thermodynamic state";
    output Real der_cv(unit="J/(kg.K.s)") 
      "Derivative of specific heat capacity";
algorithm 
  der_cv := (steam.cv-dryair.cv)*der_state.X[Water];
end der_specificHeatCapacityCv;

end Air;
 
partial package Modelica.Media.Interfaces.PartialMixtureMedium 
  "Base class for pure substances of several chemical substances"
  extends PartialMedium(redeclare replaceable record FluidConstants =
        Modelica.Media.Interfaces.Types.IdealGas.FluidConstants);

  redeclare replaceable record extends ThermodynamicState 
    "Thermodynamic state variables"
    AbsolutePressure p "Absolute pressure of medium";
    Temperature T "Temperature of medium";
    MassFraction X[nX] "Mass fractions (= (component mass)/total mass  m_i/m)";
  end ThermodynamicState;

  constant FluidConstants[nS] fluidConstants "Constant data for the fluid";

  replaceable function gasConstant 
    "Return the gas constant of the mixture (also for liquids)"
    extends Modelica.Icons.Function;
    input ThermodynamicState state "Thermodynamic state";
    output SI.SpecificHeatCapacity R "Mixture gas constant";
  end gasConstant;

  function moleToMassFractions 
    "Return mass fractions X from mole fractions"
    extends Modelica.Icons.Function;
    input SI.MoleFraction moleFractions[:] "Mole fractions of mixture";
    input MolarMass[:] MMX "Molar masses of components";
    output SI.MassFraction X[size(moleFractions, 1)] 
      "Mass fractions of gas mixture";
  protected 
    MolarMass Mmix=moleFractions*MMX "Molar mass of mixture";
  algorithm 
    for i in 1:size(moleFractions, 1) loop
      X[i] := moleFractions[i]*MMX[i]/Mmix;
    end for;
  end moleToMassFractions;

  function massToMoleFractions 
    "Return mole fractions from mass fractions X"
    extends Modelica.Icons.Function;
    input SI.MassFraction X[:] "Mass fractions of mixture";
    input SI.MolarMass[:] MMX "Molar masses of components";
    output SI.MoleFraction moleFractions[size(X, 1)] 
      "Mole fractions of gas mixture";
  protected 
    Real invMMX[size(X, 1)] "Inverses of molar weights";
    SI.MolarMass Mmix "Molar mass of mixture";
  algorithm 
    for i in 1:size(X, 1) loop
      invMMX[i] := 1/MMX[i];
    end for;
    Mmix := 1/(X*invMMX);
    for i in 1:size(X, 1) loop
      moleFractions[i] := Mmix*X[i]/MMX[i];
    end for;
  end massToMoleFractions;

end PartialMixtureMedium;
 
record Modelica.Media.Interfaces.Types.IdealGas.FluidConstants 
  "Extended fluid constants"
  extends Modelica.Media.Interfaces.Types.Basic.FluidConstants;
  Temperature criticalTemperature "Critical temperature";
  AbsolutePressure criticalPressure "Critical pressure";
  MolarVolume criticalMolarVolume "Critical molar Volume";
  Real acentricFactor "Pitzer acentric factor";
  //   Temperature triplePointTemperature "Triple point temperature";
  //   AbsolutePressure triplePointPressure "Triple point pressure";
  Temperature meltingPoint "Melting point at 101325 Pa";
  Temperature normalBoilingPoint "Normal boiling point (at 101325 Pa)";
  DipoleMoment dipoleMoment 
    "Dipole moment of molecule in Debye (1 debye = 3.33564e10-30 C.m)";
  Boolean hasIdealGasHeatCapacity=false 
    "True if ideal gas heat capacity is available";
  Boolean hasCriticalData=false "True if critical data are known";
  Boolean hasDipoleMoment=false "True if a dipole moment known";
  Boolean hasFundamentalEquation=false "True if a fundamental equation";
  Boolean hasLiquidHeatCapacity=false 
    "True if liquid heat capacity is available";
  Boolean hasSolidHeatCapacity=false "True if solid heat capacity is available";
  Boolean hasAccurateViscosityData=false 
    "True if accurate data for a viscosity function is available";
  Boolean hasAccurateConductivityData=false 
    "True if accurate data for thermal conductivity is available";
  Boolean hasVapourPressureCurve=false 
    "True if vapour pressure data, e.g., Antoine coefficents are known";
  Boolean hasAcentricFactor=false "True if Pitzer accentric factor is known";
  SpecificEnthalpy HCRIT0=0.0 
    "Critical specific enthalpy of the fundamental equation";
  SpecificEntropy SCRIT0=0.0 
    "Critical specific entropy of the fundamental equation";
  SpecificEnthalpy deltah=0.0 
    "Difference between specific enthalpy model (h_m) and f.eq. (h_f) (h_m - h_f)";
  SpecificEntropy deltas=0.0 
    "Difference between specific enthalpy model (s_m) and f.eq. (s_f) (s_m - s_f)";
end FluidConstants;
 
  constant IdealGases.Common.DataRecord Modelica.Media.IdealGases.Common.SingleGasesData.H2O(
    name="H2O",
    MM=0.01801528,
    Hf=-13423382.81725291,
    H0=549760.6476280135,
    Tlimit=1000,
    alow={-39479.6083,575.573102,0.931782653,0.00722271286,-7.34255737e-006,
        4.95504349e-009,-1.336933246e-012},
    blow={-33039.7431,17.24205775},
    ahigh={1034972.096,-2412.698562,4.64611078,0.002291998307,-6.836830479999999e-007,
        9.426468930000001e-011,-4.82238053e-015},
    bhigh={-13842.86509,-7.97814851},
    R=461.5233290850878);
 
record Modelica.Media.IdealGases.Common.DataRecord 
  "Coefficient data record for properties of ideal gases based on NASA source"
  extends Modelica.Icons.Record;
  String name "Name of ideal gas";
  SI.MolarMass MM "Molar mass";
  SI.SpecificEnthalpy Hf "Enthalpy of formation at 298.15K";
  SI.SpecificEnthalpy H0 "H0(298.15K) - H0(0K)";
  SI.Temperature Tlimit "Temperature limit between low and high data sets";
  Real alow[7] "Low temperature coefficients a";
  Real blow[2] "Low temperature constants b";
  Real ahigh[7] "High temperature coefficients a";
  Real bhigh[2] "High temperature constants b";
  SI.SpecificHeatCapacity R "Gas constant";
end DataRecord;
 
  constant IdealGases.Common.DataRecord Modelica.Media.IdealGases.Common.SingleGasesData.Air(
    name="Air",
    MM=0.0289651159,
    Hf=-4333.833858403446,
    H0=298609.6803431054,
    Tlimit=1000,
    alow={10099.5016,-196.827561,5.00915511,-0.00576101373,1.06685993e-005,-7.94029797e-009,
        2.18523191e-012},
    blow={-176.796731,-3.921504225},
    ahigh={241521.443,-1257.8746,5.14455867,-0.000213854179,7.06522784e-008,-1.07148349e-011,
        6.57780015e-016},
    bhigh={6462.26319,-8.147411905},
    R=287.0512249529787);
 
  constant Modelica.SIunits.SpecificEnthalpy BuildingSystems.Utilities.Psychrometrics.Constants.h_fg=
                                                    2501014.5 
  "Enthalpy of evaporation of water at the reference temperature";
 
partial package Modelica.Media.Interfaces.PartialCondensingGases 
  "Base class for mixtures of condensing and non-condensing gases"
  extends PartialMixtureMedium(ThermoStates=Modelica.Media.Interfaces.Choices.IndependentVariables.pTX);

  replaceable partial function saturationPressure 
    "Return saturation pressure of condensing fluid"
    extends Modelica.Icons.Function;
    input Temperature Tsat "Saturation temperature";
    output AbsolutePressure psat "Saturation pressure";
  end saturationPressure;

  replaceable partial function enthalpyOfVaporization 
    "Return vaporization enthalpy of condensing fluid"
    extends Modelica.Icons.Function;
    input Temperature T "Temperature";
    output SpecificEnthalpy r0 "Vaporization enthalpy";
  end enthalpyOfVaporization;

  replaceable partial function enthalpyOfLiquid 
    "Return liquid enthalpy of condensing fluid"
    extends Modelica.Icons.Function;
    input Temperature T "Temperature";
    output SpecificEnthalpy h "Liquid enthalpy";
  end enthalpyOfLiquid;

  replaceable partial function enthalpyOfGas 
    "Return enthalpy of non-condensing gas mixture"
    extends Modelica.Icons.Function;
    input Temperature T "Temperature";
    input MassFraction[:] X "Vector of mass fractions";
    output SpecificEnthalpy h "Specific enthalpy";
  end enthalpyOfGas;

  replaceable partial function enthalpyOfCondensingGas 
    "Return enthalpy of condensing gas (most often steam)"
    extends Modelica.Icons.Function;
    input Temperature T "Temperature";
    output SpecificEnthalpy h "Specific enthalpy";
  end enthalpyOfCondensingGas;

  replaceable partial function enthalpyOfNonCondensingGas 
    "Return enthalpy of the non-condensing species"
    extends Modelica.Icons.Function;
    input Temperature T "Temperature";
    output SpecificEnthalpy h "Specific enthalpy";
  end enthalpyOfNonCondensingGas;
end PartialCondensingGases;
 
type Modelica.Media.Interfaces.Choices.IndependentVariables = enumeration(
    T "Temperature",
    pT "Pressure, Temperature",
    ph "Pressure, Specific Enthalpy",
    phX "Pressure, Specific Enthalpy, Mass Fraction",
    pTX "Pressure, Temperature, Mass Fractions",
    dTX "Density, Temperature, Mass Fractions") 
  "Enumeration defining the independent variables of a medium";
 
  final constant Real Modelica.Constants.R(
                        final unit="J/(mol.K)") = 8.314472 "Molar gas constant";
 
  constant Modelica.Media.Interfaces.Types.IdealGas.FluidConstants Modelica.Media.IdealGases.Common.FluidData.H2O(
                       chemicalFormula =        "H2O",
                       iupacName =              "oxidane",
                       structureFormula =       "H2O",
                       casRegistryNumber =      "7732-18-5",
                       meltingPoint =           273.15,
                       normalBoilingPoint =     373.124,
                       criticalTemperature =    647.096,
                       criticalPressure =       220.64e5,
                       criticalMolarVolume =     55.95e-6,
                       acentricFactor =           0.344,
                       dipoleMoment =             1.8,
                       molarMass =              SingleGasesData.H2O.MM,
                       hasDipoleMoment =       true,
                       hasIdealGasHeatCapacity=true,
                       hasCriticalData =       true,
                       hasAcentricFactor =     true);
 
  constant Modelica.Media.Interfaces.Types.IdealGas.FluidConstants Modelica.Media.IdealGases.Common.FluidData.N2(
                       chemicalFormula =        "N2",
                       iupacName =              "unknown",
                       structureFormula =       "unknown",
                       casRegistryNumber =      "7727-37-9",
                       meltingPoint =            63.15,
                       normalBoilingPoint =      77.35,
                       criticalTemperature =    126.20,
                       criticalPressure =        33.98e5,
                       criticalMolarVolume =     90.10e-6,
                       acentricFactor =           0.037,
                       dipoleMoment =             0.0,
                       molarMass =              SingleGasesData.N2.MM,
                       hasDipoleMoment =       true,
                       hasIdealGasHeatCapacity=true,
                       hasCriticalData =       true,
                       hasAcentricFactor =     true);
 
  constant IdealGases.Common.DataRecord Modelica.Media.IdealGases.Common.SingleGasesData.N2(
    name="N2",
    MM=0.0280134,
    Hf=0,
    H0=309498.4543111511,
    Tlimit=1000,
    alow={22103.71497,-381.846182,6.08273836,-0.00853091441,1.384646189e-005,-9.62579362e-009,
        2.519705809e-012},
    blow={710.846086,-10.76003744},
    ahigh={587712.406,-2239.249073,6.06694922,-0.00061396855,1.491806679e-007,-1.923105485e-011,
        1.061954386e-015},
    bhigh={12832.10415,-15.86640027},
    R=296.8033869505308);
 
model BuildingSystems.Buildings.BaseClasses.RelationRadiationConvection 
  "Model for distribution to radiative and convective heat flows"

  BuildingSystems.Interfaces.HeatPort heatPort;
  BuildingSystems.Interfaces.HeatPort heatPortCv;
  BuildingSystems.Interfaces.HeatPort heatPortLw;
  parameter Real radiationportion;
equation 
  heatPortCv.Q_flow + (1.0 - radiationportion) * heatPort.Q_flow = 0.0;
  heatPortLw.Q_flow + radiationportion * heatPort.Q_flow = 0.0;
  heatPort.T = 293.15;

end RelationRadiationConvection;
 
block Modelica.Blocks.Continuous.LimPID 
  "P, PI, PD, and PID controller with limited output, anti-windup compensation and setpoint weighting"
  import Modelica.Blocks.Types.InitPID;
  import Modelica.Blocks.Types.Init;
  import Modelica.Blocks.Types.SimpleController;
  extends Interfaces.SVcontrol;
  output Real controlError = u_s - u_m 
    "Control error (set point - measurement)";

  parameter .Modelica.Blocks.Types.SimpleController controllerType=
         .Modelica.Blocks.Types.SimpleController.PID "Type of controller";
  parameter Real k(min=0, unit="1") = 1 "Gain of controller";
  parameter SIunits.Time Ti(min=Modelica.Constants.small)=0.5 
    "Time constant of Integrator block";
  parameter SIunits.Time Td(min=0)= 0.1 "Time constant of Derivative block";
  parameter Real yMax(start=1) "Upper limit of output";
  parameter Real yMin=-yMax "Lower limit of output";
  parameter Real wp(min=0) = 1 "Set-point weight for Proportional block (0..1)";
  parameter Real wd(min=0) = 0 "Set-point weight for Derivative block (0..1)";
  parameter Real Ni(min=100*Modelica.Constants.eps) = 0.9 
    "Ni*Ti is time constant of anti-windup compensation";
  parameter Real Nd(min=100*Modelica.Constants.eps) = 10 
    "The higher Nd, the more ideal the derivative block";
  parameter .Modelica.Blocks.Types.InitPID initType= .Modelica.Blocks.Types.InitPID.DoNotUse_InitialIntegratorState 
    "Type of initialization (1: no init, 2: steady state, 3: initial state, 4: initial output)";
  parameter Boolean limitsAtInit = true 
    "= false, if limits are ignored during initialization";
  parameter Real xi_start=0 
    "Initial or guess value value for integrator output (= integrator state)";
  parameter Real xd_start=0 
    "Initial or guess value for state of derivative block";
  parameter Real y_start=0 "Initial value of output";
  parameter Boolean strict=false "= true, if strict limits with noEvent(..)";
  constant SI.Time unitTime=1;
  Blocks.Math.Add addP(k1=wp, k2=-1);
  Blocks.Math.Add addD(k1=wd, k2=-1) if with_D;
  Blocks.Math.Gain P(k=1);
  Blocks.Continuous.Integrator I(k=unitTime/Ti, y_start=xi_start,
    initType=if initType==InitPID.SteadyState then 
                Init.SteadyState else 
             if initType==InitPID.InitialState or 
                initType==InitPID.DoNotUse_InitialIntegratorState then 
                Init.InitialState else Init.NoInit) if with_I;
  Blocks.Continuous.Derivative D(k=Td/unitTime, T=max([Td/Nd, 1.e-14]), x_start=xd_start,
    initType=if initType==InitPID.SteadyState or 
                initType==InitPID.InitialOutput then Init.SteadyState else 
             if initType==InitPID.InitialState then Init.InitialState else 
                Init.NoInit) if with_D;
  Blocks.Math.Gain gainPID(k=k);
  Blocks.Math.Add3 addPID;
  Blocks.Math.Add3 addI(k2=-1) if with_I;
  Blocks.Math.Add addSat(k1=+1, k2=-1) if 
                                   with_I;
  Blocks.Math.Gain gainTrack(k=1/(k*Ni)) if with_I;
  Blocks.Nonlinear.Limiter limiter(uMax=yMax, uMin=yMin, strict=strict, limitsAtInit=limitsAtInit);
protected 
  parameter Boolean with_I = controllerType==SimpleController.PI or 
                             controllerType==SimpleController.PID;
  parameter Boolean with_D = controllerType==SimpleController.PD or 
                             controllerType==SimpleController.PID;
public 
  Sources.Constant Dzero(k=0) if not with_D;
  Sources.Constant Izero(k=0) if not with_I;
initial equation 
  if initType==InitPID.InitialOutput then
     gainPID.y = y_start;
  end if;
equation 
  assert(yMax >= yMin, "LimPID: Limits must be consistent. However, yMax (=" + String(yMax) +
                       ") < yMin (=" + String(yMin) + ")");
  if initType == InitPID.InitialOutput and (y_start < yMin or y_start > yMax) then
      Modelica.Utilities.Streams.error("LimPID: Start value y_start (=" + String(y_start) +
         ") is outside of the limits of yMin (=" + String(yMin) +") and yMax (=" + String(yMax) + ")");
  end if;
  assert(limitsAtInit or not limitsAtInit and y >= yMin and y <= yMax,
         "LimPID: During initialization the limits have been switched off.\n" +
         "After initialization, the output y (=" + String(y) +
         ") is outside of the limits of yMin (=" + String(yMin) +") and yMax (=" + String(yMax) + ")");

  connect(u_s, addP.u1);
  connect(u_s, addD.u1);
  connect(u_s, addI.u1);
  connect(addP.y, P.u);
  connect(addD.y, D.u);
  connect(addI.y, I.u);
  connect(P.y, addPID.u1);
  connect(D.y, addPID.u2);
  connect(I.y, addPID.u3);
  connect(addPID.y, gainPID.u);
  connect(gainPID.y, addSat.u2);
  connect(gainPID.y, limiter.u);
  connect(limiter.y, addSat.u1);
  connect(limiter.y, y);
  connect(addSat.y, gainTrack.u);
  connect(gainTrack.y, addI.u3);
  connect(u_m, addP.u2);
  connect(u_m, addD.u2);
  connect(u_m, addI.u2);
  connect(Dzero.y, addPID.u2);
  connect(Izero.y, addPID.u3);
end LimPID;
 
type Modelica.Blocks.Types.InitPID = enumeration(
    NoInit 
      "No initialization (start values are used as guess values with fixed=false)",

    SteadyState "Steady state initialization (derivatives of states are zero)",

    InitialState "Initialization with initial states",
    InitialOutput 
      "Initialization with initial outputs (and steady state of the states if possible)",

    DoNotUse_InitialIntegratorState 
      "Don not use, only for backward compatibility (initialize only integrator state)")
  "Enumeration defining initialization of PID and LimPID blocks";
 
type Modelica.Blocks.Types.Init = enumeration(
    NoInit 
      "No initialization (start values are used as guess values with fixed=false)",

    SteadyState "Steady state initialization (derivatives of states are zero)",

    InitialState "Initialization with initial states",
    InitialOutput 
      "Initialization with initial outputs (and steady state of the states if possible)")
  "Enumeration defining initialization of a block";
 
type Modelica.Blocks.Types.SimpleController = enumeration(
    P "P controller",
    PI "PI controller",
    PD "PD controller",
    PID "PID controller") 
  "Enumeration defining P, PI, PD, or PID simple controller type";
 
partial block Modelica.Blocks.Interfaces.SVcontrol 
  "Single-Variable continuous controller"
  extends Modelica.Blocks.Icons.Block;

  RealInput u_s "Connector of setpoint input signal";
  RealInput u_m "Connector of measurement input signal";
  RealOutput y "Connector of actuator output signal";
end SVcontrol;
 
partial package Modelica.Icons.IconsPackage 
  "Icon for packages containing icons"
  extends Modelica.Icons.Package;
end IconsPackage;
 
partial block Modelica.Blocks.Icons.Block 
  "Basic graphical layout of input/output block"


end Block;
 
  final constant Real Modelica.Constants.small=
                            ModelicaServices.Machine.small 
  "Smallest number such that small and -small are representable on the machine";
 
  final constant Real ModelicaServices.Machine.small=
                            1.e-60 
  "Smallest number such that small and -small are representable on the machine";
 
block Modelica.Blocks.Math.Add "Output the sum of the two inputs"
  extends Interfaces.SI2SO;

  parameter Real k1=+1 "Gain of upper input";
  parameter Real k2=+1 "Gain of lower input";

equation 
  y = k1*u1 + k2*u2;
end Add;
 
partial block Modelica.Blocks.Interfaces.SI2SO 
  "2 Single Input / 1 Single Output continuous control block"
  extends Modelica.Blocks.Icons.Block;

  RealInput u1 "Connector of Real input signal 1";
  RealInput u2 "Connector of Real input signal 2";
  RealOutput y "Connector of Real output signal";


end SI2SO;
 
block Modelica.Blocks.Math.Gain 
  "Output the product of a gain value with the input signal"

  parameter Real k(start=1, unit="1") "Gain value multiplied with input signal";
public 
  Interfaces.RealInput u "Input signal connector";
  Interfaces.RealOutput y "Output signal connector";

equation 
  y = k*u;
end Gain;
 
block Modelica.Blocks.Continuous.Integrator 
  "Output the integral of the input signal"
  import Modelica.Blocks.Types.Init;
  parameter Real k(unit="1")=1 "Integrator gain";

  /* InitialState is the default, because it was the default in Modelica 2.2
     and therefore this setting is backward compatible
  */
  parameter Modelica.Blocks.Types.Init initType=Modelica.Blocks.Types.Init.InitialState 
    "Type of initialization (1: no init, 2: steady state, 3,4: initial output)";
  parameter Real y_start=0 "Initial or guess value of output (= state)";
  extends Interfaces.SISO(y(start=y_start));

initial equation 
  if initType == Init.SteadyState then
     der(y) = 0;
  elseif initType == Init.InitialState or 
         initType == Init.InitialOutput then
    y = y_start;
  end if;
equation 
  der(y) = k*u;
end Integrator;
 
partial block Modelica.Blocks.Interfaces.SISO 
  "Single Input Single Output continuous control block"
  extends Modelica.Blocks.Icons.Block;

  RealInput u "Connector of Real input signal";
  RealOutput y "Connector of Real output signal";
end SISO;
 
block Modelica.Blocks.Continuous.Derivative 
  "Approximated derivative block"
  import Modelica.Blocks.Types.Init;
  parameter Real k(unit="1")=1 "Gains";
  parameter SIunits.Time T(min=Modelica.Constants.small) = 0.01 
    "Time constants (T>0 required; T=0 is ideal derivative block)";
  parameter Modelica.Blocks.Types.Init initType=Modelica.Blocks.Types.Init.NoInit 
    "Type of initialization (1: no init, 2: steady state, 3: initial state, 4: initial output)";
  parameter Real x_start=0 "Initial or guess value of state";
  parameter Real y_start=0 "Initial value of output (= state)";
  extends Interfaces.SISO;

  output Real x(start=x_start) "State of block";

protected 
  parameter Boolean zeroGain = abs(k) < Modelica.Constants.eps;
initial equation 
  if initType == Init.SteadyState then
    der(x) = 0;
  elseif initType == Init.InitialState then
    x = x_start;
  elseif initType == Init.InitialOutput then
    if zeroGain then
       x = u;
    else
       y = y_start;
    end if;
  end if;
equation 
  der(x) = if zeroGain then 0 else (u - x)/T;
  y = if zeroGain then 0 else (k/T)*(u - x);
end Derivative;
 
block Modelica.Blocks.Math.Add3 "Output the sum of the three inputs"
  extends Modelica.Blocks.Icons.Block;

  parameter Real k1=+1 "Gain of upper input";
  parameter Real k2=+1 "Gain of middle input";
  parameter Real k3=+1 "Gain of lower input";
  Interfaces.RealInput u1 "Connector 1 of Real input signals";
  Interfaces.RealInput u2 "Connector 2 of Real input signals";
  Interfaces.RealInput u3 "Connector 3 of Real input signals";
  Interfaces.RealOutput y "Connector of Real output signals";

equation 
  y = k1*u1 + k2*u2 + k3*u3;
end Add3;
 
block Modelica.Blocks.Nonlinear.Limiter "Limit the range of a signal"
  parameter Real uMax(start=1) "Upper limits of input signals";
  parameter Real uMin= -uMax "Lower limits of input signals";
  parameter Boolean strict=false "= true, if strict limits with noEvent(..)";
  parameter Boolean limitsAtInit=true 
    "= false, if limits are ignored during initialization (i.e., y=u)";
  extends Interfaces.SISO;

equation 
  assert(uMax >= uMin, "Limiter: Limits must be consistent. However, uMax (=" + String(uMax) +
                       ") < uMin (=" + String(uMin) + ")");
  if initial() and not limitsAtInit then
     y = u;
     assert(u >= uMin - 0.01*abs(uMin) and 
            u <= uMax + 0.01*abs(uMax),
           "Limiter: During initialization the limits have been ignored.\n"+
           "However, the result is that the input u is not within the required limits:\n"+
           "  u = " + String(u) + ", uMin = " + String(uMin) + ", uMax = " + String(uMax));
  elseif strict then
     y = smooth(0, noEvent(if u > uMax then uMax else if u < uMin then uMin else u));
  else
     y = smooth(0,if u > uMax then uMax else if u < uMin then uMin else u);
  end if;
end Limiter;
 
partial package Modelica.Icons.SourcesPackage 
  "Icon for packages containing sources"
  extends Modelica.Icons.Package;
end SourcesPackage;
 
block Modelica.Blocks.Sources.Constant 
  "Generate constant signal of type Real"
  parameter Real k(start=1) "Constant output value";
  extends Interfaces.SO;

equation 
  y = k;
end Constant;
 
  "Single Output continuous control block"
  extends Modelica.Blocks.Icons.Block;

  RealOutput y "Connector of Real output signal";

end SO;
 
connector BuildingSystems.Interfaces.HeatFlowRateOutput =
                               Modelica.Blocks.Interfaces.RealOutput(final quantity="HeatFlowRate",final unit="W",displayUnit="W");
 
model Modelica.Thermal.HeatTransfer.Sources.PrescribedHeatFlow 
  "Prescribed heat flow boundary condition"
  parameter Modelica.SIunits.Temperature T_ref=293.15 "Reference temperature";
  parameter Modelica.SIunits.LinearTemperatureCoefficient alpha=0 
    "Temperature coefficient of heat flow rate";
  Modelica.Blocks.Interfaces.RealInput Q_flow(unit="W");
  Interfaces.HeatPort_b port;
equation 
  port.Q_flow = -Q_flow*(1 + alpha*(port.T - T_ref));
end PrescribedHeatFlow;
 
connector Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b 
  "Thermal port for 1-dim. heat transfer (unfilled rectangular icon)"

  extends HeatPort;

end HeatPort_b;
 
connector BuildingSystems.Interfaces.Moisture_absInput =
                              Modelica.Blocks.Interfaces.RealInput(final quantity="Moisture_abs",final unit="kg/kg",displayUnit="kg/kg");
 
connector BuildingSystems.Interfaces.AirchangeRateInput =
                               Modelica.Blocks.Interfaces.RealInput(final quantity="AirchangeRate",final unit="1/h",displayUnit="1/h");
 
model BuildingSystems.Buildings.Airpathes.AirpathPrescribedMassFlowRate 
  "Air path model for a given mass flow rate"

  Modelica.Fluid.Interfaces.FluidPort_a airpathPort_1(
    redeclare final package Medium=BuildingSystems.Media.Air);
  Modelica.Blocks.Interfaces.RealInput m_flow_in if use_m_flow_in;
  BuildingSystems.Interfaces.Temp_KInput T_in if use_T_in;
  BuildingSystems.Interfaces.Moisture_absInput x_in if use_x_in;
  parameter Boolean use_m_flow_in = false 
    "Get the mas flow from the input connector";
  parameter Boolean use_T_in= false 
    "Get the temperature from the input connector";
  parameter Boolean use_x_in = false 
    "Get the composition from the input connector";
  parameter Modelica.SIunits.MassFlowRate m_flow = 0.0 
    "Fixed value of mass flow rate";
  parameter Modelica.SIunits.Temp_K T = airpathPort_1.Medium.T_default 
    "Fixed value of temperature";
  parameter Modelica.SIunits.MassFraction x = 0.005 
    "Fixed value of absolute moisture";
protected 
  Modelica.Blocks.Interfaces.RealInput m_flow_internal 
    "Needed to connect to conditional connector";
  Modelica.Blocks.Interfaces.RealInput T_internal 
    "Needed to connect to conditional connector";
  Modelica.Blocks.Interfaces.RealInput x_internal 
    "Needed to connect to conditional connector";
equation 
  connect(m_flow_in, m_flow_internal);
  connect(T_in, T_internal);
  connect(x_in, x_internal);
  if not use_m_flow_in then
    m_flow_internal = m_flow;
  end if;
  if not use_T_in then
    T_internal = T;
  end if;
  if not use_x_in then
    x_internal = x;
  end if;

  airpathPort_1.m_flow = m_flow_internal;
  airpathPort_1.h_outflow = BuildingSystems.Media.Air.specificEnthalpy_pTX(p=100000, T=T_internal, X={x_internal,1-x_internal});
  airpathPort_1.Xi_outflow[1] = x_internal;

end AirpathPrescribedMassFlowRate;
 
connector Modelica.Fluid.Interfaces.FluidPort_a 
  "Generic fluid connector at design inlet"
  extends FluidPort;
end FluidPort_a;
 
partial model BuildingSystems.Buildings.BaseClasses.BuildingTemplate 
  "General template for building models"
  final package Medium = BuildingSystems.Media.Air;

  parameter Integer nZones = 0 "Number of thermal zones of the building";
  parameter Integer nHeatSources = 0 "Number of heat sources of the building";
  parameter Integer nMoistureSources = 0 
    "Number of moisture sources of the building";
  final parameter Integer nSurfacesAmbient = surfacesToAmbient.nSurfaces 
    "Number of surfaces (with air contact) to the building ambient";
  parameter BuildingSystems.HAM.ConvectiveHeatTransfer.Types.Convection convectionOnSurfaces = BuildingSystems.HAM.ConvectiveHeatTransfer.Types.Convection.const 
    "Type of convection calculation for outside building surfaces";
  parameter Modelica.SIunits.SurfaceCoefficientOfHeatTransfer alphaConstant= 10.0 
    "Convective heat transfer coefficient for simplified calculations";
  parameter Integer gridSurface[surfacesToAmbient.nSurfaces,2]=fill({1,1},surfacesToAmbient.nSurfaces) 
    "Grid in y and z dimension of each surface";
  parameter Integer nSurfacesSolid = 0 
    "Number of surfaces (with contact to solids) to the building ambient";
  parameter Modelica.SIunits.Conversions.NonSIunits.Angle_deg angleDegAziBuilding = 0.0 
    "Azimuth angle of the building: south: 0 deg, east: -90 deg, west +90 deg, north: 180 deg";
  parameter Boolean prescribedAirchange = true 
    "Switch for air change calculation";
  parameter Boolean useAirPathes = true 
    "True: airpath calculation is possible; false: no airpath calculation";
  parameter Integer nAirpathes = 0 
    "Number of air pathes to the building ambient";
  parameter Boolean calcHygroThermal = false 
    "Switch for hygro-thermal calculation";
  parameter Boolean calcIdealLoads = true 
    "True: calculation of the ideal heating and cooling load; false: no calculation";
  parameter Boolean heatSources = false 
    "True: heat source present; false: no heat source present";
  parameter Boolean moistureSources = false 
    "True: moisture source present; false: no moisture source present";
  parameter Boolean show_TAir = false 
    "Show air temperatures of each building zone as an output (vector)";
  parameter Boolean show_xAir = false 
    "Show air humidity of each building zone as an output (vector)";
  parameter Boolean show_TSur = false 
    "Show suface temperatures of each building element as an output (vector)";
  parameter Integer nSurfaces = 0 
    "if show_TSur = true: Overall number of building surfaces";
  input BuildingSystems.Interfaces.Temp_KInput T_setHeating[nZones] if calcIdealLoads 
    "Set air temperature for heating of each thermal zone";
  input BuildingSystems.Interfaces.Temp_KInput T_setCooling[nZones] if calcIdealLoads 
    "Set air temperature for cooling of each thermal zone";
  input BuildingSystems.Interfaces.AirchangeRateInput airchange[nZones] if prescribedAirchange 
    "Air change rate of each thermal zone";
  input BuildingSystems.Interfaces.Temp_KInput TAirAmb if prescribedAirchange 
    "Air temperature of the building ambient";
  input BuildingSystems.Interfaces.Moisture_absInput xAirAmb if prescribedAirchange 
    "Absolute moisture of the building ambient";
  output BuildingSystems.Interfaces.Temp_KOutput TAir[nZones] if show_TAir 
    "Air temperature of each thermal zone";
  output BuildingSystems.Interfaces.Moisture_absOutput xAir[nZones] if show_xAir 
    "Air humidity  of each thermal zone";
  output BuildingSystems.Interfaces.Temp_KOutput TSur[nSurfaces] if show_TSur 
    "Surface temperatures of the individual building elements";
  output BuildingSystems.Interfaces.HeatFlowRateOutput Q_flow_cooling[nZones] if calcIdealLoads 
    "Cooling power of each thermal zone";
  output BuildingSystems.Interfaces.HeatFlowRateOutput Q_flow_heating[nZones] if calcIdealLoads 
    "Heating power of each thermal zone";
  Modelica.Fluid.Vessels.BaseClasses.VesselFluidPorts_b toAmbientAirpathPorts[nAirpathes](
    redeclare each final package Medium = Medium) if useAirPathes;
  BuildingSystems.Buildings.Interfaces.SurfaceToSurfacesPorts toAmbientSurfacesPorts[nSurfacesAmbient](
    nY=gridSurface[:,1],
    nZ=gridSurface[:,2]) 
    "Interfaces between outside building surfaces to surfaces of the building ambient";
  BuildingSystems.Buildings.Interfaces.SurfaceToAirPorts toAmbientAirPorts[nSurfacesAmbient](
    nY=gridSurface[:,1],
    nZ=gridSurface[:,2]) 
    "Interfaces between outside building surfaces to the air of the building ambient";
  BuildingSystems.Buildings.Surfaces.SurfacesToAir surfacesToAmbient(
    gridSurface=gridSurface,
    surface(each convectionOnSurface = convectionOnSurfaces,
    each alphaConstant = alphaConstant)) 
    "Model for all building surfaces to the building ambient";
  BuildingSystems.Interfaces.HeatPort2D toSolidHeatPorts[nSurfacesSolid] 
    "Heat port to the ground under the building";
  BuildingSystems.Interfaces.HeatPorts conHeatSourcesPorts[nHeatSources] if heatSources 
    "Heat port to internal convective heat sources of the building";
  BuildingSystems.Interfaces.HeatPorts radHeatSourcesPorts[nHeatSources] if heatSources 
    "Heat port to internal long-wave radiation heat sources of the building";
  BuildingSystems.Interfaces.MoisturePorts moisturePorts[nMoistureSources] if moistureSources 
    "Moisture port to internal moisture sources";
  BuildingSystems.Interfaces.MoisturePort2D toSolidMoisturePorts[nSurfacesSolid] if calcHygroThermal 
    "Mosture port to the ground under the building";
  BuildingSystems.Buildings.Surfaces.SurfacesToSolids surfacesToSolids(calcHygroThermal=calcHygroThermal,nSurfaces=nSurfacesSolid) 
    "Model for all building surfaces to the ground under the building";
equation 
  for i in 1:nSurfacesAmbient loop
    connect(surfacesToAmbient.toAirPorts[i],toAmbientAirPorts[i]);
    connect(surfacesToAmbient.toSurfacesPorts[i],toAmbientSurfacesPorts[i]);
  end for;
  for i in 1:nSurfacesSolid loop
    connect(surfacesToSolids.heatPorts[i],toSolidHeatPorts[i]);
    if calcHygroThermal then
      connect(surfacesToSolids.moisturePorts[i],toSolidMoisturePorts[i]);
    end if;
  end for;

end BuildingTemplate;
 
connector BuildingSystems.Interfaces.HeatPort2D 
  "Port for heat transfer in 2 dimensions (base connector type)"
  parameter Integer nY = 1 "Number of surface elements in the y dimension";
  parameter Integer nZ = 1 "Number of surface elements in the z dimension";
  BuildingSystems.Interfaces.HeatPort heatPort[nY,nZ];
end HeatPort2D;
 
connector BuildingSystems.Interfaces.MoisturePort2D 
  "Port for moisture transfer in 2 dimensions (base connector type)"
  parameter Integer nY = 1 "Number of surface elements in the y dimension";
  parameter Integer nZ = 1 "Number of surface elements in the z dimension";
  BuildingSystems.Interfaces.MoisturePort moisturePort[nY,nZ];
end MoisturePort2D;
 
model BuildingSystems.Buildings.Surfaces.SurfacesToSolids 
  "Set of surface models between a set of constructions and solid materials"
  parameter Integer nSurfaces=1;
  parameter Integer gridSurface[nSurfaces,2]=fill({1,1},nSurfaces) 
    "Grid in y and z dimension of each surface";
  parameter Boolean calcHygroThermal = false 
    "Switch for hygro-thermal calculation";
  BuildingSystems.Buildings.Surfaces.SurfaceToSolid surface[nSurfaces](
    each calcHygroThermal=calcHygroThermal,
    nY = gridSurface[:, 1],
    nZ = gridSurface[:, 2]);
  BuildingSystems.Buildings.Interfaces.SurfaceToConstructionPorts toConstructionPorts[nSurfaces](
    nY = gridSurface[:,1],
    nZ = gridSurface[:,2]);
  BuildingSystems.Interfaces.HeatPort2D heatPorts[nSurfaces](
    nY = gridSurface[:,1],
    nZ = gridSurface[:,2]);
  BuildingSystems.Interfaces.MoisturePort2D moisturePorts[nSurfaces](
    nY = gridSurface[:,1],
    nZ = gridSurface[:,2]) if calcHygroThermal;
equation 
  for i in 1:nSurfaces loop
    connect(surface[i].toConstructionPort,toConstructionPorts[i]);
    connect(surface[i].heatPort,heatPorts[i].heatPort);
    if calcHygroThermal then
      connect(surface[i].moisturePort,moisturePorts[i].moisturePort);
    end if;
  end for;
end SurfacesToSolids;
 
model BuildingSystems.Buildings.Surfaces.SurfaceToSolid 
  "Surface model between a constructions and a solid material"
  extends Buildings.BaseClasses.SurfaceGeneral;
  BuildingSystems.Interfaces.HeatPort heatPort[nY,nZ];
  BuildingSystems.Interfaces.MoisturePort moisturePort[nY,nZ] if calcHygroThermal;
  BuildingSystems.Climate.Sources.RadiationFixed radBc(
    IrrDir_constant=0.0,
    IrrDif_constant=0.0,
    angleDegInc_constant=0.0);
  parameter Boolean calcHygroThermal = false 
    "Switch for hygro-thermal calculation";
  BuildingSystems.HAM.HeatAndMoistureTransport.Sources.AbsoluteMoistureFixed moistBc(x_constant=0.0) if not calcHygroThermal 
    "Dummy boundary condition for absolute moisture";
equation 
  for j in 1:nY loop
    for k in 1:nZ loop
      connect(toConstructionPort.moisturePort[j,k],moistBc.moisturePort);
      connect(toConstructionPort.radiationPort_in[j,k],radBc.radiationPort);
    end for;
  end for;
  connect(toConstructionPort.moisturePort,moisturePort);
  connect(toConstructionPort.heatPort,heatPort);
end SurfaceToSolid;
 
model BuildingSystems.Climate.Sources.RadiationFixed 
  "Boundary condition of a constant direct and diffuse solar irradiation"

  BuildingSystems.Interfaces.RadiationPort radiationPort(
    IrrDir = IrrDir_constant,
    IrrDif = IrrDif_constant,
    angleDegInc = angleDegInc_constant);
  parameter Modelica.SIunits.RadiantEnergyFluenceRate IrrDir_constant = 0.0 
    "Constant area specific direct solar radiation";
  parameter Modelica.SIunits.RadiantEnergyFluenceRate IrrDif_constant = 0.0 
    "Conatant area specific diffuse solar radiation";
  parameter Modelica.SIunits.Conversions.NonSIunits.Angle_deg angleDegInc_constant = 0.0 
    "Constant incident angle of the direct solar radiation";
end RadiationFixed;
 
model
  BuildingSystems.HAM.HeatAndMoistureTransport.Sources.AbsoluteMoistureFixed 
  "Boundary condition of a constant absolute moisture"
  extends MoistureSourceGeneral(moisturePort(x = x_constant));
  parameter Modelica.SIunits.MassFraction x_constant = 0.05 
    "Constant absolute moisture";

end AbsoluteMoistureFixed;
 
partial model
  BuildingSystems.HAM.HeatAndMoistureTransport.Sources.MoistureSourceGeneral 
  "Partial moisture boundary condition model"

    BuildingSystems.Interfaces.MoisturePort moisturePort "Moisture port";
end MoistureSourceGeneral;
 
model BuildingSystems.Buildings.Constructions.Walls.WallThermal1DNodes 
  "Thermal wall model with 1D discritisation of the single layers"
  extends BuildingSystems.Buildings.BaseClasses.WallThermalGeneral(
  final equidistantGrid = true,
  final nY=1,
  final nZ=1,
  final pointsSegY = {0.0,0.0},
  final pointsSegZ = {0.0,0.0});
  BuildingSystems.Interfaces.HeatPort heatSourcePort = construction.layer[layerWithHeatSource].heatPort_source[nodeWithHeatSource] if heatSource;
  BuildingSystems.HAM.HeatConduction.MultiLayerHeatConduction1DNodes construction(
    lengthY=width,
    lengthZ=height,
    nLayers=constructionData.nLayers,
    nNodes=nNodes,
    thickness=constructionData.thickness,
    material=constructionData.material,
    T_start=T_start);
  parameter Integer nNodes[constructionData.nLayers] = fill(1,constructionData.nLayers) 
    "Number of numerical nodes of each layer";
  parameter Integer nodeWithHeatSource = 1 
    "Numerical node of the specified layer with internal heat source";
  parameter Boolean show_TSur = false "Show surface temperatures on both sides";
  BuildingSystems.Interfaces.Temp_KOutput TSur_1 = toSurfacePort_1.heatPort[1,1].T if show_TSur 
    "Temperature on surface side 1";
  BuildingSystems.Interfaces.Temp_KOutput TSur_2 = toSurfacePort_2.heatPort[1,1].T if show_TSur 
    "Temperature on surface side 2";
equation 
  connect(toSurfacePort_1.moisturePort[1,1], moistBcPort1.moisturePort);
  connect(toSurfacePort_2.moisturePort[1,1], moistBcPort2.moisturePort);
  connect(construction.heatPort_x2, toSurfacePort_2.heatPort[1,1]);
  connect(toSurfacePort_1.heatPort[1,1], construction.heatPort_x1);

end WallThermal1DNodes;
 
partial model BuildingSystems.Buildings.BaseClasses.WallGeneral 
  "General wall model"
  extends BuildingSystems.Buildings.BaseClasses.ConstructionGeneral(
  width = if not equidistantGrid then pointsSegY[nY+1] - pointsSegY[1] else 1.0,
  height = if not equidistantGrid then pointsSegZ[nZ+1] - pointsSegZ[1] else 1.0,
  A = height * width - sum(AInnSur),
  nY = 1,
  nZ = 1);
  BuildingSystems.Buildings.Interfaces.SurfaceToConstructionPort toSurfacePort_2(
    A=if equidistantGrid then fill(A/(nY*nZ),nY,nZ) else {{lengthSegY[j] * lengthSegZ[k] for k in 1:nZ} for j in 1:nY},
    nY=nY,
    nZ=nZ,
    abs = fill(abs_2,nY,nZ),
    geo(
    angleDegAzi =   angleDegAzi,
    angleDegTil =   angleDegTil,
    width =   width,
    height =   height,
    zMean =     zLevel + Modelica.Math.sin(Modelica.Constants.pi/180.0*angleDegTil) * height,
      point(
    x =         {0.0,width,width,0.0},
    y =         {0.0,0.0,height,height},
    z =         {0.0,0.0,0.0,0.0})),
    epsilon = fill(epsilon_2,nY,nZ));
  BuildingSystems.Buildings.Interfaces.SurfaceToConstructionPort toSurfacePort_1(
    A=if equidistantGrid then fill(A/(nY*nZ),nY,nZ) else {{lengthSegY[j] * lengthSegZ[k] for k in 1:nZ} for j in 1:nY},
    nY=nY,
    nZ=nZ,
    abs = fill(abs_1,nY,nZ),
    geo(
    angleDegAzi =   angleDegAzi,
    angleDegTil =   angleDegTil,
    width =   width,
    height =   height,
    zMean =     zLevel + Modelica.Math.sin(Modelica.Constants.pi/180.0*angleDegTil) * height,
      point(
    x =         {0.0,width,width,0.0},
    y =         {0.0,0.0,height,height},
    z =         {0.0,0.0,0.0,0.0})),
    epsilon = fill(epsilon_1,nY,nZ));
  BuildingSystems.Climate.Sources.RadiationFixed radBcPort1(
    IrrDir_constant = 0.0,
    IrrDif_constant = 0.0,
    angleDegInc_constant = 0.0);
  BuildingSystems.Climate.Sources.RadiationFixed radBcPort2(
    IrrDir_constant = 0.0,
    IrrDif_constant = 0.0,
    angleDegInc_constant = 0.0);
  parameter Integer nInnSur = 0 "Number of enclosed surfaces";
  parameter Modelica.SIunits.Area AInnSur[nInnSur] = fill(0.0,nInnSur) 
    "Area of each enclosed surface";
  parameter Boolean equidistantGrid = true 
    "True: division in equidistant partions; false: division in non-equidistant partions";
  parameter Modelica.SIunits.Length pointsSegY[nY+1] = fill(0.0,nY+1) 
    "Grid points of the partitions in y direction";
  parameter Modelica.SIunits.Length pointsSegZ[nZ+1] = fill(0.0,nZ+1) 
    "Grid points of the partitions in z direction";
  parameter Boolean heatSource = false 
    "True: heat source present in specified layer; false: no heat source present in specified layer";
  parameter Integer layerWithHeatSource = 1 
    "Wall layer with internal heat source (used if heatSource = true)";
protected 
  parameter Modelica.SIunits.Length lengthSegY[nY] = if equidistantGrid then fill(width/nY,nY) else {pointsSegY[j+1]-pointsSegY[j] for j in 1:nY} 
    "Length of the partitions in y direction";
  parameter Modelica.SIunits.Length lengthSegZ[nZ] = if equidistantGrid then fill(height/nZ,nZ) else {pointsSegZ[k+1]-pointsSegZ[k] for k in 1:nZ} 
    "Length of the partitions in z direction";
equation 
  connect(radBcPort1.radiationPort, toSurfacePort_1.radiationPort_out[1,1]);
  connect(radBcPort2.radiationPort, toSurfacePort_2.radiationPort_out[1,1]);

end WallGeneral;
 
partial model BuildingSystems.Buildings.BaseClasses.ConstructionGeneral 
  "General model of building constructions (walls, windows, roofs etc.)"
  parameter Modelica.SIunits.Length width "Width";
  parameter Modelica.SIunits.Length height "Height";
  parameter Modelica.SIunits.Area A 
    "Net area (gross area minus enclosed surfaces)";
  parameter Modelica.SIunits.Conversions.NonSIunits.Angle_deg angleDegAzi = 0.0 
    "Azimuth angle";
  parameter Modelica.SIunits.Conversions.NonSIunits.Angle_deg angleDegTil = 90.0 
    "Tilt angle";
  parameter Modelica.SIunits.Length zLevel = 0.0 "Vertical position";
  parameter Integer nY = 1 "Number of cells in the y dimension";
  parameter Integer nZ = 1 "Number of cells in the z dimension";
  parameter BuildingSystems.Types.Absorptance abs_1 = 0.5 
    "Short-wave absorptance side 1";
  parameter BuildingSystems.Types.Absorptance abs_2 = 0.5 
    "Short-wave absorptance side 2";
  parameter Modelica.SIunits.Emissivity epsilon_1 = 0.9 
    "Long-wave emittance side 1";
  parameter Modelica.SIunits.Emissivity epsilon_2 = 0.9 
    "Long-wave emittance side 2";
end ConstructionGeneral;
 
  final constant Real Modelica.Constants.pi=
                         2*Modelica.Math.asin(1.0);
 
model BuildingSystems.HAM.HeatConduction.MultiLayerHeatConduction1DNodes 
  "Multi layered-body with 1D heat conduction and a potential inner discretization of each layer"
  BuildingSystems.HAM.HeatConduction.HeatConduction1DNodes layer[nLayers](material=material,
    each lengthY=lengthY,each lengthZ=lengthZ,lengthX=thickness,nNodesX=nNodes,T_start=T_start);
  BuildingSystems.Interfaces.HeatPort heatPort_x1 "Heat port in direction x1";
  BuildingSystems.Interfaces.HeatPort heatPort_x2 "Heat port in direction x2";
  parameter 
    BuildingSystems.HAM.Data.MaterialProperties.BaseClasses.MaterialThermalGeneral
                                                                                   material[nLayers];
  parameter Modelica.SIunits.Length lengthY = 1.0 "Length in y dimension";
  parameter Modelica.SIunits.Length lengthZ = 1.0 "Length in z dimension";
  parameter Integer nLayers = 1 "Number of material layers in the x dimension";
  parameter Integer nNodes[nLayers] = {1} 
    "Number of numerical nodes of layer i";
  parameter Modelica.SIunits.Length thickness[nLayers] = {1.0} 
    "Thickness of layer i";
  parameter Modelica.SIunits.Temp_K T_start[nLayers]={293.15 for i in 1:nLayers} 
    "Start temperature of the layer i";

equation 
  connect(heatPort_x1,layer[1].heatPort_x1);
  for i in 1:nLayers-1 loop
    connect(layer[i].heatPort_x2,layer[i+1].heatPort_x1);
  end for;
  connect(heatPort_x2,layer[nLayers].heatPort_x2);

end MultiLayerHeatConduction1DNodes;
 
model BuildingSystems.HAM.HeatConduction.HeatConduction1DNodes 
  "Model for 1D heat conduction and an optional additional discretisation"
  extends BuildingSystems.HAM.HeatConduction.BaseClasses.HeatConductionGeneral;
  BuildingSystems.Interfaces.HeatPort heatPort_x1 "Heat port in direction x1";
  BuildingSystems.Interfaces.HeatPort heatPort_x2 "Heat port in direction x2";
  BuildingSystems.Interfaces.HeatPort heatPort_source[nNodesX] 
    "Optional heat source at the numerical node";
  parameter Integer nNodesX = 1 "Number of numerical nodes in the x dimension";
  parameter Modelica.SIunits.Temp_K T_start = 293.15 
    "Start temperature of the thermal nodes";
  Modelica.SIunits.Temp_K T[nNodesX](each start = T_start) 
    "Temperature of the numerical node";
protected 
  parameter Modelica.SIunits.Length dx[nNodesX](each fixed = false);
  parameter Modelica.SIunits.ThermalConductance CTh[nNodesX+1](each fixed=false) 
    "Thermal conductance of the numerical node";
  parameter Modelica.SIunits.HeatCapacity C[nNodesX](each fixed = false) 
    "Heat capacity of the numerical node";

initial algorithm 
  for i in 1:nNodesX loop
    dx[i]:= lengthX / nNodesX;
    C[i]:= material.c * material.rho * dx[i] * lengthY * lengthZ;
  end for;
  for i in 1:nNodesX+1 loop
    if i == 1 then
      CTh[1] := 2.0 * material.lambda / dx[1] * lengthY * lengthZ;
    elseif i > 1 and i < nNodesX+1 then
      CTh[i] := material.lambda / dx[i]  * lengthY * lengthZ;
    else
      CTh[i] := 2.0 * material.lambda / dx[i-1]  * lengthY * lengthZ;
    end if;
  end for;

equation 
  heatPort_source[1].T = T[1];
  // Heat flux side 1
  heatPort_x1.Q_flow = CTh[1] * (heatPort_x1.T - T[1]);
  // Heat flux side 2
  heatPort_x2.Q_flow = CTh[nNodesX+1] * (heatPort_x2.T - T[nNodesX]);
  if nNodesX > 1 then
    // First node side 1
    C[1] * der(T[1]) = heatPort_x1.Q_flow + CTh[2] * (T[2] - T[1]) + heatPort_source[1].Q_flow;
    // Mean nodes
    for i in 2:nNodesX-1 loop
      heatPort_source[i].T = T[i];
      C[i] * der(T[i]) = CTh[i] * T[i-1] - (CTh[i] + CTh[i+1]) * T[i] + CTh[i+1] * T[i+1] + heatPort_source[i].Q_flow;
    end for;
    // last node side 2
    heatPort_source[nNodesX].T = T[nNodesX];
    C[nNodesX] * der(T[nNodesX]) = CTh[nNodesX] * (T[nNodesX-1] - T[nNodesX]) + heatPort_x2.Q_flow + heatPort_source[nNodesX].Q_flow;
  else
    // body with only one node
    C[1] * der(T[1]) = heatPort_x1.Q_flow + heatPort_x2.Q_flow + heatPort_source[1].Q_flow;
  end if;

end HeatConduction1DNodes;
 
partial model
  BuildingSystems.HAM.HeatConduction.BaseClasses.HeatConductionGeneral 
  "General model for heat conduction of a body"
  replaceable parameter 
    BuildingSystems.HAM.Data.MaterialProperties.BaseClasses.MaterialThermalGeneral
                                                                                                       material 
    "Material of the body";
  parameter Modelica.SIunits.Length lengthX = 1.0 "Length in x dimension";
  parameter Modelica.SIunits.Length lengthY = 1.0 "Length in y dimension";
  parameter Modelica.SIunits.Length lengthZ = 1.0 "Length in z dimension";

end HeatConductionGeneral;
 
record
  BuildingSystems.HAM.Data.MaterialProperties.BaseClasses.MaterialThermalGeneral

  extends MaterialGeneral;
  parameter Modelica.SIunits.ThermalConductivity lambda = 1.0 
    "Heat conductivity";
  parameter Modelica.SIunits.SpecificHeatCapacity c = 1000.0 
    "Specific heat capacity";
  parameter Modelica.SIunits.Density rho = 1000.0 "Density";
end MaterialThermalGeneral;
 
record BuildingSystems.HAM.Data.MaterialProperties.BaseClasses.MaterialGeneral
  extends Modelica.Icons.Record;
  parameter Integer id=0;
  parameter String name="";
end MaterialGeneral;
 
partial model BuildingSystems.Buildings.BaseClasses.WallThermalGeneral 
  "General thermal wall model"
  extends BuildingSystems.Buildings.BaseClasses.WallGeneral;
  BuildingSystems.HAM.HeatAndMoistureTransport.Sources.MoistureFlowFixed moistBcPort1(
    m_flow_constant = 0.0);
  BuildingSystems.HAM.HeatAndMoistureTransport.Sources.MoistureFlowFixed moistBcPort2(
    m_flow_constant = 0.0);
  parameter Modelica.SIunits.Temp_K T_start[constructionData.nLayers]={293.15 for i in 1:constructionData.nLayers} 
    "Start temperature of each layer";
  replaceable parameter 
    BuildingSystems.Buildings.Data.Constructions.OpaqueThermalConstruction                     constructionData 
    "Data of the thermal construction";
  final parameter Modelica.SIunits.SurfaceCoefficientOfHeatTransfer alphaIns = 7.692 
    "Heat transfer coefficient (convection + radiation) inside of the wall"; // after German DIN 4701 Teil2 tabular 16"
  final parameter Modelica.SIunits.SurfaceCoefficientOfHeatTransfer alphaAmb = 25.0 
    "Heat transfer coefficient (convection + radiation) outside of the wall"; // after german DIN 4701 Teil2 tabular 16"
  final parameter Modelica.SIunits.CoefficientOfHeatTransfer UVal=
    1.0/(1.0/alphaIns+sum(constructionData.thickness[i]/constructionData.material[i].lambda for i in 1:constructionData.nLayers)+1.0/alphaAmb) 
    "U-value of the wall construction under standard conditions";
end WallThermalGeneral;
 
model BuildingSystems.HAM.HeatAndMoistureTransport.Sources.MoistureFlowFixed 
  "Boundary condition of a constant moisture flow"
  extends MoistureSourceGeneral(moisturePort(m_flow = - m_flow_constant));
  parameter Modelica.SIunits.MassFlowRate m_flow_constant = 0.0 
    "Constant moisture flow rate of water vapour";

end MoistureFlowFixed;
 
record BuildingSystems.Buildings.Data.Constructions.OpaqueThermalConstruction 
  "Template for opaque thermal layered constructions"
  extends BuildingSystems.Buildings.BaseClasses.OpaqueConstruction;
  parameter 
    BuildingSystems.HAM.Data.MaterialProperties.BaseClasses.MaterialThermalGeneral
                                                                                           material[nLayers];
end OpaqueThermalConstruction;
 
record BuildingSystems.Buildings.BaseClasses.OpaqueConstruction 
  "Template for layered constructions"
  extends Modelica.Icons.Record;
  parameter Integer nLayers(min=1)=1 "Number of layers of the construction";
  parameter Modelica.SIunits.Length thickness[nLayers]={0.1} 
    "Thickness of each construction layer";
  final parameter Modelica.SIunits.Length thicknessTotal=sum(thickness) 
    "Total thickness of the construction";
end OpaqueConstruction;
 
model BuildingSystems.Buildings.Constructions.Windows.Window 
  "Simplified model of a window"
  extends BuildingSystems.Buildings.BaseClasses.ConstructionGeneral(
    A = height * width,
    final nY = 1,
    final nZ = 1,
    final abs_1 = 0.0,
    final abs_2 = 0.0);
  final package Medium = BuildingSystems.Media.Air;
  BuildingSystems.Buildings.Interfaces.SurfaceToConstructionPort toSurfacePort_2(
    A=fill(A,1,1),
    nY=nY,
    nZ=nZ,
    abs = fill(abs_2,1,1),
    geo(
    angleDegAzi =   angleDegAzi,
    angleDegTil =   angleDegTil,
    width =   width,
    height =   height,
    zMean =     zLevel + Modelica.Math.sin(Modelica.Constants.pi/180.0*angleDegTil) * height,
      point(
    x =         {0.0,width,width,0.0},
    y =         {0.0,0.0,height,height},
    z =         {0.0,0.0,0.0,0.0})),
    epsilon = fill(epsilon_2,nY,nZ));
  BuildingSystems.Buildings.Interfaces.SurfaceToConstructionPort toSurfacePort_1(
    A=fill(A,1,1),
    nY=nY,
    nZ=nZ,
    abs = fill(abs_1,1,1),
    geo(
    angleDegAzi =   angleDegAzi,
    angleDegTil =   angleDegTil,
    width =   width,
    height =   height,
    zMean =     zLevel + Modelica.Math.sin(Modelica.Constants.pi/180.0*angleDegTil) * height,
      point(
    x =         {0.0,width,width,0.0},
    y =         {0.0,0.0,height,height},
    z =         {0.0,0.0,0.0,0.0})),
    epsilon = fill(epsilon_1,nY,nZ));
  parameter Real framePortion = 0.2 "Frame portion of the window";
  parameter Modelica.SIunits.Length thicknessPane = 0.006 
    "Thickness of all panes";
  parameter Modelica.SIunits.Density rhoPane = 2000.0 "Density of the panes";
  parameter Modelica.SIunits.SpecificHeatCapacity cPane = 1000.0 
    "Specific heat capacity of the panes";
  parameter Modelica.SIunits.CoefficientOfHeatTransfer UVal = 3.0 
    "Mean U-value of the window";
  parameter Real tauDir0 = 0.7 
    "Transmittance of direct radiation for perpendicular irradiation";
  parameter Real tauDif = 0.7 "Transmittance of diffuse radiation";
  parameter Real b0 = 0.7;
  parameter Real fShadow = 0.0 "Shadowing coefficient";
  parameter Boolean calcAirchange = false 
    "True: calculation of air exchange through the window, false: no air exchange";
  parameter BuildingSystems.Types.CoefficientOfAirChange aF = 1.0 
    "Joint coefficient";
  parameter Boolean show_TSur = false "Show surface temperatures on both sides";
  BuildingSystems.Interfaces.Temp_KOutput TSur_1 = toSurfacePort_1.heatPort[1,1].T if show_TSur 
    "Temperature on surface side 1";
  BuildingSystems.Interfaces.Temp_KOutput TSur_2 = toSurfacePort_2.heatPort[1,1].T if show_TSur 
    "Temperature on surface side 2";
  parameter Modelica.SIunits.Temp_K T_start=293.15 
    "Start temperature of the window";
  BuildingSystems.Buildings.Constructions.Windows.RadiationTransmission.RadiationTransmissionSimple
                                                                                                    radTra1to2(
    tauDir0=tauDir0,
    b0=b0,
    tauDif=tauDif,
    fShadow=fShadow,
    framePortion=framePortion);
  BuildingSystems.Buildings.Constructions.Windows.RadiationTransmission.RadiationTransmissionSimple
                                                                                                    radTra2to1(
    tauDir0=tauDir0,
    b0=b0,
    tauDif=tauDif,
    fShadow=fShadow,
    framePortion=framePortion);
  BuildingSystems.HAM.HeatConduction.HeatConduction1D heatTransfer(
    material(
      lambda = UVal*thicknessPane,
      rho = rhoPane,
      c = cPane),
    lengthX=thicknessPane,
    lengthY=width,
    lengthZ=height,
    T_start=T_start);
  BuildingSystems.HAM.HeatAndMoistureTransport.Sources.MoistureFlowFixed moistBcPort1(
    m_flow_constant=0.0);
  BuildingSystems.HAM.HeatAndMoistureTransport.Sources.MoistureFlowFixed moistBcPort2(
    m_flow_constant=0.0);
  BuildingSystems.Buildings.Airpathes.AirpathVariable airpathDown if calcAirchange;
  BuildingSystems.Buildings.Airpathes.AirpathVariable airpathUp if calcAirchange;
  Modelica.Fluid.Interfaces.FluidPort_a airpathPortUp_1(redeclare final package
      Medium =                                                                         Medium) 
    if                                                                                            calcAirchange;
  Modelica.Fluid.Interfaces.FluidPort_b airpathPortUp_2(redeclare final package
      Medium =                                                                         Medium) 
    if                                                                                            calcAirchange;
  Modelica.Fluid.Interfaces.FluidPort_a airpathPortDown_1(redeclare final 
      package Medium =                                                                   Medium) 
    if                                                                                              calcAirchange;
  Modelica.Fluid.Interfaces.FluidPort_b airpathPortDown_2(redeclare final 
      package Medium =                                                                   Medium) 
    if                                                                                              calcAirchange;
  BuildingSystems.Interfaces.Angle_degInput angleDegPanes if calcAirchange;
  BuildingSystems.Buildings.Data.AirpathCharacteristics.AirpathCharacteristicWindow
                                                                                    airpathChar(
    width = width,
    height = 0.5 * height,
    aF = aF/3600.0) if calcAirchange "Characteristic of the window airpathes";
equation 
  // Solar Transmittance
  connect(radTra1to2.radiationPort_in, toSurfacePort_1.radiationPort_in[1,1]);
  connect(radTra1to2.radiationPort_out, toSurfacePort_2.radiationPort_out[1,1]);
  connect(radTra2to1.radiationPort_in, toSurfacePort_2.radiationPort_in[1,1]);
  connect(radTra2to1.radiationPort_out, toSurfacePort_1.radiationPort_out[1,1]);
  // Heat transfer
  connect(heatTransfer.heatPort_x2, toSurfacePort_2.heatPort[1,1]);
  connect(heatTransfer.heatPort_x1, toSurfacePort_1.heatPort[1,1]);
  // Moisture transport
  connect(moistBcPort1.moisturePort, toSurfacePort_1.moisturePort[1,1]);
  connect(moistBcPort2.moisturePort, toSurfacePort_2.moisturePort[1,1]);
  // Airpath calculation
  connect(airpathChar.angleDegPanes,angleDegPanes);
  connect(airpathUp.kVar,airpathChar.k);
  connect(airpathUp.mVar,airpathChar.m);
  connect(airpathDown.kVar,airpathChar.k);
  connect(airpathDown.mVar,airpathChar.m);
  connect(airpathUp.airpathPort_1, airpathPortUp_1);
  connect(airpathUp.airpathPort_2, airpathPortUp_2);
  connect(airpathDown.airpathPort_1, airpathPortDown_1);
  connect(airpathDown.airpathPort_2, airpathPortDown_2);

end Window;
 
model
  BuildingSystems.Buildings.Constructions.Windows.RadiationTransmission.RadiationTransmissionSimple


  BuildingSystems.Interfaces.RadiationPort radiationPort_in;
  BuildingSystems.Interfaces.RadiationPort radiationPort_out;
  parameter Real tauDir0 = 0.7 
    "Transmittance of direct radiation for perpendicular irradiation";
  parameter Real b0 = 0.7;
  parameter Real tauDif = 0.7 "Transmittance of diffuse radiation";
  parameter Real fShadow = 0.0 "Shadowing coefficient";
  parameter Real framePortion "Frame portion of the window";
  Real tauBeam "Transmittance of direct radiation";
equation 
  tauBeam = tauDir0 * BuildingSystems.Utilities.SmoothFunctions.softcut_lower((1.0 - b0 * (1.0 / BuildingSystems.Utilities.SmoothFunctions.softcut_lower(Modelica.Math.cos(Modelica.Constants.pi / 180.0 * radiationPort_in.angleDegInc),0.0,0.001) - 1.0)),0.0,0.001);
  radiationPort_out.IrrDir = radiationPort_in.IrrDir * tauBeam * (1.0 - fShadow) * (1.0-framePortion);
  radiationPort_out.IrrDif = radiationPort_in.IrrDif * tauDif * (1.0-framePortion);
  radiationPort_out.angleDegInc = radiationPort_in.angleDegInc;

end RadiationTransmissionSimple;
 
model BuildingSystems.HAM.HeatConduction.HeatConduction1D 
  "Model for 1D heat conduction"
  extends BuildingSystems.HAM.HeatConduction.BaseClasses.HeatConductionGeneral;

  BuildingSystems.Interfaces.HeatPort heatPort_x1 "Heat port in direction x1";
  BuildingSystems.Interfaces.HeatPort heatPort_x2 "Heat port in direction x2";
  BuildingSystems.Interfaces.HeatPort heatPort_source 
    "Optional heat source at the thermal node";
  parameter Modelica.SIunits.Temp_K T_start = 293.15 
    "Start temperature of the thermal node";
  Modelica.SIunits.Temp_K T(start = T_start) "Temperature of the thermal node";
protected 
  parameter Modelica.SIunits.HeatCapacity C = material.c * material.rho * lengthX * lengthY * lengthZ 
    "Heat capacity of the thermal node";
  parameter Modelica.SIunits.ThermalConductance kX = 2.0 * material.lambda / lengthX * lengthY * lengthZ 
    "Thermal conductance in the x dimension";
equation 
  heatPort_x1.Q_flow = kX * (heatPort_x1.T - T);
  heatPort_x2.Q_flow = kX * (heatPort_x2.T - T);
  heatPort_source.T = T;
  C * der(T) = heatPort_x1.Q_flow + heatPort_x2.Q_flow + heatPort_source.Q_flow;

end HeatConduction1D;
 
model BuildingSystems.Buildings.Airpathes.AirpathVariable 
  "Model of an air path with an variable opening"
  extends BuildingSystems.Buildings.BaseClasses.AirpathGeneral(k=kVar, m=mVar);
  Modelica.Blocks.Interfaces.RealInput kVar "Flow coefficient";
  Modelica.Blocks.Interfaces.RealInput mVar "Flow exponent";
end AirpathVariable;
 
partial model BuildingSystems.Buildings.BaseClasses.AirpathGeneral 
  "Abstract model of an air path"
  final package Medium = BuildingSystems.Media.Air;
  Modelica.Fluid.Interfaces.FluidPort_a airpathPort_1(
    redeclare final package Medium=Medium);
  Modelica.Fluid.Interfaces.FluidPort_b airpathPort_2(
    redeclare final package Medium=Medium);
  BuildingSystems.Types.FlowCoefficient k = 0.5 "Flow coefficient";
  Real m(unit = "1") = 0.5 "Flow exponent";
  constant Real factor = 20.0 "Numerical factor for air exchange calculation";
  constant Modelica.SIunits.Density rho_nominal = 1.2 
    "Air density under nominal conditions";
equation 
  // Isenthalpic state transformation (no heat production by friction)
  airpathPort_1.h_outflow = inStream(airpathPort_2.h_outflow);
  airpathPort_2.h_outflow = inStream(airpathPort_1.h_outflow);

  // Mass balance (no storage)
  airpathPort_1.m_flow + airpathPort_2.m_flow = 0;

   // Transport of substances
  airpathPort_1.Xi_outflow = inStream(airpathPort_2.Xi_outflow);
  airpathPort_2.Xi_outflow = inStream(airpathPort_1.Xi_outflow);

  airpathPort_1.C_outflow = inStream(airpathPort_2.C_outflow);
  airpathPort_2.C_outflow = inStream(airpathPort_1.C_outflow);

  // Mass flow trough air path
  airpathPort_1.m_flow = Modelica.Math.tanh(factor * (airpathPort_1.p - airpathPort_2.p)) * rho_nominal * k
    * BuildingSystems.Utilities.SmoothFunctions.safepow(BuildingSystems.Utilities.SmoothFunctions.softfabs(airpathPort_1.p - airpathPort_2.p,0.05),m);

end AirpathGeneral;
 
connector Modelica.Fluid.Interfaces.FluidPort_b 
  "Generic fluid connector at design outlet"
  extends FluidPort;
end FluidPort_b;
 
connector BuildingSystems.Interfaces.Angle_degInput =
                           Modelica.Blocks.Interfaces.RealInput(final quantity="Angle_deg",final unit="deg",displayUnit="deg");
 
block
  BuildingSystems.Buildings.Data.AirpathCharacteristics.AirpathCharacteristicWindow

  input BuildingSystems.Interfaces.Angle_degInput angleDegPanes 
    "Tilt angle of the panes";
  parameter Modelica.SIunits.Length height "Height of the opening";
  parameter Modelica.SIunits.Length width "Width of the opening";
  parameter BuildingSystems.Types.CoefficientOfAirChange aF "Joint coefficient";
  output Modelica.Blocks.Interfaces.RealOutput k "Flow coefficient";
  output Modelica.Blocks.Interfaces.RealOutput m;
  constant Modelica.SIunits.Density rhoAir = 1.2 "Mean air density";
protected 
            Real kClosed, kOpen;
algorithm 
  kClosed := aF * (2 * height+width);
  kOpen := CdTiltedPane(height,width,angleDegPanes) * width * height * (2.0/rhoAir)^0.5;
  k := BuildingSystems.Utilities.SmoothFunctions.softswitch(angleDegPanes, 0.1,kClosed,kOpen,0.01);
  m := BuildingSystems.Utilities.SmoothFunctions.softswitch(angleDegPanes, 0.1,0.5,0.666,0.01);
end AirpathCharacteristicWindow;
 
model BuildingSystems.Buildings.Ambient 
  "Model which calculates the outside climate boundary conditions of one ore more buildings"
  final package Medium = BuildingSystems.Media.Air;
  function x 
    "Absolute humidity dependent on air pressure, saturation pressure and relative humidity"
    input Modelica.SIunits.Pressure p;
    input Modelica.SIunits.Pressure pSat;
    input BuildingSystems.Types.RelativeHumidity phi;
    output Modelica.SIunits.MassFraction  value;
  algorithm 
    value := 0.622 * phi * pSat / (p - phi * pSat);
  end x;

  parameter Integer nSurfaces(min=1) "Number of building surfaces";
  parameter Integer gridSurface[nSurfaces,2]=fill({1,1},nSurfaces) 
    "Grid in y and z dimension of each surface";
  parameter Boolean calcLwRad = true 
    "True: long-wave radiation exchange on building surfaces is considered; false: no long-wave radiation exchange";
  parameter Integer nAirpathes = 0 "Number of airpathes to the building";
  parameter Modelica.SIunits.Length heightAirpath[nAirpathes] = fill(0.0,nAirpathes) 
    "Height of the airpathes to the building facades";
  replaceable parameter BuildingSystems.Climate.WeatherData.WeatherDataFile weatherDataFile
    constrainedby BuildingSystems.Climate.WeatherData.WeatherDataFile 
    "Weather data file for the location";
  parameter Real rhoAmb(unit = "1") = 0.2 
    "Reflection factor for short-wave radiation of the ground";
  parameter Modelica.SIunits.Length zRefvWind = 10.0 
    "Reference height for wind measurement";
                                                     // Standard value of TRY
  parameter Real P(unit = "1") = 0.4 
    "Roughness exponent for wind profil calculation";
                                     // Typical roughness for city districts
  parameter Modelica.SIunits.Length zRefTAir = 2.0 
    "Reference height air temperature measurement";
                                                   // Standard value of TRY
  parameter Real gamma(unit = "K/m") = 0.01 
    "Temperature gradient of the planetary boundary layer";
  parameter Modelica.SIunits.Pressure pAirRef = 100000.0 
    "Static air pressure on reference height";
  constant Real RAir(unit="J/(kg.K)") = 288.0 "Gas constant dry air";
  BuildingSystems.Climate.WeatherData.WeatherDataNetcdf weatherData(weatherDataFile=weatherDataFile) 
    "Weather data from file";
  Modelica.Blocks.Math.UnitConversions.From_degC from_degC;
  BuildingSystems.Buildings.Interfaces.SurfaceToAirPorts toAirPorts[nSurfaces](
    nY = gridSurface[:,1],
    nZ= gridSurface[:,2]) 
    "Climate boundary conditions for the building surfaces dependent on the ambient air";
  BuildingSystems.Buildings.Interfaces.SurfaceToSurfacesPorts toSurfacePorts[nSurfaces](
    nY = gridSurface[:,1],
    nZ= gridSurface[:,2]) 
    "Climate boundary conditions for the building surfaces dependent on ambient surfaces";
  Modelica.Fluid.Vessels.BaseClasses.VesselFluidPorts_b toAirpathPorts[nAirpathes](
    redeclare each final package Medium = Medium) 
    "Climate boundary conditions for the building airpathes";
  Modelica.SIunits.Pressure pGround=
    pAirRef * ((TAirRef - gamma * (0.0 - zRefTAir)) / TAirRef)^(Modelica.Constants.g_n / (gamma * RAir)) 
    "Air pressure on ground level";
  output BuildingSystems.Interfaces.Moisture_absOutput xAir=
    BuildingSystems.Utilities.Psychrometrics.Functions.X_pSatpphi(BuildingSystems.Utilities.Psychrometrics.Functions.saturationPressure(from_degC.y),100000.0,phi) 
    "Absolute moisture of ambient air";

  // Air temperature on reference height
  parameter BuildingSystems.Buildings.Types.DataSource TAirRefSou = BuildingSystems.Buildings.Types.DataSource.File 
    "Data source for air temperature on reference height";
  parameter Modelica.SIunits.Temp_K TAirRef_constant = 293.15 
    "Air temperature on reference height (used if TAirRefSou=Parameter)";
  output BuildingSystems.Interfaces.Temp_KOutput TAirRef 
    "Air temperature on reference height";
  input BuildingSystems.Interfaces.Temp_KInput TAirRef_in if TAirRefSou == BuildingSystems.Buildings.Types.DataSource.Input 
    "Air temperature on reference height from input";

  // Relative humidity of the ambient air
  parameter BuildingSystems.Buildings.Types.DataSource phiSou = BuildingSystems.Buildings.Types.DataSource.File 
    "Data source for relative humidity of the ambient air";
  parameter BuildingSystems.Types.RelativeHumidity phi_constant = 0.5 
    "Relative humidity of the ambient air (used if phiSou=Parameter)";
  BuildingSystems.Types.RelativeHumidity phi 
    "Relative humidity of the ambient air";
  input Modelica.Blocks.Interfaces.RealInput phi_in(
      min=0,
      max=1.01,
      unit="1") if phiSou == BuildingSystems.Buildings.Types.DataSource.Input 
    "Relative humidity of the ambient air from input";

  // Solar beam radiation of horizontal surface
  parameter BuildingSystems.Buildings.Types.DataSource IrrDirHorSou = BuildingSystems.Buildings.Types.DataSource.File 
    "Data source for solar beam radiation of horizontal surface";
  parameter Modelica.SIunits.RadiantEnergyFluenceRate IrrDirHor_constant = 0.0 
    "Solar beam radiation of horizontal surface (used if IrrDirHorSou=Parameter)";
  output BuildingSystems.Interfaces.RadiantEnergyFluenceRateOutput IrrDirHor 
    "Solar beam radiation of horizontal surface";
  input BuildingSystems.Interfaces.RadiantEnergyFluenceRateInput IrrDirHor_in if IrrDirHorSou == BuildingSystems.Buildings.Types.DataSource.Input 
    "Solar beam radiation of horizontal surface from input";

  // Solar diffuse radiation of horizontal surface
  parameter BuildingSystems.Buildings.Types.DataSource IrrDifHorSou = BuildingSystems.Buildings.Types.DataSource.File 
    "Data source for solar diffuse radiation of horizontal surface";
  parameter Modelica.SIunits.RadiantEnergyFluenceRate IrrDifHor_constant = 0.0 
    "Solar diffuse radiation of horizontal surface (used if IrrDifHorSou=Parameter)";
  output BuildingSystems.Interfaces.RadiantEnergyFluenceRateOutput IrrDifHor 
    "Solar diffuse radiation of horizontal surface";
  input BuildingSystems.Interfaces.RadiantEnergyFluenceRateInput IrrDifHor_in if IrrDifHorSou == BuildingSystems.Buildings.Types.DataSource.Input 
    "Solar diffuse radiation of horizontal surface from input";

  // Wind speed on reference height
  parameter BuildingSystems.Buildings.Types.DataSource vWindRefSou = BuildingSystems.Buildings.Types.DataSource.File 
    "Data source for solar wind speed on reference height";
  parameter Modelica.SIunits.Velocity vWindRef_constant = 0.0 
    "Wind speed on reference height (used if vWindRefSou=Parameter)";
  output BuildingSystems.Interfaces.VelocityOutput vWindRef 
    "Wind speed on reference height";
  input BuildingSystems.Interfaces.VelocityInput vWindRef_in if vWindRefSou == BuildingSystems.Buildings.Types.DataSource.Input 
    "Wind speed on reference height from input";

  // Wind direction on reference height
  parameter BuildingSystems.Buildings.Types.DataSource angleDegWindRefSou = BuildingSystems.Buildings.Types.DataSource.File 
    "Data source for Angle of wind direction on reference height";
  parameter Modelica.SIunits.Conversions.NonSIunits.Angle_deg angleDegWindRef_constant = 0.0 
    "Angle of wind direction on reference height (used if angleDegWindRefSou=Parameter)";
  output BuildingSystems.Interfaces.Angle_degOutput angleDegWindRef 
    "Angle of wind direction on reference height";
  input BuildingSystems.Interfaces.Angle_degInput angleDegWindRef_in if angleDegWindRefSou == BuildingSystems.Buildings.Types.DataSource.Input 
    "Angle of wind direction on reference height from input";

  // Cloud cover of the sky
  parameter BuildingSystems.Buildings.Types.DataSource cloudCoverSou = BuildingSystems.Buildings.Types.DataSource.File 
    "Data source for cloud cover of the sky";
  parameter Real cloudCover_constant(min = 0.0,max = 8.0, unit = "1") = 0.0 
    "Cloud cover of the sky (used if cloudCoverSou=Parameter)";
  Real cloudCover(min = 0.0,max = 8.0, unit = "1") "Cloud cover of the sky";
  input Modelica.Blocks.Interfaces.RealInput cloudCover_in(min = 0.0,max = 8.0, unit = "1") if cloudCoverSou == BuildingSystems.Buildings.Types.DataSource.Input 
    "Cloud cover of the sky from input";

  output BuildingSystems.Interfaces.Temp_KOutput TSky=
    BuildingSystems.Buildings.Functions.TSky(TAirRef,time,cloudCover/8.0,xAir,pAirRef,pGround) 
    "Sky temperature";
  BuildingSystems.Climate.SolarRadiationTransformers.SolarRadiationTransformerIsotropicSky
                                                                                           radiation[nSurfaces](
    each rhoAmb=rhoAmb,
    angleDegAzi= toSurfacePorts.angleDegAzi,
    angleDegTil= toSurfacePorts.angleDegTil) "Radiation on tilted surfaces";
equation 
  for i in 1:nSurfaces loop
    // position of the location
    connect(weatherData.longitudeDeg0, radiation[i].longitudeDeg0);
    connect(weatherData.latitudeDeg, radiation[i].latitudeDeg);
    connect(weatherData.longitudeDeg, radiation[i].longitudeDeg);
    // Direct horizontal radiation
    IrrDirHor = radiation[i].IrrDirHor;
    // Diffuse horizontal radiation
    IrrDifHor = radiation[i].IrrDifHor;
    for j in 1:gridSurface[i,1] loop
      for k in 1:gridSurface[i,2] loop
        // Climate data
        toAirPorts[i].heatPort[j,k].T = BuildingSystems.Buildings.Functions.TAir(TAirRef,toSurfacePorts[i].zMean,zRefTAir,gamma);
        toAirPorts[i].moisturePort[j,k].x = xAir;
        toAirPorts[i].vAir[j,k] = BuildingSystems.Buildings.Functions.vWind(vWindRef,toSurfacePorts[i].zMean,zRefvWind,P);
        toAirPorts[i].angleDegAir[j,k] = 0.0;
        // Further ambient parameters
        if calcLwRad then
          toSurfacePorts[i].heatPortLw[j,k].Q_flow = Modelica.Constants.sigma * toSurfacePorts[i].epsilon[j,k] * (toSurfacePorts[i].heatPortLw[j,k].T^4 - TSky^4) * toSurfacePorts[i].A[j,k];
        else
          toSurfacePorts[i].heatPortLw[j,k].Q_flow = 0.0;
        end if;
        toSurfacePorts[i].heatPortSw[j,k].Q_flow = - toSurfacePorts[i].abs[j,k] * (radiation[i].radiationPort.IrrDir + radiation[i].radiationPort.IrrDif) * toSurfacePorts[i].A[j,k];
        connect(radiation[i].radiationPort, toSurfacePorts[i].radiationPort_in[j,k]);
      end for;
    end for;
  end for;
  // Air path calculation
  for i in 1:nAirpathes loop
    toAirpathPorts[i].p = BuildingSystems.Buildings.Functions.pAir(pAirRef,TAirRef,heightAirpath[i],zRefTAir,gamma);
    toAirpathPorts[i].h_outflow = Medium.specificEnthalpy_pTX(p=100000, T=BuildingSystems.Buildings.Functions.TAir(TAirRef,heightAirpath[i],zRefTAir,gamma), X={xAir,1-xAir});
    toAirpathPorts[i].Xi_outflow[1] = xAir;
  end for;
  connect(weatherData.y[3], from_degC.u);

  // Select source for air temperature on reference height
  if TAirRefSou == BuildingSystems.Buildings.Types.DataSource.Parameter then
    TAirRef = TAirRef_constant;
  elseif TAirRefSou == BuildingSystems.Buildings.Types.DataSource.File then
    connect(TAirRef, from_degC.y);
  else
    connect(TAirRef, TAirRef_in);
  end if;

  // Select source for relative humidity of the ambient air
  if phiSou == BuildingSystems.Buildings.Types.DataSource.Parameter then
    phi = phi_constant;
  elseif phiSou == BuildingSystems.Buildings.Types.DataSource.File then
    phi = weatherData.y[6];
  else
    connect(phi, phi_in);
  end if;

  // Select source for solar diffuse radiation of horizontal surface
  if IrrDirHorSou == BuildingSystems.Buildings.Types.DataSource.Parameter then
    IrrDirHor = IrrDirHor_constant;
  elseif IrrDirHorSou == BuildingSystems.Buildings.Types.DataSource.File then
    connect(IrrDirHor, weatherData.y[1]);
  else
    connect(IrrDirHor, IrrDirHor_in);
  end if;

  // Select source for solar diffuse radiation of horizontal surface
  if IrrDifHorSou == BuildingSystems.Buildings.Types.DataSource.Parameter then
    IrrDifHor = IrrDifHor_constant;
  elseif IrrDifHorSou == BuildingSystems.Buildings.Types.DataSource.File then
    connect(IrrDifHor, weatherData.y[2]);
  else
    connect(IrrDifHor, IrrDifHor_in);
  end if;

  // Select source for Wind speed on reference height
  if vWindRefSou == BuildingSystems.Buildings.Types.DataSource.Parameter then
    vWindRef = vWindRef_constant;
  elseif vWindRefSou == BuildingSystems.Buildings.Types.DataSource.File then
    connect(vWindRef, weatherData.y[4]);
  else
    connect(vWindRef, vWindRef_in);
  end if;

  // Select source for wind direction on reference height
  if angleDegWindRefSou == BuildingSystems.Buildings.Types.DataSource.Parameter then
    angleDegWindRef = angleDegWindRef_constant;
  elseif angleDegWindRefSou == BuildingSystems.Buildings.Types.DataSource.File then
    connect(angleDegWindRef, weatherData.y[5]);
  else
    connect(angleDegWindRef, angleDegWindRef_in);
  end if;

  // Select source for Cloud cover of the sky
  if cloudCoverSou == BuildingSystems.Buildings.Types.DataSource.Parameter then
    cloudCover = cloudCover_constant;
  elseif angleDegWindRefSou == BuildingSystems.Buildings.Types.DataSource.File then
    cloudCover = weatherData.y[7];
  else
    connect(cloudCover, cloudCover_in);
  end if;

end Ambient;
 
record BuildingSystems.Climate.WeatherData.WeatherDataFile 
  "Template for weather data files"
  parameter String info = "";
  parameter String fileName = "";
end WeatherDataFile;
 
block BuildingSystems.Climate.WeatherData.WeatherDataNetcdf 
  "Weather data reader with Netcdf format"
  extends BuildingSystems.Utilities.NcDataReader2.NcDataReader(
  final nout = size(varNameTime,1),
  final varNameTime = {
    "beam_radiation",
    "diffuse_radiation",
    "air_temperature",
    "wind_speed",
    "wind_direction",
    "relative_humidity",
    "cloud_cover"},
  final varTimeLowerLimit = {0.0, 0.0,-100, 0.0, 0.0, 0.0, 0.0},
  final varTimeUpperLimit = {1000.0, 1000.0, 100.0, 100.0, 360.0, 1.0, 8.0},
  final varNameConstant = {"longitude", "latitude", "longitude_0"},
  final fileName = weatherDataFile.fileName,
  y(final quantity={"EnergyFluenceRate","EnergyFluenceRate","ThermodynamicTemperature","Velocity","Angle_deg","RelativeHumidity","CloudCover"},
    final unit={"W/m2","W/m2","K","m/s","deg","1","1"},
    final displayUnit={"W/m2","W/m2","degC","m/s","deg","1","1"}));
  output BuildingSystems.Interfaces.Angle_degOutput latitudeDeg = constantVariable[2] 
    "Longitude of the local point";
  output BuildingSystems.Interfaces.Angle_degOutput longitudeDeg = constantVariable[1] 
    "Latitude of the local point";
  output BuildingSystems.Interfaces.Angle_degOutput longitudeDeg0 = constantVariable[3] 
    "Longitude of the local time zone";
  replaceable parameter BuildingSystems.Climate.WeatherData.WeatherDataFile weatherDataFile 
    "Selected weather data file";

end WeatherDataNetcdf;
 
connector BuildingSystems.Interfaces.Angle_degOutput =
                            Modelica.Blocks.Interfaces.RealOutput(final quantity="Angle_deg",final unit="deg",displayUnit="deg");
 
block BuildingSystems.Utilities.NcDataReader2.NcDataReader
  extends Modelica.Blocks.Interfaces.MO(nout = size(varNameTime,1));
  parameter String varNameTime[:];
  parameter String varNameConstant[:];
  parameter String fileName;
  parameter Real varTimeUpperLimit[size(varNameTime,1)];
  parameter Real varTimeLowerLimit[size(varNameTime,1)];
protected 
  parameter Real constantVariable[size(varNameConstant,1)] = {ncEasyGetAttributeDouble(fileName,"",varNameConstant[j]) for j in 1:size(varNameConstant, 1)};

algorithm 
  for i in 1:nout loop
    y[i] := BuildingSystems.Utilities.SmoothFunctions.softcut(
      ncEasyGet1D(
        fileName,
        varNameTime[i],
        time),
      varTimeLowerLimit[i],
      varTimeUpperLimit[i],
      0.01);
  end for;
end NcDataReader;
 
  "Multiple Output continuous control block"
  extends Modelica.Blocks.Icons.Block;

  parameter Integer nout(min=1) = 1 "Number of outputs";
  RealOutput y[nout] "Connector of Real output signals";

end MO;
 
block Modelica.Blocks.Math.UnitConversions.From_degC 
  "Convert from degCelsius to Kelvin"
  extends Modelica.Blocks.Interfaces.PartialConversionBlock(u(unit="degC"),
      y(unit="K"));
equation 
  y = SI.Conversions.from_degC(u);
end From_degC;
 
partial block Modelica.Blocks.Interfaces.PartialConversionBlock 
  "Partial block defining the interface for conversion blocks"

  RealInput u "Connector of Real input signal to be converted";
  RealOutput y 
    "Connector of Real output signal containing input signal u in another unit";

end PartialConversionBlock;
 
type BuildingSystems.Buildings.Types.DataSource = enumeration(
    File "Use data from file",
    Parameter "Use parameter",
    Input "Use input connector") "Enumeration to select data source";
 
connector BuildingSystems.Interfaces.RadiantEnergyFluenceRateOutput =
    Modelica.Blocks.Interfaces.RealOutput (final quantity="RadiantEnergyFluenceRate",final unit="W/m2", displayUnit="W/m2");
 
connector BuildingSystems.Interfaces.RadiantEnergyFluenceRateInput =
                                          Modelica.Blocks.Interfaces.RealInput(final quantity="RadiantEnergyFluenceRate",final unit="W/m2", displayUnit="W/m2");
 
connector BuildingSystems.Interfaces.VelocityOutput =
                           Modelica.Blocks.Interfaces.RealOutput(final quantity="Velocity",final unit="m/s",min = 0.0, displayUnit="m/s");
 
connector BuildingSystems.Interfaces.VelocityInput =
                          Modelica.Blocks.Interfaces.RealInput(final quantity="Velocity",final unit="m/s",min = 0.0, displayUnit="m/s");
 
model
  BuildingSystems.Climate.SolarRadiationTransformers.SolarRadiationTransformerIsotropicSky
  "Solar radiation calculation on a tilted surface (isotropic sky model)"
  extends SolarRadiationTransformerGeneral;
equation 
  R = BuildingSystems.Utilities.SmoothFunctions.softcut_upper(cosAngleDegInc/cosAngleZen,5.0,0.001);

  radiationPort.IrrDir = R * IrrDirHor;

  // softcut for the limit of the solar constant = 1341 W/m^2
  IrrTotTil = BuildingSystems.Utilities.SmoothFunctions.softcut_upper(R * IrrDirHor + 0.5 * (1.0 + cosAngleDegTil) * IrrDifHor,1341.0,0.01)
    + 0.5 * (1.0 - cosAngleDegTil) * rhoAmb * IrrTotHor;

end SolarRadiationTransformerIsotropicSky;
 
partial model
  BuildingSystems.Climate.SolarRadiationTransformers.SolarRadiationTransformerGeneral
  "Solar radiation calculation on a tilted surface (general model)"

  input BuildingSystems.Interfaces.Angle_degInput latitudeDeg 
    "Latitude of the location";
  input BuildingSystems.Interfaces.Angle_degInput longitudeDeg 
    "Longitude of the location";
  input BuildingSystems.Interfaces.Angle_degInput longitudeDeg0 
    "Longitude of the local time zone";
  parameter Real rhoAmb "Reflection factor of the ambience";
  parameter Modelica.SIunits.Conversions.NonSIunits.Angle_deg angleDegL = 0 
    "Grad correction winter-/summer time";
  input BuildingSystems.Interfaces.RadiantEnergyFluenceRateInput IrrDirHor 
    "Solar beam radiation of horizontal surface";
  input BuildingSystems.Interfaces.RadiantEnergyFluenceRateInput IrrDifHor 
    "Solar diffuse radiation of horizontal surface";
  BuildingSystems.Interfaces.RadiationPort radiationPort 
    "Radiation port to the tilted surface";
  Modelica.SIunits.RadiantEnergyFluenceRate IrrTotHor 
    "Solar total radiation of horizontal surface";
  Modelica.SIunits.RadiantEnergyFluenceRate IrrTotTil 
    "Solar total radiation of tilted surface";
  input BuildingSystems.Interfaces.Angle_degInput angleDegAzi 
    "Azimuth angle of the surface";
  input BuildingSystems.Interfaces.Angle_degInput angleDegTil 
    "Tilt angle of the surface";
  Modelica.SIunits.Conversions.NonSIunits.Angle_deg angleZen "Zenith angle";
  Real cosAngleDegAzi "Cosinus of the azimuth angle";
  Real cosAngleDegInc "Cosinus of the incidence angle";
  Real cosAngleDegTil "Cosinus of the tilt angle";
  Real cosAngleZen "Cosinus of the zenith angle";
  Modelica.SIunits.Angle angleDec "Declination angle of the sun";
  Modelica.SIunits.Angle angleHr "Hour angle of the sun";
  Real R "R-factor for solar beam radiation";
  Real sinangleDegAzi "Sinus of the azimuth angle";
  Real sinangleDegTil "Sinus of the tilt angle";
  BuildingSystems.Types.Time_hr timeSun "Solar time";
  Real dayOfYear "Day of year";
  Real x "Helping variable";
  Real Z "Shift factor";
  Real sinAngleLat = sin(latitudeDeg * Modelica.Constants.pi / 180.0) 
    "Sinus of the latitude";
  Real cosAngleLat = cos(latitudeDeg * Modelica.Constants.pi / 180.0) 
    "Cosinus of the latitude";
equation 
  dayOfYear = time / (3600.0 * 24.0) + 0.5;

  x = 0.9856 * dayOfYear - 2.72;

  Z = - 7.66 * sin(x * Modelica.Constants.pi / 180.0) - 9.87 * sin((2.0 * x  + 24.99 + 3.83 * sin(x * Modelica.Constants.pi / 180.0)) * Modelica.Constants.pi / 180.0);

  angleDec = 23.45 * Modelica.Constants.pi / 180.0 * sin((360.0 * (284.0 + dayOfYear) / 365.0) * (Modelica.Constants.pi / 180.0));

  timeSun = time / 3600.0 + Z / 60.0 + 4.0 / 60.0 * (longitudeDeg0 - longitudeDeg + angleDegL);

  angleHr = 15.0 * (timeSun - 12.0) * Modelica.Constants.pi / 180.0;

  cosAngleZen = BuildingSystems.Utilities.SmoothFunctions.softcut(cosAngleLat * cos(angleDec) * cos(angleHr)
    + sinAngleLat * sin(angleDec),0.00001,1.0,0.0001);

  angleZen = acos(cosAngleZen) * 180.0 / Modelica.Constants.pi;

  cosAngleDegInc = BuildingSystems.Utilities.SmoothFunctions.softcut(sin(angleDec) * sinAngleLat * cosAngleDegTil
    - sin(angleDec) * cosAngleLat * sinangleDegTil * cosAngleDegAzi
    + cos(angleDec) * cosAngleLat * cosAngleDegTil * cos(angleHr)
    + cos(angleDec) * sinAngleLat * sinangleDegTil * cosAngleDegAzi * cos(angleHr)
    + cos(angleDec) * sinangleDegTil * sinangleDegAzi * sin(angleHr),0.0,1.0,0.0001);

  radiationPort.angleDegInc = acos(cosAngleDegInc) * 180.0 / Modelica.Constants.pi;

  sinangleDegAzi = sin(angleDegAzi * Modelica.Constants.pi / 180.0);

  cosAngleDegAzi = cos(angleDegAzi * Modelica.Constants.pi / 180.0);

  sinangleDegTil = sin(angleDegTil * Modelica.Constants.pi / 180.0);

  cosAngleDegTil = cos(angleDegTil * Modelica.Constants.pi / 180.0);

  IrrTotHor = IrrDirHor + IrrDifHor;

  IrrTotTil = radiationPort.IrrDif + radiationPort.IrrDir;
end SolarRadiationTransformerGeneral;


Vielen Dank fürs anschauen.

Gruss Stefan

Carles Ribas Tugores

unread,
Jan 11, 2017, 5:51:43 AM1/11/17
to Modelica-BuildingSystems
Hallo Stefan,

Das Building1Zone0D Model hat ein einziges zone, bzw. ZoneTemplateAirvolumeMixed. Daher setzt Building1Zone0D das Parameter nZones auf 1 mit dem Prefix finalWenn du das Modell instantiierst, solltest du dieses Parameter nicht überschreiben.

Lösung: statt BuildingSystems.Buildings.BuildingTemplates.Building1Zone0D buildingTest(nZones=1) schreibt BuildingSystems.Buildings.BuildingTemplates.Building1Zone0D buildingTest

Danach muss du noch ein Weather data für das ambient Modell auswählen. Dann sollte das Model simuliert werden!

Grüße,
Carles



 


Reply all
Reply to author
Forward
0 new messages