-
Notifications
You must be signed in to change notification settings - Fork 238
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
Add support for isothermal conditions in control volumes. #1558
Merged
Merged
Changes from all commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
1a58c7c
Extended control volumes
andrewlee94 93c41b8
Extended CV with isothermal option
andrewlee94 eaeabc4
Docs for extended CVs
andrewlee94 70c3475
Black and pylint
andrewlee94 feee062
Apply suggestions from code review
andrewlee94 9476565
Fix XCV1D isothermal contraint
andrewlee94 e482c37
Merge upstream changes
andrewlee94 6b9ea94
Cleaning up some cruft in tests
andrewlee94 e54dcb5
Typo in error messages
andrewlee94 88a0394
Apply discretization in 1d tests
andrewlee94 7f2d9f9
Running black
andrewlee94 71245de
Rename to isothermal constraint and add type hints
andrewlee94 08e3983
Running black
andrewlee94 05ee497
Fixing duplicated import
andrewlee94 de153a7
Updaing docs and doc strings
andrewlee94 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
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
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
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
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
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
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
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,112 @@ | ||
################################################################################# | ||
# The Institute for the Design of Advanced Energy Systems Integrated Platform | ||
# Framework (IDAES IP) was produced under the DOE Institute for the | ||
# Design of Advanced Energy Systems (IDAES). | ||
# | ||
# Copyright (c) 2018-2024 by the software owners: The Regents of the | ||
# University of California, through Lawrence Berkeley National Laboratory, | ||
# National Technology & Engineering Solutions of Sandia, LLC, Carnegie Mellon | ||
# University, West Virginia University Research Corporation, et al. | ||
# All rights reserved. Please see the files COPYRIGHT.md and LICENSE.md | ||
# for full copyright and license information. | ||
################################################################################# | ||
""" | ||
0D Control Volume class with support for isothermal energy balance. | ||
""" | ||
|
||
__author__ = "Andrew Lee" | ||
|
||
from pyomo.environ import Constraint, Expression | ||
|
||
# Import IDAES cores | ||
from idaes.core.base.control_volume0d import ControlVolume0DBlockData | ||
from idaes.core import declare_process_block_class | ||
from idaes.core.util.exceptions import ConfigurationError | ||
|
||
import idaes.logger as idaeslog | ||
|
||
_log = idaeslog.getLogger(__name__) | ||
|
||
|
||
@declare_process_block_class( | ||
"ExtendedControlVolume0DBlock", | ||
doc=""" | ||
ExtendedControlVolume0DBlock is an extension of the ControlVolume0D | ||
block with support for isothermal conditions in place of a formal | ||
energy balance.""", | ||
) | ||
class ExtendedControlVolume0DBlockData(ControlVolume0DBlockData): | ||
""" | ||
Extended 0-Dimensional (Non-Discretized) ControlVolume Class | ||
|
||
This class extends the existing ControlVolume0DBlockData class | ||
with support for isothermal energy balances. | ||
""" | ||
|
||
def add_isothermal_constraint( | ||
self, | ||
has_heat_of_reaction: bool = False, | ||
has_heat_transfer: bool = False, | ||
has_work_transfer: bool = False, | ||
has_enthalpy_transfer: bool = False, | ||
custom_term: Expression = None, | ||
) -> Constraint: | ||
""" | ||
This method constructs an isothermal constraint for the control volume. | ||
|
||
Arguments are supported for compatibility with other forms but must be False | ||
or None otherwise an Exception is raised. | ||
|
||
Args: | ||
has_heat_of_reaction: whether terms for heat of reaction should | ||
be included in enthalpy balance | ||
has_heat_transfer: whether terms for heat transfer should be | ||
included in enthalpy balances | ||
has_work_transfer: whether terms for work transfer should be | ||
included in enthalpy balances | ||
has_enthalpy_transfer: whether terms for enthalpy transfer due to | ||
mass transfer should be included in enthalpy balance. This | ||
should generally be the same as the has_mass_transfer | ||
argument in the material balance methods | ||
custom_term: a Python method which returns Pyomo expressions representing | ||
custom terms to be included in enthalpy balances. | ||
Method should accept time and phase list as arguments. | ||
|
||
Returns: | ||
Constraint object representing isothermal constraint | ||
""" | ||
if has_heat_transfer: | ||
raise ConfigurationError( | ||
f"{self.name}: isothermal energy balance option requires that has_heat_transfer is False. " | ||
"If you are trying to solve for heat duty to achieve isothermal operation, please use " | ||
"a full energy balance and add a constraint to equate inlet and outlet temperatures." | ||
) | ||
if has_work_transfer: | ||
raise ConfigurationError( | ||
f"{self.name}: isothermal energy balance option requires that has_work_transfer is False. " | ||
"If you are trying to solve for work under isothermal operation, please use " | ||
"a full energy balance and add a constraint to equate inlet and outlet temperatures." | ||
) | ||
if has_enthalpy_transfer: | ||
raise ConfigurationError( | ||
f"{self.name}: isothermal energy balance option does not support enthalpy transfer." | ||
) | ||
if has_heat_of_reaction: | ||
raise ConfigurationError( | ||
f"{self.name}: isothermal energy balance option requires that has_heat_of_reaction is False. " | ||
"If you are trying to solve for heat duty to achieve isothermal operation, please use " | ||
"a full energy balance and add a constraint to equate inlet and outlet temperatures." | ||
) | ||
if custom_term is not None: | ||
raise ConfigurationError( | ||
f"{self.name}: isothermal energy balance option does not support custom terms." | ||
) | ||
|
||
# Add isothermal constraint | ||
@self.Constraint( | ||
self.flowsheet().time, doc="Isothermal constraint - replaces energy balance" | ||
) | ||
def isothermal_constraint(b, t): | ||
return b.properties_in[t].temperature == b.properties_out[t].temperature | ||
|
||
return self.isothermal_constraint |
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,121 @@ | ||
################################################################################# | ||
# The Institute for the Design of Advanced Energy Systems Integrated Platform | ||
# Framework (IDAES IP) was produced under the DOE Institute for the | ||
# Design of Advanced Energy Systems (IDAES). | ||
# | ||
# Copyright (c) 2018-2024 by the software owners: The Regents of the | ||
# University of California, through Lawrence Berkeley National Laboratory, | ||
# National Technology & Engineering Solutions of Sandia, LLC, Carnegie Mellon | ||
# University, West Virginia University Research Corporation, et al. | ||
# All rights reserved. Please see the files COPYRIGHT.md and LICENSE.md | ||
# for full copyright and license information. | ||
################################################################################# | ||
""" | ||
1D Control Volume class with support for isothermal energy balance. | ||
""" | ||
|
||
__author__ = "Andrew Lee" | ||
|
||
# Import Pyomo libraries | ||
from pyomo.environ import Constraint, Expression | ||
|
||
# Import IDAES cores | ||
from idaes.core.base.control_volume1d import ControlVolume1DBlockData | ||
from idaes.core import declare_process_block_class | ||
from idaes.core.util.exceptions import ConfigurationError | ||
|
||
import idaes.logger as idaeslog | ||
|
||
_log = idaeslog.getLogger(__name__) | ||
|
||
|
||
@declare_process_block_class( | ||
"ExtendedControlVolume1DBlock", | ||
doc=""" | ||
ExtendedControlVolume1DBlock is an extension of the ControlVolume1D | ||
block with support for isothermal conditions in place of a formal | ||
energy balance.""", | ||
) | ||
class ExtendedControlVolume1DBlockData(ControlVolume1DBlockData): | ||
""" | ||
Extended 1-Dimensional ControlVolume Class | ||
|
||
This class extends the existing ControlVolume1DBlockData class | ||
with support for isothermal energy balances. | ||
""" | ||
|
||
def add_isothermal_constraint( | ||
self, | ||
has_heat_of_reaction: bool = False, | ||
has_heat_transfer: bool = False, | ||
has_work_transfer: bool = False, | ||
has_enthalpy_transfer: bool = False, | ||
custom_term: Expression = None, | ||
) -> None: | ||
""" | ||
This method constructs an isothermal constraint for the control volume. | ||
|
||
Arguments are supported for compatibility with other forms but must be False | ||
or None otherwise an Exception is raised. | ||
|
||
Args: | ||
has_heat_of_reaction: whether terms for heat of reaction should | ||
be included in enthalpy balance | ||
has_heat_transfer: whether terms for heat transfer should be | ||
included in enthalpy balances | ||
has_work_transfer: whether terms for work transfer should be | ||
included in enthalpy balances | ||
has_enthalpy_transfer: whether terms for enthalpy transfer due to | ||
mass transfer should be included in enthalpy balance. This | ||
should generally be the same as the has_mass_transfer | ||
argument in the material balance methods | ||
custom_term: a Python method which returns Pyomo expressions representing | ||
custom terms to be included in enthalpy balances. | ||
Method should accept time and phase list as arguments. | ||
|
||
Returns: | ||
Constraint object representing isothermal constraints | ||
""" | ||
if has_heat_transfer: | ||
raise ConfigurationError( | ||
f"{self.name}: isothermal energy balance option requires that has_heat_transfer is False. " | ||
"If you are trying to solve for heat duty to achieve isothermal operation, please use " | ||
"a full energy balance and add a constraint to equate inlet and outlet temperatures." | ||
) | ||
if has_work_transfer: | ||
raise ConfigurationError( | ||
f"{self.name}: isothermal energy balance option requires that has_work_transfer is False. " | ||
"If you are trying to solve for work under isothermal operation, please use " | ||
"a full energy balance and add a constraint to equate inlet and outlet temperatures." | ||
) | ||
if has_enthalpy_transfer: | ||
raise ConfigurationError( | ||
f"{self.name}: isothermal energy balance option does not support enthalpy transfer. " | ||
) | ||
if has_heat_of_reaction: | ||
raise ConfigurationError( | ||
f"{self.name}: isothermal energy balance option requires that has_heat_of_reaction is False. " | ||
"If you are trying to solve for heat duty to achieve isothermal operation, please use " | ||
"a full energy balance and add a constraint to equate inlet and outlet temperatures." | ||
) | ||
if custom_term is not None: | ||
raise ConfigurationError( | ||
f"{self.name}: isothermal energy balance option does not support custom terms. " | ||
) | ||
|
||
# Add isothermal constraint | ||
@self.Constraint( | ||
self.flowsheet().time, | ||
self.length_domain, | ||
doc="Isothermal constraint - replaces energy balances", | ||
) | ||
def isothermal_constraint(b, t, x): | ||
if x == b.length_domain.first(): | ||
return Constraint.Skip | ||
|
||
return ( | ||
b.properties[t, b.length_domain.prev(x)].temperature | ||
== b.properties[t, x].temperature | ||
) | ||
|
||
return self.isothermal_constraint |
Oops, something went wrong.
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.
It looks like the constraint would be skipped at the outlet when using forward scheme, but what does this mean for temperature at the outlet?
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.
Actually, most of this is not needed as there is no partial derivative. The way this is written, it has to skip the first point no matter what.
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 might be misunderstanding, but as written, it appears that for backwards transformation, temperature at the inlet (x=0) would be set equal to the temperature of the next element, and this equality would be propagated across adjacent pairs for the whole length domain. So the temperature for each element would be covered.
However, for the forward transformation case, it seems that all elements except the last element would be covered by the equality constraint.
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.
OK, now I think the issue is 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.
Can we also rename
enthalpy_balances
toisothermal_constraint
or something here?