def _set_ene_bal_scaling(unit):
    max_enth_mol_phase = 1
    min_scale = 1
    for phase in unit.control_volume.properties_in[0.0].enth_mol_phase:
        val = max(
            min_scale,
            abs(
                value(unit.control_volume.properties_in[0.0].
                      enth_mol_phase[phase].expr)),
        )
        max_enth_mol_phase = max(val, max_enth_mol_phase)
        iscale.set_scaling_factor(
            unit.control_volume.properties_in[0.0]._enthalpy_flow_term[phase],
            10 / val)
        iscale.set_scaling_factor(
            unit.control_volume.properties_out[0.0]._enthalpy_flow_term[phase],
            10 / val)

    iscale.constraint_scaling_transform(
        unit.control_volume.enthalpy_balances[0.0], 10 / max_enth_mol_phase)
示例#2
0
    def calculate_scaling_factors(self):
        # set a default Reynolds number scaling
        for v in self.N_Re.values():
            if iscale.get_scaling_factor(v, warning=True) is None:
                iscale.set_scaling_factor(v, 1e-4)

        for v in self.friction_factor_darcy.values():
            if iscale.get_scaling_factor(v, warning=True) is None:
                iscale.set_scaling_factor(v, 100)

        for v in self.deltaP_gravity.values():
            if iscale.get_scaling_factor(v, warning=True) is None:
                iscale.set_scaling_factor(v, 1e-3)

        for v in self.deltaP_friction.values():
            if iscale.get_scaling_factor(v, warning=True) is None:
                iscale.set_scaling_factor(v, 1e-3)

        for t, c in self.volume_eqn.items():
            sf = iscale.get_scaling_factor(self.volume[t],
                                           default=1,
                                           warning=True)
            iscale.constraint_scaling_transform(c, sf, overwrite=False)

        for t, c in self.Reynolds_number_eqn.items():
            sf = iscale.get_scaling_factor(self.N_Re[t],
                                           default=1,
                                           warning=True)
            sf *= iscale.get_scaling_factor(
                self.control_volume.properties_in[t].visc_d_phase["Liq"],
                default=1,
                warning=True)
            iscale.constraint_scaling_transform(c, sf, overwrite=False)

        for t, c in self.pressure_change_friction_eqn.items():
            sf = iscale.get_scaling_factor(self.deltaP_friction[t],
                                           default=1,
                                           warning=True)
            iscale.constraint_scaling_transform(c, sf, overwrite=False)

        for t, c in self.pressure_change_gravity_eqn.items():
            sf = iscale.get_scaling_factor(self.deltaP_gravity[t],
                                           default=1,
                                           warning=True)
            iscale.constraint_scaling_transform(c, sf, overwrite=False)

        for t, c in self.pressure_change_total_eqn.items():
            sf = iscale.get_scaling_factor(self.deltaP[t],
                                           default=1,
                                           warning=True)
            iscale.constraint_scaling_transform(c, sf, overwrite=False)
    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)
示例#4
0
    def m(self):
        m = pyo.ConcreteModel()
        m.a = pyo.Var(initialize=0.25, bounds=(-0.5, 0.5))
        m.b = b = pyo.Block()
        b.a = pyo.Var([1, 2], bounds=(-10, 10))

        m.c = pyo.Constraint(expr=(0, 1. / (m.a**2), 100))
        b.c = pyo.Constraint([1, 2], rule=lambda b, i: (i - 1, b.a[i], i + 2))
        b.d = pyo.Constraint(expr=b.a[1]**4 + b.a[2]**4 <= 4)
        set_scaling_factor(b.d, 1e6)

        b.o = pyo.Expression(expr=sum(b.a)**2)

        m.o = pyo.Objective(expr=m.a + b.o)

        # references are tricky, could cause a variable
        # to be iterated over several times in
        # component_data_objects
        m.b_a = pyo.Reference(b.a)

        return m
示例#5
0
    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', 'NaCl'],
                           1e2)
        calculate_scaling_factors(m.fs)

        # check that all variables have scaling factors
        unscaled_var_list = list(unscaled_variables_generator(m))
        for v in unscaled_var_list:
            print(v)
        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
示例#6
0
def set_scaling_factors(m):
    """ Set scaling factors for variables and expressions. These are used for
    variable scaling and used by the framework to scale constraints.

    Args:
        m: plant model to set scaling factors for.

    Returns:
        None
    """
    # Set scaling factors for boiler system
    iscale.set_scaling_factor(m.fs.tank.control_volume.energy_holdup, 1e-10)
    iscale.set_scaling_factor(m.fs.tank.control_volume.material_holdup, 1e-6)
    if m.dynamic:
        for t, c in m.fs.tank.control_volume\
                .energy_accumulation_disc_eq.items():
            iscale.constraint_scaling_transform(c, 1e-6)

    # scaling factor for control valves
    for t in m.fs.config.time:
        iscale.set_scaling_factor(
            m.fs.valve.control_volume.properties_in[t].flow_mol, 0.001)

    # Calculate calculated scaling factors
    iscale.calculate_scaling_factors(m)
示例#7
0
def calculate_chemical_scaling_factors_for_material_balances(unit):
    # Next, try adding scaling for species
    min = 1e-3
    for i in unit.control_volume.properties_out[0.0].mole_frac_phase_comp:
        # i[0] = phase, i[1] = species
        if unit.inlet.mole_frac_comp[0, i[1]].value > min:
            scale = unit.inlet.mole_frac_comp[0, i[1]].value
        else:
            scale = min
        iscale.set_scaling_factor(
            unit.control_volume.properties_out[0.0].mole_frac_comp[i[1]],
            10 / scale)
        iscale.set_scaling_factor(
            unit.control_volume.properties_out[0.0].mole_frac_phase_comp[i],
            10 / scale)
        iscale.set_scaling_factor(
            unit.control_volume.properties_out[0.0].flow_mol_phase_comp[i],
            10 / scale)
        iscale.constraint_scaling_transform(
            unit.control_volume.properties_out[0.0].component_flow_balances[
                i[1]],
            10 / scale,
        )
        iscale.constraint_scaling_transform(
            unit.control_volume.material_balances[0.0, i[1]], 10 / scale)
    def calculate_scaling_factors(self):
        # Get default scale factors and do calculations from base classes
        super().calculate_scaling_factors()

        d_sf_Q = self.params.default_scaling_factor["flow_vol"]
        d_sf_c = self.params.default_scaling_factor["conc_mass_comp"]

        for j, v in self.flow_mass_comp.items():
            if iscale.get_scaling_factor(v) is None:
                iscale.set_scaling_factor(v, d_sf_Q * d_sf_c)

        if self.is_property_constructed("flow_vol"):
            if iscale.get_scaling_factor(self.flow_vol) is None:
                iscale.set_scaling_factor(self.flow_vol, d_sf_Q)

        if self.is_property_constructed("conc_mass_comp"):
            for j, v in self.conc_mass_comp.items():
                sf_c = iscale.get_scaling_factor(self.conc_mass_comp[j])
                if sf_c is None:
                    try:
                        sf_c = self.params.default_scaling_factor[(
                            "conc_mass_comp", j)]
                    except KeyError:
                        sf_c = d_sf_c
                    iscale.set_scaling_factor(self.conc_mass_comp[j], sf_c)
