Empirical expression developed by Warren and Parkins (1984). This model contains the empirical expression developed by Warren and Parkins.

within AixLib.Airflow.WindowVentilation.EmpiricalExpressions;
model WarrenParkins "Empirical expression developed by Warren and Parkins (1984)"
  extends AixLib.Airflow.WindowVentilation.BaseClasses.PartialEmpiricalFlowStack(
    redeclare replaceable model OpeningArea =
      AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSimple,
    final varNameIntRes = "V_flow_th");
  Modelica.Blocks.Interfaces.RealInput winSpe10(unit="m/s", min=0)
    "Local wind speed at a height of 10 m"
protected
  Real cofDcg = 0.61 "Discharge coefficient";
  Modelica.Units.SI.VolumeFlowRate V_flow_th "Thermal induced volume flow";
  Modelica.Units.SI.VolumeFlowRate V_flow_win "Wind induced volume flow";
equation
  intRes = Modelica.Constants.g_n*winClrHeight*dTRoomAmb/TAvg;
  V_flow_th = if noEvent(intRes > Modelica.Constants.eps) then
    1/3*cofDcg*openingArea.A*sqrt(intRes) else 0;
  V_flow_win = 0.025*openingArea.A*winSpe10;
  V_flow = max(V_flow_th, V_flow_win);
end WarrenParkins;


Calculation of different opening areas. This example simulates and checks the models in package OpeningAreas, calculating the window opening area with variable opening width or angle.

within AixLib.Airflow.WindowVentilation.Examples;
model OpeningArea "Calculation of different opening areas"
  extends Modelica.Icons.Example;
  parameter Modelica.Units.SI.Length winClrWidth = 1.0 "Window clear width";
  parameter Modelica.Units.SI.Height winClrHeight = 1.5 "Window clear height";
  parameter Modelica.Units.SI.Thickness sWinSas = 0.08 "Window sash thickness";
  Modelica.Blocks.Sources.Ramp opnWidthSet(
    height=0.5,
    duration=50,
    startTime=5) "Window opening width set value"
  Modelica.Blocks.Sources.Ramp opnAngSet(
    height=30,
    duration=50,
    startTime=5) "Window opening angle set value"
  Modelica.Blocks.Math.UnitConversions.From_deg from_deg
    "Convert from deg to rad"
  AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSimple opnSimp(
    winClrWidth=winClrWidth,
    winClrHeight=winClrHeight) "Simple opening without sash"
  AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSimpleVDI2078 opnSimpVDI2078(
    winClrWidth=winClrWidth,
    winClrHeight=winClrHeight) "Simple opening without sash, VDI 2078"
  AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSashCommon opnSasSdHunInGeo(
    winClrWidth=winClrWidth,
    winClrHeight=winClrHeight,
    opnTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.SideHungInward,
    opnAreaTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.OpeningAreaTypes.Geometric)
    "Side-hung, inward, geometric opening"
  AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSashCommon opnSasSdHunInPrj(
    winClrWidth=winClrWidth,
    winClrHeight=winClrHeight,
    opnTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.SideHungInward,
    opnAreaTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.OpeningAreaTypes.Projective)
    "Side-hung, inward, projective opening"
  AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSashCommon opnSasSdHunInEqv(
    winClrWidth=winClrWidth,
    winClrHeight=winClrHeight,
    opnTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.SideHungInward,
    opnAreaTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.OpeningAreaTypes.Equivalent)
    "Side-hung, inward, equivalent opening"
  AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSashCommon opnSasSdHunInEff(
    winClrWidth=winClrWidth,
    winClrHeight=winClrHeight,
    opnTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.SideHungInward,
    opnAreaTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.OpeningAreaTypes.Effective)
    "Side-hung, inward, effective opening"
  AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSashCommon opnSasSdHunOutGeo(
    winClrWidth=winClrWidth,
    winClrHeight=winClrHeight,
    opnTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.SideHungOutward,
    opnAreaTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.OpeningAreaTypes.Geometric)
    "Side-hung, outward, geometric opening"
  AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSashCommon opnSasBtmHunInGeo(
    winClrWidth=winClrWidth,
    winClrHeight=winClrHeight,
    opnTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.BottomHungInward,
    opnAreaTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.OpeningAreaTypes.Geometric)
    "Bottom-hung, inward, geometric opening"
  AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSashCommon opnSasBtmHunInPrj(
    winClrWidth=winClrWidth,
    winClrHeight=winClrHeight,
    opnTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.BottomHungInward,
    opnAreaTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.OpeningAreaTypes.Projective)
    "Bottom-hung, inward, projective opening"
  AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSashCommon opnSasBtmHunInEqv(
    winClrWidth=winClrWidth,
    winClrHeight=winClrHeight,
    opnTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.BottomHungInward,
    opnAreaTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.OpeningAreaTypes.Equivalent)
    "Bottom-hung, inward, equivalent opening"
  AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSashCommon opnSasBtmHunInEff(
    winClrWidth=winClrWidth,
    winClrHeight=winClrHeight,
    opnTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.BottomHungInward,
    opnAreaTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.OpeningAreaTypes.Effective)
    "Bottom-hung, inward, effective opening"
  AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSashCommon opnSasTopHunOutPrj(
    winClrWidth=winClrWidth,
    winClrHeight=winClrHeight,
    opnTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.TopHungOutward,
    opnAreaTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.OpeningAreaTypes.Projective)
    "Top-hung, outward, projective opening"
  AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSashCommon opnSasPivVerGeo(
    winClrWidth=winClrWidth,
    winClrHeight=winClrHeight,
    opnTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.PivotVertical,
    opnAreaTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.OpeningAreaTypes.Geometric)
    "Pivot, vertical, geometric opening"
  AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSashCommon opnSasPivVerPrj(
    winClrWidth=winClrWidth,
    winClrHeight=winClrHeight,
    opnTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.PivotVertical,
    opnAreaTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.OpeningAreaTypes.Projective)
    "Pivot, vertical, projective opening"
  AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSashCommon opnSasPivVerEqv(
    winClrWidth=winClrWidth,
    winClrHeight=winClrHeight,
    opnTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.PivotVertical,
    opnAreaTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.OpeningAreaTypes.Equivalent)
    "Pivot, vertical, equivalent opening"
  AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSashCommon opnSasPivVerEff(
    winClrWidth=winClrWidth,
    winClrHeight=winClrHeight,
    opnTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.PivotVertical,
    opnAreaTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.OpeningAreaTypes.Effective)
    "Pivot, vertical, effective opening"
  AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSashCommon opnSasPivHorGeo(
    winClrWidth=winClrWidth,
    winClrHeight=winClrHeight,
    opnTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.PivotHorizontal,
    opnAreaTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.OpeningAreaTypes.Geometric)
    "Pivot, horizontal, geometric opening"
  AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSashCommon opnSasPivHorPrj(
    winClrWidth=winClrWidth,
    winClrHeight=winClrHeight,
    opnTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.PivotHorizontal,
    opnAreaTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.OpeningAreaTypes.Projective)
    "Pivot, horizontal, projective opening"
  AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSashCommon opnSasPivHorEqv(
    winClrWidth=winClrWidth,
    winClrHeight=winClrHeight,
    opnTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.PivotHorizontal,
    opnAreaTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.OpeningAreaTypes.Equivalent)
    "Pivot, horizontal, equivalent opening"
  AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSashCommon opnSasPivHorEff(
    winClrWidth=winClrWidth,
    winClrHeight=winClrHeight,
    opnTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.PivotHorizontal,
    opnAreaTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.OpeningAreaTypes.Effective)
    "Pivot, horizontal, effective opening"
  AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSashCommon opnSasPivHorEffPre(
    winClrWidth=winClrWidth,
    winClrHeight=winClrHeight,
    use_opnWidth_in=false,
    prescribedOpnWidth=0.5,
    opnTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.PivotHorizontal,
    opnAreaTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.OpeningAreaTypes.Effective)
    "Pivot, horizontal, effective opening, prescribed input"
  AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSashCommon opnSasSldVerGeo(
    winClrWidth=winClrWidth,
    winClrHeight=winClrHeight,
    opnTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.SlidingVertical,
    opnAreaTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.OpeningAreaTypes.Geometric)
    "Sliding, vertical, geometric opening"
  AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSashCommon opnSasSldHorGeo(
    winClrWidth=winClrWidth,
    winClrHeight=winClrHeight,
    opnTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.SlidingHorizontal,
    opnAreaTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.OpeningAreaTypes.Geometric)
    "Sliding, horizontal, geometric opening"
  AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSashDIN16798 opnSasBtmHunInDIN16798(
    winClrWidth=winClrWidth,
    winClrHeight=winClrHeight,
    opnTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.BottomHungInward)
    "Bottom-hung, inward, DIN 16798"
  AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSashDIN4108 opnSasSdHunInDIN4108(
    winClrWidth=winClrWidth,
    winClrHeight=winClrHeight,
    opnTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.SideHungInward)
    "Side-hung, inward, DIN 4108"
  AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSashDIN4108 opnSasBtmHunInDIN4108(
    winClrWidth=winClrWidth,
    winClrHeight=winClrHeight,
    opnTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.BottomHungInward)
    "Bottom-hung, inward, DIN 4108"
  AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSashDIN4108 opnSasPivHorDIN4108(
    winClrWidth=winClrWidth,
    winClrHeight=winClrHeight,
    opnTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.PivotHorizontal,
    sWinSas=sWinSas) "Pivot, horizontal, DIN 4108"
  AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSashHall opnSasBtmHunInHall(
    winClrWidth=winClrWidth,
    winClrHeight=winClrHeight,
    sWinSas=sWinSas) "Bottom-hung, inward, Hall"
  AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSashVDI2078 opnSasBtmHunInVDI2078(
    winClrWidth=winClrWidth,
    winClrHeight=winClrHeight,
    sWinSas=sWinSas) "Bottom-hung, inward, VDI2078"
  AixLib.Airflow.WindowVentilation.Utilities.AngleToWidth angToWidth(lenAxs=opnSasAngBtmHunInGeo.lenAxs,
      lenAxsToFrm=opnSasAngBtmHunInGeo.lenAxsToFrm)
    "Convert opening angle to opening width"
  AixLib.Airflow.WindowVentilation.Utilities.WidthToAngle widthToAng(lenAxs=opnSasAngBtmHunInGeo.lenAxs,
      lenAxsToFrm=opnSasAngBtmHunInGeo.lenAxsToFrm)
    "Convert opening width to opening angle"
  AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSashCommon opnSasAngBtmHunInGeo(
    winClrWidth=winClrWidth,
    winClrHeight=winClrHeight,
    opnTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.BottomHungInward,
    opnAreaTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.OpeningAreaTypes.Geometric)
    "Input of angle, bottom-hung, inward, geometric opening"

equation
  connect(opnWidthSet.y, opnSasSdHunInGeo.opnWidth_in)
  connect(opnWidthSet.y, opnSasSdHunInPrj.opnWidth_in)
  connect(opnWidthSet.y, opnSasSdHunInEqv.opnWidth_in)
  connect(opnWidthSet.y, opnSasSdHunInEff.opnWidth_in)
  connect(opnWidthSet.y, opnSasSdHunOutGeo.opnWidth_in)
  connect(opnWidthSet.y, opnSasBtmHunInGeo.opnWidth_in)
  connect(opnWidthSet.y, opnSasBtmHunInPrj.opnWidth_in)
  connect(opnWidthSet.y, opnSasBtmHunInEqv.opnWidth_in)
  connect(opnWidthSet.y, opnSasBtmHunInEff.opnWidth_in)
  connect(opnWidthSet.y, opnSasTopHunOutPrj.opnWidth_in)
  connect(opnWidthSet.y, opnSasPivVerGeo.opnWidth_in)
  connect(opnWidthSet.y, opnSasPivVerPrj.opnWidth_in)
  connect(opnWidthSet.y, opnSasPivVerEqv.opnWidth_in)
  connect(opnWidthSet.y, opnSasPivVerEff.opnWidth_in)
  connect(opnWidthSet.y, opnSasPivHorGeo.opnWidth_in)
  connect(opnWidthSet.y, opnSasPivHorPrj.opnWidth_in)
  connect(opnWidthSet.y, opnSasPivHorEqv.opnWidth_in)
  connect(opnWidthSet.y, opnSasPivHorEff.opnWidth_in)
  connect(opnWidthSet.y, opnSasSldVerGeo.opnWidth_in)
  connect(opnWidthSet.y, opnSasSldHorGeo.opnWidth_in)
  connect(opnAngSet.y, from_deg.u)
  connect(opnWidthSet.y, opnSasBtmHunInDIN16798.opnWidth_in)
  connect(opnWidthSet.y, opnSasSdHunInDIN4108.opnWidth_in)
  connect(opnWidthSet.y, opnSasBtmHunInDIN4108.opnWidth_in)
  connect(opnWidthSet.y, opnSasPivHorDIN4108.opnWidth_in)
  connect(opnWidthSet.y, opnSasBtmHunInHall.opnWidth_in)
  connect(opnWidthSet.y, opnSasBtmHunInVDI2078.opnWidth_in)
  connect(from_deg.y, angToWidth.u)
  connect(angToWidth.y, opnSasAngBtmHunInGeo.opnWidth_in)
  connect(angToWidth.y, widthToAng.u)
end OpeningArea;


Use different empirical expressions to determine the window ventilation flow rate by sash opening. This example checks the models that simulate the window ventilation flow rate with the sash opening. For the sash opening type, all models are set to the bottom-hung opening.

