-
Notifications
You must be signed in to change notification settings - Fork 235
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
1D Membrane Model for CO2 Capture and Utilization #1378
base: main
Are you sure you want to change the base?
Conversation
idaes/models_extra/co2_capture_and_utilization/unit_models/README.md
Outdated
Show resolved
Hide resolved
idaes/models_extra/co2_capture_and_utilization/unit_models/membrane_1d.py
Show resolved
Hide resolved
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.
Here is a first batch of comments. Most are minor things and ways to do things better, and otherwise what I have seen so far looks good.
Some general comments are:
- Fix all the pylint issues (either by running
pylint
yourself or looking throguh the notifications here on GitHub). - Fix the tests so that they run.
- We will also need some basic documentation to merge this PR.
idaes/models_extra/co2_capture_and_utilization/unit_models/membrane_1d.py
Show resolved
Hide resolved
idaes/models_extra/co2_capture_and_utilization/unit_models/tests/test_membrane_1d.py
Outdated
Show resolved
Hide resolved
idaes/models_extra/co2_capture_and_utilization/unit_models/membrane_1d.py
Show resolved
Hide resolved
idaes/models_extra/co2_capture_and_utilization/unit_models/membrane_1d.py
Show resolved
Hide resolved
idaes/models_extra/co2_capture_and_utilization/unit_models/membrane_1d.py
Outdated
Show resolved
Hide resolved
idaes/models_extra/co2_capture_and_utilization/unit_models/membrane_1d.py
Outdated
Show resolved
Hide resolved
idaes/models_extra/co2_capture_and_utilization/unit_models/membrane_1d.py
Outdated
Show resolved
Hide resolved
idaes/models_extra/co2_capture_and_utilization/unit_models/membrane_1d.py
Outdated
Show resolved
Hide resolved
idaes/models_extra/co2_capture_and_utilization/unit_models/membrane_1d.py
Show resolved
Hide resolved
idaes/models_extra/co2_capture_and_utilization/unit_models/membrane_1d.py
Show resolved
Hide resolved
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1378 +/- ##
==========================================
+ Coverage 77.60% 77.63% +0.02%
==========================================
Files 391 393 +2
Lines 64333 64462 +129
Branches 14245 14272 +27
==========================================
+ Hits 49926 50042 +116
- Misses 11831 11841 +10
- Partials 2576 2579 +3 ☔ View full report in Codecov by Sentry. |
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.
A number of comments. A few other things:
- There are a lot of lines of code that are not covered by tests (mostly things like different combinations of configurations). Whilst not required for models_extra, I would strongly encourage you to do at least minimal testing of the different configurations to ensure they at least build successfully.
- You do not have the methods required to support the
report
and stream table functionality (and thus the visualizer). Whilst again not critical, they would be a good thing to include for usability. - You need to include some basic documentation. At a minimum of explaining what these models are for, the key equations and what degrees of freedom the user should set (this is especially important given my comment about selectivity).
One-dimensional membrane class for CO2 gas separation | ||
""" | ||
|
||
# pylint: disable=unused-import |
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.
Why is this being disabled? Enum
is being used, so there should not be a warning issued by this.
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.
Again, why is this disabled? This implies you have an unused import which should be removed.
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.
It is disabled to pass the pylint test.
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.
You miss my point. I am asking why you are disabling the test, as you generally should not turn off pytest checks.
idaes/models_extra/co2_capture_and_utilization/unit_models/membrane_1d.py
Outdated
Show resolved
Hide resolved
idaes/models_extra/co2_capture_and_utilization/unit_models/membrane_1d.py
Outdated
Show resolved
Hide resolved
idaes/models_extra/co2_capture_and_utilization/unit_models/membrane_1d.py
Outdated
Show resolved
Hide resolved
idaes/models_extra/co2_capture_and_utilization/unit_models/membrane_1d.py
Outdated
Show resolved
Hide resolved
self.selectivity = Var( | ||
self.flowsheet().time, | ||
self.mscontactor.elements, | ||
self.mscontactor.feed_side.component_list, |
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.
Do you need the full factorial combination of these? I suspect you do not need the combination where both components are the same, and that S[i, j] == 1/S[j, i]
. Looking below, I think this is confirmed by the following constraint.
Thus, my question becomes how do you intend for a user to use these? If a user were to naively fix all the selectivity, then the problem would be over-specified.
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.
How are you handling the possible over-specification here?
idaes/models_extra/co2_capture_and_utilization/unit_models/membrane_1d.py
Outdated
Show resolved
Hide resolved
idaes/models_extra/co2_capture_and_utilization/unit_models/tests/test_membrane_1d.py
Outdated
Show resolved
Hide resolved
idaes/models_extra/co2_capture_and_utilization/unit_models/tests/test_membrane_1d.py
Outdated
Show resolved
Hide resolved
idaes/models_extra/co2_capture_and_utilization/unit_models/tests/test_membrane_1d.py
Show resolved
Hide resolved
Also, Sphinx is complaining about a doc string in you model. I think you need to add a line break at the end of line 57 in you model. |
@Morgan88888888 any update on this? |
Based on the feedback, several major improvements have been made: Documentation has been added to provide better model explanations. |
A line break has been added, and more documentation has been included. |
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.
A number of comments on some edge cases and a few outstanding issues.
idaes/models_extra/co2_capture_and_utilization/unit_models/__init__.py
Outdated
Show resolved
Hide resolved
One-dimensional membrane class for CO2 gas separation | ||
""" | ||
|
||
# pylint: disable=unused-import |
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.
Again, why is this disabled? This implies you have an unused import which should be removed.
|
||
self.permeance = Var( | ||
self.flowsheet().time, | ||
self.mscontactor.elements, |
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.
What happens here if the two property packages have different components? Should this instead use the intersection of the two component lists (which is easy to do)?
self.mscontactor.elements, | ||
self.mscontactor.feed_side.component_list, | ||
initialize=1, | ||
doc="Values in Gas Permeance Unit(GPU)", |
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.
Missing space "Unit (GPU)"
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.
fixed
doc=" This is a coefficient that will convert the unit of permeability from GPU to SI units for further calculation", | ||
) | ||
|
||
""" |
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.
Pylint complains about this - general practice is to do this as single line comments (i.e. use #
).
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.
fixed by using #
self.selectivity = Var( | ||
self.flowsheet().time, | ||
self.mscontactor.elements, | ||
self.mscontactor.feed_side.component_list, |
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.
How are you handling the possible over-specification here?
return ( | ||
self.permeance[t, e, a] * self.selectivity[t, e, a, b] | ||
== self.permeance[t, e, b] | ||
) |
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.
This looks like it results in an over-specified problem. You write a constraint for a, b
and b, a
which are reflections of each other. If the user specifies all the selectivities they will have a degree of freedom issue.
I think you really need to only cover the unique pairs (and exclude a=b).
|
||
p_units = feed_side_units.PRESSURE | ||
|
||
crossover_component_list = list( |
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.
I think you needed this earlier. It might also be a good idea to attach this ot the model to save Pyomo replicating this every time you use it.
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.
moved and used for permeance as well
self.mscontactor.elements, | ||
doc="Energy balance", | ||
) | ||
def energy_transfer(self, t, s): |
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.
For clarity, I would call this an isothermal constraint. It is not an energy balance.
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.
fixed
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.
I would also suggest changing the name of the constraint (i.e. the name of the rule/function).
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.
changed
{ | ||
"Feed Inlet": self.feed_side_inlet, | ||
"Feed Outlet": self.feed_side_outlet, | ||
"Permeate Inlet": self.sweep_side_inlet, |
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.
You need logic here to handle cases where the sweep stream is not present.
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.
added
@Morgan88888888 Please of not mark issues as resolved unless they are minor typo corrections. Reviewers need to be able to look over the issues and ensure that they have been addressed. |
@Morgan88888888 Also, this PR still needs to have at least basic documentation before it can be merged. |
@andrewlee94 I have addressed your comments. I changed the model input to require permeance for all components across the membrane, and basic documentation has been added. |
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.
A few more minor things.
self.mscontactor.elements, | ||
doc="Energy balance", | ||
) | ||
def energy_transfer(self, t, s): |
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.
I would also suggest changing the name of the constraint (i.e. the name of the rule/function).
) | ||
|
||
# Check unit config arguments | ||
print("=====================================================") |
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.
You should remove these print statements for the tests.
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.
removed
can be connected for this application. The two sides of the membrane are called the feed side | ||
and sweep side. The sweep stream inlet is optional. The driving force across the membrane is the | ||
partial pressure difference in this gas separation application. Additionally, the energy balance | ||
assumes that temperature remains constant on each side of the membrane. |
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.
A few comments here:
- Reference guides should be entirely autogenerated using Sphinx. Any thing that is hand written really should be an explanation (they go else where in the docs structure).
- It would be good to have a short code example here, or a discussion of what the inputs/degrees of freedom are. This will help users understand what information they should be supplying.
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.
Thanks and more info about model inputs/degrees of freedom are added.
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.
One more minor comment for now. Otherwise I am just waiting to see that the tests all pass (so I suggest you not push any changes until they finish).
* Feed flowrate - :math:`F_fr` | ||
* Feed compositions - :math:`x` | ||
* Feed pressure - :math:`P` | ||
* Feed temperature - :math:`T` |
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.
Should selectivity be here, or is that calculated from permeances?
Also, should there be mention of sweep conditions here too?
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.
Thanks! The selectivity could be calculated and sweep condition is mentioned in the beginning.
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.
Pending fixing the final test failure, I think this is OK.
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1378 +/- ##
=======================================
Coverage 77.05% 77.05%
=======================================
Files 384 386 +2
Lines 62335 62415 +80
Branches 10222 10230 +8
=======================================
+ Hits 48031 48095 +64
- Misses 11875 11888 +13
- Partials 2429 2432 +3 ☔ View full report in Codecov by Sentry. |
Summary/Motivation:
There is a new project ongoing to support NETL's reactive capture technology. The goal of this work is to integrate CO2-selective polymer membranes with electrochemical conversion to efficiently transform captured CO2 into formic acid. The unit and flowsheet models developed in the field of capturing and utilizing CO2 during this project will be maintained in this repository. These models will benefit other ongoing work, such as membrane design and process configuration optimization.
Changes proposed in this PR:
Legal Acknowledgement
By contributing to this software project, I agree to the following terms and conditions for my contribution: