Skip to content

Commit

Permalink
Add ScalingProfiler tests for dewatering unit
Browse files Browse the repository at this point in the history
  • Loading branch information
MarcusHolly committed Jan 10, 2025
1 parent adc9362 commit 7ddf784
Showing 1 changed file with 130 additions and 1 deletion.
131 changes: 130 additions & 1 deletion watertap/unit_models/tests/test_dewatering_unit.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"""
Tests for dewatering unit example.
"""

from io import StringIO
import pytest
from pyomo.environ import (
ConcreteModel,
Expand All @@ -34,6 +34,7 @@
jacobian_cond,
)
from idaes.core.scaling.scaling_base import ScalerBase
from idaes.core.scaling.scaler_profiling import ScalingProfiler

from idaes.models.unit_models.separator import SplittingType

Expand Down Expand Up @@ -1184,3 +1185,131 @@ def test_example_case_scaler(self):
assert (jacobian_cond(jac=jac, scaled=False)) == pytest.approx(
2.100583344e4, rel=1e-3
)


def build_model():
m = ConcreteModel()
m.fs = FlowsheetBlock(dynamic=False)

m.fs.props = ASM1ParameterBlock()

m.fs.unit = DewateringUnit(property_package=m.fs.props)

m.fs.unit.inlet.flow_vol.fix(178.4674 * units.m**3 / units.day)
m.fs.unit.inlet.temperature.fix(308.15 * units.K)
m.fs.unit.inlet.pressure.fix(1 * units.atm)

m.fs.unit.inlet.conc_mass_comp[0, "S_I"].fix(130.867 * units.mg / units.liter)
m.fs.unit.inlet.conc_mass_comp[0, "S_S"].fix(258.5789 * units.mg / units.liter)
m.fs.unit.inlet.conc_mass_comp[0, "X_I"].fix(17216.2434 * units.mg / units.liter)
m.fs.unit.inlet.conc_mass_comp[0, "X_S"].fix(2611.4843 * units.mg / units.liter)
m.fs.unit.inlet.conc_mass_comp[0, "X_BH"].fix(1e-6 * units.mg / units.liter)
m.fs.unit.inlet.conc_mass_comp[0, "X_BA"].fix(1e-6 * units.mg / units.liter)
m.fs.unit.inlet.conc_mass_comp[0, "X_P"].fix(626.0652 * units.mg / units.liter)
m.fs.unit.inlet.conc_mass_comp[0, "S_O"].fix(1e-6 * units.mg / units.liter)
m.fs.unit.inlet.conc_mass_comp[0, "S_NO"].fix(1e-6 * units.mg / units.liter)
m.fs.unit.inlet.conc_mass_comp[0, "S_NH"].fix(1442.7882 * units.mg / units.liter)
m.fs.unit.inlet.conc_mass_comp[0, "S_ND"].fix(0.54323 * units.mg / units.liter)
m.fs.unit.inlet.conc_mass_comp[0, "X_ND"].fix(100.8668 * units.mg / units.liter)
m.fs.unit.inlet.alkalinity.fix(97.8459 * units.mol / units.m**3)

m.fs.unit.hydraulic_retention_time.fix()

solver = get_solver()
solver.solve(m)

return m


def scale_vars_with_scalers(m):
scaler = DewatererScaler()
scaler.scale_model(
m.fs.unit,
submodel_scalers={
m.fs.unit.mixed_state: ASM1PropertiesScaler,
m.fs.unit.underflow_state: ASM1PropertiesScaler,
m.fs.unit.overflow_state: ASM1PropertiesScaler,
},
)


def scale_vars_with_iscale(m):
# Set scaling factors for badly scaled variables
iscale.calculate_scaling_factors(m.fs.unit)


def perturb_solution(m):
m.fs.unit.inlet.flow_vol.fix(178.4674 * 0.8 * units.m**3 / units.day)
m.fs.unit.inlet.conc_mass_comp[0, "S_I"].fix(
130.867 * 0.55 * units.mg / units.liter
)


@pytest.mark.requires_idaes_solver
@pytest.mark.unit
def test_scaling_profiler_with_scalers():
sp = ScalingProfiler(
build_model=build_model,
user_scaling=scale_vars_with_scalers,
perturb_state=perturb_solution,
)

stream = StringIO()

sp.report_scaling_profiles(stream=stream)

expected = """
============================================================================
Scaling Profile Report
----------------------------------------------------------------------------
Scaling Method || User Scaling || Perfect Scaling
Unscaled || 4.958E+07 | Solved 1 ||
Vars Only || 1.379E+13 | Solved 3 || 1.270E+18 | Solved 5
Harmonic || 1.379E+13 | Solved 3 || 1.314E+05 | Solved 1
Inverse Sum || 1.379E+13 | Solved 3 || 4.501E+03 | Solved 1
Inverse Root Sum Squares || 1.379E+13 | Solved 3 || 6.085E+03 | Solved 1
Inverse Maximum || 1.379E+13 | Solved 3 || 8.354E+03 | Solved 1
Inverse Minimum || 1.379E+13 | Solved 3 || 1.236E+05 | Solved 1
Nominal L1 Norm || 1.379E+13 | Solved 3 || 4.933E+03 | Solved 1
Nominal L2 Norm || 1.379E+13 | Solved 3 || 5.883E+03 | Solved 1
Actual L1 Norm || 1.379E+13 | Solved 3 || 5.468E+13 | Solved 1
Actual L2 Norm || 1.379E+13 | Solved 3 || 6.356E+13 | Solved 1
============================================================================
"""

assert stream.getvalue() == expected


@pytest.mark.requires_idaes_solver
@pytest.mark.unit
def test_scaling_profiler_with_iscale():
sp = ScalingProfiler(
build_model=build_model,
user_scaling=scale_vars_with_iscale,
perturb_state=perturb_solution,
)

stream = StringIO()

sp.report_scaling_profiles(stream=stream)

expected = """
============================================================================
Scaling Profile Report
----------------------------------------------------------------------------
Scaling Method || User Scaling || Perfect Scaling
Unscaled || 4.958E+07 | Solved 1 ||
Vars Only || 9.503E+10 | Solved 3 || 1.270E+18 | Solved 5
Harmonic || 5.041E+15 | Solved 3 || 1.314E+05 | Solved 1
Inverse Sum || 9.487E+14 | Solved 3 || 4.501E+03 | Solved 1
Inverse Root Sum Squares || 7.199E+14 | Solved 3 || 6.085E+03 | Solved 1
Inverse Maximum || 5.224E+14 | Solved 3 || 8.354E+03 | Solved 1
Inverse Minimum || 9.593E+15 | Solved 3 || 1.236E+05 | Solved 1
Nominal L1 Norm || 1.493E+09 | Solved 1 || 4.933E+03 | Solved 1
Nominal L2 Norm || 1.558E+09 | Solved 1 || 5.883E+03 | Solved 1
Actual L1 Norm || 2.955E+07 | Solved 2 || 5.468E+13 | Solved 1
Actual L2 Norm || 3.193E+07 | Solved 2 || 6.356E+13 | Solved 1
============================================================================
"""

assert stream.getvalue() == expected

0 comments on commit 7ddf784

Please sign in to comment.