within AixLib.Airflow.WindowVentilation.Examples;
model VentilationFlowRateSashOpening
  "Use different empirical expressions to determine the window ventilation flow rate by sash opening"
  extends Modelica.Icons.Example;
  /*Parameters for boundary conditions*/
  parameter Modelica.Units.SI.Length winClrWidth(min=0)=1.0
    "Width of the window clear opening";
  parameter Modelica.Units.SI.Height winClrHeight(min=0)=1.8
    "Height of the window clear opening";
  parameter Modelica.Units.SI.Angle aziRef(displayUnit="deg")=0
    "Azimuth angle of the referece surface impacted by wind";
  parameter Modelica.Units.SI.Height locHeight(min=0)=4
    "Middle local height of the ventilation zone";
  Modelica.Blocks.Sources.Ramp TRoomSet(
    height=15,
    duration=120,
    offset=15,
    startTime=50) "Set room temperature in °C"
  Modelica.Blocks.Math.UnitConversions.From_degC from_degC "Convert degC to K"
  Modelica.Blocks.Sources.Ramp TAmbSet(
    height=-40,
    duration=160,
    offset=40,
    startTime=10) "Set ambient temperature in °C"
  Modelica.Blocks.Math.UnitConversions.From_degC from_degC1 "Convert degC to K"
  Modelica.Blocks.Sources.TimeTable winSpe10Set(table=[0,0; 20,0; 30,5; 40,0; 50,
        10; 60,0; 70,20; 80,0; 100,0; 110,20; 120,0; 130,10; 140,0; 150,5; 160,0;
        180,0]) "Set wind speed at the height of 10 m"
  Modelica.Blocks.Sources.Sine winDirSet(amplitude=2*Modelica.Constants.pi, f=0.05)
    "Set wind direction"
  AixLib.Airflow.WindowVentilation.EmpiricalExpressions.WarrenParkins warrenParkins(
    winClrWidth=winClrWidth,
    winClrHeight=winClrHeight,
    redeclare model OpeningArea =
      AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSashCommon (
        opnTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.BottomHungInward,
        opnAreaTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.OpeningAreaTypes.Geometric))
        "Model Warren Parkins"
  AixLib.Airflow.WindowVentilation.EmpiricalExpressions.GidsPhaff gidsPhaff(
    winClrWidth=winClrWidth,
    winClrHeight=winClrHeight,
    redeclare model OpeningArea =
      AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSashCommon (
        opnTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.BottomHungInward,
        opnAreaTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.OpeningAreaTypes.Geometric))
      "Model de Gids Phaff"
  AixLib.Airflow.WindowVentilation.EmpiricalExpressions.LarsenHeiselberg larsenHeiselberg(
    winClrWidth=winClrWidth,
    winClrHeight=winClrHeight,
    redeclare model OpeningArea =
      AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSashCommon (
        opnTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.BottomHungInward,
        opnAreaTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.OpeningAreaTypes.Geometric),
    aziRef=aziRef) "Model Larsen Heiselberg"
  AixLib.Airflow.WindowVentilation.EmpiricalExpressions.Caciolo caciolo(
    winClrWidth=winClrWidth,
    winClrHeight=winClrHeight,
    redeclare model OpeningArea =
      AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSashCommon (
        opnTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.BottomHungInward,
        opnAreaTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.OpeningAreaTypes.Geometric),
    aziRef=aziRef) "Model Caciolo"
  AixLib.Airflow.WindowVentilation.Utilities.WindProfilePowerLaw winSpeProLoc(
    height=locHeight, heightRef=10)
    "Calculate wind speed profile local"
  AixLib.Airflow.WindowVentilation.EmpiricalExpressions.Tang tang(
    winClrWidth=winClrWidth,
    winClrHeight=winClrHeight,
    redeclare model OpeningArea =
      AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSashCommon (
        opnTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.BottomHungInward,
        opnAreaTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.OpeningAreaTypes.Geometric))
    "Model Tang"
  AixLib.Airflow.WindowVentilation.EmpiricalExpressions.VDI2078 vdi2078_1(
    winClrWidth=winClrWidth,
    winClrHeight=winClrHeight,
    redeclare model OpeningArea =
      AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSashVDI2078,
    sunShaTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.SunshadingInstallationTypesVDI2078.NoSunshading)
    "Model VDI 2078, without sun shading"
  AixLib.Airflow.WindowVentilation.EmpiricalExpressions.VDI2078 vdi2078_2(
    winClrWidth=winClrWidth,
    winClrHeight=winClrHeight,
    redeclare model OpeningArea =
      AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSashVDI2078 (
        use_opnWidth_in=false, prescribedOpnWidth=0.1),
    sunShaTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.SunshadingInstallationTypesVDI2078.ExternalBlindsOn)
    "Model VDI 2078, with sun shading"
  AixLib.Airflow.WindowVentilation.EmpiricalExpressions.VDI2078 vdi2078_3(
    winClrWidth=winClrWidth,
    winClrHeight=winClrHeight,
    redeclare model OpeningArea =
      AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSashVDI2078 (
        use_opnWidth_in=false, prescribedOpnWidth=0.1),
    use_cofSunSha_in=true) "Model VDI 2078, with sun shading input"
  AixLib.Airflow.WindowVentilation.EmpiricalExpressions.DIN16798 din16798_1(
    winClrWidth=winClrWidth,
    winClrHeight=winClrHeight,
    redeclare model OpeningArea =
      AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSashDIN16798 (
        opnTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.BottomHungInward),
    heightASL=200) "Model DIN 16798"
  AixLib.Airflow.WindowVentilation.EmpiricalExpressions.DIN4108 din4108_1(
    winClrWidth=winClrWidth,
    winClrHeight=winClrHeight,
    redeclare model OpeningArea =
      AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSashDIN4108 (
        opnTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.BottomHungInward))
    "Model DIN 4108"
  AixLib.Airflow.WindowVentilation.EmpiricalExpressions.ASHRAE ashrae(
    winClrWidth=winClrWidth,
    winClrHeight=winClrHeight,
    redeclare model OpeningArea =
      AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSashCommon (
        opnTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.BottomHungInward,
        opnAreaTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.OpeningAreaTypes.Geometric),
    aziRef=aziRef) "Model ASHRAE"
  Modelica.Blocks.Sources.Pulse cofSunShaSet(
    amplitude=0.5,
    period=10,
    offset=0.5) "Set sunshading coefficient"
  Modelica.Blocks.Sources.SawTooth winOpnWidthSet(amplitude=0.3, period=10)
    "Set window opening width"
  Modelica.Blocks.Sources.Ramp dpSet(
    height=20,
    duration=160,
    offset=-10,
    startTime=10) "Set pressure difference"
  AixLib.Airflow.WindowVentilation.EmpiricalExpressions.Maas maas(
    winClrWidth=winClrWidth, winClrHeight=winClrHeight)
    "Model Maas"
  AixLib.Airflow.WindowVentilation.Utilities.WindProfilePowerLaw winSpePro13(
    height=13, heightRef=10)
    "Calculate wind speed profile at height of 13 m"
  AixLib.Airflow.WindowVentilation.EmpiricalExpressions.Hall hall(
    winClrWidth=winClrWidth, winClrHeight=winClrHeight)
    "Model Hall"
  AixLib.Airflow.WindowVentilation.EmpiricalExpressions.Jiang jiang(
    winClrWidth=winClrWidth, winClrHeight=winClrHeight)
    "Model Jiang"
equation
  connect(TRoomSet.y, from_degC.u)
  connect(TAmbSet.y, from_degC1.u)
  connect(winSpe10Set.y, winSpeProLoc.winSpeRef)
  connect(winSpe10Set.y, winSpePro13.winSpeRef)
  connect(cofSunShaSet.y, vdi2078_3.cofSunSha_in)
  connect(from_degC.y, warrenParkins.TRoom)
  connect(from_degC1.y, warrenParkins.TAmb)
  connect(winSpe10Set.y, warrenParkins.winSpe10)
  connect(from_degC.y, gidsPhaff.TRoom)
  connect(from_degC1.y, gidsPhaff.TAmb)
  connect(winSpe10Set.y, gidsPhaff.winSpe10)
  connect(from_degC.y, larsenHeiselberg.TRoom)
  connect(from_degC1.y, larsenHeiselberg.TAmb)
  connect(winSpe10Set.y, larsenHeiselberg.winSpe10)
  connect(winDirSet.y, larsenHeiselberg.winDir)
  connect(from_degC.y, caciolo.TRoom)
  connect(from_degC1.y, caciolo.TAmb)
  connect(winSpeProLoc.winSpe, caciolo.winSpeLoc)
  connect(winDirSet.y, caciolo.winDir)
  connect(from_degC.y, tang.TRoom)
  connect(from_degC1.y, tang.TAmb)
  connect(from_degC.y, maas.TRoom)
  connect(from_degC1.y, maas.TAmb)
  connect(winSpePro13.winSpe, maas.winSpe13)
  connect(from_degC.y, vdi2078_1.TRoom)
  connect(from_degC1.y, vdi2078_1.TAmb)
  connect(from_degC.y, vdi2078_2.TRoom)
  connect(from_degC1.y, vdi2078_2.TAmb)
  connect(from_degC.y, vdi2078_3.TRoom)
  connect(from_degC1.y, vdi2078_3.TAmb)
  connect(from_degC.y, din16798_1.TRoom)
  connect(from_degC1.y, din16798_1.TAmb)
  connect(winSpe10Set.y, din16798_1.winSpe10)
  connect(from_degC.y, din4108_1.TRoom)
  connect(from_degC1.y, din4108_1.TAmb)
  connect(winSpeProLoc.winSpe, din4108_1.winSpeLoc)
  connect(from_degC.y, ashrae.TRoom)
  connect(from_degC1.y, ashrae.TAmb)
  connect(winSpeProLoc.winSpe, ashrae.winSpeLoc)
  connect(winDirSet.y, ashrae.winDir)
  connect(from_degC.y, hall.TRoom)
  connect(from_degC1.y, hall.TAmb)
  connect(dpSet.y, jiang.dp)
  connect(winOpnWidthSet.y, warrenParkins.opnWidth_in)
  connect(winOpnWidthSet.y, gidsPhaff.opnWidth_in)
  connect(winOpnWidthSet.y, larsenHeiselberg.opnWidth_in)
  connect(winOpnWidthSet.y, caciolo.opnWidth_in)
  connect(winOpnWidthSet.y, tang.opnWidth_in)
  connect(winOpnWidthSet.y, maas.opnWidth_in)
  connect(winOpnWidthSet.y, vdi2078_1.opnWidth_in)
  connect(winOpnWidthSet.y, din16798_1.opnWidth_in)
  connect(winOpnWidthSet.y, din4108_1.opnWidth_in)
  connect(winOpnWidthSet.y, ashrae.opnWidth_in)
  connect(winOpnWidthSet.y, hall.opnWidth_in)
  connect(winOpnWidthSet.y, jiang.opnWidth_in)
end VentilationFlowRateSashOpening;


Use different empirical expressions to determine the window ventilation flow rate by simple opening. This example checks the models that simulate the window ventilation flow rate with the simple opening.