示例#9
0
    def test_compressor(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": True
            })
        # set inputs
        m.fs.unit.inlet.flow_mol[0].fix(10000)
        m.fs.unit.inlet.enth_mol[0].fix(4000)
        m.fs.unit.inlet.pressure[0].fix(101325)
        m.fs.unit.deltaP.fix(500000)
        m.fs.unit.efficiency_isentropic.fix(0.9)
        iscale.set_scaling_factor(m.fs.unit.control_volume.work[0], 1e-5)
        iscale.calculate_scaling_factors(m)

        assert degrees_of_freedom(m) == 0
        m.fs.unit.get_costing(mover_type="compressor")
        m.fs.unit.initialize()
        results = solver.solve(m)
        # Check for optimal solution
        assert results.solver.termination_condition == \
            TerminationCondition.optimal
        assert results.solver.status == SolverStatus.ok

        assert value(m.fs.unit.control_volume.work[0]) == \
            pytest.approx(101410.4, rel=1e-5)

        assert m.fs.unit.costing.purchase_cost.value == \
            pytest.approx(334598, rel=1e-5)

        assert_units_consistent(m.fs.unit)

        solver.solve(m, tee=True)
        assert m.fs.unit.costing.purchase_cost.value == \
            pytest.approx(334598, rel=1e-5)
示例#10
0
    def test_calculate_scaling(self, Pump_frame):
        m = Pump_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', 'TDS'))
        calculate_scaling_factors(m)

        if get_scaling_factor(
                m.fs.unit.ratioP
        ) is None:  # if IDAES hasn't specified a scaling factor
            set_scaling_factor(m.fs.unit.ratioP, 1)

        # 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
示例#11
0
    def calculate_scaling_factors(self):
        for v in self.deltaP_gravity.values():
            if iscale.get_scaling_factor(v, warning=True) is None:
                iscale.set_scaling_factor(v, 1e-3)

        for v in self.deltaP_contraction.values():
            if iscale.get_scaling_factor(v, warning=True) is None:
                iscale.set_scaling_factor(v, 1e-3)

        for t, c in self.pressure_change_contraction_eqn.items():
            sf = iscale.get_scaling_factor(
                self.deltaP_contraction[t], default=1, warning=True)
            iscale.constraint_scaling_transform(c, sf)

        for t, c in self.pressure_change_gravity_eqn.items():
            sf = iscale.get_scaling_factor(
                self.deltaP_gravity[t], default=1, warning=True)
            iscale.constraint_scaling_transform(c, sf)

        for t, c in self.pressure_change_total_eqn.items():
            sf = iscale.get_scaling_factor(
                self.deltaP[t], default=1, warning=True)
            iscale.constraint_scaling_transform(c, sf)
    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
        )
示例#13
0
    def test_scaling(self, model):
        iscale.set_scaling_factor(
            model.fs.unit.liquid_phase.properties_out[0].fug_phase_comp["Liq",
                                                                        "CO2"],
            1e-5)
        iscale.set_scaling_factor(
            model.fs.unit.liquid_phase.properties_out[0].fug_phase_comp["Liq",
                                                                        "H2O"],
            1e-3)

        iscale.calculate_scaling_factors(model.fs.unit)

        assert iscale.get_constraint_transform_applied_scaling_factor(
            model.fs.unit.unit_material_balance[0, "CO2"]) == 1
        assert iscale.get_constraint_transform_applied_scaling_factor(
            model.fs.unit.unit_material_balance[0, "H2O"]) == 1
        assert iscale.get_constraint_transform_applied_scaling_factor(
            model.fs.unit.unit_material_balance[0, "MEA"]) is None
        assert iscale.get_constraint_transform_applied_scaling_factor(
            model.fs.unit.unit_material_balance[0, "N2"]) == 1e8
        assert iscale.get_constraint_transform_applied_scaling_factor(
            model.fs.unit.unit_material_balance[0, "O2"]) == 1e8

        assert iscale.get_constraint_transform_applied_scaling_factor(
            model.fs.unit.unit_phase_equilibrium[0, "CO2"]) == 1e-5
        assert iscale.get_constraint_transform_applied_scaling_factor(
            model.fs.unit.unit_phase_equilibrium[0, "H2O"]) == 1e-3

        assert iscale.get_constraint_transform_applied_scaling_factor(
            model.fs.unit.unit_temperature_equality[0]) == 1e-2

        assert iscale.get_constraint_transform_applied_scaling_factor(
            model.fs.unit.unit_enthalpy_balance[0]) == 1

        assert iscale.get_constraint_transform_applied_scaling_factor(
            model.fs.unit.unit_pressure_balance[0]) == 1e-5
示例#14
0
def test_scale_arcs():
    m = pyo.ConcreteModel()
    m.x = pyo.Var([1, 2, 3, 4])
    m.y = pyo.Var([1, 2, 3, 4])

    m.p1 = Port()
    m.p1.add(m.x[1], name="x")
    m.p1.add(m.y[1], name="y")

    m.p = Port([2, 3, 4])
    m.p[2].add(m.x[2], name="x")
    m.p[2].add(m.y[2], name="y")
    m.p[3].add(m.x[3], name="x")
    m.p[3].add(m.y[3], name="y")
    m.p[4].add(m.x[4], name="x")
    m.p[4].add(m.y[4], name="y")

    def arc_rule(b, i):
        if i == 1:
            return (m.p1, m.p[2])
        elif i == 2:
            return (m.p[3], m.p[4])

    m.arcs = Arc([1, 2], rule=arc_rule)

    sc.set_scaling_factor(m.x, 10)
    sc.set_scaling_factor(m.y, 20)
    sc.set_scaling_factor(m.x[1], 5)

    # make sure there is no error if the scaling is done with unexpanded arcs
    sc.scale_arc_constraints(m)

    # expand and make sure it works
    pyo.TransformationFactory('network.expand_arcs').apply_to(m)
    sc.scale_arc_constraints(m)
    m.x[1] = 1
    m.x[2] = 2
    m.x[3] = 3
    m.x[4] = 4
    m.y[1] = 11
    m.y[2] = 12
    m.y[3] = 13
    m.y[4] = 14

    # for all the arc constraints the differnce is 1 the scale factor is the
    # smallest scale factor for variables in a constraint.  Make sure the
    # constraints are scaled as expected.
    assert abs(m.arcs_expanded[1].x_equality.body()) == 5
    assert abs(m.arcs_expanded[2].x_equality.body()) == 10
    assert abs(m.arcs_expanded[1].y_equality.body()) == 20
    assert abs(m.arcs_expanded[2].y_equality.body()) == 20
