Exemple #1
0
def calculate_operating_pressure(
    feed_state_block=None,
    over_pressure=0.15,
    water_recovery=0.5,
    NaCl_passage=0.01,
    solver=None,
):
    """
    estimate operating pressure for RO unit model given the following arguments:

    Arguments:
        feed_state_block:   the state block of the RO feed that has the non-pressure state
                            variables initialized to their values (default=None)
        over_pressure:  the amount of operating pressure above the brine osmotic pressure
                        represented as a fraction (default=0.15)
        water_recovery: the mass-based fraction of inlet H2O that becomes permeate
                        (default=0.5)
        NaCl_passage:   the mass-based fraction of inlet NaCl that becomes permeate
                        (default=0.01)
        solver:     solver object to be used (default=None)
    """
    t = ConcreteModel()  # create temporary model
    prop = feed_state_block.config.parameters
    t.brine = prop.build_state_block([0], default={})

    # specify state block
    t.brine[0].flow_mass_phase_comp["Liq", "H2O"].fix(
        value(feed_state_block.flow_mass_phase_comp["Liq", "H2O"])
        * (1 - water_recovery)
    )
    t.brine[0].flow_mass_phase_comp["Liq", "NaCl"].fix(
        value(feed_state_block.flow_mass_phase_comp["Liq", "NaCl"]) * (1 - NaCl_passage)
    )
    t.brine[0].pressure.fix(
        101325
    )  # valid when osmotic pressure is independent of hydraulic pressure
    t.brine[0].temperature.fix(value(feed_state_block.temperature))

    # calculate osmotic pressure
    # since properties are created on demand, we must touch the property to create it
    t.brine[0].pressure_osm
    # solve state block
    results = solve_indexed_blocks(solver, [t.brine])
    assert_optimal_termination(results)

    return value(t.brine[0].pressure_osm) * (1 + over_pressure)
Exemple #2
0
    def test_external_function(self):
        DLL = find_GSL()
        if not DLL:
            self.skipTest('Could not find the amplgls.dll library')

        opt = pe.SolverFactory('appsi_ipopt')
        if not opt.available(exception_flag=False):
            raise unittest.SkipTest

        m = pe.ConcreteModel()
        m.hypot = pe.ExternalFunction(library=DLL, function='gsl_hypot')
        m.x = pe.Var(bounds=(-10, 10), initialize=2)
        m.y = pe.Var(initialize=2)
        e = 2 * m.hypot(m.x, m.x * m.y)
        m.c = pe.Constraint(expr=e == 2.82843)
        m.obj = pe.Objective(expr=m.x)
        res = opt.solve(m)
        pe.assert_optimal_termination(res)
        self.assertAlmostEqual(pe.value(m.c.body) - pe.value(m.c.lower), 0)
def test_municipal_treatment():
    m, results = main()

    assert_optimal_termination(results)

    assert value(
        m.fs.feed.properties[0].flow_mass_comp["H2O"]) == pytest.approx(
            921.8, rel=1e-3)
    assert value(
        m.fs.feed.properties[0].flow_mass_comp["tds"]) == pytest.approx(
            0.5811, rel=1e-3)
    assert value(
        m.fs.feed.properties[0].flow_mass_comp["toc"]) == pytest.approx(
            3.690e-3, rel=1e-3)
    assert value(
        m.fs.feed.properties[0].flow_mass_comp["tss"]) == pytest.approx(
            6.019e-3, rel=1e-3)

    assert value(m.fs.backwash_pump.properties[0].flow_mass_comp["H2O"]
                 ) == pytest.approx(36.87, rel=1e-3)
    assert value(m.fs.backwash_pump.properties[0].flow_mass_comp["tds"]
                 ) == pytest.approx(0, abs=1e-6)
    assert value(m.fs.backwash_pump.properties[0].flow_mass_comp["toc"]
                 ) == pytest.approx(0, abs=1e-6)
    assert value(m.fs.backwash_pump.properties[0].flow_mass_comp["tss"]
                 ) == pytest.approx(5.356e-5, rel=1e-3)

    assert value(m.fs.recharge_pump.properties[0].flow_mass_comp["H2O"]
                 ) == pytest.approx(884.8, rel=1e-3)
    assert value(m.fs.recharge_pump.properties[0].flow_mass_comp["tds"]
                 ) == pytest.approx(5.811e-2, rel=1e-3)
    assert value(m.fs.recharge_pump.properties[0].flow_mass_comp["toc"]
                 ) == pytest.approx(9.477e-4, rel=1e-3)
    assert value(m.fs.recharge_pump.properties[0].flow_mass_comp["tss"]
                 ) == pytest.approx(1.656e-6, rel=1e-3)

    assert value(m.fs.costing.LCOW) == pytest.approx(5.1533e-7,
                                                     rel=1e-3)  # in M$/m**3
    assert value(m.fs.costing.electricity_intensity) == pytest.approx(
        4.4812e-1, rel=1e-3)
def test_municipal_treatment():
    m, results = main()

    assert_optimal_termination(results)

    assert value(m.fs.feed.properties[0].flow_mass_comp["H2O"]) == pytest.approx(
        115.807, rel=1e-3
    )
    assert value(m.fs.feed.properties[0].flow_mass_comp["bod"]) == pytest.approx(
        0.01193, rel=1e-3
    )
    assert value(
        m.fs.feed.properties[0].flow_mass_comp["ammonium_as_nitrogen"]
    ) == pytest.approx(3.01167e-3, rel=1e-3)
    assert value(m.fs.feed.properties[0].flow_mass_comp["nitrate"]) == pytest.approx(
        1.50583e-4, rel=1e-3
    )
    assert value(m.fs.feed.properties[0].flow_mass_comp["tss"]) == pytest.approx(
        0.011583, rel=1e-3
    )

    assert value(
        m.fs.dmbr.properties_treated[0].flow_mass_comp["H2O"]
    ) == pytest.approx(104.226, rel=1e-3)
    assert value(
        m.fs.dmbr.properties_treated[0].flow_mass_comp["bod"]
    ) == pytest.approx(6.562e-3, rel=1e-3)
    assert value(
        m.fs.dmbr.properties_treated[0].flow_mass_comp["ammonium_as_nitrogen"]
    ) == pytest.approx(9.035e-4, rel=1e-3)
    assert value(
        m.fs.dmbr.properties_treated[0].flow_mass_comp["nitrate"]
    ) == pytest.approx(3.953e-4, rel=1e-3)
    assert value(
        m.fs.dmbr.properties_treated[0].flow_mass_comp["tss"]
    ) == pytest.approx(2.317e-3, rel=1e-3)

    assert value(m.fs.costing.LCOW) == pytest.approx(0.1322, rel=1e-3)  # in M$/m**3
    assert value(m.fs.costing.electricity_intensity) == pytest.approx(0.1183, rel=1e-3)
Exemple #5
0
def main():
    m = build()

    set_operating_conditions(m)
    assert_degrees_of_freedom(m, 0)
    assert_units_consistent(m)

    initialize_system(m)

    results = solve(m)
    assert_optimal_termination(results)
    display_results(m)

    add_costing(m)
    initialize_costing(m)
    assert_degrees_of_freedom(m, 0)
    assert_units_consistent(m)

    results = solve(m)
    display_costing(m)

    return m, results
def run_ideal_naocl_chlorination_example():
    model = ConcreteModel()
    model.fs = FlowsheetBlock(default={"dynamic": False})

    # add properties to model
    build_ideal_naocl_prop(model)

    # add equilibrium unit
    build_ideal_naocl_chlorination_unit(model)

    # Set some inlet values
    set_ideal_naocl_chlorination_inlets(model)

    # fix the inlets
    fix_ideal_naocl_chlorination_inlets(model)

    check_dof(model)

    # scale the chlorination unit
    state_args = scale_ideal_naocl_chlorination(
        model.fs.ideal_naocl_chlorination_unit,
        model.fs.ideal_naocl_rxn_params,
        model.fs.ideal_naocl_thermo_params,
        ideal_naocl_reaction_config,
    )

    # initialize the unit
    initialize_ideal_naocl_chlorination(model.fs.ideal_naocl_chlorination_unit,
                                        state_args,
                                        debug_out=False)

    results = solver.solve(model, tee=True)
    assert_optimal_termination(results)

    display_results_of_chlorination_unit(
        model.fs.ideal_naocl_chlorination_unit)

    return model
Exemple #7
0
def test_mvc():
    m = ConcreteModel()
    m.fs = FlowsheetBlock(default={"dynamic": False})

    build(m)
    assert_units_consistent(m)
    scale(m)
    specify(m)
    assert degrees_of_freedom(m) == 0

    initialize(m)

    solver = get_solver()
    results = solver.solve(m, tee=False)
    assert_optimal_termination(results)

    m.fs.compressor.report()
    m.fs.evaporator.condenser.report()
    m.fs.evaporator.display()
    brine_blk = m.fs.evaporator.feed_side.properties_brine[0]
    # evaporator values
    assert brine_blk.pressure.value == pytest.approx(2.2738e4, rel=1e-3)
    assert m.fs.evaporator.lmtd.value == pytest.approx(12.30, rel=1e-3)
    assert m.fs.evaporator.feed_side.heat_transfer.value == pytest.approx(
        1.231e6, rel=1e-3)

    # compressor values
    compressed_blk = m.fs.compressor.control_volume.properties_out[0]
    assert m.fs.compressor.control_volume.work[0].value == pytest.approx(
        5.843e4, rel=1e-3)
    assert compressed_blk.pressure.value == pytest.approx(4.548e4, rel=1e-3)
    assert compressed_blk.temperature.value == pytest.approx(412.98, rel=1e-3)

    # condenser values
    condensed_blk = m.fs.evaporator.condenser.control_volume.properties_out[0]
    assert m.fs.evaporator.condenser.control_volume.heat[
        0].value == pytest.approx(-1.231e6, rel=1e-3)
    assert condensed_blk.temperature.value == pytest.approx(337.95, rel=1e-3)
Exemple #8
0
def test_noscalers():
    keras_folder_name = os.path.join(this_file_dir(), 'data', 'keras_models')
    keras_model = load_keras_json_hd5(keras_folder_name,
                                      'PT_data_2_10_10_2_sigmoid')

    input_labels = ['Temperature_K', 'Pressure_Pa']
    output_labels = ['EnthMol', 'VapFrac']
    input_bounds = {'Temperature_K': (-3.0, 3.0), 'Pressure_Pa': (-3.0, 3.0)}

    keras_surrogate = KerasSurrogate(keras_model=keras_model,
                                     input_labels=input_labels,
                                     output_labels=output_labels,
                                     input_bounds=input_bounds)
    # check solve with pyomo
    x_test = pd.DataFrame({'Temperature_K': [0.5], 'Pressure_Pa': [0.5]})
    y_test = keras_surrogate.evaluate_surrogate(x_test)

    m = ConcreteModel()
    m.obj = Objective(expr=1)
    m.surrogate = SurrogateBlock()
    m.surrogate.build_model(surrogate_object=keras_surrogate,
                            formulation=KerasSurrogate.Formulation.FULL_SPACE)
    m.surrogate.inputs['Temperature_K'].fix(0.5)
    m.surrogate.inputs['Pressure_Pa'].fix(0.5)
    solver = SolverFactory('ipopt')
    status = solver.solve(m, tee=True)
    assert_optimal_termination(status)

    y_test_pyomo = pd.DataFrame({
        'EnthMol': [value(m.surrogate.outputs['EnthMol'])],
        'VapFrac': [value(m.surrogate.outputs['VapFrac'])]
    })
    pd.testing.assert_frame_equal(y_test,
                                  y_test_pyomo,
                                  check_dtype=False,
                                  rtol=rtol,
                                  atol=atol)
Exemple #9
0
    def test_solve(self, NF_frame):
        m = NF_frame
        results = solver.solve(m)

        # Check for optimal solution
        assert_optimal_termination(results)
    def test_NF_with_generic_property_model(self):
        m = ConcreteModel()
        m.fs = FlowsheetBlock(default={"dynamic": False})
        m.fs.properties = GenericParameterBlock(default=configuration)
        m.fs.unit = NanofiltrationZO(default={
            "property_package": m.fs.properties,
            "has_pressure_change": False
        })

        # fully specify system
        m.fs.unit.inlet.flow_mol_phase_comp[0, "Liq", "Na_+"].fix(0.008845)
        m.fs.unit.inlet.flow_mol_phase_comp[0, "Liq", "Ca_2+"].fix(0.000174)
        m.fs.unit.inlet.flow_mol_phase_comp[0, "Liq", "Mg_2+"].fix(0.001049)
        m.fs.unit.inlet.flow_mol_phase_comp[0, "Liq", "SO4_2-"].fix(0.000407)
        m.fs.unit.inlet.flow_mol_phase_comp[0, "Liq", "Cl_-"].fix(0.010479)
        m.fs.unit.inlet.flow_mol_phase_comp[0, "Liq", "H2O"].fix(0.979046)
        m.fs.unit.feed_side.properties_in[0].pressure.fix(4e5)
        m.fs.unit.feed_side.properties_in[0].temperature.fix(298.15)

        m.fs.unit.flux_vol_solvent.fix(1.67e-6)
        m.fs.unit.recovery_vol_phase.fix(0.86)
        m.fs.unit.properties_permeate[0].pressure.fix(101325)

        m.fs.unit.rejection_phase_comp[0, "Liq", "Na_+"].fix(0.01)
        m.fs.unit.rejection_phase_comp[0, "Liq", "Ca_2+"].fix(0.79)
        m.fs.unit.rejection_phase_comp[0, "Liq", "Mg_2+"].fix(0.94)
        m.fs.unit.rejection_phase_comp[0, "Liq", "SO4_2-"].fix(0.87)
        m.fs.unit.rejection_phase_comp[
            0, "Liq",
            "Cl_-"] = 0.15  # guess, but electroneutrality enforced below
        charge_comp = {
            "Na_+": 1,
            "Ca_2+": 2,
            "Mg_2+": 2,
            "SO4_2-": -2,
            "Cl_-": -1
        }
        m.fs.unit.eq_electroneutrality = Constraint(expr=0 == sum(
            charge_comp[j] *
            m.fs.unit.feed_side.properties_out[0].conc_mol_phase_comp["Liq", j]
            for j in charge_comp))
        constraint_scaling_transform(m.fs.unit.eq_electroneutrality, 1)

        assert_units_consistent(m)

        assert_no_degrees_of_freedom(m)

        calculate_scaling_factors(m)

        initialization_tester(m)

        results = solver.solve(m)

        # Check for optimal solution
        assert_optimal_termination(results)

        assert pytest.approx(0.868, rel=1e-3) == value(
            m.fs.unit.properties_permeate[0].flow_mass_phase_comp["Liq", "H2O"]
            / m.fs.unit.feed_side.properties_in[0].flow_mass_phase_comp["Liq",
                                                                        "H2O"])
        assert pytest.approx(1.978, rel=1e-3) == value(
            m.fs.unit.properties_permeate[0].conc_mol_phase_comp["Liq",
                                                                 "Ca_2+"])
        assert pytest.approx(479.1, rel=1e-3) == value(
            m.fs.unit.properties_permeate[0].conc_mol_phase_comp["Liq",
                                                                 "Cl_-"])
        assert pytest.approx(3.407, rel=1e-3) == value(
            m.fs.unit.properties_permeate[0].conc_mol_phase_comp["Liq",
                                                                 "Mg_2+"])
        assert pytest.approx(473.9, rel=1e-3) == value(
            m.fs.unit.properties_permeate[0].conc_mol_phase_comp["Liq",
                                                                 "Na_+"])
        assert pytest.approx(2.864, rel=1e-3) == value(
            m.fs.unit.properties_permeate[0].conc_mol_phase_comp["Liq",
                                                                 "SO4_2-"])
    return pyo.Constraint.Skip


model.InfDynamics = pyo.Constraint(model.S_SI, rule=_InfDynamics)


def _SusDynamics(model, i):
    if i != 1:
        return model.S[i] == model.S[i - 1] - model.I[i]
    return pyo.Constraint.Skip


model.SusDynamics = pyo.Constraint(model.S_SI, rule=_SusDynamics)


def _Data(model, i):
    return model.P_REP_CASES[i] == model.I[i] + model.eps_I[i]


model.Data = pyo.Constraint(model.S_SI, rule=_Data)

# create the ConcreteModel
instance = model.create_instance('disease_estimation.dat')
status = pyo.SolverFactory('ipopt').solve(instance)
pyo.assert_optimal_termination(status)

print(' ***')
print(' *** Optimal beta Value: %.2f' % pyo.value(instance.beta))
print(' *** Optimal alpha Value: %.2f' % pyo.value(instance.alpha))
print(' ***')
    def test_solve(self, model):
        results = solver.solve(model)

        assert_optimal_termination(results)
Exemple #13
0
    def test_CP_calculation_with_kf_fixed(self):
        """ Testing 0D-RO with ConcentrationPolarizationType.calculated option enabled.
        This option makes use of an alternative constraint for the feed-side, membrane-interface concentration.
        Additionally, two more variables are created when this option is enabled: Kf - feed-channel
        mass transfer coefficients at the channel inlet and outlet.
        """
        m = ConcreteModel()
        m.fs = FlowsheetBlock(default={"dynamic": False})

        m.fs.properties = props.NaClParameterBlock()

        m.fs.unit = ReverseOsmosis0D(default={
            "property_package": m.fs.properties,
            "has_pressure_change": True,
            "concentration_polarization_type": ConcentrationPolarizationType.calculated,
            "mass_transfer_coefficient": MassTransferCoefficient.fixed})

        # fully specify system
        feed_flow_mass = 1
        feed_mass_frac_NaCl = 0.035
        feed_pressure = 50e5
        feed_temperature = 273.15 + 25
        membrane_pressure_drop = 3e5
        membrane_area = 50
        A = 4.2e-12
        B = 3.5e-8
        pressure_atmospheric = 101325
        kf = 2e-5

        feed_mass_frac_H2O = 1 - feed_mass_frac_NaCl
        m.fs.unit.inlet.flow_mass_phase_comp[0, 'Liq', 'NaCl'].fix(
            feed_flow_mass * feed_mass_frac_NaCl)
        m.fs.unit.inlet.flow_mass_phase_comp[0, 'Liq', 'H2O'].fix(
            feed_flow_mass * feed_mass_frac_H2O)
        m.fs.unit.inlet.pressure[0].fix(feed_pressure)
        m.fs.unit.inlet.temperature[0].fix(feed_temperature)
        m.fs.unit.deltaP.fix(-membrane_pressure_drop)
        m.fs.unit.area.fix(membrane_area)
        m.fs.unit.A_comp.fix(A)
        m.fs.unit.B_comp.fix(B)
        m.fs.unit.permeate.pressure[0].fix(pressure_atmospheric)
        m.fs.unit.Kf[0, 0., 'NaCl'].fix(kf)
        m.fs.unit.Kf[0, 1., 'NaCl'].fix(kf)

        # test statistics
        assert number_variables(m) == 125
        assert number_total_constraints(m) == 96
        assert number_unused_variables(m) == 7  # vars from property package parameters

        # test degrees of freedom
        assert degrees_of_freedom(m) == 0

        # test scaling
        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'))
        calculate_scaling_factors(m)

        # check that all variables have scaling factors.
        # TODO: Setting the "include_fixed" arg as True reveals
        #  unscaled vars that weren't being accounted for previously. However, calling the whole block (i.e.,
        #  m) shows that several NaCl property parameters are unscaled. For now, we are just interested in ensuring
        #  unit variables are scaled (hence, calling m.fs.unit) but might need to revisit scaling and associated
        #  testing for property models.

        unscaled_var_list = list(unscaled_variables_generator(m.fs.unit, include_fixed=True))
        assert len(unscaled_var_list) == 0

        # # test initialization
        initialization_tester(m, fail_on_warning=True)

        # test variable scaling
        badly_scaled_var_lst = list(badly_scaled_var_generator(m))
        assert badly_scaled_var_lst == []

        # test solve
        results = solver.solve(m)

        # Check for optimal solution
        assert_optimal_termination(results)

        # test solution
        assert (pytest.approx(3.815e-3, rel=1e-3) ==
                value(m.fs.unit.flux_mass_phase_comp_avg[0, 'Liq', 'H2O']))
        assert (pytest.approx(1.668e-6, rel=1e-3) ==
                value(m.fs.unit.flux_mass_phase_comp_avg[0, 'Liq', 'NaCl']))
        assert (pytest.approx(0.1908, rel=1e-3) ==
                value(m.fs.unit.mixed_permeate[0].flow_mass_phase_comp['Liq', 'H2O']))
        assert (pytest.approx(8.337e-5, rel=1e-3) ==
                value(m.fs.unit.mixed_permeate[0].flow_mass_phase_comp['Liq', 'NaCl']))
        assert (pytest.approx(46.07, rel=1e-3) ==
                value(m.fs.unit.feed_side.properties_interface[0, 0.].conc_mass_phase_comp['Liq', 'NaCl']))
        assert (pytest.approx(44.34, rel=1e-3) ==
                value(m.fs.unit.feed_side.properties_out[0].conc_mass_phase_comp['Liq', 'NaCl']))
        assert (pytest.approx(50.20, rel=1e-3) ==
                value(m.fs.unit.feed_side.properties_interface[0, 1.].conc_mass_phase_comp['Liq', 'NaCl']))
def test_evaporator():
    m = ConcreteModel()
    m.fs = FlowsheetBlock(default={"dynamic": False})
    m.fs.properties_feed = props_sw.SeawaterParameterBlock()
    m.fs.properties_vapor = props_w.WaterParameterBlock()
    m.fs.evaporator = Evaporator(
        default={
            "property_package_feed": m.fs.properties_feed,
            "property_package_vapor": m.fs.properties_vapor,
        })

    # scaling
    m.fs.properties_feed.set_default_scaling("flow_mass_phase_comp",
                                             1,
                                             index=("Liq", "H2O"))
    m.fs.properties_feed.set_default_scaling("flow_mass_phase_comp",
                                             1e2,
                                             index=("Liq", "TDS"))
    m.fs.properties_vapor.set_default_scaling("flow_mass_phase_comp",
                                              1,
                                              index=("Vap", "H2O"))
    m.fs.properties_vapor.set_default_scaling("flow_mass_phase_comp",
                                              1,
                                              index=("Liq", "H2O"))
    iscale.set_scaling_factor(m.fs.evaporator.area, 1e-3)
    iscale.set_scaling_factor(m.fs.evaporator.U, 1e-3)
    iscale.set_scaling_factor(m.fs.evaporator.delta_temperature_in, 1e-1)
    iscale.set_scaling_factor(m.fs.evaporator.delta_temperature_out, 1e-1)
    iscale.set_scaling_factor(m.fs.evaporator.lmtd, 1e-1)
    # iscale.set_scaling_factor(m.fs.evaporator.heat_transfer, 1e-6)
    iscale.calculate_scaling_factors(m)

    # assert False

    # state variables
    # Feed inlet
    m.fs.evaporator.inlet_feed.flow_mass_phase_comp[0, "Liq", "H2O"].fix(10)
    m.fs.evaporator.inlet_feed.flow_mass_phase_comp[0, "Liq", "TDS"].fix(0.05)
    m.fs.evaporator.inlet_feed.temperature[0].fix(273.15 + 50.52)  # K
    m.fs.evaporator.inlet_feed.pressure[0].fix(1e5)  # Pa

    # Condenser inlet
    m.fs.evaporator.inlet_condenser.flow_mass_phase_comp[0, "Vap",
                                                         "H2O"].fix(0.5)
    m.fs.evaporator.inlet_condenser.flow_mass_phase_comp[0, "Liq",
                                                         "H2O"].fix(1e-8)
    m.fs.evaporator.inlet_condenser.temperature[0].fix(400)  # K
    m.fs.evaporator.inlet_condenser.pressure[0].fix(0.5e5)  # Pa

    # Evaporator/condenser specifications
    m.fs.evaporator.outlet_brine.temperature[0].fix(273.15 + 60)
    m.fs.evaporator.U.fix(1e3)  # W/K-m^2
    m.fs.evaporator.area.fix(100)  # m^2

    # check build
    assert_units_consistent(m)
    assert degrees_of_freedom(m) == 0

    # initialize
    m.fs.evaporator.initialize()

    # solve
    solver = get_solver()
    results = solver.solve(m, tee=False)
    assert_optimal_termination(results)

    # check values, TODO: make a report for the evaporator
    # m.fs.evaporator.display()
    vapor_blk = m.fs.evaporator.feed_side.properties_vapor[0]
    assert vapor_blk.flow_mass_phase_comp["Vap", "H2O"].value == pytest.approx(
        0.3540, rel=1e-3)
    assert m.fs.evaporator.lmtd.value == pytest.approx(12.30, rel=1e-3)
    assert m.fs.evaporator.feed_side.heat_transfer.value == pytest.approx(
        1.230e6, rel=1e-3)
    def test_property_regression(self):
        self.configure_class()

        # create model
        m = ConcreteModel()
        m.fs = FlowsheetBlock(default={"dynamic": False})
        m.fs.properties = self.prop_pack()
        m.fs.stream = m.fs.properties.build_state_block(
            [0], default=self.param_args)

        # set default scaling
        for (v_str, ind), sf in self.scaling_args.items():
            m.fs.properties.set_default_scaling(v_str, sf, index=ind)

        # set state variables
        for (v_str, ind), val in self.state_args.items():
            var = getattr(m.fs.stream[0], v_str)
            var[ind].fix(val)

        # touch all properties
        metadata = m.fs.properties.get_metadata().properties
        for v_str in metadata.keys():
            getattr(m.fs.stream[0], v_str)

        # scale model
        calculate_scaling_factors(m)

        # solve model
        opt = get_solver(self.solver, self.optarg)
        results = opt.solve(m)
        assert_optimal_termination(results)

        # check results
        for (v_name, ind), val in self.regression_solution.items():
            var = getattr(m.fs.stream[0], v_name)[ind]
            # relative tolerance doesn't mean anything for 0-valued things
            if val == 0:
                if not pytest.approx(val, abs=1.0e-08) == value(var):
                    raise PropertyValueError(
                        "Variable {v_name} with index {ind} is expected to have a value of {val} +/- 1.0e-08, but it "
                        "has a value of {val_t}. \nUpdate regression_solution in the configure function "
                        "that sets up the PropertyRegressionTest".format(
                            v_name=v_name, ind=ind, val=val, val_t=value(var)))
            elif not pytest.approx(val, rel=1e-3) == value(var):
                raise PropertyValueError(
                    "Variable {v_name} with index {ind} is expected to have a value of {val} +/- 0.1%, but it "
                    "has a value of {val_t}. \nUpdate regression_solution in the configure function "
                    "that sets up the PropertyRegressionTest".format(
                        v_name=v_name, ind=ind, val=val, val_t=value(var)))

        # check if any variables are badly scaled
        lst = []
        for (var, val) in badly_scaled_var_generator(m,
                                                     large=1e2,
                                                     small=1e-2,
                                                     zero=1e-8):
            lst.append((var.name, val))
            print(var.name, var.value)
        if lst:
            raise PropertyValueError(
                "The following variable(s) are poorly scaled: {lst}".format(
                    lst=lst))
Exemple #16
0
    def test_solve(self, model):
        results = solver.solve(model)

        # Check for optimal solution
        assert_optimal_termination(results)
Exemple #17
0
def test_seawater_data():
    m = ConcreteModel()
    m.fs = FlowsheetBlock(default={"dynamic": False})
    m.fs.properties = DSPMDEParameterBlock(
        default={
            "solute_list": ["Ca_2+", "SO4_2-", "Na_+", "Cl_-", "Mg_2+"],
            "diffusivity_data": {
                ("Liq", "Ca_2+"): 0.792e-9,
                ("Liq", "SO4_2-"): 1.06e-9,
                ("Liq", "Na_+"): 1.33e-9,
                ("Liq", "Cl_-"): 2.03e-9,
                ("Liq", "Mg_2+"): 0.706e-9,
            },
            "mw_data": {
                "H2O": 18e-3,
                "Na_+": 23e-3,
                "Ca_2+": 40e-3,
                "Mg_2+": 24e-3,
                "Cl_-": 35e-3,
                "SO4_2-": 96e-3,
            },
            "electrical_mobility_data": {
                "Na_+": 5.19e-8,
                "Ca_2+": 6.17e-8,
                "Mg_2+": 5.50e-8,
                "Cl_-": 7.92e-8,
                "SO4_2-": 8.29e-8,
            },
            "stokes_radius_data": {
                "Na_+": 0.184e-9,
                "Ca_2+": 0.309e-9,
                "Mg_2+": 0.347e-9,
                "Cl_-": 0.121e-9,
                "SO4_2-": 0.230e-9,
            },
            "charge": {
                "Na_+": 1,
                "Ca_2+": 2,
                "Mg_2+": 2,
                "Cl_-": -1,
                "SO4_2-": -2
            },
            "density_calculation": DensityCalculation.seawater,
            "activity_coefficient_model": ActivityCoefficientModel.davies,
        })

    m.fs.stream = stream = m.fs.properties.build_state_block(
        [0], default={"defined_state": True})

    mass_flow_in = 1 * pyunits.kg / pyunits.s
    feed_mass_frac = {
        "Na_+": 11122e-6,
        "Ca_2+": 382e-6,
        "Mg_2+": 1394e-6,
        "SO4_2-": 2136e-6,
        "Cl_-": 20300e-6,
    }
    for ion, x in feed_mass_frac.items():
        mol_comp_flow = (x * pyunits.kg / pyunits.kg * mass_flow_in /
                         stream[0].mw_comp[ion])

        stream[0].flow_mol_phase_comp["Liq", ion].fix(mol_comp_flow)

    H2O_mass_frac = 1 - sum(x for x in feed_mass_frac.values())
    H2O_mol_comp_flow = (H2O_mass_frac * pyunits.kg / pyunits.kg *
                         mass_flow_in / stream[0].mw_comp["H2O"])

    stream[0].flow_mol_phase_comp["Liq", "H2O"].fix(H2O_mol_comp_flow)
    stream[0].temperature.fix(298.15)
    stream[0].pressure.fix(101325)

    stream[0].assert_electroneutrality(defined_state=True,
                                       tol=1e-2,
                                       adjust_by_ion="Cl_-")

    metadata = m.fs.properties.get_metadata().properties
    for v_name in metadata:
        getattr(stream[0], v_name)
    assert stream[0].is_property_constructed("conc_mol_phase_comp")

    assert_units_consistent(m)

    check_dof(m, fail_flag=True)

    m.fs.properties.set_default_scaling("flow_mol_phase_comp",
                                        1e-1,
                                        index=("Liq", "H2O"))
    m.fs.properties.set_default_scaling("flow_mol_phase_comp",
                                        1e1,
                                        index=("Liq", "Na_+"))
    m.fs.properties.set_default_scaling("flow_mol_phase_comp",
                                        1e1,
                                        index=("Liq", "Cl_-"))
    m.fs.properties.set_default_scaling("flow_mol_phase_comp",
                                        1e2,
                                        index=("Liq", "Ca_2+"))
    m.fs.properties.set_default_scaling("flow_mol_phase_comp",
                                        1e2,
                                        index=("Liq", "SO4_2-"))
    m.fs.properties.set_default_scaling("flow_mol_phase_comp",
                                        1e2,
                                        index=("Liq", "Mg_2+"))

    calculate_scaling_factors(m)

    stream.initialize()

    # check if any variables are badly scaled
    badly_scaled_var_list = list(
        badly_scaled_var_generator(m, large=100, small=0.01, zero=1e-10))
    assert len(badly_scaled_var_list) == 0

    results = solver.solve(m)
    assert_optimal_termination(results)

    assert value(stream[0].flow_vol_phase["Liq"]) == pytest.approx(9.767e-4,
                                                                   rel=1e-3)
    assert value(stream[0].flow_mol_phase_comp["Liq", "H2O"]) == pytest.approx(
        53.59256, rel=1e-3)
    assert value(stream[0].flow_mol_phase_comp["Liq",
                                               "Na_+"]) == pytest.approx(
                                                   0.4836, rel=1e-3)
    assert value(stream[0].flow_mol_phase_comp["Liq",
                                               "Ca_2+"]) == pytest.approx(
                                                   0.00955, rel=1e-3)
    assert value(stream[0].flow_mol_phase_comp["Liq",
                                               "Mg_2+"]) == pytest.approx(
                                                   0.05808, rel=1e-3)
    assert value(stream[0].flow_mol_phase_comp["Liq",
                                               "Cl_-"]) == pytest.approx(
                                                   0.57443, rel=1e-3)
    assert value(stream[0].flow_mol_phase_comp["Liq",
                                               "SO4_2-"]) == pytest.approx(
                                                   0.02225, rel=1e-3)

    assert value(stream[0].dens_mass_phase["Liq"]) == pytest.approx(1023.816,
                                                                    rel=1e-3)
    assert value(stream[0].pressure_osm_phase["Liq"]) == pytest.approx(
        29.132e5, rel=1e-3)
    assert value(
        stream[0].electrical_conductivity_phase["Liq"]) == pytest.approx(
            8.08, rel=1e-3)
    assert value(stream[0].flow_vol) == pytest.approx(9.767e-4, rel=1e-3)

    assert value(
        sum(stream[0].conc_mass_phase_comp["Liq", j]
            for j in m.fs.properties.ion_set
            | m.fs.properties.solute_set)) == pytest.approx(35.9744, rel=1e-3)
    assert value(
        sum(stream[0].mass_frac_phase_comp["Liq", j]
            for j in m.fs.properties.ion_set
            | m.fs.properties.solute_set)) == pytest.approx(0.035142, rel=1e-3)
    assert value(
        sum(stream[0].mass_frac_phase_comp["Liq", j]
            for j in m.fs.properties.component_list)) == pytest.approx(
                1, rel=1e-3)
    assert value(
        sum(stream[0].mole_frac_phase_comp["Liq", j]
            for j in m.fs.properties.component_list)) == pytest.approx(
                1, rel=1e-3)

    assert value(stream[0].conc_mol_phase_comp["Liq",
                                               "Na_+"]) == pytest.approx(
                                                   495.082, rel=1e-3)
    assert value(stream[0].conc_mol_phase_comp["Liq",
                                               "Cl_-"]) == pytest.approx(
                                                   588.0431, rel=1e-3)
    assert value(stream[0].conc_mol_phase_comp["Liq",
                                               "Ca_2+"]) == pytest.approx(
                                                   9.777, rel=1e-3)
    assert value(stream[0].conc_mol_phase_comp["Liq",
                                               "SO4_2-"]) == pytest.approx(
                                                   22.780, rel=1e-3)
    assert value(stream[0].conc_mol_phase_comp["Liq",
                                               "Mg_2+"]) == pytest.approx(
                                                   59.467, rel=1e-3)

    assert value(stream[0].conc_mass_phase_comp["Liq",
                                                "Na_+"]) == pytest.approx(
                                                    11.387, rel=1e-3)
    assert value(stream[0].conc_mass_phase_comp["Liq",
                                                "Cl_-"]) == pytest.approx(
                                                    20.5815, rel=1e-3)
    assert value(stream[0].conc_mass_phase_comp["Liq",
                                                "Ca_2+"]) == pytest.approx(
                                                    0.391, rel=1e-3)
    assert value(stream[0].conc_mass_phase_comp["Liq",
                                                "SO4_2-"]) == pytest.approx(
                                                    2.187, rel=1e-3)
    assert value(stream[0].conc_mass_phase_comp["Liq",
                                                "Mg_2+"]) == pytest.approx(
                                                    1.427, rel=1e-3)

    assert value(stream[0].mole_frac_phase_comp["Liq",
                                                "Na_+"]) == pytest.approx(
                                                    8.833e-3, rel=1e-3)
    assert value(stream[0].mole_frac_phase_comp["Liq",
                                                "Cl_-"]) == pytest.approx(
                                                    1.049e-2, rel=1e-3)
    assert value(stream[0].mole_frac_phase_comp["Liq",
                                                "Ca_2+"]) == pytest.approx(
                                                    1.744e-4, rel=1e-3)
    assert value(stream[0].mole_frac_phase_comp["Liq",
                                                "SO4_2-"]) == pytest.approx(
                                                    4.064e-4, rel=1e-3)
    assert value(stream[0].mole_frac_phase_comp["Liq",
                                                "Mg_2+"]) == pytest.approx(
                                                    1.061e-3, rel=1e-3)

    assert value(stream[0].mass_frac_phase_comp["Liq",
                                                "Na_+"]) == pytest.approx(
                                                    1.112e-2, rel=1e-3)
    assert value(stream[0].mass_frac_phase_comp["Liq",
                                                "Cl_-"]) == pytest.approx(
                                                    2.01e-2, rel=1e-3)
    assert value(stream[0].mass_frac_phase_comp["Liq",
                                                "Ca_2+"]) == pytest.approx(
                                                    3.82e-4, rel=1e-3)
    assert value(stream[0].mass_frac_phase_comp["Liq",
                                                "SO4_2-"]) == pytest.approx(
                                                    2.136e-3, rel=1e-3)
    assert value(stream[0].mass_frac_phase_comp["Liq",
                                                "Mg_2+"]) == pytest.approx(
                                                    1.394e-3, rel=1e-3)

    assert value(stream[0].debye_huckel_constant) == pytest.approx(0.01554,
                                                                   rel=1e-3)
    assert value(stream[0].ionic_strength) == pytest.approx(0.73467, rel=1e-3)
