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

Base class for handling the spacer correlations and process block cla… #1496

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

charansamineni
Copy link

…ss to create a RO 1D unit model with user choice for spacer type, sherwood correlation, and pressure drop calculation. Original constraints are not deleted just deactivated

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:

  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.

…ss to create a RO 1D unit model with user choice for spacer type, sherwood correlation, and pressure drop calculation. Original constraints are not deleted just deactivated
@ksbeattie
Copy link
Contributor

@charansamineni might you be able to provide some tests and documentation updates for this?

@charansamineni
Copy link
Author

@ksbeattie, I am working on getting it ready. I have to add some more functionality based on feedback from reviewers.

Copy link
Contributor

@adam-a-a adam-a-a left a comment

Choose a reason for hiding this comment

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

Thank you for putting up these proposed changes, and congratulations on putting up your first PR here! I have long wanted to incorporate more detailed correlations related to spacer geometry and am glad that you've taken the step to do so.

There is a bit of work to do here before we can merge these changes. After my first pass, here are my overall, initial suggestions:

  1. Add a test file for ro_1D_custom_spacer. Here, you can test different configuration setups for RO, which would show reviewers more clearly how the changes would channel through to the user. Moreover, this would give you the chance to identify low-hanging bugs in the existing code. Perhaps you shouldn't add every test under the sun in relation to the correlations in custom_spacer_base because, if we do keep the separate class, I would think there would be a dedicated test file for that class. That said, it won't hurt to do so minimal level of testing and move tests later. From here, we should do another pass of reviews.
  2. After that, once you have some basic tests that probe the various ways of configuring RO1D, now you can switch gears and try merging changes from ro_1D_custom_spacer directly into the existing classes for RO and/or membrane channel. You would also add your new tests for this custom RO1d to the existing test file for RO1d. Many things will break, and all that breakage will need repair until tests pass.

Try doing step 1, and let's revisit the custom_spacer_base class after that.

_log.setLevel(idaeslog.DEBUG)


@declare_process_block_class("ReverseOsmosis1DCustomSpacer")
Copy link
Contributor

Choose a reason for hiding this comment

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

The first thought that comes to mind is that this should not be a separate unit model. Although it could be, this would add redundancy that we typically try to avoid. Have you tried bringing your changes into the existing RO1D model? If we were to implement these changes, we'd likely want to incorporate into the membrane_channel and RO classes, where relevant. This makes the implementation a little trickier but is ultimately what should be merged into the main codebase.

_add_geometry_config(CONFIG=CONFIG)

def build(self):
_log.warning("CUSTOM SPACER RO MODEL is being used for the build")
Copy link
Contributor

@adam-a-a adam-a-a Oct 3, 2024

Choose a reason for hiding this comment

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

This would be unnecessary once incorporating into our existing RO unit, but I do like the idea of logging what the user ultimately defined in the RO model configuration! No need to pursue that in this PR, but given the increasing complexity of config options, it might not be a bad idea for the user to get a snapshot of what config settings they ultimately are working with upon instantiation, since much of this can be opaque to new and experienced users alike.

self.config.transformation_scheme = "BACKWARD"
return

def _check_spacer_config(self):
Copy link
Contributor

Choose a reason for hiding this comment

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

This method is going to require quite a bit of testing to ensure that intended combinations of config options work the way they should, and unintended, incorrect combinations actually raise the exception that you would expect.

doc="Sherwood number equation modified to "
+ str(self.config.sherwood_correlation),
)
def eq_N_Sh_comp_modified(b, t, x, j):
Copy link
Contributor

Choose a reason for hiding this comment

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

Initially, I would think that the N_sh constraint should keep the original name rather creating a new constraint name, for the purpose of maintaining symmetry in the model when possible.

Comment on lines +242 to +243
self.feed_side.eq_N_Sh_comp.deactivate()
self.feed_side.eq_N_Sh_comp_modified.activate()
Copy link
Contributor

Choose a reason for hiding this comment

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

I would prefer this not to be here. Instead, it'd be great if we just kept eq_N_Sh_comp. This works as a bandaid for doing analysis locally, but in terms of merging to main and documenting model additions, having the one original constraint makes more sense.

Comment on lines +249 to +250
self.feed_side.eq_friction_factor.deactivate()
self.feed_side.eq_friction_factor_modified.activate()
Copy link
Contributor

Choose a reason for hiding this comment

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

same thing here---rather deactivate the original constraint and activate a new one, we should try to just use the original constraint and make appropriate changes to do so with overwriting the constraint, which Pyomo will throw up a warning for.

)

if self.config.sherwood_correlation == SherwoodCorrelation.da_costa:
self.feed_side.Sh_corr_factor_da_costa = Var(
Copy link
Contributor

Choose a reason for hiding this comment

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

These are intended for the feed_side of RO, which indicates that this should be in membrane_channel or the RO class. Can any of the correlations be applied to the permeate side, say, in OARO? If yes, then putting in one of the membrane_channel cases might make sense. If limited to the feed side for RO, then I wonder whether this should live here. In essence, custom_space_base hinges upon RO, but the fact that its introduced as a separate base class could indicate otherwise. Does it make more sense to not have this separate base class? I say this only after a relatively quick scan--it could be that having this separate class is beneficial. Will be able to tell more after testing is introduced.

# Porosity calculation from Equation 3.7 in Da Costa, Andre. Fluid flow and mass transfer in spacer-filled
# channels for ultrafiltration. Diss. UNSW Sydney, 1993.
def eq_spacer_porosity(b):
return b.spacer_porosity == 1 - pi * b.filament_dia**2 / (
Copy link
Contributor

Choose a reason for hiding this comment

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

FYI, we normally import constants like pi from idaes.core.util.constants. In this case, idaes just uses the same math import for pi anyway, so doesn't matter here.

# Constraint for spacer height
@self.feed_side.Constraint(doc="Spacer height calculation for net spacer")
def eq_spacer_height(b):
return b.spacer_height == 2 * b.filament_dia
Copy link
Contributor

Choose a reason for hiding this comment

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

Should it always be the case that spacer height is 2*D? If not, should we add a mutable Param initialized to 2 instead? Also, are we introducing redundant constraints by doing this since spacer height=channel height?

Copy link
Contributor

Choose a reason for hiding this comment

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

I guess the question is--is there ever a case when spacer height does not equal channel height? If there is no such exception, I would suggest only maintaining channel_height. And if you really are tied to referring to spacer height, you could always create an Expression, spacer_height, which would just point to channel_height

Comment on lines +123 to +128
graetz = auto()
sieder = auto()
guillen = auto()
schock = auto()
da_costa = auto()
parameterized = auto()
Copy link
Contributor

Choose a reason for hiding this comment

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

Given the breadth of additions in this PR, we'll definitely want to add documentation to readthedocs to capture all the additions. That can come at the end of this though, once satisfied with the core code changes.

Copy link

codecov bot commented Oct 9, 2024

Codecov Report

Attention: Patch coverage is 0% with 300 lines in your changes missing coverage. Please review.

Project coverage is 92.87%. Comparing base (e93578f) to head (af722d4).
Report is 4 commits behind head on main.

Files with missing lines Patch % Lines
watertap/core/custom_spacer_base.py 0.00% 197 Missing ⚠️
watertap/unit_models/ro_1D_custom_spacer.py 0.00% 103 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1496      +/-   ##
==========================================
- Coverage   93.78%   92.87%   -0.92%     
==========================================
  Files         282      284       +2     
  Lines       29996    30697     +701     
==========================================
+ Hits        28133    28510     +377     
- Misses       1863     2187     +324     

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Priority:Low Low Priority Issue or PR
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants