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

Enable RO0D to be dynamic #1471

Merged
merged 126 commits into from
Oct 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
126 commits
Select commit Hold shift + click to select a range
0992ca4
revised dyanmic and has holdup for membrane channel base/RO 0D, but p…
adam-a-a Jul 24, 2024
07ee8d2
Changed dynamic and has_holdup to not be hardcoded to False
fahim831 Jul 24, 2024
ddc50db
Merge branch 'ro0d_hasholdup' into dynamic-exploratory2
adam-a-a Jul 25, 2024
fa7dc7f
run black
adam-a-a Jul 25, 2024
90707f2
cleanup test
adam-a-a Jul 25, 2024
3554e8c
Fixed NaCl property package as per TIm's instructions to allow dynamics
fahim831 Jul 25, 2024
511db4a
add material_density by component
adam-a-a Jul 25, 2024
7951363
Merge branch 'mat_dens_terms' into dynamic-exploratory2
adam-a-a Jul 25, 2024
6fcd8a6
blk
adam-a-a Jul 25, 2024
3d0b908
put mat dens expr in right place
adam-a-a Jul 25, 2024
d8f9287
fix mat dens epr brackets
adam-a-a Jul 25, 2024
8b9e407
fix ro test
adam-a-a Jul 25, 2024
6d34229
blk
adam-a-a Jul 25, 2024
cd04d24
fix unintentional addition of conc_mass_phase_comp to state vars
adam-a-a Jul 25, 2024
2685ebd
remove commented out code
adam-a-a Jul 25, 2024
e3dab5e
Merge branch 'watertap-org:main' into dynamic-exploratory2
fahim831 Jul 25, 2024
42ffd7a
add new instance with simple configs
adam-a-a Jul 25, 2024
e9bd78a
Merge branch 'dynamic-exploratory2' of https://github.com/fahim831/wa…
adam-a-a Jul 25, 2024
d88c80e
black
adam-a-a Jul 25, 2024
e111ec8
Added numbers to initialize RO0D unit_models
fahim831 Jul 25, 2024
b4af3b4
Merge branch 'dynamic-exploratory2' of https://github.com/fahim831/wa…
fahim831 Jul 25, 2024
f59b598
raise config error for simple RO
adam-a-a Jul 25, 2024
1c19e60
Merge branch 'dynamic-exploratory2' of https://github.com/fahim831/wa…
adam-a-a Jul 25, 2024
90dfda7
Added pressure change back in to be identical to Adam's specs
fahim831 Jul 25, 2024
78eaa5d
Merge branch 'dynamic-exploratory2' of https://github.com/fahim831/wa…
fahim831 Jul 25, 2024
6c0d5af
setup.py point to dynamic_cv0d
kurbansitterley Jul 30, 2024
6e6a3a8
add back pyomo
kurbansitterley Jul 30, 2024
49c8ac8
black
kurbansitterley Jul 30, 2024
c94d453
revert debug changes after idaes PR fix; add check to tests to check …
adam-a-a Jul 30, 2024
a143bc3
cleanup and check material_holdup
adam-a-a Jul 30, 2024
b6ad14a
adjust test
adam-a-a Jul 30, 2024
939a8ee
blk
adam-a-a Jul 30, 2024
f875b52
initialize without the assert_units_consistent check in place
adam-a-a Jul 30, 2024
0f418f5
mixed_permeate as CV0D
kurbansitterley Jul 30, 2024
30ca95c
Merge branch 'dynamic-exploratory2' of https://github.com/fahim831/wa…
kurbansitterley Jul 30, 2024
3f30fbd
black RO-base
kurbansitterley Jul 30, 2024
4c304fb
add permeate port to mixed_permeate
kurbansitterley Jul 30, 2024
ad43f37
revert debug changes after idaes PR fix; add check to tests to check …
adam-a-a Jul 30, 2024
b14f6c0
cleanup and check material_holdup
adam-a-a Jul 30, 2024
8f5bb1d
adjust test
adam-a-a Jul 30, 2024
d219511
blk
adam-a-a Jul 30, 2024
88062be
initialize without the assert_units_consistent check in place
adam-a-a Jul 30, 2024
7c77610
Merge branch 'dynamic-exploratory2' of https://github.com/fahim831/wa…
kurbansitterley Jul 30, 2024
ed81950
undo RO0D and RObase changes
kurbansitterley Jul 30, 2024
a9c8758
revert setup.py
kurbansitterley Jul 30, 2024
79cfc27
black again
kurbansitterley Jul 30, 2024
e816dc5
add idaes temporary dependency
adam-a-a Jul 31, 2024
4e8b0fa
Merge branch 'dynamic-exploratory2' of https://github.com/fahim831/wa…
adam-a-a Jul 31, 2024
f1f5a77
black
adam-a-a Jul 31, 2024
8678ffe
add idaes dependency with CV0D fix
adam-a-a Jul 31, 2024
48a42d2
blk
adam-a-a Jul 31, 2024
607821a
move assertion
adam-a-a Jul 31, 2024
0feba1a
Currently DOF=2
fahim831 Jul 31, 2024
2db6427
Merge branch 'dynamic-exploratory2' of https://github.com/fahim831/wa…
fahim831 Jul 31, 2024
0befd21
petsc succeeds with DOF=0
adam-a-a Aug 1, 2024
34c7370
cleanup
adam-a-a Aug 1, 2024
69396f3
Merge branch 'dynamic-exploratory2' of https://github.com/fahim831/wa…
adam-a-a Aug 1, 2024
5a9e47f
bring my changes back in after merging with fahim's last commits
adam-a-a Aug 1, 2024
ab88730
remove unused imports
adam-a-a Aug 1, 2024
8fdfc1d
one more import to delete
adam-a-a Aug 1, 2024
1e13c0a
add petsc to github actions
adam-a-a Aug 1, 2024
2845d43
skip test for workflows that don't have petsc available; note, tests …
adam-a-a Aug 1, 2024
6ffa537
Nonzero accumulation. Can get dynamic change now.
fahim831 Aug 2, 2024
38695bb
Getting a plot for RO0D now.
fahim831 Aug 3, 2024
2347c54
Plotting permeate NaCl conc.
fahim831 Aug 3, 2024
f215368
Plotting feed outlet C_NaCl
fahim831 Aug 5, 2024
c4fd016
Blacked RO0D test
fahim831 Aug 5, 2024
0247f90
Plots 5 things.
fahim831 Aug 5, 2024
cabfad7
Preliminary results obtained.
fahim831 Aug 9, 2024
546d4d7
try to fix failed mac test and run black
adam-a-a Aug 12, 2024
d52cc8b
revised dyanmic and has holdup for membrane channel base/RO 0D, but p…
adam-a-a Jul 24, 2024
18db269
add material_density by component
adam-a-a Jul 25, 2024
8590640
fix mat dens epr brackets
adam-a-a Jul 25, 2024
8e6f7a1
add new instance with simple configs
adam-a-a Jul 25, 2024
e22a7d6
raise config error for simple RO
adam-a-a Jul 25, 2024
8bc6f6c
black
kurbansitterley Jul 30, 2024
2356a5f
revert debug changes after idaes PR fix; add check to tests to check …
adam-a-a Jul 30, 2024
91e696b
revert debug changes after idaes PR fix; add check to tests to check …
adam-a-a Jul 30, 2024
a8c2ead
petsc succeeds with DOF=0
adam-a-a Aug 1, 2024
b54a7ba
Currently DOF=2
fahim831 Jul 31, 2024
5f16747
bring my changes back in after merging with fahim's last commits
adam-a-a Aug 1, 2024
d54b982
remove unused imports
adam-a-a Aug 1, 2024
b20bc96
Validate dynamic results.
fahim831 Aug 15, 2024
8b29ade
Validate dynamic model.
fahim831 Aug 15, 2024
89806cf
Validate dynamic model.
fahim831 Aug 15, 2024
8eb9dd2
Merge branch 'watertap-org:main' into dynamic-exploratory2
fahim831 Aug 15, 2024
d8f0054
black
adam-a-a Aug 15, 2024
1e714fa
try to fix test_cstr
adam-a-a Aug 15, 2024
861e6bd
bk
adam-a-a Aug 15, 2024
7bd476f
test commit
kurbansitterley Aug 15, 2024
409e693
black again
adam-a-a Aug 15, 2024
9e32a65
remove unused import
adam-a-a Aug 15, 2024
7feaca4
Revert "try to fix failed mac test and run black"
adam-a-a Aug 20, 2024
8ed69f7
test ro back up and running
adam-a-a Aug 20, 2024
b020636
run black and remove extra import
adam-a-a Aug 20, 2024
5014771
cleanup RO base
adam-a-a Aug 20, 2024
05c0b71
Apply suggestions from code review
adam-a-a Aug 20, 2024
867071b
Update setup.py
adam-a-a Aug 20, 2024
a282f18
Merge branch 'main' into dynamic-exploratory2
adam-a-a Aug 22, 2024
1cdd1a2
Merge branch 'main' into dynamic-exploratory2
adam-a-a Sep 11, 2024
fb0ed2d
fix checks
adam-a-a Sep 11, 2024
cbabaca
probe failure
adam-a-a Sep 11, 2024
0e2bfe0
bring back reverted commit
adam-a-a Sep 11, 2024
32f6ab6
Revert "Merge branch 'main' into dynamic-exploratory2"
adam-a-a Sep 11, 2024
c3edf5f
remove file that surprisingly made its way into a commit
adam-a-a Sep 11, 2024
ac7ec77
point to 2.6rc
adam-a-a Sep 11, 2024
ca1b1ac
Merge branch 'main' into dynamic-exploratory2
adam-a-a Sep 12, 2024
fccd484
adjust HRT constraint on cstr and check failing macos test
adam-a-a Sep 12, 2024
998259a
remove unused import
adam-a-a Sep 12, 2024
88a78c8
Merge branch 'dynamic-exploratory2' of https://github.com/fahim831/wa…
adam-a-a Sep 12, 2024
8ef8e4b
black
adam-a-a Sep 12, 2024
efa5423
reset membrance_channel0d to match main
adam-a-a Sep 12, 2024
5aff8c4
merge main flowsheets
adam-a-a Sep 13, 2024
f3e52a8
bring back other changes that are in main already
adam-a-a Sep 13, 2024
096dbcd
Merge branch 'main' into dynamic-exploratory2
adam-a-a Sep 13, 2024
0f3a41d
revert hydraulic retention time constraint
adam-a-a Oct 3, 2024
99b1e8c
Merge branch 'dynamic-exploratory2' of https://github.com/fahim831/wa…
adam-a-a Oct 3, 2024
bd2caa8
checkpoint: add scaling to cstr but didn't note any affect on BSM2-P …
adam-a-a Oct 7, 2024
05b717a
Merge branch 'main' of https://github.com/watertap-org/watertap
adam-a-a Oct 18, 2024
ce1232c
add requires idaes solver mark for dynamic ro test
adam-a-a Oct 23, 2024
62e9fa9
Merge branch 'main' into dynamic-exploratory2
adam-a-a Oct 23, 2024
5752735
cleanup
adam-a-a Oct 24, 2024
f755bf8
Revert "checkpoint: add scaling to cstr but didn't note any affect on…
adam-a-a Oct 24, 2024
10ae589
black
adam-a-a Oct 24, 2024
07b53b7
address pylint
adam-a-a Oct 24, 2024
8e6f462
Merge branch 'main' into dynamic-exploratory2
adam-a-a Oct 24, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ jobs:
pip show idaes-pse
echo '::endgroup::'
echo '::group::Output of "idaes get-extensions" command'
idaes get-extensions --verbose
idaes get-extensions --extra petsc --verbose
echo '::endgroup::'
- name: Add coverage report pytest options
if: matrix.coverage
Expand Down Expand Up @@ -218,7 +218,7 @@ jobs:
pip show idaes-pse
echo '::endgroup::'
echo '::group::Output of "idaes get-extensions" command'
idaes get-extensions --verbose
idaes get-extensions --extra petsc --verbose
echo '::endgroup::'
- name: Run pytest
run: |
Expand Down Expand Up @@ -263,7 +263,7 @@ jobs:
pip show idaes-pse
echo '::endgroup::'
echo '::group::Output of "idaes get-extensions" command'
idaes get-extensions --verbose
idaes get-extensions --extra petsc --verbose
echo '::endgroup::'
- name: Install Jupyter kernel
run: |
Expand Down
16 changes: 13 additions & 3 deletions watertap/core/membrane_channel_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ class FrictionFactor(Enum):
"dynamic",
ConfigValue(
default=False,
domain=In([False]),
domain=Bool,
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
Expand All @@ -120,7 +120,7 @@ class FrictionFactor(Enum):
"has_holdup",
ConfigValue(
default=False,
domain=In([False]),
domain=Bool,
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
Expand Down Expand Up @@ -1011,7 +1011,17 @@ def calculate_scaling_factors(self):

# helper for validating configuration arguments for this CV
def validate_membrane_config_args(unit):

if unit.config.dynamic and unit.config.has_holdup:
if not (
(unit.config.pressure_change_type != PressureChangeType.fixed_per_stage)
or (
unit.config.mass_transfer_coefficient
== MassTransferCoefficient.calculated
)
):
raise ConfigurationError(
f"dynamics=True and has_holdup=True will not work while pressure_change_type={unit.config.pressure_change_type} and mass_tranfer_coefficient={unit.config.mass_transfer_coefficient}\n. To enable dynamics, choose any other configuration option for pressure_change_type or mass_transfer_coefficient."
)
if (
unit.config.pressure_change_type is not PressureChangeType.fixed_per_stage
and unit.config.has_pressure_change is False
Expand Down
27 changes: 20 additions & 7 deletions watertap/property_models/NaCl_prop_pack.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,14 @@ def build(self):
doc="Molecular weight kg/mol",
)

# Density of water at 25 C
self.dens_mass_solvent = Var(
within=Reals,
initialize=997,
units=pyunits.kg / pyunits.m**3,
doc="Mass density of water",
)

# mass density parameters, eq 4 in Bartholomew
dens_mass_param_dict = {"0": 995, "1": 756}
self.dens_mass_param = Var(
Expand Down Expand Up @@ -226,7 +234,7 @@ def fix_initialization_states(self):
# Constraint on water concentration at outlet - unfix in these cases
for b in self.values():
if b.config.defined_state is False:
b.conc_mol_comp["H2O"].unfix()
b.flow_mass_phase_comp["Liq", "H2O"].unfix()

def initialize(
self,
Expand Down Expand Up @@ -491,7 +499,7 @@ def build(self):
)

# -----------------------------------------------------------------------------
# Property Methods
# On-demand Property Methods
def _mass_frac_phase_comp(self):
self.mass_frac_phase_comp = Var(
self.params.phase_list,
Expand Down Expand Up @@ -788,11 +796,16 @@ def get_enthalpy_flow_terms(self, p):
return self.enth_flow

# TODO: make property package compatible with dynamics
# def get_material_density_terms(self, p, j):
# """Create material density terms."""

# def get_enthalpy_density_terms(self, p):
# """Create enthalpy density terms."""
def get_material_density_terms(self, p, j):
"""Create material density terms."""
if j == "H2O":
return self.params.dens_mass_solvent
else:
return self.conc_mass_phase_comp[p, j]

def get_energy_density_terms(self, p):
"""Create enthalpy density terms."""
return self.enth_mass_phase[p] * self.dens_mass_phase[p]

def default_material_balance_type(self):
return MaterialBalanceType.componentTotal
Expand Down
4 changes: 2 additions & 2 deletions watertap/unit_models/reverse_osmosis_0D.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ class ReverseOsmosisData(ReverseOsmosisBaseData):
def _add_feed_side_membrane_channel_and_geometry(self):
# Build membrane channel control volume
self.feed_side = MembraneChannel0DBlock(
dynamic=False,
has_holdup=False,
dynamic=self.config.dynamic,
has_holdup=self.config.has_holdup,
property_package=self.config.property_package,
property_package_args=self.config.property_package_args,
)
Expand Down
9 changes: 7 additions & 2 deletions watertap/unit_models/tests/test_cstr.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
SingleControlVolumeUnitInitializer,
InitializationStatus,
)
import idaes.logger as idaeslog

# -----------------------------------------------------------------------------
# Get default solver for testing
Expand Down Expand Up @@ -271,13 +272,17 @@ def model(self):
m.fs.unit.heat_duty[0].fix(0)
m.fs.unit.deltaP[0].fix(0)

iscale.calculate_scaling_factors(m)
return m

@pytest.mark.requires_idaes_solver
@pytest.mark.component
def test_general_hierarchical(self, model):
initializer = SingleControlVolumeUnitInitializer()
initializer.initialize(model.fs.unit)
initializer = SingleControlVolumeUnitInitializer(
writer_config={"linear_presolve": False}
)

initializer.initialize(model.fs.unit, output_level=idaeslog.DEBUG)

assert initializer.summary[model.fs.unit]["status"] == InitializationStatus.Ok

Expand Down
118 changes: 115 additions & 3 deletions watertap/unit_models/tests/test_reverse_osmosis_0D.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,15 @@
# information, respectively. These files are also available online at the URL
# "https://github.com/watertap-org/watertap/"
#################################################################################
from pyomo.environ import ConcreteModel
from pyomo.environ import (
ConcreteModel,
units as pyunits,
TransformationFactory,
assert_optimal_termination,
)
from pyomo.network import Port
from idaes.core.solvers import petsc

from idaes.core import (
FlowsheetBlock,
MaterialBalanceType,
Expand Down Expand Up @@ -43,6 +50,10 @@
from watertap.unit_models.tests.unit_test_harness import UnitTestHarness
import pytest

from idaes.core.solvers import petsc
import numpy as np


# -----------------------------------------------------------------------------
# Get default solver for testing
solver = get_solver()
Expand Down Expand Up @@ -115,9 +126,9 @@ def test_default_config_and_build():
== "fs._time*fs.unit.feed_side.length_domain"
)
# test statistics
assert number_variables(m) == 134
assert number_variables(m) == 135
assert number_total_constraints(m) == 110
assert number_unused_variables(m) == 1
assert number_unused_variables(m) == 2


def build():
Expand Down Expand Up @@ -982,3 +993,104 @@ def configure(self):
}

return m


@pytest.mark.requires_idaes_solver
@pytest.mark.unit
def test_RO_dynamic_instantiation():
# TODO: add test to check exception for simplest RO0D with dynamics

m = ConcreteModel()
m.fs = FlowsheetBlock(
dynamic=True,
time_set=list(np.linspace(0, 200, 6)),
time_units=pyunits.s,
)

m.fs.properties = props.NaClParameterBlock()

m.fs.unit = ReverseOsmosis0D(
dynamic=True,
has_holdup=True,
property_package=m.fs.properties,
has_pressure_change=True,
concentration_polarization_type=ConcentrationPolarizationType.calculated,
mass_transfer_coefficient=MassTransferCoefficient.calculated,
pressure_change_type=PressureChangeType.calculated,
module_type=ModuleType.spiral_wound,
)

time_nfe = len(m.fs.time) - 1
TransformationFactory("dae.finite_difference").apply_to(
m.fs, nfe=time_nfe, wrt=m.fs.time, scheme="BACKWARD"
)
Copy link
Contributor

Choose a reason for hiding this comment

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

It might be better to add this as a config option in future.


NaCl_g_per_L_basis = 39
NaCl_kg_per_L_basis = NaCl_g_per_L_basis * 1e-3
h2o_kg_per_L_basis = 1 - NaCl_kg_per_L_basis # 0.96
desired_feed_flow_start = 22 / 60 # 22 L/min to kg/s
NaCl_kg_per_L_start = desired_feed_flow_start / (
h2o_kg_per_L_basis / NaCl_kg_per_L_basis + 1
)
h2o_kg_per_L_start = NaCl_kg_per_L_start * h2o_kg_per_L_basis / NaCl_kg_per_L_basis
desired_feed_flow_end = 24 / 60 # 22 L/min to kg/s
NaCl_kg_per_L_end = desired_feed_flow_end / (
h2o_kg_per_L_basis / NaCl_kg_per_L_basis + 1
)
h2o_kg_per_L_end = NaCl_kg_per_L_end * h2o_kg_per_L_basis / NaCl_kg_per_L_basis
ramp_gradient_NaCl = NaCl_kg_per_L_end - NaCl_kg_per_L_start
ramp_gradient_h2o = h2o_kg_per_L_end - h2o_kg_per_L_start

m.fs.unit.inlet.flow_mass_phase_comp[:, "Liq", "NaCl"].fix(NaCl_kg_per_L_end)
m.fs.unit.inlet.flow_mass_phase_comp[:, "Liq", "H2O"].fix(h2o_kg_per_L_end)
m.fs.unit.inlet.pressure[:].fix(900 * 6895) # feed pressure (Pa)
ramp_len = 80
for i in list([0, 40, ramp_len]):
m.fs.unit.inlet.flow_mass_phase_comp[i, "Liq", "NaCl"].fix(NaCl_kg_per_L_start)
m.fs.unit.inlet.flow_mass_phase_comp[i, "Liq", "H2O"].fix(h2o_kg_per_L_start)
m.fs.unit.inlet.flow_mass_phase_comp[ramp_len + i, "Liq", "NaCl"].fix(
NaCl_kg_per_L_start + ramp_gradient_NaCl / ramp_len * i
)
m.fs.unit.inlet.flow_mass_phase_comp[ramp_len + i, "Liq", "H2O"].fix(
h2o_kg_per_L_start + ramp_gradient_h2o / ramp_len * i
)
m.fs.unit.inlet.pressure[i].fix(800 * 6895) # feed pressure (Pa)
m.fs.unit.inlet.pressure[ramp_len + i].fix(
(800 + 100 / ramp_len * i) * 6895
) # feed pressure (Pa)

m.fs.unit.inlet.temperature[:].fix(293.15) # feed temperature (K)

m.fs.unit.area.fix(7.4) # membrane area (m^2)
m.fs.unit.A_comp.fix(3.75e-12) # membrane water permeability (m/Pa/s)
m.fs.unit.B_comp.fix(3e-8) # membrane salt permeability (m/s)
m.fs.unit.permeate.pressure[:].fix(101325) # permeate pressure (Pa)

m.fs.unit.feed_side.channel_height.fix(0.001)
m.fs.unit.feed_side.spacer_porosity.fix(0.729) # 72.9%
m.fs.unit.length.fix(1.016 - 2 * 0.0267) # m

m.fs.unit.feed_side.material_accumulation[:, :, :].value = 0
m.fs.unit.feed_side.material_accumulation[0, :, :].fix(0)

assert not hasattr(m.fs.unit.feed_side, "energy_accumulation")

m.fs.properties.set_default_scaling("flow_mass_phase_comp", 1, index=("Liq", "H2O"))
m.fs.properties.set_default_scaling(
"flow_mass_phase_comp", 1e2, index=("Liq", "NaCl")
)

iscale.set_scaling_factor(m.fs.unit.area, 1e-2)

iscale.calculate_scaling_factors(m)

m.fs.unit.initialize()

iscale.calculate_scaling_factors(m)

results = petsc.petsc_dae_by_time_element(
m,
time=m.fs.time,
)
for result in results.results:
assert_optimal_termination(result)
Loading