Exemple #18
0
def test_property_ions(model2):
    m = model2

    stream = m.fs.stream = m.fs.properties.build_state_block(
        [0], default={"defined_state": True})

    stream[0].flow_mol_phase_comp["Liq", "A"].fix(0.000407)
    stream[0].flow_mol_phase_comp["Liq", "B"].fix(0.010479)
    stream[0].flow_mol_phase_comp["Liq", "C"].fix(0.010479)
    stream[0].flow_mol_phase_comp["Liq", "D"].fix(0.000407)
    stream[0].flow_mol_phase_comp["Liq", "H2O"].fix(0.99046)
    stream[0].temperature.fix(298.15)
    stream[0].pressure.fix(101325)

    stream[0].diffus_phase_comp["Liq", "A"] = 1e-9
    stream[0].diffus_phase_comp["Liq", "B"] = 1e-10
    stream[0].diffus_phase_comp["Liq", "C"] = 1e-7
    stream[0].diffus_phase_comp["Liq", "D"] = 1e-11

    stream[0].mw_comp["H2O"] = 18e-3
    stream[0].mw_comp["A"] = 10e-3
    stream[0].mw_comp["B"] = 25e-3
    stream[0].mw_comp["C"] = 100e-3
    stream[0].mw_comp["D"] = 25e-3

    stream[0].radius_stokes_comp["A"] = 1e-9
    stream[0].radius_stokes_comp["B"] = 1e-9
    stream[0].radius_stokes_comp["C"] = 1e-9
    stream[0].radius_stokes_comp["D"] = 1e-10

    stream[0].charge_comp["A"] = 1
    stream[0].charge_comp["B"] = -2
    stream[0].charge_comp["C"] = 2
    stream[0].charge_comp["D"] = -1

    stream[0].electrical_mobility_comp["A"] = 5.19e-8
    stream[0].electrical_mobility_comp["B"] = 8.29e-8
    stream[0].electrical_mobility_comp["C"] = 6.17e-8
    stream[0].electrical_mobility_comp["D"] = 7.92e-8

    stream[0].assert_electroneutrality(defined_state=True, tol=1e-8)

    stream[0].mole_frac_phase_comp

    stream[0].flow_mass_phase_comp

    stream[0].molality_comp
    stream[0].electrical_conductivity_phase
    stream[0].pressure_osm_phase
    stream[0].dens_mass_phase
    stream[0].conc_mol_phase_comp
    stream[0].flow_vol
    calculate_scaling_factors(m.fs)

    assert_units_consistent(m)

    check_dof(m, fail_flag=True)

    stream.initialize()

    results = solver.solve(m)
    assert_optimal_termination(results)
    assert value(stream[0].flow_vol_phase["Liq"]) == pytest.approx(1.91524e-5,
                                                                   rel=1e-3)
def test_heat_exchanger():
    m = ConcreteModel()
    m.fs = FlowsheetBlock(default={"dynamic": False})
    m.fs.properties = props.SeawaterParameterBlock()
    m.fs.unit = HeatExchanger(
        default={
            "hot_side_name": "hot",
            "cold_side_name": "cold",
            "hot": {
                "property_package": m.fs.properties
            },
            "cold": {
                "property_package": m.fs.properties
            },
            "delta_temperature_callback": delta_temperature_chen_callback,
            "flow_pattern": HeatExchangerFlowPattern.countercurrent,
        })

    # scaling
    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", "TDS"))
    iscale.set_scaling_factor(m.fs.unit.hot.heat, 1e-3)
    iscale.set_scaling_factor(m.fs.unit.cold.heat, 1e-3)
    iscale.set_scaling_factor(m.fs.unit.overall_heat_transfer_coefficient,
                              1e-3)
    iscale.set_scaling_factor(m.fs.unit.area, 1)
    iscale.calculate_scaling_factors(m)

    # ---specifications---
    # state variables
    m.fs.unit.hot_inlet.flow_mass_phase_comp[0, "Liq", "H2O"].fix(1)
    m.fs.unit.hot_inlet.flow_mass_phase_comp[0, "Liq", "TDS"].fix(0.01)
    m.fs.unit.hot_inlet.temperature[0].fix(350)
    m.fs.unit.hot_inlet.pressure[0].fix(2e5)

    m.fs.unit.cold_inlet.flow_mass_phase_comp[0, "Liq", "H2O"].fix(0.5)
    m.fs.unit.cold_inlet.flow_mass_phase_comp[0, "Liq", "TDS"].fix(0.01)
    m.fs.unit.cold_inlet.temperature[0].fix(298)
    m.fs.unit.cold_inlet.pressure[0].fix(2e5)

    m.fs.unit.area.fix(5)
    m.fs.unit.overall_heat_transfer_coefficient.fix(1000)

    # solving
    assert_units_consistent(m)
    degrees_of_freedom(m)

    m.fs.unit.initialize()

    solver = get_solver()
    results = solver.solve(m, tee=False)
    assert_optimal_termination(results)

    report_io = StringIO()
    m.fs.unit.report(ostream=report_io)
    output = """
====================================================================================
Unit : fs.unit                                                             Time: 0.0
------------------------------------------------------------------------------------
    Unit Performance

    Variables: 

    Key            : Value  : Fixed : Bounds
           HX Area : 5.0000 :  True : (0, None)
    HX Coefficient : 1000.0 :  True : (0, None)
         Heat Duty : 89050. : False : (None, None)

    Expressions: 

    Key             : Value
    Delta T Driving : 17.810
         Delta T In : 9.2239
        Delta T Out : 30.689

------------------------------------------------------------------------------------
    Stream Table
                                         Hot Inlet  Hot Outlet  Cold Inlet  Cold Outlet
    flow_mass_phase_comp ('Liq', 'H2O')     1.0000      1.0000     0.50000     0.50000 
    flow_mass_phase_comp ('Liq', 'TDS')   0.010000    0.010000    0.010000    0.010000 
    temperature                             350.00      328.69      298.00      340.78 
    pressure                            2.0000e+05  2.0000e+05  2.0000e+05  2.0000e+05 
====================================================================================
"""
    assert output == report_io.getvalue()
