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)
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)
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
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)
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)
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)
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))
def test_solve(self, model): results = solver.solve(model) # Check for optimal solution assert_optimal_termination(results)
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)
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()
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"])
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']))
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")
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)
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
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)
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()
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)))
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)