within AixLib.Airflow.WindowVentilation.Examples;
model VentilationFlowRateSimpleOpening
  "Use different empirical expressions to determine the window ventilation flow rate by simple opening"
  extends Modelica.Icons.Example;
  /*Parameters for boundary conditions*/
  parameter Modelica.Units.SI.Length winClrWidth(min=0)=1.0
    "Width of the window clear opening";
  parameter Modelica.Units.SI.Height winClrHeight(min=0)=1.8
    "Height of the window clear opening";
  parameter Modelica.Units.SI.Angle aziRef(displayUnit="deg")=0
    "Azimuth angle of the referece surface impacted by wind";
  parameter Modelica.Units.SI.Height locHeight(min=0)=4
    "Middle local height of the ventilation zone";
  Modelica.Blocks.Sources.Ramp TRoomSet(
    height=15,
    duration=120,
    offset=15,
    startTime=50) "Set room temperature in °C"
  Modelica.Blocks.Math.UnitConversions.From_degC from_degC "Convert degC to K"
  Modelica.Blocks.Sources.Ramp TAmbSet(
    height=-40,
    duration=160,
    offset=40,
    startTime=10) "Set ambient temperature in °C"
  Modelica.Blocks.Math.UnitConversions.From_degC from_degC1 "Convert degC to K"
  Modelica.Blocks.Sources.TimeTable winSpe10Set(table=[0,0; 20,0; 30,5; 40,0; 50,
        10; 60,0; 70,20; 80,0; 100,0; 110,20; 120,0; 130,10; 140,0; 150,5; 160,0;
        180,0]) "Set wind speed at the height of 10 m"
  Modelica.Blocks.Sources.Sine winDirSet(amplitude=2*Modelica.Constants.pi, f=0.05)
    "Set wind direction"
  AixLib.Airflow.WindowVentilation.EmpiricalExpressions.WarrenParkins warrenParkins(
    winClrWidth=winClrWidth,
    winClrHeight=winClrHeight,
    redeclare model OpeningArea =
      AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSimple)
        "Model Warren Parkins"
  AixLib.Airflow.WindowVentilation.EmpiricalExpressions.GidsPhaff gidsPhaff(
    winClrWidth=winClrWidth,
    winClrHeight=winClrHeight,
    redeclare model OpeningArea =
      AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSimple)
      "Model de Gids Phaff"
  AixLib.Airflow.WindowVentilation.EmpiricalExpressions.LarsenHeiselberg larsenHeiselberg(
    winClrWidth=winClrWidth,
    winClrHeight=winClrHeight,
    redeclare model OpeningArea =
      AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSimple,
    aziRef=aziRef) "Model Larsen Heiselberg"
  AixLib.Airflow.WindowVentilation.EmpiricalExpressions.Caciolo caciolo(
    winClrWidth=winClrWidth,
    winClrHeight=winClrHeight,
    redeclare model OpeningArea =
      AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSimple,
    aziRef=aziRef) "Model Caciolo"
  AixLib.Airflow.WindowVentilation.Utilities.WindProfilePowerLaw winSpeProLoc(
    height=locHeight, heightRef=10)
    "Calculate wind speed profile local"
  AixLib.Airflow.WindowVentilation.EmpiricalExpressions.Tang tang(
    winClrWidth=winClrWidth,
    winClrHeight=winClrHeight,
    redeclare model OpeningArea =
      AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSimple)
    "Model Tang"
  AixLib.Airflow.WindowVentilation.EmpiricalExpressions.VDI2078 vdi2078_1(
    winClrWidth=winClrWidth,
    winClrHeight=winClrHeight,
    redeclare model OpeningArea =
      AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSimpleVDI2078,
    sunShaTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.SunshadingInstallationTypesVDI2078.NoSunshading)
    "Model VDI 2078, without sun shading"
  AixLib.Airflow.WindowVentilation.EmpiricalExpressions.VDI2078 vdi2078_2(
    winClrWidth=winClrWidth,
    winClrHeight=winClrHeight,
    redeclare model OpeningArea =
      AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSimpleVDI2078,
    sunShaTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.SunshadingInstallationTypesVDI2078.ExternalBlindsOn)
    "Model VDI 2078, with sun shading"
  AixLib.Airflow.WindowVentilation.EmpiricalExpressions.VDI2078 vdi2078_3(
    winClrWidth=winClrWidth,
    winClrHeight=winClrHeight,
    redeclare model OpeningArea =
      AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSimpleVDI2078,
    use_cofSunSha_in=true) "Model VDI 2078, with sun shading input"
  AixLib.Airflow.WindowVentilation.EmpiricalExpressions.DIN16798 din16798_1(
    winClrWidth=winClrWidth,
    winClrHeight=winClrHeight,
    redeclare model OpeningArea =
      AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSimple,
    heightASL=200) "Model DIN 16798"
  AixLib.Airflow.WindowVentilation.EmpiricalExpressions.DIN4108 din4108_1(
    winClrWidth=winClrWidth,
    winClrHeight=winClrHeight,
    redeclare model OpeningArea =
      AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSimple)
    "Model DIN 4108"
  AixLib.Airflow.WindowVentilation.EmpiricalExpressions.ASHRAE ashrae(
    winClrWidth=winClrWidth,
    winClrHeight=winClrHeight,
    redeclare model OpeningArea =
      AixLib.Airflow.WindowVentilation.OpeningAreas.OpeningAreaSimple,
    aziRef=aziRef) "Model ASHRAE"
  Modelica.Blocks.Sources.Pulse cofSunShaSet(
    amplitude=0.5,
    period=10,
    offset=0.5) "Set sunshading coefficient"
equation
  connect(TRoomSet.y, from_degC.u)
  connect(TAmbSet.y, from_degC1.u)
  connect(winSpe10Set.y, winSpeProLoc.winSpeRef)
  connect(cofSunShaSet.y, vdi2078_3.cofSunSha_in)
  connect(from_degC.y, warrenParkins.TRoom)
  connect(from_degC1.y, warrenParkins.TAmb)
  connect(winSpe10Set.y, warrenParkins.winSpe10)
  connect(from_degC.y, gidsPhaff.TRoom)
  connect(from_degC1.y, gidsPhaff.TAmb)
  connect(winSpe10Set.y, gidsPhaff.winSpe10)
  connect(from_degC.y, larsenHeiselberg.TRoom)
  connect(from_degC1.y, larsenHeiselberg.TAmb)
  connect(winSpe10Set.y, larsenHeiselberg.winSpe10)
  connect(winDirSet.y, larsenHeiselberg.winDir)
  connect(from_degC.y, caciolo.TRoom)
  connect(from_degC1.y, caciolo.TAmb)
  connect(winSpeProLoc.winSpe, caciolo.winSpeLoc)
  connect(winDirSet.y, caciolo.winDir)
  connect(from_degC.y, tang.TRoom)
  connect(from_degC1.y, tang.TAmb)
  connect(from_degC.y, vdi2078_1.TRoom)
  connect(from_degC1.y, vdi2078_1.TAmb)
  connect(from_degC.y, vdi2078_2.TRoom)
  connect(from_degC1.y, vdi2078_2.TAmb)
  connect(from_degC.y, vdi2078_3.TRoom)
  connect(from_degC1.y, vdi2078_3.TAmb)
  connect(from_degC.y, din16798_1.TRoom)
  connect(from_degC1.y, din16798_1.TAmb)
  connect(winSpe10Set.y, din16798_1.winSpe10)
  connect(from_degC.y, din4108_1.TRoom)
  connect(from_degC1.y, din4108_1.TAmb)
  connect(winSpeProLoc.winSpe, din4108_1.winSpeLoc)
  connect(from_degC.y, ashrae.TRoom)
  connect(from_degC1.y, ashrae.TAmb)
  connect(winSpeProLoc.winSpe, ashrae.winSpeLoc)
  connect(winDirSet.y, ashrae.winDir)
end VentilationFlowRateSimpleOpening;


Calculate geometric, projective, equivalent, and effective window opening
  areas, by different types of sash opening. This partial model provides a base class of common window sash opening area, incl. geometric, projective, equivalent, and effective opening area.

within AixLib.Airflow.WindowVentilation.OpeningAreas;
model OpeningAreaSashCommon
  "Calculate geometric, projective, equivalent, and effective window opening
  areas, by different types of sash opening"
  extends AixLib.Airflow.WindowVentilation.BaseClasses.PartialOpeningAreaSash;
  parameter AixLib.Airflow.WindowVentilation.BaseClasses.Types.OpeningAreaTypes
    opnAreaTyp = AixLib.Airflow.WindowVentilation.BaseClasses.Types.OpeningAreaTypes.Geometric
    "Window opening area types to calculate";

  /*Characterize lengths*/
  final parameter Modelica.Units.SI.Length lenAxs(min=0)=
    if (opnTyp == AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.SideHungInward or
    opnTyp == AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.SideHungOutward or
    opnTyp == AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.PivotVertical) then
    winClrHeight else if (opnTyp == AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.TopHungOutward or
    opnTyp == AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.BottomHungInward or
    opnTyp == AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.PivotHorizontal) then
    winClrWidth else 0
    "Length to characterize the hung and pivot window opening:
    length of the hinged axis";
  final parameter Modelica.Units.SI.Length lenAxsToFrm(min=0)=
    if (opnTyp == AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.SideHungInward or
    opnTyp == AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.SideHungOutward) then
    winClrWidth else if (opnTyp == AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.TopHungOutward or
    opnTyp == AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.BottomHungInward) then
    winClrHeight else if (opnTyp == AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.PivotVertical) then
    winClrWidth/2 else if (opnTyp == AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.PivotHorizontal) then
    winClrHeight/2 else 0
    "Length to characterize the hung and pivot window opening:
    distance from the hinged axis to the frame across the opening area";

  /*Variables to describe the opening*/
  Modelica.Units.SI.Area AGeoOpn(min=0) "Geometric opening area";
  Modelica.Units.SI.Area APrjOpn(min=0) "Projective opening area";
  Modelica.Units.SI.Area AEqvOpn(min=0) "Equivalent opening area";
  Modelica.Units.SI.Area AEffOpn(min=0) "Effective opening area";
protected
  Modelica.Units.SI.Length opnWidth90(min=0)
    "Sash opening width by 90° opening / full sliding opening";
  Modelica.Units.SI.Area AGeoOpn90(min=0)
    "Geometric opening area by 90° opening";
  Modelica.Units.SI.Area AEqvOpn90(min=0)
    "Equivalent opening area by 90° opening";
initial equation
  if opnTyp == AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.SlidingVertical or
    opnTyp == AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.SlidingHorizontal then
    assert(
      opnAreaTyp == AixLib.Airflow.WindowVentilation.BaseClasses.Types.OpeningAreaTypes.Geometric,
      "By opening type 'Sliding', only 'geometric' opening area is valid.",
      AssertionLevel.error);
  end if;
equation
  /*Hinged opening*/
  if opnTyp == AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.SideHungInward or
    opnTyp == AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.SideHungOutward or
    opnTyp == AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.TopHungOutward or
    opnTyp == AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.BottomHungInward then
    /*Calculate area values*/
    AGeoOpn =
      AixLib.Airflow.WindowVentilation.BaseClasses.Functions.OpeningAreaHinged.GeometricOpeningArea(
      lenAxs, lenAxsToFrm, opnWidth_internal);
    APrjOpn =
      AixLib.Airflow.WindowVentilation.BaseClasses.Functions.OpeningAreaHinged.ProjectiveOpeningArea(
      lenAxs, lenAxsToFrm, opnWidth_internal);
    opnWidth90 =
      AixLib.Airflow.WindowVentilation.BaseClasses.Functions.OpeningAreaHinged.AngleToWidth(
      lenAxs, lenAxsToFrm, Modelica.Constants.pi/2);
    AGeoOpn90 = AixLib.Airflow.WindowVentilation.BaseClasses.Functions.OpeningAreaHinged.GeometricOpeningArea(
      lenAxs, lenAxsToFrm, opnWidth90);

  /*Pivot opening*/
  elseif opnTyp == AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.PivotVertical or
    opnTyp == AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.PivotHorizontal then
    /*Calculate area values*/
    AGeoOpn =
      AixLib.Airflow.WindowVentilation.BaseClasses.Functions.OpeningAreaHinged.GeometricOpeningArea(
      lenAxs, lenAxsToFrm, opnWidth_internal)*2;
    APrjOpn =
      AixLib.Airflow.WindowVentilation.BaseClasses.Functions.OpeningAreaHinged.ProjectiveOpeningArea(
      lenAxs, lenAxsToFrm, opnWidth_internal)*2;
    opnWidth90 =
      AixLib.Airflow.WindowVentilation.BaseClasses.Functions.OpeningAreaHinged.AngleToWidth(
      lenAxs, lenAxsToFrm, Modelica.Constants.pi/2);
    AGeoOpn90 = AixLib.Airflow.WindowVentilation.BaseClasses.Functions.OpeningAreaHinged.GeometricOpeningArea(
      lenAxs, lenAxsToFrm, opnWidth90)*2;

  /*Sliding opening*/
  elseif opnTyp == AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.SlidingVertical or
    opnTyp == AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.SlidingHorizontal then
    /*Calculate area values*/
    if opnTyp == AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.SlidingVertical then
      /*Vertical*/
      AGeoOpn = winClrWidth*opnWidth_internal;
      opnWidth90 = winClrHeight;
      AGeoOpn90 = winClrWidth*opnWidth90;
    else
      /*Horizontal*/
      AGeoOpn = winClrHeight*opnWidth_internal;
      opnWidth90 = winClrWidth;
      AGeoOpn90 = winClrHeight*opnWidth90;
    end if;
    APrjOpn = AGeoOpn;

  /*Exceptions*/
  else
    AGeoOpn = 0;
    APrjOpn = 0;
    opnWidth90 = 0;
    AGeoOpn90 = 0;
  end if;

  /*Calculate the rest area types*/
  AEqvOpn = AixLib.Airflow.WindowVentilation.BaseClasses.Functions.OpeningAreaHinged.EquivalentOpeningArea(
    AClrOpn, AGeoOpn);
  AEqvOpn90 = AixLib.Airflow.WindowVentilation.BaseClasses.Functions.OpeningAreaHinged.EquivalentOpeningArea(
    AClrOpn, AGeoOpn90);
  AEffOpn = AixLib.Airflow.WindowVentilation.BaseClasses.Functions.OpeningAreaHinged.EffectiveOpeningArea(
    AClrOpn, AEqvOpn, AEqvOpn90);

  /*Export area to port based on choice*/
  A = if opnAreaTyp == AixLib.Airflow.WindowVentilation.BaseClasses.Types.OpeningAreaTypes.Geometric then
    AGeoOpn else if opnAreaTyp == AixLib.Airflow.WindowVentilation.BaseClasses.Types.OpeningAreaTypes.Projective then
    APrjOpn else if opnAreaTyp == AixLib.Airflow.WindowVentilation.BaseClasses.Types.OpeningAreaTypes.Equivalent then
    AEqvOpn else if opnAreaTyp == AixLib.Airflow.WindowVentilation.BaseClasses.Types.OpeningAreaTypes.Effective then
    AEffOpn else 0;
end OpeningAreaSashCommon;


Specified DIN CEN/TR 16798-8: Only valid for bottom- or top-hung opening. This model determines the window opening area according to DIN CEN/TR 16798-8 (DIN SPEC 32739-8):2018-03.

within AixLib.Airflow.WindowVentilation.OpeningAreas;
model OpeningAreaSashDIN16798
  "Specified DIN CEN/TR 16798-8: Only valid for bottom- or top-hung opening"
  extends AixLib.Airflow.WindowVentilation.BaseClasses.PartialOpeningAreaSash;
  Real cof "Coefficient depending on the kind of window";
initial equation
  assert(
    opnTyp == AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.TopHungOutward or
    opnTyp == AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.BottomHungInward,
    "The model is only valid for top- or bottom-hung opening.",
    AssertionLevel.error);
  assert((winClrHeight/winClrWidth >= 1) and (winClrHeight/winClrWidth <= 2),
    "For hinged windows, the model applies for height and width geometries of approx. 1:1 to 2:1",
    AssertionLevel.warning);