示例#15
0
def _set_mat_bal_scaling_FpcTP(unit, min_flow_mol_phase_comp=1e-3):
    # For species
    for i in unit.control_volume.properties_out[0.0].mole_frac_phase_comp:
        # i[0] = phase, i[1] = species
        scale = max(min_flow_mol_phase_comp,
                    unit.inlet.flow_mol_phase_comp[0, i[0], i[1]].value)

        iscale.set_scaling_factor(
            unit.control_volume.properties_out[0.0].mole_frac_comp[i[1]],
            10 / scale)
        iscale.set_scaling_factor(
            unit.control_volume.properties_out[0.0].mole_frac_phase_comp[i],
            10 / scale)
        iscale.set_scaling_factor(
            unit.control_volume.properties_out[0.0].flow_mol_phase_comp[i],
            10 / scale)
        iscale.constraint_scaling_transform(
            unit.control_volume.material_balances[0.0, i[1]], 10 / scale)

    if hasattr(unit.control_volume, "volume"):
        iscale.set_scaling_factor(unit.control_volume.volume,
                                  10 / unit.volume[0.0].value)
示例#16
0
    def calculate_scaling_factors(self):
        super().calculate_scaling_factors()

        # set a default waterwall zone heat scaling factor
        for v in self.waterwall_heat.values():
            if iscale.get_scaling_factor(v, warning=True) is None:
                iscale.set_scaling_factor(v, 1e-7)

        # set a default platen heat scaling factor
        if self.config.has_platen_superheater is True:
            for v in self.platen_heat.values():
                if iscale.get_scaling_factor(v, warning=True) is None:
                    iscale.set_scaling_factor(v, 1e-7)

        # set a default roof heat scaling factor
        if self.config.has_roof_superheater is True:
            for v in self.roof_heat.values():
                if iscale.get_scaling_factor(v, warning=True) is None:
                    iscale.set_scaling_factor(v, 1e-6)

        # set waterwall heat constraint scaling factor
        for t, c in self.eq_surr_waterwall_heat.items():
            sf = iscale.get_scaling_factor(self.waterwall_heat[t],
                                           default=1e-7,
                                           warning=True)
            iscale.constraint_scaling_transform(c, sf)

        # set platen heat constraint scaling factor
        if self.config.has_platen_superheater is True:
            for t, c in self.eq_surr_platen_heat.items():
                sf = iscale.get_scaling_factor(self.platen_heat[t],
                                               default=1e-7,
                                               warning=True)
                iscale.constraint_scaling_transform(c, sf)

        # set roof heat constraint scaling factor
        if self.config.has_roof_superheater is True:
            for t, c in self.eq_surr_roof_heat.items():
                sf = iscale.get_scaling_factor(self.roof_heat[t],
                                               default=1e-6,
                                               warning=True)
                iscale.constraint_scaling_transform(c, sf)

        # set flue gas temperature constraint scaling factor
        for t, c in self.flue_gas_temp_eqn.items():
            sf = iscale.get_scaling_factor(self.platen_heat[t],
                                           default=1e-7,
                                           warning=True)
            iscale.constraint_scaling_transform(c, sf)
示例#17
0
    def test_jacobian(self):
        """Make sure the Jacobian from Pynumero matches expectation.  This is
        mostly to ensure we understand the interface and catch if things change.
        """
        m = self.model()
        assert number_activated_objectives(m) == 0
        jac, jac_scaled, nlp = sc.constraint_autoscale_large_jac(m,
                                                                 no_scale=True)
        assert number_activated_objectives(m) == 0

        c1_row = nlp._condata_to_idx[m.c1]
        c2_row = nlp._condata_to_idx[m.c2]
        c3_row = nlp._condata_to_idx[m.c3]
        x_col = nlp._vardata_to_idx[m.x]
        y_col = nlp._vardata_to_idx[m.y]
        z_col = nlp._vardata_to_idx[m.z]

        assert jac[c1_row, x_col] == pytest.approx(-1e6)
        assert jac[c1_row, y_col] == pytest.approx(-1e3)
        assert jac[c1_row, z_col] == pytest.approx(1)

        assert jac[c2_row, x_col] == pytest.approx(3)
        assert jac[c2_row, y_col] == pytest.approx(4)
        assert jac[c2_row, z_col] == pytest.approx(2)

        assert jac[c3_row, z_col] == pytest.approx(3e8)

        # Make sure scaling factors don't affect the result
        sc.set_scaling_factor(m.c1, 1e-6)
        sc.set_scaling_factor(m.x, 1e-3)
        sc.set_scaling_factor(m.y, 1e-6)
        sc.set_scaling_factor(m.z, 1e-4)
        jac, jac_scaled, nlp = sc.constraint_autoscale_large_jac(m,
                                                                 no_scale=True)
        assert jac[c1_row, x_col] == pytest.approx(-1e6)
        # Check the scaled jacobian calculation
        assert jac_scaled[c1_row, x_col] == pytest.approx(-1000)
        assert jac_scaled[c1_row, y_col] == pytest.approx(-1000)
        assert jac_scaled[c1_row, z_col] == pytest.approx(0.01)
示例#18
0
    def calculate_scaling_factors(self):
        super().calculate_scaling_factors()

        # scale variables
        if iscale.get_scaling_factor(
                self.efficiency_pressure_exchanger) is None:
            # efficiency should always be between 0.1-1
            iscale.set_scaling_factor(self.efficiency_pressure_exchanger, 1)

        # scale expressions
        if iscale.get_scaling_factor(self.low_pressure_side.work) is None:
            sf = iscale.get_scaling_factor(
                self.low_pressure_side.properties_in[0].flow_vol)
            sf = sf * iscale.get_scaling_factor(
                self.low_pressure_side.deltaP[0])
            iscale.set_scaling_factor(self.low_pressure_side.work, sf)

        if iscale.get_scaling_factor(self.high_pressure_side.work) is None:
            sf = iscale.get_scaling_factor(
                self.high_pressure_side.properties_in[0].flow_vol)
            sf = sf * iscale.get_scaling_factor(
                self.high_pressure_side.deltaP[0])
            iscale.set_scaling_factor(self.high_pressure_side.work, sf)

        # transform constraints
        for t, c in self.low_pressure_side.eq_isothermal_temperature.items():
            sf = iscale.get_scaling_factor(
                self.low_pressure_side.properties_in[t].temperature)
            iscale.constraint_scaling_transform(c, sf)

        for t, c in self.high_pressure_side.eq_isothermal_temperature.items():
            sf = iscale.get_scaling_factor(
                self.high_pressure_side.properties_in[t].temperature)
            iscale.constraint_scaling_transform(c, sf)

        for t, c in self.eq_pressure_transfer.items():
            sf = iscale.get_scaling_factor(self.low_pressure_side.deltaP[t])
            iscale.constraint_scaling_transform(c, sf)

        for t, c in self.eq_equal_flow_vol.items():
            sf = iscale.get_scaling_factor(
                self.low_pressure_side.properties_in[t].flow_vol)
            iscale.constraint_scaling_transform(c, sf)

        for t, c in self.eq_equal_low_pressure.items():
            sf = iscale.get_scaling_factor(
                self.low_pressure_side.properties_in[t].pressure)
            iscale.constraint_scaling_transform(c, sf)
