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;


Test model for declination. This model validates the computation of the solar declination, which is the angle between the equatorial plane and the solar beam. The time table solDecNOAA outputs the solar declination according to the computation of the National Oceanic and Atmospheric Administration (NOAA), using their yearly calculator from http://www.esrl.noaa.gov/gmd/grad/solcalc/calcdetails.html. The values differ slightly because the equation in AixLib.BoundaryConditions.SolarGeometry.BaseClasses.Declination is an approximation.

within AixLib.BoundaryConditions.SolarGeometry.BaseClasses.Examples;
model Declination "Test model for declination"
  extends Modelica.Icons.Example;
  AixLib.BoundaryConditions.SolarGeometry.BaseClasses.Declination decAng
    "Declination angle"
  AixLib.Utilities.Time.ModelTime modTim "Model time"

  Modelica.Blocks.Sources.TimeTable solDecNOAA(table=[
       0, -0.4007544;
 2678400, -0.2960882;
 5097600, -0.1292836;
 7776000,  0.0824143;
10368000,  0.2656267;
13046400,  0.3860123;
15638400,  0.4027150;
18316800,  0.3123199;
20995200,  0.1414929;
23587200, -0.0587907;
26265600, -0.2544026;
28857600, -0.3817216;
28944000, -0.3843185;
31536000, -0.4010977], y(unit="rad")) "Solar declination according to NOAA"
equation
  connect(modTim.y, decAng.nDay)
end Declination;


Test model for incidence angle. This example computes the solar incidence angle on a tilted surface.
This model is also part of more extensive tests that run the
model for different orientations. These tests are at

AixLib.BoundaryConditions.SolarGeometry.Examples.IncidenceAngle.

within AixLib.BoundaryConditions.SolarGeometry.BaseClasses.Examples;
model IncidenceAngle "Test model for incidence angle"
  extends Modelica.Icons.Example;
  AixLib.BoundaryConditions.SolarGeometry.BaseClasses.Declination decAng
    "Declination angle"
  AixLib.BoundaryConditions.SolarGeometry.BaseClasses.SolarHourAngle
    solHouAng "Solar hour angle"
  AixLib.BoundaryConditions.SolarGeometry.BaseClasses.IncidenceAngle incAng(
    azi=AixLib.Types.Azimuth.S,
    til=AixLib.Types.Tilt.Wall)
    "Incidence 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"
equation
  connect(decAng.decAng, incAng.decAng)
  connect(solHouAng.solHouAng, incAng.solHouAng)
  connect(weaDat.weaBus, weaBus)
  connect(weaBus.cloTim, decAng.nDay)
  connect(weaBus.solTim, solHouAng.solTim)
  connect(weaBus.lat, incAng.lat)
end IncidenceAngle;


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


Test model for zenith angle. This example computes the solar azimuth angle.

within AixLib.BoundaryConditions.SolarGeometry.BaseClasses.Examples;
model SolarAzimuth "Test model for zenith angle"
  extends Modelica.Icons.Example;

  AixLib.BoundaryConditions.SolarGeometry.BaseClasses.SolarHourAngle
    solHouAng "Solar hour angle"
  AixLib.BoundaryConditions.SolarGeometry.BaseClasses.ZenithAngle zen
    "Zenith angle"
  AixLib.BoundaryConditions.SolarGeometry.BaseClasses.Declination decAng
    "Declination angle"
  AixLib.BoundaryConditions.SolarGeometry.BaseClasses.SolarAzimuth solAzi
    "Solar azimuth"
  WeatherData.ReaderTMY3 weaDat(
    filNam=Modelica.Utilities.Files.loadResource("modelica://AixLib/Resources/weatherdata/USA_IL_Chicago-OHare.Intl.AP.725300_TMY3.mos"))
    "Weather data"
  WeatherData.Bus weaBus "Weather bus"
equation
  connect(zen.zen, solAzi.zen)
  connect(solHouAng.solHouAng, zen.solHouAng)
  connect(decAng.decAng, solAzi.decAng)
  connect(decAng.decAng, zen.decAng)
  connect(weaDat.weaBus, weaBus)
  connect(weaBus.cloTim, decAng.nDay)
  connect(weaBus.solTim, solHouAng.solTim)
  connect(weaBus.solTim, solAzi.solTim)
  connect(zen.lat, weaBus.lat)
  connect(solAzi.lat, weaBus.lat)
end SolarAzimuth;


Test model for solar hour angle. This example 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.Examples;
model SolarHourAngle "Test model for solar hour angle"
  extends Modelica.Icons.Example;
  AixLib.BoundaryConditions.SolarGeometry.BaseClasses.SolarHourAngle
    solHouAng "Solar hour Angle"
  WeatherData.ReaderTMY3 weaDat(
    filNam=Modelica.Utilities.Files.loadResource("modelica://AixLib/Resources/weatherdata/USA_IL_Chicago-OHare.Intl.AP.725300_TMY3.mos"))
    "Weather data"
  WeatherData.Bus weaBus "Weather bus"
equation
  connect(weaDat.weaBus, weaBus)
  connect(weaBus.solTim, solHouAng.solTim)
end SolarHourAngle;


Test model for wall solar azimuth angle. This example calculates the wall solar azimuth angle.

within AixLib.BoundaryConditions.SolarGeometry.BaseClasses.Examples;
model WallSolarAzimuth "Test model for wall solar azimuth angle"
extends Modelica.Icons.Example;
  AixLib.BoundaryConditions.SolarGeometry.IncidenceAngle incAng(
    azi=0,
    til=1.5707963267949) "solar incidence 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.WallSolarAzimuth
    walSolAzi "Vertical wall solar azimuth angle"
  AixLib.BoundaryConditions.SolarGeometry.BaseClasses.AltitudeAngle altAng
    "Altitude angle"
  parameter Modelica.Units.SI.Angle lat=41.98*Modelica.Constants.pi/180
    "Latitude";
equation
  connect(weaDat.weaBus, weaBus)
  connect(weaDat.weaBus, incAng.weaBus)
  connect(incAng.y, walSolAzi.incAng)
  connect(altAng.alt, walSolAzi.alt)
  connect(weaBus.solZen, altAng.zen)
end WallSolarAzimuth;


Test model for zenith angle. This example computes the zenith angle,
which is the angle between the earth surface normal and the sun's beam.

within AixLib.BoundaryConditions.SolarGeometry.BaseClasses.Examples;
model ZenithAngle "Test model for zenith angle"
  extends Modelica.Icons.Example;
  AixLib.BoundaryConditions.SolarGeometry.BaseClasses.ZenithAngle zen
    "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"
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(weaBus.lat, zen.lat)
end ZenithAngle;


Test model for solar incidence angle. This example computes the solar incidence angle on tilted surfaces.
There are fives surfaces, a horizontal surface and a surface
that faces Norths, East, South and West.

within AixLib.BoundaryConditions.SolarGeometry.Examples;
model IncidenceAngle "Test model for solar incidence angle"
  extends Modelica.Icons.Example;
  AixLib.BoundaryConditions.SolarGeometry.IncidenceAngle incAngHor(
    til=AixLib.Types.Tilt.Ceiling, azi=0.3)
    "Incidence angle on horizontal surface"
  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 (Chicago)"
  AixLib.BoundaryConditions.SolarGeometry.IncidenceAngle incAngNor(
    azi=AixLib.Types.Azimuth.N,
    til=AixLib.Types.Tilt.Wall) "Incidence angle on North-facing surface"
  AixLib.BoundaryConditions.SolarGeometry.IncidenceAngle incAngWes(
    azi=AixLib.Types.Azimuth.W,
    til=AixLib.Types.Tilt.Wall) "Incidence angle on West-facing surface"
  AixLib.BoundaryConditions.SolarGeometry.IncidenceAngle incAngSou(
    azi=AixLib.Types.Azimuth.S,
    til=AixLib.Types.Tilt.Wall) "Incidence angle on South-facing surface"
  AixLib.BoundaryConditions.SolarGeometry.IncidenceAngle incAngEas(
    azi=AixLib.Types.Azimuth.E,
    til=AixLib.Types.Tilt.Wall) "Incidence angle on East-facing surface"
equation
  connect(weaDat.weaBus, incAngHor.weaBus)
  connect(incAngNor.weaBus, weaDat.weaBus)
  connect(incAngWes.weaBus, weaDat.weaBus)
  connect(incAngSou.weaBus, weaDat.weaBus)
  connect(incAngEas.weaBus, weaDat.weaBus)
end IncidenceAngle;


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


Test model for zenith angle. This example computes the zenith angle,
which is the angle between the earth surface normal and the sun beam.

within AixLib.BoundaryConditions.SolarGeometry.Examples;
model ZenithAngle "Test model for zenith angle"
  extends Modelica.Icons.Example;
  AixLib.BoundaryConditions.SolarGeometry.ZenithAngle zen
    "Zenith angle"
  AixLib.BoundaryConditions.WeatherData.ReaderTMY3 weaDat(
    filNam=Modelica.Utilities.Files.loadResource("modelica://AixLib/Resources/weatherdata/USA_IL_Chicago-OHare.Intl.AP.725300_TMY3.mos"))
equation
  connect(weaDat.weaBus, zen.weaBus)
end ZenithAngle;


Diffuse solar irradiation on a tilted surface with an isotropic sky model. This component computes the hemispherical diffuse irradiation
on a tilted surface using an isotropic model.
The irradiation is a sum composed of diffuse solar irradiation and
radiation reflected by the ground.
For a definition of the parameters, see the
User's Guide.

within AixLib.BoundaryConditions.SolarIrradiation;
block DiffuseIsotropic
  "Diffuse solar irradiation on a tilted surface with an isotropic sky model"
  extends
    AixLib.BoundaryConditions.SolarIrradiation.BaseClasses.PartialSolarIrradiation;
  parameter Real rho(min=0, max=1, final unit="1")=0.2 "Ground reflectance";
  parameter Boolean outSkyCon=false
    "Output contribution of diffuse irradiation from sky";
  parameter Boolean outGroCon=false
    "Output contribution of diffuse irradiation from ground";

  Modelica.Blocks.Math.Add add "Block to add radiation"

  Modelica.Blocks.Interfaces.RealOutput HSkyDifTil if outSkyCon
    "Diffuse solar irradiation on a tilted surface from the sky"
  Modelica.Blocks.Interfaces.RealOutput HGroDifTil if outGroCon
    "Diffuse solar irradiation on a tilted surface from the ground"
protected
  AixLib.BoundaryConditions.SolarIrradiation.BaseClasses.DiffuseIsotropic
    HDifTilIso(til=til, rho=rho) "Diffuse isotropic irradiation on tilted surface"

equation
  connect(weaBus.HGloHor, HDifTilIso.HGloHor)
  connect(weaBus.HDifHor, HDifTilIso.HDifHor)

  connect(HDifTilIso.HSkyDifTil, add.u1)
  connect(HDifTilIso.HGroDifTil, add.u2)
  connect(add.y, H)

  connect(HDifTilIso.HSkyDifTil, HSkyDifTil)
  connect(HDifTilIso.HGroDifTil, HGroDifTil)
end DiffuseIsotropic;


Hemispherical diffuse irradiation on a tilted surface using Perez's anisotropic sky model. This component computes the hemispherical diffuse irradiation on a tilted surface using an anisotropic
sky model proposed by Perez.
For a definition of the parameters, see the
User's Guide.

within AixLib.BoundaryConditions.SolarIrradiation;
block DiffusePerez
  "Hemispherical diffuse irradiation on a tilted surface using Perez's anisotropic sky model"
  extends
    AixLib.BoundaryConditions.SolarIrradiation.BaseClasses.PartialSolarIrradiation;

  parameter Real rho(min=0, max=1, final unit="1")=0.2 "Ground reflectance";
  parameter Modelica.Units.SI.Angle azi "Surface azimuth";
  parameter Boolean outSkyCon=false
    "Output contribution of diffuse irradiation from sky";
  parameter Boolean outGroCon=false
    "Output contribution of diffuse irradiation from ground";

  Modelica.Blocks.Interfaces.RealOutput HSkyDifTil if outSkyCon
    "Hemispherical diffuse solar irradiation on a tilted surface from the sky"
  Modelica.Blocks.Interfaces.RealOutput HGroDifTil if outGroCon
    "Hemispherical diffuse solar irradiation on a tilted surface from the ground"

protected
  BaseClasses.DiffusePerez HDifTil(
    final til=til,
    final rho=rho) "Diffuse irradiation on tilted surface"
  BaseClasses.SkyClearness skyCle "Sky clearness"
  BaseClasses.BrighteningCoefficient briCoe "Brightening coefficient"
  BaseClasses.RelativeAirMass relAirMas "Relative air mass"
  BaseClasses.SkyBrightness skyBri "Sky brightness"
  SolarGeometry.IncidenceAngle incAng(
    final azi=azi,
    final til=til) "Incidence angle"
  Modelica.Blocks.Math.Add add "Block to add radiations"
equation
  connect(relAirMas.relAirMas, skyBri.relAirMas)
  connect(skyBri.skyBri, briCoe.skyBri)
  connect(skyCle.skyCle, briCoe.skyCle)
  connect(incAng.y, HDifTil.incAng)
  connect(weaBus.solZen, skyCle.zen)
  connect(weaBus.solZen, relAirMas.zen)
  connect(weaBus.solZen, briCoe.zen)
  connect(weaBus.HDirNor, skyCle.HDirNor)
  connect(weaBus.HDifHor, skyCle.HDifHor)
  connect(weaBus.HDifHor, skyBri.HDifHor)
  connect(weaBus.HGloHor, HDifTil.HGloHor)
  connect(weaBus.HDifHor, HDifTil.HDifHor)

  connect(briCoe.F2, HDifTil.briCof2)
  connect(briCoe.F1, HDifTil.briCof1)
  connect(weaBus, incAng.weaBus)
  connect(weaBus.solZen, HDifTil.zen)
  connect(HDifTil.HSkyDifTil, add.u1)
  connect(HDifTil.HGroDifTil, add.u2)
  connect(add.y, H)

  connect(HDifTil.HSkyDifTil, HSkyDifTil)
  connect(HDifTil.HGroDifTil, HGroDifTil)
  connect(weaBus.solTim, skyBri.solTim)
  connect(weaBus.alt, relAirMas.alt)
end DiffusePerez;


Direct solar irradiation on a tilted surface. This component computes the direct solar irradiation on a tilted surface.
For a definition of the parameters, see the
User's Guide.

within AixLib.BoundaryConditions.SolarIrradiation;
block DirectTiltedSurface "Direct solar irradiation on a tilted surface"
  extends
    AixLib.BoundaryConditions.SolarIrradiation.BaseClasses.PartialSolarIrradiation;

  parameter Modelica.Units.SI.Angle azi "Surface azimuth";

  Modelica.Blocks.Interfaces.RealOutput inc(
    final quantity="Angle",
    final unit="rad",
    displayUnit="deg") "Incidence angle"

protected
  SolarGeometry.IncidenceAngle incAng(
    final azi=azi,
    final til=til) "Incidence angle"
  AixLib.BoundaryConditions.SolarIrradiation.BaseClasses.DirectTiltedSurface
    HDirTil "Direct irradition on tilted surface"

equation
  connect(incAng.y, HDirTil.incAng)

  connect(weaBus.HDirNor, HDirTil.HDirNor)
  connect(incAng.y, inc)
  connect(HDirTil.HDirTil, H)

  connect(weaBus, incAng.weaBus)
end DirectTiltedSurface;


Global solar irradiation on a tilted surface with diffuse irradiation calculation following Perez. This component computes the hemispherical direct and diffuse irradiation on a tilted surface
and outputs the global irradiation.

within AixLib.BoundaryConditions.SolarIrradiation;
block GlobalPerezTiltedSurface
  "Global solar irradiation on a tilted surface with diffuse irradiation calculation following Perez"
  extends
    AixLib.BoundaryConditions.SolarIrradiation.BaseClasses.PartialSolarIrradiation;
  parameter Modelica.Units.SI.Angle azi "Surface azimuth";
  parameter Real rho=0.2 "Ground reflectance";
  parameter Boolean outSkyCon=false
    "Output contribution of diffuse irradiation from sky";
  parameter Boolean outGroCon=false
    "Output contribution of diffuse irradiation from ground";
  DiffusePerez HDifTil(
    final til=til,
    final rho=rho,
    final azi=azi,
    final outSkyCon=outSkyCon,
    final outGroCon=outGroCon)
    "Diffuse irradiation on tilted surface"
  DirectTiltedSurface HDirTil(
    final til=til,
    final azi=azi)
    "Direct irradiation on tilted surface"
  Modelica.Blocks.Math.Add HGloTil(
      final k1=1,
      final k2=1)
    "Global irradiation on tilted surface"

equation
  connect(weaBus, HDifTil.weaBus)
  connect(weaBus, HDirTil.weaBus)
  connect(HDifTil.H, HGloTil.u1)
  connect(HDirTil.H, HGloTil.u2)
  connect(HGloTil.y, H)
end GlobalPerezTiltedSurface;


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


Circumsolar and horizon brightening coefficients. This component computes the circumsolar and horizon brightening coefficients.

within AixLib.BoundaryConditions.SolarIrradiation.BaseClasses;
block BrighteningCoefficient "Circumsolar and horizon brightening coefficients"
  extends Modelica.Blocks.Icons.Block;
  import H = AixLib.Utilities.Math.Functions.regStep;
  Modelica.Blocks.Interfaces.RealInput zen(
    quantity="Angle",
    unit="rad",
    displayUnit="deg") "Zenith angle of the sun beam"
  Modelica.Blocks.Interfaces.RealInput skyCle
    "Sky clearness. skyCle=1: overcast sky; skyCle=8 clear sky"
  Modelica.Blocks.Interfaces.RealInput skyBri "Sky brightness [0,1]"
  Modelica.Blocks.Interfaces.RealOutput F1
    "Circumsolar brightening coefficient"
  Modelica.Blocks.Interfaces.RealOutput F2 "Horizon brightening coefficient"
protected
  Real F11;
  Real F12;
  Real F13;
  Real F21;
  Real F22;
  Real F23;
  Real d=0.01;
  Real a1;
  Real a2;
  Real a3;
  Real a4;
  Real a5;
  Real a6;
  Real a7;
  Real a8;
  Real b1;
  Real b2;
  Real b3;
  Real b4;
  Real b5;
  Real b6;
  Real b7;
  Real b8;
equation
  b1 = H(
    y1=1,
    y2=0,
    x=1.065 - skyCle,
    x_small=d);
  b2 = H(
    y1=1,
    y2=0,
    x=1.23 - skyCle,
    x_small=d);
  b3 = H(
    y1=1,
    y2=0,
    x=1.50 - skyCle,
    x_small=d);
  b4 = H(
    y1=1,
    y2=0,
    x=1.95 - skyCle,
    x_small=d);
  b5 = H(
    y1=1,
    y2=0,
    x=2.80 - skyCle,
    x_small=d);

  b6 = H(
    y1=1,
    y2=0,
    x=4.50 - skyCle,
    x_small=d);
  b7 = H(
    y1=1,
    y2=0,
    x=6.20 - skyCle,
    x_small=d);
  b8 = H(
    y1=1,
    y2=0,
    x=skyCle - 6.20,
    x_small=d);

  a1 = b1;
  a2 = b2 - b1;
  a3 = b3 - b2;
  a4 = b4 - b3;
  a5 = b5 - b4;
  a6 = b6 - b5;
  a7 = b7 - b6;
  a8 = b8;

  F11 = -0.0083117*a1 + 0.1299457*a2 + 0.3296958*a3 + 0.5682053*a4 + 0.8730280*
    a5 + 1.1326077*a6 + 1.0601591*a7 + 0.6777470*a8;
  F12 = 0.5877285*a1 + 0.6825954*a2 + 0.4868735*a3 + 0.1874525*a4 - 0.3920403*
    a5 - 1.2367284*a6 - 1.5999137*a7 - 0.3272588*a8;
  F13 = -0.0620636*a1 - 0.1513725*a2 - 0.2210958*a3 - 0.2951290*a4 - 0.3616149*
    a5 - 0.4118494*a6 - 0.3589221*a7 - 0.2504286*a8;
  F21 = -0.0596012*a1 - 0.0189325*a2 + 0.0554140*a3 + 0.1088631*a4 + 0.2255647*
    a5 + 0.2877813*a6 + 0.2642124*a7 + 0.1561313*a8;
  F22 = 0.0721249*a1 + 0.0659650*a2 - 0.0639588*a3 - 0.1519229*a4 - 0.4620442*
    a5 - 0.8230357*a6 - 1.1272340*a7 - 1.3765031*a8;
  F23 = -0.0220216*a1 - 0.0288748*a2 - 0.0260542*a3 - 0.0139754*a4 + 0.0012448*
    a5 + 0.0558651*a6 + 0.1310694*a7 + 0.2506212*a8;
  F1 = AixLib.Utilities.Math.Functions.smoothMax(
    0,
    F11 + F12*skyBri + F13*zen,
    0.01);
  F2 = F21 + F22*skyBri + F23*zen;