equation
  cof = AixLib.Airflow.WindowVentilation.BaseClasses.Functions.OpeningAreaHinged.CoeffOpeningAreaDIN16798(
    opnAng);
  A = cof*AClrOpn;
end OpeningAreaSashDIN16798;


Specified DIN/TS 4108-8: Valid for different opening types. This model determines the window opening area according to DIN/TS 4108-8:2022-09.

within AixLib.Airflow.WindowVentilation.OpeningAreas;
model OpeningAreaSashDIN4108
  "Specified DIN/TS 4108-8: Valid for different opening types"
  extends AixLib.Airflow.WindowVentilation.BaseClasses.PartialOpeningAreaSash;
  parameter Modelica.Units.SI.Thickness sWinSas(min=0) = 0
    "Window sash thickness (depth)"
initial equation
  if opnTyp == AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.TopHungOutward or
    opnTyp == AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.BottomHungInward then
    assert((winClrHeight/winClrWidth >= 1) and (winClrHeight/winClrWidth <= 2),
      "For hinged windows, the model applies for height and width geometries of approx. 1:1 to 2:1",
      AssertionLevel.warning);
  end if;
equation
  if opnTyp == AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.SideHungInward or
    opnTyp == AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.SideHungOutward then
    A = if opnWidth_internal < Modelica.Constants.eps then 0 else sqrt(1/(
      (winClrWidth*winClrHeight)^(-2) + (2*winClrWidth*winClrHeight*sin(opnAng/2)
      + winClrWidth^2*sin(opnAng))^(-2)));

  elseif opnTyp == AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.TopHungOutward or
    opnTyp == AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.BottomHungInward then
    assert(opnAng <= Modelica.Units.Conversions.from_deg(30),
      "The model only applies to a maximum tilt angle of 30°",
      AssertionLevel.warning);
    A = AixLib.Airflow.WindowVentilation.BaseClasses.Functions.OpeningAreaHinged.CoeffOpeningAreaDIN16798(
      opnAng)*winClrWidth*winClrHeight;

  elseif opnTyp == AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.PivotVertical or
    opnTyp == AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.PivotHorizontal then
    A = if opnWidth_internal < Modelica.Constants.eps then 0 else min(2*(
      opnWidth_internal*(winClrWidth - 2*sWinSas) + opnWidth_internal*sqrt((
      winClrHeight/2*opnWidth_internal/(opnWidth_internal + sWinSas))^2 - 0.25*
      opnWidth_internal^2)), (winClrHeight - sWinSas)*winClrWidth);

  elseif opnTyp == AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.SlidingVertical then
    A = opnWidth_internal*winClrWidth;

  elseif opnTyp == AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.SlidingHorizontal then
    A = opnWidth_internal*winClrHeight;

  else
    A = 0;
  end if;
end OpeningAreaSashDIN4108;


Specified Hall: Only valid for bottom-hung inwards opening. This model determines the window opening area according to the empirical expression developed by Hall.

within AixLib.Airflow.WindowVentilation.OpeningAreas;
model OpeningAreaSashHall
  "Specified Hall: Only valid for bottom-hung inwards opening"
  extends AixLib.Airflow.WindowVentilation.BaseClasses.PartialOpeningAreaSash(
    final opnTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.BottomHungInward);
  parameter Modelica.Units.SI.Thickness sWinSas(min=0) = 0
    "Window sash thickness (depth)";
  parameter Modelica.Units.SI.Length widthWinGap(min=0) = 0.01
    "Gap width in the overlap area between the frame and the sash";
  Real corNPL "Correction factor of the neutral pressure level";
initial equation
  assert(winClrHeight >= winClrWidth,
    "The model only applies to windows whose height is not less than the width",
    AssertionLevel.warning);
equation
  corNPL = sqrt((winClrWidth - opnWidth_internal)/winClrHeight);
  A = if noEvent(opnWidth_internal > Modelica.Constants.eps) then corNPL*
    opnWidth_internal*(winClrHeight*opnWidth_internal/(opnWidth_internal +
    sWinSas) - winClrHeight*(1 - corNPL)) + 2*winClrHeight*sWinSas/(
    opnWidth_internal + sWinSas)*widthWinGap else 0;
end OpeningAreaSashHall;


Specified VDI 2078: Only valid for bottom-hung inwards opening. This model determines the window opening area according to VDI 2078:2015-06.

within AixLib.Airflow.WindowVentilation.OpeningAreas;
model OpeningAreaSashVDI2078
  "Specified VDI 2078: Only valid for bottom-hung inwards opening"
  extends AixLib.Airflow.WindowVentilation.BaseClasses.PartialOpeningAreaSash(
    final opnTyp=AixLib.Airflow.WindowVentilation.BaseClasses.Types.WindowOpeningTypes.BottomHungInward);
  parameter Modelica.Units.SI.Height heightRevToFrm = 0.1
    "Vertical distance (height) between the reveal above the window and window top frame";
  parameter Modelica.Units.SI.Thickness sWinSas(min=0) = 0
    "Window sash thickness (depth)";
  Modelica.Units.SI.Height effHeight(min=0)
    "Effective height for the thermal updraft";
  Modelica.Units.SI.Height ovlHeight(min=0)
    "Height of the overlap between window frame and casement";
  Real corRev "Correction factor of the window reveal";
equation
  assert(opnAng <= Modelica.Units.Conversions.from_deg(15),
    "The model only applies to a maximum tilt angle of 15°",
    AssertionLevel.warning);
  effHeight = 2/3*(winClrHeight - ovlHeight);
  ovlHeight = if sWinSas > Modelica.Constants.eps then
    sWinSas/(opnWidth_internal + sWinSas)*winClrHeight else 0;
  corRev = if opnWidth_internal <= heightRevToFrm then 1 else
    1 - 0.6*(1 - heightRevToFrm/opnWidth_internal);
  A = if noEvent(opnWidth_internal > Modelica.Constants.eps) then
    ((winClrWidth + winClrHeight - ovlHeight)*opnWidth_internal/3)*corRev else 0;
end OpeningAreaSashVDI2078;


Common simple opening (no sash). This model determines the window opening area by a simple opening without window sash.

within AixLib.Airflow.WindowVentilation.OpeningAreas;
model OpeningAreaSimple "Common simple opening (no sash)"
  extends AixLib.Airflow.WindowVentilation.BaseClasses.PartialOpeningArea(
    final use_opnWidth_in=false,
    final prescribedOpnWidth=0);
equation
  A = AClrOpn;
end OpeningAreaSimple;


Specified VDI 2078: Simple opening (no sash). This model determines the window opening area by a simple opening without window sash according to VDI 2078:2015-06.

within AixLib.Airflow.WindowVentilation.OpeningAreas;
model OpeningAreaSimpleVDI2078
  "Specified VDI 2078: Simple opening (no sash)"
  extends AixLib.Airflow.WindowVentilation.BaseClasses.PartialOpeningArea(
    final use_opnWidth_in=false,
    final prescribedOpnWidth=0);
  final parameter Modelica.Units.SI.Height effHeight(min=0) = 2/3*winClrHeight
    "Effective height for the thermal updraft";
equation
  A = 1/3*AClrOpn;
end OpeningAreaSimpleVDI2078;


within AixLib.Airflow.WindowVentilation;
package OpeningAreas "Calculation of different opening areas based on different window types"
  extends Modelica.Icons.VariantsPackage;
end OpeningAreas;


Convert from window opening angle to opening width. Convert from window opening angle to opening width.

within AixLib.Airflow.WindowVentilation.Utilities;
model AngleToWidth
  "Convert from window opening angle to opening width"
  extends Modelica.Blocks.Interfaces.PartialConversionBlock(
    u(unit="rad"), y(unit="m"));
  parameter Modelica.Units.SI.Length lenAxs(min=0)
    "Length of the hinged axis, the axis should be parallel to a window frame";
  parameter Modelica.Units.SI.Length lenAxsToFrm(min=0)
    "Distance from the hinged axis to the frame across the opening area";
equation
  y =
    AixLib.Airflow.WindowVentilation.BaseClasses.Functions.OpeningAreaHinged.AngleToWidth(
    lenAxs, lenAxsToFrm, u);
end AngleToWidth;


Convert from window opening width to opening angle. Convert from window opening width to opening angle.

within AixLib.Airflow.WindowVentilation.Utilities;
model WidthToAngle
  "Convert from window opening width to opening angle"
  extends Modelica.Blocks.Interfaces.PartialConversionBlock(
    u(unit="m"), y(unit="rad"));
  parameter Modelica.Units.SI.Length lenAxs(min=0)
    "Length of the hinged axis, the axis should be parallel to a window frame";
  parameter Modelica.Units.SI.Length lenAxsToFrm(min=0)
    "Distance from the hinged axis to the frame across the opening area";
equation
  y =
    AixLib.Airflow.WindowVentilation.BaseClasses.Functions.OpeningAreaHinged.WidthToAngle(
    lenAxs, lenAxsToFrm, u);
end WidthToAngle;


Wind profile power law relationship of Hellmann. This model contains the wind profile power law relationship of
  Hellmann.

within AixLib.Airflow.WindowVentilation.Utilities;
model WindProfilePowerLaw
  "Wind profile power law relationship of Hellmann"
  parameter Modelica.Units.SI.Height height(min=0)
    "Height of the wind speed to calculate";
  parameter Modelica.Units.SI.Height heightRef(min=0)=10
    "Reference height of the known wind speed";
  parameter Modelica.Units.SI.Length lenRuf(min=0)=0.6 "Roughness length";
  final parameter Real cof = 1/log(height/lenRuf)
    "Hellmann exponent (coefficient)";
  Modelica.Blocks.Interfaces.RealInput winSpeRef(unit="m/s", min=0)
    "Wind speed at the reference height"
  Modelica.Blocks.Interfaces.RealOutput winSpe(unit="m/s", min=0)
    "Wind speed at height"
initial equation
  assert(
    height > lenRuf,
    "Power law not applicable by height less than the roughness length",
    AssertionLevel.error);
equation
  winSpe = winSpeRef*(height/heightRef)^cof;
end WindProfilePowerLaw;


within AixLib;
package BoundaryConditions "Package with models for boundary conditions"
  extends Modelica.Icons.Package;
end BoundaryConditions;


Package with type definitions

within AixLib.BoundaryConditions;
package Types "Package with type definitions"
 extends Modelica.Icons.TypesPackage;
  type DataSource = enumeration(
      File "Use data from file",
      Parameter "Use parameter",
      Input "Use input connector") "Enumeration to define data source"

  type RadiationDataSource = enumeration(
      File "Use data from file",
      Input_HGloHor_HDifHor
        "Global horizontal and diffuse horizontal radiation from connector",
      Input_HDirNor_HDifHor
        "Direct normal and diffuse horizontal radiation from connector",
      Input_HDirNor_HGloHor
        "Direct normal and global horizontal radiation from connector")
    "Enumeration to define solar radiation data source"
  type SkyTemperatureCalculation = enumeration(
      HorizontalRadiation
        "Use horizontal irradiation",
      TemperaturesAndSkyCover
        "Use dry-bulb and dew-point temperatures and sky cover")
    "Enumeration for computation of sky temperature"
end Types;


User's Guide

within AixLib.BoundaryConditions;
package UsersGuide "User's Guide"
  extends Modelica.Icons.Information;
end UsersGuide;


Model for undisturbed ground temperature.

within AixLib.BoundaryConditions.GroundTemperature;
model GroundTemperatureKusuda "Model for undisturbed ground temperature"

  parameter Modelica.Units.SI.Temperature T_mean
    "Average air temperature over the year";
  parameter Modelica.Units.SI.TemperatureDifference T_amp
    "Amplitude of surface temperature [(maximum air temperature - minimum air temperature)/2]";
  parameter Modelica.Units.SI.Distance D "Depth of ground temperature";
  parameter Modelica.Units.SI.ThermalDiffusivity alpha=0.04
    "Thermal diffusivity of the ground. Declare in m2/day!";
  parameter Modelica.Units.SI.Time t_shift
    "Time of the year with minimum air temperature. Declare in days!";

  Modelica.Thermal.HeatTransfer.Sources.PrescribedTemperature
    prescribedTemperature "Transfers computed ground temperature to heat port"
  Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b port
    "Heat port for ground"

equation

  prescribedTemperature.T =  (T_mean)-(T_amp)*(exp(-D*sqrt(Modelica.Constants.pi/(365*alpha)))*cos(2*Modelica.Constants.pi/365*(time/(3600*24)-t_shift-D/2*sqrt(Modelica.Constants.pi/(365*alpha)))));

  connect(prescribedTemperature.port, port)
end GroundTemperatureKusuda;


within AixLib.BoundaryConditions;
package GroundTemperature "Package with models to compute the ground temperature"
  extends Modelica.Icons.VariantsPackage;
end GroundTemperature;


Ground temperature at the site of EBC. This example shows the ground temperature at the site of the
  Institute for Energy Efficient Buildings and Indoor Climate at RWTH
  Aachen University's E.ON Energy Research Center (Mathieustr. 10,
  52074 Aachen).

within AixLib.BoundaryConditions.GroundTemperature.Examples;
model ExampleAachen "Ground temperature at the site of EBC"
  extends Modelica.Icons.Example;
  GroundTemperatureKusuda groundTemperatureAachen(
    alpha=0.039,
    D=1,
    T_amp=19.25,
    t_shift=3,
    T_mean=283.6)
    "Undisturbed ground temperature model with values for EBC main building"
  Modelica.Thermal.HeatTransfer.Sensors.TemperatureSensor temperatureSensor
    "Sensor to show ground temperature"
  Modelica.Blocks.Interfaces.RealOutput T_ground
    "Output to show ground temperature"
equation
  connect(groundTemperatureAachen.port, temperatureSensor.port)
  connect(temperatureSensor.T, T_ground)
end ExampleAachen;


Keeps track of the maximum air temperature. Example to test and tune Kusuda ground temperature model with the
  weather model from the Modelica Buildings Library.

within AixLib.BoundaryConditions.GroundTemperature.Examples;
model ExampleSanFran
  extends Modelica.Icons.Example;
  Real T_max(start=0) "Keeps track of the maximum air temperature";
  Real T_min(start=300) "Keeps track of the minimum air temperature";

  AixLib.BoundaryConditions.WeatherData.Bus    weaBus "Component to supply air
  temperature"
  Modelica.Blocks.Interfaces.RealOutput T_air "Output to show air temperature"
  Modelica.Blocks.Continuous.Integrator integrator "Integrates air temperature
  to compute average air temperature"
  Modelica.Blocks.Math.Division division "Division for average air temperature"
  Modelica.Blocks.Sources.RealExpression timeSource(y=time) "Denominator for
  average air temperature"
  Modelica.Blocks.Interfaces.RealOutput T_mean "Output of average air
  temperature since beginning of simulation"
  Modelica.Blocks.Math.Max denominatorTmean
    "Max-function to prevent division by 0 at time=0"
  Modelica.Blocks.Sources.RealExpression denominatorAtTimeZero(y=1) "Real source
  to prevent division by 0 at time=0"
  AixLib.BoundaryConditions.WeatherData.ReaderTMY3    weaDat(
      computeWetBulbTemperature=false, filNam=Modelica.Utilities.Files.loadResource("modelica://AixLib/Resources/weatherdata/USA_CA_San.Francisco.Intl.AP.724940_TMY3.mos"))
                                       "File reader that reads weather data"
  GroundTemperatureKusuda groundTemperatureKusuda(
    t_shift=23,
    alpha=0.039,
    D=1,
    T_amp=15.49,
    T_mean=286.95) "Undisturbed ground temperature model"
  Modelica.Blocks.Interfaces.RealOutput T_ground "Output to show ground
  temperature"
  Modelica.Thermal.HeatTransfer.Sensors.TemperatureSensor temperatureSensor
    "Sensor to show ground temperature"
  Modelica.Blocks.Interfaces.RealOutput T_amp
    "Keeps track of the amplitude of the air temperature"
equation

 T_max=max(T_max, T_air);
 T_min=min(T_min, T_air);
 T_amp = (T_max-T_min)/2;
  connect(T_air, weaBus.TDryBul)
  connect(integrator.u, T_air)
  connect(integrator.y, division.u1)
  connect(division.y, T_mean)
  connect(division.u2, denominatorTmean.y)
  connect(denominatorTmean.u2, timeSource.y)
  connect(denominatorAtTimeZero.y, denominatorTmean.u1)
  connect(weaDat.weaBus, weaBus)
  connect(groundTemperatureKusuda.port, temperatureSensor.port)
  connect(temperatureSensor.T, T_ground)
  connect(T_mean, T_mean)
end ExampleSanFran;


within AixLib.BoundaryConditions;
package InternalGains "Models for humans, maschines, light and other heat sources"
  extends Modelica.Icons.Package;
end InternalGains;


low

within AixLib.BoundaryConditions.InternalGains;
package Types
  type MachineActivity = enumeration(
      low "low",
      middle "middle",
      high "high") "Enumeration to define the machine activity";
end Types;


Partial model to build a heat source with convective and radiative component. Overview

within AixLib.BoundaryConditions.InternalGains.BaseClasses;
partial model PartialInternalGain
  "Partial model to build a heat source with convective and radiative component"
  parameter Real ratioConv(final min=0, final max=1) = 0.6
    "Ratio convective to total heat release"
  parameter Modelica.Units.SI.Emissivity emissivity(
    min=0,
    max=1) = 0.95 "Emissivity of radiative heat source surface";
  Modelica.Blocks.Interfaces.RealInput uRel(min=0, max=1) "Relative input related to max. value (might be a ratio related to number of people [-] or room area and specific heat flow [W/m2] or maximal heat flow [W]"
  Modelica.Thermal.HeatTransfer.Sources.PrescribedHeatFlow convectiveHeat(final T_ref=293.15, final alpha=0)
  Modelica.Thermal.HeatTransfer.Sources.PrescribedHeatFlow radiativeHeat(final T_ref=293.15, final alpha=0)
  AixLib.Utilities.HeatTransfer.HeatToRad radConvertor(final eps=emissivity, final use_A_in=true)
    "Adaptor for approximative longwave radiation exchange with surface area"
  Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a convHeat
    "Convective heat flow connector"
  AixLib.Utilities.Interfaces.RadPort radHeat
    "Radiative heat flow connector"
  Modelica.Blocks.Math.Gain gain
  Modelica.Blocks.Math.Gain gainSurfaces
  Modelica.Blocks.Nonlinear.Limiter limiter(final uMax=Modelica.Constants.inf, final uMin=Modelica.Constants.eps)
protected
  Modelica.Blocks.Math.MultiProduct productHeatOutput(nu=1, y(final quantity="Power", final unit="W"))
  Modelica.Blocks.Math.Gain gainConv(final k=ratioConv)
  Modelica.Blocks.Math.Gain gainRad(final k=1 - ratioConv)
equation
  connect(convectiveHeat.port,convHeat)
  connect(gainConv.y, convectiveHeat.Q_flow)
  connect(gainRad.y, radiativeHeat.Q_flow)
  connect(productHeatOutput.y, gainConv.u)
  connect(productHeatOutput.y, gainRad.u)
  connect(radiativeHeat.port, radConvertor.convPort)
  connect(radConvertor.radPort, radHeat)
  connect(uRel, gain.u)
  connect(gain.y, productHeatOutput.u[1])
  connect(gainSurfaces.y,limiter. u)
  connect(limiter.y, radConvertor.A_in)
  connect(uRel, gainSurfaces.u)
end PartialInternalGain;


Calculation of CO2 concentration within a thermal zone. This model assumes co2 as an ideal gas to calculate the density of
  co2:

within AixLib.BoundaryConditions.InternalGains.CO2;
model CO2Balance "Calculation of CO2 concentration within a thermal zone"
  parameter Modelica.Units.SI.Area areaZon "Zone area";
  parameter Real actDeg = 1.8 "Activity degree (Met units)";
  parameter Modelica.Units.SI.Volume VZon "Zone volume";
  parameter Modelica.Units.SI.MassFraction XCO2_amb=6.12157E-4
    "Massfraction of CO2 in atmosphere (equals 403ppm)";
  parameter Modelica.Units.SI.Area areaBod=1.8
    "Body surface area source SIA 2024:2015";
  parameter Modelica.Units.SI.DensityOfHeatFlowRate metOnePerSit=58
    "Metabolic rate of a relaxed seated person in Met (1 Met = 58 W/m^2)";
  parameter Real spePeo(unit="1/(m.m)") = 0.05
    "Specific persons per square metre room area";

  Modelica.Blocks.Interfaces.RealInput XCO2(final quantity="MassFraction",
      final unit="kg/kg") "Massfraction of CO2 in room in kgCO2/kgTotalAir"
  Modelica.Blocks.Interfaces.RealInput airExc(final quantity="VolumeFlowRate",
      final unit="1/h") "Total ventilation and infiltration rate in 1/h"
  Modelica.Blocks.Interfaces.RealOutput mCO2_flow(final quantity="MassFlowRate",
      final unit="kg/s") "Incoming and outgoing CO2 massflow in kg/s"
  Modelica.Blocks.Interfaces.RealInput TAir(
    final quantity="ThermodynamicTemperature",
    final unit="K",
    displayUnit="degC") "Air temperature of thermal zone"
  Modelica.Blocks.Interfaces.RealInput uRel
    "relative number of people related to max. value"
  Modelica.Blocks.Interfaces.RealOutput CO2Con(min=0, max=1000000)
    "CO2 concentration in the thermal zone in ppm"

protected
  constant Modelica.Units.SI.MolarMass MolCO2=0.04401;
  constant Modelica.Units.SI.MolarMass MolAir=0.028949;
  constant Real CalEqu=5.617*3600*1000
    "caloric equivalent in J/m^3";
  constant Real ResQuo=0.83 "respiratory quotient in m^3_CO2/ m^3_O2";
  constant Modelica.Units.SI.Pressure pAir=101325;
  constant Modelica.Units.SI.Density rhoAir=1.2041;
  Real numPeo "Number of people in the thermal zone";
  Modelica.Units.SI.VolumeFlowRate VCO2OnePer_flow
    "Pure CO2 emission of an adult person";
  Modelica.Units.SI.DensityOfHeatFlowRate metOnePerAct
    "Metabolic heat production rate considering activity degree in W/m^2";
  Modelica.Units.SI.MassFlowRate mCO2Peo_flow;
  Modelica.Units.SI.MassFlowRate mAirExc_flow
    "Massflowrate of ventilation and infiltration in kg/s";
  Modelica.Units.SI.Density rhoCO2 "CO2 density";
  Modelica.Units.SI.MassFlowRate mCO2OnePer_flow
    "Emission CO2 of one Person in kg/s";

equation

  // ideal gas equation
  rhoCO2 = MolCO2*pAir/(Modelica.Constants.R*TAir);

  // CO2 emissions of people in the zone
  metOnePerAct = metOnePerSit*actDeg;
  VCO2OnePer_flow = ResQuo*metOnePerAct*areaBod/CalEqu*TAir/273.15;
  mCO2OnePer_flow = VCO2OnePer_flow*rhoCO2;
  numPeo = spePeo*areaZon*uRel;
  mCO2Peo_flow = mCO2OnePer_flow*numPeo;

  // CO2 balance
  mAirExc_flow = airExc/3600*rhoAir*VZon;
  mCO2_flow = mAirExc_flow*(XCO2_amb - XCO2) + mCO2Peo_flow;

  // calculation of concentration in the thermal zone in ppm
  CO2Con = XCO2*(MolAir/MolCO2)*1E6;
end CO2Balance;


Package for examples of internal gains

within AixLib.BoundaryConditions.InternalGains;
package Examples "Package for examples of internal gains"
  extends Modelica.Icons.ExamplesPackage;
end Examples;


Simulation to check the human models.

within AixLib.BoundaryConditions.InternalGains.Examples.InternalGains;
model HumansSenTDep "Simulation to check the human models"
  extends Modelica.Icons.Example;
  extends AixLib.BoundaryConditions.InternalGains.Examples.InternalGains.BaseClasses.PartialHumansExample(redeclare Humans.HumanSensibleHeatTemperatureDependent humanIntGains);
equation
end HumansSenTDep;


Simulation to check the human models.

within AixLib.BoundaryConditions.InternalGains.Examples.InternalGains;
model HumansSenTIndep "Simulation to check the human models"
  extends Modelica.Icons.Example;
  extends AixLib.BoundaryConditions.InternalGains.Examples.InternalGains.BaseClasses.PartialHumansExample(redeclare Humans.HumanSensibleHeatTemperatureIndependent humanIntGains);
equation
end HumansSenTIndep;


Simulation to check the human models.

within AixLib.BoundaryConditions.InternalGains.Examples.InternalGains;
model HumansTotTDep "Simulation to check the human models"
  extends Modelica.Icons.Example;
  extends AixLib.BoundaryConditions.InternalGains.Examples.InternalGains.BaseClasses.PartialHumansExample(redeclare Humans.HumanTotalHeatTemperatureDependent humanIntGains, sumQ_flows(nu=3));
equation

  connect(humanIntGains.QLat_flow, sumQ_flows.u[3])
end HumansTotTDep;


Simulation to check the light models.

within AixLib.BoundaryConditions.InternalGains.Examples.InternalGains;
model Lights "Simulation to check the light models"
  extends Modelica.Icons.Example;
  AixLib.BoundaryConditions.InternalGains.Lights.LightsAreaSpecific lightsAreaSpecific(roomArea=20)
  AixLib.BoundaryConditions.InternalGains.Lights.LightsRelToMaxValue lightsFromMaxValue(maxHeatFlowAbsolute=100)
  Modelica.Blocks.Sources.CombiTimeTable combiTimeTable(table=[0,0; 28740,0;
        28800,1; 64800,1; 64860,0; 86400,0])
  Modelica.Thermal.HeatTransfer.Sources.FixedTemperature fixedTemp(T=293.15)
equation
  connect(combiTimeTable.y[1], lightsAreaSpecific.uRel)
  connect(combiTimeTable.y[1], lightsFromMaxValue.uRel)
  connect(lightsAreaSpecific.convHeat, fixedTemp.port)
  connect(lightsFromMaxValue.convHeat, fixedTemp.port)
  connect(lightsFromMaxValue.radHeat, fixedTemp.port)
  connect(lightsAreaSpecific.radHeat, fixedTemp.port)
end Lights;


Simulation to check the machine models.

within AixLib.BoundaryConditions.InternalGains.Examples.InternalGains;
model Machines "Simulation to check the machine models"
  extends Modelica.Icons.Example;
  AixLib.BoundaryConditions.InternalGains.Machines.MachinesDIN18599 machinesSensibleHeatDIN18599(areaSurfaceMachinesTotal=10)
  AixLib.BoundaryConditions.InternalGains.Machines.MachinesRelToMaxValue machinesSensibleHeatFromMaxValue(areaSurfaceMachinesTotal=10, maxHeatFlowAbsolute=200)
  Modelica.Blocks.Sources.CombiTimeTable combiTimeTable(table=[0,0; 28740,0;
        28800,1; 64800,1; 64860,0; 86400,0])
  Modelica.Thermal.HeatTransfer.Sources.FixedTemperature fixedTemp(T=293.15)
  AixLib.BoundaryConditions.InternalGains.Machines.MachinesAreaSpecific machinesAreaSpecific(areaSurfaceMachinesTotal=10, roomArea=20)
equation
  connect(combiTimeTable.y[1], machinesSensibleHeatDIN18599.uRel)
  connect(combiTimeTable.y[1], machinesSensibleHeatFromMaxValue.uRel)
  connect(machinesSensibleHeatDIN18599.convHeat, fixedTemp.port)
  connect(machinesSensibleHeatDIN18599.radHeat, fixedTemp.port)
  connect(machinesSensibleHeatFromMaxValue.convHeat, fixedTemp.port)
  connect(machinesSensibleHeatFromMaxValue.radHeat, fixedTemp.port)
  connect(combiTimeTable.y[1], machinesAreaSpecific.uRel)
  connect(machinesAreaSpecific.convHeat, fixedTemp.port)
  connect(machinesAreaSpecific.radHeat, fixedTemp.port)
end Machines;


dassl.

within AixLib.BoundaryConditions.InternalGains.Examples.InternalGains;
model OneOffice
  extends Modelica.Icons.Example;
  AixLib.BoundaryConditions.InternalGains.Humans.HumanSensibleHeatTemperatureDependent humanSensibleHeat(roomArea=20)
  AixLib.BoundaryConditions.InternalGains.Machines.MachinesDIN18599 machinesSensibleHeatDIN18599(nrPeople=2, areaSurfaceMachinesTotal=10)
  AixLib.BoundaryConditions.InternalGains.Lights.LightsAreaSpecific lightsAreaSpecific(roomArea=20)
  Modelica.Thermal.HeatTransfer.Sources.PrescribedTemperature RoomTemp
  Modelica.Blocks.Sources.Ramp Evolution_RoomTemp(duration = 36000, offset = 293.15, startTime = 4000, height = 0)
  Modelica.Blocks.Sources.CombiTimeTable combiTimeTable(columns = {2, 3, 4, 5}, extrapolation = Modelica.Blocks.Types.Extrapolation.Periodic, tableOnFile = false, table = [0, 0, 0.1, 0, 0; 36000, 0, 0.1, 0, 0; 36060, 1, 1, 0.3, 0.8; 72000, 1, 1, 0.3, 0.8; 72060, 0, 0.1, 0, 0; 86400, 0, 0.1, 0, 0])
  Modelica.Thermal.HeatTransfer.Sources.FixedTemperature fixedTemp(T = 293.15)
equation
  connect(RoomTemp.port, humanSensibleHeat.TRoom)
  connect(Evolution_RoomTemp.y, RoomTemp.T)
  connect(combiTimeTable.y[2], machinesSensibleHeatDIN18599.uRel)
  connect(combiTimeTable.y[3], lightsAreaSpecific.uRel)
  connect(machinesSensibleHeatDIN18599.convHeat, fixedTemp.port)
  connect(machinesSensibleHeatDIN18599.radHeat, fixedTemp.port)
  connect(lightsAreaSpecific.convHeat, fixedTemp.port)
  connect(lightsAreaSpecific.radHeat, fixedTemp.port)
  connect(combiTimeTable.y[1], humanSensibleHeat.uRel)
  connect(humanSensibleHeat.convHeat, fixedTemp.port)
  connect(humanSensibleHeat.radHeat, fixedTemp.port)
end OneOffice;


Base class with bounday conditions for humans' examples.

within AixLib.BoundaryConditions.InternalGains.Examples.InternalGains.BaseClasses;
partial model PartialHumansExample "Base class with bounday conditions for humans' examples"
  Modelica.Thermal.HeatTransfer.Sources.PrescribedTemperature varTempRoom
  Modelica.Blocks.Sources.CombiTimeTable combiTimeTable(table=[0,0; 28740,0; 28800,1; 43200,1; 43260,0; 46800,0; 46860,1; 64800,1; 64860,0; 86400,0])
  Modelica.Blocks.Sources.Sine sine(
    amplitude=2,
    f=1/(24*3600),
    offset=273.15 + 20,
    phase(displayUnit="deg") = -3.1415926535898)
  Modelica.Thermal.HeatTransfer.Sensors.HeatFlowSensor heatFlowSensorConv
  Modelica.Thermal.HeatTransfer.Sources.FixedTemperature fixedTemp(T=293.15)
  Modelica.Thermal.HeatTransfer.Sensors.HeatFlowSensor heatFlowSensorRad
  Modelica.Blocks.Math.MultiSum sumQ_flows(nu=2)
  replaceable AixLib.BoundaryConditions.InternalGains.Humans.BaseClasses.PartialHuman humanIntGains(roomArea=20) constrainedby AixLib.BoundaryConditions.InternalGains.Humans.BaseClasses.PartialHuman(roomArea=20)
  Modelica.Blocks.Interfaces.RealOutput HeatOut(quantity = "Power", unit = "W")
equation
  connect(sine.y,varTempRoom. T)
  connect(heatFlowSensorConv.port_b,fixedTemp. port)
  connect(fixedTemp.port,heatFlowSensorRad. port_b)
  connect(heatFlowSensorConv.Q_flow,sumQ_flows. u[1])
  connect(heatFlowSensorRad.Q_flow,sumQ_flows. u[2])
  connect(sumQ_flows.y,HeatOut)
  connect(varTempRoom.port, humanIntGains.TRoom)
  connect(combiTimeTable.y[1], humanIntGains.uRel)
  connect(heatFlowSensorConv.port_a, humanIntGains.convHeat)
  connect(heatFlowSensorRad.port_a, humanIntGains.radHeat)
end PartialHumansExample;


Model for sensible heat output of humans to environment dependent on the room temperature. Overview

within AixLib.BoundaryConditions.InternalGains.Humans;
model HumanSensibleHeatTemperatureDependent
  "Model for sensible heat output of humans to environment dependent on the room temperature"
  extends BaseClasses.PartialHuman(productHeatOutput(nu=2));
  parameter Real activityDegree=1.0 "activity degree of persons in room in met";
  BaseClasses.TemperatureDependentHeatOutputSIA2024
    temperatureDependentHeatOutputSIA2024_1(activityDegree=activityDegree)
    "Temperature dependent heat output per person"
equation
  connect(TRoom,temperatureSensor. port)
  connect(temperatureSensor.T,to_degC. u)
  connect(to_degC.y, temperatureDependentHeatOutputSIA2024_1.T)
  connect(temperatureDependentHeatOutputSIA2024_1.heatOutput, productHeatOutput.u[2])
end HumanSensibleHeatTemperatureDependent;


Model for sensible heat output of humans not depending on the room temperature. Overview

within AixLib.BoundaryConditions.InternalGains.Humans;
model HumanSensibleHeatTemperatureIndependent
  "Model for sensible heat output of humans not depending on the room temperature"
  extends BaseClasses.PartialHuman(productHeatOutput(nu=2));

  Modelica.Blocks.Sources.RealExpression specificHeatOutput(
    y=specificHeatPerPerson)
    "Specific heat output per person"
equation
  connect(specificHeatOutput.y, productHeatOutput.u[2])
end HumanSensibleHeatTemperatureIndependent;


Model for total heat and moisture output of humans depending on the room temperature. Overview

within AixLib.BoundaryConditions.InternalGains.Humans;
model HumanTotalHeatTemperatureDependent
  "Model for total heat and moisture output of humans depending on the room temperature"
  extends HumanSensibleHeatTemperatureDependent;

  BaseClasses.TemperatureDependentMoistureOutputSIA2024
    temperatureDependentMoistuerOutputSIA2024_1(activityDegree=activityDegree)
    "Temperature dependent moisture output per person"
  Modelica.Blocks.Interfaces.RealOutput QLat_flow(final quantity="Power", final unit="W")
    "latent heat of moisture gains"
  Modelica.Blocks.Math.Gain toKgPerSecond(k=1/(3600*1000))
    "Converter from g/h to kg/s"
  Modelica.Blocks.Math.MultiProduct productMoistureOutput(nu=2)
    "Product of moisture output per person and number of people"
  Modelica.Blocks.Math.Product latentHeat
    "Converter from mass flow moisture to latent heat"
  Modelica.Blocks.Sources.RealExpression specificLatentHeat(y=h_fg)
    "Latent heat per kg moisture"
protected
  constant Modelica.Units.SI.SpecificHeatCapacity cp_steam=AixLib.Utilities.Psychrometrics.Constants.cpSte
    "Specific heat capacity of steam";
  constant Modelica.Units.SI.SpecificEnthalpy EnthalpyOfEvaporation=AixLib.Utilities.Psychrometrics.Constants.h_fg
    "Enthalpy of evaporation";
  constant Modelica.Units.SI.SpecificEnergy h_fg=
      Media.Air.enthalpyOfCondensingGas(273.15 + 37)
    "Latent heat of water vapor";
equation
  connect(to_degC.y, temperatureDependentMoistuerOutputSIA2024_1.T)
  connect(productMoistureOutput.y, toKgPerSecond.u)
  connect(toKgPerSecond.y, latentHeat.u1)
  connect(specificLatentHeat.y, latentHeat.u2)
  connect(latentHeat.y, QLat_flow)
  connect(temperatureDependentMoistuerOutputSIA2024_1.moistOutput, productMoistureOutput.u[1])
  connect(gain.y, productMoistureOutput.u[2])
end HumanTotalHeatTemperatureDependent;


Partial model for internal gains of humans. Overview

within AixLib.BoundaryConditions.InternalGains.Humans.BaseClasses;
partial model PartialHuman "Partial model for internal gains of humans"
  extends AixLib.BoundaryConditions.InternalGains.BaseClasses.PartialInternalGain(
    emissivity=0.98,
    gain(final k=specificPersons*roomArea),
    gainSurfaces(final k=specificPersons*roomArea*surfaceAreaOnePersion));
  //Internal Gains People
  parameter Real specificPersons(unit="1/(m.m)") = 0.05 "Specific persons per square metre room area"
  parameter Modelica.Units.SI.Area roomArea "Area of room"
  parameter Modelica.Units.SI.HeatFlowRate specificHeatPerPerson=70
    "Specific heat output per person";

  Modelica.Thermal.HeatTransfer.Sensors.TemperatureSensor temperatureSensor
    "Room temperature sensor"
  Modelica.Blocks.Math.UnitConversions.To_degC to_degC
    "Converter from Kelvin to Celsius"
  Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a TRoom
    "Air temperature in room"
protected
  parameter Modelica.Units.SI.Area surfaceAreaOnePersion=2
    "Human Surface (per person)";
  parameter Modelica.Units.SI.HeatFlowRate heatPerPerson=70
    "Average Heat Flow per person taken from DIN V 18599-10"
equation
  connect(TRoom,temperatureSensor. port)
  connect(temperatureSensor.T,to_degC. u)
end PartialHuman;


Model for temperature dependent heat output based on formulas of SIA 2024. Overview

within AixLib.BoundaryConditions.InternalGains.Humans.BaseClasses;
model TemperatureDependentHeatOutputSIA2024
  "Model for temperature dependent heat output based on formulas of SIA 2024"

  parameter Real activityDegree=1.0 "Activity degree of persons in room in met";

  Modelica.Blocks.Interfaces.RealInput T
    "Room temperature used for heat output calculation"

  Modelica.Blocks.Interfaces.RealOutput heatOutput
protected
  constant Real HeatPerMet(unit="W/(m.m)") = 58 "Heat per m² for 1 met";
  constant Modelica.Units.SI.Area BodySurface=1.8 "Body surface of one person";
  constant Real TemperatureCoefficient(unit="1/K") = 0.025
    "Parameter for temperature dependency";
  constant Modelica.Units.SI.HeatFlowRate MinimumHeat=35 "Minimum heat output";
equation

  heatOutput =max(0, (0.865 - (TemperatureCoefficient*T))*(activityDegree*
    HeatPerMet*BodySurface) + MinimumHeat);
end TemperatureDependentHeatOutputSIA2024;


Model for temperature dependent moisture output based on formulas of SIA 2024. Overview

within AixLib.BoundaryConditions.InternalGains.Humans.BaseClasses;
model TemperatureDependentMoistureOutputSIA2024
  "Model for temperature dependent moisture output based on formulas of SIA 2024"

  parameter Real activityDegree=1.0 "Activity degree of persons in room in met";

  Modelica.Blocks.Interfaces.RealInput T
    "Room temperature used for heat output calculation"

  Modelica.Blocks.Interfaces.RealOutput moistOutput "Moisture output in g/h"
  TemperatureDependentHeatOutputSIA2024 temperatureDependentHeatOutput_SIA2024(activityDegree=activityDegree)
    "Temperature dependent heat output"
protected
  constant Real HeatPerMet(unit="W/(m.m)") = 58 "Heat per m² for 1 met";
  constant Modelica.Units.SI.Area BodySurface=1.8 "Body surface of one person";
  constant Real MoistGain(unit="g/h") = 10/7 "Gain for moisture output";
equation

  moistOutput = max(0,MoistGain*((activityDegree*HeatPerMet*BodySurface)-temperatureDependentHeatOutput_SIA2024.heatOutput));

  connect(T, temperatureDependentHeatOutput_SIA2024.T)