示例#19
0
def test_find_unscaled_vars_and_constraints():
    m = pyo.ConcreteModel()
    m.b = pyo.Block()
    m.x = pyo.Var(initialize=1e6)
    m.y = pyo.Var(initialize=1e-8)
    m.z = pyo.Var(initialize=1e-20)
    m.c1 = pyo.Constraint(expr=m.x == 0)
    m.c2 = pyo.Constraint(expr=m.y == 0)
    m.b.w = pyo.Var([1, 2, 3], initialize=1e10)
    m.b.c1 = pyo.Constraint(expr=m.b.w[1] == 0)
    m.b.c2 = pyo.Constraint(expr=m.b.w[2] == 0)
    m.c3 = pyo.Constraint(expr=m.z == 0)

    sc.set_scaling_factor(m.x, 1)
    sc.set_scaling_factor(m.b.w[1], 2)
    sc.set_scaling_factor(m.c1, 1)
    sc.set_scaling_factor(m.b.c1, 1)
    sc.constraint_scaling_transform(m.c3, 1)

    a = [id(v) for v in sc.unscaled_variables_generator(m)]
    # Make sure we pick up the right variales
    assert id(m.x) not in a
    assert id(m.y) in a
    assert id(m.z) in a
    assert id(m.b.w[1]) not in a
    assert id(m.b.w[2]) in a
    assert id(m.b.w[3]) in a
    assert len(a) == 4  #make sure we didn't pick up any other random stuff

    a = [id(v) for v in sc.unscaled_constraints_generator(m)]
    assert id(m.c1) not in a
    assert id(m.b.c1) not in a
    assert id(m.c2) in a
    assert id(m.b.c2) in a
    assert id(m.c3) not in a
    assert len(a) == 2  #make sure we didn't pick up any other random stuff
示例#20
0
    def model_scaling(self, model, variant: Variant):
        map_variant_reaction_scale_func = {
            Variant.equilibrium: self._do_equilibrium_reaction_scaling,
            Variant.inherent: self._do_inherent_reaction_scaling,
        }

        scale_func = map_variant_reaction_scale_func[variant]
        scale_func(model)

        # 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)
        return model
示例#21
0
def test_user_set_scaling():
    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.set_scaling_factor(m.fs.cv.heat[0, 0], 17)
    iscale.calculate_scaling_factors(m)
    # Make sure the heat and work scaling factors are set and not overwritten
    # by the defaults in calculate_scaling_factors
    assert iscale.get_scaling_factor(m.fs.cv.heat) == 11
    assert iscale.get_scaling_factor(m.fs.cv.work) == 12
    # Make sure scaling factor is propagated but does not overwrite index specific factor
    for t in m.fs.time:
        for x in m.fs.cv.length_domain:
            if t == 0 and x == 0:
                assert iscale.get_scaling_factor(m.fs.cv.heat[t, x]) == 17
            else:
                assert iscale.get_scaling_factor(m.fs.cv.heat[t, x]) == 11
            assert iscale.get_scaling_factor(m.fs.cv.work[t, x]) == 12
示例#22
0
def test_map_scaling_factor(caplog):
    m = pyo.ConcreteModel()
    m.x = pyo.Var([1, 2, 3, 4])
    sc.set_scaling_factor(m.x[1], 11)
    sc.set_scaling_factor(m.x[2], 12)
    sc.set_scaling_factor(m.x[3], 13)
    caplog.set_level(logging.WARNING)
    caplog.clear()
    assert sc.map_scaling_factor(m.x.values(), warning=True) == 1
    logrec = caplog.records[0]
    assert logrec.levelno == logging.WARNING
    assert "missing scaling factor" in logrec.message

    assert sc.map_scaling_factor(m.x.values(), func=max) == 13
    assert sc.map_scaling_factor(m.x.values(), default=20) == 11
    with pytest.raises(TypeError):
        sc.map_scaling_factor(m.x.values(), default=None)

    # test min_scaling_factor with just calls map_scaling_factor
    assert sc.min_scaling_factor(m.x.values()) == 1
    assert sc.min_scaling_factor(m.x.values(), default=14) == 11
示例#23
0
    def calculate_scaling_factors(self):
        # Get default scale factors and do calculations from base classes
        super().calculate_scaling_factors()

        # Lock attribute creation to avoid hasattr triggering builds
        self._lock_attribute_creation = True

        # Due to the exponential relationship between most reaction properties
        # and temeprature, it is very hard to calculate good scaling factors
        # from order-of-magnitude guesses. Thus ,reaction scaling will always
        # require a lot of user input. Here we will calculate scaling factors
        # for those properties that have non-exponential relationships to T.
        if hasattr(self, "dh_rxn"):
            for r, v in self.dh_rxn.items():
                if iscale.get_scaling_factor(v) is None:
                    rblock = getattr(self.params, "reaction_" + r)
                    try:
                        carg = self.params.config.rate_reactions[r]
                    except (AttributeError, KeyError):
                        carg = self.params.config.equilibrium_reactions[r]
                    sf = carg["heat_of_reaction"].calculate_scaling_factors(
                        self, rblock)
                    iscale.set_scaling_factor(v, sf)

        if hasattr(self, "k_eq"):
            for r, v in self.k_eq.items():
                if iscale.get_scaling_factor(v) is None:
                    rblock = getattr(self.params, "reaction_" + r)
                    carg = self.params.config.equilibrium_reactions[r]
                    sf = carg[
                        "equilibrium_constant"].calculate_scaling_factors(
                            self, rblock)
                    iscale.set_scaling_factor(v, sf)

        if hasattr(self, "log_k_eq"):
            for r, v in self.log_k_eq.items():
                if iscale.get_scaling_factor(v) is None:
                    rblock = getattr(self.params, "reaction_" + r)
                    carg = self.params.config.equilibrium_reactions[r]
                    sf = carg[
                        "equilibrium_constant"].calculate_scaling_factors(
                            self, rblock)
                    iscale.set_scaling_factor(v, log(sf))

        if hasattr(self, "equilibrium_constraint"):
            for r, v in self.equilibrium_constraint.items():
                carg = self.params.config.equilibrium_reactions[r]
                if iscale.get_scaling_factor(v) is None:
                    if carg["equilibrium_form"].__name__.startswith("log_"):
                        # Log form constraint
                        sf = iscale.get_scaling_factor(self.log_k_eq[r],
                                                       default=1,
                                                       warning=True)
                    else:
                        sf = iscale.get_scaling_factor(self.k_eq[r],
                                                       default=1,
                                                       warning=True)

                sf_const = carg["equilibrium_form"].calculate_scaling_factors(
                    self, sf)

                iscale.constraint_scaling_transform(v,
                                                    sf_const,
                                                    overwrite=False)

        # Unlock attribute creation when done
        self._lock_attribute_creation = False
