-
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
Reformulate solubility_products constraints #1197
Conversation
… betweem s and Q. Modified bounds of mole_frac_phase_comp to be consistent with those of log_mole_frac_phase_comp
For a bit more context, Xinhong has been working to make some of chemistry models in WaterTAP more stable. She found this issue with the formulation and came up with this fix to keep these smooth_max constraints scaled consistently. |
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 have a few questions about why you chose the formulation you did, as well as about consitency with other state definitions.
idaes/models/properties/modular_properties/state_definitions/FpcTP.py
Outdated
Show resolved
Hide resolved
idaes/models/properties/modular_properties/reactions/equilibrium_forms.py
Outdated
Show resolved
Hide resolved
idaes/models/properties/modular_properties/reactions/equilibrium_forms.py
Outdated
Show resolved
Hide resolved
Also, the tests for the solubility product are all failing right now. |
An alternate approach is to add a scaling factor to smooth_max.
From an implementation perspective, I proposed adding an optional I also like @andrewlee94's suggestion about scaling variables carefully. |
Remove initialization opts after updating bounds in state_difinitions
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.
@lxhowl Changing the bounds on the mole fractions is not the correct way to address the variables outside of bounds warning - that is something that needs to be fixed in either the model or the tool that is setting the value outside the bounds. The value of 1w-20 was deliberately chose to avoid singularities, and this change is likely what caused the testing in the plate heat exchanger model to start failing.
idaes/models_extra/column_models/tests/test_plate_heat_exchanger.py
Outdated
Show resolved
Hide resolved
idaes/models/properties/modular_properties/state_definitions/electrolyte_states.py
Outdated
Show resolved
Hide resolved
Codecov ReportPatch coverage:
Additional details and impacted files@@ Coverage Diff @@
## main #1197 +/- ##
==========================================
- Coverage 76.84% 76.83% -0.01%
==========================================
Files 390 390
Lines 61875 61885 +10
Branches 11389 11391 +2
==========================================
+ Hits 47547 47552 +5
- Misses 11866 11871 +5
Partials 2462 2462
☔ View full report in Codecov by Sentry. |
@lxhowl if the user does not specify |
@agarciadiego I am leaning towards just having the one version - the old one already had a smoothing factor that the user should be setting anyway so this just adds more flexibility (and better scaling overall). If we think it is necessary to keep both formulations, then I think they should be separate methods the user chooses from rather than an if statement in the code. An if buried in the code is far harder for the user to find and understand. @lxhowl This discussion did remind me however that you need to update the documentation to reflect the new formulation and explain the new parameters (and how the user should adjust them). |
@agarciadiego The tests I updated contains cases without The formulation of the updated |
The test failures are likely due to #1215 |
Q = b.log_k_eq[r_idx] - e | ||
# Q should be unitless due to log form | ||
|
||
return s - smooth_max(0, s - Q, rblock.eps) == 0 | ||
return Q - smooth_max(0, Q - s, rblock.eps) == 0 |
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.
If one or both Q and s need to be zero, could this just bee smooth min(Q, s) == 0?
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.
Current expression goes Q-0.5(Q-s+|Q-s|) == 0
while the smooth min gives 0.5(Q+s-|Q-s|)==0
. The complexity remains the same. The current expression keeps Q as a leading term, which might be easy for users to scale the solubility product with other equilibrium reactions.
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.
@eslickj I think this formulation is correct - it is a bit more complicated than just one of Q or s needing to be zero.
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.
@andrewlee94, I'm sure you are probably right. Can someone explain the difference to me? Why is this one preferred? I think both should work, but I may be missing something. To me, the the one in the code currently just seems convoluted.
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.
@eslickj I cannot remember the details - I asked Larry Biegler to help with this is and this is the form he suggested.
@lxhowl Is this ready for re-review yet? |
|
idaes/models/properties/modular_properties/reactions/equilibrium_forms.py
Outdated
Show resolved
Hide resolved
idaes/models/properties/modular_properties/reactions/equilibrium_forms.py
Outdated
Show resolved
Hide resolved
...models/properties/modular_properties/reactions/tests/test_solubility_product_verification.py
Outdated
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.
Looks good to me.
Fixes
pH-dependent solubility tests from WaterTAP
Summary/Motivation:
This solubility equilibrium constraint used a smoothing strategy to compare precipitate amount s and the solution state Q. Only one of s and Q can be greater than zero at any time. When s and Q differ in several orders of magnitude, the problem becomes hard to scale, especially when Q is in log form, the original formulation will sacrifice the accuracy of s, the precipitate amount, which could be very small (i.e., 1e-10) and important in water-related applications.
Fix outside of bounds warning in the initialization of pH-dependent solubility tests.
Changes proposed in this PR:
Normalize the precipitate amount s to be 0-1 with respect to its solubility product constant Ksp.
Update mole_frac_phase_comp bounds in FpcTP to be consistent with log_mole_frac_phase_comp bounds.
Legal Acknowledgement
By contributing to this software project, I agree to the following terms and conditions for my contribution: