-
Notifications
You must be signed in to change notification settings - Fork 162
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
54
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 all commits
Commits
Show all changes
54 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 2c71507
move all the paras to the dataset
01cdd28
model doc update and package restructure
5cc2922
refer result update
fc585cd
clean up
6cc13a9
fix typo
0d724ec
model doc update
0073880
Merge pull request #4095 from SenHuang19/issue3618_airFilter
JayHuLBL a59aa8f
corrected package order
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 that can be captured by the filter"; | ||
parameter String namCon[:]={"CO2"} | ||
"Name of trace substance"; | ||
parameter | ||
Buildings.Fluid.AirFilters.Data.Characteristics.FiltrationEfficiencyParameters | ||
filEffPar | ||
"Filtration efficiency versus relative mass of the contaminant"; | ||
Buildings.Controls.OBC.CDL.Interfaces.RealInput mCon( | ||
final unit="kg") | ||
"Mass of the contaminant captured by the filter" | ||
annotation (Placement(transformation(extent={{-140,-20},{-100,20}}))); | ||
Buildings.Controls.OBC.CDL.Interfaces.RealOutput y[nConSub]( | ||
each final unit="1", | ||
each final min=0, | ||
each final max=1) | ||
"Filtration efficiency of each contaminant" | ||
annotation (Placement(transformation(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}}))); | ||
protected | ||
parameter Integer nConSub = size(namCon,1) | ||
"Total types of contaminant substances"; | ||
equation | ||
rat = Buildings.Utilities.Math.Functions.smoothMin( | ||
x1=1, | ||
x2= mCon/mCon_nominal, | ||
deltaX=0.1) | ||
"Calculate the relative mass of the contaminant captured by the filter"; | ||
for i in 1:nConSub loop | ||
y[i] = Buildings.Utilities.Math.Functions.smoothInterpolation( | ||
x=rat, | ||
xSup=filEffPar.rat[i], | ||
ySup=filEffPar.eps[i]) | ||
"Calculate the filtration efficiency"; | ||
end for; | ||
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>, using cubic Hermite spline interpolation of | ||
the filter dataset (see | ||
<a href=\"modelica://Buildings.Fluid.AirFilters.Data.Characteristics.filtrationEfficiencyParameters\"> | ||
Buildings.Fluid.AirFilters.Data.Characteristics.filtrationEfficiencyParameters</a>) | ||
with respect to <i>rat</i>. | ||
</p> | ||
<p> | ||
The <i>rat</i> is the relative mass of the contaminant that is 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 that is captured by the filter, and | ||
<i>mCon_nominal</i> is the filter's maximum contaminant capacity. | ||
</p> | ||
<P> | ||
<b>Note:</b> | ||
The upper limit of <i>rat</i> is 1 and any value exceeding 1 will be capped at 1. | ||
</p> | ||
</html>", revisions="<html> | ||
<ul> | ||
<li> | ||
December 22, 2023, by Sen Huang:<br/> | ||
First implementation. | ||
</li> | ||
</ul> | ||
</html>")); | ||
end FiltrationEfficiency; |
65 changes: 65 additions & 0 deletions
65
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,65 @@ | ||
within Buildings.Fluid.AirFilters.BaseClasses; | ||
model FlowCoefficientCorrection | ||
"Component that calculates the flow coefficient correction factor" | ||
parameter Real b=1.1 | ||
"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={{-140,-20},{-100,20}}))); | ||
Buildings.Controls.OBC.CDL.Interfaces.RealOutput y( | ||
final unit="1", | ||
final min=1) | ||
"Flow coefficient correction" | ||
annotation (Placement(transformation(extent={{100,-20},{140,20}}))); | ||
initial equation | ||
assert(b-1.0>0.01, | ||
"In " + getInstanceName() + ":The resistance coefficient must be larger | ||
than 1", | ||
level = AssertionLevel.error) | ||
"Validate the resistance coefficient"; | ||
equation | ||
y=b^rat; | ||
|
||
annotation (defaultComponentName="coeCor", | ||
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)), | ||
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 must be greater than 1, | ||
<code>rat</code> is the relative mass of the contaminant that is 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; |
87 changes: 87 additions & 0 deletions
87
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,87 @@ | ||
within Buildings.Fluid.AirFilters.BaseClasses; | ||
model MassAccumulation | ||
"Component that mimics the accumulation of the contaminants" | ||
parameter Integer nConSub( | ||
final min=1)=1 | ||
"Total number of contaminant substance types"; | ||
parameter Real mCon_nominal( | ||
final unit = "kg") | ||
"Maximum mass of the contaminant that can be captured by the filter"; | ||
parameter Real mCon_reset( | ||
final min = 0) | ||
"Initial contaminant mass of the filter after replacement"; | ||
Buildings.Controls.OBC.CDL.Interfaces.RealInput mCon_flow[nConSub]( | ||
each final unit="kg/s") | ||
"Contaminant mass flow rate" | ||
annotation (Placement(transformation(extent={{-140,-20},{-100,20}}))); | ||
Buildings.Controls.OBC.CDL.Interfaces.BooleanInput uRep | ||
"Replacing the filter when trigger becomes true" | ||
annotation (Placement(transformation(extent={{-140,-80},{-100,-40}}))); | ||
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}}))); | ||
Buildings.Controls.OBC.CDL.Reals.IntegratorWithReset intWitRes( | ||
final k=1, | ||
final y_start=mCon_reset) | ||
"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,40},{60,60}}))); | ||
Buildings.Controls.OBC.CDL.Reals.Sources.Constant con1( | ||
final k=mCon_nominal) | ||
"Constant" | ||
annotation (Placement(transformation(extent={{-20,40},{0,60}}))); | ||
Buildings.Controls.OBC.CDL.Utilities.Assert assMes( | ||
final message="In " + getInstanceName() + ": The filter needs to be replaced.") | ||
"Warning message when the filter is full" | ||
annotation (Placement(transformation(extent={{72,40},{92,60}}))); | ||
Buildings.Controls.OBC.CDL.Reals.MultiSum mulSum( | ||
final nin=nConSub) "Summation of the inputs" | ||
annotation (Placement(transformation(extent={{-52,-10},{-32,10}}))); | ||
equation | ||
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,50},{61,50}}, color={255,0,255})); | ||
connect(greater.u2, intWitRes.y) | ||
annotation (Line(points={{38,42},{20,42},{20,0},{12,0}}, color={0,0,127})); | ||
connect(con1.y, greater.u1) | ||
annotation (Line(points={{2,50},{38,50}}, color={0,0,127})); | ||
connect(mulSum.y, intWitRes.u) | ||
annotation (Line(points={{-30,0},{-12,0}}, color={0,0,127})); | ||
connect(mulSum.u, mCon_flow) | ||
annotation (Line(points={{-54,0},{-120,0}}, color={0,0,127})); | ||
annotation (Placement(transformation(extent={{20,62},{40,82}})), | ||
defaultComponentName="masAcc", | ||
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)), | ||
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 reset 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,97 @@ | ||
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; | ||
parameter String namCon[:]={"CO2"} | ||
"Name of trace substance"; | ||
Buildings.Controls.OBC.CDL.Interfaces.RealInput eps[nConSub]( | ||
each final unit = "1", | ||
each final min = 0, | ||
each final max= 1) | ||
"Mass transfer coefficient" | ||
annotation (Placement(transformation(extent={{-140,40},{-100,80}}))); | ||
Buildings.Controls.OBC.CDL.Interfaces.RealOutput mCon_flow[nConSub]( | ||
each final unit = "kg/s") | ||
"Contaminant mass flow rate" | ||
annotation (Placement(transformation(extent={{100,40},{140,80}}))); | ||
|
||
protected | ||
parameter Integer nConSub=size(namCon,1) | ||
"Total types of contaminant substances"; | ||
parameter Real s[:,:]={ | ||
{if (Modelica.Utilities.Strings.isEqual(string1=Medium.extraPropertiesNames[i], | ||
string2=namCon[j], | ||
caseSensitive=false)) | ||
then 1 else 0 for i in 1:nConSub} | ||
for j in 1:Medium.nC} | ||
"Vector to check if the trace substances in the medium are included in the performance dataset" | ||
annotation(Evaluate=true); | ||
initial equation | ||
assert(abs(sum(s) - nConSub) < 0.1, | ||
"In " + getInstanceName() + ":Some specified trace substances are | ||
not present in medium '" + Medium.mediumName + "'.\n" | ||
+ "Check filter parameter and medium model.", | ||
level = AssertionLevel.warning) | ||
"Check if all the specified substances are included in the medium"; | ||
|
||
equation | ||
// Modify the substances individually. | ||
for i in 1:Medium.nC loop | ||
if max(s[i]) > 0.9 then | ||
for j in 1:nConSub loop | ||
if s[i,j]>0.9 then | ||
port_b.C_outflow[i]=inStream(port_a.C_outflow[i])*(1 - eps[j] * s[i,j]); | ||
port_a.C_outflow[i]=inStream(port_a.C_outflow[i]); | ||
mCon_flow[j]=inStream(port_a.C_outflow[j])* eps[j]; | ||
end if; | ||
end for; | ||
else | ||
port_b.C_outflow[i]=inStream(port_a.C_outflow[i]); | ||
port_a.C_outflow[i]=inStream(port_b.C_outflow[i]); | ||
end if; | ||
end for; | ||
// 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 (defaultComponentName="masTra", | ||
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)), | ||
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. | ||
</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?