Exemple #20
0
def test_compressor():
    m = ConcreteModel()
    m.fs = FlowsheetBlock(default={"dynamic": False})
    m.fs.properties = props.WaterParameterBlock()
    m.fs.compressor = Compressor(default={"property_package": m.fs.properties})
    # m.fs.compressor.control_volume.display()

    # scaling
    m.fs.properties.set_default_scaling("flow_mass_phase_comp",
                                        1,
                                        index=("Vap", "H2O"))
    m.fs.properties.set_default_scaling("flow_mass_phase_comp",
                                        1,
                                        index=("Liq", "H2O"))
    iscale.set_scaling_factor(m.fs.compressor.control_volume.work, 1e-6)
    iscale.calculate_scaling_factors(m)

    # state variables
    m.fs.compressor.inlet.flow_mass_phase_comp[0, "Vap", "H2O"].fix(1)
    m.fs.compressor.inlet.flow_mass_phase_comp[0, "Liq", "H2O"].fix(1e-8)
    m.fs.compressor.inlet.temperature[0].fix(350)  # K
    m.fs.compressor.inlet.pressure[0].fix(0.5e5)  # Pa

    # specifications
    m.fs.compressor.pressure_ratio.fix(2)
    m.fs.compressor.efficiency.fix(0.8)

    # check build
    assert_units_consistent(m)
    assert degrees_of_freedom(m) == 0

    # initialize
    m.fs.compressor.initialize()

    # solve
    solver = get_solver()
    results = solver.solve(m, tee=False)
    assert_optimal_termination(results)

    report_io = StringIO()
    m.fs.compressor.report(ostream=report_io)
    output = """
====================================================================================
Unit : fs.compressor                                                       Time: 0.0
------------------------------------------------------------------------------------
    Unit Performance

    Variables: 

    Key            : Value      : Fixed : Bounds
        Efficiency :    0.80000 :  True : (1e-08, 1)
    Pressure ratio :     2.0000 :  True : (1, 10)
              Work : 1.1534e+05 : False : (None, None)

------------------------------------------------------------------------------------
    Stream Table
                                           Inlet     Outlet  
    flow_mass_phase_comp ('Liq', 'H2O') 1.0000e-08 1.0000e-08
    flow_mass_phase_comp ('Vap', 'H2O')     1.0000     1.0000
    temperature                             350.00     429.57
    pressure                                50000. 1.0000e+05
====================================================================================
"""
    assert output == report_io.getvalue()
    def test_Pdrop_calculation(self):
        """Testing 0D-RO with PressureChangeType.calculated option."""
        m = ConcreteModel()
        m.fs = FlowsheetBlock(default={"dynamic": False})

        m.fs.properties = props.NaClParameterBlock()

        m.fs.unit = ReverseOsmosis0D(
            default={
                "property_package": m.fs.properties,
                "has_pressure_change": True,
                "concentration_polarization_type":
                ConcentrationPolarizationType.calculated,
                "mass_transfer_coefficient":
                MassTransferCoefficient.calculated,
                "pressure_change_type": PressureChangeType.calculated,
            })

        # fully specify system
        feed_flow_mass = 1 / 3.6
        feed_mass_frac_NaCl = 0.035
        feed_mass_frac_H2O = 1 - feed_mass_frac_NaCl
        feed_pressure = 70e5
        feed_temperature = 273.15 + 25
        membrane_area = 19
        A = 4.2e-12
        B = 3.5e-8
        pressure_atmospheric = 101325

        m.fs.unit.inlet.flow_mass_phase_comp[0, "Liq", "NaCl"].fix(
            feed_flow_mass * feed_mass_frac_NaCl)
        m.fs.unit.inlet.flow_mass_phase_comp[0, "Liq", "H2O"].fix(
            feed_flow_mass * feed_mass_frac_H2O)
        m.fs.unit.inlet.pressure[0].fix(feed_pressure)
        m.fs.unit.inlet.temperature[0].fix(feed_temperature)
        m.fs.unit.area.fix(membrane_area)
        m.fs.unit.A_comp.fix(A)
        m.fs.unit.B_comp.fix(B)
        m.fs.unit.permeate.pressure[0].fix(pressure_atmospheric)
        m.fs.unit.channel_height.fix(0.001)
        m.fs.unit.spacer_porosity.fix(0.97)
        m.fs.unit.length.fix(16)

        # test statistics
        assert number_variables(m) == 147
        assert number_total_constraints(m) == 118
        assert number_unused_variables(
            m) == 0  # vars from property package parameters

        # test degrees of freedom
        assert degrees_of_freedom(m) == 0

        # test scaling
        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"))

        calculate_scaling_factors(m)

        # check that all variables have scaling factors.
        # TODO: see aforementioned TODO on revisiting scaling and associated testing for property models.
        unscaled_var_list = list(
            unscaled_variables_generator(m.fs.unit, include_fixed=True))
        assert len(unscaled_var_list) == 0

        # test initialization
        initialization_tester(m, fail_on_warning=True)

        # test variable scaling
        badly_scaled_var_lst = list(badly_scaled_var_generator(m))
        assert badly_scaled_var_lst == []

        # test solve
        results = solver.solve(m, tee=True)

        # Check for optimal solution
        assert_optimal_termination(results)

        # test solution
        assert pytest.approx(-1.661e5, rel=1e-3) == value(m.fs.unit.deltaP[0])
        assert pytest.approx(-1.038e4, rel=1e-3) == value(m.fs.unit.deltaP[0] /
                                                          m.fs.unit.length)
        assert pytest.approx(395.8, rel=1e-3) == value(m.fs.unit.N_Re[0, 0.0])
        assert pytest.approx(0.2361,
                             rel=1e-3) == value(m.fs.unit.velocity[0, 0.0])
        assert pytest.approx(191.1, rel=1e-3) == value(m.fs.unit.N_Re[0, 1.0])
        assert pytest.approx(0.1187,
                             rel=1e-3) == value(m.fs.unit.velocity[0, 1.0])
        assert pytest.approx(7.089e-3, rel=1e-3) == value(
            m.fs.unit.flux_mass_phase_comp_avg[0, "Liq", "H2O"])
        assert pytest.approx(2.188e-6, rel=1e-3) == value(
            m.fs.unit.flux_mass_phase_comp_avg[0, "Liq", "NaCl"])
        assert pytest.approx(0.1347, rel=1e-3) == value(
            m.fs.unit.mixed_permeate[0].flow_mass_phase_comp["Liq", "H2O"])
        assert pytest.approx(4.157e-5, rel=1e-3) == value(
            m.fs.unit.mixed_permeate[0].flow_mass_phase_comp["Liq", "NaCl"])
        assert pytest.approx(50.08, rel=1e-3) == value(
            m.fs.unit.feed_side.properties_interface[
                0, 0.0].conc_mass_phase_comp["Liq", "NaCl"])
        assert pytest.approx(70.80, rel=1e-3) == value(
            m.fs.unit.feed_side.properties_out[0].conc_mass_phase_comp["Liq",
                                                                       "NaCl"])
        assert pytest.approx(76.32, rel=1e-3) == value(
            m.fs.unit.feed_side.properties_interface[
                0, 1.0].conc_mass_phase_comp["Liq", "NaCl"])
Exemple #22
0
    def test_Pdrop_fixed_per_unit_length(self):
        """ Testing 0D-RO with PressureChangeType.fixed_per_unit_length option.
        """
        m = ConcreteModel()
        m.fs = FlowsheetBlock(default={"dynamic": False})

        m.fs.properties = props.NaClParameterBlock()

        m.fs.unit = ReverseOsmosis0D(default={
            "property_package": m.fs.properties,
            "has_pressure_change": True,
            "concentration_polarization_type": ConcentrationPolarizationType.calculated,
            "mass_transfer_coefficient": MassTransferCoefficient.calculated,
            "pressure_change_type": PressureChangeType.fixed_per_unit_length})

        # fully specify system
        feed_flow_mass = 1
        feed_mass_frac_NaCl = 0.035
        feed_mass_frac_H2O = 1 - feed_mass_frac_NaCl
        feed_pressure = 50e5
        feed_temperature = 273.15 + 25
        membrane_area = 50
        length = 20
        A = 4.2e-12
        B = 3.5e-8
        pressure_atmospheric = 101325
        membrane_pressure_drop = 3e5

        m.fs.unit.inlet.flow_mass_phase_comp[0, 'Liq', 'NaCl'].fix(
            feed_flow_mass * feed_mass_frac_NaCl)
        m.fs.unit.inlet.flow_mass_phase_comp[0, 'Liq', 'H2O'].fix(
            feed_flow_mass * feed_mass_frac_H2O)
        m.fs.unit.inlet.pressure[0].fix(feed_pressure)
        m.fs.unit.inlet.temperature[0].fix(feed_temperature)
        m.fs.unit.area.fix(membrane_area)
        m.fs.unit.A_comp.fix(A)
        m.fs.unit.B_comp.fix(B)
        m.fs.unit.permeate.pressure[0].fix(pressure_atmospheric)

        m.fs.unit.channel_height.fix(0.002)
        m.fs.unit.spacer_porosity.fix(0.75)
        m.fs.unit.length.fix(length)
        m.fs.unit.dP_dx.fix(-membrane_pressure_drop / length)

        # test statistics
        assert number_variables(m) == 142
        assert number_total_constraints(m) == 112
        assert number_unused_variables(m) == 0

        # test degrees of freedom
        assert degrees_of_freedom(m) == 0

        # test scaling
        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'))

        calculate_scaling_factors(m)

        # check that all variables have scaling factors.
        # TODO: see aforementioned TODO on revisiting scaling and associated testing for property models.
        unscaled_var_list = list(unscaled_variables_generator(m.fs.unit, include_fixed=True))
        assert len(unscaled_var_list) == 0

        # test initialization
        initialization_tester(m, fail_on_warning=True)

        # test variable scaling
        badly_scaled_var_lst = list(badly_scaled_var_generator(m))
        assert badly_scaled_var_lst == []

        # test solve
        results = solver.solve(m, tee=True)

        # Check for optimal solution
        assert_optimal_termination(results)

        # test solution
        assert (pytest.approx(-3.000e5, rel=1e-3) == value(m.fs.unit.deltaP[0]))
        assert (pytest.approx(4.562e-3, rel=1e-3) ==
                value(m.fs.unit.flux_mass_phase_comp_avg[0, 'Liq', 'H2O']))
        assert (pytest.approx(1.593e-6, rel=1e-3) ==
                value(m.fs.unit.flux_mass_phase_comp_avg[0, 'Liq', 'NaCl']))
        assert (pytest.approx(0.2281, rel=1e-3) ==
                value(m.fs.unit.mixed_permeate[0].flow_mass_phase_comp['Liq', 'H2O']))
        assert (pytest.approx(7.963e-5, rel=1e-3) ==
                value(m.fs.unit.mixed_permeate[0].flow_mass_phase_comp['Liq', 'NaCl']))
        assert (pytest.approx(41.96, rel=1e-3) ==
                value(m.fs.unit.feed_side.properties_interface[0,0.].conc_mass_phase_comp['Liq', 'NaCl']))
        assert (pytest.approx(46.57, rel=1e-3) ==
                value(m.fs.unit.feed_side.properties_out[0].conc_mass_phase_comp['Liq', 'NaCl']))
        assert (pytest.approx(49.94, rel=1e-3) ==
                value(m.fs.unit.feed_side.properties_interface[0, 1.].conc_mass_phase_comp['Liq', 'NaCl']))