示例#24
0
    def calculate_scaling_factors(self):
        super().calculate_scaling_factors()

        units_meta = self.config.property_package.get_metadata().get_derived_units

        # scaling factors for turbidity relationship
        #       Supressing warning (these factors are not very important)
        if iscale.get_scaling_factor(self.slope) is None:
            sf = iscale.get_scaling_factor(self.slope, default=1, warning=False)
            iscale.set_scaling_factor(self.slope, sf)
        if iscale.get_scaling_factor(self.intercept) is None:
            sf = iscale.get_scaling_factor(self.intercept, default=1, warning=False)
            iscale.set_scaling_factor(self.intercept, sf)

        # scaling factors for turbidity measurements and chemical doses
        #       Supressing warning
        if iscale.get_scaling_factor(self.initial_turbidity_ntu) is None:
            sf = iscale.get_scaling_factor(self.initial_turbidity_ntu, default=1, warning=False)
            iscale.set_scaling_factor(self.initial_turbidity_ntu, sf)
        if iscale.get_scaling_factor(self.final_turbidity_ntu) is None:
            sf = iscale.get_scaling_factor(self.final_turbidity_ntu, default=1, warning=False)
            iscale.set_scaling_factor(self.final_turbidity_ntu, sf)
        if iscale.get_scaling_factor(self.chemical_doses) is None:
            sf = iscale.get_scaling_factor(self.chemical_doses, default=1, warning=False)
            iscale.set_scaling_factor(self.chemical_doses, sf)

        # set scaling for tss_loss_rate
        if iscale.get_scaling_factor(self.tss_loss_rate) is None:
            sf = 0
            for t in self.control_volume.properties_in:
                sf += value(self.control_volume.properties_in[t].flow_mass_phase_comp['Liq','TSS'])
            sf = sf / len(self.control_volume.properties_in)
            if sf < 0.01:
                sf = 0.01
            iscale.set_scaling_factor(self.tss_loss_rate, 1/sf)

            for ind, c in self.eq_tss_loss_rate.items():
                iscale.constraint_scaling_transform(c, 1/sf)

        # set scaling for tds_gain_rate
        if self.config.chemical_additives:
            if iscale.get_scaling_factor(self.tds_gain_rate) is None:
                sf = 0
                for t in self.control_volume.properties_in:
                    sum = 0
                    for j in self.config.chemical_additives.keys():
                        chem_dose = pyunits.convert(self.chemical_doses[t, j],
                                        to_units=units_meta('mass')*units_meta('length')**-3)
                        chem_dose = chem_dose/self.chemical_mw[j] * \
                                self.salt_from_additive_mole_ratio[j] * \
                                self.salt_mw[j]*self.control_volume.properties_in[t].flow_vol_phase['Liq']
                        sum = sum+chem_dose
                    sf += value(sum)
                sf = sf / len(self.control_volume.properties_in)
                if sf < 0.001:
                    sf = 0.001
                iscale.set_scaling_factor(self.tds_gain_rate, 1/sf)

                for ind, c in self.eq_tds_gain_rate.items():
                    iscale.constraint_scaling_transform(c, 1/sf)

        # set scaling for mass transfer terms
        for ind, c in self.eq_mass_transfer_term.items():
            if ind[2] == "TDS":
                if self.config.chemical_additives:
                    sf = iscale.get_scaling_factor(self.tds_gain_rate)
                else:
                    sf = 1
            elif ind[2] == "TSS":
                sf = iscale.get_scaling_factor(self.tss_loss_rate)
            elif ind[2] == "Sludge":
                sf = iscale.get_scaling_factor(self.tss_loss_rate)
            else:
                sf = 1
            iscale.constraint_scaling_transform(c, sf)
            iscale.set_scaling_factor(self.control_volume.mass_transfer_term[ind] , sf)

        # set scaling factors for control_volume.properties_in based on control_volume.properties_out
        for t in self.control_volume.properties_in:
            if iscale.get_scaling_factor(self.control_volume.properties_in[t].dens_mass_phase) is None:
                sf = iscale.get_scaling_factor(self.control_volume.properties_out[t].dens_mass_phase)
                iscale.set_scaling_factor(self.control_volume.properties_in[t].dens_mass_phase, sf)

            if iscale.get_scaling_factor(self.control_volume.properties_in[t].flow_mass_phase_comp) is None:
                for ind in self.control_volume.properties_in[t].flow_mass_phase_comp:
                    sf = iscale.get_scaling_factor(self.control_volume.properties_out[t].flow_mass_phase_comp[ind])
                    iscale.set_scaling_factor(self.control_volume.properties_in[t].flow_mass_phase_comp[ind], sf)

            if iscale.get_scaling_factor(self.control_volume.properties_in[t].mass_frac_phase_comp) is None:
                for ind in self.control_volume.properties_in[t].mass_frac_phase_comp:
                    sf = iscale.get_scaling_factor(self.control_volume.properties_out[t].mass_frac_phase_comp[ind])
                    iscale.set_scaling_factor(self.control_volume.properties_in[t].mass_frac_phase_comp[ind], sf)

            if iscale.get_scaling_factor(self.control_volume.properties_in[t].flow_vol_phase) is None:
                for ind in self.control_volume.properties_in[t].flow_vol_phase:
                    sf = iscale.get_scaling_factor(self.control_volume.properties_out[t].flow_vol_phase[ind])
                    iscale.set_scaling_factor(self.control_volume.properties_in[t].flow_vol_phase[ind], sf)

        # update scaling for control_volume.properties_out
        for t in self.control_volume.properties_out:
            if iscale.get_scaling_factor(self.control_volume.properties_out[t].dens_mass_phase) is None:
                iscale.set_scaling_factor(self.control_volume.properties_out[t].dens_mass_phase, 1e-3)

            # need to update scaling factors for TSS, Sludge, and TDS to account for the
            #   expected change in their respective values from the loss/gain rates
            for ind in self.control_volume.properties_out[t].flow_mass_phase_comp:
                if ind[1] == "TSS":
                    sf_og = iscale.get_scaling_factor(self.control_volume.properties_out[t].flow_mass_phase_comp[ind])
                    sf_new = iscale.get_scaling_factor(self.tss_loss_rate)
                    iscale.set_scaling_factor(self.control_volume.properties_out[t].flow_mass_phase_comp[ind], 100*sf_new*(sf_new/sf_og))
                if ind[1] == "Sludge":
                    sf_og = iscale.get_scaling_factor(self.control_volume.properties_out[t].flow_mass_phase_comp[ind])
                    sf_new = iscale.get_scaling_factor(self.tss_loss_rate)
                    iscale.set_scaling_factor(self.control_volume.properties_out[t].flow_mass_phase_comp[ind], 100*sf_new*(sf_new/sf_og))

            for ind in self.control_volume.properties_out[t].mass_frac_phase_comp:
                if ind[1] == "TSS":
                    sf_og = iscale.get_scaling_factor(self.control_volume.properties_out[t].mass_frac_phase_comp[ind])
                    sf_new = iscale.get_scaling_factor(self.tss_loss_rate)
                    iscale.set_scaling_factor(self.control_volume.properties_out[t].mass_frac_phase_comp[ind], 100*sf_new*(sf_new/sf_og))
                if ind[1] == "Sludge":
                    sf_og = iscale.get_scaling_factor(self.control_volume.properties_out[t].mass_frac_phase_comp[ind])
                    sf_new = iscale.get_scaling_factor(self.tss_loss_rate)
                    iscale.set_scaling_factor(self.control_volume.properties_out[t].mass_frac_phase_comp[ind], 100*sf_new*(sf_new/sf_og))
