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

BSM2 full flowsheet #1038

Merged
merged 84 commits into from
Aug 18, 2023
Merged

BSM2 full flowsheet #1038

merged 84 commits into from
Aug 18, 2023

Conversation

agarciadiego
Copy link
Contributor

@agarciadiego agarciadiego commented May 22, 2023

Summary/Motivation:

BSM2 full flowsheet #934

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.

@agarciadiego agarciadiego self-assigned this May 22, 2023
@agarciadiego agarciadiego marked this pull request as draft May 22, 2023 15:34
Copy link
Contributor

@bknueven bknueven left a comment

Choose a reason for hiding this comment

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

Just capturing some initial thoughts / questions I have on the code

@andrewlee94
Copy link
Collaborator

@adam-a-a @agarciadiego ExprIf is generally OK as long as the solution does not exist near (or frequently cross) the boundary.

There are two potential issues with ExprIf:

  1. If the function is discontinuous and the first (and maybe second) partial derivatives are non-monotonic then you can have issues with the solution around the switch point. If these conditions are met then the solution should be stable at least.
  2. The other issue is that when the state of the model crosses the switch point, the solver generally needs to rebuild the problem (as the matrices have now changed). This adds an overhead, which can be a big issue if the state keeps oscillating around the switch point (or in a DAE system where you can see each point in the domain switching in sequence).

** 2
),
return (
-3
* (
smooth_max(0, self.params.pH_UL_ac - self.pH, eps=1e-8)
/ (self.params.pH_UL_ac - self.params.pH_LL_ac)
)
** 2
)

self.I_pH_ac = pyo.Expression(
rule=rule_I_pH_ac, doc="pH inhibition of acetate-utilizing microorganisms"
)

def rule_I_pH_h2(self):
return pyo.Expr_if(
self.pH > self.params.pH_UL_h2,
1,
pyo.exp(
-3
* (
(self.pH - self.params.pH_UL_h2)
/ (self.params.pH_UL_h2 - self.params.pH_LL_h2)
)
** 2
),
return (
-3
* (
smooth_max(0, self.params.pH_UL_h2 - self.pH, eps=1e-8)
/ (self.params.pH_UL_h2 - self.params.pH_LL_h2)
)
** 2
Copy link
Contributor

Choose a reason for hiding this comment

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

Technically, these are log(I_pH_ac) and log(I_pH_h2). We should name the associated expressions accordingly.

smooth_max(0, self.params.pH_UL_h2 - self.pH, eps=1e-8)
/ (self.params.pH_UL_h2 - self.params.pH_LL_h2)
)
** 2
)

self.I_pH_h2 = pyo.Expression(
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
self.I_pH_h2 = pyo.Expression(
self.log_I_pH_h2 = pyo.Expression(

smooth_max(0, self.params.pH_UL_ac - self.pH, eps=1e-8)
/ (self.params.pH_UL_ac - self.params.pH_LL_ac)
)
** 2
)

self.I_pH_ac = pyo.Expression(
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
self.I_pH_ac = pyo.Expression(
self.log_I_pH_ac = pyo.Expression(

** 2
),
return (
-3
Copy link
Contributor

Choose a reason for hiding this comment

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

Same comments as before- should rename expressions to indicate logarithmic form as well as doc string descriptions.

Comment on lines +644 to +652
assert value(model.fs.unit.liquid_phase.reactions[0].pKW, Var) == pytest.approx(
-log10(2.08e-14), rel=1e-2
)
assert value(
model.fs.unit.liquid_phase.reactions[0].K_a_co2, Var
) == pytest.approx(4.94e-7, rel=1e-2)
model.fs.unit.liquid_phase.reactions[0].pK_a_co2, Var
) == pytest.approx(-log10(4.94e-7), rel=1e-2)
assert value(
model.fs.unit.liquid_phase.reactions[0].K_a_IN, Var
) == pytest.approx(1.11e-9, rel=1e-2)
model.fs.unit.liquid_phase.reactions[0].pK_a_IN, Var
) == pytest.approx(-log10(1.11e-9), rel=1e-2)
Copy link
Contributor

Choose a reason for hiding this comment

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

@MarcusHolly can we verify whether updates to documentation will be needed based on the changes in this PR to some variables/constraints?

Copy link
Contributor

Choose a reason for hiding this comment

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

If so, let's track with an issue

Copy link
Contributor

Choose a reason for hiding this comment

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

@adam-a-a Yes - it appears some changes will need to be made to the ADM1 and modified ADM1 documentation. I will add it to the master issue and get to it when I have the time.

Comment on lines +594 to +600
m.fs.unit.inlet.conc_mass_comp[0, "X_su"].fix(1e-8)
m.fs.unit.inlet.conc_mass_comp[0, "X_aa"].fix(1e-8)
m.fs.unit.inlet.conc_mass_comp[0, "X_fa"].fix(1e-8)
m.fs.unit.inlet.conc_mass_comp[0, "X_c4"].fix(1e-8)
m.fs.unit.inlet.conc_mass_comp[0, "X_pro"].fix(1e-8)
m.fs.unit.inlet.conc_mass_comp[0, "X_ac"].fix(1e-8)
m.fs.unit.inlet.conc_mass_comp[0, "X_h2"].fix(1e-8)
Copy link
Contributor

Choose a reason for hiding this comment

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

curious why 0s were able to be set for other model specifications after changes but not 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.

That change affected the translators

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.

I have several suggestions that I think can be handled in a subsequent PR. Let's get this in and keep the locomotive moving! Great job!

@adam-a-a
Copy link
Contributor

NOTE: @agarciadiego @MarcusHolly @luohezhiming @TimBartholomew - I renamed the BSM2 folder as "full_water_resource_recovery_facility" since the fixed values specified in the flowsheet deviate from that of BSM2 defaults. Our other implementation of this flowsheet, with BSM2 defaults, is intended to be conveyed through Jupyter Notebook.

Also, we talked a bit about this but after some more thought, since we plan to export BSM2 to the GUI, we should probably consider replacing values in the full_WRRF_with_ASM1_and_ADM1 flowsheet in this PR with BSM2 defaults and use that for the GUI export.

@adam-a-a adam-a-a enabled auto-merge (squash) August 17, 2023 19:07
@adam-a-a adam-a-a merged commit 579b0b9 into watertap-org:main Aug 18, 2023
22 of 23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Priority:High High Priority Issue or PR
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants