Esempio n. 1
0
    def test_conservation(self, iron_oc):
        # Conservation of material check
        calculate_variable_from_constraint(
            iron_oc.fs.unit.gas_inlet_block[0].mw,
            iron_oc.fs.unit.gas_inlet_block[0].mw_eqn)
        calculate_variable_from_constraint(
            iron_oc.fs.unit.gas_outlet_block[0].mw,
            iron_oc.fs.unit.gas_outlet_block[0].mw_eqn)
        mbal_gas = value((iron_oc.fs.unit.gas_inlet.flow_mol[0] *
                          iron_oc.fs.unit.gas_inlet_block[0].mw) -
                         (iron_oc.fs.unit.gas_outlet.flow_mol[0] *
                          iron_oc.fs.unit.gas_outlet_block[0].mw))
        mbal_solid = value(iron_oc.fs.unit.solid_inlet.flow_mass[0] -
                           iron_oc.fs.unit.solid_outlet.flow_mass[0])
        mbal_tol = mbal_gas + mbal_solid
        assert abs(mbal_tol) <= 1e-2

        # Reaction stoichiometric ratio check
        # Overall reducer reactions for methane combustion:
        # CH4 + 12Fe2O3 => 8Fe3O4 + CO2 + 2H2O
        mole_gas_reacted = value(
            iron_oc.fs.unit.gas_inlet.flow_mol[0] *
            iron_oc.fs.unit.gas_inlet.mole_frac_comp[0, 'CH4'] -
            iron_oc.fs.unit.gas_outlet.flow_mol[0] *
            iron_oc.fs.unit.gas_outlet.mole_frac_comp[0, 'CH4'])
        mole_solid_reacted = value(
            (iron_oc.fs.unit.solid_inlet.flow_mass[0] *
             iron_oc.fs.unit.solid_inlet.mass_frac_comp[0, 'Fe2O3'] /
             iron_oc.fs.unit.solid_inlet_block[0]._params.mw_comp['Fe2O3']) -
            (iron_oc.fs.unit.solid_outlet.flow_mass[0] *
             iron_oc.fs.unit.solid_outlet.mass_frac_comp[0, 'Fe2O3'] /
             iron_oc.fs.unit.solid_outlet_block[0]._params.mw_comp['Fe2O3']))
        stoichiometric_ratio = mole_solid_reacted / mole_gas_reacted
        assert (pytest.approx(12, abs=1e-6) == stoichiometric_ratio)
Esempio n. 2
0
    def test_linear(self):
        m = ConcreteModel()
        m.x = Var()
        m.c = Constraint(expr=5*m.x == 10)

        calculate_variable_from_constraint(m.x, m.c)
        self.assertEqual(value(m.x), 2)
    def test_turbine(self):
        m = ConcreteModel()
        m.fs = FlowsheetBlock(default={"dynamic": False})
        m.fs.properties = iapws95.Iapws95ParameterBlock()
        m.fs.unit = PressureChanger(
            default={
                "property_package": m.fs.properties,
                "thermodynamic_assumption": ThermodynamicAssumption.isentropic,
                "compressor": False
            })
        # set inputs
        m.fs.unit.inlet.flow_mol[0].fix(1000)  # mol/s
        Tin = 500  # K
        Pin = 1000000  # Pa
        Pout = 700000  # Pa
        hin = iapws95.htpx(Tin * units.K, Pin * units.Pa)
        m.fs.unit.inlet.enth_mol[0].fix(hin)
        m.fs.unit.inlet.pressure[0].fix(Pin)

        m.fs.unit.deltaP.fix(Pout - Pin)
        m.fs.unit.efficiency_isentropic.fix(0.9)

        m.fs.unit.initialize()

        m.fs.unit.get_costing()
        calculate_variable_from_constraint(m.fs.unit.costing.purchase_cost,
                                           m.fs.unit.costing.cp_cost_eq)
        assert degrees_of_freedom(m) == 0

        assert_units_consistent(m.fs.unit)

        solver.solve(m, tee=True)
        assert m.fs.unit.costing.purchase_cost.value ==\
            pytest.approx(213199, 1e-5)
Esempio n. 4
0
    def test_linear(self):
        m = ConcreteModel()
        m.x = Var()
        m.c = Constraint(expr=5 * m.x == 10)

        calculate_variable_from_constraint(m.x, m.c)
        self.assertEqual(value(m.x), 2)
Esempio n. 5
0
    def calculate_variable_scaling_factor(self, var):
        """
        Calculates the scaling factor of a variable based on the
        constraint assigned to it. Loads each variable in that constraint
        with its nominal value (inverse of scaling factor), calculates
        the value of the target variable from the constraint, then sets
        its scaling factor to the inverse of the calculated value.
        """
        vardata = self.get_representative_data_object(var)
        condata = self.var2con[vardata]
        scaling_factor = self.scaling_factor

        in_constraint = list(identify_variables(condata.expr))
        source_vars = [v for v in in_constraint if v is not vardata]
        nominal_source = [1 / scaling_factor[var] for var in source_vars]

        with CacheVars(in_constraint) as cache:
            for v, nom_val in zip(source_vars, nominal_source):
                v.set_value(nom_val)
            # This assumes that target var is initialized to a somewhat
            # reasonable value
            calculate_variable_from_constraint(vardata, condata)
            nominal_target = vardata.value
        if nominal_target == 0:
            target_factor = 1.0
        else:
            target_factor = abs(1 / nominal_target)

        if self.dim == 0:
            scaling_factor[var] = target_factor
        else:
            for v in var.values():
                scaling_factor[v] = target_factor
    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.calculate_scaling_factors(m)

        m.fs.unit.initialize()

        assert degrees_of_freedom(m) == 0
        m.fs.unit.get_costing(mover_type="compressor")
        calculate_variable_from_constraint(m.fs.unit.costing.purchase_cost,
                                           m.fs.unit.costing.cp_cost_eq)

        assert_units_consistent(m.fs.unit)

        solver.solve(m, tee=True)
        assert m.fs.unit.costing.purchase_cost.value == \
            pytest.approx(334648, 1e-5)
Esempio n. 7
0
    def test_nonlinear_bound_violation(self):
        m = ConcreteModel()
        m.v1 = Var(initialize=1, domain=NonNegativeReals)
        m.c1 = Constraint(expr=m.v1 == 0)

        # Test nonlinear solution falling outside bounds
        m.c4 = Constraint(expr=m.v1**3 == -8)
        m.v1.set_value(1)
        calculate_variable_from_constraint(m.v1, m.c4)
        self.assertEqual(value(m.v1), -2)
Esempio n. 8
0
    def initialize(self,
                   solver=None,
                   optarg=None,
                   outlvl=idaeslog.NOTSET,
                   **kwargs):
        self.outlet_state.initialize(hold_state=False,
                                     solver=solver,
                                     optarg=optarg,
                                     outlvl=outlvl)

        for t in self.flowsheet().config.time:
            calculate_variable_from_constraint(self.outlet.flow_mol[t],
                                               self.efficiency_curve[t])
Esempio n. 9
0
def test_compressor_fan():
    m = pyo.ConcreteModel()
    m.fs = FlowsheetBlock(default={"dynamic": False})

    m.fs.properties = iapws95.Iapws95ParameterBlock()
    # Add property packages to flowsheet library
    m.fs.prop_fluegas = FlueGasParameterBlock()
    m.fs.unit = PressureChanger(
        default={
            "property_package": m.fs.prop_fluegas,
            "thermodynamic_assumption": ThermodynamicAssumption.isentropic,
            "compressor": True
        })

    # # FLUE GAS Inlet from Primary Superheater
    FGrate = 425.813998  # mol/s
    # # Use FG molar composition to set component flow rates (baseline report)
    m.fs.unit.control_volume.properties_in[0].flow_mol_comp["H2O"].\
        fix(FGrate*8.69/100)
    m.fs.unit.control_volume.properties_in[0].flow_mol_comp["CO2"].\
        fix(FGrate*14.49/100)
    m.fs.unit.control_volume.properties_in[0].flow_mol_comp["N2"].\
        fix(FGrate*74.34/100)
    m.fs.unit.control_volume.properties_in[0].flow_mol_comp["O2"].\
        fix(FGrate*2.47/100)
    m.fs.unit.control_volume.properties_in[0].flow_mol_comp["NO"].\
        fix(FGrate*0.0006)
    m.fs.unit.control_volume.properties_in[0].flow_mol_comp["SO2"]\
        .fix(FGrate*0.002)
    m.fs.unit.control_volume.properties_in[0].temperature.fix(200.335)
    m.fs.unit.control_volume.properties_in[0].pressure.fix(98658.6)

    m.fs.unit.deltaP.fix(101325 - 98658.6)
    m.fs.unit.efficiency_isentropic.fix(0.9)
    m.fs.unit.initialize()
    m.fs.unit.get_costing(mover_type='fan')

    calculate_variable_from_constraint(m.fs.unit.costing.purchase_cost,
                                       m.fs.unit.costing.cp_cost_eq)
    assert degrees_of_freedom(m) == 0
    # Check unit config arguments
    assert isinstance(m.fs.unit.costing.purchase_cost, pyo.Var)
    assert isinstance(m.fs.unit.costing.base_cost, pyo.Var)
    results = solver.solve(m, tee=True)
    assert results.solver.termination_condition == \
        pyo.TerminationCondition.optimal
    assert results.solver.status == pyo.SolverStatus.ok
    assert (pytest.approx(pyo.value(m.fs.unit.costing.base_cost),
                          abs=1e-2) == 4543.6428)
    assert (pytest.approx(pyo.value(m.fs.unit.costing.purchase_cost),
                          abs=1e-2) == 22106.9807)
