def test_find_badly_scaled_vars():
    m = pyo.ConcreteModel()
    m.x = pyo.Var(initialize=1e6)
    m.y = pyo.Var(initialize=1e-8)
    m.z = pyo.Var(initialize=1e-20)
    m.b = pyo.Block()
    m.b.w = pyo.Var(initialize=1e10)

    a = [id(v) for v, sv in sc.badly_scaled_var_generator(m)]
    assert id(m.x) in a
    assert id(m.y) in a
    assert id(m.b.w) in a
    assert id(m.z) not in a

    m.scaling_factor = pyo.Suffix(direction=pyo.Suffix.EXPORT)
    m.b.scaling_factor = pyo.Suffix(direction=pyo.Suffix.EXPORT)
    m.scaling_factor[m.x] = 1e-6
    m.scaling_factor[m.y] = 1e6
    m.scaling_factor[m.z] = 1
    m.b.scaling_factor[m.b.w] = 1e-5

    a = [id(v) for v, sv in sc.badly_scaled_var_generator(m)]
    assert id(m.x) not in a
    assert id(m.y) not in a
    assert id(m.b.w) in a
    assert id(m.z) not in a
    def test_scaling(self, coag_obj_wo_chems):
        model = coag_obj_wo_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"))

        # Here we are skipping setting scaling factors for performance to test the
        #   effectiveness of the defaults AND get better test coverage

        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)
        }
        print(iscale.get_scaling_factor(model.fs.unit.tss_loss_rate))
        assert not badly_scaled_var_values
