Skip to content
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

Crossflow hx #1382

Merged
merged 46 commits into from
Apr 22, 2024
Merged

Crossflow hx #1382

merged 46 commits into from
Apr 22, 2024

Conversation

dallan-keylogic
Copy link
Contributor

@dallan-keylogic dallan-keylogic commented Mar 20, 2024

Summary/Motivation:

Adds models for crossflow heat exchanger and heater used in SOC dynamic flowsheet to models_extra.

Legal Acknowledgement

By contributing to this software project, I agree to the following terms and conditions for my contribution:

  1. I agree my contributions are submitted under the license terms described in the LICENSE.txt file at the top level of this directory.
  2. I represent I am authorized to make the contributions and grant the license. If my employer has rights to intellectual property that includes these contributions, I represent that I have received permission to make contributions and grant the required license on behalf of that employer.

@dallan-keylogic
Copy link
Contributor Author

The test failures are from what were supposed to be minor changes to the HeatExchanger1D model. Apparently having opposite discretization methods on both sides causes problems with the energy balance. This is a function of coarse discretization---when I switched to collocation the problem disappeared.

Copy link

codecov bot commented Mar 22, 2024

Codecov Report

Attention: Patch coverage is 83.51145% with 108 lines in your changes are missing coverage. Please review.

Project coverage is 77.69%. Comparing base (4e6a0f0) to head (09e6b31).

Files Patch % Lines
...ration/unit_models/cross_flow_heat_exchanger_1D.py 74.66% 53 Missing and 22 partials ⚠️
...er_generation/unit_models/heat_exchanger_common.py 90.47% 3 Missing and 17 partials ⚠️
...ls_extra/power_generation/unit_models/heater_1D.py 91.15% 9 Missing and 4 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1382      +/-   ##
==========================================
+ Coverage   77.62%   77.69%   +0.07%     
==========================================
  Files         391      394       +3     
  Lines       64375    65030     +655     
  Branches    14257    14384     +127     
==========================================
+ Hits        49973    50527     +554     
- Misses      11830    11895      +65     
- Partials     2572     2608      +36     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Member

@andrewlee94 andrewlee94 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few more comments but again mostly minor (and some are just suggestions you can feel free to ignore).

=========================== ============ =================================================================================


Initialization
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest moving the text here to the Initializer doc string (if it isn't there already) and use autodocs here. That way the user gets to see the arguments for the initializer and a hint to the name to import.


@pytest.mark.integration
def test_units(model_no_dP):
assert_units_consistent(model_no_dP.fs.heat_exchanger)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible to replace this with a model diagnostics check?

dt = DiagnosticsToolbox(m)
dt.assert_no_structural_issues()

This includes unit consistency, as well as all the other structural checks. There is an equivalent method for numerical checks too.

This is not critical for contrib model, but is good if we can do it.

# FIXME estimate from parameters
if blk.config.has_holdup:
s_U_holdup = gsf(blk.heat_holdup[t, z])
cst(blk.heat_holdup_eqn[t, z], s_U_holdup)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not necessary to do unless you want to (more just suggestions for future developements), but it would be nice to have some unit tests for these. They will get covered by the unit models, but unit testing these might help narrow down where failures are occurring if something does go wrong. I also see a lot of opportunities for breaking out smaller private functions that make up the main public methods for testing here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unit tests for scaling factors? Probably better to have some assertion about no numerical issues from the diagnostics toolbox.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You really want both - the purpose of the unit test is not to check the scaling factors themselves but that the code runs smoothly (i.e. to help you narrow down where the issues is occurring rather than having to work throguh the entire unit-level method to find where it breaks). You do need a separate set of tests to make sure that the scaling factors do improve the condition of the model (for limited test cases at least).

model.control_volume.pressure.fix()

model.control_volume.length.fix()
assert degrees_of_freedom(model.control_volume) == 0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You probably should not have an assert here, because if this fails it won't give the user a useful error message. The base class already does an initial DoF check, so you can probably get away without this here.

with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc:
res = solver_obj.solve(model.control_volume, tee=slc.tee)

assert_optimal_termination(res)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly, I think you need a try/except here to emit a useful error message.

model.control_volume.pressure.unfix()
model.control_volume.pressure[:, 0].fix()

assert degrees_of_freedom(model) == 0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As above, and a few lines below too.


CONFIG = UnitModelBlockData.CONFIG()
CONFIG.declare(
"has_fluid_holdup",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this distinct from the has_holdup that UnitModelBlockData.CONFIG already has? If so, a little more explanation of the difference might be needed. I suspect you are trying to separate energy holdup form fluid holdup.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it is. It's a stub for potentially having mass and energy holdup in the fluid (as opposed to the energy holdup in the walls). However, due to concerns about pressure waves, its only valid value is False for the time being.

),
)

CONFIG = CONFIG
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to be unnecessary.

Reference,
units as pyunits,
)
import pyomo.opt
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you need the blanket import for pyomo.opt?

# Important to do before initializing property packages in
# case it is implemented as Var-Constraint pair instead of
# an Expression
value(hot_side.properties[t0, 0].cp_mol)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor point, but you don't even need the value here - it is enough to just call hot_side.properties[t0, 0].cp_mol

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I took those out, but then Pylint complained the statements were pointless, so I put them back in.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Went back and took the values out while disabling Pylint warnings for them because there's no guarantee the evaluation won't cause some error before the model is initialized.

@codecov-commenter
Copy link

Codecov Report

Attention: Patch coverage is 83.17757% with 108 lines in your changes are missing coverage. Please review.

Project coverage is 77.69%. Comparing base (3a1d54a) to head (29c4a88).

Files Patch % Lines
...ration/unit_models/cross_flow_heat_exchanger_1D.py 77.74% 58 Missing and 21 partials ⚠️
...ls_extra/power_generation/unit_models/heater_1D.py 89.93% 12 Missing and 3 partials ⚠️
...er_generation/unit_models/heat_exchanger_common.py 89.70% 3 Missing and 11 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1382      +/-   ##
==========================================
+ Coverage   77.63%   77.69%   +0.06%     
==========================================
  Files         391      394       +3     
  Lines       64391    65033     +642     
  Branches    14264    14380     +116     
==========================================
+ Hits        49989    50530     +541     
- Misses      11830    11903      +73     
- Partials     2572     2600      +28     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@andrewlee94 andrewlee94 merged commit b3d55b7 into IDAES:main Apr 22, 2024
48 of 72 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Priority:Normal Normal Priority Issue or PR
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants