-
Notifications
You must be signed in to change notification settings - Fork 161
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3541 from SenHuang19/issue3538_Air2Air_recovery
Issue3538 air2air recovery
- Loading branch information
Showing
33 changed files
with
1,458 additions
and
0 deletions.
There are no files selected for viewing
165 changes: 165 additions & 0 deletions
165
Buildings/Fluid/HeatExchangers/AirToAirHeatRecovery/BaseClasses/EffectivenessCalculation.mo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,165 @@ | ||
within Buildings.Fluid.HeatExchangers.AirToAirHeatRecovery.BaseClasses; | ||
model EffectivenessCalculation | ||
"Model for calculating the heat exchange effectiveness of heat exchangers" | ||
extends Modelica.Blocks.Icons.Block; | ||
|
||
parameter Modelica.Units.SI.Efficiency epsS_cool_nominal(max=1) = 0.8 | ||
"Nominal sensible heat exchanger effectiveness at the cooling mode"; | ||
parameter Modelica.Units.SI.Efficiency epsL_cool_nominal(max=1) = 0.8 | ||
"Nominal latent heat exchanger effectiveness at the cooling mode"; | ||
parameter Modelica.Units.SI.Efficiency epsS_cool_partload(max=1) = 0.75 | ||
"Partial load (75%) sensible heat exchanger effectiveness at the cooling mode"; | ||
parameter Modelica.Units.SI.Efficiency epsL_cool_partload(max=1) = 0.75 | ||
"Partial load (75%) latent heat exchanger effectiveness at the cooling mode"; | ||
parameter Modelica.Units.SI.Efficiency epsS_heat_nominal(max=1) = 0.8 | ||
"Nominal sensible heat exchanger effectiveness at the heating mode"; | ||
parameter Modelica.Units.SI.Efficiency epsL_heat_nominal(max=1) = 0.8 | ||
"Nominal latent heat exchanger effectiveness at the heating mode"; | ||
parameter Modelica.Units.SI.Efficiency epsS_heat_partload(max=1) = 0.75 | ||
"Partial load (75%) sensible heat exchanger effectiveness at the heating mode"; | ||
parameter Modelica.Units.SI.Efficiency epsL_heat_partload(max=1) = 0.75 | ||
"Partial load (75%) latent heat exchanger effectiveness at the heating mode"; | ||
parameter Modelica.Units.SI.VolumeFlowRate v_flow_sup_nominal(min = 100*Modelica.Constants.eps) | ||
"Nominal supply air flow rate"; | ||
|
||
Modelica.Blocks.Interfaces.RealInput TSup( | ||
final min=0, | ||
final unit="K", | ||
final displayUnit="degC") | ||
"Supply air temperature" | ||
annotation (Placement(transformation(extent={{-140,20},{-100,60}}))); | ||
Modelica.Blocks.Interfaces.RealInput TExh( | ||
final min=0, | ||
final unit="K", | ||
final displayUnit="degC") | ||
"Exhaust air temperature | ||
" annotation (Placement(transformation(extent={{-140,-20},{-100,20}}))); | ||
Modelica.Blocks.Interfaces.RealInput v_flow_Sup(final unit="m3/s") | ||
"Volumetric flow rate of the supply air" | ||
annotation (Placement(transformation(extent={{-140,-60},{-100,-20}}))); | ||
Modelica.Blocks.Interfaces.RealInput v_flow_Exh( final unit="m3/s") | ||
"Volumetric flow rate of the exhaust air" | ||
annotation (Placement(transformation(extent={{-140,-100},{-100,-60}}))); | ||
Modelica.Blocks.Interfaces.RealInput y(final unit="1") "Wheel speed ratio" | ||
annotation (Placement(transformation(extent={{-140,60},{-100,100}}))); | ||
Modelica.Blocks.Interfaces.RealOutput epsS(final unit="1") | ||
"Sensible heat exchanger effectiveness" | ||
annotation (Placement(transformation(extent={{100,30},{120,50}}))); | ||
Modelica.Blocks.Interfaces.RealOutput epsL(final unit="1") | ||
"Latent heat exchanger effectivenessr" | ||
annotation (Placement(transformation(extent={{100,-50},{120,-30}}))); | ||
|
||
protected | ||
Real vRat | ||
"Ratio of the average operating volumetric air flow rate to the nominal supply air flow rate"; | ||
|
||
algorithm | ||
// calculate effectiveness | ||
if TSup > TExh then | ||
// cooling mode | ||
epsS :=y*(epsS_cool_partload + (epsS_cool_nominal - epsS_cool_partload)*( | ||
vRat-0.75)/0.25); | ||
epsL :=y*(epsL_cool_partload + (epsL_cool_nominal - epsL_cool_partload)*( | ||
vRat-0.75)/0.25); | ||
else | ||
// heating mode | ||
epsS :=y*(epsS_heat_partload + (epsS_heat_nominal - epsS_heat_partload)*( | ||
vRat-0.75)/0.25); | ||
epsL :=y*(epsL_heat_partload + (epsL_heat_nominal - epsL_heat_partload)*( | ||
vRat-0.75)/0.25); | ||
end if; | ||
epsS := Buildings.Utilities.Math.Functions.smoothMax( | ||
x1 = 0.01, | ||
x2 = epsS, | ||
deltaX = 1E-7); | ||
epsS := Buildings.Utilities.Math.Functions.smoothMin( | ||
x1 = 0.99, | ||
x2 = epsS, | ||
deltaX = 1E-7); | ||
|
||
epsL := Buildings.Utilities.Math.Functions.smoothMax( | ||
x1 = 0.01, | ||
x2 = epsL, | ||
deltaX = 1E-7); | ||
epsL := Buildings.Utilities.Math.Functions.smoothMin( | ||
x1 = 0.99, | ||
x2 = epsL, | ||
deltaX = 1E-7); | ||
|
||
equation | ||
// check if the extrapolation goes too far | ||
assert(v_flow_Sup - 2*v_flow_Exh < 0 or v_flow_Exh - 2*v_flow_Sup < 0, | ||
"Unbalanced air flow ratio", | ||
level=AssertionLevel.warning); | ||
// calculate the average volumetric air flow and flow rate ratio | ||
vRat = (v_flow_Sup + v_flow_Exh)/2/v_flow_sup_nominal; | ||
// check if the extrapolation goes too far | ||
assert(vRat > 0.5 and vRat < 1.3, | ||
"Operatiing flow rate outside full accuracy range", | ||
level=AssertionLevel.warning); | ||
annotation (Icon(coordinateSystem(preserveAspectRatio=false), graphics={Text( | ||
extent={{-54,28},{50,-40}}, | ||
textColor={28,108,200}, | ||
textString="eps")}), Diagram( | ||
coordinateSystem(preserveAspectRatio=false)), | ||
defaultComponentName="EffCal", | ||
Documentation(info="<html> | ||
<p> | ||
This block calculates the sensible and latent effectiveness of the heat exchanger for heating and cooling conditions | ||
at different air flow rates of the supply air stream and the exhaust air stream. | ||
</p> | ||
<p> It first calculates the average volumetric air flow rate through the heat exchanger by:</p> | ||
<pre> | ||
v_ave = (v_sup + v_exh)/2, | ||
vRat = v_ave/v_sup_nom, | ||
</pre> | ||
<p> | ||
where <code>v_ave</code> is the average volumetric air flow rate, | ||
<code>v_sup</code> is the air flow of the supply air stream, | ||
<code>v_exh</code> is the air flow of the exhaust air stream, | ||
<code>v_sup_nom</code> is the nominal air flow of the supply air stream and | ||
<code>vRat</code> is the flow ratio. | ||
</p> | ||
<p> It then calculates the sensible and latent effectiveness by:</p> | ||
<pre> | ||
epsS = y * (epsS_75 + (epsS_100 - epsS_75) * (vRat - 0.75)/0.25), | ||
epsL = y * (epsL_75 + (epsL_100 - epsL_75) * (vRat - 0.75)/0.25), | ||
</pre> | ||
where <code>epsS</code> and <code>epsL</code> are the effectiveness | ||
for the sensible and latent heat transfer, respectively. | ||
<code>epsS_100</code> and <code>epsS_75</code> are the effectiveness | ||
for the sensible heat transfer when <code>vRat</code> is 1 and 0.75, respectively. | ||
<code>epsL_100</code> and <code>epsL_75</code> are the effectiveness | ||
for the latent heat transfer when <code>vRat</code> is 1 and 0.75, respectively. | ||
<code>y</code> is an effectiveness associated with the speed of a rotary wheel. | ||
<p> | ||
<code>epsS_100</code>, <code>epsS_75</code>, <code>epsL_100</code>, and <code>epsL_75</code> are parameters. | ||
Depending on the cooling or heating mode, their values are different. | ||
In this model, if the supply air temperature is larger than the exhaust air temperature, the exchanger is considered to operate under | ||
the cooling mode; | ||
Otherwise, it is considered to operate under a heating mode. | ||
</p> | ||
<P> | ||
<b>Note:</b> The average volumetric air flow rate should be between 50% and 130% of the nominal supply air flow rate. | ||
In addition, the ratio of the supply air flow rate to the exhaust air flow rate should be between 0.5 and 2. | ||
</P> | ||
<h4>References</h4> | ||
U.S. Department of Energy 2016. | ||
"EnergyPlus Engineering reference". | ||
</html>", revisions="<html> | ||
<ul> | ||
<li> | ||
September 29, 2023, by Sen Huang:<br/> | ||
First implementation<br/> | ||
</li> | ||
</ul> | ||
</html>")); | ||
end EffectivenessCalculation; |
183 changes: 183 additions & 0 deletions
183
...uid/HeatExchangers/AirToAirHeatRecovery/BaseClasses/HeatExchagerWithInputEffectiveness.mo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,183 @@ | ||
within Buildings.Fluid.HeatExchangers.AirToAirHeatRecovery.BaseClasses; | ||
model HeatExchagerWithInputEffectiveness | ||
"Heat and moisture exchanger with varying effectiveness" | ||
extends Buildings.Fluid.HeatExchangers.BaseClasses.PartialEffectiveness( | ||
redeclare replaceable package Medium1 = | ||
Modelica.Media.Interfaces.PartialCondensingGases, | ||
redeclare replaceable package Medium2 = | ||
Modelica.Media.Interfaces.PartialCondensingGases, | ||
sensibleOnly1=false, | ||
sensibleOnly2=false, | ||
final prescribedHeatFlowRate1=true, | ||
final prescribedHeatFlowRate2=true, | ||
Q1_flow = epsS * QMax_flow + QLat_flow, | ||
Q2_flow = -Q1_flow, | ||
mWat1_flow = +mWat_flow, | ||
mWat2_flow = -mWat_flow); | ||
|
||
Modelica.Blocks.Interfaces.RealInput epsS(unit="1") | ||
"Sensible heat exchanger effectiveness" | ||
annotation (Placement(transformation(extent={{-140,20},{-100,60}}))); | ||
Modelica.Blocks.Interfaces.RealInput epsL(unit="1") | ||
"Latent heat exchanger effectiveness" | ||
annotation (Placement(transformation(extent={{-140,-60},{-100,-20}}))); | ||
Modelica.Units.SI.HeatFlowRate QLat_flow | ||
"Latent heat exchange from medium 2 to medium 1"; | ||
Medium1.MassFraction X_w_in1 | ||
"Inlet water mass fraction of medium 1"; | ||
Medium2.MassFraction X_w_in2 | ||
"Inlet water mass fraction of medium 2"; | ||
Modelica.Units.SI.MassFlowRate mWat_flow | ||
"Water flow rate from medium 2 to medium 1"; | ||
Modelica.Units.SI.MassFlowRate mMax_flow | ||
"Maximum water flow rate from medium 2 to medium 1"; | ||
|
||
protected | ||
parameter Integer i1_w(min=1, fixed=false) "Index for water substance"; | ||
parameter Integer i2_w(min=1, fixed=false) "Index for water substance"; | ||
Real gai1(min=0, max=1) "Auxiliary variable for smoothing at zero flow"; | ||
Real gai2(min=0, max=1) "Auxiliary variable for smoothing at zero flow"; | ||
|
||
initial algorithm | ||
i1_w:= -1; | ||
i2_w:= -1; | ||
for i in 1:Medium1.nXi loop | ||
if Modelica.Utilities.Strings.isEqual(string1=Medium1.substanceNames[i], | ||
string2="Water", | ||
caseSensitive=false) then | ||
i1_w := i; | ||
end if; | ||
end for; | ||
for i in 1:Medium2.nXi loop | ||
if Modelica.Utilities.Strings.isEqual(string1=Medium2.substanceNames[i], | ||
string2="Water", | ||
caseSensitive=false) then | ||
i2_w := i; | ||
end if; | ||
end for; | ||
assert(i1_w > 0, "Substance 'water' is not present in Medium1 '" | ||
+ Medium1.mediumName + "'.\n" | ||
+ "Check medium model."); | ||
assert(i2_w > 0, "Substance 'water' is not present in Medium2 '" | ||
+ Medium2.mediumName + "'.\n" | ||
+ "Check medium model."); | ||
equation | ||
// Definitions for effectiveness model | ||
X_w_in1 = Modelica.Fluid.Utilities.regStep(m1_flow, | ||
state_a1_inflow.X[i1_w], | ||
state_b1_inflow.X[i1_w], m1_flow_small); | ||
X_w_in2 = Modelica.Fluid.Utilities.regStep(m2_flow, | ||
state_a2_inflow.X[i2_w], | ||
state_b2_inflow.X[i2_w], m2_flow_small); | ||
|
||
// mass exchange | ||
// Compute a gain that goes to zero near zero flow rate. | ||
// This is required to smoothen the heat transfer at very small flow rates. | ||
// Note that gaiK = 1 for abs(mK_flow) > mK_flow_small | ||
gai1 = Modelica.Fluid.Utilities.regStep(abs(m1_flow) - 0.75*m1_flow_small, | ||
1, 0, 0.25*m1_flow_small); | ||
gai2 = Modelica.Fluid.Utilities.regStep(abs(m2_flow) - 0.75*m2_flow_small, | ||
1, 0, 0.25*m2_flow_small); | ||
|
||
mMax_flow = smooth(1, min(smooth(1, gai1 * abs(m1_flow)), | ||
smooth(1, gai2 * abs(m2_flow)))) * (X_w_in2 - X_w_in1); | ||
mWat_flow = epsL * mMax_flow; | ||
// As enthalpyOfCondensingGas is dominated by the latent heat of phase change, | ||
// we simplify and use Medium1.enthalpyOfVaporization for the | ||
// latent heat that is exchanged among the fluid streams. | ||
// This is simply added to QSen_flow, while mass is conserved because | ||
// of the assignment of mWat1_flow and mWat2_flow. | ||
QLat_flow = mWat_flow * Medium1.enthalpyOfVaporization(Medium1.T_default); | ||
|
||
annotation ( | ||
Icon(coordinateSystem(preserveAspectRatio=false, extent={{-100, | ||
-100},{100,100}}), graphics={ | ||
Rectangle( | ||
extent={{-70,80},{70,-80}}, | ||
lineColor={0,0,255}, | ||
pattern=LinePattern.None, | ||
fillColor={0,62,0}, | ||
fillPattern=FillPattern.Solid), | ||
Text( | ||
extent={{-62,50},{48,-10}}, | ||
textColor={255,255,255}, | ||
textString="epsS=%epsS"), | ||
Text( | ||
extent={{-60,4},{50,-56}}, | ||
textColor={255,255,255}, | ||
textString="epsL=%epsL")}), | ||
preferredView="info", | ||
defaultComponentName="hexInpEff", | ||
Documentation(info="<html> | ||
<p> | ||
This block is identical to | ||
<a href=\"modelica://Buildings.Fluid.MassExchangers.ConstantEffectiveness\"> | ||
Buildings.Fluid.MassExchangers.ConstantEffectivenesst</a>, | ||
except that the effectiveness are inputs rather than parameters. | ||
</p> | ||
This model transfers heat and moisture in the amount of | ||
<pre> | ||
QSen = epsS * Q_max, | ||
m = epsL * mWat_max, | ||
</pre> | ||
where <code>epsS</code> and <code>epsL</code> are input effectiveness | ||
for the sensible and latent heat transfer, | ||
<code>Q_max</code> is the maximum sensible heat that can be transferred and | ||
<code>mWat_max</code> is the maximum moisture that can be transferred. | ||
This model can only be used with medium models that define the integer constant | ||
<code>Water</code> which needs to be equal to the index of the water mass fraction | ||
in the species vector. | ||
</html>", | ||
revisions="<html> | ||
<ul> | ||
<li> | ||
September 29, 2023, by Sen Huang:<br/> | ||
Changing the effectiveness from parameters to inputs<br/> | ||
</li> | ||
<li> | ||
April 30, 2018, by Filip Jorissen:<br/> | ||
Set <code>final prescribedHeatFlowRate1=true</code> and | ||
<code>final prescribedHeatFlowRate2=true</code>.<br/> | ||
See | ||
<a href=\"https://github.com/ibpsa/modelica-ibpsa/issues/907\">#907</a>. | ||
</li> | ||
<li> | ||
April 11, 2017, by Michael Wetter:<br/> | ||
Corrected bug as <code>Q1_flow</code> did not include latent heat flow rate.<br/> | ||
This is for issue | ||
<a href=\"https://github.com/lbl-srg/modelica-buildings/issues/704\">Buildings #704</a>. | ||
</li> | ||
<li> | ||
October 14, 2013 by Michael Wetter:<br/> | ||
Replaced access to constant <code>Medium1.Water</code> by introducing | ||
the parameter <code>i1_w</code>, and used a similar construct for | ||
<code>Medium2</code>. | ||
This avoids an error during model check as these constants are not known | ||
in the partial medium model. | ||
</li> | ||
<li> | ||
August 13, 2013 by Michael Wetter:<br/> | ||
Corrected error in the documentation. | ||
</li> | ||
<li> | ||
July 30, 2013 by Michael Wetter:<br/> | ||
Updated model to use new variable <code>mWat_flow</code> | ||
in the base class. | ||
</li> | ||
<li> | ||
January 28, 2010, by Michael Wetter:<br/> | ||
Added regularization near zero flow. | ||
</li> | ||
<li> | ||
October 21, 2008, by Michael Wetter:<br/> | ||
First implementation, based on | ||
<a href=\"modelica://Buildings.Fluid.HeatExchangers.ConstantEffectiveness\"> | ||
Buildings.Fluid.HeatExchangers.ConstantEffectiveness</a>. | ||
</li> | ||
</ul> | ||
</html>")); | ||
end HeatExchagerWithInputEffectiveness; |
Oops, something went wrong.