示例#25
0
def set_operating_conditions(m):

    # ---specifications---
    # parameters
    pump_efi = 0.75  # pump efficiency [-]
    erd_efi = 0.8  # energy recovery device efficiency [-]
    mem_A = 4.2e-12  # membrane water permeability coefficient [m/s-Pa]
    mem_B = 3.5e-8  # membrane salt permeability coefficient [m/s]
    height = 1e-3  # channel height in membrane stage [m]
    spacer_porosity = 0.97  # spacer porosity in membrane stage [-]
    width = 5 # membrane width factor [m]
    area = 100 # membrane area [m^2]
    pressure_atm = 101325  # atmospheric pressure [Pa]

    # feed
    feed_flow_mass = 1*pyunits.kg/pyunits.s
    feed_mass_frac_NaCl = 70.0/1000.0
    feed_temperature = 273.15 + 25

    # initialize feed
    m.fs.feed.pressure[0].fix(pressure_atm)
    m.fs.feed.temperature[0].fix(feed_temperature)
    m.fs.feed.flow_mass_phase_comp[0, 'Liq', 'NaCl'].fix(feed_flow_mass * feed_mass_frac_NaCl)
    m.fs.feed.flow_mass_phase_comp[0, 'Liq', 'H2O'].fix(feed_flow_mass * (1-feed_mass_frac_NaCl))

    # initialize pumps
    for pump in m.fs.PrimaryPumps.values():
        pump.control_volume.properties_out[0].pressure = 75e5
        pump.efficiency_pump.fix(pump_efi)
        pump.control_volume.properties_out[0].pressure.fix()
        iscale.set_scaling_factor(pump.control_volume.work, 1e-3)

    # initialize eq pumps
    for pump in m.fs.BoosterPumps.values():
        pump.efficiency_pump.fix(pump_efi)
        iscale.set_scaling_factor(pump.control_volume.work, 1e-3)

    # initialize stages
    for idx, stage in m.fs.ROUnits.items():
        if idx > m.fs.StageSet.first():
            B_scale = 100.0
        else:
            B_scale = 1.0
        stage.A_comp.fix(mem_A)
        stage.B_comp.fix(mem_B*B_scale)
        stage.channel_height.fix(height)
        stage.spacer_porosity.fix(spacer_porosity)
        stage.area.fix(area/float(idx))
        stage.width.fix(width)
        stage.permeate.pressure[0].fix(pressure_atm)

    # energy recovery device
    m.fs.EnergyRecoveryDevice.efficiency_pump.fix(erd_efi)
    m.fs.EnergyRecoveryDevice.control_volume.properties_out[0].pressure.fix(pressure_atm)
    iscale.set_scaling_factor(m.fs.EnergyRecoveryDevice.control_volume.work, 1e-3)

    # ---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'))
    iscale.calculate_scaling_factors(m)

    # ---checking model---
    assert_units_consistent(m)
    assert_no_degrees_of_freedom(m)

    print('Feed Concentration = %.1f ppt' % (value(m.fs.feed.flow_mass_phase_comp[0, 'Liq', 'NaCl'])*1000))
示例#26
0
    def calculate_scaling_factors(self):
        super().calculate_scaling_factors()

        # setting scaling factors for variables

        # default scaling factors have already been set with
        # idaes.core.property_base.calculate_scaling_factors()

        # scaling factors for parameters
        for j, v in self.params.mw_comp.items():
            if iscale.get_scaling_factor(v) is None:
                iscale.set_scaling_factor(self.params.mw_comp[j], 1e2)

        if iscale.get_scaling_factor(self.params.dens_mass) is None:
            iscale.set_scaling_factor(self.params.dens_mass, 1e-3)

        if iscale.get_scaling_factor(self.params.cp) is None:
            iscale.set_scaling_factor(self.params.cp, 1e-3)

        # these variables should have user input
        if iscale.get_scaling_factor(self.flow_mass_phase_comp["Liq",
                                                               "H2O"]) is None:
            sf = iscale.get_scaling_factor(self.flow_mass_phase_comp["Liq",
                                                                     "H2O"],
                                           default=1,
                                           warning=True)
            iscale.set_scaling_factor(self.flow_mass_phase_comp["Liq", "H2O"],
                                      sf)

        if iscale.get_scaling_factor(self.flow_mass_phase_comp["Liq",
                                                               "Na"]) is None:
            sf = iscale.get_scaling_factor(self.flow_mass_phase_comp["Liq",
                                                                     "Na"],
                                           default=1e2,
                                           warning=True)
            iscale.set_scaling_factor(self.flow_mass_phase_comp["Liq", "Na"],
                                      sf)

        if iscale.get_scaling_factor(self.flow_mass_phase_comp["Liq",
                                                               "Ca"]) is None:
            sf = iscale.get_scaling_factor(self.flow_mass_phase_comp["Liq",
                                                                     "Ca"],
                                           default=1e4,
                                           warning=True)
            iscale.set_scaling_factor(self.flow_mass_phase_comp["Liq", "Ca"],
                                      sf)

        if iscale.get_scaling_factor(self.flow_mass_phase_comp["Liq",
                                                               "Mg"]) is None:
            sf = iscale.get_scaling_factor(self.flow_mass_phase_comp["Liq",
                                                                     "Mg"],
                                           default=1e3,
                                           warning=True)
            iscale.set_scaling_factor(self.flow_mass_phase_comp["Liq", "Mg"],
                                      sf)

        if iscale.get_scaling_factor(self.flow_mass_phase_comp["Liq",
                                                               "SO4"]) is None:
            sf = iscale.get_scaling_factor(self.flow_mass_phase_comp["Liq",
                                                                     "SO4"],
                                           default=1e3,
                                           warning=True)
            iscale.set_scaling_factor(self.flow_mass_phase_comp["Liq", "SO4"],
                                      sf)

        if iscale.get_scaling_factor(self.flow_mass_phase_comp["Liq",
                                                               "Cl"]) is None:
            sf = iscale.get_scaling_factor(self.flow_mass_phase_comp["Liq",
                                                                     "Cl"],
                                           default=1e2,
                                           warning=True)
            iscale.set_scaling_factor(self.flow_mass_phase_comp["Liq", "Cl"],
                                      sf)

        # these variables do not typically require user input,
        # will not override if the user does provide the scaling factor
        if self.is_property_constructed("mass_frac_phase_comp"):
            for j in self.params.component_list:
                if (iscale.get_scaling_factor(
                        self.mass_frac_phase_comp["Liq", j]) is None):
                    if j == "H2O":
                        iscale.set_scaling_factor(
                            self.mass_frac_phase_comp["Liq", j], 1)
                    else:
                        sf = iscale.get_scaling_factor(
                            self.flow_mass_phase_comp[
                                "Liq", j]) / iscale.get_scaling_factor(
                                    self.flow_mass_phase_comp["Liq", "H2O"])
                        iscale.set_scaling_factor(
                            self.mass_frac_phase_comp["Liq", j], sf)

        if self.is_property_constructed("flow_vol"):
            sf = iscale.get_scaling_factor(
                self.flow_mass_phase_comp["Liq",
                                          "H2O"]) / iscale.get_scaling_factor(
                                              self.params.dens_mass)
            iscale.set_scaling_factor(self.flow_vol, sf)

        if self.is_property_constructed("flow_mol_phase_comp"):
            for j in self.params.component_list:
                if (iscale.get_scaling_factor(
                        self.flow_mol_phase_comp["Liq", j]) is None):
                    sf = iscale.get_scaling_factor(self.flow_mass_phase_comp[
                        "Liq", j]) / iscale.get_scaling_factor(
                            self.params.mw_comp[j])
                    iscale.set_scaling_factor(
                        self.flow_mol_phase_comp["Liq", j], sf)

        if self.is_property_constructed("conc_mol_phase_comp"):
            for j in self.params.component_list:
                if (iscale.get_scaling_factor(
                        self.conc_mol_phase_comp["Liq", j]) is None):
                    sf = iscale.get_scaling_factor(self.flow_mol_phase_comp[
                        "Liq", j]) / iscale.get_scaling_factor(self.flow_vol)
                    iscale.set_scaling_factor(
                        self.conc_mol_phase_comp["Liq", j], sf)

        if self.is_property_constructed("enth_flow"):
            if iscale.get_scaling_factor(self.enth_flow) is None:
                sf = (iscale.get_scaling_factor(self.params.cp) *
                      iscale.get_scaling_factor(
                          self.flow_mass_phase_comp["Liq", "H2O"]) * 1e-1
                      )  # temperature change on the order of 1e1
                iscale.set_scaling_factor(self.enth_flow, sf)

        # transforming constraints
        # property relationships with no index, simple constraint
        v_str_lst_simple = ["flow_vol"]
        for v_str in v_str_lst_simple:
            if self.is_property_constructed(v_str):
                v = getattr(self, v_str)
                sf = iscale.get_scaling_factor(v, default=1, warning=True)
                c = getattr(self, "eq_" + v_str)
                iscale.constraint_scaling_transform(c, sf)

        # property relationships indexed by component and phase
        v_str_lst_phase_comp = [
            "mass_frac_phase_comp",
            "flow_mol_phase_comp",
            "conc_mol_phase_comp",
        ]
        for v_str in v_str_lst_phase_comp:
            if self.is_property_constructed(v_str):
                v_comp = getattr(self, v_str)
                c_comp = getattr(self, "eq_" + v_str)
                for j, c in c_comp.items():
                    sf = iscale.get_scaling_factor(v_comp["Liq", j],
                                                   default=1,
                                                   warning=True)
                    iscale.constraint_scaling_transform(c, sf)