Exemple #3
0
def test_scaling(model3):
    m = model3
    metadata = m.fs.properties.get_metadata().properties

    for v_name in metadata:
        getattr(m.fs.stream[0], v_name)

    calculate_scaling_factors(m)

    # check that all variables have scaling factors
    unscaled_var_list = list(unscaled_variables_generator(m))
    [print(i) for i in unscaled_var_list]
    assert len(unscaled_var_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

    # check that all constraints have been scaled
    unscaled_constraint_list = list(unscaled_constraints_generator(m))
    [print(i) for i in unscaled_constraint_list]

    assert len(unscaled_constraint_list) == 0

    # m.fs.stream[0].scaling_factor.display()
    for j in m.fs.properties.config.solute_list:
        assert get_scaling_factor(m.fs.stream[0].mw_comp[j]) is not None
        assert (get_scaling_factor(m.fs.stream[0].diffus_phase_comp["Liq", j])
                is not None)
        assert (get_scaling_factor(m.fs.stream[0].act_coeff_phase_comp["Liq",
                                                                       j])
                is not None)
    assert get_scaling_factor(
        m.fs.stream[0].dens_mass_phase["Liq"]) is not None
    assert get_scaling_factor(m.fs.stream[0].visc_d_phase["Liq"]) is not None
    def test_scaling_equilibrium(self, equilibrium_config):
        model = equilibrium_config

        # Call scaling factor helper functions
        _set_equ_rxn_scaling(model.fs.unit, reaction_config)
        _set_mat_bal_scaling_FpcTP(model.fs.unit)
        _set_ene_bal_scaling(model.fs.unit)

        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)

        # When using equilibrium reactions, there are another set of scaling factors calculated
        assert isinstance(
            model.fs.unit.control_volume.reactions[0.0].scaling_factor, Suffix)

        # 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=1e4, small=1e-2)
        }
        assert not badly_scaled_var_values
    def test_scaling(self, coag_obj_wo_chems):
        model = coag_obj_wo_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'))
        #iscale.set_scaling_factor(model.fs.unit.tss_loss_rate, 100)
        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)
        }
        print(iscale.get_scaling_factor(model.fs.unit.tss_loss_rate))
        assert not badly_scaled_var_values
    def test_scaling(self, coag_obj):
        model = coag_obj

        # 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",
                                                1e3,
                                                index=("Liq", "Sludge"))
        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 that all constraints have been scaled
        unscaled_constraint_list = list(
            iscale.unscaled_constraints_generator(model))
        assert len(unscaled_constraint_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_default_scaling(self, coag_obj_fail):
        model = coag_obj_fail

        model.fs.stream = model.fs.properties.build_state_block([0],
                                                                default={})

        # call scaling without setting defaults
        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 that all constraints have been scaled
        unscaled_constraint_list = list(
            iscale.unscaled_constraints_generator(model))
        assert len(unscaled_constraint_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_calculate_state(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)

        # touch all properties in var_args
        for (v_name, ind), val in self.var_args.items():
            getattr(m.fs.stream[0], v_name)

        # scale model
        calculate_scaling_factors(m)

        # calculate state
        results = m.fs.stream.calculate_state(var_args=self.var_args,
                                              solver=self.solver,
                                              optarg=self.optarg)
        assert_optimal_termination(results)

        # check results
        for (v_name, ind), val in self.state_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 state_solution in the configure function "
                        "that sets up the PropertyCalculateStateTest".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 state_solution in the configure function "
                    "that sets up the PropertyCalculateStateTest".format(
                        v_name=v_name, ind=ind, val=val, val_t=value(var)))

        # check if any variables are badly scaled
        lst = []
        for (var, val) in badly_scaled_var_generator(m,
                                                     large=1e2,
                                                     small=1e-2,
                                                     zero=1e-8):
            lst.append((var.name, val))
            print(var.name, var.value)
        if lst:
            raise PropertyValueError(
                "The following variable(s) are poorly scaled: {lst}".format(
                    lst=lst))
Exemple #9
0
 def test_solve(self, electrodialysis_cell3):
     m = electrodialysis_cell3
     # run solver and check for optimal solution
     results = solver.solve(m)
     assert_optimal_termination(results)
     badly_scaled_var_values = {
         var.name: val
         for (var, val) in iscale.badly_scaled_var_generator(m)
     }
     assert not badly_scaled_var_values
 def test_badly_scaled(self, frame_stateblock):
     m = frame_stateblock
     badly_scaled_var_list = list(
         badly_scaled_var_generator(m, large=1e2, small=1e-2, zero=1e-8))
     if len(badly_scaled_var_list) != 0:
         lst = []
         for (var, val) in badly_scaled_var_list:
             lst.append((var.name, val))
         raise PropertyValueError(
             "The following variable(s) are poorly scaled: {lst}".format(
                 lst=lst))
Exemple #11
0
    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_solve(self, coag_obj_wo_chems):
        model = coag_obj_wo_chems

        # first, check to make sure that after initialized, the scaling is still good
        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

        # run solver and check for optimal solution
        results = solver.solve(model)
        assert_optimal_termination(results)
    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(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
Exemple #15
0
    def test_calculate_scaling(self, NF_frame):
        m = NF_frame

        m.fs.properties.set_default_scaling("flow_mol_phase_comp",
                                            1e5,
                                            index=("Liq", "Ca_2+"))
        m.fs.properties.set_default_scaling("flow_mol_phase_comp",
                                            1e5,
                                            index=("Liq", "SO4_2-"))

        calculate_scaling_factors(m)

        # check that all variables have scaling factors
        unscaled_var_list = list(unscaled_variables_generator(m.fs.unit))
        assert len(unscaled_var_list) == 0

        badly_scaled_var_lst = list(
            badly_scaled_var_generator(m, include_fixed=True))
        assert len(unscaled_var_list) == 0
Exemple #16
0
 def test_initialization_scaling(self, electrodialysis_cell2):
     m = electrodialysis_cell2
     # set default scaling for state vars
     m.fs.properties.set_default_scaling("flow_mol_phase_comp",
                                         1e2,
                                         index=("Liq", "H2O"))
     m.fs.properties.set_default_scaling("flow_mol_phase_comp",
                                         1e4,
                                         index=("Liq", "Na_+"))
     m.fs.properties.set_default_scaling("flow_mol_phase_comp",
                                         1e4,
                                         index=("Liq", "Cl_-"))
     iscale.calculate_scaling_factors(m.fs)
     initialization_tester(m)
     badly_scaled_var_values = {
         var.name: val
         for (var, val) in iscale.badly_scaled_var_generator(m)
     }
     assert not badly_scaled_var_values
     # check to make sure DOF does not change
     assert degrees_of_freedom(m) == 0
    def test_calculate_scaling(self, Crystallizer_frame):
        m = Crystallizer_frame

        m.fs.properties.set_default_scaling("flow_mass_phase_comp",
                                            1e-1,
                                            index=("Liq", "H2O"))
        m.fs.properties.set_default_scaling("flow_mass_phase_comp",
                                            1e-1,
                                            index=("Liq", "NaCl"))
        m.fs.properties.set_default_scaling("flow_mass_phase_comp",
                                            1e-1,
                                            index=("Vap", "H2O"))
        m.fs.properties.set_default_scaling("flow_mass_phase_comp",
                                            1e-1,
                                            index=("Sol", "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_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
        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

        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)

        # test statistics
        assert number_variables(m) == 115
        assert number_total_constraints(m) == 86
        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

        # check that all constraints have been scaled
        unscaled_constraint_list = list(unscaled_constraints_generator(m))
        assert len(unscaled_constraint_list) == 0

        # test initialization
        initialization_tester(m)

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

        # test solve
        solver.options = {'nlp_scaling_method': 'user-scaling'}
        results = solver.solve(m, tee=True)

        # Check for optimal solution
        assert results.solver.termination_condition == \
               TerminationCondition.optimal
        assert results.solver.status == SolverStatus.ok

        # test solution
        assert (pytest.approx(-9.173e5,
                              rel=1e-3) == value(m.fs.unit.deltaP[0]))
        assert (pytest.approx(1.904e-3, rel=1e-3) == value(
            m.fs.unit.flux_mass_phase_comp_avg[0, 'Liq', 'H2O']))
        assert (pytest.approx(1.727e-6, rel=1e-3) == value(
            m.fs.unit.flux_mass_phase_comp_avg[0, 'Liq', 'NaCl']))
        assert (pytest.approx(0.0952, rel=1e-3) == value(
            m.fs.unit.properties_permeate[0].flow_mass_phase_comp['Liq',
                                                                  'H2O']))
        assert (pytest.approx(8.637e-5, rel=1e-3) == value(
            m.fs.unit.properties_permeate[0].flow_mass_phase_comp['Liq',
                                                                  'NaCl']))
        assert (pytest.approx(35.751, rel=1e-3) == value(
            m.fs.unit.feed_side.properties_in[0].conc_mass_phase_comp['Liq',
                                                                      'NaCl']))
        assert (pytest.approx(53.561, rel=1e-3) == value(
            m.fs.unit.feed_side.properties_interface_in[0].
            conc_mass_phase_comp['Liq', 'NaCl']))
        assert (pytest.approx(39.524, rel=1e-3) == value(
            m.fs.unit.feed_side.properties_out[0].conc_mass_phase_comp['Liq',
                                                                       'NaCl'])
                )
        assert (pytest.approx(
            46.958, rel=1e-3
        ) ==  # TODO: expected this value to be higher than interface concentration at inlet, but bypassing for now- has to do with pressure drop
                value(m.fs.unit.feed_side.properties_interface_out[0].
                      conc_mass_phase_comp['Liq', 'NaCl']))
Exemple #19
0
def test_seawater_data():
    m = ConcreteModel()
    m.fs = FlowsheetBlock(default={'dynamic': False})
    m.fs.properties = DSPMDEParameterBlock(
        default={
            "solute_list": ["Ca_2+", "SO4_2-", "Na_+", "Cl_-", "Mg_2+"],
            "diffusivity_data": {
                ("Liq", "Ca_2+"): 0.792e-9,
                ("Liq", "SO4_2-"): 1.06e-9,
                ("Liq", "Na_+"): 1.33e-9,
                ("Liq", "Cl_-"): 2.03e-9,
                ("Liq", "Mg_2+"): 0.706e-9
            },
            "mw_data": {
                "H2O": 18e-3,
                "Na_+": 23e-3,
                "Ca_2+": 40e-3,
                "Mg_2+": 24e-3,
                "Cl_-": 35e-3,
                "SO4_2-": 96e-3
            },
            "stokes_radius_data": {
                "Na_+": 0.184e-9,
                "Ca_2+": 0.309e-9,
                "Mg_2+": 0.347e-9,
                "Cl_-": 0.121e-9,
                "SO4_2-": 0.230e-9
            },
            "charge": {
                "Na_+": 1,
                "Ca_2+": 2,
                "Mg_2+": 2,
                "Cl_-": -1,
                "SO4_2-": -2
            },
        })

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

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

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

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

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

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

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

    assert_units_consistent(m)

    check_dof(m, fail_flag=True)

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

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

    stream.initialize()

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

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

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

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

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

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

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

    assert value(stream[0].mass_frac_phase_comp['Liq',
                                                'Na_+']) == pytest.approx(
                                                    1.112e-2, rel=1e-3)
    assert value(stream[0].mass_frac_phase_comp['Liq',
                                                'Cl_-']) == pytest.approx(
                                                    2.03e-2, rel=1e-3)
    assert value(stream[0].mass_frac_phase_comp['Liq',
                                                'Ca_2+']) == pytest.approx(
                                                    3.82e-4, rel=1e-3)
    assert value(stream[0].mass_frac_phase_comp['Liq',
                                                'SO4_2-']) == pytest.approx(
                                                    2.136e-3, rel=1e-3)
    assert value(stream[0].mass_frac_phase_comp['Liq',
                                                'Mg_2+']) == pytest.approx(
                                                    1.394e-3, rel=1e-3)
        "H2O":0.0,
        "CO2":0.0034,
        "N2":0.0361,
        "Ar":0.0,
        "SO2":0.0}

    m, solver = main(
        comps=comps,
        rxns=rxns,
        phases=phases,
        air_comp=air_comp,
        ng_comp=ng_comp)
    run_full_load(m, solver)
    #iscale.constraint_autoscale_large_jac(m)
    jac, nlp = iscale.get_jacobian(m, scaled=True)
    print("Extreme Jacobian entries:")
    for i in iscale.extreme_jacobian_entries(jac=jac, nlp=nlp, large=100):
        print(f"    {i[0]:.2e}, [{i[1]}, {i[2]}]")
    print("Unscaled constraints:")
    for c in iscale.unscaled_constraints_generator(m):
        print(f"    {c}")
    print("Scaled constraints by factor:")
    for c, s in iscale.constraints_with_scale_factor_generator(m):
        print(f"    {c}, {s}")
    print("Badly scaled variables:")
    for v, sv in iscale.badly_scaled_var_generator(m, large=1e2, small=1e-2, zero=1e-12):
        print(f"    {v} -- {sv} -- {iscale.get_scaling_factor(v)}")
    print(f"Jacobian Condition Number: {iscale.jacobian_cond(jac=jac):.2e}")
    write_pfd_results("gas_turbine_results.svg", m.tags, m.tag_format)
    #run_series(m, solver)
Exemple #21
0
    def test_CP_calculation_with_kf_fixed(self):
        """ Testing 0D-RO with ConcentrationPolarizationType.calculated option enabled.
        This option makes use of an alternative constraint for the feed-side, membrane-interface concentration.
        Additionally, two more variables are created when this option is enabled: Kf - feed-channel
        mass transfer coefficients at the channel inlet and outlet.
        """
        m = ConcreteModel()
        m.fs = FlowsheetBlock(default={"dynamic": False})

        m.fs.properties = props.NaClParameterBlock()

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

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

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

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

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

        # test scaling
        m.fs.properties.set_default_scaling('flow_mass_phase_comp', 1, index=('Liq', 'H2O'))
        m.fs.properties.set_default_scaling('flow_mass_phase_comp', 1e2, index=('Liq', 'NaCl'))
        calculate_scaling_factors(m)

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

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

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

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

        # test solve
        results = solver.solve(m)

        # Check for optimal solution
        assert_optimal_termination(results)

        # test solution
        assert (pytest.approx(3.815e-3, rel=1e-3) ==
                value(m.fs.unit.flux_mass_phase_comp_avg[0, 'Liq', 'H2O']))
        assert (pytest.approx(1.668e-6, rel=1e-3) ==
                value(m.fs.unit.flux_mass_phase_comp_avg[0, 'Liq', 'NaCl']))
        assert (pytest.approx(0.1908, rel=1e-3) ==
                value(m.fs.unit.mixed_permeate[0].flow_mass_phase_comp['Liq', 'H2O']))
        assert (pytest.approx(8.337e-5, rel=1e-3) ==
                value(m.fs.unit.mixed_permeate[0].flow_mass_phase_comp['Liq', 'NaCl']))
        assert (pytest.approx(46.07, rel=1e-3) ==
                value(m.fs.unit.feed_side.properties_interface[0, 0.].conc_mass_phase_comp['Liq', 'NaCl']))
        assert (pytest.approx(44.34, rel=1e-3) ==
                value(m.fs.unit.feed_side.properties_out[0].conc_mass_phase_comp['Liq', 'NaCl']))
        assert (pytest.approx(50.20, rel=1e-3) ==
                value(m.fs.unit.feed_side.properties_interface[0, 1.].conc_mass_phase_comp['Liq', 'NaCl']))
Exemple #22
0
    def test_Pdrop_fixed_per_unit_length(self):
        """ Testing 0D-RO with PressureChangeType.fixed_per_unit_length option.
        """
        m = ConcreteModel()
        m.fs = FlowsheetBlock(default={"dynamic": False})

        m.fs.properties = props.NaClParameterBlock()

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

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

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

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

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

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

        # test scaling
        m.fs.properties.set_default_scaling('flow_mass_phase_comp', 1, index=('Liq', 'H2O'))
        m.fs.properties.set_default_scaling('flow_mass_phase_comp', 1e2, index=('Liq', 'NaCl'))

        calculate_scaling_factors(m)

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

        # test initialization
        initialization_tester(m, fail_on_warning=True)

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

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

        # Check for optimal solution
        assert_optimal_termination(results)

        # test solution
        assert (pytest.approx(-3.000e5, rel=1e-3) == value(m.fs.unit.deltaP[0]))
        assert (pytest.approx(4.562e-3, rel=1e-3) ==
                value(m.fs.unit.flux_mass_phase_comp_avg[0, 'Liq', 'H2O']))
        assert (pytest.approx(1.593e-6, rel=1e-3) ==
                value(m.fs.unit.flux_mass_phase_comp_avg[0, 'Liq', 'NaCl']))
        assert (pytest.approx(0.2281, rel=1e-3) ==
                value(m.fs.unit.mixed_permeate[0].flow_mass_phase_comp['Liq', 'H2O']))
        assert (pytest.approx(7.963e-5, rel=1e-3) ==
                value(m.fs.unit.mixed_permeate[0].flow_mass_phase_comp['Liq', 'NaCl']))
        assert (pytest.approx(41.96, rel=1e-3) ==
                value(m.fs.unit.feed_side.properties_interface[0,0.].conc_mass_phase_comp['Liq', 'NaCl']))
        assert (pytest.approx(46.57, rel=1e-3) ==
                value(m.fs.unit.feed_side.properties_out[0].conc_mass_phase_comp['Liq', 'NaCl']))
        assert (pytest.approx(49.94, rel=1e-3) ==
                value(m.fs.unit.feed_side.properties_interface[0, 1.].conc_mass_phase_comp['Liq', 'NaCl']))
Exemple #23
0
 def test_var_scaling(self, NF_frame):
     m = NF_frame
     badly_scaled_var_lst = list(badly_scaled_var_generator(m))
     assert badly_scaled_var_lst == []
Exemple #24
0
 def test_repeated_scaling(self, RO_frame):
     # check repeated scaling does not create badly scaled vars
     calculate_scaling_factors(RO_frame)
     for _ in badly_scaled_var_generator(RO_frame):
         assert False
Exemple #25
0
def test_seawater_data():
    m = ConcreteModel()
    m.fs = FlowsheetBlock(default={"dynamic": False})
    m.fs.properties = DSPMDEParameterBlock(
        default={
            "solute_list": ["Ca_2+", "SO4_2-", "Na_+", "Cl_-", "Mg_2+"],
            "diffusivity_data": {
                ("Liq", "Ca_2+"): 0.792e-9,
                ("Liq", "SO4_2-"): 1.06e-9,
                ("Liq", "Na_+"): 1.33e-9,
                ("Liq", "Cl_-"): 2.03e-9,
                ("Liq", "Mg_2+"): 0.706e-9,
            },
            "mw_data": {
                "H2O": 18e-3,
                "Na_+": 23e-3,
                "Ca_2+": 40e-3,
                "Mg_2+": 24e-3,
                "Cl_-": 35e-3,
                "SO4_2-": 96e-3,
            },
            "electrical_mobility_data": {
                "Na_+": 5.19e-8,
                "Ca_2+": 6.17e-8,
                "Mg_2+": 5.50e-8,
                "Cl_-": 7.92e-8,
                "SO4_2-": 8.29e-8,
            },
            "stokes_radius_data": {
                "Na_+": 0.184e-9,
                "Ca_2+": 0.309e-9,
                "Mg_2+": 0.347e-9,
                "Cl_-": 0.121e-9,
                "SO4_2-": 0.230e-9,
            },
            "charge": {
                "Na_+": 1,
                "Ca_2+": 2,
                "Mg_2+": 2,
                "Cl_-": -1,
                "SO4_2-": -2
            },
            "density_calculation": DensityCalculation.seawater,
            "activity_coefficient_model": ActivityCoefficientModel.davies,
        })

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

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

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

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

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

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

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

    assert_units_consistent(m)

    check_dof(m, fail_flag=True)

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

    calculate_scaling_factors(m)

    stream.initialize()

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

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

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

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

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

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

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

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

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

    assert value(stream[0].debye_huckel_constant) == pytest.approx(0.01554,
                                                                   rel=1e-3)
    assert value(stream[0].ionic_strength) == pytest.approx(0.73467, rel=1e-3)
Exemple #26
0
        data_module.add_data_match_obj(model=main_model.case[i].m,
                                       df_meta=df_meta,
                                       bin_stdev=bin_stdev)
        #load data and model inputs already solved
        ms.from_json(main_model.case[i].m,
                     fname=f"results/state4_{i}.json.gz",
                     root_name="unknown")
        main_model.case[i].m.obj_datarec.deactivate()
    #make sure the whole thing solves
    main_model.obj = pyo.Objective(expr=sum(main_model.case[i].m.obj_expr
                                            for i in case_indexes) /
                                   len(case_indexes) / 100)
    strip_bounds = pyo.TransformationFactory("contrib.strip_var_bounds")
    strip_bounds.apply_to(main_model, reversible=False)
    for v, sv in iscale.badly_scaled_var_generator(main_model,
                                                   small=0,
                                                   large=100):
        iscale.set_scaling_factor(v, 1 / pyo.value(v))
    iscale.calculate_scaling_factors(main_model)
    solver.solve(main_model, linear_eliminate=True, tee=True)

    set_weight("1JT66801S", 30, case_indexes)
    set_weight("1FWS-FWFLW-A", 20, case_indexes)
    set_weight("DGS3", 0.5, case_indexes)
    set_weight("S634", 2, case_indexes)
    set_weight("S831", 5, case_indexes)

    drop_tags = [
        "1FWS-STMFLW-A",
        "1TCMVACPT2",
        "S11",
    def test_Pdrop_calculation(self):
        """Testing 0D-RO with PressureChangeType.calculated option."""
        m = ConcreteModel()
        m.fs = FlowsheetBlock(default={"dynamic": False})

        m.fs.properties = props.NaClParameterBlock()

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

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

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

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

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

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

        calculate_scaling_factors(m)

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

        # test initialization
        initialization_tester(m, fail_on_warning=True)

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

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

        # Check for optimal solution
        assert_optimal_termination(results)

        # test solution
        assert pytest.approx(-1.661e5, rel=1e-3) == value(m.fs.unit.deltaP[0])
        assert pytest.approx(-1.038e4, rel=1e-3) == value(m.fs.unit.deltaP[0] /
                                                          m.fs.unit.length)
        assert pytest.approx(395.8, rel=1e-3) == value(m.fs.unit.N_Re[0, 0.0])
        assert pytest.approx(0.2361,
                             rel=1e-3) == value(m.fs.unit.velocity[0, 0.0])
        assert pytest.approx(191.1, rel=1e-3) == value(m.fs.unit.N_Re[0, 1.0])
        assert pytest.approx(0.1187,
                             rel=1e-3) == value(m.fs.unit.velocity[0, 1.0])
        assert pytest.approx(7.089e-3, rel=1e-3) == value(
            m.fs.unit.flux_mass_phase_comp_avg[0, "Liq", "H2O"])
        assert pytest.approx(2.188e-6, rel=1e-3) == value(
            m.fs.unit.flux_mass_phase_comp_avg[0, "Liq", "NaCl"])
        assert pytest.approx(0.1347, rel=1e-3) == value(
            m.fs.unit.mixed_permeate[0].flow_mass_phase_comp["Liq", "H2O"])
        assert pytest.approx(4.157e-5, rel=1e-3) == value(
            m.fs.unit.mixed_permeate[0].flow_mass_phase_comp["Liq", "NaCl"])
        assert pytest.approx(50.08, rel=1e-3) == value(
            m.fs.unit.feed_side.properties_interface[
                0, 0.0].conc_mass_phase_comp["Liq", "NaCl"])
        assert pytest.approx(70.80, rel=1e-3) == value(
            m.fs.unit.feed_side.properties_out[0].conc_mass_phase_comp["Liq",
                                                                       "NaCl"])
        assert pytest.approx(76.32, rel=1e-3) == value(
            m.fs.unit.feed_side.properties_interface[
                0, 1.0].conc_mass_phase_comp["Liq", "NaCl"])
Exemple #28
0
 def _test_no_badly_scaled_vars(m):
     for v, _ in badly_scaled_var_generator(m):
         # TODO: COSTING_UPDATE come back after costing has scaling strategy
         if "costing" in v.name:
             continue
         raise Exception(f"Badly scaled variable {v.name}")