Exemple #23
0
 def test_passthrough_positive(self, m, s):
     s.options["nlp_scaling_method"] = "gradient-based"
     pyo.assert_optimal_termination(s.solve(m, tee=True))
     del s.options["nlp_scaling_method"]
     self._test_bounds(m)
     assert not hasattr(s, "_scaling_cache")
Exemple #24
0
def test_seawater_data():
    m = ConcreteModel()
    m.fs = FlowsheetBlock(default={'dynamic': False})
    m.fs.properties = DSPMDEParameterBlock(
        default={
            "solute_list": ["Ca_2+", "SO4_2-", "Na_+", "Cl_-", "Mg_2+"],
            "diffusivity_data": {
                ("Liq", "Ca_2+"): 0.792e-9,
                ("Liq", "SO4_2-"): 1.06e-9,
                ("Liq", "Na_+"): 1.33e-9,
                ("Liq", "Cl_-"): 2.03e-9,
                ("Liq", "Mg_2+"): 0.706e-9
            },
            "mw_data": {
                "H2O": 18e-3,
                "Na_+": 23e-3,
                "Ca_2+": 40e-3,
                "Mg_2+": 24e-3,
                "Cl_-": 35e-3,
                "SO4_2-": 96e-3
            },
            "stokes_radius_data": {
                "Na_+": 0.184e-9,
                "Ca_2+": 0.309e-9,
                "Mg_2+": 0.347e-9,
                "Cl_-": 0.121e-9,
                "SO4_2-": 0.230e-9
            },
            "charge": {
                "Na_+": 1,
                "Ca_2+": 2,
                "Mg_2+": 2,
                "Cl_-": -1,
                "SO4_2-": -2
            },
        })

    m.fs.stream = stream = m.fs.properties.build_state_block(
        [0], default={'defined_state': True})

    mass_flow_in = 1 * pyunits.kg / pyunits.s
    feed_mass_frac = {
        'Na_+': 11122e-6,
        'Ca_2+': 382e-6,
        'Mg_2+': 1394e-6,
        'SO4_2-': 2136e-6,
        'Cl_-': 20300e-6
    }
    for ion, x in feed_mass_frac.items():
        mol_comp_flow = x * pyunits.kg / pyunits.kg * mass_flow_in / stream[
            0].mw_comp[ion]

        stream[0].flow_mol_phase_comp['Liq', ion].fix(mol_comp_flow)

    H2O_mass_frac = 1 - sum(x for x in feed_mass_frac.values())
    H2O_mol_comp_flow = H2O_mass_frac * pyunits.kg / pyunits.kg * mass_flow_in / stream[
        0].mw_comp['H2O']

    stream[0].flow_mol_phase_comp['Liq', 'H2O'].fix(H2O_mol_comp_flow)
    stream[0].temperature.fix(298.15)
    stream[0].pressure.fix(101325)

    stream[0].assert_electroneutrality(tol=1e-2)

    metadata = m.fs.properties.get_metadata().properties
    for v_name in metadata:
        getattr(stream[0], v_name)
    assert stream[0].is_property_constructed('conc_mol_phase_comp')

    assert_units_consistent(m)

    check_dof(m, fail_flag=True)

    m.fs.properties.set_default_scaling('flow_mol_phase_comp',
                                        1,
                                        index=('Liq', 'H2O'))
    m.fs.properties.set_default_scaling('flow_mol_phase_comp',
                                        1,
                                        index=('Liq', 'Na_+'))
    m.fs.properties.set_default_scaling('flow_mol_phase_comp',
                                        1,
                                        index=('Liq', 'Cl_-'))
    m.fs.properties.set_default_scaling('flow_mol_phase_comp',
                                        1e1,
                                        index=('Liq', 'Ca_2+'))
    m.fs.properties.set_default_scaling('flow_mol_phase_comp',
                                        1e1,
                                        index=('Liq', 'SO4_2-'))
    m.fs.properties.set_default_scaling('flow_mol_phase_comp',
                                        1,
                                        index=('Liq', 'Mg_2+'))
    calculate_scaling_factors(m)

    # check if any variables are badly scaled
    badly_scaled_var_list = list(badly_scaled_var_generator(m))
    assert len(badly_scaled_var_list) == 0

    stream.initialize()

    # check if any variables are badly scaled
    badly_scaled_var_list = list(badly_scaled_var_generator(m))
    assert len(badly_scaled_var_list) == 0

    results = solver.solve(m)
    assert_optimal_termination(results)

    assert value(stream[0].flow_vol_phase['Liq']) == pytest.approx(0.001,
                                                                   rel=1e-3)
    assert value(stream[0].flow_mol_phase_comp['Liq', 'H2O']) == pytest.approx(
        53.59256, rel=1e-3)
    assert value(stream[0].flow_mol_phase_comp['Liq',
                                               'Na_+']) == pytest.approx(
                                                   0.4836, rel=1e-3)
    assert value(stream[0].flow_mol_phase_comp['Liq',
                                               'Ca_2+']) == pytest.approx(
                                                   0.00955, rel=1e-3)
    assert value(stream[0].flow_mol_phase_comp['Liq',
                                               'Mg_2+']) == pytest.approx(
                                                   0.05808, rel=1e-3)
    assert value(stream[0].flow_mol_phase_comp['Liq',
                                               'Cl_-']) == pytest.approx(
                                                   0.58, rel=1e-3)
    assert value(stream[0].flow_mol_phase_comp['Liq',
                                               'SO4_2-']) == pytest.approx(
                                                   0.02225, rel=1e-3)
    assert value(stream[0].dens_mass_phase['Liq']) == pytest.approx(1000,
                                                                    rel=1e-3)
    assert value(stream[0].pressure_osm) == pytest.approx(28.593e5, rel=1e-3)
    assert value(stream[0].flow_vol) == pytest.approx(0.001, rel=1e-3)

    assert value(
        sum(stream[0].conc_mass_phase_comp['Liq', j]
            for j in m.fs.properties.solute_set)) == pytest.approx(35.334,
                                                                   rel=1e-3)
    assert value(
        sum(stream[0].mass_frac_phase_comp['Liq', j]
            for j in m.fs.properties.solute_set)) == pytest.approx(35334e-6,
                                                                   rel=1e-3)
    assert value(
        sum(stream[0].mass_frac_phase_comp['Liq', j]
            for j in m.fs.properties.component_list)) == pytest.approx(
                1, rel=1e-3)
    assert value(
        sum(stream[0].mole_frac_phase_comp['Liq', j]
            for j in m.fs.properties.component_list)) == pytest.approx(
                1, rel=1e-3)

    assert value(stream[0].conc_mol_phase_comp['Liq',
                                               'Na_+']) == pytest.approx(
                                                   483.565, rel=1e-3)
    assert value(stream[0].conc_mol_phase_comp['Liq',
                                               'Cl_-']) == pytest.approx(
                                                   580, rel=1e-3)
    assert value(stream[0].conc_mol_phase_comp['Liq',
                                               'Ca_2+']) == pytest.approx(
                                                   9.55, rel=1e-3)
    assert value(stream[0].conc_mol_phase_comp['Liq',
                                               'SO4_2-']) == pytest.approx(
                                                   22.25, rel=1e-3)
    assert value(stream[0].conc_mol_phase_comp['Liq',
                                               'Mg_2+']) == pytest.approx(
                                                   58.08, rel=1e-3)

    assert value(stream[0].conc_mass_phase_comp['Liq',
                                                'Na_+']) == pytest.approx(
                                                    11.122, rel=1e-3)
    assert value(stream[0].conc_mass_phase_comp['Liq',
                                                'Cl_-']) == pytest.approx(
                                                    20.3, rel=1e-3)
    assert value(stream[0].conc_mass_phase_comp['Liq',
                                                'Ca_2+']) == pytest.approx(
                                                    0.382, rel=1e-3)
    assert value(stream[0].conc_mass_phase_comp['Liq',
                                                'SO4_2-']) == pytest.approx(
                                                    2.136, rel=1e-3)
    assert value(stream[0].conc_mass_phase_comp['Liq',
                                                'Mg_2+']) == pytest.approx(
                                                    1.394, rel=1e-3)

    assert value(stream[0].mole_frac_phase_comp['Liq',
                                                'Na_+']) == pytest.approx(
                                                    8.833e-3, rel=1e-3)
    assert value(stream[0].mole_frac_phase_comp['Liq',
                                                'Cl_-']) == pytest.approx(
                                                    1.059e-2, rel=1e-3)
    assert value(stream[0].mole_frac_phase_comp['Liq',
                                                'Ca_2+']) == pytest.approx(
                                                    1.744e-4, rel=1e-3)
    assert value(stream[0].mole_frac_phase_comp['Liq',
                                                'SO4_2-']) == pytest.approx(
                                                    4.064e-4, rel=1e-3)
    assert value(stream[0].mole_frac_phase_comp['Liq',
                                                'Mg_2+']) == pytest.approx(
                                                    1.061e-3, rel=1e-3)

    assert value(stream[0].mass_frac_phase_comp['Liq',
                                                'Na_+']) == pytest.approx(
                                                    1.112e-2, rel=1e-3)
    assert value(stream[0].mass_frac_phase_comp['Liq',
                                                'Cl_-']) == pytest.approx(
                                                    2.03e-2, rel=1e-3)
    assert value(stream[0].mass_frac_phase_comp['Liq',
                                                'Ca_2+']) == pytest.approx(
                                                    3.82e-4, rel=1e-3)
    assert value(stream[0].mass_frac_phase_comp['Liq',
                                                'SO4_2-']) == pytest.approx(
                                                    2.136e-3, rel=1e-3)
    assert value(stream[0].mass_frac_phase_comp['Liq',
                                                'Mg_2+']) == pytest.approx(
                                                    1.394e-3, rel=1e-3)