end BrighteningCoefficient;


Diffuse solar irradiation on a tilted surface with an isotropic model. This component computes the hemispherical diffuse irradiation on a tilted surface.
The irradiation is composed of the diffuse horizontal solar irradiation and the irradiation
that has been reflected by the ground. Both components are adjusted to take into account
the tilt of the receiving surface.

within AixLib.BoundaryConditions.SolarIrradiation.BaseClasses;
block DiffuseIsotropic
  "Diffuse solar irradiation on a tilted surface with an isotropic model"
  extends Modelica.Blocks.Icons.Block;
  parameter Real rho=0.2 "Ground reflectance";
  parameter Modelica.Units.SI.Angle til(displayUnit="deg") "Surface tilt angle";

  Modelica.Blocks.Interfaces.RealInput HDifHor(quantity=
        "RadiantEnergyFluenceRate", unit="W/m2")
    "Horizontal diffuse solar radiation"
  Modelica.Blocks.Interfaces.RealInput HGloHor(quantity=
        "RadiantEnergyFluenceRate", unit="W/m2") "Horizontal global radiation"

  Modelica.Blocks.Interfaces.RealOutput HGroDifTil(final quantity="RadiantEnergyFluenceRate",
      final unit="W/m2")
    "Diffuse solar irradiation on a tilted surface from the ground"
  Modelica.Blocks.Interfaces.RealOutput HSkyDifTil(final quantity="RadiantEnergyFluenceRate",
      final unit="W/m2")
    "Diffuse solar irradiation on a tilted surface from the sky"
protected
  Real til_c "Cosine of tilt angle";
equation
  til_c = Modelica.Math.cos(til);
  HSkyDifTil = 0.5*HDifHor*(1 + til_c);
  HGroDifTil = 0.5*HGloHor*rho*(1 - til_c);
end DiffuseIsotropic;


Hemispherical diffuse irradiation on a tilted surface with Perez's anisotropic model. This component computes the hemispherical diffuse irradiation on a tilted surface by using an anisotropic model proposed by Perez.

within AixLib.BoundaryConditions.SolarIrradiation.BaseClasses;
block DiffusePerez
  "Hemispherical diffuse irradiation on a tilted surface with Perez's anisotropic model"
  extends Modelica.Blocks.Icons.Block;
  parameter Real rho=0.2 "Ground reflectance";
  parameter Modelica.Units.SI.Angle til(displayUnit="deg") "Surface tilt angle";
  Modelica.Blocks.Interfaces.RealInput briCof1 "Brightening Coeffcient F1"
  Modelica.Blocks.Interfaces.RealInput briCof2 "Brightening Coeffcient F2"
  Modelica.Blocks.Interfaces.RealInput HDifHor(quantity=
        "RadiantEnergyFluenceRate", unit="W/m2")
    "Diffuse horizontal solar radiation"
  Modelica.Blocks.Interfaces.RealInput HGloHor(quantity=
        "RadiantEnergyFluenceRate", unit="W/m2") "Global horizontal radiation"

  Modelica.Blocks.Interfaces.RealInput zen(
    quantity="Angle",
    unit="rad",
    displayUnit="deg") "Zenith angle of the sun beam"
  Modelica.Blocks.Interfaces.RealInput incAng(
    quantity="Angle",
    unit="rad",
    displayUnit="deg") "Solar incidence angle on the surface"

  Modelica.Blocks.Interfaces.RealOutput HGroDifTil(final quantity=
        "RadiantEnergyFluenceRate", final unit="W/m2")
    "Hemispherical diffuse solar irradiation on a tilted surface from the ground"
  Modelica.Blocks.Interfaces.RealOutput HSkyDifTil(final quantity=
        "RadiantEnergyFluenceRate", final unit="W/m2")
    "Hemispherical diffuse solar irradiation on a tilted surface from the sky"
protected
  Real a;
  Real b;
  constant Real bMin=Modelica.Math.cos(Modelica.Constants.pi*85/180)
    "Lower bound for b";
equation
  a = AixLib.Utilities.Math.Functions.smoothMax(
    0,
    Modelica.Math.cos(incAng),
    0.01);
  b = AixLib.Utilities.Math.Functions.smoothMax(
    bMin,
    Modelica.Math.cos(zen),
    0.01);
  HSkyDifTil = HDifHor*(0.5*(1 - briCof1)*(1 + Modelica.Math.cos(til)) +
    briCof1*a/b + briCof2*Modelica.Math.sin(til));
  HGroDifTil = HGloHor*0.5*rho*(1 - Modelica.Math.cos(til));
end DiffusePerez;


Direct solar irradiation on a tilted surface. This component computes the direct solar irradiation on a tilted surface.

within AixLib.BoundaryConditions.SolarIrradiation.BaseClasses;
block DirectTiltedSurface "Direct solar irradiation on a tilted surface"
  extends Modelica.Blocks.Icons.Block;
  Modelica.Blocks.Interfaces.RealInput incAng(
    quantity="Angle",
    unit="rad",
    displayUnit="deg") "Incidence angle of the sun beam on a tilted surface"
  Modelica.Blocks.Interfaces.RealInput HDirNor(quantity=
        "RadiantEnergyFluenceRate", unit="W/m2") "Direct normal radiation"
  Modelica.Blocks.Interfaces.RealOutput HDirTil(final quantity=
        "RadiantEnergyFluenceRate", final unit="W/m2")
    "Direct solar irradiation on a tilted surface"

equation
  HDirTil =  max(0, Modelica.Math.cos(incAng)*HDirNor);
end DirectTiltedSurface;


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


Partial model that is used to compute the direct and diffuse solar irradiation. This is a partial model that is used to implement the direct and diffuse irradiation.

within AixLib.BoundaryConditions.SolarIrradiation.BaseClasses;
partial block PartialSolarIrradiation
  "Partial model that is used to compute the direct and diffuse solar irradiation"
  extends Modelica.Blocks.Icons.Block;
  parameter Modelica.Units.SI.Angle til(displayUnit="deg") "Surface tilt";
  Modelica.Blocks.Interfaces.RealOutput H(
     final quantity="RadiantEnergyFluenceRate",
     final unit="W/m2") "Radiation per unit area"

  WeatherData.Bus weaBus "Bus with weather data"
end PartialSolarIrradiation;


Relative air mass. This component computes the relative air mass for sky brightness.

within AixLib.BoundaryConditions.SolarIrradiation.BaseClasses;
block RelativeAirMass "Relative air mass"
  extends Modelica.Blocks.Icons.Block;
  Modelica.Blocks.Interfaces.RealInput alt(
    quantity="Length",
    unit="m") "location altitude"
  Modelica.Blocks.Interfaces.RealInput zen(
    quantity="Angle",
    unit="rad",
    displayUnit="deg") "Zenith angle of the sun beam"
  Modelica.Blocks.Interfaces.RealOutput relAirMas "Relative air mass"
protected
  Real zenLim "Zenith angle bounded from above by 90 degree";
  Real zenDeg "Zenith angle in degree";