end TemperatureDependentMoistureOutputSIA2024;


Heat flow due to lighting relative to room area and specific lighting power.

within AixLib.BoundaryConditions.InternalGains.Lights;
model LightsAreaSpecific "Heat flow due to lighting relative to room area and specific lighting power"
  extends BaseClasses.PartialInternalGain(
    emissivity=0.98,
    ratioConv=0.5,
    radConvertor(final A=max(Modelica.Constants.eps, areaSurfaceLightsTotal)),
    gain(final k=roomArea*lightingPowerRoomAreaSpecific),
    gainSurfaces(final k=areaSurfaceLightsTotal));
  parameter Modelica.Units.SI.Area roomArea "Area of room"
  parameter Real lightingPowerRoomAreaSpecific=10 "Lighting power per square meter room"
  parameter Modelica.Units.SI.Area areaSurfaceLightsTotal=0.01*roomArea
    "Surface of all lights in the room";
end LightsAreaSpecific;


Multiplies relative input with max value (heat flow due to lighting in W).

within AixLib.BoundaryConditions.InternalGains.Lights;
model LightsRelToMaxValue "Multiplies relative input with max value (heat flow due to lighting in W)"
  extends BaseClasses.PartialInternalGain(emissivity=0.98, gainSurfaces(final k=areaSurfaceLightsTotal),
    gain(final k=maxHeatFlowAbsolute));

  parameter Modelica.Units.SI.HeatFlowRate maxHeatFlowAbsolute
    "Maximal absolute heat flow due to lighting";
  parameter Modelica.Units.SI.Area areaSurfaceLightsTotal=0.001*
      maxHeatFlowAbsolute "Surface of all lights in the room";

equation

  connect(radConvertor.radPort, radHeat)
  connect(radiativeHeat.port, radConvertor.convPort)
end LightsRelToMaxValue;


<html><p>
  Simple model for internal gains through lights.
</p>
</html>

within AixLib.BoundaryConditions.InternalGains;
package Lights
  extends Modelica.Icons.Package;
end Lights;


Heat flow due to machines relative to room area and specific power.

within AixLib.BoundaryConditions.InternalGains.Machines;
model MachinesAreaSpecific "Heat flow due to machines relative to room area and specific power"
  extends BaseClasses.PartialInternalGain(
    emissivity=0.98,
    gain(final k=intGainsMachinesRoomAreaSpecific*roomArea),
    gainSurfaces(final k=areaSurfaceMachinesTotal));

  parameter Modelica.Units.SI.HeatFlux intGainsMachinesRoomAreaSpecific=1.0
    "Heat flow from machines per square meter room"
  parameter Modelica.Units.SI.Area areaSurfaceMachinesTotal=max(1e-4,
      surfaceMachine*intGainsMachinesRoomAreaSpecific*(1/HeatPerMachine)*
      roomArea)
    "Total surface area of all machines (radiative heat source) (for a room in a single-family hous e.g. 2 m2)";
  parameter Modelica.Units.SI.Area roomArea "Area of room"

protected
  parameter Modelica.Units.SI.HeatFlowRate HeatPerMachine=100
    "Average Heat Flow per machine taken from DIN V 18599-10"
  parameter Modelica.Units.SI.Area surfaceMachine=2.0
    "Surface area of one machine";
end MachinesAreaSpecific;


Heat flow due to machines based on DIN 18599 (number of people and activity type of machines).

within AixLib.BoundaryConditions.InternalGains.Machines;
model MachinesDIN18599 "Heat flow due to machines based on DIN 18599 (number of people and activity type of machines)"
  extends BaseClasses.PartialInternalGain(
    emissivity=0.98,
    productHeatOutput(nu=2),
    gain(final k=nrPeople),
    gainSurfaces(final k=areaSurfaceMachinesTotal));

  parameter AixLib.BoundaryConditions.InternalGains.Types.MachineActivity activityType=AixLib.BoundaryConditions.InternalGains.Types.MachineActivity.middle "Machine activity"
  parameter Real nrPeople=1.0 "Number of people with machines"
  parameter Modelica.Units.SI.Area areaSurfaceMachinesTotal=max(1e-4,
      surfaceMachine*nrPeople)
    "Total surface area of all machines (radiative heat source) (for a room in a single-family hous e.g. 2 m2)";

protected
  parameter Modelica.Units.SI.Area surfaceMachine=2.0
    "Surface area of one machine";
  Modelica.Blocks.Tables.CombiTable1Dv tableHeatOutput(
    smoothness=Modelica.Blocks.Types.Smoothness.LinearSegments,
    tableOnFile=false,
    table=[1,50; 2,100; 3,150],
    columns={2})
  Modelica.Blocks.Sources.Constant activity(k=if activityType==AixLib.BoundaryConditions.InternalGains.Types.MachineActivity.low then 1
  elseif activityType==AixLib.BoundaryConditions.InternalGains.Types.MachineActivity.middle then 2
  else 3)
equation
  connect(activity.y, tableHeatOutput.u[1])
  connect(tableHeatOutput.y[1], productHeatOutput.u[2])
end MachinesDIN18599;


Multiplies relative input with max value (heat flow due to machines in W).

within AixLib.BoundaryConditions.InternalGains.Machines;
model MachinesRelToMaxValue "Multiplies relative input with max value (heat flow due to machines in W)"
  extends BaseClasses.PartialInternalGain(
    emissivity=0.98,
    gainSurfaces(final k=areaSurfaceMachinesTotal),
    gain(final k=maxHeatFlowAbsolute));
  parameter Modelica.Units.SI.Area areaSurfaceMachinesTotal=0.02*
      maxHeatFlowAbsolute
    "Total surface area of all machines (radiative heat source) (for a room in a single-family hous e.g. 2 m2)";
  parameter Modelica.Units.SI.HeatFlowRate maxHeatFlowAbsolute
    "Maximal absolute heat flow of machines";

equation
end MachinesRelToMaxValue;


Model for moisture gains that are produced by plants, cooking, etc.. Overview

within AixLib.BoundaryConditions.InternalGains.Moisture;
model MoistureGains
  "Model for moisture gains that are produced by plants, cooking, etc."

  parameter Real specificMoistureProduction(unit="g/(h.m.m)") = 0.5
    "Specific moisture production without persons in the room due to plants, cooking, showering, etc.";
  parameter Modelica.Units.SI.Area roomArea=20 "Area of room";

  Modelica.Blocks.Interfaces.RealOutput QLat_flow
    "Latent heat of moisture gain"
  Modelica.Blocks.Sources.Constant moistureGain(k=specificMoistureProduction)
    "Specific moisture production"
  Modelica.Blocks.Math.Gain squareMetre(k=roomArea) "Room area"
  Modelica.Blocks.Math.Gain toKgPerSeconds(k=1/(1000*3600))
    "Converter from g/h to kg/s"
  Modelica.Blocks.Math.Product toLatentHeat
    "Converter from kg/s moisture to latent heat flow"
  Modelica.Blocks.Sources.RealExpression specificLatentHeat(y=h_fg)
  "Specific latent heat of moisture"
protected
  constant Modelica.Units.SI.SpecificEnergy h_fg=
      Media.Air.enthalpyOfCondensingGas(273.15 + 37)
    "Latent heat of water vapor";
equation
  connect(moistureGain.y, squareMetre.u)
  connect(squareMetre.y, toKgPerSeconds.u)
  connect(toKgPerSeconds.y, toLatentHeat.u1)
  connect(specificLatentHeat.y, toLatentHeat.u2)
  connect(toLatentHeat.y, QLat_flow)
end MoistureGains;


Calculate black body sky temperature. This component computes the black-body sky temperature.

within AixLib.BoundaryConditions.SkyTemperature;
block BlackBody "Calculate black body sky temperature"
  extends Modelica.Blocks.Icons.Block;

  parameter AixLib.BoundaryConditions.Types.SkyTemperatureCalculation calTSky=
    AixLib.BoundaryConditions.Types.SkyTemperatureCalculation.TemperaturesAndSkyCover
    "Computation of black-body sky temperature"
  Modelica.Blocks.Interfaces.RealInput TDryBul(
    final quantity="ThermodynamicTemperature",
    final unit="K",
    displayUnit="degC") "Dry bulb temperature at ground level"
  Modelica.Blocks.Interfaces.RealInput TDewPoi(
    final quantity="ThermodynamicTemperature",
    final unit="K",
    displayUnit="degC") "Dew point temperature"
  Modelica.Blocks.Interfaces.RealInput nOpa( min=0, max=1, unit="1")
    "Opaque sky cover [0, 1]"
  Modelica.Blocks.Interfaces.RealOutput TBlaSky(
    final quantity="ThermodynamicTemperature",
    displayUnit="degC",
    final unit="K") "Black-body sky temperature"
  Modelica.Blocks.Interfaces.RealInput HHorIR(
    unit="W/m2",
    min=0,
    nominal=100) "Horizontal infrared irradiation"
protected
  Modelica.Units.SI.Temperature TDewPoiK "Dewpoint temperature";
  Modelica.Units.SI.Emissivity epsSky "Black-body absorptivity of sky";
  Real nOpa10(min=0, max=10) "Opaque sky cover in [0, 10]";
equation
  if calTSky == AixLib.BoundaryConditions.Types.SkyTemperatureCalculation.TemperaturesAndSkyCover then
    TDewPoiK =  AixLib.Utilities.Math.Functions.smoothMin(TDryBul, TDewPoi, 0.1);
    nOpa10 =  10*nOpa "Input nOpa is scaled to [0,1] instead of [0,10]";
    epsSky =  (0.787 + 0.764*Modelica.Math.log(-TDewPoiK/Modelica.Constants.T_zero))*(1 + 0.0224*nOpa10 -
      0.0035*(nOpa10^2) + 0.00028*(nOpa10^3));
    TBlaSky =  TDryBul*(epsSky^0.25);
  else
    TDewPoiK =  273.15;
    nOpa10   =  0.0;
    epsSky   =  0.0;
    TBlaSky  =  (HHorIR/Modelica.Constants.sigma)^0.25;
  end if;
end BlackBody;


within AixLib.BoundaryConditions;
package SkyTemperature "Package with models to compute the sky temperature"
  extends Modelica.Icons.VariantsPackage;
end SkyTemperature;


Test model for black body sky temperature. This example computes the black-body sky temperature
for Chicago.

within AixLib.BoundaryConditions.SkyTemperature.Examples;
model BlackBody "Test model for black body sky temperature"
  extends Modelica.Icons.Example;

  AixLib.BoundaryConditions.WeatherData.ReaderTMY3 weaDat(filNam=
        Modelica.Utilities.Files.loadResource("modelica://AixLib/Resources/weatherdata/USA_IL_Chicago-OHare.Intl.AP.725300_TMY3.mos"))
  AixLib.BoundaryConditions.SkyTemperature.BlackBody TBlaSky
    "Black body sky temperature computed from temperature and sky cover"
  AixLib.BoundaryConditions.WeatherData.Bus weaBus "Weather data bus"
  AixLib.BoundaryConditions.SkyTemperature.BlackBody TBlaSkyIrr(calTSky=
        AixLib.BoundaryConditions.Types.SkyTemperatureCalculation.HorizontalRadiation)
    "Black body sky temperature computation compued from horizontal infrared radiation"
equation

  connect(weaBus, weaDat.weaBus)
  connect(weaBus.TDewPoi, TBlaSky.TDewPoi)
  connect(weaBus.nOpa, TBlaSky.nOpa)

  connect(weaBus.TDryBul, TBlaSky.TDryBul)
  connect(weaBus.HHorIR, TBlaSky.HHorIR)
  connect(weaBus.TDewPoi, TBlaSkyIrr.TDewPoi)
  connect(weaBus.nOpa, TBlaSkyIrr.nOpa)
  connect(weaBus.TDryBul, TBlaSkyIrr.TDryBul)
  connect(weaBus.HHorIR, TBlaSkyIrr.HHorIR)
end BlackBody;


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


Solar incidence angle on a tilted surface. This component computes the solar incidence angle on a tilted surface.
For a definition of the parameters, see the User's Guide
AixLib.BoundaryConditions.UsersGuide.

within AixLib.BoundaryConditions.SolarGeometry;
block IncidenceAngle "Solar incidence angle on a tilted surface"
  extends Modelica.Blocks.Icons.Block;
  parameter Modelica.Units.SI.Angle azi "Surface azimuth";
  parameter Modelica.Units.SI.Angle til "Surface tilt";

  Modelica.Blocks.Interfaces.RealOutput y(
    final quantity="Angle",
    final unit="rad",
    displayUnit="deg") "Incidence angle"
  WeatherData.Bus weaBus "Weather data"
protected
  AixLib.BoundaryConditions.SolarGeometry.BaseClasses.Declination decAng
    "Declination angle"
  AixLib.BoundaryConditions.SolarGeometry.BaseClasses.SolarHourAngle
    solHouAng "Solar hour angle"
  AixLib.BoundaryConditions.SolarGeometry.BaseClasses.IncidenceAngle incAng(
    final azi=azi,
    final til=til) "Incidence angle"
equation
  connect(incAng.incAng, y)
  connect(decAng.decAng, incAng.decAng)
  connect(solHouAng.solHouAng, incAng.solHouAng)
  connect(weaBus.cloTim, decAng.nDay)
  connect(weaBus.solTim, solHouAng.solTim)
  connect(weaBus.lat, incAng.lat)
end IncidenceAngle;


within AixLib.BoundaryConditions;
package SolarGeometry "Package with models to compute solar geometry"
  extends Modelica.Icons.VariantsPackage;
