def test_dynamic_build(self): m = ConcreteModel() m.fs = FlowsheetBlock(default={"dynamic": True, "time_units": units.s}) m.fs.properties = PhysicalParameterTestBlock() m.fs.unit = PressureChanger( default={"property_package": m.fs.properties}) iscale.calculate_scaling_factors(m) assert hasattr(m.fs.unit, "volume")
def test_scaling(self, model): iscale.calculate_scaling_factors(model) assert iscale.get_constraint_transform_applied_scaling_factor( model.fs.unit.water_recovery_equation[0]) == 1e5 assert iscale.get_constraint_transform_applied_scaling_factor( model.fs.unit.solute_treated_equation[0, "A"]) == 1e5 assert iscale.get_constraint_transform_applied_scaling_factor( model.fs.unit.solute_treated_equation[0, "B"]) == 1e5 assert iscale.get_constraint_transform_applied_scaling_factor( model.fs.unit.solute_treated_equation[0, "C"]) == 1e5
def test_calculate_scaling(self, unit_frame): m = unit_frame calculate_scaling_factors(m) # check that all variables have scaling factors unscaled_var_list = list( unscaled_variables_generator(m.fs.unit, include_fixed=True)) assert len(unscaled_var_list) == 0 # check that all constraints have been scaled unscaled_constraint_list = list(unscaled_constraints_generator(m)) assert len(unscaled_constraint_list) == 0
def test_scaling(self, model): iscale.calculate_scaling_factors(model) assert (iscale.get_constraint_transform_applied_scaling_factor( model.fs.unit.water_recovery_equation[0]) == 1e5) assert (iscale.get_constraint_transform_applied_scaling_factor( model.fs.unit.mass_balance[0]) == 1e5) assert (iscale.get_constraint_transform_applied_scaling_factor( model.fs.unit.solute_removal_equation[0, "cod"]) == 1e5) assert (iscale.get_constraint_transform_applied_scaling_factor( model.fs.unit.solute_treated_equation[0, "cod"]) == 1e5)
def test_base_build(): m = pyo.ConcreteModel() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.pp = PhysicalParameterTestBlock() m.fs.cv = ControlVolume1DBlock( default={ "property_package": m.fs.pp, "transformation_method": "dae.finite_difference", "transformation_scheme": "BACKWARD", "finite_elements": 10, }) m.fs.cv.add_geometry() m.fs.cv.add_state_blocks(has_phase_equilibrium=False) m.fs.cv.add_material_balances( balance_type=MaterialBalanceType.componentTotal, has_phase_equilibrium=False) m.fs.cv.add_energy_balances(balance_type=EnergyBalanceType.enthalpyTotal, has_heat_transfer=True, has_work_transfer=True) # add momentum balance m.fs.cv.add_momentum_balances( balance_type=MomentumBalanceType.pressureTotal, has_pressure_change=True) m.fs.cv.apply_transformation() # The scaling factors used for this test were selected to be easy values to # test, they do not represent typical scaling factors. iscale.set_scaling_factor(m.fs.cv.heat, 11) iscale.set_scaling_factor(m.fs.cv.work, 12) iscale.calculate_scaling_factors(m) # Make sure the heat and work scaling factors are set and not overwitten # by the defaults in calculate_scaling_factors for (t, x), v in m.fs.cv.heat.items(): assert iscale.get_scaling_factor(v) == 11 for (t, x), v in m.fs.cv.work.items(): assert iscale.get_scaling_factor(v) == 12 # Didn't specify a deltaP scaling factor, so by default pressure in scaling # factor * 10 is used. for v in m.fs.cv.deltaP.values(): #deltaP is time indexed assert iscale.get_scaling_factor(v) == 1040 # check scaling on mass, energy, and pressure balances. for c in m.fs.cv.material_balances.values(): # this uses the minmum material flow term scale assert iscale.get_constraint_transform_applied_scaling_factor(c) == 112 for c in m.fs.cv.enthalpy_balances.values(): # this uses the minmum enthalpy flow term scale assert iscale.get_constraint_transform_applied_scaling_factor(c) == 110 for c in m.fs.cv.pressure_balance.values(): # This uses the inlet pressure scale assert iscale.get_constraint_transform_applied_scaling_factor(c) == 104
def test_property_seawater_ions(): m = ConcreteModel() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.properties = GenericParameterBlock(default=configuration) m.fs.stream = m.fs.properties.build_state_block( [0], default={'defined_state': True}) # specify m.fs.stream[0].flow_mol_phase_comp['Liq', 'Na_+'].fix(0.008845) m.fs.stream[0].flow_mol_phase_comp['Liq', 'Ca_2+'].fix(0.000174) m.fs.stream[0].flow_mol_phase_comp['Liq', 'Mg_2+'].fix(0.001049) m.fs.stream[0].flow_mol_phase_comp['Liq', 'SO4_2-'].fix(0.000407) m.fs.stream[0].flow_mol_phase_comp['Liq', 'Cl_-'].fix(0.010479) m.fs.stream[0].flow_mol_phase_comp['Liq', 'H2O'].fix(0.979046) m.fs.stream[0].temperature.fix(273.15 + 25) m.fs.stream[0].pressure.fix(101325) # # scaling iscale.calculate_scaling_factors(m.fs) # checking state block assert_units_consistent(m) # check dof = 0 check_dof(m, fail_flag=True) # initialize m.fs.stream.initialize() # check solve results = solver.solve(m) assert_optimal_termination(results) # # check values assert value(m.fs.stream[0].mole_frac_phase_comp['Liq', 'Na_+']) == pytest.approx( 8.845e-3, rel=1e-3) assert value( m.fs.stream[0].mole_frac_phase_comp['Liq', 'Ca_2+']) == pytest.approx( 1.74e-4, rel=1e-3) assert value(m.fs.stream[0].mole_frac_phase_comp['Liq', 'Cl_-']) == pytest.approx( 1.048e-2, rel=1e-3) assert value(m.fs.stream[0].mole_frac_phase_comp['Liq', 'H2O']) == pytest.approx( 0.9790, rel=1e-3) assert value( m.fs.stream[0].mole_frac_phase_comp['Liq', 'Mg_2+']) == pytest.approx( 1.049e-3, rel=1e-3) assert value( m.fs.stream[0].mole_frac_phase_comp['Liq', 'SO4_2-']) == pytest.approx( 4.07e-4, rel=1e-3)
def iapws_turb(self): m = ConcreteModel() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.properties = iapws95.Iapws95ParameterBlock() m.fs.unit = PressureChanger(default={ "property_package": m.fs.properties, "thermodynamic_assumption": ThermodynamicAssumption.isentropic, "compressor": False}) iscale.calculate_scaling_factors(m) return m
def test_adiabatic(self): m = ConcreteModel() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.properties = PhysicalParameterTestBlock() m.fs.unit = PressureChanger( default={ "property_package": m.fs.properties, "thermodynamic_assumption": ThermodynamicAssumption.adiabatic }) iscale.calculate_scaling_factors(m)
def test_pump(self): m = ConcreteModel() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.properties = PhysicalParameterTestBlock() m.fs.unit = PressureChanger(default={ "property_package": m.fs.properties, "thermodynamic_assumption": ThermodynamicAssumption.pump}) iscale.calculate_scaling_factors(m) assert isinstance(m.fs.unit.fluid_work_calculation, Constraint)
def test_construction_component_not_in_phase(): m = ConcreteModel() m.fs = FlowsheetBlock() m.fs.prop_params = GenericParameterBlock( default=get_prop(["H2O", "H2"], ["Liq", "Vap"])) m.fs.inject1 = Mixer( default={ "property_package": m.fs.prop_params, "inlet_list": ["in1", "in2"], "momentum_mixing_type": MomentumMixingType.none }) iscale.calculate_scaling_factors(m)
def test_property_ions(model): m = model m.fs.stream = m.fs.properties.build_state_block( [0], default={"defined_state": True}) m.fs.stream[0].flow_mol_phase_comp["Liq", "A"].fix(0.000407) m.fs.stream[0].flow_mol_phase_comp["Liq", "B"].fix(0.010479) m.fs.stream[0].flow_mol_phase_comp["Liq", "C"].fix(0.010479) m.fs.stream[0].flow_mol_phase_comp["Liq", "D"].fix(0.000407) m.fs.stream[0].flow_mol_phase_comp["Liq", "H2O"].fix(0.99046) m.fs.stream[0].temperature.fix(298.15) m.fs.stream[0].pressure.fix(101325) m.fs.stream[0].assert_electroneutrality(defined_state=True) m.fs.stream[0].mole_frac_phase_comp m.fs.stream[0].flow_mass_phase_comp m.fs.stream[0].molality_comp m.fs.stream[0].pressure_osm_phase m.fs.stream[0].dens_mass_phase m.fs.stream[0].conc_mol_phase_comp m.fs.stream[0].act_coeff_phase_comp calculate_scaling_factors(m.fs) assert_units_consistent(m) check_dof(m, fail_flag=True) m.fs.stream.initialize() results = solver.solve(m) assert_optimal_termination(results) assert value(m.fs.stream[0].conc_mass_phase_comp["Liq", "A"]) == pytest.approx( 2.1288e-1, rel=1e-3) assert value(m.fs.stream[0].conc_mol_phase_comp["Liq", "A"]) == pytest.approx( 21.288, rel=1e-3) assert value(m.fs.stream[0].molality_comp["A"]) == pytest.approx(2.2829e-2, rel=1e-3) assert value(m.fs.stream[0].pressure_osm_phase["Liq"]) == pytest.approx( 60.546e5, rel=1e-3) assert value(m.fs.stream[0].dens_mass_phase["Liq"]) == pytest.approx( 1001.76, rel=1e-3) assert value(m.fs.stream[0].act_coeff_phase_comp["Liq", "A"]) == 1
def test_basic_scaling(): m = pyo.ConcreteModel() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.pp = PhysicalParameterTestBlock() # Set flag to include inherent reactions m.fs.pp._has_inherent_reactions = True m.fs.cv = ControlVolume1DBlock( default={ "property_package": m.fs.pp, "transformation_method": "dae.finite_difference", "transformation_scheme": "BACKWARD", "finite_elements": 10 }) m.fs.cv.add_geometry() m.fs.cv.add_state_blocks(has_phase_equilibrium=False) m.fs.cv.add_material_balances( balance_type=MaterialBalanceType.componentTotal, has_phase_equilibrium=False) m.fs.cv.add_energy_balances(balance_type=EnergyBalanceType.enthalpyTotal) m.fs.cv.add_momentum_balances( balance_type=MomentumBalanceType.pressureTotal, has_pressure_change=True) m.fs.cv.apply_transformation() iscale.calculate_scaling_factors(m) # check scaling on select variables assert iscale.get_scaling_factor(m.fs.cv.area) == 1 for (t, x), v in m.fs.cv.deltaP.items(): assert iscale.get_scaling_factor( v) == 1040 # 10x the properties pressure scaling factor for t in m.fs.time: for x in m.fs.cv.length_domain: assert iscale.get_scaling_factor( m.fs.cv.properties[t, x].flow_vol) == 100 # check scaling on mass, energy, and pressure balances. for c in m.fs.cv.material_balances.values(): # this uses the minimum material flow term scale assert iscale.get_constraint_transform_applied_scaling_factor(c) == 112 for c in m.fs.cv.enthalpy_balances.values(): # this uses the minimum enthalpy flow term scale assert iscale.get_constraint_transform_applied_scaling_factor(c) == 110 for c in m.fs.cv.pressure_balance.values(): # This uses the inlet pressure scale assert iscale.get_constraint_transform_applied_scaling_factor(c) == 104
def test_calculate_scaling(self, RO_frame): m = RO_frame 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 unscaled_var_list = list(unscaled_variables_generator(m)) assert len(unscaled_var_list) == 0 for _ in badly_scaled_var_generator(m): assert False
def test_complete_condense(): m = ConcreteModel() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.properties = props.WaterParameterBlock() m.fs.unit = Condenser(default={"property_package": m.fs.properties}) # 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.unit.control_volume.heat, 1e-6) iscale.calculate_scaling_factors(m) # state variables m.fs.unit.inlet.flow_mass_phase_comp[0, "Vap", "H2O"].fix(1) m.fs.unit.inlet.flow_mass_phase_comp[0, "Liq", "H2O"].fix(1e-8) m.fs.unit.inlet.temperature[0].fix(400) # K m.fs.unit.inlet.pressure[0].fix(0.5e5) # Pa m.fs.unit.outlet.temperature[0].fix(340) # K # solving assert_units_consistent(m) assert degrees_of_freedom(m) == 0 m.fs.unit.initialize() solver = get_solver() results = solver.solve(m, tee=False) assert_optimal_termination(results) assert pytest.approx(-2.4358e6, rel=1e-4) == value(m.fs.unit.control_volume.heat[0]) assert pytest.approx(1.0, rel=1e-4) == value( m.fs.unit.outlet.flow_mass_phase_comp[0, "Liq", "H2O"]) assert pytest.approx(1e-10, rel=1e-4) == value( m.fs.unit.outlet.flow_mass_phase_comp[0, "Vap", "H2O"]) assert pytest.approx(5.0e4, rel=1e-4) == value(m.fs.unit.outlet.pressure[0]) m.fs.unit.report() perf_dict = m.fs.unit._get_performance_contents() assert perf_dict == { "vars": { "Heat duty": m.fs.unit.control_volume.heat[0] } }
def test_initialize_unit(build_unit): m = build_unit # Set inputs # FLUE GAS Inlet NETL baseline report FGrate = 5109.76 # mol/s equivalent of ~1930.08 klb/hr m.fs.mole_frac_air = Param( m.fs.prop_fluegas.component_list, mutable=False, initialize={ "O2": 0.20784, "N2": 0.783994, "NO": 0.000001, "CO2": 0.000337339, "H2O": 0.0078267, "SO2": 0.000001, }, doc="mole fraction of air species", ) m.fs.unit.side_1_inlet.flow_mol_comp[0, "H2O"].fix(FGrate*8.69/100) m.fs.unit.side_1_inlet.flow_mol_comp[0, "CO2"].fix(FGrate*14.49/100) m.fs.unit.side_1_inlet.flow_mol_comp[0, "N2"].fix(FGrate*74.34/100) m.fs.unit.side_1_inlet.flow_mol_comp[0, "O2"].fix(FGrate*2.47/100) m.fs.unit.side_1_inlet.flow_mol_comp[0, "NO"].fix(FGrate*0.0006) m.fs.unit.side_1_inlet.flow_mol_comp[0, "SO2"].fix(FGrate*0.002) m.fs.unit.side_1_inlet.temperature[0].fix(650.335) m.fs.unit.side_1_inlet.pressure[0].fix(100145) for i in m.fs.prop_fluegas.component_list: m.fs.unit.side_2_inlet.flow_mol_comp[0, i].fix( FGrate * 0.6 * m.fs.mole_frac_air[i] ) for i in m.fs.prop_fluegas.component_list: m.fs.unit.side_3_inlet.flow_mol_comp[0, i].fix( FGrate * 0.4 * m.fs.mole_frac_air[i] ) m.fs.unit.side_2_inlet.temperature[0].fix(324.15) m.fs.unit.side_2_inlet.pressure[0].fix(100145) m.fs.unit.side_3_inlet.temperature[0].fix(373.15) m.fs.unit.side_3_inlet.pressure[0].fix(100145) iscale.calculate_scaling_factors(m) m.fs.unit.ua_side_2[0].fix(1.5e5) m.fs.unit.ua_side_3[0].fix(6.2e5) m.fs.unit.frac_heatloss.fix(0.05) m.fs.unit.deltaP_side_1[0].fix(-1000) m.fs.unit.deltaP_side_2[0].fix(-1000) m.fs.unit.deltaP_side_3[0].fix(-1000) assert degrees_of_freedom(m) == 0 initialization_tester(m, dof=0)
def test_scaling_inherent(self, inherent_reactions_config): model = inherent_reactions_config for i in model.fs.unit.control_volume.inherent_reaction_extent_index: scale = value( model.fs.unit.control_volume.properties_out[0.0].k_eq[ i[1]].expr) iscale.set_scaling_factor( model.fs.unit.control_volume.inherent_reaction_extent[0.0, i[1]], 10 / scale) iscale.constraint_scaling_transform( model.fs.unit.control_volume.properties_out[0.0]. inherent_equilibrium_constraint[i[1]], 0.1) # Next, try adding scaling for species min = 1e-3 for i in model.fs.unit.control_volume.properties_out[ 0.0].mole_frac_phase_comp: # i[0] = phase, i[1] = species if model.fs.unit.inlet.mole_frac_comp[0, i[1]].value > min: scale = model.fs.unit.inlet.mole_frac_comp[0, i[1]].value else: scale = min iscale.set_scaling_factor( model.fs.unit.control_volume.properties_out[0.0]. mole_frac_comp[i[1]], 10 / scale) iscale.set_scaling_factor( model.fs.unit.control_volume.properties_out[0.0]. mole_frac_phase_comp[i], 10 / scale) iscale.set_scaling_factor( model.fs.unit.control_volume.properties_out[0.0]. flow_mol_phase_comp[i], 10 / scale) iscale.constraint_scaling_transform( model.fs.unit.control_volume.properties_out[0.0]. component_flow_balances[i[1]], 10 / scale) iscale.constraint_scaling_transform( model.fs.unit.control_volume.material_balances[0.0, i[1]], 10 / scale) iscale.calculate_scaling_factors(model.fs.unit) assert isinstance(model.fs.unit.control_volume.scaling_factor, Suffix) assert isinstance( model.fs.unit.control_volume.properties_out[0.0].scaling_factor, Suffix) assert isinstance( model.fs.unit.control_volume.properties_in[0.0].scaling_factor, Suffix)
def test_default_scaling_factors(self, frame): # check that the calculate_scaling_factors method successfully copies # the default scaling factors to the scaling suffixes. If there are # no default scaling factors, this should pass iscale.calculate_scaling_factors(frame) #this also ensure, it doesn't except for v in frame.fs.props[1].component_data_objects( (Constraint, Var, Expression), descend_into=False): name = v.getname().split("[")[0] index = v.index() print(v) assert (iscale.get_scaling_factor(v) == frame.fs.props[1].config.parameters.get_default_scaling(name, index)) or ( frame.fs.props[1].config.parameters.get_default_scaling(name, index) is None)
def test_isentropic_comp_total_balances(self): m = ConcreteModel() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.properties = PhysicalParameterTestBlock() m.fs.unit = PressureChanger(default={ "property_package": m.fs.properties, "thermodynamic_assumption": ThermodynamicAssumption.isentropic, "material_balance_type": MaterialBalanceType.componentTotal}) iscale.calculate_scaling_factors(m) assert isinstance(m.fs.unit.state_material_balances, Constraint) assert len(m.fs.unit.state_material_balances) == 2
def test_initialize_drum1D(build_drum1D): m = build_drum1D iscale.calculate_scaling_factors(m) state_args_water_steam = {'flow_mol': 14409.02, # mol/s 'pressure': 12024201.99, # Pa 'enth_mol': 28365.2608} # j/mol state_args_feedwater = {'flow_mol': 11554.58, 'pressure': 12024201.99, 'enth_mol': 22723.907} initialization_tester(build_drum1D, dof=5, state_args_water_steam=state_args_water_steam, state_args_feedwater=state_args_feedwater)
def build_translator_from_RO_to_chlorination_block(model): # Translator inlet from RO and outlet goes to chlorination model.fs.RO_to_Chlor = Translator( default={ "inlet_property_package": model.fs.prop_TDS, "outlet_property_package": model.fs.ideal_naocl_thermo_params }) # Add constraints to define how the translator will function model.fs.RO_to_Chlor.eq_equal_temperature = Constraint( expr=model.fs.RO_to_Chlor.inlet.temperature[0] == model.fs.RO_to_Chlor.outlet.temperature[0]) model.fs.RO_to_Chlor.eq_equal_pressure = Constraint( expr=model.fs.RO_to_Chlor.inlet.pressure[0] == model.fs.RO_to_Chlor.outlet.pressure[0]) model.fs.RO_to_Chlor.total_flow_cons = Constraint( expr=model.fs.RO_to_Chlor.outlet.flow_mol[0] == (model.fs.RO_to_Chlor.inlet.flow_mass_phase_comp[0, 'Liq', 'H2O'] / 18e-3) + (model.fs.RO_to_Chlor.inlet.flow_mass_phase_comp[0, 'Liq', 'TDS'] / 58.4e-3)) model.fs.RO_to_Chlor.H_con = Constraint( expr=model.fs.RO_to_Chlor.outlet.mole_frac_comp[0, "H_+"] == 0) model.fs.RO_to_Chlor.OH_con = Constraint( expr=model.fs.RO_to_Chlor.outlet.mole_frac_comp[0, "OH_-"] == 0) model.fs.RO_to_Chlor.HOCl_con = Constraint( expr=model.fs.RO_to_Chlor.outlet.mole_frac_comp[0, "HOCl"] == 0) model.fs.RO_to_Chlor.OCl_con = Constraint( expr=model.fs.RO_to_Chlor.outlet.mole_frac_comp[0, "OCl_-"] == 0) model.fs.RO_to_Chlor.Cl_con = Constraint( expr=model.fs.RO_to_Chlor.outlet.mole_frac_comp[0, "Cl_-"] == (model.fs.RO_to_Chlor.inlet.flow_mass_phase_comp[0, 'Liq', 'TDS'] / 58.4e-3) / model.fs.RO_to_Chlor.outlet.flow_mol[0]) model.fs.RO_to_Chlor.Na_con = Constraint( expr=model.fs.RO_to_Chlor.outlet.mole_frac_comp[0, "Na_+"] == (model.fs.RO_to_Chlor.inlet.flow_mass_phase_comp[0, 'Liq', 'TDS'] / 58.4e-3) / model.fs.RO_to_Chlor.outlet.flow_mol[0] + model.fs.RO_to_Chlor.outlet.mole_frac_comp[0, "OCl_-"]) model.fs.RO_to_Chlor.H2O_con = Constraint( expr=model.fs.RO_to_Chlor.outlet.mole_frac_comp[0, "H2O"] == 1 - sum(model.fs.RO_to_Chlor.outlet.mole_frac_comp[0, j] for j in ["H_+", "OH_-", "HOCl", "OCl_-", "Cl_-", "Na_+"])) iscale.calculate_scaling_factors(model.fs.RO_to_Chlor)
def test_full_auto_scaling_dynamic(): m = pyo.ConcreteModel() m.fs = FlowsheetBlock(default={"dynamic": True, "time_units": pyo.units.s}) m.fs.pp = PhysicalParameterTestBlock() m.fs.rp = ReactionParameterTestBlock(default={"property_package": m.fs.pp}) m.fs.cv = ControlVolume1DBlock( default={ "property_package": m.fs.pp, "reaction_package": m.fs.rp, "transformation_method": "dae.finite_difference", "transformation_scheme": "BACKWARD", "finite_elements": 10 }) m.fs.cv.add_geometry() m.fs.cv.add_state_blocks(has_phase_equilibrium=True) m.fs.cv.add_reaction_blocks(has_equilibrium=True) m.fs.cv.add_material_balances( balance_type=MaterialBalanceType.componentTotal, has_rate_reactions=True, has_equilibrium_reactions=True, has_phase_equilibrium=True, has_mass_transfer=True) m.fs.cv.add_energy_balances(balance_type=EnergyBalanceType.enthalpyTotal, has_heat_of_reaction=True, has_heat_transfer=True, has_work_transfer=True, has_enthalpy_transfer=True) m.fs.cv.add_momentum_balances( balance_type=MomentumBalanceType.pressureTotal, has_pressure_change=True) m.fs.cv.apply_transformation() m.discretizer = pyo.TransformationFactory('dae.finite_difference') m.discretizer.apply_to(m, nfe=3, wrt=m.fs.time, scheme="BACKWARD") iscale.calculate_scaling_factors(m) # check that all variables have scaling factors unscaled_var_list = list(iscale.unscaled_variables_generator(m)) # Unscaled variables are: # rate_reaction_extent (2 reactions, 44 time & space points) # equilibrium_reaction_extent (2 reactions, 44 time & space points) assert len(unscaled_var_list) == 176 # check that all constraints have been scaled unscaled_constraint_list = list(iscale.unscaled_constraints_generator(m)) assert len(unscaled_constraint_list) == 0
def model(self): m = ConcreteModel() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.liquid_properties = GenericParameterBlock(default=aqueous_mea) m.fs.vapor_properties = GenericParameterBlock(default=wet_co2) m.fs.unit = SolventCondenser( default={ "liquid_property_package": m.fs.liquid_properties, "vapor_property_package": m.fs.vapor_properties }) m.fs.unit.inlet.flow_mol[0].fix(1.1117) m.fs.unit.inlet.temperature[0].fix(339.33) m.fs.unit.inlet.pressure[0].fix(184360) m.fs.unit.inlet.mole_frac_comp[0, "CO2"].fix(0.8817) m.fs.unit.inlet.mole_frac_comp[0, "H2O"].fix(0.1183) m.fs.unit.reflux.flow_mol[0].fix(0.1083) iscale.set_scaling_factor( m.fs.unit.vapor_phase.mass_transfer_term[0, "Vap", "CO2"], 1e4) iscale.set_scaling_factor( m.fs.unit.vapor_phase.mass_transfer_term[0, "Vap", "H2O"], 10) iscale.set_scaling_factor( m.fs.unit.vapor_phase.properties_out[0].pressure, 1e-5) iscale.set_scaling_factor( m.fs.unit.vapor_phase.properties_out[0].fug_phase_comp["Vap", "CO2"], 1e-5) iscale.set_scaling_factor( m.fs.unit.vapor_phase.properties_out[0].fug_phase_comp["Vap", "H2O"], 1e-3) iscale.set_scaling_factor( m.fs.unit.vapor_phase.properties_out[0].temperature, 1e-2) iscale.set_scaling_factor( m.fs.unit.vapor_phase.properties_out[0].enth_mol_phase["Vap"], 1e-3) iscale.set_scaling_factor(m.fs.unit.vapor_phase.enthalpy_transfer[0], 1e-3) iscale.calculate_scaling_factors(m.fs.unit) return m
def solve_SepRO(base="TDS"): m = ConcreteModel() m.fs = FlowsheetBlock(default={"dynamic": False}) property_models.build_prop(m, base=base) build_SepRO(m, base=base) property_models.specify_feed(m.fs.RO.mixed_state[0], base=base) check_dof(m) calculate_scaling_factors(m) solve_block(m) m.fs.RO.inlet.display() m.fs.RO.permeate.display() m.fs.RO.retentate.display() return m
def build_tb(m): # build translator block m.fs.tb_pretrt_to_desal = Translator( default={"inlet_property_package": m.fs.stoich_softening_thermo_params, "outlet_property_package": m.fs.prop_TDS}) blk = m.fs.tb_pretrt_to_desal # add translator block constraints blk.eq_equal_temperature = Constraint( expr=blk.properties_in[0].temperature == blk.properties_out[0].temperature) blk.eq_equal_pressure = Constraint( expr=blk.properties_in[0].pressure == blk.properties_out[0].pressure) blk.eq_H2O_balance = Constraint( expr=blk.properties_in[0].flow_mol * blk.properties_in[0].mole_frac_comp['H2O'] == blk.properties_out[0].flow_mol_phase_comp['Liq', 'H2O']) mw_comp = {'H2O': 18.015e-3, 'Na': 22.990e-3, 'Ca': 40.078e-3, 'Mg': 24.305e-3, 'SO4': 96.06e-3, 'Cl': 35.453e-3} # TODO: this does not catch the Cl that is not associated with with Na blk.eq_TDS_balance = Constraint( expr= blk.properties_out[0].flow_mass_phase_comp['Liq', 'TDS'] == blk.properties_in[0].flow_mol * blk.properties_in[0].mole_frac_comp['Ca(HCO3)2'] * mw_comp['Ca'] + blk.properties_in[0].flow_mol * blk.properties_in[0].mole_frac_comp['Mg(HCO3)2'] * mw_comp['Mg'] + blk.properties_in[0].flow_mol * blk.properties_in[0].mole_frac_comp['NaCl'] * (mw_comp['Na'] + mw_comp['Cl']) + blk.properties_in[0].flow_mol * blk.properties_in[0].mole_frac_comp['Cl_-'] * mw_comp['Cl'] + blk.properties_in[0].flow_mol * blk.properties_in[0].mole_frac_comp['SO4_2-'] * mw_comp['SO4'] ) # scale translator block to get scaling factors calculate_scaling_factors(blk) constraint_scaling_transform(blk.eq_equal_temperature, get_scaling_factor(blk.properties_out[0].temperature)) constraint_scaling_transform(blk.eq_equal_pressure, get_scaling_factor(blk.properties_out[0].pressure)) constraint_scaling_transform(blk.eq_H2O_balance, get_scaling_factor(blk.properties_out[0].flow_mol_phase_comp['Liq', 'H2O'])) constraint_scaling_transform( blk.eq_TDS_balance, get_scaling_factor(blk.properties_out[0].flow_mass_phase_comp['Liq', 'TDS'])) # touch variables blk.properties_out[0].mass_frac_phase_comp
def test_scaling_stoich(self, water_stoich): m = water_stoich # Next, try adding scaling for species min = 1e-3 for i in m.fs.unit.control_volume.properties_out[0.0].mole_frac_phase_comp: # i[0] = phase, i[1] = species if m.fs.unit.inlet.mole_frac_comp[0, i[1]].value > min: scale = m.fs.unit.inlet.mole_frac_comp[0, i[1]].value else: scale = min iscale.set_scaling_factor( m.fs.unit.control_volume.properties_out[0.0].mole_frac_comp[i[1]], 10 / scale, ) iscale.set_scaling_factor( m.fs.unit.control_volume.properties_out[0.0].mole_frac_phase_comp[i], 10 / scale, ) iscale.set_scaling_factor( m.fs.unit.control_volume.properties_out[0.0].flow_mol_phase_comp[i], 10 / scale, ) iscale.constraint_scaling_transform( m.fs.unit.control_volume.properties_out[0.0].component_flow_balances[ i[1] ], 10 / scale, ) iscale.constraint_scaling_transform( m.fs.unit.control_volume.material_balances[0.0, i[1]], 10 / scale ) iscale.set_scaling_factor( m.fs.unit.control_volume.rate_reaction_extent[0.0, "R1"], 1 ) iscale.calculate_scaling_factors(m.fs.unit) assert isinstance(m.fs.unit.control_volume.scaling_factor, Suffix) assert isinstance( m.fs.unit.control_volume.properties_out[0.0].scaling_factor, Suffix ) assert isinstance( m.fs.unit.control_volume.properties_in[0.0].scaling_factor, Suffix )
def solve_ZONF(base="ion"): m = ConcreteModel() m.fs = FlowsheetBlock(default={"dynamic": False}) property_models.build_prop(m, base=base) build_ZONF(m, base=base) property_models.specify_feed(m.fs.NF.feed_side.properties_in[0], base="ion") check_dof(m) calculate_scaling_factors(m) solve_block(m) m.fs.NF.inlet.display() m.fs.NF.permeate.display() m.fs.NF.retentate.display() return m
def solve_SepNF(base="ion"): m = ConcreteModel() m.fs = FlowsheetBlock(default={"dynamic": False}) property_models.build_prop(m, base=base) build_SepNF(m, base=base) property_models.specify_feed(m.fs.NF.mixed_state[0], base=base) m.fs.NF.mixed_state[0].mass_frac_phase_comp # touching for tests check_dof(m) calculate_scaling_factors(m) solve_block(m) m.fs.NF.inlet.display() m.fs.NF.permeate.display() m.fs.NF.retentate.display() return m
def test_scaling(self, frame): m = frame set_scaling_factor(m.fs.stream[0].flow_mass_phase_comp['Liq', 'H2O'], 1) set_scaling_factor(m.fs.stream[0].flow_mass_phase_comp['Liq', 'TDS'], 1e2) calculate_scaling_factors(m.fs) # check that all variables have scaling factors unscaled_var_list = list(unscaled_variables_generator(m)) assert len(unscaled_var_list) == 0 # check that all constraints have been scaled unscaled_constraint_list = list(unscaled_constraints_generator(m)) assert len(unscaled_constraint_list) == 0 # check if any variables are badly scaled badly_scaled_var_list = list(badly_scaled_var_generator(m)) assert len(badly_scaled_var_list) == 0
def test_scaling(self, coag_obj_w_chems): model = coag_obj_w_chems # Set some scaling factors and look for 'bad' scaling model.fs.properties.set_default_scaling("flow_mass_phase_comp", 1, index=("Liq", "H2O")) model.fs.properties.set_default_scaling("flow_mass_phase_comp", 1e2, index=("Liq", "TSS")) model.fs.properties.set_default_scaling("flow_mass_phase_comp", 1e2, index=("Liq", "TDS")) model.fs.properties.set_default_scaling("flow_mass_phase_comp", 1e2, index=("Liq", "Sludge")) # set scaling factors for performance iscale.set_scaling_factor(model.fs.unit.rapid_mixing_retention_time, 1e-1) iscale.set_scaling_factor(model.fs.unit.num_rapid_mixing_basins, 1) iscale.set_scaling_factor(model.fs.unit.rapid_mixing_vel_grad, 1e-2) iscale.set_scaling_factor(model.fs.unit.floc_retention_time, 1e-3) iscale.set_scaling_factor(model.fs.unit.single_paddle_length, 1) iscale.set_scaling_factor(model.fs.unit.single_paddle_width, 1) iscale.set_scaling_factor(model.fs.unit.paddle_rotational_speed, 10) iscale.set_scaling_factor(model.fs.unit.paddle_drag_coef, 1) iscale.set_scaling_factor(model.fs.unit.vel_fraction, 1) iscale.set_scaling_factor(model.fs.unit.num_paddle_wheels, 1) iscale.set_scaling_factor(model.fs.unit.num_paddles_per_wheel, 1) iscale.calculate_scaling_factors(model.fs) # check that all variables have scaling factors unscaled_var_list = list(iscale.unscaled_variables_generator(model)) assert len(unscaled_var_list) == 0 # check if any variables are badly scaled badly_scaled_var_values = { var.name: val for (var, val) in iscale.badly_scaled_var_generator( model, large=1e2, small=1e-2) } assert not badly_scaled_var_values
def test_scaling_inherent(self, inherent_reactions_config): model = inherent_reactions_config iscale.calculate_scaling_factors(model.fs.unit) assert hasattr(model.fs.unit.control_volume, 'scaling_factor') assert isinstance(model.fs.unit.control_volume.scaling_factor, Suffix) assert hasattr(model.fs.unit.control_volume.properties_out[0.0], 'scaling_factor') assert isinstance( model.fs.unit.control_volume.properties_out[0.0].scaling_factor, Suffix) assert hasattr(model.fs.unit.control_volume.properties_in[0.0], 'scaling_factor') assert isinstance( model.fs.unit.control_volume.properties_in[0.0].scaling_factor, Suffix)