equation
  zenLim = AixLib.Utilities.Math.Functions.smoothMin(
    zen,
    Modelica.Constants.pi/2,
    0.01);
  zenDeg = zenLim*180/Modelica.Constants.pi;
  relAirMas = exp(-0.0001184*alt)/(Modelica.Math.cos(zenLim) + 0.15*(93.9 - zenDeg)^(-1.253));
end RelativeAirMass;


Sky brightness. This component computes the sky brightness.

within AixLib.BoundaryConditions.SolarIrradiation.BaseClasses;
block SkyBrightness "Sky brightness"
  extends Modelica.Blocks.Icons.Block;
  Modelica.Blocks.Interfaces.RealInput relAirMas "Relative air mass"
  Modelica.Blocks.Interfaces.RealInput HDifHor(quantity=
        "RadiantEnergyFluenceRate", unit="W/m2")
    "Horizontal diffuse solar radiation"
  Modelica.Blocks.Interfaces.RealInput solTim(quantity="Time", unit="s")
    "Solar time"
  Modelica.Blocks.Interfaces.RealOutput skyBri "Sky brightness"

  Real extRadCor "Correction for extraterrestrial radiation";
equation
  extRadCor =1 + 0.033*cos(2*Modelica.Constants.pi*(solTim/86400 + 1)/365);
  skyBri = AixLib.Utilities.Math.Functions.smoothMin(
    HDifHor*relAirMas/(1366.1*extRadCor),
    1,
    0.025);
end SkyBrightness;


Sky clearness. This component computes the sky clearness.

within AixLib.BoundaryConditions.SolarIrradiation.BaseClasses;
block SkyClearness "Sky clearness"
  extends Modelica.Blocks.Icons.Block;

  Modelica.Blocks.Interfaces.RealInput zen(
    quantity="Angle",
    unit="rad",
    displayUnit="deg") "Zenith angle of the sun beam"
  Modelica.Blocks.Interfaces.RealInput HDifHor(quantity=
        "RadiantEnergyFluenceRate", unit="W/m2")
    "Horizontal diffuse solar radiation"
  Modelica.Blocks.Interfaces.RealInput HDirNor(quantity=
        "RadiantEnergyFluenceRate", unit="W/m2")
    "Horizontal global solar radiation"
  Modelica.Blocks.Interfaces.RealOutput skyCle
    "Sky clearness. skyCle=1: overast sky; skyCle=8: clear sky"
  // Set hSmall so that hSmall + deltaX < 1E-4. See info section.
protected
  constant Modelica.Units.SI.Irradiance hSmall=0.5e-4
    "Small radiation for regularization";
  constant Modelica.Units.SI.Irradiance deltaX=hSmall/2
    "Small radiation for regularization";
  constant Real k = 5.534e-6*(180/Modelica.Constants.pi)^3 "Constant factor";
  Real tmp1 "Intermediate variable";
  Modelica.Units.SI.Irradiance HDifHorBou
    "Diffuse horizontal irradiation, bounded away from zero";
equation
  tmp1 =  k*zen^3;
  HDifHorBou = AixLib.Utilities.Math.Functions.smoothMax(
                 x1 = HDifHor,
                 x2 = hSmall,
                 deltaX = deltaX);
  // In the Buildings library, HDirNor is always larger than 1E-4
  // (minus some small undershoot due to regularization. Hence,
  // it makes no sense to simplify the equation for
  // HDirNor < Modelica.Constants.small.
  skyCle = AixLib.Utilities.Math.Functions.smoothLimit(
        x = ((HDirNor+HDifHorBou)/HDifHorBou + tmp1)/(1 + tmp1),
        l = 1,
        u = 8,
        deltaX = 0.01);
end SkyClearness;


Test model for brightening coeffcients. This example computes the circumsolar and horizon brightening coefficients.

within AixLib.BoundaryConditions.SolarIrradiation.BaseClasses.Examples;
model BrighteningCoefficient "Test model for brightening coeffcients"
  extends Modelica.Icons.Example;
  AixLib.BoundaryConditions.SolarGeometry.ZenithAngle zen
  AixLib.BoundaryConditions.SolarIrradiation.BaseClasses.SkyClearness skyCle
  AixLib.BoundaryConditions.SolarIrradiation.BaseClasses.BrighteningCoefficient
    briCoe
  AixLib.BoundaryConditions.SolarIrradiation.BaseClasses.RelativeAirMass
    relAirMas
  AixLib.BoundaryConditions.SolarIrradiation.BaseClasses.SkyBrightness
    skyBri
  AixLib.BoundaryConditions.WeatherData.ReaderTMY3 weaDat(filNam=
        Modelica.Utilities.Files.loadResource("modelica://AixLib/Resources/weatherdata/USA_CA_San.Francisco.Intl.AP.724940_TMY3.mos"))
  AixLib.BoundaryConditions.WeatherData.Bus weaBus
equation
  connect(zen.y, skyCle.zen)
  connect(relAirMas.relAirMas, skyBri.relAirMas)
  connect(zen.y, relAirMas.zen)
  connect(skyBri.skyBri, briCoe.skyBri)
  connect(skyCle.skyCle, briCoe.skyCle)
  connect(zen.y, briCoe.zen)
  connect(weaDat.weaBus, weaBus)
  connect(weaBus.HDifHor, skyCle.HDifHor)
  connect(weaBus.HDifHor, skyBri.HDifHor)
  connect(weaBus, zen.weaBus)
  connect(weaBus.solTim, skyBri.solTim)
  connect(weaBus.HDirNor, skyCle.HDirNor)
  connect(weaBus.alt, relAirMas.alt)
end BrighteningCoefficient;


Test model for diffuse solar irradiation on a tilted surface by using isotropic model. This example computes the hemispherical diffuse irradiation on a tilted surface.

within AixLib.BoundaryConditions.SolarIrradiation.BaseClasses.Examples;
model DiffuseIsotropic
  "Test model for diffuse solar irradiation on a tilted surface by using isotropic model"
  extends Modelica.Icons.Example;
  AixLib.BoundaryConditions.SolarIrradiation.BaseClasses.DiffuseIsotropic
    HDifTilIso(til=1.5707963267949)
  AixLib.BoundaryConditions.WeatherData.ReaderTMY3 weaDat(filNam=
        Modelica.Utilities.Files.loadResource("modelica://AixLib/Resources/weatherdata/USA_CA_San.Francisco.Intl.AP.724940_TMY3.mos"))
  AixLib.BoundaryConditions.WeatherData.Bus weaBus
equation
  connect(weaDat.weaBus, weaBus)
  connect(weaBus.HGloHor, HDifTilIso.HGloHor)
  connect(weaBus.HDifHor, HDifTilIso.HDifHor)
end DiffuseIsotropic;


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


Test model for relative air mass. This example computes the relative air mass for sky brightness.

within AixLib.BoundaryConditions.SolarIrradiation.BaseClasses.Examples;
model RelativeAirMass "Test model for relative air mass"
  extends Modelica.Icons.Example;
  AixLib.BoundaryConditions.SolarIrradiation.BaseClasses.RelativeAirMass
    relAirMas
  AixLib.BoundaryConditions.SolarGeometry.ZenithAngle zen
  AixLib.BoundaryConditions.WeatherData.ReaderTMY3 weaDat(filNam=
        Modelica.Utilities.Files.loadResource("modelica://AixLib/Resources/weatherdata/USA_CA_San.Francisco.Intl.AP.724940_TMY3.mos"))
  WeatherData.Bus weaBus