Exemple #25
0
def _do_param_sweep(
    model,
    sweep_params,
    outputs,
    local_values,
    optimize_function,
    optimize_kwargs,
    reinitialize_function,
    reinitialize_kwargs,
    reinitialize_before_sweep,
    comm,
):

    # Initialize space to hold results
    local_num_cases = np.shape(local_values)[0]

    # Create the output skeleton for storing detailed data
    local_output_dict = _create_local_output_skeleton(model, sweep_params,
                                                      outputs, local_num_cases)

    local_results = np.zeros(
        (local_num_cases, len(local_output_dict["outputs"])))

    local_solve_successful_list = []

    # ================================================================
    # Run all optimization cases
    # ================================================================

    for k in range(local_num_cases):
        # Update the model values with a single combination from the parameter space
        _update_model_values(model, sweep_params, local_values[k, :])

        run_successful = False  # until proven otherwise

        # Forced reinitialization of the flowsheet if enabled
        if reinitialize_before_sweep:
            try:
                assert reinitialize_function is not None
            except:
                raise ValueError(
                    "Reinitialization function was not specified. The model will not be reinitialized."
                )
            else:
                reinitialize_function(model, **reinitialize_kwargs)

        try:
            # Simulate/optimize with this set of parameter
            with capture_output():
                results = optimize_function(model, **optimize_kwargs)
            pyo.assert_optimal_termination(results)

        except:
            # run_successful remains false. We try to reinitialize and solve again
            if reinitialize_function is not None:
                try:
                    reinitialize_function(model, **reinitialize_kwargs)
                    with capture_output():
                        results = optimize_function(model, **optimize_kwargs)
                    pyo.assert_optimal_termination(results)

                except:
                    pass  # run_successful is still False
                else:
                    run_successful = True

        else:
            # If the simulation suceeds, report stats
            run_successful = True

        # Update the loop based on the reinitialization
        _update_local_output_dict(
            model,
            sweep_params,
            k,
            local_values[k, :],
            run_successful,
            local_output_dict,
        )

        local_solve_successful_list.append(run_successful)

    local_output_dict["solve_successful"] = local_solve_successful_list

    return local_output_dict
Exemple #26
0
def test_save_load():
    keras_surrogate = create_keras_model(name='PT_data_2_10_10_2_sigmoid',
                                         return_keras_model_only=False)

    new_keras_surrogate = None
    dname = None
    with TempfileManager.new_context() as tf:
        dname = tf.mkdtemp()
        keras_surrogate.save_to_folder(dname)
        assert os.path.isdir(dname)
        assert os.path.isfile(os.path.join(dname, 'idaes_info.json'))

        new_keras_surrogate = KerasSurrogate.load_from_folder(dname)

    # Check for clean up
    assert not os.path.isdir(dname)

    # check surrogate data members
    assert new_keras_surrogate._input_labels == [
        'Temperature_K', 'Pressure_Pa'
    ]
    assert new_keras_surrogate._output_labels == ['EnthMol', 'VapFrac']
    assert sorted(new_keras_surrogate._input_bounds.keys()) == [
        'Pressure_Pa', 'Temperature_K'
    ]
    assert new_keras_surrogate._input_bounds['Temperature_K'][
        0] == pytest.approx(360.0)
    assert new_keras_surrogate._input_bounds['Temperature_K'][
        1] == pytest.approx(380.0)
    assert new_keras_surrogate._input_bounds['Pressure_Pa'][
        0] == pytest.approx(101325.0)
    assert new_keras_surrogate._input_bounds['Pressure_Pa'][
        1] == pytest.approx(1.2 * 101325.0)

    # check input scaler
    expected_columns = ['Temperature_K', 'Pressure_Pa']
    offset_series = pd.Series({
        'Temperature_K': 369.983611,
        'Pressure_Pa': 111421.319811
    })
    factor_series = pd.Series({
        'Temperature_K': 5.836047,
        'Pressure_Pa': 5917.954504
    })
    scaler = new_keras_surrogate._input_scaler
    assert scaler._expected_columns == expected_columns
    pd.testing.assert_series_equal(scaler._offset,
                                   offset_series,
                                   rtol=rtol,
                                   atol=atol)
    pd.testing.assert_series_equal(scaler._factor,
                                   factor_series,
                                   rtol=rtol,
                                   atol=atol)

    # check output scaler
    expected_columns = ['EnthMol', 'VapFrac']
    offset_series = pd.Series({'EnthMol': 54599.629980, 'VapFrac': 0.403307})
    factor_series = pd.Series({'EnthMol': 14654.226615, 'VapFrac': 0.430181})
    scaler = new_keras_surrogate._output_scaler
    assert scaler._expected_columns == expected_columns
    pd.testing.assert_series_equal(scaler._offset,
                                   offset_series,
                                   rtol=rtol,
                                   atol=atol)
    pd.testing.assert_series_equal(scaler._factor,
                                   factor_series,
                                   rtol=rtol,
                                   atol=atol)

    # check evaluation
    x_test = pd.DataFrame({
        'Temperature_K': [360, 370, 380],
        'Pressure_Pa': [1.05 * 101325, 1.10 * 101325, 1.15 * 101325]
    })
    y_test = keras_surrogate.evaluate_surrogate(x_test)
    expected_y = pd.DataFrame({
        'EnthMol': [40194.5586954288, 48660.288218426984, 75178.30324367314],
        'VapFrac':
        [0.002291496299564877, 0.21942246438431742, 0.9996716243380308]
    })
    pd.testing.assert_frame_equal(y_test, expected_y, rtol=rtol, atol=atol)

    # check solve with pyomo
    x_test = pd.DataFrame({
        'Temperature_K': [370],
        'Pressure_Pa': [1.1 * 101325]
    })
    y_test = keras_surrogate.evaluate_surrogate(x_test)

    m = ConcreteModel()
    m.obj = Objective(expr=1)
    m.surrogate = SurrogateBlock()
    m.surrogate.build_model(surrogate_object=keras_surrogate,
                            formulation=KerasSurrogate.Formulation.FULL_SPACE)
    m.surrogate.inputs['Temperature_K'].fix(370)
    m.surrogate.inputs['Pressure_Pa'].fix(1.1 * 101325)
    solver = SolverFactory('ipopt')
    status = solver.solve(m, tee=True)
    assert_optimal_termination(status)

    y_test_pyomo = pd.DataFrame({
        'EnthMol': [value(m.surrogate.outputs['EnthMol'])],
        'VapFrac': [value(m.surrogate.outputs['VapFrac'])]
    })
    pd.testing.assert_frame_equal(y_test, y_test_pyomo, rtol=rtol, atol=atol)
Exemple #27
0
def test_keras_surrogate_auto_creating_variables():
    ###
    # Test 1->2 sigmoid
    ###
    keras_surrogate = create_keras_model(name='T_data_1_10_10_2_sigmoid',
                                         return_keras_model_only=False)
    x_test = pd.DataFrame({'Temperature_K': [370]})
    y_test = keras_surrogate.evaluate_surrogate(x_test)

    # Test full-space
    m = ConcreteModel()
    m.obj = Objective(expr=1)
    m.surrogate = SurrogateBlock()
    m.surrogate.build_model(surrogate_object=keras_surrogate,
                            formulation=KerasSurrogate.Formulation.FULL_SPACE)
    m.surrogate.inputs['Temperature_K'].fix(370)
    solver = SolverFactory('ipopt')
    status = solver.solve(m, tee=True)
    assert_optimal_termination(status)

    y_test_pyomo = pd.DataFrame({
        'EnthMol': [value(m.surrogate.outputs['EnthMol'])],
        'VapFrac': [value(m.surrogate.outputs['VapFrac'])]
    })
    pd.testing.assert_frame_equal(y_test, y_test_pyomo, rtol=rtol, atol=atol)

    # Test reduced-space
    m = ConcreteModel()
    m.obj = Objective(expr=1)
    m.surrogate = SurrogateBlock()
    m.surrogate.build_model(
        surrogate_object=keras_surrogate,
        formulation=KerasSurrogate.Formulation.REDUCED_SPACE)
    m.surrogate.inputs['Temperature_K'].fix(370)
    solver = SolverFactory('ipopt')
    status = solver.solve(m, tee=True)
    assert_optimal_termination(status)

    y_test_pyomo = pd.DataFrame({
        'EnthMol': [value(m.surrogate.outputs['EnthMol'])],
        'VapFrac': [value(m.surrogate.outputs['VapFrac'])]
    })
    pd.testing.assert_frame_equal(y_test, y_test_pyomo, rtol=rtol, atol=atol)

    ###
    # Test 1->2 relu
    ###
    keras_surrogate = create_keras_model(name='T_data_1_10_10_2_relu',
                                         return_keras_model_only=False)
    x_test = pd.DataFrame({'Temperature_K': [370]})
    y_test = keras_surrogate.evaluate_surrogate(x_test)

    # Test relu complementarity
    m = ConcreteModel()
    m.obj = Objective(expr=1)
    m.surrogate = SurrogateBlock()
    m.surrogate.build_model(
        surrogate_object=keras_surrogate,
        formulation=KerasSurrogate.Formulation.RELU_COMPLEMENTARITY)
    m.surrogate.inputs['Temperature_K'].fix(370)
    solver = SolverFactory('ipopt')
    status = solver.solve(m, tee=True)
    assert_optimal_termination(status)

    y_test_pyomo = pd.DataFrame({
        'EnthMol': [value(m.surrogate.outputs['EnthMol'])],
        'VapFrac': [value(m.surrogate.outputs['VapFrac'])]
    })
    pd.testing.assert_frame_equal(y_test, y_test_pyomo, rtol=rtol, atol=atol)

    ###
    # Test 2->2 sigmoid
    ###
    keras_surrogate = create_keras_model(name='PT_data_2_10_10_2_sigmoid',
                                         return_keras_model_only=False)
    x_test = pd.DataFrame({
        'Temperature_K': [370],
        'Pressure_Pa': [1.1 * 101325]
    })
    y_test = keras_surrogate.evaluate_surrogate(x_test)

    # Test full-space
    m = ConcreteModel()
    m.obj = Objective(expr=1)
    m.surrogate = SurrogateBlock()
    m.surrogate.build_model(surrogate_object=keras_surrogate,
                            formulation=KerasSurrogate.Formulation.FULL_SPACE)
    m.surrogate.inputs['Temperature_K'].fix(370)
    m.surrogate.inputs['Pressure_Pa'].fix(1.1 * 101325)
    solver = SolverFactory('ipopt')
    status = solver.solve(m, tee=True)
    assert_optimal_termination(status)

    y_test_pyomo = pd.DataFrame({
        'EnthMol': [value(m.surrogate.outputs['EnthMol'])],
        'VapFrac': [value(m.surrogate.outputs['VapFrac'])]
    })
    pd.testing.assert_frame_equal(y_test, y_test_pyomo, rtol=rtol, atol=atol)

    # Test reduced-space
    m = ConcreteModel()
    m.obj = Objective(expr=1)
    m.surrogate = SurrogateBlock()
    m.surrogate.build_model(
        surrogate_object=keras_surrogate,
        formulation=KerasSurrogate.Formulation.REDUCED_SPACE)
    m.surrogate.inputs['Temperature_K'].fix(370)
    m.surrogate.inputs['Pressure_Pa'].fix(1.1 * 101325)
    solver = SolverFactory('ipopt')
    status = solver.solve(m, tee=True)
    assert_optimal_termination(status)

    y_test_pyomo = pd.DataFrame({
        'EnthMol': [value(m.surrogate.outputs['EnthMol'])],
        'VapFrac': [value(m.surrogate.outputs['VapFrac'])]
    })
    pd.testing.assert_frame_equal(y_test, y_test_pyomo, rtol=rtol, atol=atol)

    ###
    # Test 2->2 relu
    ###
    keras_surrogate = create_keras_model(name='PT_data_2_10_10_2_relu',
                                         return_keras_model_only=False)
    x_test = pd.DataFrame({
        'Temperature_K': [370],
        'Pressure_Pa': [1.1 * 101325]
    })
    y_test = keras_surrogate.evaluate_surrogate(x_test)

    # Test relu complementarity
    m = ConcreteModel()
    m.obj = Objective(expr=1)
    m.surrogate = SurrogateBlock()
    m.surrogate.build_model(
        surrogate_object=keras_surrogate,
        formulation=KerasSurrogate.Formulation.RELU_COMPLEMENTARITY)
    m.surrogate.inputs['Temperature_K'].fix(370)
    m.surrogate.inputs['Pressure_Pa'].fix(1.1 * 101325)
    solver = SolverFactory('ipopt')
    status = solver.solve(m, tee=True)
    assert_optimal_termination(status)

    y_test_pyomo = pd.DataFrame({
        'EnthMol': [value(m.surrogate.outputs['EnthMol'])],
        'VapFrac': [value(m.surrogate.outputs['VapFrac'])]
    })
    pd.testing.assert_frame_equal(y_test, y_test_pyomo, rtol=rtol, atol=atol)
