-
Notifications
You must be signed in to change notification settings - Fork 57
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 MD 0D #1105
Add MD 0D #1105
Conversation
Codecov ReportAttention:
Additional details and impacted files@@ Coverage Diff @@
## main #1105 +/- ##
==========================================
- Coverage 94.88% 94.86% -0.02%
==========================================
Files 336 340 +4
Lines 33269 33931 +662
==========================================
+ Hits 31566 32189 +623
- Misses 1703 1742 +39
☔ View full report in Codecov by Sentry. |
if type == "hot_ch": | ||
state_args_properties_out = state_args["hot_outlet"] | ||
|
||
self.properties_out.initialize( | ||
state_args=state_args_properties_out, | ||
outlvl=outlvl, | ||
optarg=optarg, | ||
solver=solver, | ||
) | ||
elif type == "cold_ch": | ||
state_args_properties_out = state_args["cold_outlet"] | ||
|
||
self.properties_out.initialize( | ||
state_args=state_args_properties_out, | ||
outlvl=outlvl, | ||
optarg=optarg, | ||
solver=solver, | ||
) | ||
else: | ||
raise ConfigurationError( | ||
"Either hot_ch or cold_ch must be set in the configuration." | ||
) |
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 it one or the other? Shouldn't both be initialized? Also, it looks like you would need pass strings to type
here, which I don't think we want to do.
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.
cold outlet and hot outlet are initialized differently based on inlet
CONFIG.declare( | ||
"dynamic", | ||
ConfigValue( | ||
default=False, | ||
domain=In([False]), | ||
description="Dynamic model flag - must be False", | ||
doc="""Indicates whether this model will be dynamic or not. | ||
**default** - False. Membrane units do not yet support dynamic | ||
behavior.""", | ||
), | ||
) | ||
CONFIG.declare( | ||
"has_holdup", | ||
ConfigValue( | ||
default=False, | ||
domain=In([False]), | ||
description="Holdup construction flag - must be False", | ||
doc="""Indicates whether holdup terms should be constructed or not. | ||
**default** - False. Membrane units do not have defined volume, thus | ||
this must be False.""", | ||
), | ||
) |
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.
Any reason that we need dynamic
and has_holdup
in the main config block as well as in the config template for hot and cold channels? I would think you could eliminate these 2 from config_template, but maybe there is some reason for doing this.
_CONFIG_Template.declare( | ||
"property_package_vapor", | ||
ConfigValue( | ||
default=useDefault, | ||
domain=is_physical_parameter_block, | ||
description="Property package to use for control volume", | ||
doc="""Property parameter object used to define property calculations, | ||
**default** - useDefault. | ||
**Valid values:** { | ||
**useDefault** - use default package from parent model or flowsheet, | ||
**PhysicalParameterObject** - a PhysicalParameterBlock object.}""", | ||
), | ||
) | ||
_CONFIG_Template.declare( | ||
"property_package_args_vapor", | ||
ConfigBlock( | ||
implicit=True, | ||
description="Arguments to use for constructing property packages", | ||
doc="""A ConfigBlock with arguments to be passed to a property block(s) | ||
and used when constructing these, | ||
**default** - None. | ||
**Valid values:** { | ||
see property package for documentation.}""", | ||
), | ||
) | ||
|
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.
Is there any need to have property_package_vapor
specified for each channel, or can we just specify it once on the main CONFIG
block?
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.
From the tests, I see you need to specify twice (once for each channel). Maybe there is some alternative configuration where you might want to consider 2 different vapor packages that I am not seeing, but from my current perspective, I don't see any immediate use cases for having 2 different vapor property packages.
@self.Constraint( | ||
self.flowsheet().config.time, | ||
self.difference_elements, | ||
doc="hot side evaporation enthalpy flux", | ||
) | ||
def eq_flux_hot_enth(b, t, x): | ||
return ( | ||
b.flux_enth_hot[t, x] | ||
== b.flux_mass[t, x] | ||
* b.hot_ch.properties_vapor[t, x].enth_mass_phase["Vap"] | ||
) | ||
|
||
@self.Constraint( | ||
self.flowsheet().config.time, | ||
self.difference_elements, | ||
doc="cold side evaporation enthalpy flux", | ||
) | ||
def eq_flux_cold_enth(b, t, x): | ||
return ( | ||
b.flux_enth_cold[t, x] | ||
== b.flux_mass[t, x] | ||
* b.cold_ch.properties_vapor[t, x].enth_mass_phase["Vap"] | ||
) | ||
|
||
@self.Expression( | ||
self.flowsheet().config.time, | ||
doc="Average hot side enthalpy flux expression", | ||
) | ||
def flux_enth_hot_avg(b, t): | ||
return ( | ||
sum(b.flux_enth_hot[t, x] for x in self.difference_elements) / self.nfe | ||
) | ||
|
||
@self.Expression( | ||
self.flowsheet().config.time, | ||
doc="Average cold side enthalpy flux expression", | ||
) | ||
def flux_enth_cold_avg(b, t): | ||
return ( | ||
sum(b.flux_enth_cold[t, x] for x in self.difference_elements) / self.nfe | ||
) |
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.
Shouldn't these be consolidated and put in MD_channel_base (or MD_channel_0D)?
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.
Mass and heat fluxes connect the channels but are not defined for each individual channel. Even the eq_flux_hot_enth and eq_flux_cold_enth are defined by the mass flux that connects the hot and cold channels.
self.flux_enth_hot = Var( | ||
self.flowsheet().config.time, | ||
self.difference_elements, | ||
initialize=1e3, | ||
bounds=(1e-4, 1e5), | ||
units=pyunits.J * pyunits.s**-1 * pyunits.m**-2, | ||
doc="hot side evaporation enthalpy flux", | ||
) | ||
|
||
self.flux_enth_cold = Var( | ||
self.flowsheet().config.time, | ||
self.difference_elements, | ||
initialize=1e3, | ||
bounds=(1e-4, 1e5), | ||
units=pyunits.J * pyunits.s**-1 * pyunits.m**-2, | ||
doc="cold side condensation enthalpy flux", | ||
) |
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't these go in one of the channel files? Then, you could later reference hot_ch.flux_enth
or cold_ch.flux_enth
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.
Only these two variables, but not their associated constraints, may go to MD_channel_base.
CONFIG.declare("hot_ch", _CONFIG_Template(doc="hot channel config arguments")) | ||
CONFIG.declare("cold_ch", _CONFIG_Template(doc="cold channel config arguments")) |
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.
Minor preference here, but I think it'd be better to fully spell out hot_channel
and cold_channel
.
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.
We can do this in future PRs as it requires changing many lines of code.
@ElmiraShamlou is planning to work on some details and documentation but overall should be soon ready for review. |
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 primarily reviewed the documentation and test file and it looks good.
One suggestion I have that would be for a later PR would be to change "ch" to "channel". Renaming won't be that big of deal, but lots of lines of code would change.
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 attempted to look through all of the files. It looks good to me.
I made comments on a few possible typos.
): | ||
super().add_state_blocks(has_phase_equilibrium=has_phase_equilibrium) | ||
|
||
# quack like a 1D model |
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 is meant here? I think there is a typo.
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.
@savannahsakhai Even though the model is 0D, it intentionally includes a length domain and inlet/outlet properties, aligning with the flow direction, much like a 1D model would
solute_set, | ||
doc="Concentration polarization modulus", | ||
) | ||
def eq_cp_modulus(b, t, x, j): # pylint: disable=function-redefined |
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.
Was this comment meant to be left in?
# self.config.hot_ch.property_package.phase_list, | ||
# self.config.hot_ch.property_package.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.
Are these meant to be left this way? Are they serving a purpose?
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.
We typically delete commented code, so we can delete in a subsequent PR.
self.flux_enth_hot = Var( | ||
self.flowsheet().config.time, | ||
self.difference_elements, | ||
initialize=1e3, | ||
bounds=(1e-10, 1e5), | ||
units=pyunits.J * pyunits.s**-1 * pyunits.m**-2, | ||
doc="hot side evaporation enthalpy flux", | ||
) | ||
|
||
self.flux_enth_cold = Var( | ||
self.flowsheet().config.time, | ||
self.difference_elements, | ||
initialize=1e3, | ||
bounds=(1e-10, 1e5), | ||
units=pyunits.J * pyunits.s**-1 * pyunits.m**-2, | ||
doc="cold side condensation enthalpy flux", | ||
) |
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.
The variables directly above this use units_meta. Is there a reason that these variables do not follow the same convention? I believe this only occurs a few times across the files.
m.fs.unit.permeability_coef.fix(1e-10) | ||
m.fs.unit.membrane_thickness.fix(1e-4) | ||
m.fs.unit.membrane_tc.fix(0.2) | ||
# m.fs.unit.hot_ch.cp_modulus.fix(1) |
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.
Is this comment meant to be left this way?
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.
LGTM - @ElmiraShamlou please create an issue tracking any comments here that we would consider in a follow-up PR.
Fixes/Resolves:
(replace this with the issue # fixed or resolved, if no issue exists then a brief statement of what this PR does)
Summary/Motivation:
Changes proposed in this PR:
Legal Acknowledgement
By contributing to this software project, I agree to the following terms and conditions for my contribution: