Skip to content

Commit

Permalink
Merge pull request #1495 from RWTH-EBC/1492-window-ventilation
Browse files Browse the repository at this point in the history
1492 window ventilation
  • Loading branch information
Jun-Jiang-92 authored Jul 16, 2024
2 parents c5d1547 + a54d83a commit e834573
Show file tree
Hide file tree
Showing 77 changed files with 4,007 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
within AixLib.Airflow.WindowVentilation.BaseClasses.Functions;
function CoeffsSunshadingInstallationVDI2078
"Calculate the sunshading coefficient based on its installation defined by VDI 2078"
extends Modelica.Icons.Function;
input AixLib.Airflow.WindowVentilation.BaseClasses.Types.SunshadingInstallationTypesVDI2078
typ "Sunshading type defined in VDI 2078";
output Real cof "Coefficient of sunshading";
algorithm
cof := if typ == AixLib.Airflow.WindowVentilation.BaseClasses.Types.SunshadingInstallationTypesVDI2078.NoSunshading
then 1.0 else if typ == AixLib.Airflow.WindowVentilation.BaseClasses.Types.SunshadingInstallationTypesVDI2078.ExternalBlindsFront
then 0.9 else if typ == AixLib.Airflow.WindowVentilation.BaseClasses.Types.SunshadingInstallationTypesVDI2078.ExternalBlindsOn
then 0.66 else if typ == AixLib.Airflow.WindowVentilation.BaseClasses.Types.SunshadingInstallationTypesVDI2078.Awning
then 1 else if typ == AixLib.Airflow.WindowVentilation.BaseClasses.Types.SunshadingInstallationTypesVDI2078.Screen
then 0.33 else 0;
annotation (Documentation(revisions="<html>
<ul>
<li>
June 14, 2024, by Jun Jiang:<br/>
First implementation (see <a href=\"https://github.com/RWTH-EBC/AixLib/issues/1492\">issue 1492</a>)
</li>
</ul>
</html>", info="<html>
<p>This function finds the sunshading coefficient according to the input sunshading type. Values are defined by VDI 2078.</p>
</html>"));
end CoeffsSunshadingInstallationVDI2078;
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
within AixLib.Airflow.WindowVentilation.BaseClasses.Functions.OpeningAreaHinged;
function AngleToWidth
"Conversion from the hinged opening angle to hinged opening width"
extends Modelica.Icons.Function;
input Modelica.Units.SI.Length lenAxs(min=0)
"Length of the hinged axis, the axis should be parallel to a window frame";
input Modelica.Units.SI.Length lenAxsToFrm(min=0)
"Distance from the hinged axis to the frame across the opening area";
input Modelica.Units.SI.Angle ang(min=0, max=Modelica.Constants.pi/2)
"Opening angle of window sash";
output Modelica.Units.SI.Length width(min=0) "Opening width of window sash";
algorithm
width := 2*lenAxsToFrm*sin(ang/2);
annotation (Documentation(revisions="<html>
<ul>
<li>
June 13, 2024, by Jun Jiang:<br/>
First implementation (see <a href=\"https://github.com/RWTH-EBC/AixLib/issues/1492\">issue 1492</a>)
</li>
</ul>
</html>", info="<html>
<p>This function converts the hinged opening angle to hinged opening width.</p>
</html>"));
end AngleToWidth;
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
within AixLib.Airflow.WindowVentilation.BaseClasses.Functions.OpeningAreaHinged;
function CoeffOpeningAreaDIN16798
"Coefficient for hinged opening area according to DIN CEN/TR 16798-8 (DIN SPEC 32739-8)"
extends Modelica.Icons.Function;
input Modelica.Units.SI.Angle ang(min=0, max=Modelica.Constants.pi/2)
"Window sash opening angle";
output Real cof "Coefficient";
protected
Modelica.Units.NonSI.Angle_deg angDeg "Window sash opening angle in deg";
algorithm
angDeg := Modelica.Units.Conversions.to_deg(ang);
assert(angDeg <= 90,
"The model only applies to a maximum tilt angle of 90°",
AssertionLevel.error);
cof := 2.6e-7*(angDeg^3) - 1.19e-4*(angDeg^2) + 1.86e-2*angDeg;
annotation (Documentation(revisions="<html>
<ul>
<li>
June 13, 2024, by Jun Jiang:<br/>
First implementation (see <a href=\"https://github.com/RWTH-EBC/AixLib/issues/1492\">issue 1492</a>)
</li>
</ul>
</html>", info="<html>
<p>This function calculates the coefficient for hinged opening area according to DIN CEN/TR 16798-8 (DIN SPEC 32739-8).</p>
</html>"));
end CoeffOpeningAreaDIN16798;
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
within AixLib.Airflow.WindowVentilation.BaseClasses.Functions.OpeningAreaHinged;
function EffectiveOpeningArea
"Calculation of the effective opening area"
extends Modelica.Icons.Function;
input Modelica.Units.SI.Area AClr(min=0) "Window clear opening area";
input Modelica.Units.SI.Area AEqv(min=0) "Window equivalent opening area";
input Modelica.Units.SI.Area AEqv90(min=0)
"Window equivalent opening area by 90° opening";
output Modelica.Units.SI.Area AEff(min=0) "Effective opening area";
algorithm
AEff := AEqv/AEqv90*AClr;
annotation (Documentation(revisions="<html>
<ul>
<li>
June 13, 2024, by Jun Jiang:<br/>
First implementation (see <a href=\"https://github.com/RWTH-EBC/AixLib/issues/1492\">issue 1492</a>)
</li>
</ul>
</html>", info="<html>
<p>This function calculates the effective opening area.</p>
</html>"));
end EffectiveOpeningArea;
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
within AixLib.Airflow.WindowVentilation.BaseClasses.Functions.OpeningAreaHinged;
function EquivalentOpeningArea
"Calculation of the equivalent opening area"
extends Modelica.Icons.Function;
input Modelica.Units.SI.Area AClr(min=0) "Window clear opening area";
input Modelica.Units.SI.Area AGeo(min=0) "Window geometric opening area";
output Modelica.Units.SI.Area AEqv(min=0) "Equivalent opening area";
algorithm
if (AClr<Modelica.Constants.eps) or (AGeo<Modelica.Constants.eps) then
AEqv := 0;
else
AEqv := (AClr^(-2) + AGeo^(-2))^(-0.5);
end if;
annotation (Documentation(revisions="<html>
<ul>
<li>
June 13, 2024, by Jun Jiang:<br/>
First implementation (see <a href=\"https://github.com/RWTH-EBC/AixLib/issues/1492\">issue 1492</a>)
</li>
</ul>
</html>", info="<html>
<p>This function calculates the equivalent opening area.</p>
</html>"));
end EquivalentOpeningArea;
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
within AixLib.Airflow.WindowVentilation.BaseClasses.Functions.OpeningAreaHinged;
function GeometricOpeningArea
"Calculation of the geometric opening area"
extends
AixLib.Airflow.WindowVentilation.BaseClasses.Functions.OpeningAreaHinged.PartialOpeningArea;
protected
Modelica.Units.SI.Angle ang=
AixLib.Airflow.WindowVentilation.BaseClasses.Functions.OpeningAreaHinged.WidthToAngle(
lenAxs, lenAxsToFrm, width) "Hinged opening angle";
Modelica.Units.SI.Area A1 "Opening area of oppsite side";
Modelica.Units.SI.Area A2 "Opening area of profile side";
algorithm
A1 := width*lenAxs;
A2 := 0.5*width*lenAxsToFrm*cos(ang/2);
A := A1 + 2*A2;
annotation (Documentation(revisions="<html>
<ul>
<li>
June 13, 2024, by Jun Jiang:<br/>
First implementation (see <a href=\"https://github.com/RWTH-EBC/AixLib/issues/1492\">issue 1492</a>)
</li>
</ul>
</html>", info="<html>
<p>This function calculates the geometric opening area.</p>
</html>"));
end GeometricOpeningArea;
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
within AixLib.Airflow.WindowVentilation.BaseClasses.Functions.OpeningAreaHinged;
partial function PartialOpeningArea
"Calculation of hinged-opening area by rectangular windows, unspecified types"
extends Modelica.Icons.Function;
input Modelica.Units.SI.Length lenAxs(min=0)
"Length of the hinged axis, the axis should be parallel to a window frame";
input Modelica.Units.SI.Length lenAxsToFrm(min=0)
"Distance from the hinged axis to the frame across the opening area";
input Modelica.Units.SI.Length width(min=0) "Opening width of window sash";
output Modelica.Units.SI.Area A(min=0) "Opening area";
annotation (Documentation(revisions="<html>
<ul>
<li>
June 13, 2024, by Jun Jiang:<br/>
First implementation (see <a href=\"https://github.com/RWTH-EBC/AixLib/issues/1492\">issue 1492</a>)
</li>
</ul>
</html>", info="<html>
<p>This partial function defines the inputs and output of the function for opening area calculation.</p>
</html>"));
end PartialOpeningArea;
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
within AixLib.Airflow.WindowVentilation.BaseClasses.Functions.OpeningAreaHinged;
function ProjectiveOpeningArea
"Calculation of the projective opening area"
extends
AixLib.Airflow.WindowVentilation.BaseClasses.Functions.OpeningAreaHinged.PartialOpeningArea;
protected
Modelica.Units.SI.Angle ang=
AixLib.Airflow.WindowVentilation.BaseClasses.Functions.OpeningAreaHinged.WidthToAngle(
lenAxs, lenAxsToFrm, width) "Hinged opening angle";
Modelica.Units.SI.Area A1 "Projective opening of oppsite side";
Modelica.Units.SI.Area A2 "Projectvie opening of profile side";
algorithm
A1 := lenAxs*lenAxsToFrm*(1 - cos(ang));
A2 := 0.5*lenAxsToFrm*sin(ang)*lenAxsToFrm*cos(ang);
A := A1 + 2*A2;
annotation (Documentation(revisions="<html>
<ul>
<li>
June 13, 2024, by Jun Jiang:<br/>
First implementation (see <a href=\"https://github.com/RWTH-EBC/AixLib/issues/1492\">issue 1492</a>)
</li>
</ul>
</html>", info="<html>
<p>This function calculates the projective opening area.</p>
</html>"));
end ProjectiveOpeningArea;
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
within AixLib.Airflow.WindowVentilation.BaseClasses.Functions.OpeningAreaHinged;
function WidthToAngle
"Conversion from the hinged opening width to hinged opening angle"
extends Modelica.Icons.Function;
input Modelica.Units.SI.Length lenAxs(min=0)
"Length of the hinged axis, the axis should be parallel to a window frame";
input Modelica.Units.SI.Length lenAxsToFrm(min=0)
"Distance from the hinged axis to the frame across the opening area";
input Modelica.Units.SI.Length width(min=0) "Opening width of window sash";
output Modelica.Units.SI.Angle ang(min=0, max=Modelica.Constants.pi/2)
"Opening angle of window sash";
algorithm
assert(width <= sqrt(2)*lenAxsToFrm,
"The opening angle should be less or equal than 90°",
AssertionLevel.error);
ang := 2*asin(width/(2*lenAxsToFrm));
annotation (Documentation(revisions="<html>
<ul>
<li>
June 13, 2024, by Jun Jiang:<br/>
First implementation (see <a href=\"https://github.com/RWTH-EBC/AixLib/issues/1492\">issue 1492</a>)
</li>
</ul>
</html>", info="<html>
<p>This function converts the hinged opening width to hinged opening angle.</p>
</html>"));
end WidthToAngle;
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
within AixLib.Airflow.WindowVentilation.BaseClasses.Functions;
package OpeningAreaHinged "Calculation of different hinged-opening areas by rectangular windows"
extends Modelica.Icons.FunctionsPackage;
end OpeningAreaHinged;
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
AngleToWidth
CoeffOpeningAreaDIN16798
EffectiveOpeningArea
EquivalentOpeningArea
GeometricOpeningArea
PartialOpeningArea
ProjectiveOpeningArea
WidthToAngle
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
within AixLib.Airflow.WindowVentilation.BaseClasses.Functions;
function SmallestAngleDifference
"Smallest difference between two angles around a point"
input AixLib.Airflow.WindowVentilation.BaseClasses.Types.SmallestAngleDifferenceTypes
typ=AixLib.Airflow.WindowVentilation.BaseClasses.Types.SmallestAngleDifferenceTypes.Range180;
input Modelica.Units.SI.Angle ang1 "Input angle";
input Modelica.Units.SI.Angle ang2=0 "Reference angle";
output Modelica.Units.SI.Angle angDif "Difference between two angels";
algorithm
angDif := ang1 - ang2;
if typ == AixLib.Airflow.WindowVentilation.BaseClasses.Types.SmallestAngleDifferenceTypes.Range180 then
/*Convert difference to -180°...+180°*/
while angDif <= -Modelica.Constants.pi loop
angDif := angDif + 2*Modelica.Constants.pi;
end while;
while angDif > Modelica.Constants.pi loop
angDif := angDif - 2*Modelica.Constants.pi;
end while;
elseif typ == AixLib.Airflow.WindowVentilation.BaseClasses.Types.SmallestAngleDifferenceTypes.Range360 then
/*Convert difference to 0...360°*/
while angDif < 0 loop
angDif := angDif + 2*Modelica.Constants.pi;
end while;
while angDif >= 2*Modelica.Constants.pi loop
angDif := angDif - 2*Modelica.Constants.pi;
end while;
else
/*Exceptions*/
angDif := 0;
end if;
annotation (Documentation(revisions="<html>
<ul>
<li>
June 13, 2024, by Jun Jiang:<br/>
First implementation (see <a href=\"https://github.com/RWTH-EBC/AixLib/issues/1492\">issue 1492</a>)
</li>
</ul>
</html>", info="<html>
<p>This function finds the smallest difference between two angles around a point.</p>
<p>The difference is calculated as input angle &apos;ang1&apos; to the reference angle &apos;ang2&apos;, positive value shows a clockwise direction from input to reference, i.e. shows a counter-clockwise by measurement.</p>
</html>"));
end SmallestAngleDifference;
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
within AixLib.Airflow.WindowVentilation.BaseClasses;
package Functions
extends Modelica.Icons.FunctionsPackage;
end Functions;
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
CoeffsSunshadingInstallationVDI2078
SmallestAngleDifference
OpeningAreaHinged
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
within AixLib.Airflow.WindowVentilation.BaseClasses;
partial model PartialEmpiricalFlow
"Partial model for empirical expressions of ventilation flow rate"
parameter Modelica.Units.SI.Length winClrWidth(min=0)
"Width of the window clear opening";
parameter Modelica.Units.SI.Height winClrHeight(min=0)
"Height of the window clear opening";
final parameter Boolean use_opnWidth_in=openingArea.use_opnWidth_in
"Use input port for window sash opening";
Modelica.Blocks.Interfaces.RealInput opnWidth_in(
final quantity="Length", final unit="m", min=0) if use_opnWidth_in
"Conditional input port for window sash opening width"
annotation (Placement(transformation(
extent={{-20,-20},{20,20}},
rotation=-90,
origin={0,120})));
Modelica.Blocks.Interfaces.RealOutput V_flow(
final quantity="VolumeFlowRate", final unit="m3/s", min=0)
"Ventilation flow rate"
annotation (Placement(transformation(extent={{100,-10},{120,10}})));
replaceable model OpeningArea =
AixLib.Airflow.WindowVentilation.BaseClasses.PartialOpeningArea
constrainedby
AixLib.Airflow.WindowVentilation.BaseClasses.PartialOpeningArea(
final winClrWidth=winClrWidth,
final winClrHeight=winClrHeight)
"Model for window opening area calculation"
annotation(choicesAllMatching=true);
OpeningArea openingArea "Model instance for window opening area calculation"
annotation (Placement(transformation(extent={{20,60},{40,80}})));
//Variables and parameters for assertion check
Real intRes
"Interim result used to check the if assertion is raised in root calculation";
Integer errCouIntRes(start=0) "Warning counter for interim result warnings";
parameter String varNameIntRes "Variable name of interim result";
initial equation
errCouIntRes = 0;
equation
// Assertion check
when intRes < Modelica.Constants.eps then
errCouIntRes = pre(errCouIntRes) + 1;
end when;
assert(intRes > Modelica.Constants.eps or errCouIntRes > 1,
"In " + getInstanceName() + ": The polynomial under the square root to
calculate '" + varNameIntRes + "' is equal or less than 0, '" +
varNameIntRes + "' will be set to 0",
AssertionLevel.warning);
// Connection(s)
connect(opnWidth_in, openingArea.opnWidth_in) annotation (Line(
points={{0,120},{0,70},{18,70}},
color={0,0,127},
pattern=DynamicSelect(LinePattern.Dash, if use_opnWidth_in then
LinePattern.Solid else LinePattern.Dash)));
annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram(
coordinateSystem(preserveAspectRatio=false)),
Documentation(revisions="<html>
<ul>
<li>
June 13, 2024, by Jun Jiang:<br/>
First implementation (see <a href=\"https://github.com/RWTH-EBC/AixLib/issues/1492\">issue 1492</a>)
</li>
</ul>
</html>", info="<html>
<p>This partial model provides a base class of models that estimate ventilation volume flow.</p>
</html>"));
end PartialEmpiricalFlow;
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
within AixLib.Airflow.WindowVentilation.BaseClasses;
partial model PartialEmpiricalFlowStack
"Partial model for empirical expressions with stack effect considered"
extends AixLib.Airflow.WindowVentilation.BaseClasses.PartialEmpiricalFlow;
Modelica.Blocks.Interfaces.RealInput TRoom(
final unit="K", min=273, max=313)
"Room temperature, ranging from 0 to 40 °C"
annotation (Placement(transformation(extent={{-140,60},{-100,100}})));
Modelica.Blocks.Interfaces.RealInput TAmb(
final unit="K", min=243, max=323)
"Ambient temperature, ranging from -30 to 50 °C"
annotation (Placement(transformation(extent={{-140,20},{-100,60}})));
protected
Modelica.Units.SI.TemperatureDifference dTRoomAmb = TRoom - TAmb
"Temperature difference between room and ambient";
Modelica.Units.SI.Temperature TAvg = (TRoom + TAmb)/2
"Average temperature of room and ambient";
annotation (Documentation(revisions="<html>
<ul>
<li>
June 13, 2024, by Jun Jiang:<br/>
First implementation (see <a href=\"https://github.com/RWTH-EBC/AixLib/issues/1492\">issue 1492</a>)
</li>
</ul>
</html>", info="<html>
<p>This partial model provides a base class of models that estimate ventilation volume flow. The model has indoor and ambient temperature input ports to account for the thermal stack effect.</p>
</html>"));
end PartialEmpiricalFlowStack;
Loading

0 comments on commit e834573

Please sign in to comment.