equation
  connect(zen.y, relAirMas.zen)
  connect(weaDat.weaBus, zen.weaBus)
  connect(weaDat.weaBus, weaBus)
  connect(weaBus.alt, relAirMas.alt)
end RelativeAirMass;


Test model for sky brightness. This example computes the sky brightness.

within AixLib.BoundaryConditions.SolarIrradiation.BaseClasses.Examples;
model SkyBrightness "Test model for sky brightness"
  extends Modelica.Icons.Example;
  AixLib.BoundaryConditions.SolarIrradiation.BaseClasses.RelativeAirMass relAirMas
    "Relative air mass"
  AixLib.BoundaryConditions.SolarGeometry.ZenithAngle zen
    "Zenith angle"
  AixLib.BoundaryConditions.SolarIrradiation.BaseClasses.SkyBrightness skyBri
    "Sky brightness"
  AixLib.BoundaryConditions.WeatherData.ReaderTMY3 weaDat(filNam=
    Modelica.Utilities.Files.loadResource("modelica://AixLib/Resources/weatherdata/USA_CA_San.Francisco.Intl.AP.724940_TMY3.mos"))
    "Weather data"
  AixLib.BoundaryConditions.WeatherData.Bus weaBus "Weather data bus"
equation
  connect(zen.y, relAirMas.zen)
  connect(relAirMas.relAirMas, skyBri.relAirMas)
  connect(weaDat.weaBus, weaBus)
  connect(weaBus.HDifHor, skyBri.HDifHor)
  connect(zen.weaBus, weaBus)
  connect(weaBus.solTim, skyBri.solTim)
  connect(weaBus.alt, relAirMas.alt)
end SkyBrightness;


Test model for sky clearness. This example computes the sky clearness.

within AixLib.BoundaryConditions.SolarIrradiation.BaseClasses.Examples;
model SkyClearness "Test model for sky clearness"
  extends Modelica.Icons.Example;

  AixLib.BoundaryConditions.SolarGeometry.ZenithAngle zen
  AixLib.BoundaryConditions.SolarIrradiation.BaseClasses.SkyClearness skyCle

  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.WeatherData.Bus weaBus
equation
  connect(zen.y, skyCle.zen)

  connect(weaDat.weaBus, weaBus)
  connect(weaBus.HDirNor, skyCle.HDirNor)
  connect(weaBus.HDifHor, skyCle.HDifHor)

  connect(weaBus, zen.weaBus)
end SkyClearness;


Test model for diffuse solar irradiation on a tilted surface using the isotropic model. This example computes the hemispherical diffuse irradiation
on a roof, wall and a floor, using an isotropic sky model.
Since the floor only sees the ground,
it receives the lowest amount of diffuse solar irradiation.

within AixLib.BoundaryConditions.SolarIrradiation.Examples;
model DiffuseIsotropic
  "Test model for diffuse solar irradiation on a tilted surface using the isotropic model"
  extends Modelica.Icons.Example;
  parameter Real rho=0.2 "Ground reflectance";

  AixLib.BoundaryConditions.WeatherData.ReaderTMY3 weaDat(filNam=
        Modelica.Utilities.Files.loadResource("modelica://AixLib/Resources/weatherdata/USA_CA_San.Francisco.Intl.AP.724940_TMY3.mos"))
  AixLib.BoundaryConditions.WeatherData.Bus weaBus "Weather data bus"
  AixLib.BoundaryConditions.SolarIrradiation.DiffuseIsotropic
        HDifRoo(til=AixLib.Types.Tilt.Ceiling,
                rho=rho) "Diffuse irradiation on roof"
  AixLib.BoundaryConditions.SolarIrradiation.DiffuseIsotropic
        HDifFlo(til=AixLib.Types.Tilt.Floor,
                rho=rho) "Diffuse irradiation on floor"
  AixLib.BoundaryConditions.SolarIrradiation.DiffuseIsotropic
        HDifWal(
        til=AixLib.Types.Tilt.Wall,
        rho=rho) "Diffuse irradiation on wall"

equation
  connect(weaDat.weaBus, weaBus)

  connect(weaBus,HDifRoo. weaBus)
  connect(HDifWal.weaBus, weaBus)
  connect(HDifFlo.weaBus, weaBus)
end DiffuseIsotropic;


Test model for diffuse solar irradiation on a tilted surface using the Perez model. This model tests the implementation of Perez' model for diffuse solar radiation.
The three instances of Perez' model compute the diffuse solar
irradiation on a roof, a wall and a floor.
Since the floor only sees the ground but not the radiative heat flow that is
scattered in the atmosphere, it receives the lowest amount of
diffuse solar irradiation.

within AixLib.BoundaryConditions.SolarIrradiation.Examples;
model DiffusePerez
  "Test model for diffuse solar irradiation on a tilted surface using the Perez model"
  extends Modelica.Icons.Example;
  parameter Modelica.Units.SI.Angle azi=0.3 "Azi angle";
  parameter Modelica.Units.SI.Angle til=0.5 "Tilted angle";
  AixLib.BoundaryConditions.WeatherData.ReaderTMY3 weaDat(filNam=
        Modelica.Utilities.Files.loadResource("modelica://AixLib/Resources/weatherdata/USA_CA_San.Francisco.Intl.AP.724940_TMY3.mos"))
  AixLib.BoundaryConditions.WeatherData.Bus weaBus
    "Weather data bus"
  AixLib.BoundaryConditions.SolarIrradiation.DiffusePerez HDifRoo(
    til=AixLib.Types.Tilt.Ceiling,
    azi=0.78539816339745)
    "Diffuse irradiation on roof"
  AixLib.BoundaryConditions.SolarIrradiation.DiffusePerez HDifFlo(
    til=AixLib.Types.Tilt.Floor,
    azi=0.78539816339745)
    "Diffuse irradiation on floor"
  AixLib.BoundaryConditions.SolarIrradiation.DiffusePerez HDifWal(
    til=AixLib.Types.Tilt.Wall,
    azi=0.78539816339745)
    "Diffuse irradiation on wall"
equation
  connect(weaDat.weaBus, weaBus)
  connect(weaBus,HDifRoo. weaBus)

  connect(weaBus, HDifFlo.weaBus)
  connect(weaBus, HDifWal.weaBus)
end DiffusePerez;


Test model for direct solar irradiation on a tilted surface. This model tests the direct solar irradiation received on a ceiling, a wall and a floor.
The assert statement will stop the simulation if the floor receives
any direct solar irradiation.

within AixLib.BoundaryConditions.SolarIrradiation.Examples;
model DirectTiltedSurface
  "Test model for direct solar irradiation on a tilted surface"
  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.SolarIrradiation.DirectTiltedSurface HDirRoo(
    til=AixLib.Types.Tilt.Ceiling,
    azi=0.78539816339745)
    "Direct irradiation on roof"
  AixLib.BoundaryConditions.SolarIrradiation.DirectTiltedSurface HDirFlo(
    til=AixLib.Types.Tilt.Floor,
    azi=0.78539816339745)
    "Direct irradiation on floor"
  AixLib.BoundaryConditions.SolarIrradiation.DirectTiltedSurface HDirWal(
    til=AixLib.Types.Tilt.Wall,
    azi=0.78539816339745)
    "Direct irradiation on wall"
  AixLib.Utilities.Diagnostics.AssertEquality assEqu
    "Assert to ensure that direct radiation received by floor construction is zero"
  Modelica.Blocks.Sources.Constant const(k=0) "Block that outputs zero"
