Skip to content

Commit

Permalink
Merge pull request #4088 from SenHuang19/issue3538_Air2Air_recovery
Browse files Browse the repository at this point in the history
Issue3538 air2 air recovery
  • Loading branch information
JayHuLBL authored Jan 15, 2025
2 parents d9f6b54 + b1d93c1 commit 566a56e
Show file tree
Hide file tree
Showing 42 changed files with 461 additions and 682 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,28 @@ model VariableSpeedThermalWheels
extends Modelica.Icons.Example;
parameter Buildings.Fluid.HeatExchangers.ThermalWheels.Data.ASHRAE
perSenWhe(
motorEfficiency(uSpe={0.1,0.6,0.8,1}, eta={0.3,0.8,0.85,1}),
mSup_flow_nominal=1,
mExh_flow_nominal=1,
motorEfficiency(uSpe={0.1,0.6,0.8,1},
eta={0.3,0.8,0.85,1}),
haveLatentHeatExchange=false,
useDefaultMotorEfficiencyCurve=false)
"Performance record for the sensible heat wheel"
annotation (Placement(transformation(extent={{-80,74},{-60,94}})));
parameter Buildings.Fluid.HeatExchangers.ThermalWheels.Data.ASHRAE perLatWhe(
motorEfficiency(uSpe={0.1,0.6,0.8,1}, eta={0.3,0.8,0.85,1}),
parameter Buildings.Fluid.HeatExchangers.ThermalWheels.Data.ASHRAE
perLatWhe(
mSup_flow_nominal=1,
mExh_flow_nominal=1,
motorEfficiency(uSpe={0.1,0.6,0.8,1},
eta={0.3,0.8,0.85,1}),
haveLatentHeatExchange=true,
useDefaultMotorEfficiencyCurve=false)
"Performance record for the enthalpy wheel"
annotation (Placement(transformation(extent={{-40,74},{-20,94}})));
parameter Buildings.Fluid.HeatExchangers.ThermalWheels.Data.ASHRAE perLatWheDefMotCur(
parameter Buildings.Fluid.HeatExchangers.ThermalWheels.Data.ASHRAE
perLatWheDefMotCur(
mSup_flow_nominal=1,
mExh_flow_nominal=1,
haveLatentHeatExchange=true,
useDefaultMotorEfficiencyCurve=true)
"Performance record for the enthalpy wheel with default motor dataset"
Expand All @@ -24,19 +34,20 @@ model VariableSpeedThermalWheels
senWhe(per=perSenWhe)
"Sensible heat wheel"
annotation (Placement(transformation(extent={{-10,40},{10,60}})));

Modelica.Blocks.Sources.Ramp uSpe(
duration=1,
startTime=0,
offset=0,
height=1)
"Speed ratio"
annotation (Placement(transformation(extent={{-60,-10},{-40,10}})));
Buildings.Fluid.HeatExchangers.ThermalWheels.BaseClasses.SpeedCorrectionLatent latWhe(
Buildings.Fluid.HeatExchangers.ThermalWheels.BaseClasses.SpeedCorrectionLatent
latWhe(
per=perLatWhe)
"Enthalpy wheel"
annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
Buildings.Fluid.HeatExchangers.ThermalWheels.BaseClasses.SpeedCorrectionLatent latWheDefMotCur(
Buildings.Fluid.HeatExchangers.ThermalWheels.BaseClasses.SpeedCorrectionLatent
latWheDefMotCur(
per=perLatWheDefMotCur)
"Enthalpy wheel with default motor curve"
annotation (Placement(transformation(extent={{-10,-60},{10,-40}})));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
within Buildings.Fluid.HeatExchangers.ThermalWheels.Data;
record ASHRAE = Buildings.Fluid.HeatExchangers.ThermalWheels.Data.Generic(
final haveVariableSpeed=true,
senHeatExchangeEffectiveness(
uSpe={0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1},
epsCor={0,0.40,0.71,0.83,0.90,0.93,0.96,0.97,0.98,0.99,1}),
Expand Down
74 changes: 56 additions & 18 deletions Buildings/Fluid/HeatExchangers/ThermalWheels/Data/Generic.mo
Original file line number Diff line number Diff line change
@@ -1,37 +1,71 @@
within Buildings.Fluid.HeatExchangers.ThermalWheels.Data;
record Generic "Generic data record for variable-speed wheels"
record Generic "Generic data record for thermal wheels"
extends Modelica.Icons.Record;

parameter Modelica.Units.SI.MassFlowRate mSup_flow_nominal
"Nominal supply air mass flow rate"
annotation (Dialog(group="Nominal condition"));
parameter Modelica.Units.SI.MassFlowRate mExh_flow_nominal
"Nominal exhaust air mass flow rate"
annotation (Dialog(group="Nominal condition"));
parameter Modelica.Units.SI.PressureDifference dpSup_nominal(displayUnit="Pa")=500
"Nominal supply air pressure drop across the heat exchanger"
annotation (Dialog(group="Nominal condition"));
parameter Modelica.Units.SI.PressureDifference dpExh_nominal(displayUnit="Pa")=dpSup_nominal
"Nominal exhaust air pressure drop across the heat exchanger"
annotation (Dialog(group="Nominal condition"));
parameter Real P_nominal(final unit="W")=100
"Power consumption at the design condition";
"Power consumption at the design condition"
annotation (Dialog(group="Nominal condition"));
parameter Modelica.Units.SI.Efficiency epsSen_nominal(
final max=1)=0.8
"Nominal sensible heat exchanger effectiveness"
annotation (Dialog(group="Nominal condition"));
parameter Modelica.Units.SI.Efficiency epsSenPL(
final max=1)=0.75
"Part load (75% of the nominal supply flow rate) sensible heat exchanger effectiveness"
annotation (Dialog(group="Part load effectiveness"));
parameter Modelica.Units.SI.Efficiency epsLat_nominal(
final max=1)=0.8
"Nominal latent heat exchanger effectiveness"
annotation (Dialog(group="Nominal condition"),
enable=haveLatentHeatExchange);
parameter Modelica.Units.SI.Efficiency epsLatPL(
final max=1)=0.75
"Part load (75% of the nominal supply mass flow rate) latent heat exchanger effectiveness"
annotation (Dialog(group="Part load effectiveness"),
enable=haveLatentHeatExchange);
parameter Characteristics.HeatExchangerEffectiveness senHeatExchangeEffectiveness(
uSpe={0},
epsCor={0.7})
"Multiplication factor for sensible heat exchange effectiveness due to wheel speed ratio between 0 and 1"
annotation (Dialog(group="Heat exchange effectiveness computation"));
annotation (Dialog(group="Heat exchange effectiveness computation",
enable=haveVariableSpeed));
parameter Characteristics.HeatExchangerEffectiveness latHeatExchangeEffectiveness(
uSpe={0},
epsCor={0.7})
"Multiplication factor for latent heat exchange effectiveness due to wheel speed ratio between 0 and 1" annotation (
Dialog(group="Heat exchange effectiveness computation", enable=
haveLatentHeatExchange));
"Multiplication factor for latent heat exchange effectiveness due to wheel speed ratio between 0 and 1"
annotation (Dialog(group="Heat exchange effectiveness computation",
enable=haveLatentHeatExchange and haveVariableSpeed));
parameter Characteristics.MotorEfficiency motorEfficiency(
uSpe={0},
eta={0.7})
"Motor efficiency versus wheel speed ratio"
annotation (Dialog(group="Power computation", enable=useDefaultMotorEfficiencyCurve ==
false));
annotation (Dialog(group="Power computation",
enable=haveVariableSpeed));
final parameter Buildings.Fluid.Movers.BaseClasses.Characteristics.efficiencyParameters_yMot
motorEfficiency_default=Buildings.Fluid.Movers.BaseClasses.Characteristics.motorEfficiencyCurve(
P_nominal=P_nominal,
eta_max=1)
"Motor efficiency versus default wheel speed ratio"
annotation (Dialog(group="Power computation", enable=useDefaultMotorEfficiencyCurve ==
true));
parameter Boolean haveLatentHeatExchange = true
annotation (Dialog(group="Power computation"));
parameter Boolean haveLatentHeatExchange=true
"Set to true to compute latent heat exchange";
parameter Boolean useDefaultMotorEfficiencyCurve = true
"Set to true to use default motor efficiency curve";
parameter Boolean useDefaultMotorEfficiencyCurve=true
"Set to true to use default motor efficiency curve"
annotation (Dialog(enable=haveVariableSpeed));
parameter Boolean haveVariableSpeed=true
"Set to true for the heat recovery wheel with a variable speed drive";

annotation (
defaultComponentPrefixes = "parameter",
Expand All @@ -45,16 +79,20 @@ First implementation.
</ul>
</html>", info="<html>
<p>
Record containing power and heat exchange parameters for variable-speed thermal wheels.
Record containing performance-related parameters for thermal wheels.
</p>
<p>
It is used as a template of performance data
for the variable-speed wheel models in
for the thermal wheel models in
<a href=\"modelica://Buildings.Fluid.HeatExchangers.ThermalWheels.BaseClasses\">
Buildings.Fluid.HeatExchangers.ThermalWheels.BaseClasses</a>.
</p>
<p>
The record contains four datasets:
The record contains the parameters, including the nominal mass flow rates, nominal pressure drops,
and the heat exchanger effectiveness at part load (75% of the nominal supply flow rate) and at nominal conditions.
</p>
<p>
For the variable-speed thermal wheel (<code>haveVariableSpeed=true</code>), the record also includes the following datasets:
</p>
<ul>
<li>
Expand Down Expand Up @@ -86,12 +124,12 @@ corrections versus wheel speed ratio are correction factors that are multiplied
with the heat exchange effectiveness that the wheel has a full rotational speed.
</li>
<li>
When <code>haveLatentHeatExchange = true</code>,
When <code>haveLatentHeatExchange=true</code>,
the dataset of the latent heat exchange effectiveness
corrections versus wheel speed ratio is enabled,
</li>
<li>
When <code>useDefaultMotorEfficiencyCurve = true</code>,
When <code>useDefaultMotorEfficiencyCurve=true</code>,
the motor efficiency versus wheel speed ratio is disabled,
and the default motor percent full-load
efficiency versus wheel speed ratio is enabled.
Expand Down
4 changes: 2 additions & 2 deletions Buildings/Fluid/HeatExchangers/ThermalWheels/Data/package.mo
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
within Buildings.Fluid.HeatExchangers.ThermalWheels;
package Data "Performance data for variable-speed wheels"
package Data "Performance data for thermal wheels"
extends Modelica.Icons.MaterialPropertiesPackage;

annotation (Documentation(info="<html>
<p>
This package contains performance data sets for variable-speed thermal wheels.
This package contains performance data sets for thermal wheels.
</p>
</html>"));
end Data;
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,22 @@ within Buildings.Fluid.HeatExchangers.ThermalWheels.Latent.BaseClasses;
model Effectiveness
"Model for calculating the heat exchange effectiveness"
extends Modelica.Blocks.Icons.Block;
parameter Modelica.Units.SI.Efficiency epsSenCoo_nominal(final max=1)
"Nominal sensible heat exchanger effectiveness at the cooling mode";
parameter Modelica.Units.SI.Efficiency epsLatCoo_nominal(final max=1)
"Nominal latent heat exchanger effectiveness at the cooling mode";
parameter Modelica.Units.SI.Efficiency epsSenCooPL(final max=1)
"Part load (75% of the nominal supply flow rate) sensible heat exchanger effectiveness at the cooling mode";
parameter Modelica.Units.SI.Efficiency epsLatCooPL(final max=1)
"Part load (75% of the nominal supply flow rate) latent heat exchanger effectiveness at the cooling mode";
parameter Modelica.Units.SI.Efficiency epsSenHea_nominal(final max=1)
"Nominal sensible heat exchanger effectiveness at the heating mode";
parameter Modelica.Units.SI.Efficiency epsLatHea_nominal(final max=1)
"Nominal latent heat exchanger effectiveness at the heating mode";
parameter Modelica.Units.SI.Efficiency epsSenHeaPL(final max=1)
"Part load (75% of the nominal supply flow rate) sensible heat exchanger effectiveness at the heating mode";
parameter Modelica.Units.SI.Efficiency epsLatHeaPL(final max=1)
"Part load (75% of the nominal supply flow rate) latent heat exchanger effectiveness at the heating mode";
parameter Modelica.Units.SI.Efficiency epsSen_nominal(final max=1)
"Nominal sensible heat exchanger effectiveness";
parameter Modelica.Units.SI.Efficiency epsLat_nominal(final max=1)
"Nominal latent heat exchanger effectiveness";
parameter Modelica.Units.SI.Efficiency epsSenPL(final max=1)
"Part load (75% of the nominal supply flow rate) sensible heat exchanger effectiveness";
parameter Modelica.Units.SI.Efficiency epsLatPL(final max=1)
"Part load (75% of the nominal supply flow rate) latent heat exchanger effectiveness";
parameter Modelica.Units.SI.MassFlowRate mSup_flow_nominal
"Nominal supply air mass flow rate";

Buildings.Controls.OBC.CDL.Interfaces.RealInput TSup(
final unit="K")
"Supply air temperature"
annotation (Placement(transformation(extent={{-140,-60},{-100,-20}})));
Buildings.Controls.OBC.CDL.Interfaces.RealInput TExh(
final unit="K")
"Exhaust air temperature"
annotation (Placement(transformation(extent={{-140,-100},{-100,-60}})));
Buildings.Controls.OBC.CDL.Interfaces.RealInput mSup_flow(final unit="kg/s")
"Supply air mass flow rate"
annotation (Placement(transformation(extent={{-140,60},{-100,100}})));
annotation (Placement(transformation(extent={{-140,40},{-100,80}})));
Buildings.Controls.OBC.CDL.Interfaces.RealInput mExh_flow(final unit="kg/s")
"Exhaust air mass flow rate"
annotation (Placement(transformation(extent={{-140,20},{-100,60}})));
annotation (Placement(transformation(extent={{-140,-80},{-100,-40}})));
Buildings.Controls.OBC.CDL.Interfaces.RealOutput epsSen(final unit="1")
"Sensible heat exchanger effectiveness"
annotation (Placement(transformation(extent={{100,30},{140,70}}),
Expand All @@ -45,58 +28,28 @@ model Effectiveness
iconTransformation(extent={{100,-70},{140,-30}})));

protected
parameter Boolean equSen_nominal = abs(epsSenCoo_nominal-epsSenHea_nominal) < Modelica.Constants.eps
"true if the sensible cooling and heating efficiencies at nominal conditions are equal";
parameter Boolean equSenPL = abs(epsSenCooPL-epsSenHeaPL) < Modelica.Constants.eps
"true if the sensible cooling and heating efficiencies at part load conditions are equal";
parameter Boolean equLat_nominal = abs(epsLatCoo_nominal-epsLatHea_nominal) < Modelica.Constants.eps
"true if the latent cooling and heating efficiencies at nominal conditions are equal";
parameter Boolean equLatPL = abs(epsLatCooPL-epsLatHeaPL) < Modelica.Constants.eps
"true if the latent cooling and heating efficiencies at part load conditions are equal";
Real fraCoo(
final min=0,
final max=1,
final unit="1") "Fraction of efficiency contribution from cooling parameters (used for regularization)";

Real rat
"Ratio of the average operating air flow rate to the nominal supply air flow rate";
Real ratRes
"Ratio of the average operating air flow rate to the nominal supply air flow rate, restricted to valid domain";
Modelica.Units.SI.Efficiency epsSenPL
"Part load sensible heat exchanger effectiveness used for calculation";
Modelica.Units.SI.Efficiency epsSen_nominal
"Nominal sensible heat exchanger effectiveness used for calculation";
Modelica.Units.SI.Efficiency epsLatPL
"Part load latent heat exchanger effectiveness used for calculation";
Modelica.Units.SI.Efficiency epsLat_nominal
"Nominal latent heat exchanger effectiveness used for calculation";

equation
// Calculate the average volumetric air flow and flow rate ratio.
rat=(mSup_flow+mExh_flow)/2/mSup_flow_nominal;
// Check if the air flows are too unbalanced, unless rat < 0.05, in which case
// the system is likely off or transitioning to on or off.
assert(rat < 0.05 or (mSup_flow - 2*mExh_flow <= 1e-5 and mExh_flow - 2*mSup_flow <= 1e-5),
assert(rat<0.05 or (mSup_flow-2*mExh_flow<1e-5 and mExh_flow-2*mSup_flow<1e-5),
"In " + getInstanceName() + ": The ratio of the supply flow rate to the exhaust flow rate should be in the range of [0.5, 2] when flow rates are non-zero.",
level=AssertionLevel.warning);
// Calculate the average volumetric air flow and flow rate ratio.
rat = (mSup_flow+mExh_flow)/2/mSup_flow_nominal;
// Switch between cooling and heating modes based on the difference between the supply air temperature and the exhaust air temperature
fraCoo = if (equSen_nominal and equSenPL and equLat_nominal and equLatPL) then 0.5 else Buildings.Utilities.Math.Functions.regStep(TSup-TExh, 1, 0, 1e-5);

epsSenPL = if equSenPL then epsSenCooPL else fraCoo*epsSenCooPL + (1-fraCoo) * epsSenHeaPL;
epsSen_nominal = if equSen_nominal then epsSenCoo_nominal else fraCoo*epsSenCoo_nominal + (1-fraCoo) * epsSenHea_nominal;

epsLatPL = if equLatPL then epsLatCooPL else fraCoo*epsLatCooPL + (1-fraCoo) * epsLatHeaPL;
epsLat_nominal = if equLat_nominal then epsLatCoo_nominal else fraCoo*epsLatCoo_nominal + (1-fraCoo) * epsLatHea_nominal;

// Calculate effectiveness
ratRes = Buildings.Utilities.Math.Functions.smoothLimit(x=rat, l=0.5, u=1.3, deltaX=0.01);
epsSen = (epsSenPL + (epsSen_nominal - epsSenPL)*(ratRes - 0.75)/0.25);
epsLat = (epsLatPL + (epsLat_nominal - epsLatPL)*(ratRes - 0.75)/0.25);
assert(epsSen >= 0 and epsSen < 1,
ratRes=Buildings.Utilities.Math.Functions.smoothLimit(x=rat, l=0.5, u=1.3, deltaX=0.01);
epsSen=(epsSenPL+(epsSen_nominal-epsSenPL)*(ratRes-0.75)/0.25);
epsLat=(epsLatPL+(epsLat_nominal-epsLatPL)*(ratRes-0.75)/0.25);
assert(epsSen>=0 and epsSen<1,
"In " + getInstanceName() + ": The sensible heat exchange effectiveness epsSen = " + String(epsSen) + ". It should be in the range of [0, 1].
Check if the part load (75% of the nominal supply flow rate) or nominal sensible heat exchanger effectiveness is too high or too low.",
level=AssertionLevel.error);
assert(epsLat >= 0 and epsLat < 1,
assert(epsLat>=0 and epsLat<1,
"In " + getInstanceName() + ": The latent heat exchange effectiveness epsLat = " + String(epsLat) + ". It should be in the range of [0, 1],
Check if the part load (75% of the nominal supply flow rate) or nominal latent heat exchanger effectiveness is too high or too low.",
level=AssertionLevel.error);
Expand Down Expand Up @@ -140,15 +93,6 @@ for the sensible heat transfer when <code>rat</code> is 1 and 0.75, respectively
<code>epsLat_nominal</code> and <code>epsLatPL</code> are the effectiveness
for the latent heat transfer when <code>Rat</code> is 1 and 0.75, respectively.
</p>
<p>
The parameters <code>epsSen_nominal</code>, <code>epsSenPL</code>, <code>epsLat_nominal</code>, and
<code>epsLatPL</code> have different values depending on if the wheel is in
the cooling or heating mode.
If the supply air temperature is greater than the exhaust air
temperature, the exchanger is considered to operate under
the cooling mode;
Otherwise, it operates under the heating mode.
</p>
<P>
<b>Note:</b>
The value of the <code>rat</code> is suggested to be between <i>0.5</i> and <i>1.3</i> during normal operation
Expand Down
Loading

0 comments on commit 566a56e

Please sign in to comment.