示例#27
0
def test_evaporator():
    m = ConcreteModel()
    m.fs = FlowsheetBlock(default={"dynamic": False})
    m.fs.properties_feed = props_sw.SeawaterParameterBlock()
    m.fs.properties_vapor = props_w.WaterParameterBlock()
    m.fs.evaporator = Evaporator(
        default={
            "property_package_feed": m.fs.properties_feed,
            "property_package_vapor": m.fs.properties_vapor,
        })

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

    # assert False

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

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

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

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

    # initialize
    m.fs.evaporator.initialize()

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

    # check values, TODO: make a report for the evaporator
    # m.fs.evaporator.display()
    vapor_blk = m.fs.evaporator.feed_side.properties_vapor[0]
    assert vapor_blk.flow_mass_phase_comp["Vap", "H2O"].value == pytest.approx(
        0.3540, rel=1e-3)
    assert m.fs.evaporator.lmtd.value == pytest.approx(12.30, rel=1e-3)
    assert m.fs.evaporator.feed_side.heat_transfer.value == pytest.approx(
        1.230e6, rel=1e-3)
示例#28
0
    def calculate_scaling_factors(self):
        if iscale.get_scaling_factor(self.dens_solvent) is None:
            sf = iscale.get_scaling_factor(
                self.feed_side.properties[0, 0].dens_mass_phase['Liq'])
            iscale.set_scaling_factor(self.dens_solvent, sf)

        super().calculate_scaling_factors()

        # these variables should have user input, if not there will be a warning
        if iscale.get_scaling_factor(self.width) is None:
            sf = iscale.get_scaling_factor(self.width, default=1, warning=True)
            iscale.set_scaling_factor(self.width, sf)

        if iscale.get_scaling_factor(self.length) is None:
            sf = iscale.get_scaling_factor(self.length,
                                           default=10,
                                           warning=True)
            iscale.set_scaling_factor(self.length, sf)

        # setting scaling factors for variables

        # will not override if the user provides the scaling factor
        ## default of 1 set by ControlVolume1D
        if iscale.get_scaling_factor(self.area_cross) == 1:
            iscale.set_scaling_factor(self.area_cross, 100)

        for (t, x, p, j), v in self.mass_transfer_phase_comp.items():
            sf = (iscale.get_scaling_factor(
                self.feed_side.properties[t, x].get_material_flow_terms(p, j))
                  / iscale.get_scaling_factor(self.feed_side.length)) * value(
                      self.nfe)
            if iscale.get_scaling_factor(v) is None:
                iscale.set_scaling_factor(v, sf)
            v = self.feed_side.mass_transfer_term[t, x, p, j]
            if iscale.get_scaling_factor(v) is None:
                iscale.set_scaling_factor(v, sf)

        if hasattr(self, 'deltaP'):
            for v in self.deltaP.values():
                if iscale.get_scaling_factor(v) is None:
                    iscale.set_scaling_factor(v, 1e-4)

        if hasattr(self, 'dP_dx'):
            for v in self.feed_side.pressure_dx.values():
                iscale.set_scaling_factor(v, 1e-5)
        else:
            for v in self.feed_side.pressure_dx.values():
                iscale.set_scaling_factor(v, 1e5)
示例#29
0
    def calculate_scaling_factors(self):
        # setting scaling factors for variables
        # will not override if the user does provide the scaling factor
        if iscale.get_scaling_factor(self.dens_solvent) is None:
            sf = iscale.get_scaling_factor(
                self.feed_side.properties_in[0].dens_mass_phase['Liq'])
            iscale.set_scaling_factor(self.dens_solvent, sf)

        super().calculate_scaling_factors()

        for (t, p, j), v in self.mass_transfer_phase_comp.items():
            sf = iscale.get_scaling_factor(
                self.feed_side.properties_in[t].get_material_flow_terms(p, j))
            if iscale.get_scaling_factor(v) is None:
                iscale.set_scaling_factor(v, sf)
            v = self.feed_side.mass_transfer_term[t, p, j]
            if iscale.get_scaling_factor(v) is None:
                iscale.set_scaling_factor(v, sf)

        if hasattr(self, 'area_cross'):
            if iscale.get_scaling_factor(self.area_cross) is None:
                iscale.set_scaling_factor(self.area_cross, 100)

        if hasattr(self, 'length'):
            if iscale.get_scaling_factor(self.length) is None:
                iscale.set_scaling_factor(self.length, 1)

        if hasattr(self, 'width'):
            if iscale.get_scaling_factor(self.width) is None:
                iscale.set_scaling_factor(self.width, 1)

        if hasattr(self, 'dP_dx'):
            for v in self.dP_dx.values():
                if iscale.get_scaling_factor(v) is None:
                    iscale.set_scaling_factor(v, 1e-4)