equation
  connect(assEqu.u1, HDirFlo.H)
  connect(const.y, assEqu.u2)
  connect(weaDat.weaBus, HDirRoo.weaBus)
  connect(HDirWal.weaBus, weaDat.weaBus)
  connect(HDirFlo.weaBus, weaDat.weaBus)
end DirectTiltedSurface;


Test model for global solar irradiation on a tilted surface with diffuse
  irradiation calculation based on Perez. This model tests the implementation of global irradiation computation based on Perez' model for diffuse solar radiation.

within AixLib.BoundaryConditions.SolarIrradiation.Examples;
model GlobalPerezTiltedSurface
  "Test model for global solar irradiation on a tilted surface with diffuse
  irradiation calculation based on Perez"
  extends Modelica.Icons.Example;

  parameter Real rho=0.2 "Ground reflectance";

  WeatherData.ReaderTMY3 weaDat(filNam=
        Modelica.Utilities.Files.loadResource("modelica://AixLib/Resources/weatherdata/USA_CA_San.Francisco.Intl.AP.724940_TMY3.mos"))

  AixLib.BoundaryConditions.SolarIrradiation.GlobalPerezTiltedSurface HGloRoo(
    til=AixLib.Types.Tilt.Ceiling,
    azi=0.78539816339745,
    rho=rho)
    "Diffuse irradiation on roof"
  AixLib.BoundaryConditions.SolarIrradiation.GlobalPerezTiltedSurface HGloFlo(
    til=AixLib.Types.Tilt.Floor,
    azi=0.78539816339745,
    rho=rho)
    "Diffuse irradiation on floor"
  AixLib.BoundaryConditions.SolarIrradiation.GlobalPerezTiltedSurface HGloWal(
    til=AixLib.Types.Tilt.Wall,
    azi=0.78539816339745,
    rho=rho)
    "Diffuse irradiation on wall"
  WeatherData.Bus weaBus
    "Weather data bus"
equation
  connect(weaDat.weaBus,weaBus)
  connect(weaBus,HGloRoo. weaBus)
  connect(weaBus,HGloFlo. weaBus)
  connect(weaBus,HGloWal. weaBus)
end GlobalPerezTiltedSurface;


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


Partial model to run BESTEST validation case studies for weather data processing. This model outputs the global radiation with a certain inclination and orientation
using the isotropic sky model and the Perez sky model. The variable H is
the global radiation calculated using the isotropic sky model, while HPer is
the global radiation calculated using the Perez sky model.

within AixLib.BoundaryConditions.Validation;
model IsotropicAndPerezDiffuseRadiation
  "Partial model to run BESTEST validation case studies for weather data processing"
  extends AixLib.BoundaryConditions.SolarIrradiation.BaseClasses.PartialSolarIrradiation;
  Modelica.Blocks.Interfaces.RealOutput HPer(
    final quantity="RadiantEnergyFluenceRate",
    final unit="W/m2")
    "Radiation per unit area using Perez Model"
  parameter Modelica.Units.SI.Angle til(displayUnit="deg") "Surface tilt angle";
  parameter Modelica.Units.SI.Angle azi(displayUnit="deg") "Azimuth angle";
  parameter Real rho=0.2
    "Ground reflectance";
  SolarIrradiation.DirectTiltedSurface HDir(
    til=til,
    azi=azi)
    "Direct Irradiation on tilted surface"
  SolarIrradiation.DiffuseIsotropic HDiffIso(
    til=til,
    rho=rho,
    outSkyCon=true,
    outGroCon=true)
    "Isoentropic diffuse radiation"
  SolarIrradiation.DiffusePerez HDiffPer(
    til=til,
    rho=rho,
    azi=azi,
    outSkyCon=true,
    outGroCon=true)
    "Diffused radiation using Perez"

protected
  Modelica.Blocks.Math.Add addHDirHDiffIso
    "Sum of Direct radiation and Isoentropic radiation"
  Modelica.Blocks.Math.Add addHDirHDiffPer
    "Sum of Direct radiation and Perez radiation"

equation
  connect(weaBus,HDiffIso.weaBus)
  connect(HDir.weaBus,HDiffIso.weaBus)
  connect(HDiffPer.weaBus,HDiffIso.weaBus)
  connect(HDir.H,addHDirHDiffPer.u1)
  connect(HDiffPer.H,addHDirHDiffPer.u2)
  connect(HDiffIso.H,addHDirHDiffIso.u1)
  connect(HDir.H,addHDirHDiffIso.u2)
  connect(addHDirHDiffIso.y,H)
  connect(addHDirHDiffPer.y,HPer)
end IsotropicAndPerezDiffuseRadiation;


within AixLib.BoundaryConditions;
package Validation "Collection of validation models Validation"
  extends Modelica.Icons.ExamplesPackage;
end Validation;


User's Guide

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


within AixLib.BoundaryConditions.Validation;
package BESTEST "Boundary conditions validation according to BESTEST specifications"
  extends Modelica.Icons.ExamplesPackage;
end BESTEST;


Test model for BESTEST weather data: base case.