end SolarGeometry;


Zenith angle. This component computes the zenith angle,
which is the angle between the earth surface normal and the sun beam.
For a definition of the parameters, see the User's Guide

AixLib.BoundaryConditions.UsersGuide.

within AixLib.BoundaryConditions.SolarGeometry;
block ZenithAngle "Zenith angle"
  extends Modelica.Blocks.Icons.Block;
  Modelica.Blocks.Interfaces.RealOutput y(
    final quantity="Angle",
    final unit="rad",
    displayUnit="deg") "Zenith angle"
  WeatherData.Bus weaBus "Weather data"
protected
   AixLib.BoundaryConditions.SolarGeometry.BaseClasses.ZenithAngle zen
equation
  connect(zen.zen, y)
  connect(weaBus.solDec, zen.decAng)
  connect(weaBus.solHouAng, zen.solHouAng)
  connect(weaBus.lat, zen.lat)
end ZenithAngle;


Solar altitude angle. This block computes the altitude angle of the sun with respect to a horizontal surface.
The altitude angle is the angle between the sun ray and the projection of the ray
on a horizontal surface.
It is the complementory angle to the zenith angle.

within AixLib.BoundaryConditions.SolarGeometry.BaseClasses;
block AltitudeAngle "Solar altitude angle"
  extends Modelica.Blocks.Icons.Block;
  Modelica.Blocks.Interfaces.RealInput zen(quantity="Angle", unit="rad")
    "Zenith angle"
  Modelica.Blocks.Interfaces.RealOutput alt(
    final quantity="Angle",
    final unit="rad",
    displayUnit="deg") "Solar altitude angle"
equation
  alt = (Modelica.Constants.pi/2) - zen;
end AltitudeAngle;


Declination angle. This component computes the solar declination, which is
the angle between the equatorial plane and the solar beam.
The input signal nDay is the one-based number of the day, but in seconds.
Hence, during January 1, we should have nDay = 86400 seconds.
Since the effect of using a continuous number rather than an integer is small,
we approximate this so that nDay = 0 at the start of January 1,
and nDay = 86400 at the end of January 1.

within AixLib.BoundaryConditions.SolarGeometry.BaseClasses;
block Declination "Declination angle"
  extends AixLib.BoundaryConditions.WeatherData.BaseClasses.PartialConvertTime;
  Modelica.Blocks.Interfaces.RealInput nDay(quantity="Time", unit="s")
    "Day number with units of seconds"
  Modelica.Blocks.Interfaces.RealOutput decAng(
    final quantity="Angle",
    final unit="rad",
    displayUnit="deg") "Solar declination angle"
protected
  constant Real k1 = sin(23.45*2*Modelica.Constants.pi/360) "Constant";
  constant Real k2 = 2*Modelica.Constants.pi/365.25 "Constant";
equation
  modTimAux = nDay;
  decAng = Modelica.Math.asin(-k1 * Modelica.Math.cos((calTimAux/86400 + 10)*k2))
    "(A4.5)";
end Declination;


The solar incidence angle on a tilted surface. This component computes the solar incidence angle on a tilted surface using the solar hour angle and the declination angle as input.

within AixLib.BoundaryConditions.SolarGeometry.BaseClasses;
block IncidenceAngle "The solar incidence angle on a tilted surface"
  extends Modelica.Blocks.Icons.Block;
  parameter Modelica.Units.SI.Angle azi(displayUnit="deg")
    "Surface azimuth. azi=-90 degree if surface outward unit normal points toward east; azi=0 if it points toward south";
  parameter Modelica.Units.SI.Angle til(displayUnit="deg")
    "Surface tilt. til=90 degree for walls; til=0 for ceilings; til=180 for roof";
  Modelica.Blocks.Interfaces.RealInput solHouAng(quantity="Angle", unit="rad")
    "Solar hour angle"
  Modelica.Blocks.Interfaces.RealInput decAng(quantity="Angle", unit="rad")
    "Declination"
  Modelica.Blocks.Interfaces.RealOutput incAng(
    final quantity="Angle",
    final unit="rad",
    displayUnit="deg") "Incidence angle on a tilted surface"
  Modelica.Blocks.Interfaces.RealInput lat(quantity="Angle",
    unit="rad",
    displayUnit="deg")
    "Latitude"
protected
  Real dec_c=Modelica.Math.cos(decAng) "Cosine of declination angle";
  Real dec_s=Modelica.Math.sin(decAng) "Sine of declination angle";
  Real sol_c=Modelica.Math.cos(solHouAng) "Cosine of solar hour angle";
  Real sol_s=Modelica.Math.sin(solHouAng) "Sine of solar hour angle";
  Real lat_c=Modelica.Math.cos(lat) "Cosine of latitude";
  Real lat_s=Modelica.Math.sin(lat) "Sine of latitude";
equation
  incAng = Modelica.Math.acos(Modelica.Math.cos(til)*(dec_c*sol_c*lat_c + dec_s
    *lat_s) + Modelica.Math.sin(til)*(Modelica.Math.sin(azi)*dec_c*sol_s +
    Modelica.Math.cos(azi)*(dec_c*sol_c*lat_s - dec_s*lat_c))) "(A.4.13)";
end IncidenceAngle;


within AixLib.BoundaryConditions.SolarGeometry;
package BaseClasses "Package with base classes for AixLib.BoundaryConditions.SolarGeometry"
  extends Modelica.Icons.BasesPackage;
end BaseClasses;


Solar azimuth. This component computes the solar azimuth angle.

within AixLib.BoundaryConditions.SolarGeometry.BaseClasses;
block SolarAzimuth "Solar azimuth"
  extends Modelica.Blocks.Icons.Block;
  Modelica.Blocks.Interfaces.RealInput zen(quantity="Angle", unit="rad")
    "Zenith angle"
  Modelica.Blocks.Interfaces.RealInput solTim(quantity="Time", unit="s")
    "Solar time"
  Modelica.Blocks.Interfaces.RealInput lat(quantity="Angle", unit="rad")
    "Latitude"
  Modelica.Blocks.Interfaces.RealOutput solAzi(
    final quantity="Angle",
    final unit="rad",
    displayUnit="deg") "Solar Azimuth"
  Modelica.Blocks.Interfaces.RealInput decAng(quantity="Angle", unit="rad")
    "Declination angle"

protected
  Real arg "cos(solAzi) after data validity check";
  Real tmp "cos(solAzi) before data validity check";
  Real solAziTem "Temporary variable for solar azimuth";

  constant Modelica.Units.SI.Time day=86400 "Number of seconds in a day";
  constant Modelica.Units.SI.Angle polarCircle=1.1617
    "Latitude of polar circle (66 degree 33 min 44 sec)";
  Boolean outsidePolarCircle = lat < polarCircle and lat > -polarCircle
    "Flag, true if latitude is outside polar region";
equation
  tmp = (Modelica.Math.sin(lat)*Modelica.Math.cos(zen) - Modelica.Math.sin(
    decAng))/(Modelica.Math.cos(lat)*Modelica.Math.sin(zen));
  arg = min(1.0, max(-1.0, tmp));

  solAziTem =  Modelica.Math.acos(arg); // Solar azimuth (A4.9a and b) as a positive number

  // If outside the polar circle, the only non-differentiability is at night when the sun is set.
  // Hence, we use noEvent.
  // If inside the polar circle, there is a jump at (solar-)midnight when the sun can
  // be above the horizon. Hence, we do not use noEvent(...)
  // Written as one line with functions so that lat does not become structural parameter with JModelica.org
  solAzi = if outsidePolarCircle then solarAzimuthNoEvent(solAziTem, solTim, day) else solarAzimuthWithEvent(solAziTem, solTim, day);
end SolarAzimuth;


Solar hour angle. This component computes the solar hour angle,
which is defined as the angle between the circle
that passes through an observer, the north pole and the south pole,
and the circle that passes through the sun, the north and the south pole.

within AixLib.BoundaryConditions.SolarGeometry.BaseClasses;
block SolarHourAngle "Solar hour angle"
  extends Modelica.Blocks.Icons.Block;
  Modelica.Blocks.Interfaces.RealInput solTim(quantity="Time", unit="s")
    "Solar time"
  Modelica.Blocks.Interfaces.RealOutput solHouAng(
    final quantity="Angle",
    final unit="rad",
    displayUnit="deg") "Solar hour angle"
equation
  solHouAng = (solTim/3600 - 12)*2*Modelica.Constants.pi/24
    "Our unit is s instead of h in (A4.6)";
end SolarHourAngle;


Angle measured in a horizontal plane between the projection of the sun's rays and the normal to a vertical surface. This block computes the wall solar azimuth angle.
It is the angle between the projection of the sun ray on a horizontal surface
and the line perpendicular to the wall. The value of this angle varies from 0 to 180 degrees.
In the northern hemisphere at solar noon, the value of the wall solar azimuth angle is zero if the wall is facing south.

within AixLib.BoundaryConditions.SolarGeometry.BaseClasses;
block WallSolarAzimuth
  "Angle measured in a horizontal plane between the projection of the sun's rays and the normal to a vertical surface"
  extends Modelica.Blocks.Icons.Block;

  Modelica.Blocks.Interfaces.RealInput incAng(quantity="Angle",
                                              unit="rad",
                                              displayUnit="rad")
    "Solar incidence angle"
  Modelica.Blocks.Interfaces.RealInput alt(quantity="Angle",
                                         unit="rad",
                                         displayUnit="rad")
    "Solar altitude angle (angle between sun ray and horizontal surface)"
  Modelica.Blocks.Interfaces.RealOutput verAzi(
    final quantity="Angle",
    final unit="rad",
    displayUnit="deg")
    "Angle between projection of sun's rays and normal to vertical surface"
protected
  constant Modelica.Units.SI.Angle delta=1*Modelica.Constants.pi/180
    "Small angle";
  constant Modelica.Units.SI.Angle ninety=Modelica.Constants.pi/2 - delta
    "+89 degree";
  constant Real deltaX = 1E-4 "Small number used for smoothing";
  Real alt_c "Cosine of altitude, bounded away from zero";
  Real rat "Ratio of cosines";
equation
  alt_c=Modelica.Math.cos(AixLib.Utilities.Math.Functions.smoothLimit(
        x=alt, l=-ninety, u=ninety, deltaX=delta));
  rat = Modelica.Math.cos(incAng)/alt_c;
  // Due to the smoothLimit, rat can be about 1E-3 greater than 1 or smaller than -1.
  // Hence, below we use another call to smoothLimit to ensure that the argument of
  // acos(.) is inside the interval [-1, 1].
  verAzi=Modelica.Math.acos(
       AixLib.Utilities.Math.Functions.smoothLimit(x=rat, l=-1+deltaX, u=1-deltaX, deltaX=deltaX/10));
end WallSolarAzimuth;


Zenith angle. This component computes the zenith angle, which is the angle between the earth surface normal and the sun's beam.
Input are the solar hour angle and the declination angle.

within AixLib.BoundaryConditions.SolarGeometry.BaseClasses;
block ZenithAngle "Zenith angle"
  extends Modelica.Blocks.Icons.Block;
  Modelica.Blocks.Interfaces.RealInput solHouAng(quantity="Angle", unit="rad")
    "Solar hour angle"
  Modelica.Blocks.Interfaces.RealInput decAng(quantity="Angle", unit="rad")
    "Solar declination angle"
  Modelica.Blocks.Interfaces.RealOutput zen(
    final quantity="Angle",
    final unit="rad",
    displayUnit="deg") "Zenith angle"
  Modelica.Blocks.Interfaces.RealInput lat(
    quantity="Angle",
    unit="rad",
    displayUnit="deg") "Latitude"
equation
  zen =  Modelica.Math.acos(Modelica.Math.cos(lat)*Modelica.Math.cos(decAng)*
    Modelica.Math.cos(solHouAng) + Modelica.Math.sin(lat)*Modelica.Math.sin(
    decAng)) "(A4.8)";
end ZenithAngle;


Test model for altitude angle. This example calculates the altitude angle of the sun at a given time.
The altitude angle is the angle between the sun ray and the projection of the ray on a horizontal surface.

within AixLib.BoundaryConditions.SolarGeometry.BaseClasses.Examples;
model AltitudeAngle "Test model for altitude angle"
  extends Modelica.Icons.Example;
  AixLib.BoundaryConditions.SolarGeometry.BaseClasses.ZenithAngle zen(lat=
        0.73268921998722) "Zenith angle"
  AixLib.BoundaryConditions.SolarGeometry.BaseClasses.Declination decAng
    "Declination angle"
  AixLib.BoundaryConditions.SolarGeometry.BaseClasses.SolarHourAngle
    solHouAng "Solar hour angle"
  AixLib.BoundaryConditions.WeatherData.ReaderTMY3 weaDat(filNam=Modelica.Utilities.Files.loadResource("modelica://AixLib/Resources/weatherdata/USA_IL_Chicago-OHare.Intl.AP.725300_TMY3.mos"))
    "Weather data"
  AixLib.BoundaryConditions.WeatherData.Bus weaBus "Weather bus"
  AixLib.BoundaryConditions.SolarGeometry.BaseClasses.AltitudeAngle altAng
    "Altitude angle: Angle between Sun ray and horizontal surface)"
equation
  connect(decAng.decAng, zen.decAng)
  connect(solHouAng.solHouAng, zen.solHouAng)
  connect(weaDat.weaBus, weaBus)
  connect(weaBus.cloTim, decAng.nDay)
  connect(weaBus.solTim, solHouAng.solTim)
  connect(zen.zen, altAng.zen)
end AltitudeAngle;