-
Notifications
You must be signed in to change notification settings - Fork 161
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Issue3618 air filter #3676
Open
JayHuLBL
wants to merge
46
commits into
master
Choose a base branch
from
issue3618_airFilter
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Issue3618 air filter #3676
Changes from 19 commits
Commits
Show all changes
46 commits
Select commit
Hold shift + click to select a range
4c1f2ae
first implementation
ca8b5fe
cleanup
5422c41
add OM scripts
f1557a8
update the plot script
526d305
reference data generation
5c410d4
improve model doc
4702143
model restruct
763d5d2
model doc update
b0477ad
update release note
7ddd341
Merge pull request #3620 from SenHuang19/issue3618_airFilter
JayHuLBL 083dc1f
Merge branch 'master' into issue3618_airFilter
JayHuLBL 27d9538
deleted invalid word [ci skip]
JayHuLBL 8e2a608
refactored formatting
JayHuLBL d3f0636
fixed validation folder
JayHuLBL 87e5370
improved graphic arrangement
JayHuLBL 2602d9c
corrected release note
JayHuLBL 033ac22
merged master
JayHuLBL 0a6a806
changed connector name
JayHuLBL 0be4dbb
improved text [ci skip]
JayHuLBL 54cc4a6
merged master
JayHuLBL e37292a
add asserts
SenHuang19 1b6cbae
format update
SenHuang19 92fe476
Merge pull request #3807 from SenHuang19/issue3618_airFilter
JayHuLBL f7c67ee
improved text and documentation
JayHuLBL ed0bd65
added variable in reference results
JayHuLBL 2a98e8a
refactoring and adding an example
SenHuang19 5d10a8e
script update
SenHuang19 6c49dab
example update
SenHuang19 63142ce
ref dataset update
SenHuang19 db1b8b0
model doc update and small issues fix
SenHuang19 021d6b7
model doc improve
SenHuang19 a11b196
typos fix
SenHuang19 7e1f587
minor fix
SenHuang19 07ad4e9
minor doc update
SenHuang19 f649536
model doc enhance and move the per to the top level class
d3a9dfe
model doc improve
5fd768e
eliminate unnecessary calculations
2f7c2f2
minor model doc update
b731d7a
update the file name
d53922b
fix typo
929e92b
Merge pull request #3986 from SenHuang19/issue3618_airFilter
JayHuLBL 2a5e2c1
merged master
JayHuLBL 18e0ad8
corrected package order
JayHuLBL c70d36a
updated reference
JayHuLBL 53a0558
Deleted openmodelica script
JayHuLBL e746684
improved code
JayHuLBL File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
89 changes: 89 additions & 0 deletions
89
Buildings/Fluid/AirFilters/BaseClasses/FiltrationEfficiency.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,89 @@ | ||
within Buildings.Fluid.AirFilters.BaseClasses; | ||
model FiltrationEfficiency | ||
"Component that calculates the filtration efficiency" | ||
parameter Real mCon_nominal( | ||
final unit="kg") | ||
"Maximum mass of the contaminant can be captured by the filter"; | ||
parameter Real epsFun[:] | ||
"Filtration efficiency curve"; | ||
Buildings.Controls.OBC.CDL.Interfaces.RealInput mCon( | ||
final unit="kg") | ||
"Mass of the contaminant captured by the filter" | ||
annotation (Placement( | ||
transformation( | ||
extent={{20,-20},{-20,20}}, | ||
rotation=180, | ||
origin={-120,0}), iconTransformation( | ||
extent={{-20,-20},{20,20}}, | ||
rotation=0, | ||
origin={-120,0}))); | ||
Buildings.Controls.OBC.CDL.Interfaces.RealOutput y( | ||
final unit="1", | ||
final min=0, | ||
final max=1) | ||
"Filtration efficiency" | ||
annotation (Placement(transformation(extent={{100,-80},{140,-40}}), | ||
iconTransformation(extent={{100,-80},{140,-40}}))); | ||
Buildings.Controls.OBC.CDL.Interfaces.RealOutput rat( | ||
final unit="1", | ||
final min=0, | ||
final max=1) | ||
"Relative mass of the contaminant captured by the filter" | ||
annotation (Placement(transformation(extent={{100,40},{140,80}}), | ||
iconTransformation(extent={{100,40},{140,80}}))); | ||
|
||
equation | ||
rat = Buildings.Utilities.Math.Functions.smoothMin(x1=1, x2= mCon/mCon_nominal, deltaX=0.1); | ||
y = Buildings.Utilities.Math.Functions.polynomial(a=epsFun, x=rat); | ||
assert( | ||
y > 0 and y < 1, | ||
"In " + getInstanceName() + ": The filter efficiency should be in the range of [0, 1], | ||
check the filter efficiency curve.", | ||
level=AssertionLevel.error); | ||
|
||
annotation (Icon(coordinateSystem(preserveAspectRatio=false), graphics={ | ||
Rectangle( | ||
extent={{-100,100},{100,-100}}, | ||
lineColor={28,108,200}, | ||
fillColor={255,255,255}, | ||
fillPattern=FillPattern.Solid), | ||
Text( | ||
extent={{-100,140},{100,100}}, | ||
textColor={0,0,255}, | ||
textString="%name")}), | ||
Diagram(coordinateSystem(preserveAspectRatio=false)), | ||
defaultComponentName="eps", | ||
Documentation(info="<html> | ||
<p> | ||
This model calculates the filtration efficiency, <i>eps</i>, by | ||
</p> | ||
<p align=\"center\" style=\"font-style:italic;\"> | ||
eps = epsFun<sub>1</sub> + epsFun<sub>2</sub>rat + epsFun<sub>3</sub> rat<sup>2</sup> + ..., | ||
</p> | ||
<p> | ||
where the coefficients <i>epsFun<sub>i</sub></i> are declared by the parameter <i>epsFun</i>; | ||
</p> | ||
<p> | ||
The <i>rat</i> is the relative mass of the contaminant captured by the filter | ||
and is calculated by | ||
</p> | ||
<p align=\"center\" style=\"font-style:italic;\"> | ||
rat = mCon/mCon_nominal, | ||
</p> | ||
<p> | ||
where <i>mCon</i> is the mass of the contaminant captured by the filter, | ||
<i>mCon_nominal</i> is the maximum mass of the contaminant captured by the filter. | ||
</p> | ||
<P> | ||
<b>Note:</b> | ||
The upper limit of <i>rat</i> is 1 and any value above it is overwritten by 1. | ||
</p> | ||
</html>", revisions="<html> | ||
<ul> | ||
<li> | ||
December 22, 2023, by Sen Huang:<br/> | ||
First implementation. | ||
</li> | ||
</ul> | ||
</html>")); | ||
end FiltrationEfficiency; |
68 changes: 68 additions & 0 deletions
68
Buildings/Fluid/AirFilters/BaseClasses/FlowCoefficientCorrection.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,68 @@ | ||
within Buildings.Fluid.AirFilters.BaseClasses; | ||
model FlowCoefficientCorrection | ||
"Component that calculates the flow coefficient correction factor" | ||
parameter Real b( | ||
final min = 1 + 1E-3) | ||
"Resistance coefficient"; | ||
Buildings.Controls.OBC.CDL.Interfaces.RealInput rat( | ||
final unit="1", | ||
final min=0, | ||
final max=1) | ||
"Relative mass of the contaminant captured by the filter" | ||
annotation (Placement( | ||
transformation( | ||
extent={{20,-20},{-20,20}}, | ||
rotation=180, | ||
origin={-120,0}), iconTransformation( | ||
extent={{-20,-20},{20,20}}, | ||
rotation=0, | ||
origin={-120,0}))); | ||
Buildings.Controls.OBC.CDL.Interfaces.RealOutput y( | ||
final unit="1", | ||
final min=1) | ||
"Flow coefficient correction" | ||
annotation (Placement(transformation(extent={{100,-20},{140,20}}), | ||
iconTransformation(extent={{100,-20},{140,20}}))); | ||
equation | ||
y = b^rat; | ||
annotation (Dialog(group="Pressure"), | ||
Icon(coordinateSystem(preserveAspectRatio=false), graphics={ | ||
Rectangle( | ||
extent={{-100,100},{100,-100}}, | ||
lineColor={28,108,200}, | ||
fillColor={255,255,255}, | ||
fillPattern=FillPattern.Solid), | ||
Text( | ||
extent={{-100,140},{100,100}}, | ||
textColor={0,0,255}, | ||
textString="%name")}), | ||
Diagram(coordinateSystem(preserveAspectRatio=false)), | ||
defaultComponentName="kCor", | ||
Documentation(info="<html> | ||
<p> | ||
This model calculates the flow coefficient of the filter by | ||
</p> | ||
<p align=\"center\" style=\"font-style:italic;\"> | ||
kCor = b<sup>rat</sup>, | ||
</p> | ||
<p> | ||
where <code>b</code> is the resistance coefficient and it has to be greater than 1, | ||
<code>rat</code> is the relative mass of the contaminant captured by the filter | ||
(see descriptions in | ||
<a href=\"modelica://Buildings.Fluid.AirFilters.BaseClasses.FiltrationEfficiency\"> | ||
Buildings.Fluid.AirFilters.BaseClasses.FiltrationEfficiency</a>). | ||
</p> | ||
<h4>References</h4> | ||
<p> | ||
Qiang Li ta al., (2022). Experimental study on the synthetic dust loading characteristics of air filters. | ||
Separation and Purification Technology 284 (2022), 120209 | ||
</p> | ||
</html>", revisions="<html> | ||
<ul> | ||
<li> | ||
December 22, 2023, by Sen Huang:<br/> | ||
First implementation. | ||
</li> | ||
</ul> | ||
</html>")); | ||
end FlowCoefficientCorrection; |
98 changes: 98 additions & 0 deletions
98
Buildings/Fluid/AirFilters/BaseClasses/MassAccumulation.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,98 @@ | ||
within Buildings.Fluid.AirFilters.BaseClasses; | ||
model MassAccumulation | ||
"Component that mimics the accumulation of the contaminants" | ||
parameter Real mCon_nominal | ||
"Maximum mass of the contaminant captured by the filter"; | ||
parameter Real mCon_reset( | ||
final min = 0) | ||
"Initial contaminant mass of the filter after replacement"; | ||
Buildings.Controls.OBC.CDL.Interfaces.BooleanInput uRep | ||
"Replacing the filter when trigger becomes true" | ||
annotation (Placement( | ||
transformation( | ||
extent={{20,-20},{-20,20}}, | ||
rotation=180, | ||
origin={-120,-60}), iconTransformation( | ||
extent={{-20,-20},{20,20}}, | ||
rotation=0, | ||
origin={-120,-62}))); | ||
Buildings.Controls.OBC.CDL.Interfaces.RealInput mCon_flow( | ||
final unit = "kg/s") | ||
"Contaminant mass flow rate" | ||
annotation (Placement(transformation( | ||
extent={{20,-20},{-20,20}}, | ||
rotation=180, | ||
origin={-120,60}), iconTransformation( | ||
extent={{-20,-20},{20,20}}, | ||
rotation=0, | ||
origin={-120,60}))); | ||
Buildings.Controls.OBC.CDL.Interfaces.RealOutput mCon( | ||
final unit = "kg") | ||
"Mass of the contaminant captured by the filter" | ||
annotation (Placement(transformation(extent={{100,-20},{140,20}}), | ||
iconTransformation(extent={{100,-20},{140,20}}))); | ||
Buildings.Controls.OBC.CDL.Reals.IntegratorWithReset intWitRes | ||
"Calculate the mass of contaminant" | ||
annotation (Placement(transformation(extent={{-10,-10},{10,10}}))); | ||
Buildings.Controls.OBC.CDL.Reals.Sources.Constant con( | ||
final k=mCon_reset) | ||
"Constant" | ||
annotation (Placement(transformation(extent={{-80,-30},{-60,-10}}))); | ||
Modelica.Blocks.Logical.Greater greater | ||
"Check if the filter is full" | ||
annotation (Placement(transformation(extent={{40,-48},{60,-28}}))); | ||
Buildings.Controls.OBC.CDL.Reals.Sources.Constant con1( | ||
final k=mCon_nominal) | ||
"Constant" | ||
annotation (Placement(transformation(extent={{0,40},{20,60}}))); | ||
Buildings.Controls.OBC.CDL.Utilities.Assert assMes( | ||
message="In " + getInstanceName() + ":the filter needs to be replaced") | ||
"Error message when the filter is full, i.e., the mass captured by the filter is larger than the nominal value" | ||
annotation (Placement(transformation(extent={{72,-48},{92,-28}}))); | ||
equation | ||
connect(intWitRes.u, mCon_flow) annotation (Line(points={{-12,0},{-40,0},{-40, | ||
60},{-120,60}}, color={0,0,127})); | ||
connect(intWitRes.y, mCon) | ||
annotation (Line(points={{12,0},{120,0}}, color={0,0,127})); | ||
connect(con.y, intWitRes.y_reset_in) | ||
annotation (Line(points={{-58,-20},{-20,-20}, | ||
{-20,-8},{-12,-8}},color={0,0,127})); | ||
connect(intWitRes.trigger, uRep) | ||
annotation (Line(points={{0,-12},{0,-60},{-120,-60}}, color={255,0,255})); | ||
connect(assMes.u, greater.y) | ||
annotation (Line(points={{70,-38},{61,-38}}, color={255,0,255})); | ||
connect(greater.u2, intWitRes.y) | ||
annotation (Line(points={{38,-46},{20,-46},{20, | ||
0},{12,0}}, color={0,0,127})); | ||
connect(con1.y, greater.u1) | ||
annotation (Line(points={{22,50},{30,50},{30,-38}, | ||
{38,-38}}, color={0,0,127})); | ||
annotation (Icon(coordinateSystem(preserveAspectRatio=false), graphics={ | ||
Rectangle( | ||
extent={{-100,100},{100,-100}}, | ||
lineColor={28,108,200}, | ||
fillColor={255,255,255}, | ||
fillPattern=FillPattern.Solid), | ||
Text( | ||
extent={{-100,140},{100,100}}, | ||
textColor={0,0,255}, | ||
textString="%name")}), | ||
Diagram(coordinateSystem( | ||
preserveAspectRatio=false)), | ||
defaultComponentName="masAcc", | ||
Documentation(info="<html> | ||
<p> | ||
This model mimics the process for a filter to capture the contaminants. | ||
The mass of the contaminants, <code>mCon</code>, increases by time. | ||
However, when the input signal <code>uRep</code> changes from <code>false</code> | ||
to <code>true</code>, <code>mCon</code> is reinitialized to a constant, <code>mCon_reset</code>. | ||
</p> | ||
</html>", revisions="<html> | ||
<ul> | ||
<li> | ||
December 22, 2023, by Sen Huang:<br/> | ||
First implementation. | ||
</li> | ||
</ul> | ||
</html>")); | ||
end MassAccumulation; |
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,83 @@ | ||
within Buildings.Fluid.AirFilters.BaseClasses; | ||
model MassTransfer | ||
"Component that sets the trace substance at port_b based on an input trace substance mass flow rate and an input mass transfer efficiency" | ||
extends Buildings.Fluid.Interfaces.PartialTwoPortInterface; | ||
Buildings.Controls.OBC.CDL.Interfaces.RealInput C_inflow[Medium.nC] | ||
"Input trace substance rate" | ||
annotation (Placement(transformation( | ||
extent={{-20,-20},{20,20}}, | ||
rotation=270, | ||
origin={0,120}), iconTransformation( | ||
extent={{-20,-20},{20,20}}, | ||
rotation=270, | ||
origin={0,120}))); | ||
Buildings.Controls.OBC.CDL.Interfaces.RealInput eps( | ||
final unit = "1", | ||
final min = 0, | ||
final max= 1) | ||
"Mass transfer coefficient" | ||
annotation (Placement(transformation( | ||
extent={{20,-20},{-20,20}}, | ||
rotation=180, | ||
origin={-120,60}), iconTransformation( | ||
extent={{-20,-20},{20,20}}, | ||
rotation=0, | ||
origin={-120,60}))); | ||
equation | ||
if allowFlowReversal then | ||
port_b.C_outflow =inStream(port_a.C_outflow) - eps*C_inflow; | ||
port_a.C_outflow = inStream(port_a.C_outflow); | ||
else | ||
port_b.C_outflow = inStream(port_a.C_outflow); | ||
port_a.C_outflow = inStream(port_b.C_outflow); | ||
end if; | ||
// Mass balance (no storage). | ||
port_a.Xi_outflow = inStream(port_b.Xi_outflow); | ||
port_b.Xi_outflow = inStream(port_a.Xi_outflow); | ||
port_a.m_flow = -port_b.m_flow; | ||
// Pressure balance (no pressure drop). | ||
port_a.p = port_b.p; | ||
// Energy balance (no heat exchange). | ||
port_a.h_outflow = inStream(port_b.h_outflow); | ||
port_b.h_outflow = inStream(port_a.h_outflow); | ||
|
||
if not allowFlowReversal then | ||
assert(m_flow > -m_flow_small, | ||
"In " + getInstanceName() + ":Reverting flow occurs even though allowFlowReversal is false", | ||
level=AssertionLevel.error); | ||
end if; | ||
|
||
annotation (Icon(coordinateSystem(preserveAspectRatio=false), graphics={ | ||
Rectangle( | ||
extent={{-100,100},{100,-100}}, | ||
fillColor={255,255,255}, | ||
fillPattern=FillPattern.Solid, | ||
pattern=LinePattern.None)}), Diagram( | ||
coordinateSystem(preserveAspectRatio=false)), | ||
defaultComponentName="masTra", | ||
Documentation(info="<html> | ||
<p> | ||
This model sets the trace substance | ||
of the medium that leaves <code>port_b</code> by | ||
</p> | ||
<pre> | ||
port_b.C_outflow = inStream(port_a.C_outflow) - eps * C_inflow; | ||
</pre> | ||
<p> | ||
where <code>eps</code> is an input mass transfer efficiency and | ||
<code>C_inflow</code> is an input trace substance rate. | ||
</p> | ||
<p> | ||
This model has no pressure drop. In the case of reverse flow, | ||
the fluid that leaves <code>port_a</code> has the same | ||
properties as the fluid that enters <code>port_b</code>. | ||
</p> | ||
</html>", revisions="<html> | ||
<ul> | ||
<li> | ||
December 22, 2023, by Sen Huang:<br/> | ||
First implementation. | ||
</li> | ||
</ul> | ||
</html>")); | ||
end MassTransfer; |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this class, the
rat
is a scale variable, while in classBuildings.Fluid.AirFilters.BaseClasses.Characteristics.FiltrationEfficiencyParameters
, therat
is a vector. Are they same or different?Through commit e746684, I removed
each
declaration. Is it a correct change? As in Modelica,each
should only be used by the vector variable declaration.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Buildings.Fluid.AirFilters.BaseClasses.FilterationEfficiency
definesrat
while inBuildings.Fluid.AirFilters.BaseClasses.Characteristics.FiltrationEfficiencyParameters
, we declare a list ofrat
and eachrat
corresponds to a specific type of containment. Should I rename therat
inBuildings.Fluid.AirFilters.BaseClasses.Characteristics.FiltrationEfficiencyParameters
to avoid confusions?