示例#30
0
    def calculate_scaling_factors(self):
        super().calculate_scaling_factors()
        # Var scaling
        # The following Vars' sf are allowed to be provided by users or set by default.
        if (
            iscale.get_scaling_factor(self.solute_diffusivity_membrane, warning=True)
            is None
        ):
            iscale.set_scaling_factor(self.solute_diffusivity_membrane, 1e10)
        if iscale.get_scaling_factor(self.membrane_thickness, warning=True) is None:
            iscale.set_scaling_factor(self.membrane_thickness, 1e4)
        if (
            iscale.get_scaling_factor(self.water_permeability_membrane, warning=True)
            is None
        ):
            iscale.set_scaling_factor(self.water_permeability_membrane, 1e14)
        if iscale.get_scaling_factor(self.cell_length, warning=True) is None:
            iscale.set_scaling_factor(self.cell_length, 1e1)
        if iscale.get_scaling_factor(self.cell_width, warning=True) is None:
            iscale.set_scaling_factor(self.cell_width, 1e1)
        if iscale.get_scaling_factor(self.spacer_thickness, warning=True) is None:
            iscale.set_scaling_factor(self.spacer_thickness, 1e4)
        if (
            iscale.get_scaling_factor(self.membrane_surface_resistance, warning=True)
            is None
        ):
            iscale.set_scaling_factor(self.membrane_surface_resistance, 1e4)
        if iscale.get_scaling_factor(self.electrodes_resistance, warning=True) is None:
            iscale.set_scaling_factor(self.electrodes_resistance, 1e4)
        if iscale.get_scaling_factor(self.current, warning=True) is None:
            iscale.set_scaling_factor(self.current, 1)
        if iscale.get_scaling_factor(self.voltage, warning=True) is None:
            iscale.set_scaling_factor(self.voltage, 1e-1)
        # The folloing Vars are built for constructing constraints and their sf are computed from other Vars.
        iscale.set_scaling_factor(
            self.elec_migration_flux_in,
            iscale.get_scaling_factor(self.current)
            * iscale.get_scaling_factor(self.cell_length) ** -1
            * iscale.get_scaling_factor(self.cell_width) ** -1
            * 1e5,
        )
        iscale.set_scaling_factor(
            self.elec_migration_flux_out,
            iscale.get_scaling_factor(self.current)
            * iscale.get_scaling_factor(self.cell_length) ** -1
            * iscale.get_scaling_factor(self.cell_width) ** -1
            * 1e5,
        )
        iscale.set_scaling_factor(
            self.power_electrical,
            iscale.get_scaling_factor(self.current)
            * iscale.get_scaling_factor(self.voltage),
        )
        for ind, c in self.specific_power_electrical.items():
            iscale.set_scaling_factor(
                self.specific_power_electrical[ind],
                3.6e6
                * iscale.get_scaling_factor(self.current[ind])
                * iscale.get_scaling_factor(self.voltage[ind])
                * iscale.get_scaling_factor(
                    self.diluate_channel.properties_out[ind].flow_vol_phase["Liq"]
                )
                ** -1,
            )

        # Constraint scaling
        for ind, c in self.eq_current_voltage_relation.items():
            iscale.constraint_scaling_transform(
                c, iscale.get_scaling_factor(self.membrane_surface_resistance)
            )
        for ind, c in self.eq_power_electrical.items():
            iscale.constraint_scaling_transform(
                c, iscale.get_scaling_factor(self.power_electrical)
            )
        for ind, c in self.eq_specific_power_electrical.items():
            iscale.constraint_scaling_transform(
                c, iscale.get_scaling_factor(self.specific_power_electrical[ind])
            )

        for ind, c in self.eq_elec_migration_flux_in.items():
            iscale.constraint_scaling_transform(
                c, iscale.get_scaling_factor(self.elec_migration_flux_in)
            )
        for ind, c in self.eq_elec_migration_flux_out.items():
            iscale.constraint_scaling_transform(
                c, iscale.get_scaling_factor(self.elec_migration_flux_out)
            )
        for ind, c in self.eq_nonelec_flux_in.items():
            if ind[2] == "H2O":
                sf = (
                    1e-3
                    * 0.018
                    * iscale.get_scaling_factor(self.water_permeability_membrane)
                    * iscale.get_scaling_factor(
                        self.concentrate_channel.properties_in[
                            ind[0]
                        ].pressure_osm_phase[ind[1]]
                    )
                )
            sf = (
                iscale.get_scaling_factor(self.solute_diffusivity_membrane)
                / iscale.get_scaling_factor(self.membrane_thickness)
                * iscale.get_scaling_factor(
                    self.concentrate_channel.properties_in[ind[0]].conc_mol_phase_comp[
                        ind[1], ind[2]
                    ]
                )
            )
            iscale.set_scaling_factor(self.nonelec_flux_in[ind], sf)
            iscale.constraint_scaling_transform(c, sf)
        for ind, c in self.eq_nonelec_flux_out.items():
            if ind[2] == "H2O":
                sf = (
                    1e-3
                    * 0.018
                    * iscale.get_scaling_factor(self.water_permeability_membrane)
                    * iscale.get_scaling_factor(
                        self.concentrate_channel.properties_out[
                            ind[0]
                        ].pressure_osm_phase[ind[1]]
                    )
                )
            else:
                sf = (
                    iscale.get_scaling_factor(self.solute_diffusivity_membrane)
                    / iscale.get_scaling_factor(self.membrane_thickness)
                    * iscale.get_scaling_factor(
                        self.concentrate_channel.properties_out[
                            ind[0]
                        ].conc_mol_phase_comp[ind[1], ind[2]]
                    )
                )

            iscale.set_scaling_factor(self.nonelec_flux_out[ind], sf)
            iscale.constraint_scaling_transform(c, sf)
        for ind, c in self.eq_mass_transfer_term_diluate.items():
            iscale.constraint_scaling_transform(
                c,
                min(
                    iscale.get_scaling_factor(self.elec_migration_flux_in[ind]),
                    iscale.get_scaling_factor(
                        self.nonelec_flux_in[ind], self.elec_migration_flux_out[ind]
                    ),
                    iscale.get_scaling_factor(self.nonelec_flux_out[ind]),
                ),
            )
        for ind, c in self.eq_mass_transfer_term_concentrate.items():
            iscale.constraint_scaling_transform(
                c,
                min(
                    iscale.get_scaling_factor(self.elec_migration_flux_in[ind]),
                    iscale.get_scaling_factor(
                        self.nonelec_flux_in[ind], self.elec_migration_flux_out[ind]
                    ),
                    iscale.get_scaling_factor(self.nonelec_flux_out[ind]),
                ),
            )

        for ind, c in self.eq_power_electrical.items():
            iscale.constraint_scaling_transform(
                c,
                iscale.get_scaling_factor(self.power_electrical[ind]),
            )

        for ind, c in self.eq_specific_power_electrical.items():
            iscale.constraint_scaling_transform(
                c,
                iscale.get_scaling_factor(self.specific_power_electrical[ind])
                * iscale.get_scaling_factor(
                    self.diluate_channel.properties_out[ind].flow_vol_phase["Liq"]
                ),
            )
        for ind, c in self.eq_current_efficiency.items():
            iscale.constraint_scaling_transform(
                c, iscale.get_scaling_factor(self.current[ind])
            )

        for ind, c in self.eq_isothermal_diluate.items():
            iscale.constraint_scaling_transform(
                c, self.diluate_channel.properties_in[ind].temperature
            )
        for ind, c in self.eq_isothermal_concentrate.items():
            iscale.constraint_scaling_transform(
                c, self.concentrate_channel.properties_in[ind].temperature
            )