within AixLib.BoundaryConditions.Validation.BESTEST;
model WD100
  "Test model for BESTEST weather data: base case"
  extends Modelica.Icons.Example;

  parameter Real rho=0
    "Ground reflectance";
  WeatherData.ReaderTMY3 weaDatHHorIR(
    pAtmSou=AixLib.BoundaryConditions.Types.DataSource.File,
    filNam=Modelica.Utilities.Files.loadResource(
      "modelica://AixLib/Resources/Data/BoundaryConditions/Validation/BESTEST/WD100.mos"),
    calTSky=AixLib.BoundaryConditions.Types.SkyTemperatureCalculation.HorizontalRadiation)
    "Reads all weather data and Tsky using horizontal radiation"
  WeatherData.Bus weaBusHHorIR
    "weather bus to read all weather data and Tsky using horizontal radiation"
  IsotropicAndPerezDiffuseRadiation azi000til00(
    til=AixLib.Types.Tilt.Ceiling,
    azi=AixLib.Types.Azimuth.S,
    rho=rho)
    "Azimuth = Horizontal, Tilt = 0 °"
  IsotropicAndPerezDiffuseRadiation azi000til90(
    til=AixLib.Types.Tilt.Wall,
    azi=AixLib.Types.Azimuth.S,
    rho=rho)
    "Azimuth = South, Tilt = 90 °"
  IsotropicAndPerezDiffuseRadiation azi270til90(
    til=AixLib.Types.Tilt.Wall,
    azi=AixLib.Types.Azimuth.E,
    rho=rho)
    "Azimuth = East, Tilt = 90 °"
  IsotropicAndPerezDiffuseRadiation azi180til90(
    til=AixLib.Types.Tilt.Wall,
    azi=AixLib.Types.Azimuth.N,
    rho=rho)
    "Azimuth = North, Tilt = 90 °"
  IsotropicAndPerezDiffuseRadiation azi090til90(
    til=AixLib.Types.Tilt.Wall,
    azi=AixLib.Types.Azimuth.W,
    rho=rho)
    "Azimuth =  West, Tilt = 90 °"
  IsotropicAndPerezDiffuseRadiation azi315til90(
    til=AixLib.Types.Tilt.Wall,
    azi=AixLib.Types.Azimuth.SE,
    rho=rho)
    "Azimuth = 45 ° SE, Tilt = 0 °"
  IsotropicAndPerezDiffuseRadiation azi045til90(
    til=AixLib.Types.Tilt.Wall,
    azi=AixLib.Types.Azimuth.SW,
    rho=rho)
    "Azimuth = 45 SW, Tilt = 90 °"
  IsotropicAndPerezDiffuseRadiation azi270til30(
    til=0.5235987755983,
    azi=AixLib.Types.Azimuth.E,
    rho=rho)
    "Azimuth = East, Tilt = 30 °"
  IsotropicAndPerezDiffuseRadiation azi000til30(
    til=0.5235987755983,
    azi=AixLib.Types.Azimuth.S,
    rho=rho)
    "Azimuth = South, Tilt = 0 °"
  IsotropicAndPerezDiffuseRadiation azi090til30(
    til=0.5235987755983,
    azi=AixLib.Types.Azimuth.W,
    rho=rho)
    "Azimuth = West, Tilt = 0 °"
  Utilities.Psychrometrics.X_pTphi x_pTphi
  Utilities.Psychrometrics.ToDryAir toDryAir
  WeatherData.ReaderTMY3 weaDatTDryBulTDewPoinOpa(
    pAtmSou=AixLib.BoundaryConditions.Types.DataSource.File,
    filNam=Modelica.Utilities.Files.loadResource(
      "modelica://AixLib/Resources/Data/BoundaryConditions/Validation/BESTEST/WD100.mos"),
    calTSky=AixLib.BoundaryConditions.Types.SkyTemperatureCalculation.TemperaturesAndSkyCover)
    "Reads all weather data and Tsky using dry bulb temperature, dew point temperature and sky cover"
  WeatherData.Bus weaBusTDryBulTDewPoiOpa
    "Weather bus to read Tsky using dew point temperature and sky cover"

equation
  connect(weaDatHHorIR.weaBus,weaBusHHorIR)
  connect(weaBusHHorIR.pAtm,x_pTphi.p_in)
  connect(weaBusHHorIR.TDryBul,x_pTphi.T)
  connect(weaBusHHorIR.relHum,x_pTphi.phi)
  connect(x_pTphi.X[1],toDryAir.XiTotalAir)
  connect(weaDatTDryBulTDewPoinOpa.weaBus,weaBusTDryBulTDewPoiOpa)
  connect(weaBusHHorIR,azi090til90.weaBus)
  connect(weaBusHHorIR,azi090til30.weaBus)
  connect(weaBusHHorIR,azi000til30.weaBus)
  connect(weaBusHHorIR,azi180til90.weaBus)
  connect(weaBusHHorIR,azi270til30.weaBus)
  connect(weaBusHHorIR,azi270til90.weaBus)
  connect(weaBusHHorIR,azi045til90.weaBus)
  connect(weaBusHHorIR,azi000til90.weaBus)
  connect(weaBusHHorIR,azi315til90.weaBus)
  connect(weaBusHHorIR,azi000til00.weaBus)
end WD100;


Test model for BESTEST weather data: Low Elevation, Hot and Humid Case.

within AixLib.BoundaryConditions.Validation.BESTEST;
model WD200
  "Test model for BESTEST weather data: Low Elevation, Hot and Humid Case"
  extends WD100(
    rho=0,
    weaDatHHorIR(
      filNam=Modelica.Utilities.Files.loadResource(
        "modelica://AixLib/Resources/Data/BoundaryConditions/Validation/BESTEST/WD200.mos")),
    weaDatTDryBulTDewPoinOpa(
      filNam=Modelica.Utilities.Files.loadResource(
        "modelica://AixLib/Resources/Data/BoundaryConditions/Validation/BESTEST/WD200.mos")));
end WD200;


Test model for BESTEST weather data: Southern hemisphere case.

within AixLib.BoundaryConditions.Validation.BESTEST;
model WD300
  "Test model for BESTEST weather data: Southern hemisphere case"
  extends WD100(
    rho=0,
    weaDatHHorIR(
      filNam=Modelica.Utilities.Files.loadResource(
        "modelica://AixLib/Resources/Data/BoundaryConditions/Validation/BESTEST/WD300.mos")),
    weaDatTDryBulTDewPoinOpa(
      filNam=Modelica.Utilities.Files.loadResource(
        "modelica://AixLib/Resources/Data/BoundaryConditions/Validation/BESTEST/WD300.mos")));
end WD300;


Test model for BESTEST weather data: high latitude case.

within AixLib.BoundaryConditions.Validation.BESTEST;
model WD400
  "Test model for BESTEST weather data: high latitude case"
  extends WD100(
    rho=0,
    weaDatHHorIR(
      filNam=Modelica.Utilities.Files.loadResource(
        "modelica://AixLib/Resources/Data/BoundaryConditions/Validation/BESTEST/WD400.mos")),
    weaDatTDryBulTDewPoinOpa(
      filNam=Modelica.Utilities.Files.loadResource(
        "modelica://AixLib/Resources/Data/BoundaryConditions/Validation/BESTEST/WD400.mos")));
end WD400;


Test model for BESTEST weather data: time zone case.

within AixLib.BoundaryConditions.Validation.BESTEST;
model WD500
  "Test model for BESTEST weather data: time zone case"
  extends WD100(
    rho=0,
    weaDatHHorIR(
      filNam=Modelica.Utilities.Files.loadResource(
        "modelica://AixLib/Resources/Data/BoundaryConditions/Validation/BESTEST/WD500.mos")),
    weaDatTDryBulTDewPoinOpa(
      filNam=Modelica.Utilities.Files.loadResource(
        "modelica://AixLib/Resources/Data/BoundaryConditions/Validation/BESTEST/WD500.mos")));
end WD500;


Test model for BESTEST weather data: ground reflectance.

within AixLib.BoundaryConditions.Validation.BESTEST;
model WD600
  "Test model for BESTEST weather data: ground reflectance"
  extends WD100(
    rho=0.2,
    weaDatHHorIR(
      filNam=Modelica.Utilities.Files.loadResource(
        "modelica://AixLib/Resources/Data/BoundaryConditions/Validation/BESTEST/WD600.mos")),
    weaDatTDryBulTDewPoinOpa(
      filNam=Modelica.Utilities.Files.loadResource(
        "modelica://AixLib/Resources/Data/BoundaryConditions/Validation/BESTEST/WD600.mos")));
end WD600;


Weather data reader

within AixLib.BoundaryConditions;
package WeatherData "Weather data reader"
  extends Modelica.Icons.VariantsPackage;
end WeatherData;