def test_heat_exchanger():
    m = ConcreteModel()
    m.fs = FlowsheetBlock(default={"dynamic": False})
    m.fs.properties = props.SeawaterParameterBlock()
    m.fs.unit = HeatExchanger(
        default={
            "hot_side_name": "hot",
            "cold_side_name": "cold",
            "hot": {
                "property_package": m.fs.properties
            },
            "cold": {
                "property_package": m.fs.properties
            },
            "delta_temperature_callback": delta_temperature_chen_callback,
            "flow_pattern": HeatExchangerFlowPattern.countercurrent,
        })

    # scaling
    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", "TDS"))
    iscale.set_scaling_factor(m.fs.unit.hot.heat, 1e-3)
    iscale.set_scaling_factor(m.fs.unit.cold.heat, 1e-3)
    iscale.set_scaling_factor(m.fs.unit.overall_heat_transfer_coefficient,
                              1e-3)
    iscale.set_scaling_factor(m.fs.unit.area, 1)
    iscale.calculate_scaling_factors(m)

    # ---specifications---
    # state variables
    m.fs.unit.hot_inlet.flow_mass_phase_comp[0, "Liq", "H2O"].fix(1)
    m.fs.unit.hot_inlet.flow_mass_phase_comp[0, "Liq", "TDS"].fix(0.01)
    m.fs.unit.hot_inlet.temperature[0].fix(350)
    m.fs.unit.hot_inlet.pressure[0].fix(2e5)

    m.fs.unit.cold_inlet.flow_mass_phase_comp[0, "Liq", "H2O"].fix(0.5)
    m.fs.unit.cold_inlet.flow_mass_phase_comp[0, "Liq", "TDS"].fix(0.01)
    m.fs.unit.cold_inlet.temperature[0].fix(298)
    m.fs.unit.cold_inlet.pressure[0].fix(2e5)

    m.fs.unit.area.fix(5)
    m.fs.unit.overall_heat_transfer_coefficient.fix(1000)

    # solving
    assert_units_consistent(m)
    degrees_of_freedom(m)

    m.fs.unit.initialize()

    solver = get_solver()
    results = solver.solve(m, tee=False)
    assert_optimal_termination(results)

    assert pytest.approx(89050.0, rel=1e-4) == value(m.fs.unit.heat_duty[0])
    assert pytest.approx(1.0, rel=1e-4) == value(
        m.fs.unit.hot_outlet.flow_mass_phase_comp[0, "Liq", "H2O"])
    assert pytest.approx(0.01, rel=1e-4) == value(
        m.fs.unit.hot_outlet.flow_mass_phase_comp[0, "Liq", "TDS"])
    assert pytest.approx(328.69, rel=1e-4) == value(
        m.fs.unit.hot_outlet.temperature[0])
    assert pytest.approx(2.0e5,
                         rel=1e-4) == value(m.fs.unit.hot_outlet.pressure[0])
    assert pytest.approx(0.5, rel=1e-4) == value(
        m.fs.unit.cold_outlet.flow_mass_phase_comp[0, "Liq", "H2O"])
    assert pytest.approx(0.01, rel=1e-4) == value(
        m.fs.unit.cold_outlet.flow_mass_phase_comp[0, "Liq", "TDS"])
    assert pytest.approx(340.78, rel=1e-4) == value(
        m.fs.unit.cold_outlet.temperature[0])
    assert pytest.approx(2.0e5,
                         rel=1e-4) == value(m.fs.unit.cold_outlet.pressure[0])

    m.fs.unit.report()
Exemple #29
0
                                 acstream, a_line_fails_prob,
                                 stage_duration_minutes, repair_fct, lines)
    cb_data["epath"] = egret_path_to_data
    cb_data["acstream"] = acstream
    creator_options = {"cb_data": cb_data}
    scenario_names=["Scenario_"+str(i)\
                    for i in range(1,len(cb_data["etree"].rootnode.ScenarioList)+1)]

    # end options
    ef = sputils.create_EF(scenario_names, pysp2_callback, creator_options)
    ###solver.options["BarHomogeneous"] = 1
    if "gurobi" in solvername:
        solver.options["BarHomogeneous"] = 1

    results = solver.solve(ef, tee=True)
    pyo.assert_optimal_termination(results)

    print('EF objective value:', pyo.value(ef.EF_Obj))
    sputils.ef_nonants_csv(ef, "vardump.csv")
    for (sname, smodel) in sputils.ef_scenarios(ef):
        print(sname)
        for stage in smodel.stage_models:
            print("   Stage {}".format(stage))
            for gen in smodel.stage_models[stage].pg:
                print ("      gen={} pg={}, qg={}"\
                       .format(gen,
                               pyo.value(smodel.stage_models[stage].pg[gen]),
                               pyo.value(smodel.stage_models[stage].qg[gen])))
            print("   obj={}".format(pyo.value(smodel.objective)))
    print("EF objective value for case {}={}".\
          format(pyo.value(casename), pyo.value(ef.EF_Obj)))
Exemple #30
0
def test_keras_surrogate_with_variables():
    keras_surrogate = create_keras_model(name='PT_data_2_10_10_2_sigmoid',
                                         return_keras_model_only=False)
    x_test = pd.DataFrame({
        'Temperature_K': [370],
        'Pressure_Pa': [1.1 * 101325]
    })
    y_test = keras_surrogate.evaluate_surrogate(x_test)

    # Test provide scalar inputs, auto create outputs
    m = ConcreteModel()
    m.obj = Objective(expr=1)
    m.T = Var()
    m.P = Var()
    m.surrogate = SurrogateBlock()
    m.surrogate.build_model(surrogate_object=keras_surrogate,
                            input_vars=[m.T, m.P],
                            formulation=KerasSurrogate.Formulation.FULL_SPACE)
    m.T.fix(370)
    m.P.fix(1.1 * 101325)
    solver = SolverFactory('ipopt')
    status = solver.solve(m, tee=True)
    assert_optimal_termination(status)

    y_test_pyomo = pd.DataFrame({
        'EnthMol': [value(m.surrogate.outputs['EnthMol'])],
        'VapFrac': [value(m.surrogate.outputs['VapFrac'])]
    })
    pd.testing.assert_frame_equal(y_test, y_test_pyomo, rtol=rtol, atol=atol)

    # Test provide indexed inputs, auto create outputs
    m = ConcreteModel()
    m.obj = Objective(expr=1)
    m.inputs = Var(['T', 'P'])
    m.surrogate = SurrogateBlock()
    m.surrogate.build_model(surrogate_object=keras_surrogate,
                            input_vars=[m.inputs],
                            formulation=KerasSurrogate.Formulation.FULL_SPACE)
    m.inputs['T'].fix(370)
    m.inputs['P'].fix(1.1 * 101325)
    solver = SolverFactory('ipopt')
    status = solver.solve(m, tee=True)
    assert_optimal_termination(status)

    y_test_pyomo = pd.DataFrame({
        'EnthMol': [value(m.surrogate.outputs['EnthMol'])],
        'VapFrac': [value(m.surrogate.outputs['VapFrac'])]
    })
    pd.testing.assert_frame_equal(y_test, y_test_pyomo, rtol=rtol, atol=atol)

    # Test auto-create inputs, provide scalar outputs
    m = ConcreteModel()
    m.obj = Objective(expr=1)
    m.H = Var()
    m.V = Var()
    m.surrogate = SurrogateBlock()
    m.surrogate.build_model(surrogate_object=keras_surrogate,
                            output_vars=[m.H, m.V],
                            formulation=KerasSurrogate.Formulation.FULL_SPACE)
    m.surrogate.inputs['Temperature_K'].fix(370)
    m.surrogate.inputs['Pressure_Pa'].fix(1.1 * 101325)
    solver = SolverFactory('ipopt')
    status = solver.solve(m, tee=True)
    assert_optimal_termination(status)

    y_test_pyomo = pd.DataFrame({
        'EnthMol': [value(m.H)],
        'VapFrac': [value(m.V)]
    })
    pd.testing.assert_frame_equal(y_test, y_test_pyomo, rtol=rtol, atol=atol)

    # Test auto-create inputs, provide indexed outputs
    m = ConcreteModel()
    m.obj = Objective(expr=1)
    m.outputs = Var(['H', 'V'])
    m.surrogate = SurrogateBlock()
    m.surrogate.build_model(surrogate_object=keras_surrogate,
                            output_vars=[m.outputs],
                            formulation=KerasSurrogate.Formulation.FULL_SPACE)
    m.surrogate.inputs['Temperature_K'].fix(370)
    m.surrogate.inputs['Pressure_Pa'].fix(1.1 * 101325)
    solver = SolverFactory('ipopt')
    status = solver.solve(m, tee=True)
    assert_optimal_termination(status)

    y_test_pyomo = pd.DataFrame({
        'EnthMol': [value(m.outputs['H'])],
        'VapFrac': [value(m.outputs['V'])]
    })
    pd.testing.assert_frame_equal(y_test, y_test_pyomo, rtol=rtol, atol=atol)

    # Test provide scalar inputs, provide indexed outputs
    m = ConcreteModel()
    m.obj = Objective(expr=1)
    m.T = Var()
    m.P = Var()
    m.outputs = Var(['H', 'V'])
    m.surrogate = SurrogateBlock()
    m.surrogate.build_model(surrogate_object=keras_surrogate,
                            input_vars=[m.T, m.P],
                            output_vars=[m.outputs],
                            formulation=KerasSurrogate.Formulation.FULL_SPACE)
    m.T.fix(370)
    m.P.fix(1.1 * 101325)
    solver = SolverFactory('ipopt')
    status = solver.solve(m, tee=True)
    assert_optimal_termination(status)

    y_test_pyomo = pd.DataFrame({
        'EnthMol': [value(m.outputs['H'])],
        'VapFrac': [value(m.outputs['V'])]
    })
    pd.testing.assert_frame_equal(y_test, y_test_pyomo, rtol=rtol, atol=atol)