Esempio n. 10
0
def update_time_derivatives(fs,t):
    verbose = False 
    debug = True
    m = fs.MB_fuel
    if verbose: print('\nTime derivative values: \n - - -')

    for z in m.z:
        if z != m.z.first():
            for j in m.GasList:
                #if t > 0: pdb.set_trace()
                calculate_variable_from_constraint(m.dCgdt[z,j,t],m.eq_b1[z,j,t])
                if verbose: print('\t\tdCgdt ',z,',',j,',',t,':\t',m.dCgdt[z,j,t].value)

            for j in m.SolidList:
                calculate_variable_from_constraint(m.dqdt[z,j,t],m.eq_b2[z,j,t])
                if verbose: print('\t\tdqdt ',z,',',j,',',t,':\t',m.dqdt[z,j,t].value)

            calculate_variable_from_constraint(m.dTgdt[z,t],m.eq_d1[z,t])
            if verbose: print('\t\tdTgdt ',z,',',t,':\t',m.dTgdt[z,t].value)

            calculate_variable_from_constraint(m.dTsdt[z,t],m.eq_d6[z,t])
            if verbose: print('\t\tdTsdt ',z,',',t,':\t',m.dTsdt[z,t].value)

        #else:
        #    for j in m.GasList:
        #        m.dCgdt[z,j,t].set_value(0)
        #    for j in m.SolidList:
        #        m.dqdt[z,j,t].set_value(0)
        #    m.dTgdt[z,t].set_value(0)
        #    m.dTsdt[z,t].set_value(0)
    if verbose: print('- - -\n')
Esempio n. 11
0
def test_costing():
    m = ConcreteModel()
    m.fs = FlowsheetBlock(default={"dynamic": False})

    m.fs.properties = iapws95.Iapws95ParameterBlock()

    m.fs.unit = HeatExchanger(
        default={
            "shell": {
                "property_package": m.fs.properties
            },
            "tube": {
                "property_package": m.fs.properties
            },
            "flow_pattern": HeatExchangerFlowPattern.countercurrent
        })
    #   Set inputs
    m.fs.unit.inlet_1.flow_mol[0].fix(100)
    m.fs.unit.inlet_1.enth_mol[0].fix(4000)
    m.fs.unit.inlet_1.pressure[0].fix(101325)

    m.fs.unit.inlet_2.flow_mol[0].fix(100)
    m.fs.unit.inlet_2.enth_mol[0].fix(3500)
    m.fs.unit.inlet_2.pressure[0].fix(101325)

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

    assert degrees_of_freedom(m) == 0

    m.fs.unit.initialize()

    m.fs.unit.get_costing()
    calculate_variable_from_constraint(m.fs.unit.costing.base_cost,
                                       m.fs.unit.costing.base_cost_eq)

    calculate_variable_from_constraint(m.fs.unit.costing.purchase_cost,
                                       m.fs.unit.costing.cp_cost_eq)

    assert_units_consistent(m.fs.unit.costing)

    results = solver.solve(m)

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

    assert m.fs.unit.costing.purchase_cost.value == \
        pytest.approx(529738.6793, 1e-5)
Esempio n. 12
0
    def calculate_bubble_point_temperature(self, clear_components=True):
        """"To compute the bubble point temperature of the mixture."""

        if hasattr(self, "eq_temperature_bubble"):
            # Do not delete components if the block already has the components
            clear_components = False

        calculate_variable_from_constraint(self.temperature_bubble,
                                           self.eq_temperature_bubble)

        return self.temperature_bubble.value

        if clear_components is True:
            self.del_component(self.eq_temperature_bubble)
            self.del_component(self._p_sat_bubbleT)
            self.del_component(self.temperature_bubble)
    def initialize_build(self):
        calculate_variable_from_constraint(self.total_investment_cost, self.total_investment_cost_constraint)
        calculate_variable_from_constraint(self.maintenance_labor_chemical_operating_cost,
                self.maintenance_labor_chemical_operating_cost_constraint)
        calculate_variable_from_constraint(self.total_operating_cost,
                self.total_operating_cost_constraint)

        if hasattr(self, "LCOW"):
            calculate_variable_from_constraint(self.LCOW, self.LCOW_constraint)
Esempio n. 14
0
    def calculate_dew_point_pressure(self, clear_components=True):
        """"To compute the dew point pressure of the mixture."""

        if hasattr(self, "eq_pressure_dew"):
            # Do not delete components if the block already has the components
            clear_components = False

        calculate_variable_from_constraint(self.pressure_dew, self.eq_pressure_dew)

        return self.pressure_dew.value

        # Delete the var/constraint created in this method that are part of the
        # IdealStateBlock if the user desires
        if clear_components is True:
            self.del_component(self.eq_pressure_dew)
            self.del_component(self._p_sat_dewP)
            self.del_component(self.pressure_dew)
Esempio n. 15
0
    def test_has_consistent_initial_conditions(self):
        nmpc = self.make_nmpc()
        with pytest.raises(ValueError):
            # Model has not been properly initialized
            nmpc.has_consistent_initial_conditions(nmpc.plant)

        t0 = nmpc.plant_time.first()
        nmpc.plant.rate[t0, :].set_value(0.0)
        nmpc.plant.flow_out[t0].set_value(nmpc.plant.flow_in[t0].value)
        for j in nmpc.plant.components:
            calculate_variable_from_constraint(
                nmpc.plant.dcdt[t0, j],
                nmpc.plant.material_balance[t0, j],
            )
        assert nmpc.has_consistent_initial_conditions(nmpc.plant)

        nmpc.plant.flow_out[t0].set_value(0.0)
        assert not nmpc.has_consistent_initial_conditions(nmpc.plant)
def test_costing_book():
    m = ConcreteModel()
    m.fs = FlowsheetBlock(default={"dynamic": False})
    m.fs.properties = iapws95.Iapws95ParameterBlock()
    m.fs.unit = HeatExchanger(
        default={
            "shell": {
                "property_package": m.fs.properties
            },
            "tube": {
                "property_package": m.fs.properties
            },
            "flow_pattern": HeatExchangerFlowPattern.countercurrent
        })
    #   Set inputs
    m.fs.unit.inlet_1.flow_mol[0].fix(100)
    m.fs.unit.inlet_1.enth_mol[0].fix(4000)
    m.fs.unit.inlet_1.pressure[0].fix(101325)

    m.fs.unit.inlet_2.flow_mol[0].fix(100)
    m.fs.unit.inlet_2.enth_mol[0].fix(3500)
    m.fs.unit.inlet_2.pressure[0].fix(101325)

    m.fs.unit.area.fix(1000)
    m.fs.unit.overall_heat_transfer_coefficient.fix(100)
    # costing
    m.fs.unit.get_costing(hx_type='floating_head',
                          length_factor='20ft',
                          year='2018')
    m.fs.unit.area.fix(669.738)  # m2
    m.fs.unit.costing.pressure_factor.fix(1.19)
    m.fs.unit.costing.material_factor.fix(4.05)
    m.fs.costing.CE_index = 550
    m.fs.unit.costing.hx_os = 1.0
    calculate_variable_from_constraint(m.fs.unit.costing.base_cost_per_unit,
                                       m.fs.unit.costing.base_cost_per_unit_eq)

    calculate_variable_from_constraint(m.fs.unit.costing.purchase_cost,
                                       m.fs.unit.costing.cp_cost_eq)

    assert value(m.fs.unit.costing.base_cost) == \
        pytest.approx(78802.0518, 1e-5)
    assert m.fs.unit.costing.purchase_cost.value == \
        pytest.approx(417765.1377, 1e-5)
    def initialize_build(self):
        calculate_variable_from_constraint(
            self.total_investment_cost, self.total_investment_cost_constraint)
        calculate_variable_from_constraint(
            self.maintenance_labor_chemical_operating_cost,
            self.maintenance_labor_chemical_operating_cost_constraint,
        )
        calculate_variable_from_constraint(
            self.total_operating_cost, self.total_operating_cost_constraint)

        for var, con in self._registered_LCOWs.values():
            calculate_variable_from_constraint(var, con)
Esempio n. 18
0
    def test_warn_final_value_nonlinear(self):
        m = ConcreteModel()
        m.x = Var(bounds=(0, 1))
        m.c3 = Constraint(expr=(m.x - 3.5)**2 == 0)

        with LoggingIntercept() as LOG:
            calculate_variable_from_constraint(m.x, m.c3)
        self.assertRegex(
            LOG.getvalue().strip(),
            r"Setting Var 'x' to a numeric value `[0-9\.]+` outside the "
            r"bounds \(0, 1\).")
        self.assertAlmostEqual(value(m.x), 3.5, 3)

        m.x.domain = Binary
        with LoggingIntercept() as LOG:
            calculate_variable_from_constraint(m.x, m.c3)
        self.assertRegex(
            LOG.getvalue().strip(),
            r"Setting Var 'x' to a value `[0-9\.]+` \(float\) not in "
            "domain Binary.")
        self.assertAlmostEqual(value(m.x), 3.5, 3)
Esempio n. 19
0
    def test_warn_final_value_linear(self):
        m = ConcreteModel()
        m.x = Var(bounds=(0, 1))
        m.c1 = Constraint(expr=m.x == 10)
        m.c2 = Constraint(expr=5 * m.x == 10)

        with LoggingIntercept() as LOG:
            calculate_variable_from_constraint(m.x, m.c1)
        self.assertEqual(
            LOG.getvalue().strip(),
            "Setting Var 'x' to a numeric value `10` outside the "
            "bounds (0, 1).")
        self.assertEqual(value(m.x), 10)

        with LoggingIntercept() as LOG:
            calculate_variable_from_constraint(m.x, m.c2)
        self.assertEqual(
            LOG.getvalue().strip(),
            "Setting Var 'x' to a numeric value `2.0` outside the "
            "bounds (0, 1).")
        self.assertEqual(value(m.x), 2)
Esempio n. 20
0
    def test_constraint_as_tuple(self):
        m = ConcreteModel()
        m.x = Var()
        m.p = Param(initialize=15, mutable=True)

        calculate_variable_from_constraint(m.x, 5 * m.x == 5)
        self.assertEqual(value(m.x), 1)
        calculate_variable_from_constraint(m.x, (5 * m.x, 10))
        self.assertEqual(value(m.x), 2)
        calculate_variable_from_constraint(m.x, (15, 5 * m.x, m.p))
        self.assertEqual(value(m.x), 3)
        with self.assertRaisesRegex(
                ValueError, "Constraint 'tuple' is a Ranged Inequality "
                "with a variable upper bound."):
            calculate_variable_from_constraint(m.x, (15, 5 * m.x, m.x))
Esempio n. 21
0
    def set_input_values(self, input_values):
        solver = self._solver
        external_cons = self.external_cons
        external_vars = self.external_vars
        input_vars = self.input_vars

        for var, val in zip(input_vars, input_values):
            var.set_value(val)

        for block, inputs in self._scc_list:
            if len(block.vars) == 1:
                calculate_variable_from_constraint(block.vars[0],
                                                   block.cons[0])
            else:
                with TemporarySubsystemManager(to_fix=inputs):
                    solver.solve(block)

        # Send updated variable values to NLP for dervative evaluation
        primals = self._nlp.get_primals()
        to_update = input_vars + external_vars
        indices = self._nlp.get_primal_indices(to_update)
        values = np.fromiter((var.value for var in to_update), float)
        primals[indices] = values
        self._nlp.set_primals(primals)
Esempio n. 22
0
def initialize_t0(model):
    time = model.time
    t0 = time.first()
    calculate_variable_from_constraint(
            model.flow_out[t0],
            model.flow_eqn[t0],
            )
    for j in model.components:
        calculate_variable_from_constraint(
                model.rate[t0, j],
                model.rate_eqn[t0, j],
                )
        calculate_variable_from_constraint(
                model.dcdt[t0, j],
                model.material_balance[t0, j],
                )
Esempio n. 23
0
    def test_bound_violation(self):
        # Test Issue #2176: solving a constraint where the intermediate
        # value can step outside the bounds
        m = ConcreteModel()
        m.v1 = Var(initialize=1, domain=NonNegativeReals)
        m.c1 = Constraint(expr=m.v1 == 0)

        # Calculate value of v1 using constraint c1
        calculate_variable_from_constraint(m.v1, m.c1)
        self.assertEqual(value(m.v1), 0)

        # Calculate value of v1 using a scaled constraint c2
        m.c2 = Constraint(expr=m.v1 * 10 == 0)
        m.v1.set_value(1)
        calculate_variable_from_constraint(m.v1, m.c2)
        self.assertEqual(value(m.v1), 0)

        # Test linear solution falling outside bounds
        m.c3 = Constraint(expr=m.v1 * 10 == -1)
        m.v1.set_value(1)
        calculate_variable_from_constraint(m.v1, m.c3)
        self.assertEqual(value(m.v1), -0.1)
Esempio n. 24
0
    def test_pump(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.pump,
                "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(50000)
        m.fs.unit.efficiency_pump.fix(0.9)
        iscale.calculate_scaling_factors(m)
        m.fs.unit.initialize()

        assert degrees_of_freedom(m) == 0

        m.fs.unit.get_costing(pump_type='centrifugal',
                              Mat_factor='nickel',
                              pump_motor_type_factor='enclosed')
        calculate_variable_from_constraint(
            m.fs.unit.costing.motor_purchase_cost,
            m.fs.unit.costing.cp_motor_cost_eq)

        calculate_variable_from_constraint(
            m.fs.unit.costing.pump_purchase_cost,
            m.fs.unit.costing.cp_pump_cost_eq)

        calculate_variable_from_constraint(m.fs.unit.costing.purchase_cost,
                                           m.fs.unit.costing.total_cost_eq)

        solver.solve(m, tee=True)
        assert m.fs.unit.costing.purchase_cost.value == \
            pytest.approx(70141.395, 1e-5)
Esempio n. 25
0
    def test_nonlinear(self):
        m = ConcreteModel()
        m.x = Var()
        m.y = Var(initialize=0)

        m.c = Constraint(expr=m.x**2 == 16)
        m.x.set_value(1.0)  # set an initial value
        calculate_variable_from_constraint(m.x, m.c, linesearch=False)
        self.assertAlmostEqual(value(m.x), 4)

        # test that infeasible constraint throws error
        m.d = Constraint(expr=m.x**2 == -1)
        m.x.set_value(1.25)  # set the initial value
        with self.assertRaisesRegex(RuntimeError,
                                    r'Iteration limit \(10\) reached'):
            calculate_variable_from_constraint(m.x,
                                               m.d,
                                               iterlim=10,
                                               linesearch=False)

        # same problem should throw a linesearch error if linesearch is on
        m.x.set_value(1.25)  # set the initial value
        with self.assertRaisesRegex(RuntimeError,
                                    "Linesearch iteration limit reached"):
            calculate_variable_from_constraint(m.x,
                                               m.d,
                                               iterlim=10,
                                               linesearch=True)

        # same problem should raise an error if initialized at 0
        m.x = 0
        with self.assertRaisesRegex(
                RuntimeError, "Initial value for variable results in a "
                "derivative value that is very close to zero."):
            calculate_variable_from_constraint(m.x, m.c)

        # same problem should raise a value error if we are asked to
        # solve for a variable that is not present
        with self.assertRaisesRegex(ValueError, "Variable derivative == 0"):
            calculate_variable_from_constraint(m.y, m.c)

        # should succeed with or without a linesearch
        m.e = Constraint(expr=(m.x - 2.0)**2 - 1 == 0)
        m.x.set_value(3.1)
        calculate_variable_from_constraint(m.x, m.e, linesearch=False)
        self.assertAlmostEqual(value(m.x), 3)

        m.x.set_value(3.1)
        calculate_variable_from_constraint(m.x, m.e, linesearch=True)
        self.assertAlmostEqual(value(m.x), 3)

        # we expect this to succeed with the linesearch
        m.f = Constraint(expr=1.0 / (1.0 + exp(-m.x)) - 0.5 == 0)
        m.x.set_value(3.0)
        calculate_variable_from_constraint(m.x, m.f, linesearch=True)
        self.assertAlmostEqual(value(m.x), 0)

        # we expect this to fail without a linesearch
        m.x.set_value(3.0)
        with self.assertRaisesRegex(
                RuntimeError, "Newton's method encountered a derivative "
                "that was too close to zero"):
            calculate_variable_from_constraint(m.x, m.f, linesearch=False)

        # Calculate the bubble point of Benzene.  THe first step
        # computed by calculate_variable_from_constraint will make the
        # second term become complex, and the evaluation will fail.
        # This tests that the algorithm cleanly continues
        m = ConcreteModel()
        m.x = Var()
        m.pc = 48.9e5
        m.tc = 562.2
        m.psc = {
            'A': -6.98273,
            'B': 1.33213,
            'C': -2.62863,
            'D': -3.33399,
        }
        m.p = 101325

        @m.Constraint()
        def f(m):
            return m.pc * \
                exp((m.psc['A'] * (1 - m.x / m.tc) +
                     m.psc['B'] * (1 - m.x / m.tc)**1.5 +
                     m.psc['C'] * (1 - m.x / m.tc)**3 +
                     m.psc['D'] * (1 - m.x / m.tc)**6
                 ) / (1 - (1 - m.x / m.tc))) - m.p == 0

        m.x.set_value(298.15)
        calculate_variable_from_constraint(m.x, m.f, linesearch=False)
        self.assertAlmostEqual(value(m.x), 353.31855602)
        m.x.set_value(298.15)
        calculate_variable_from_constraint(m.x, m.f, linesearch=True)
        self.assertAlmostEqual(value(m.x), 353.31855602)

        # Starting with an invalid guess (above TC) should raise an
        # exception
        m.x.set_value(600)
        output = StringIO()
        with LoggingIntercept(output, 'pyomo', logging.WARNING):
            with self.assertRaises(TypeError):
                calculate_variable_from_constraint(m.x, m.f, linesearch=False)
        self.assertIn(
            'Encountered an error evaluating the expression '
            'at the initial guess', output.getvalue())

        # This example triggers an expression evaluation error if the
        # linesearch is turned off because the first step in Newton's
        # method will cause the LHS to become complex
        m = ConcreteModel()
        m.x = Var()
        m.c = Constraint(expr=(1 / m.x**3)**0.5 == 100)
        m.x = .1
        calculate_variable_from_constraint(m.x, m.c, linesearch=True)
        self.assertAlmostEqual(value(m.x), 0.046415888)
        m.x = .1
        output = StringIO()
        with LoggingIntercept(output, 'pyomo', logging.WARNING):
            with self.assertRaises(ValueError):
                # Note that the ValueError is different between Python 2
                # and Python 3: in Python 2 it is a specific error
                # "negative number cannot be raised to a fractional
                # power", and We mock up that error in Python 3 by
                # raising a generic ValueError in
                # calculate_variable_from_constraint
                calculate_variable_from_constraint(m.x, m.c, linesearch=False)
        self.assertIn(
            "Newton's method encountered an error evaluating "
            "the expression.", output.getvalue())

        # This is a completely contrived example where the linesearch
        # hits the iteration limit before Newton's method ever finds a
        # feasible step
        m = ConcreteModel()
        m.x = Var()
        m.c = Constraint(expr=m.x**0.5 == -1e-8)
        m.x = 1e-8  #197.932807183
        with self.assertRaisesRegex(
                RuntimeError, "Linesearch iteration limit reached; "
                "remaining residual = {function evaluation error}"):
            calculate_variable_from_constraint(m.x,
                                               m.c,
                                               linesearch=True,
                                               alpha_min=.5)
Esempio n. 26
0
    def initialize(blk,
                   flow_mol_phase_comp=None,
                   temperature=None,
                   pressure=None,
                   state_vars_fixed=False,
                   hold_state=False,
                   outlvl=1,
                   solver='ipopt',
                   optarg={'tol': 1e-8}):
        """
        Initialisation routine for property package.
        Keyword Arguments:
            flow_mol_phase_comp : value at which to initialize phase-component
                                flows (default=None)
            pressure : value at which to initialize pressure (default=None)
            temperature : value at which to initialize temperature
                          (default=None)
            outlvl : sets output level of initialisation routine
                     * 0 = no output (default)
                     * 1 = return solver state for each step in routine
                     * 2 = include solver output infomation (tee=True)
            optarg : solver options dictionary object (default=None)
            state_vars_fixed: Flag to denote if state vars have already been
                              fixed.
                              - True - states have already been fixed by the
                                       control volume 1D. Control volume 0D
                                       does not fix the state vars, so will
                                       be False if this state block is used
                                       with 0D blocks.
                             - False - states have not been fixed. The state
                                       block will deal with fixing/unfixing.
            solver : str indicating whcih solver to use during
                     initialization (default = 'ipopt')
            hold_state : flag indicating whether the initialization routine
                         should unfix any state variables fixed during
                         initialization (default=False).
                         - True - states varaibles are not unfixed, and
                                 a dict of returned containing flags for
                                 which states were fixed during
                                 initialization.
                        - False - state variables are unfixed after
                                 initialization by calling the
                                 relase_state method
        Returns:
            If hold_states is True, returns a dict containing flags for
            which states were fixed during initialization.
        """

        _log.info('Starting {} initialisation'.format(blk.name))

        # Fix state variables if not already fixed
        if state_vars_fixed is False:
            Fflag = {}
            Pflag = {}
            Tflag = {}

            for k in blk.keys():
                for p in blk[k]._params.phase_list:
                    for j in blk[k]._params.component_list:
                        if blk[k].flow_mol_phase_comp[p, j].fixed is True:
                            Fflag[k, p, j] = True
                        else:
                            Fflag[k, p, j] = False
                            if flow_mol_phase_comp is None:
                                blk[k].flow_mol_phase_comp[p, j].fix(
                                    1 / len(blk[k]._params.component_list))
                            else:
                                blk[k].flow_mol_phase_comp[p, j].fix(
                                    flow_mol_phase_comp[p, j])

                if blk[k].pressure.fixed is True:
                    Pflag[k] = True
                else:
                    Pflag[k] = False
                    if pressure is None:
                        blk[k].pressure.fix(101325.0)
                    else:
                        blk[k].pressure.fix(pressure)

                if blk[k].temperature.fixed is True:
                    Tflag[k] = True
                else:
                    Tflag[k] = False
                    if temperature is None:
                        blk[k].temperature.fix(325)
                    else:
                        blk[k].temperature.fix(temperature)

            # -----------------------------------------------------------------
            # If input block, return flags, else release state
            flags = {"Fflag": Fflag, "Pflag": Pflag, "Tflag": Tflag}

        else:
            # Check when the state vars are fixed already result in dof 0
            for k in blk.keys():
                if degrees_of_freedom(blk[k]) != 0:
                    raise Exception("State vars fixed but degrees of freedom "
                                    "for state block is not zero during "
                                    "initialization.")
        # Set solver options
        if outlvl > 1:
            stee = True
        else:
            stee = False

        if optarg is None:
            sopt = {'tol': 1e-8}
        else:
            sopt = optarg

        opt = SolverFactory('ipopt')
        opt.options = sopt

        # ---------------------------------------------------------------------
        # If present, initialize bubble and dew point calculations
        for k in blk.keys():
            if hasattr(blk[k], "eq_temperature_dew"):
                calculate_variable_from_constraint(blk[k].temperature_dew,
                                                   blk[k].eq_temperature_dew)

            if hasattr(blk[k], "eq_pressure_dew"):
                calculate_variable_from_constraint(blk[k].pressure_dew,
                                                   blk[k].eq_pressure_dew)

        if outlvl > 0:
            _log.info("Dew and bubble points initialization for "
                      "{} completed".format(blk.name))

        # ---------------------------------------------------------------------
        # If flash, initialize T1 and Teq
        for k in blk.keys():
            if (blk[k].config.has_phase_equilibrium
                    and not blk[k].config.defined_state):
                blk[k]._t1.value = max(blk[k].temperature.value,
                                       blk[k].temperature_bubble.value)
                blk[k]._teq.value = min(blk[k]._t1.value,
                                        blk[k].temperature_dew.value)

        if outlvl > 0:
            _log.info("Equilibrium temperature initialization for "
                      "{} completed".format(blk.name))

        # ---------------------------------------------------------------------
        # Initialize flow rates and compositions
        # TODO : This will need ot be generalised more when we move to a
        # modular implementation
        for k in blk.keys():
            # Deactivate equilibrium constraints, as state is fixed
            if hasattr(blk[k], 'equilibrium_constraint'):
                blk[k].equilibrium_constraint.deactivate()

        free_vars = 0
        for k in blk.keys():
            free_vars += number_unfixed_variables(blk[k])
        if free_vars > 0:
            try:
                results = solve_indexed_blocks(opt, [blk], tee=stee)
            except:
                results = None
        else:
            results = None

        for k in blk.keys():
            # Reactivate equilibrium constraints
            if hasattr(blk[k], 'equilibrium_constraint'):
                blk[k].equilibrium_constraint.activate()

        if outlvl > 0:
            if results is None or results.solver.termination_condition \
                    == TerminationCondition.optimal:
                _log.info("Property initialization for "
                          "{} completed".format(blk.name))
            else:
                _log.warning("Property initialization for "
                             "{} failed".format(blk.name))

        # ---------------------------------------------------------------------
        # Return state to initial conditions
        if state_vars_fixed is False:
            if hold_state is True:
                return flags
            else:
                blk.release_state(flags)

        if outlvl > 0:
            _log.info("Initialisation completed for {}".format(blk.name))
Esempio n. 27
0
    def initialize(blk,
                   state_args=None,
                   state_vars_fixed=False,
                   hold_state=False,
                   outlvl=1,
                   solver='ipopt',
                   optarg={'tol': 1e-8}):
        """
        Initialisation routine for property package.
        Keyword Arguments:
            state_args : Dictionary with initial guesses for the state vars
                         chosen. Note that if this method is triggered
                         through the control volume, and if initial guesses
                         were not provied at the unit model level, the
                         control volume passes the inlet values as initial
                         guess.The keys for the state_args dictionary are:

                         flow_mol : value at which to initialize component
                                    flows
                         pressure : value at which to initialize pressure
                         temperature : value at which to initialize temperature
                         mole_frac_comp: value at which to initialize the
                                     component mixture mole fraction
            outlvl : sets output level of initialisation routine
                     * 0 = no output (default)
                     * 1 = return solver state for each step in routine
                     * 2 = include solver output infomation (tee=True)
            optarg : solver options dictionary object (default=None)
            state_vars_fixed: Flag to denote if state vars have already been
                              fixed.
                              - True - states have already been fixed by the
                                       control volume 1D. Control volume 0D
                                       does not fix the state vars, so will
                                       be False if this state block is used
                                       with 0D blocks.
                             - False - states have not been fixed. The state
                                       block will deal with fixing/unfixing.
            solver : str indicating whcih solver to use during
                     initialization (default = 'ipopt')
            hold_state : flag indicating whether the initialization routine
                         should unfix any state variables fixed during
                         initialization (default=False).
                         - True - states varaibles are not unfixed, and
                                 a dict of returned containing flags for
                                 which states were fixed during
                                 initialization.
                        - False - state variables are unfixed after
                                 initialization by calling the
                                 relase_state method
        Returns:
            If hold_states is True, returns a dict containing flags for
            which states were fixed during initialization.
        """

        _log.info('Starting {} initialisation'.format(blk.name))

        # Deactivate the constraints specific for outlet block i.e.
        # when defined state is False
        for k in blk.keys():
            if blk[k].config.defined_state is False:
                blk[k].sum_mole_frac_out.deactivate()

        # Fix state variables if not already fixed
        if state_vars_fixed is False:
            Fflag = {}
            Xflag = {}
            Pflag = {}
            Tflag = {}

            for k in blk.keys():
                if blk[k].flow_mol.fixed is True:
                    Fflag[k] = True
                else:
                    Fflag[k] = False
                    if state_args is None:
                        blk[k].flow_mol.fix(1.0)
                    else:
                        blk[k].flow_mol.fix(state_args["flow_mol"])

                for j in blk[k]._params.component_list:
                    if blk[k].mole_frac_comp[j].fixed is True:
                        Xflag[k, j] = True
                    else:
                        Xflag[k, j] = False
                        if state_args is None:
                            blk[k].mole_frac_comp[j].fix(
                                1 / len(blk[k]._params.component_list))
                        else:
                            blk[k].mole_frac_comp[j].fix(
                                state_args["mole_frac_comp"][j])

                if blk[k].pressure.fixed is True:
                    Pflag[k] = True
                else:
                    Pflag[k] = False
                    if state_args is None:
                        blk[k].pressure.fix(101325.0)
                    else:
                        blk[k].pressure.fix(state_args["pressure"])

                if blk[k].temperature.fixed is True:
                    Tflag[k] = True
                else:
                    Tflag[k] = False
                    if state_args is None:
                        blk[k].temperature.fix(325)
                    else:
                        blk[k].temperature.fix(state_args["temperature"])

            # ---------------------------------------------------------------------
            # If input block, return flags, else release state
            flags = {
                "Fflag": Fflag,
                "Xflag": Xflag,
                "Pflag": Pflag,
                "Tflag": Tflag
            }

        else:
            # Check when the state vars are fixed already result in dof 0
            for k in blk.keys():
                if degrees_of_freedom(blk[k]) != 0:
                    raise Exception("State vars fixed but degrees of freedom "
                                    "for state block is not zero during "
                                    "initialization.")
        # Set solver options
        if outlvl > 1:
            stee = True
        else:
            stee = False

        if optarg is None:
            sopt = {'tol': 1e-8}
        else:
            sopt = optarg

        opt = SolverFactory('ipopt')
        opt.options = sopt

        # ---------------------------------------------------------------------
        # If present, initialize bubble and dew point calculations
        for k in blk.keys():
            if hasattr(blk[k], "eq_temperature_bubble"):
                calculate_variable_from_constraint(
                    blk[k].temperature_bubble, blk[k].eq_temperature_bubble)

            if hasattr(blk[k], "eq_temperature_dew"):
                calculate_variable_from_constraint(blk[k].temperature_dew,
                                                   blk[k].eq_temperature_dew)

            if hasattr(blk[k], "eq_pressure_bubble"):
                calculate_variable_from_constraint(blk[k].pressure_bubble,
                                                   blk[k].eq_pressure_bubble)

            if hasattr(blk[k], "eq_pressure_dew"):
                calculate_variable_from_constraint(blk[k].pressure_dew,
                                                   blk[k].eq_pressure_dew)

        if outlvl > 0:
            _log.info("Dew and bubble points initialization for "
                      "{} completed".format(blk.name))

        # ---------------------------------------------------------------------
        # If flash, initialize T1 and Teq
        for k in blk.keys():
            if blk[k].config.has_phase_equilibrium:
                blk[k]._t1.value = max(blk[k].temperature.value,
                                       blk[k].temperature_bubble.value)
                blk[k]._teq.value = min(blk[k]._t1.value,
                                        blk[k].temperature_dew.value)

        if outlvl > 0:
            _log.info("Equilibrium temperature initialization for "
                      "{} completed".format(blk.name))

        # ---------------------------------------------------------------------
        # Initialize flow rates and compositions
        # TODO : This will need ot be generalised more when we move to a
        # modular implementation
        for k in blk.keys():
            if blk[k]._params.config.valid_phase == "Liq":
                blk[k].flow_mol_phase['Liq'].value = \
                    blk[k].flow_mol.value

                for j in blk[k]._params.component_list:
                    blk[k].mole_frac_phase_comp['Liq', j].value = \
                        blk[k].mole_frac_comp[j].value

            elif blk[k]._params.config.valid_phase == "Vap":
                blk[k].flow_mol_phase['Vap'].value = \
                    blk[k].flow_mol.value

                for j in blk[k]._params.component_list:
                    blk[k].mole_frac_phase_comp['Vap', j].value = \
                        blk[k].mole_frac_comp[j].value

            else:
                # Seems to work best with default values for phase flows
                for j in blk[k]._params.component_list:
                    blk[k].mole_frac_phase_comp['Vap', j].value = \
                        blk[k].mole_frac_comp[j].value
                    blk[k].mole_frac_phase_comp['Liq', j].value = \
                        blk[k].mole_frac_comp[j].value

                    calculate_variable_from_constraint(
                        blk[k].pressure_sat[j], blk[k].eq_pressure_sat[j])

        # ---------------------------------------------------------------------
        # Solve phase equilibrium constraints
        for k in blk.keys():
            for c in blk[k].component_objects(Constraint):
                # Deactivate all property constraints
                if c.local_name not in ("total_flow_balance",
                                        "component_flow_balances",
                                        "equilibrium_constraint",
                                        "sum_mole_frac", "_t1_constraint",
                                        "_teq_constraint", "eq_pressure_dew",
                                        "eq_pressure_bubble",
                                        "eq_temperature_dew",
                                        "eq_temperature_bubble",
                                        "eq_pressure_sat"):
                    c.deactivate()

        results = solve_indexed_blocks(opt, [blk], tee=stee)

        if outlvl > 0:
            if results.solver.termination_condition \
                    == TerminationCondition.optimal:
                _log.info("Phase state initialization for "
                          "{} completed".format(blk.name))
            else:
                _log.warning("Phase state initialization for "
                             "{} failed".format(blk.name))

        # ---------------------------------------------------------------------
        # Initialize other properties
        for k in blk.keys():
            for c in blk[k].component_objects(Constraint):
                # Activate all constraints except sum_mole_frac_out
                if c.local_name not in ("sum_mole_frac_out"):
                    c.activate()

        if outlvl > 0:
            if results.solver.termination_condition \
                    == TerminationCondition.optimal:
                _log.info("Property initialization for "
                          "{} completed".format(blk.name))
            else:
                _log.warning("Property initialization for "
                             "{} failed".format(blk.name))

        # ---------------------------------------------------------------------
        # Return state to initial conditions
        for k in blk.keys():
            if (blk[k].config.defined_state is False):
                blk[k].sum_mole_frac_out.activate()

        if state_vars_fixed is False:
            if hold_state is True:
                return flags
            else:
                blk.release_state(flags)

        if outlvl > 0:
            _log.info("Initialisation completed for {}".format(blk.name))
Esempio n. 28
0
    def initialize(blk,
                   flow_mol_comp=None,
                   temperature=None,
                   pressure=None,
                   hold_state=False,
                   outlvl=0,
                   state_vars_fixed=False,
                   solver='ipopt',
                   optarg={'tol': 1e-8}):
        '''
        Initialisation routine for property package.

        Keyword Arguments:
            flow_mol_comp : value at which to initialize component flows
                             (default=None)
            pressure : value at which to initialize pressure (default=None)
            temperature : value at which to initialize temperature
                          (default=None)
            outlvl : sets output level of initialisation routine

                     * 0 = no output (default)
                     * 1 = return solver state for each step in routine
                     * 2 = include solver output infomation (tee=True)
            state_vars_fixed: Flag to denote if state vars have already been
                              fixed.
                              - True - states have already been fixed by the
                                       control volume 1D. Control volume 0D
                                       does not fix the state vars, so will
                                       be False if this state block is used
                                       with 0D blocks.
                             - False - states have not been fixed. The state
                                       block will deal with fixing/unfixing.
            optarg : solver options dictionary object (default=None)
            solver : str indicating whcih solver to use during
                     initialization (default = 'ipopt')
            hold_state : flag indicating whether the initialization routine
                         should unfix any state variables fixed during
                         initialization (default=False).
                         - True - states varaibles are not unfixed, and
                                 a dict of returned containing flags for
                                 which states were fixed during
                                 initialization.
                        - False - state variables are unfixed after
                                 initialization by calling the
                                 relase_state method

        Returns:
            If hold_states is True, returns a dict containing flags for
            which states were fixed during initialization.
        '''
        if state_vars_fixed is False:
            # Fix state variables if not already fixed
            Fcflag = {}
            Pflag = {}
            Tflag = {}

            for k in blk.keys():
                for j in blk[k]._params.component_list:
                    if blk[k].flow_mol_comp[j].fixed is True:
                        Fcflag[k, j] = True
                    else:
                        Fcflag[k, j] = False
                        if flow_mol_comp is None:
                            blk[k].flow_mol_comp[j].fix(1.0)
                        else:
                            blk[k].flow_mol_comp[j].fix(flow_mol_comp[j])

                if blk[k].pressure.fixed is True:
                    Pflag[k] = True
                else:
                    Pflag[k] = False
                    if pressure is None:
                        blk[k].pressure.fix(101325.0)
                    else:
                        blk[k].pressure.fix(pressure)

                if blk[k].temperature.fixed is True:
                    Tflag[k] = True
                else:
                    Tflag[k] = False
                    if temperature is None:
                        blk[k].temperature.fix(1500.0)
                    else:
                        blk[k].temperature.fix(temperature)

                for j in blk[k]._params.component_list:
                    blk[k].mole_frac[j] = \
                        (value(blk[k].flow_mol_comp[j]) /
                         sum(value(blk[k].flow_mol_comp[i])
                             for i in blk[k]._params.component_list))

            # If input block, return flags, else release state
            flags = {"Fcflag": Fcflag, "Pflag": Pflag, "Tflag": Tflag}

        else:
            # Check when the state vars are fixed already result in dof 0
            for k in blk.keys():
                if degrees_of_freedom(blk[k]) != 0:
                    raise Exception("State vars fixed but degrees of freedom "
                                    "for state block is not zero during "
                                    "initialization.")
        # Set solver options
        if outlvl > 1:
            stee = True
        else:
            stee = False

        opt = SolverFactory(solver)
        opt.options = optarg

        # ---------------------------------------------------------------------
        # Initialise values
        for k in blk.keys():
            for j in blk[k]._params.component_list:

                if hasattr(blk[k], "cp_shomate_eqn"):
                    calculate_variable_from_constraint(
                        blk[k].cp_mol_comp[j], blk[k].cp_shomate_eqn[j])

                if hasattr(blk[k], "enthalpy_shomate_eqn"):
                    calculate_variable_from_constraint(
                        blk[k].enth_mol_phase_comp["Vap", j],
                        blk[k].enthalpy_shomate_eqn[j])

                if hasattr(blk[k], "entropy_shomate_eqn"):
                    calculate_variable_from_constraint(
                        blk[k].entr_mol_phase_comp["Vap", j],
                        blk[k].entropy_shomate_eqn[j])

                if hasattr(blk[k], "partial_gibbs_energy_eqn"):
                    calculate_variable_from_constraint(
                        blk[k].gibbs_mol_phase_comp["Vap", j],
                        blk[k].partial_gibbs_energy_eqn[j])

            if hasattr(blk[k], "ideal_gas"):
                calculate_variable_from_constraint(
                    blk[k].dens_mol_phase["Vap"], blk[k].ideal_gas)

            if hasattr(blk[k], "mixture_heat_capacity_eqn"):
                calculate_variable_from_constraint(
                    blk[k].cp_mol, blk[k].mixture_heat_capacity_eqn)

            if hasattr(blk[k], "mixture_enthalpy_eqn"):
                calculate_variable_from_constraint(blk[k].enth_mol,
                                                   blk[k].mixture_enthalpy_eqn)

            if hasattr(blk[k], "mixture_entropy_eqn"):
                calculate_variable_from_constraint(blk[k].entr_mol,
                                                   blk[k].mixture_entropy_eqn)

            if hasattr(blk[k], "total_flow_eqn"):
                calculate_variable_from_constraint(blk[k].flow_mol,
                                                   blk[k].total_flow_eqn)

            if hasattr(blk[k], "mixture_gibbs_eqn"):
                calculate_variable_from_constraint(blk[k].gibbs_mol,
                                                   blk[k].mixture_gibbs_eqn)

        results = solve_indexed_blocks(opt, blk, tee=stee)

        if outlvl > 0:
            if results.solver.termination_condition \
                    == TerminationCondition.optimal:
                _log.info('{} Initialisation Step 1 Complete.'.format(
                    blk.name))
            else:
                _log.warning('{} Initialisation Step 1 Failed.'.format(
                    blk.name))

        # ---------------------------------------------------------------------
        if outlvl > 0:
            if outlvl > 0:
                _log.info('{} Initialisation Complete.'.format(blk.name))

        if state_vars_fixed is False:
            if hold_state is True:
                return flags
            else:
                blk.release_state(flags)
Esempio n. 29
0
    def initialize(blk, outlvl=idaeslog.NOTSET, optarg={}, solver=None):
        '''
        Initialisation routine for reaction package.

        Keyword Arguments:
            outlvl : sets output level of initialization routine
            optarg : solver options dictionary object (default={})
            solver : str indicating whcih solver to use during
                     initialization (default = None, use default solver)
        Returns:
            None
        '''
        init_log = idaeslog.getInitLogger(blk.name, outlvl, tag="reactions")
        solve_log = idaeslog.getSolveLogger(blk.name, outlvl, tag="reactions")

        init_log.info_high('Starting initialization')

        # TODO - Update in the future as needed
        # Get a single representative block for getting config arguments
        for k in blk.keys():
            break

        # Fix state variables if not already fixed
        # Fix state variables of the primary (solid) state block
        state_var_flags = fix_state_vars(blk[k].config.solid_state_block)

        # Fix values of secondary (gas) state block variables if not fixed,
        # as well as the solid density variable.
        # This is done to keep the initialization problem square
        Cflag = {}  # Gas concentration flag
        Dflag = {}  # Solid density flag

        for k in blk.keys():
            for j in blk[k]._params.gas_component_list:
                if blk[k].gas_state_ref.dens_mol_comp[j].fixed is True:
                    Cflag[k, j] = True
                else:
                    Cflag[k, j] = False
                    blk[k].gas_state_ref.dens_mol_comp[j].fix(
                        blk[k].gas_state_ref.dens_mol_comp[j].value)
            if blk[k].solid_state_ref.dens_mass_skeletal.fixed is True:
                Dflag[k] = True
            else:
                Dflag[k] = False
                blk[k].solid_state_ref.dens_mass_skeletal.fix(
                    blk[k].solid_state_ref.dens_mass_skeletal.value)

        # Create solver
        opt = get_solver(solver, optarg)

        # Initialise values
        for k in blk.keys():
            if hasattr(blk[k], "OC_conv_eqn"):
                calculate_variable_from_constraint(blk[k].OC_conv,
                                                   blk[k].OC_conv_eqn)

            if hasattr(blk[k], "OC_conv_temp_eqn"):
                calculate_variable_from_constraint(blk[k].OC_conv_temp,
                                                   blk[k].OC_conv_temp_eqn)

            for j in blk[k]._params.rate_reaction_idx:
                if hasattr(blk[k], "rate_constant_eqn"):
                    calculate_variable_from_constraint(
                        blk[k].k_rxn[j], blk[k].rate_constant_eqn[j])

                if hasattr(blk[k], "gen_rate_expression"):
                    calculate_variable_from_constraint(
                        blk[k].reaction_rate[j], blk[k].gen_rate_expression[j])

        # Solve property block if non-empty
        free_vars = 0
        for k in blk.keys():
            free_vars += number_unfixed_variables_in_activated_equalities(
                blk[k])

        if free_vars > 0:
            with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc:
                res = solve_indexed_blocks(opt, [blk], tee=slc.tee)
        else:
            res = ""
        init_log.info_high("reactions initialization complete {}.".format(
            idaeslog.condition(res)))

        # ---------------------------------------------------------------------
        # Revert state vars and other variables to pre-initialization states
        # Revert state variables of the primary (solid) state block
        revert_state_vars(blk[k].config.solid_state_block, state_var_flags)

        for k in blk.keys():
            for j in blk[k]._params.gas_component_list:
                if Cflag[k, j] is False:
                    blk[k].gas_state_ref.dens_mol_comp[j].unfix()
            if Dflag[k] is False:
                blk[k].solid_state_ref.dens_mass_skeletal.unfix()

        init_log = idaeslog.getInitLogger(blk.name, outlvl, tag="reactions")
        init_log.info_high('States released.')
Esempio n. 30
0
    def test_nonlinear(self):
        m = ConcreteModel()
        m.x = Var()
        m.y = Var(initialize=0)

        m.c = Constraint(expr=m.x**2 == 16)
        m.x.set_value(1.0) # set an initial value
        calculate_variable_from_constraint(m.x, m.c, linesearch=False)
        self.assertAlmostEqual(value(m.x), 4)

        # test that infeasible constraint throws error
        m.d = Constraint(expr=m.x**2 == -1)
        m.x.set_value(1.25) # set the initial value
        with self.assertRaisesRegexp(
               RuntimeError, 'Iteration limit \(10\) reached'):
           calculate_variable_from_constraint(
               m.x, m.d, iterlim=10, linesearch=False)

        # same problem should throw a linesearch error if linesearch is on
        m.x.set_value(1.25) # set the initial value
        with self.assertRaisesRegexp(
                RuntimeError, "Linesearch iteration limit reached"):
           calculate_variable_from_constraint(
               m.x, m.d, iterlim=10, linesearch=True)

        # same problem should raise an error if initialized at 0
        m.x = 0
        with self.assertRaisesRegexp(
                RuntimeError, "Initial value for variable results in a "
                "derivative value that is very close to zero."):
            calculate_variable_from_constraint(m.x, m.c)

        # same problem should raise a value error if we are asked to
        # solve for a variable that is not present
        with self.assertRaisesRegexp(
                ValueError, "Variable derivative == 0"):
            calculate_variable_from_constraint(m.y, m.c)


        # should succeed with or without a linesearch
        m.e = Constraint(expr=(m.x - 2.0)**2 - 1 == 0)
        m.x.set_value(3.1)
        calculate_variable_from_constraint(m.x, m.e, linesearch=False)
        self.assertAlmostEqual(value(m.x), 3)

        m.x.set_value(3.1)
        calculate_variable_from_constraint(m.x, m.e, linesearch=True)
        self.assertAlmostEqual(value(m.x), 3)


        # we expect this to succeed with the linesearch
        m.f = Constraint(expr=1.0/(1.0+exp(-m.x))-0.5 == 0)
        m.x.set_value(3.0)
        calculate_variable_from_constraint(m.x, m.f, linesearch=True)
        self.assertAlmostEqual(value(m.x), 0)

        # we expect this to fail without a linesearch
        m.x.set_value(3.0)
        with self.assertRaisesRegexp(
                RuntimeError, "Newton's method encountered a derivative "
                "that was too close to zero"):
            calculate_variable_from_constraint(m.x, m.f, linesearch=False)

        # Calculate the bubble point of Benzene.  THe first step
        # computed by calculate_variable_from_constraint will make the
        # second term become complex, and the evaluation will fail.
        # This tests that the algorithm cleanly continues
        m = ConcreteModel()
        m.x = Var()
        m.pc = 48.9e5
        m.tc = 562.2
        m.psc = {'A': -6.98273,
                 'B': 1.33213,
                 'C': -2.62863,
                 'D': -3.33399,
        }
        m.p = 101325
        @m.Constraint()
        def f(m):
            return m.pc * \
                exp((m.psc['A'] * (1 - m.x / m.tc) +
                     m.psc['B'] * (1 - m.x / m.tc)**1.5 +
                     m.psc['C'] * (1 - m.x / m.tc)**3 +
                     m.psc['D'] * (1 - m.x / m.tc)**6
                 ) / (1 - (1 - m.x / m.tc))) - m.p == 0
        m.x.set_value(298.15)
        calculate_variable_from_constraint(m.x, m.f, linesearch=False)
        self.assertAlmostEqual(value(m.x), 353.31855602)
        m.x.set_value(298.15)
        calculate_variable_from_constraint(m.x, m.f, linesearch=True)
        self.assertAlmostEqual(value(m.x), 353.31855602)

        # Starting with an invalid guess (above TC) should raise an
        # exception
        m.x.set_value(600)
        output = six.StringIO()
        with LoggingIntercept(output, 'pyomo', logging.WARNING):
            if six.PY2:
                expectedException = ValueError
            else:
                expectedException = TypeError
            with self.assertRaises(expectedException):
                calculate_variable_from_constraint(m.x, m.f, linesearch=False)
        self.assertIn('Encountered an error evaluating the expression '
                      'at the initial guess', output.getvalue())

        # This example triggers an expression evaluation error if the
        # linesearch is turned off because the first step in Newton's
        # method will cause the LHS to become complex
        m = ConcreteModel()
        m.x = Var()
        m.c = Constraint(expr=(1/m.x**3)**0.5 == 100)
        m.x = .1
        calculate_variable_from_constraint(m.x, m.c, linesearch=True)
        self.assertAlmostEqual(value(m.x), 0.046415888)
        m.x = .1
        output = six.StringIO()
        with LoggingIntercept(output, 'pyomo', logging.WARNING):
            with self.assertRaises(ValueError):
                # Note that the ValueError is different between Python 2
                # and Python 3: in Python 2 it is a specific error
                # "negative number cannot be raised to a fractional
                # power", and We mock up that error in Python 3 by
                # raising a generic ValueError in
                # calculate_variable_from_constraint
                calculate_variable_from_constraint(m.x, m.c, linesearch=False)
        self.assertIn("Newton's method encountered an error evaluating "
                      "the expression.", output.getvalue())

        # This is a completely contrived example where the linesearch
        # hits the iteration limit before Newton's method ever finds a
        # feasible step
        m = ConcreteModel()
        m.x = Var()
        m.c = Constraint(expr=m.x**0.5 == -1e-8)
        m.x = 1e-8#197.932807183
        with self.assertRaisesRegexp(
                RuntimeError, "Linesearch iteration limit reached; "
                "remaining residual = {function evaluation error}"):
            calculate_variable_from_constraint(m.x, m.c, linesearch=True,
                                               alpha_min=.5)
Esempio n. 31
0
    def test_initialize_value(self):
        m = ConcreteModel()
        m.x = Var()
        m.y = Var(initialize=0)
        m.c = Constraint(expr=m.x == 5)

        m.x.set_value(None)
        calculate_variable_from_constraint(m.x, m.c)
        self.assertEqual(value(m.x), 5)

        m.x.set_value(None)
        m.x.setlb(3)
        calculate_variable_from_constraint(m.x, m.c)
        self.assertEqual(value(m.x), 5)

        m.x.set_value(None)
        m.x.setlb(-10)
        calculate_variable_from_constraint(m.x, m.c)
        self.assertEqual(value(m.x), 5)

        m.x.set_value(None)
        m.x.setub(10)
        calculate_variable_from_constraint(m.x, m.c)
        self.assertEqual(value(m.x), 5)

        m.x.set_value(None)
        m.x.setlb(3)
        calculate_variable_from_constraint(m.x, m.c)
        self.assertEqual(value(m.x), 5)

        m.x.set_value(None)
        m.x.setlb(None)
        calculate_variable_from_constraint(m.x, m.c)
        self.assertEqual(value(m.x), 5)

        m.x.set_value(None)
        m.x.setub(-10)
        calculate_variable_from_constraint(m.x, m.c)
        self.assertEqual(value(m.x), 5)

        m.lt = Constraint(expr=m.x <= m.y)
        with self.assertRaisesRegexp(
                ValueError, "Constraint must be an equality constraint"):
            calculate_variable_from_constraint(m.x, m.lt)
Esempio n. 32
0
    def test_initialize_value(self):
        m = ConcreteModel()
        m.x = Var()
        m.y = Var(initialize=0)
        m.c = Constraint(expr=m.x == 5)

        m.x.set_value(None)
        calculate_variable_from_constraint(m.x, m.c)
        self.assertEqual(value(m.x), 5)

        m.x.set_value(None)
        m.x.setlb(3)
        calculate_variable_from_constraint(m.x, m.c)
        self.assertEqual(value(m.x), 5)

        m.x.set_value(None)
        m.x.setlb(-10)
        calculate_variable_from_constraint(m.x, m.c)
        self.assertEqual(value(m.x), 5)

        m.x.set_value(None)
        m.x.setub(10)
        calculate_variable_from_constraint(m.x, m.c)
        self.assertEqual(value(m.x), 5)

        m.x.set_value(None)
        m.x.setlb(3)
        calculate_variable_from_constraint(m.x, m.c)
        self.assertEqual(value(m.x), 5)

        m.x.set_value(None)
        m.x.setlb(None)
        calculate_variable_from_constraint(m.x, m.c)
        self.assertEqual(value(m.x), 5)

        m.x.set_value(None)
        m.x.setub(-10)
        calculate_variable_from_constraint(m.x, m.c)
        self.assertEqual(value(m.x), 5)

        m.lt = Constraint(expr=m.x <= m.y)
        with self.assertRaisesRegex(
                ValueError, "Constraint must be an equality constraint"):
            calculate_variable_from_constraint(m.x, m.lt)
    def initialize(blk,
                   state_args=None,
                   hold_state=False,
                   state_vars_fixed=False,
                   outlvl=idaeslog.NOTSET,
                   solver=None,
                   optarg=None):
        """
        Initialization routine for property package.
        Keyword Arguments:
            state_args : Dictionary with initial guesses for the state vars
                         chosen. Note that if this method is triggered
                         through the control volume, and if initial guesses
                         were not provided at the unit model level, the
                         control volume passes the inlet values as initial
                         guess.
                         Keys for the state_args dictionary are:
                         flow_mass, temperature, and mass_frac_comp
            outlvl : sets output level of initialization routine
            optarg : solver options dictionary object (default=None, use
                     default solver options)
            solver : str indicating which solver to use during
                     initialization (default = None, use default solver)
            hold_state : flag indicating whether the initialization routine
                         should unfix any state variables fixed during
                         initialization (default=False).
                         - True - states varaibles are not unfixed, and
                                 a dict of returned containing flags for
                                 which states were fixed during
                                 initialization.
                        - False - state variables are unfixed after
                                 initialization by calling the
                                 relase_state method
        Returns:
            If hold_states is True, returns a dict containing flags for
            which states were fixed during initialization.
        """
        init_log = idaeslog.getInitLogger(blk.name, outlvl, tag="properties")
        solve_log = idaeslog.getSolveLogger(blk.name, outlvl, tag="properties")

        init_log.info_high('Starting initialization')

        # Deactivate the constraints specific for outlet block i.e.
        # when defined state is False
        for k in blk.keys():
            if blk[k].config.defined_state is False:
                blk[k].sum_component_eqn.deactivate()

        # Fix state variables if not already fixed
        if state_vars_fixed is False:
            flags = fix_state_vars(blk, state_args)
        else:
            # Check when the state vars are fixed already result in dof 0
            for k in blk.keys():
                if degrees_of_freedom(blk[k]) != 0:
                    raise Exception("State vars fixed but degrees of freedom "
                                    "for state block is not zero during "
                                    "initialization.")

        # Create solver
        opt = get_solver(solver, optarg)

        # ---------------------------------------------------------------------
        # Initialise values
        for k in blk.keys():
            if hasattr(blk[k], "density_skeletal_constraint"):
                calculate_variable_from_constraint(
                    blk[k].dens_mass_skeletal,
                    blk[k].density_skeletal_constraint)

            if hasattr(blk[k], "mixture_heat_capacity_eqn"):
                calculate_variable_from_constraint(
                    blk[k].cp_mass, blk[k].mixture_heat_capacity_eqn)

            if hasattr(blk[k], "mixture_enthalpy_eqn"):
                calculate_variable_from_constraint(blk[k].enth_mass,
                                                   blk[k].mixture_enthalpy_eqn)

            for j in blk[k]._params.component_list:

                if hasattr(blk[k], "cp_shomate_eqn"):
                    calculate_variable_from_constraint(
                        blk[k].cp_mol_comp[j], blk[k].cp_shomate_eqn[j])

                if hasattr(blk[k], "enthalpy_shomate_eqn"):
                    calculate_variable_from_constraint(
                        blk[k].enth_mol_comp[j],
                        blk[k].enthalpy_shomate_eqn[j])

        # Solve property block if non-empty
        free_vars = 0
        for k in blk.keys():
            free_vars += number_unfixed_variables_in_activated_equalities(
                blk[k])

        if free_vars > 0:
            with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc:
                res = solve_indexed_blocks(opt, [blk], tee=slc.tee)
        else:
            res = ""
        init_log.info_high("Initialization complete {}.".format(
            idaeslog.condition(res)))

        # ---------------------------------------------------------------------
        if state_vars_fixed is False:
            if hold_state is True:
                return flags
            else:
                blk.release_state(flags)