示例#1
0
    def test_no_strip_domain(self):
        """Test bounds stripping without domain change."""
        m = ConcreteModel()
        m.v0 = Var(bounds=(2, 4))
        m.v1 = Var(domain=NonNegativeReals)
        m.v2 = Var(domain=PositiveReals)
        m.v3 = Var(bounds=(-1, 1))
        m.v4 = Var(domain=Binary)
        m.v5 = Var(domain=Integers, bounds=(15, 16))

        xfrm = TransformationFactory('contrib.strip_var_bounds')
        xfrm.apply_to(m, strip_domains=False, reversible=True)
        self.assertEqual(m.v0.bounds, (None, None))
        self.assertEqual(m.v1.bounds, (0, None))
        self.assertEqual(m.v2.bounds, (0, None))
        self.assertEqual(m.v3.bounds, (None, None))
        self.assertEqual(m.v4.bounds, (0, 1))
        self.assertEqual(m.v5.bounds, (None, None))
        self.assertEqual(m.v0.domain, Reals)
        self.assertEqual(m.v1.domain, NonNegativeReals)
        self.assertEqual(m.v2.domain, PositiveReals)
        self.assertEqual(m.v3.domain, Reals)
        self.assertEqual(m.v4.domain, Binary)
        self.assertEqual(m.v5.domain, Integers)

        xfrm.revert(m)
        self.assertEqual(m.v0.bounds, (2, 4))
        self.assertEqual(m.v1.bounds, (0, None))
        self.assertEqual(m.v2.bounds, (0, None))
        self.assertEqual(m.v3.bounds, (-1, 1))
        self.assertEqual(m.v4.bounds, (0, 1))
        self.assertEqual(m.v5.bounds, (15, 16))
        self.assertEqual(m.v0.domain, Reals)
        self.assertEqual(m.v1.domain, NonNegativeReals)
        self.assertEqual(m.v2.domain, PositiveReals)
        self.assertEqual(m.v3.domain, Reals)
        self.assertEqual(m.v4.domain, Binary)
        self.assertEqual(m.v5.domain, Integers)
示例#2
0
    def test_abs(self):
        from lms2 import DynUnit
        from pyomo.environ import AbstractModel, TransformationFactory
        from pyomo.dae import ContinuousSet

        m = AbstractModel()
        m.time = ContinuousSet()
        m.u = DynUnit()

        data_absdyn = dict(time={None: [0, 15]})

        data = \
            {None:
                {
                    'time': {None: [0, 15]},
                    'u': data_absdyn
                }
            }

        inst = m.create_instance(data)
        TransformationFactory('dae.finite_difference').apply_to(inst, nfe=1)
        self.assertEqual(inst.u.time.data(), (0, 15))
        self.assertEqual(inst.time.data(), (0, 15))
示例#3
0
    def test_cut_is_correct_facet_rescaled_fme(self):
        m = models.to_break_constraint_tolerances()
        TransformationFactory('gdp.cuttingplane').apply_to(
            m, create_cuts=create_cuts_fme, post_process_cut=None)

        cuts = m._pyomo_gdp_cuttingplane_transformation.cuts
        self.assertEqual(len(cuts), 1)

        # we don't get a whole facet. We get 0 <= 129y_1 + 123y_2 - x - y, which
        # is the sum of two facets:
        # 0 <= 2y_1 + 120y_2 - x and
        # 0 <= 127y_1 + 3y_2 - y
        # But this is valid and the only cut needed, so we won't complain.
        cut_extreme_points = [(1, 0, 2, 127), (0, 1, 120, 3)]

        for pt in cut_extreme_points:
            m.x.fix(pt[2])
            m.y.fix(pt[3])
            m.disjunct1.indicator_var.fix(pt[0])
            m.disjunct2.indicator_var.fix(pt[1])
            # tiny bit of numerical error
            self.assertAlmostEqual(value(cuts[0].lower), value(cuts[0].body))
            self.assertLessEqual(value(cuts[0].lower), value(cuts[0].body))
示例#4
0
 def test_link_with_gdp_indicators(self):
     m = _generate_boolean_model(4)
     m.d1 = Disjunct()
     m.d2 = Disjunct()
     m.x = Var()
     m.dd = Disjunct([1, 2])
     m.d1.c = Constraint(expr=m.x >= 2)
     m.d2.c = Constraint(expr=m.x <= 10)
     m.dd[1].c = Constraint(expr=m.x >= 5)
     m.dd[2].c = Constraint(expr=m.x <= 6)
     m.Y[1].associate_binary_var(m.d1.indicator_var)
     m.Y[2].associate_binary_var(m.d2.indicator_var)
     m.Y[3].associate_binary_var(m.dd[1].indicator_var)
     m.Y[4].associate_binary_var(m.dd[2].indicator_var)
     m.p = LogicalConstraint(expr=m.Y[1].implies(lor(m.Y[3], m.Y[4])))
     m.p2 = LogicalConstraint(expr=atmost(2, *m.Y[:]))
     TransformationFactory('core.logical_to_linear').apply_to(m)
     _constrs_contained_within(
         self, [(1, m.dd[1].indicator_var + m.dd[2].indicator_var + 1 -
                 m.d1.indicator_var, None),
                (None, m.d1.indicator_var + m.d2.indicator_var +
                 m.dd[1].indicator_var + m.dd[2].indicator_var, 2)],
         m.logic_to_linear.transformed_constraints)
示例#5
0
 def test_induced_linear_in_disjunct(self):
     m = ConcreteModel()
     m.x = Var([0], bounds=(-3, 8))
     m.y = Var(RangeSet(2), domain=Binary)
     m.logical = ConstraintList()
     m.logical.add(expr=m.y[1] + m.y[2] == 1)
     m.v = Var([1])
     m.v[1].setlb(-2)
     m.v[1].setub(7)
     m.bilinear_outside = Constraint(
         expr=m.x[0] * m.v[1] >= 2)
     m.disjctn = Disjunction(expr=[
         [m.x[0] * m.v[1] == 3,
          2 * m.x[0] == m.y[1] + m.y[2]],
         [m.x[0] * m.v[1] == 4]
     ])
     TransformationFactory('contrib.induced_linearity').apply_to(m)
     self.assertEqual(
         m.disjctn.disjuncts[0].constraint[1].body.polynomial_degree(), 1)
     self.assertEqual(
         m.bilinear_outside.body.polynomial_degree(), 2)
     self.assertEqual(
         m.disjctn.disjuncts[1].constraint[1].body.polynomial_degree(), 2)
示例#6
0
def test_initialize_dyn(build_turbine_dyn):
    """Initialize a turbine model"""
    m = build_turbine_dyn
    hin = iapws95.htpx(T=880, P=2.4233e7)
    discretizer = TransformationFactory('dae.finite_difference')
    discretizer.apply_to(m, nfe=4, wrt=m.fs.time, scheme='BACKWARD')

    # fix inlet
    m.fs.turb.inlet[:].enth_mol.fix(hin)
    m.fs.turb.inlet[:].flow_mol.fix(26000 / 4.0)
    m.fs.turb.inlet[:].pressure.fix(2.4233e7)
    m.fs.turb.flow_coeff[:].fix()

    assert (degrees_of_freedom(m) == 0)
    m.fs.turb.initialize()

    eq_cons = activated_equalities_generator(m)
    for c in eq_cons:
        assert (abs(c.body() - c.lower) < 1e-4)

    m.display()

    assert (degrees_of_freedom(m) == 0)
示例#7
0
    def test_reclassify_deactivated_disjuncts(self):
        m = ConcreteModel()
        m.d = Disjunct([1, 2, 3])
        m.disjunction = Disjunction(expr=[m.d[1], m.d[2], m.d[3]])
        m.d[1].deactivate()
        m.d[2].indicator_var = True
        m.d[3].indicator_var = False

        TransformationFactory('gdp.fix_disjuncts').apply_to(m)

        self.assertTrue(m.d[1].indicator_var.fixed)
        self.assertFalse(value(m.d[1].indicator_var))
        self.assertFalse(m.d[1].active)
        self.assertEqual(m.d[1].ctype, Block)

        self.assertTrue(m.d[2].indicator_var.fixed)
        self.assertTrue(value(m.d[2].indicator_var))
        self.assertTrue(m.d[2].active)
        self.assertTrue(m.d[3].indicator_var.fixed)
        self.assertFalse(value(m.d[3].indicator_var))
        self.assertFalse(m.d[3].active)
        self.assertEqual(m.d[1].ctype, Block)
        self.assertEqual(m.d[2].ctype, Block)
示例#8
0
    def test_disc_second_order_backward(self):
        m = self.m.clone()
        m.dv1dt2 = DerivativeVar(m.v1, wrt=(m.t, m.t))
        disc = TransformationFactory('dae.finite_difference')
        disc.apply_to(m, nfe=2)

        self.assertTrue(hasattr(m, 'dv1dt2_disc_eq'))
        self.assertEqual(len(m.dv1dt2_disc_eq), 1)
        self.assertEqual(len(m.v1), 3)

        self.assertTrue(hasattr(m, '_pyomo_dae_reclassified_derivativevars'))
        self.assertIn(m.dv1, m._pyomo_dae_reclassified_derivativevars)
        self.assertIn(m.dv1dt2, m._pyomo_dae_reclassified_derivativevars)

        output = \
"""\
dv1dt2_disc_eq : Size=1, Index=t, Active=True
    Key : Lower : Body                                           : Upper : Active
     10 :   0.0 : dv1dt2[10] - 0.04*(v1[10] - 2*v1[5.0] + v1[0]) :   0.0 :   True
"""
        out = StringIO()
        m.dv1dt2_disc_eq.pprint(ostream=out)
        self.assertEqual(output, out.getvalue())
示例#9
0
    def test_instanciate(self):
        from lms2 import AbsLModel
        from lms2 import ScalablePowerSource

        import pandas as pd
        from pyomo.dae import ContinuousSet
        from pyomo.environ import TransformationFactory

        m = AbsLModel()
        m.time = ContinuousSet()
        m.u = ScalablePowerSource(curtailable=False)

        df = pd.Series({0: 0, 1: 1, 2: 2, 3: 1, 4: 0})
        data_u = {
            'time': {
                None: [0, 4]
            },
            'profile_index': {
                None: df.index
            },
            'profile_value': df.to_dict()
        }

        data = \
            {None:
                {
                    'time': {None: [0, 4]},
                    'u': data_u
                }
            }
        inst = m.create_instance(data)
        TransformationFactory('dae.finite_difference').apply_to(inst, nfe=4)

        self.assertFalse(hasattr(inst.u, 'p_curt'))
        self.assertTrue(hasattr(inst.u, 'p'))
        self.assertTrue(hasattr(inst.u, 'p_scaled'))
        self.assertTrue(hasattr(inst.u, 'scale_fact'))
示例#10
0
    def test_disc_second_order_legendre(self):
        m = self.m.clone()
        m.dv1dt2 = DerivativeVar(m.v1, wrt=(m.t, m.t))
        disc = TransformationFactory('dae.collocation')
        disc.apply_to(m, nfe=2, ncp=2, scheme='LAGRANGE-LEGENDRE')

        self.assertTrue(hasattr(m, 'dv1dt2_disc_eq'))
        self.assertTrue(hasattr(m, 'v1_t_cont_eq'))
        self.assertTrue(len(m.dv1dt2_disc_eq) == 4)
        self.assertTrue(len(m.v1_t_cont_eq) == 2)
        self.assertTrue(len(m.v1) == 7)

        self.assertTrue(hasattr(m, '_pyomo_dae_reclassified_derivativevars'))
        self.assertTrue(m.dv1 in m._pyomo_dae_reclassified_derivativevars)
        self.assertTrue(m.dv1dt2 in m._pyomo_dae_reclassified_derivativevars)

        repn_baseline = {
            id(m.dv1dt2[1.056624]): 1,
            id(m.v1[0]): -0.48,
            id(m.v1[1.056624]): 0.65569,
            id(m.v1[3.943376]): -0.17569
        }

        repn = generate_standard_repn(m.dv1dt2_disc_eq[1.056624].body)
        repn_gen = repn_to_rounded_dict(repn, 5)
        self.assertEqual(repn_baseline, repn_gen)

        repn_baseline = {
            id(m.dv1dt2[6.056624]): 1,
            id(m.v1[5.0]): -0.48,
            id(m.v1[6.056624]): 0.65569,
            id(m.v1[8.943376]): -0.17569
        }

        repn = generate_standard_repn(m.dv1dt2_disc_eq[6.056624].body)
        repn_gen = repn_to_rounded_dict(repn, 5)
        self.assertEqual(repn_baseline, repn_gen)
示例#11
0
 def test_xfrm_atleast_nested(self):
     m = _generate_boolean_model(4)
     m.p = LogicalConstraint(expr=atleast(
         1,
         atleast(2, m.Y[1], m.Y[1].lor(m.Y[2]), m.Y[2]).lor(m.Y[3]),
         m.Y[4]))
     TransformationFactory('core.logical_to_linear').apply_to(m)
     Y_aug = m.logic_to_linear.augmented_vars
     self.assertEqual(len(Y_aug), 3)
     _constrs_contained_within(
         self,
         [(1, Y_aug[1].get_associated_binary() +
           m.Y[4].get_associated_binary(), None),
          (1, 1 - Y_aug[2].get_associated_binary() +
           Y_aug[1].get_associated_binary(), None),
          (1, 1 - m.Y[3].get_associated_binary() +
           Y_aug[1].get_associated_binary(), None),
          (1, Y_aug[2].get_associated_binary() +
           m.Y[3].get_associated_binary() + 1 -
           Y_aug[1].get_associated_binary(), None),
          (1, 1 - m.Y[1].get_associated_binary() +
           Y_aug[3].get_associated_binary(), None),
          (1, 1 - m.Y[2].get_associated_binary() +
           Y_aug[3].get_associated_binary(), None),
          (1,
           m.Y[1].get_associated_binary() + m.Y[2].get_associated_binary() +
           1 - Y_aug[3].get_associated_binary(), None),
          (None, 2 - 2 * (1 - Y_aug[2].get_associated_binary()) -
           (m.Y[1].get_associated_binary() +
            Y_aug[3].get_associated_binary() +
            m.Y[2].get_associated_binary()), 0),
          (None, m.Y[1].get_associated_binary() +
           Y_aug[3].get_associated_binary() +
           m.Y[2].get_associated_binary() -
           (1 + 2 * Y_aug[2].get_associated_binary()), 0)],
         m.logic_to_linear.transformed_constraints)
示例#12
0
 def test_cuts_are_correct_facets_fme(self):
     m = models.makeTwoTermDisj_boxes()
     TransformationFactory('gdp.cuttingplane').apply_to(
         m, create_cuts=create_cuts_fme, post_process_cut=None, 
         zero_tolerance=0)
     # This would also be a valid cut, it just doesn't happen to be what we
     # choose.
     # facet_extreme_pts = [
     #     (1,0,3,1),
     #     (1,0,3,2),
     #     (0,1,1,3),
     #     (0,1,1,4)
     # ]
     facet_extreme_pts = [
         (0,1,1,3),
         (0,1,2,3),
         (1,0,3,1),
         (1,0,4,1)
     ]
     
     cuts = m._pyomo_gdp_cuttingplane_transformation.cuts
     # Here, we get just one facet
     self.assertEqual(len(cuts), 1)
     cut = cuts[0]
     cut_expr = cut.body
     lower = cut.lower
     upper = cut.upper
     for pt in facet_extreme_pts:
         m.d[0].indicator_var.fix(pt[0])
         m.d[1].indicator_var.fix(pt[1])
         m.x.fix(pt[2])
         m.y.fix(pt[3])
         if lower is not None:
             self.assertEqual(value(lower), value(cut_expr))
         if upper is not None:
             self.assertEqual(value(upper), value(cut_expr))
示例#13
0
    def test_disc_multi_index2(self):
        m = self.m.clone()
        m.t2 = ContinuousSet(bounds=(0, 5))
        m.v2 = Var(m.t, m.t2)
        m.dv2dt = DerivativeVar(m.v2, wrt=m.t)
        m.dv2dt2 = DerivativeVar(m.v2, wrt=m.t2)

        disc = TransformationFactory('dae.finite_difference')
        disc.apply_to(m, nfe=2)

        self.assertTrue(hasattr(m, 'dv2dt_disc_eq'))
        self.assertTrue(hasattr(m, 'dv2dt2_disc_eq'))
        self.assertEqual(len(m.dv2dt_disc_eq), 6)
        self.assertEqual(len(m.dv2dt2_disc_eq), 6)
        self.assertEqual(len(m.v2), 9)

        expected_t_disc_points = [0, 5.0, 10]
        expected_t2_disc_points = [0, 2.5, 5]

        for idx, val in enumerate(list(m.t)):
            self.assertAlmostEqual(val, expected_t_disc_points[idx])

        for idx, val in enumerate(list(m.t2)):
            self.assertAlmostEqual(val, expected_t2_disc_points[idx])
    def build(self):

        # Call UnitModel.build to setup dynamics
        super(HydrogenTurbineData, self).build()

        self.compressor = Compressor(
            default={"property_package": self.config.property_package})

        self.stoic_reactor = StoichiometricReactor(
            default={
                "property_package": self.config.property_package,
                "reaction_package": self.config.reaction_package,
                "has_heat_of_reaction": True,
                "has_heat_transfer": False,
                "has_pressure_change": False
            })

        self.turbine = Turbine(
            default={"property_package": self.config.property_package})

        # Declare var for reactor conversion
        self.stoic_reactor.conversion = Var(initialize=0.75, bounds=(0, 1))

        self.stoic_reactor.conv_constraint = Constraint(
            expr=self.stoic_reactor.conversion *
            self.stoic_reactor.inlet.mole_frac_comp[0, "hydrogen"] == (
                self.stoic_reactor.inlet.mole_frac_comp[0, "hydrogen"] -
                self.stoic_reactor.outlet.mole_frac_comp[0, "hydrogen"]))

        # Connect arcs
        self.comp_to_reactor = Arc(source=self.compressor.outlet,
                                   destination=self.stoic_reactor.inlet)
        self.reactor_to_turbine = Arc(source=self.stoic_reactor.outlet,
                                      destination=self.turbine.inlet)

        TransformationFactory("network.expand_arcs").apply_to(self)
示例#15
0
def solve_flowsheet(**desal_kwargs):
    m = ConcreteModel()
    m.fs = FlowsheetBlock(default={"dynamic": False})
    build(m, **desal_kwargs)
    TransformationFactory("network.expand_arcs").apply_to(m)

    # scale
    scale(m, **desal_kwargs)
    calculate_scaling_factors(m)

    # initialize
    m.fs.feed.initialize()
    propagate_state(m.fs.s_pretrt_tb)
    initialize(m, **desal_kwargs)

    check_dof(m)
    solve_block(m, tee=False, fail_flag=True)

    # report
    print("==================================="
          "\n          Simulation          ")
    report(m, **desal_kwargs)

    return m
示例#16
0
 def test_relax_integrality1(self):
     # Coverage of the _clear_attribute method
     self.model.A = RangeSet(1,4)
     self.model.a = Var()
     self.model.b = Var(within=self.model.A)
     self.model.c = Var(within=NonNegativeIntegers)
     self.model.d = Var(within=Integers, bounds=(-2,3))
     self.model.e = Var(within=Boolean)
     self.model.f = Var(domain=Boolean)
     instance=self.model.create_instance()
     xfrm = TransformationFactory('core.relax_integer_vars')
     rinst = xfrm.create_using(instance)
     self.assertEqual(type(rinst.a.domain), RealSet)
     self.assertEqual(type(rinst.b.domain), RealSet)
     self.assertEqual(type(rinst.c.domain), RealSet)
     self.assertEqual(type(rinst.d.domain), RealSet)
     self.assertEqual(type(rinst.e.domain), RealSet)
     self.assertEqual(type(rinst.f.domain), RealSet)
     self.assertEqual(rinst.a.bounds, instance.a.bounds)
     self.assertEqual(rinst.b.bounds, instance.b.bounds)
     self.assertEqual(rinst.c.bounds, instance.c.bounds)
     self.assertEqual(rinst.d.bounds, instance.d.bounds)
     self.assertEqual(rinst.e.bounds, instance.e.bounds)
     self.assertEqual(rinst.f.bounds, instance.f.bounds)
示例#17
0
    def test_mgv1(self):

        from lms2 import MainGridV1
        from pyomo.environ import AbstractModel, TransformationFactory, Param, Var
        from pyomo.dae import ContinuousSet
        from pyomo.network import Port

        m = AbstractModel()
        m.time = ContinuousSet(bounds=(0, 10))
        m.mg = MainGridV1()

        data_main_grid_v1 = {
            'time': {
                None: [0, 2]
            },
            'pmax': {
                None: +100.0
            },
            'pmin': {
                None: -100.0
            },
            'cost_in': {
                None: 0.15
            },
            'cost_out': {
                None: 0.15
            }
        }

        data = {None: {'time': {None: [0, 10]}, 'mg': data_main_grid_v1}}

        inst = m.create_instance(data)
        TransformationFactory('dae.finite_difference').apply_to(inst, nfe=2)

        self.assertTrue(hasattr(m.mg, 'outlet'))
        self.assertIsInstance(m.mg.outlet, Port)
示例#18
0
 def test_relax_integrality2(self):
     # Coverage of the _clear_attribute method
     self.model.A = RangeSet(1,4)
     self.model.a = Var([1,2,3], dense=True)
     self.model.b = Var([1,2,3], within=self.model.A, dense=True)
     self.model.c = Var([1,2,3], within=NonNegativeIntegers, dense=True)
     self.model.d = Var([1,2,3], within=Integers, bounds=(-2,3), dense=True)
     self.model.e = Var([1,2,3], within=Boolean, dense=True)
     self.model.f = Var([1,2,3], domain=Boolean, dense=True)
     instance=self.model.create_instance()
     xfrm = TransformationFactory('core.relax_integer_vars')
     rinst = xfrm.create_using(instance)
     self.assertEqual(type(rinst.a[1].domain), RealSet)
     self.assertEqual(type(rinst.b[1].domain), RealSet)
     self.assertEqual(type(rinst.c[1].domain), RealSet)
     self.assertEqual(type(rinst.d[1].domain), RealSet)
     self.assertEqual(type(rinst.e[1].domain), RealSet)
     self.assertEqual(type(rinst.f[1].domain), RealSet)
     self.assertEqual(rinst.a[1].bounds, instance.a[1].bounds)
     self.assertEqual(rinst.b[1].bounds, instance.b[1].bounds)
     self.assertEqual(rinst.c[1].bounds, instance.c[1].bounds)
     self.assertEqual(rinst.d[1].bounds, instance.d[1].bounds)
     self.assertEqual(rinst.e[1].bounds, instance.e[1].bounds)
     self.assertEqual(rinst.f[1].bounds, instance.f[1].bounds)
示例#19
0
    def test_get_stream_table_contents(self):
        m = ConcreteModel()
        m.fs = FlowsheetBlock(default={"dynamic": False})

        m.fs.props = PhysicalParameterTestBlock()
        m.fs.config.default_property_package = m.fs.props

        m.fs.unit1 = Heater()
        m.fs.unit2 = Heater()

        m.fs.stream = Arc(source=m.fs.unit1.outlet,
                          destination=m.fs.unit2.inlet)
        TransformationFactory("network.expand_arcs").apply_to(m)

        df = m.fs._get_stream_table_contents()

        assert df.loc["pressure"]["stream"] == 1e5
        assert df.loc["temperature"]["stream"] == 300
        assert df.loc["component_flow_phase ('p1', 'c1')"]["stream"] == 2.0
        assert df.loc["component_flow_phase ('p1', 'c2')"]["stream"] == 2.0
        assert df.loc["component_flow_phase ('p2', 'c1')"]["stream"] == 2.0
        assert df.loc["component_flow_phase ('p2', 'c2')"]["stream"] == 2.0

        m.fs.report()
示例#20
0
    def test_zero_term_removal(self):
        """Test for removing zero terms from linear constraints."""
        m = ConcreteModel()
        m.v0 = Var()
        m.v1 = Var()
        m.v2 = Var()
        m.v3 = Var()
        m.c = Constraint(expr=m.v0 == m.v1 * m.v2 + m.v3)
        m.c2 = Constraint(expr=m.v1 * m.v2 + m.v3 <= m.v0)
        m.c3 = Constraint(expr=m.v0 <= m.v1 * m.v2 + m.v3)
        m.c4 = Constraint(expr=EXPR.inequality(1, m.v1 * m.v2 + m.v3, 3))
        m.v1.fix(0)

        TransformationFactory('contrib.remove_zero_terms').apply_to(m)
        m.v1.unfix()
        # Check that the term no longer exists
        self.assertFalse(
            any(id(m.v1) == id(v) for v in EXPR.identify_variables(m.c.body)))
        self.assertFalse(
            any(id(m.v1) == id(v) for v in EXPR.identify_variables(m.c2.body)))
        self.assertFalse(
            any(id(m.v1) == id(v) for v in EXPR.identify_variables(m.c3.body)))
        self.assertFalse(
            any(id(m.v1) == id(v) for v in EXPR.identify_variables(m.c4.body)))
示例#21
0
 def test_induced_linearity_case2(self):
     m = ConcreteModel()
     m.x = Var([0], bounds=(-3, 8))
     m.y = Var(RangeSet(4), domain=Binary)
     m.z = Var(domain=Integers, bounds=(-1, 2))
     m.constr = Constraint(expr=m.x[0] == m.y[1] + 2 * m.y[2] + m.y[3] +
                           2 * m.y[4] + m.z)
     m.logical = ConstraintList()
     m.logical.add(expr=m.y[1] + m.y[2] == 1)
     m.logical.add(expr=m.y[3] + m.y[4] == 1)
     m.logical.add(expr=m.y[2] + m.y[4] <= 1)
     m.b = Var(bounds=(-2, 7))
     m.c = Var()
     m.bilinear = Constraint(expr=(m.x[0] - 3) * (m.b + 2) -
                             (m.c + 4) * m.b + exp(m.b**2) * m.x[0] <= m.c)
     TransformationFactory('contrib.induced_linearity').apply_to(m)
     xfrmed_blk = m._induced_linearity_info.x0_b_bilinear
     self.assertSetEqual(set(xfrmed_blk.valid_values), set([1, 2, 3, 4, 5]))
     select_one_repn = generate_standard_repn(
         xfrmed_blk.select_one_value.body)
     self.assertEqual(
         ComponentSet(select_one_repn.linear_vars),
         ComponentSet(xfrmed_blk.x_active[i]
                      for i in xfrmed_blk.valid_values))
示例#22
0
    def test_disc_invalid_options(self):
        m = self.m.clone()

        try:
            TransformationFactory('dae.finite_difference').apply_to(m, wrt=m.s)
            self.fail('Expected TypeError')
        except TypeError:
            pass

        try:
            TransformationFactory('dae.finite_difference').apply_to(m, nfe=-1)
            self.fail('Expected ValueError')
        except ValueError:
            pass

        try:
            TransformationFactory('dae.finite_difference').apply_to(
                m, scheme='foo')
            self.fail('Expected ValueError')
        except ValueError:
            pass

        TransformationFactory('dae.finite_difference').apply_to(m, wrt=m.t)
        try:
            TransformationFactory('dae.finite_difference').apply_to(m, wrt=m.t)
            self.fail('Expected ValueError')
        except ValueError:
            pass

        m = self.m.clone()
        disc = TransformationFactory('dae.finite_difference')
        disc.apply_to(m)
        try:
            disc.apply_to(m)
            self.fail('Expected ValueError')
        except ValueError:
            pass
示例#23
0
def main():
    """
    Make the flowsheet object, fix some variables, and solve the problem
    """
    # Create a Concrete Model as the top level object
    m = ConcreteModel()

    # Add a flowsheet object to the model
    m.fs = FlowsheetBlock(default={"dynamic": False})

    # Add property packages to flowsheet library
    m.fs.thermo_params = thermo_props.SaponificationParameterBlock()
    m.fs.reaction_params = reaction_props.SaponificationReactionParameterBlock(
        default={"property_package": m.fs.thermo_params})

    # Create unit models
    m.fs.Tank1 = CSTR(
        default={
            "property_package": m.fs.thermo_params,
            "reaction_package": m.fs.reaction_params,
            "has_equilibrium_reactions": False,
            "has_heat_of_reaction": True,
            "has_heat_transfer": True,
            "has_pressure_change": False
        })
    m.fs.Tank2 = CSTR(
        default={
            "property_package": m.fs.thermo_params,
            "reaction_package": m.fs.reaction_params,
            "has_equilibrium_reactions": False,
            "has_heat_of_reaction": True,
            "has_heat_transfer": True,
            "has_pressure_change": False
        })

    # Make Streams to connect units
    m.fs.stream = Arc(source=m.fs.Tank1.outlet, destination=m.fs.Tank2.inlet)

    TransformationFactory("network.expand_arcs").apply_to(m)

    # Set inlet and operating conditions, and some initial conditions.
    m.fs.Tank1.inlet.flow_vol[0].fix(1.0)
    m.fs.Tank1.inlet.conc_mol_comp[0, "H2O"].fix(55388.0)
    m.fs.Tank1.inlet.conc_mol_comp[0, "NaOH"].fix(100.0)
    m.fs.Tank1.inlet.conc_mol_comp[0, "EthylAcetate"].fix(100.0)
    m.fs.Tank1.inlet.conc_mol_comp[0, "SodiumAcetate"].fix(0.0)
    m.fs.Tank1.inlet.conc_mol_comp[0, "Ethanol"].fix(0.0)

    m.fs.Tank1.inlet.temperature.fix(303.15)
    m.fs.Tank1.inlet.pressure.fix(101325.0)

    m.fs.Tank1.volume.fix(1.0)
    m.fs.Tank1.heat_duty.fix(0.0)

    m.fs.Tank2.volume.fix(1.0)
    m.fs.Tank2.heat_duty.fix(0.0)

    # Initialize Units
    m.fs.Tank1.initialize()
    m.fs.Tank2.initialize(
        state_args={
            "flow_vol": 1.0,
            "conc_mol_comp": {
                "H2O": 55388.0,
                "NaOH": 100.0,
                "EthylAcetate": 100.0,
                "SodiumAcetate": 0.0,
                "Ethanol": 0.0
            },
            "temperature": 303.15,
            "pressure": 101325.0
        })

    # Create a solver
    solver = SolverFactory('ipopt')
    results = solver.solve(m, tee=False)

    # Print results
    print(results)
    print()
    print("Results")
    print()
    print("Tank 1 Outlet")
    m.fs.Tank1.outlet.display()
    print()
    print("Tank 2 Outlet")
    m.fs.Tank2.outlet.display()

    # For testing purposes
    return (m, results)
示例#24
0
def build(number_of_stages=2):
    # ---building model---
    m = ConcreteModel()

    m.fs = FlowsheetBlock(default={"dynamic": False})
    m.fs.properties = props.NaClParameterBlock()
    m.fs.costing = WaterTAPCosting()

    m.fs.NumberOfStages = Param(initialize=number_of_stages)
    m.fs.StageSet = RangeSet(m.fs.NumberOfStages)
    m.fs.LSRRO_StageSet = RangeSet(2, m.fs.NumberOfStages)
    m.fs.NonFinal_StageSet = RangeSet(m.fs.NumberOfStages-1)

    m.fs.feed = Feed(default={'property_package': m.fs.properties})
    m.fs.product = Product(default={'property_package': m.fs.properties})
    m.fs.disposal = Product(default={'property_package': m.fs.properties})

    # Add the mixers
    m.fs.Mixers = Mixer(m.fs.NonFinal_StageSet, default={
            "property_package": m.fs.properties,
            "momentum_mixing_type": MomentumMixingType.equality,  # booster pump will match pressure
            "inlet_list": ['upstream', 'downstream']})

    total_pump_work = 0
    # Add the pumps
    m.fs.PrimaryPumps = Pump(m.fs.StageSet, default={"property_package": m.fs.properties})
    for pump in m.fs.PrimaryPumps.values():
        pump.costing = UnitModelCostingBlock(default={
                "flowsheet_costing_block":m.fs.costing})
        m.fs.costing.cost_flow(pyunits.convert(pump.work_mechanical[0], to_units=pyunits.kW), "electricity")

    # Add the equalizer pumps
    m.fs.BoosterPumps = Pump(m.fs.LSRRO_StageSet, default={"property_package": m.fs.properties})
    for pump in m.fs.BoosterPumps.values():
        pump.costing = UnitModelCostingBlock(default={
                "flowsheet_costing_block":m.fs.costing})
        m.fs.costing.cost_flow(pyunits.convert(pump.work_mechanical[0], to_units=pyunits.kW), "electricity")

    # Add the stages ROs
    m.fs.ROUnits = ReverseOsmosis0D(m.fs.StageSet, default={
            "property_package": m.fs.properties,
            "has_pressure_change": True,
            "pressure_change_type": PressureChangeType.calculated,
            "mass_transfer_coefficient": MassTransferCoefficient.calculated,
            "concentration_polarization_type": ConcentrationPolarizationType.calculated})
    for ro_unit in m.fs.ROUnits.values():
        ro_unit.costing = UnitModelCostingBlock(default={
                "flowsheet_costing_block":m.fs.costing})

    # Add EnergyRecoveryDevice
    m.fs.EnergyRecoveryDevice = Pump(default={"property_package": m.fs.properties})
    m.fs.EnergyRecoveryDevice.costing = UnitModelCostingBlock(default={
            "flowsheet_costing_block":m.fs.costing,
            "costing_method_arguments":{"pump_type":PumpType.energy_recovery_device}})
    m.fs.costing.cost_flow(pyunits.convert(m.fs.EnergyRecoveryDevice.work_mechanical[0], to_units=pyunits.kW), "electricity")

    # additional variables or expressions
    # system water recovery
    m.fs.water_recovery = Var(
            initialize=0.5,
            bounds=(0, 1),
            domain=NonNegativeReals,
            units=pyunits.dimensionless,
            doc='System Water Recovery')
    m.fs.eq_water_recovery = Constraint(expr=\
              sum(m.fs.feed.flow_mass_phase_comp[0,'Liq',:]) * m.fs.water_recovery == \
              sum(m.fs.product.flow_mass_phase_comp[0,'Liq',:]) )

    # costing
    m.fs.costing.cost_process()
    product_flow_vol_total = m.fs.product.properties[0].flow_vol
    m.fs.costing.add_LCOW(product_flow_vol_total)
    m.fs.costing.add_specific_energy_consumption(product_flow_vol_total)

    # objective
    m.fs.objective = Objective(expr=m.fs.costing.LCOW)

    # connections

    # Connect the feed to the first pump
    m.fs.feed_to_pump = Arc(source=m.fs.feed.outlet, destination=m.fs.PrimaryPumps[1].inlet)

    # Connect the primary RO permeate to the product
    m.fs.primary_RO_to_product = Arc(source=m.fs.ROUnits[1].permeate, destination=m.fs.product.inlet)

    # Connect the Pump n to the Mixer n
    m.fs.pump_to_mixer = Arc(m.fs.NonFinal_StageSet,
            rule=lambda fs,n : {'source':fs.PrimaryPumps[n].outlet,
                                'destination':fs.Mixers[n].upstream})

    # Connect the Mixer n to the Stage n
    m.fs.mixer_to_stage = Arc(m.fs.NonFinal_StageSet,
            rule=lambda fs,n : {'source':fs.Mixers[n].outlet,
                                'destination':fs.ROUnits[n].inlet})

    # Connect the Stage n to the Pump n+1
    m.fs.stage_to_pump = Arc(m.fs.NonFinal_StageSet,
            rule=lambda fs,n : {'source':fs.ROUnits[n].retentate,
                                'destination':fs.PrimaryPumps[n+1].inlet})

    # Connect the Stage n to the Eq Pump n
    m.fs.stage_to_eq_pump = Arc(m.fs.LSRRO_StageSet,
            rule=lambda fs,n : {'source':fs.ROUnits[n].permeate,
                                'destination':fs.BoosterPumps[n].inlet})

    # Connect the Eq Pump n to the Mixer n-1
    m.fs.eq_pump_to_mixer = Arc(m.fs.LSRRO_StageSet,
            rule=lambda fs,n : {'source':fs.BoosterPumps[n].outlet,
                                'destination':fs.Mixers[n-1].downstream})

    # Connect the Pump N to the Stage N
    last_stage = m.fs.StageSet.last()
    m.fs.pump_to_stage = Arc(source=m.fs.PrimaryPumps[last_stage].outlet,
            destination=m.fs.ROUnits[last_stage].inlet)

    # Connect Final Stage to EnergyRecoveryDevice Pump
    m.fs.stage_to_erd = Arc(source=m.fs.ROUnits[last_stage].retentate,
            destination=m.fs.EnergyRecoveryDevice.inlet)

    # Connect the EnergyRecoveryDevice to the disposal
    m.fs.erd_to_disposal = Arc(source=m.fs.EnergyRecoveryDevice.outlet,
            destination=m.fs.disposal.inlet)

    # additional bounding
    for b in m.component_data_objects(Block, descend_into=True):
        # NaCl solubility limit
        if hasattr(b, 'mass_frac_phase_comp'):
            b.mass_frac_phase_comp['Liq', 'NaCl'].setub(0.26)

    TransformationFactory("network.expand_arcs").apply_to(m)

    return m
示例#25
0
    m.use4implies6or7 = LogicalConstraint(
        expr=m.Y[4].implies(lor(m.Y[6], m.Y[7])))
    m.use3implies8 = LogicalConstraint(expr=m.Y[3].implies(m.Y[8]))
    m.use6or7implies4 = LogicalConstraint(
        expr=lor(m.Y[6], m.Y[7]).implies(m.Y[4]))
    m.use6or7 = LogicalConstraint(expr=m.Y[6].xor(m.Y[7]))
    """Profit (objective) function definition"""
    m.profit = Objective(expr=sum(m.yCF[unit] for unit in m.units) +
                         sum(m.flow[stream] * CV[stream]
                             for stream in m.streams) + CONSTANT,
                         sense=minimize)
    """Bound definitions"""
    # x (flow) upper bounds
    x_ubs = {3: 2, 5: 2, 9: 2, 10: 1, 14: 1, 17: 2, 19: 2, 21: 2, 25: 3}
    for i, x_ub in x_ubs.item():
        m.flow[i].setub(x_ub)

    # Optimal solution uses units 2, 4, 6, 8 with objective value 68.

    return m


if __name__ == "__main__":
    m = build_eight_process_flowsheet()
    from pyomo.environ import TransformationFactory
    TransformationFactory('core.logical_to_linear').apply_to(m)
    SolverFactory('gdpopt').solve(m, tee=True)
    update_boolean_vars_from_binary(m)
    m.Y.display()
    m.flow.display()
示例#26
0
def test_initialize_by_time_element():
    horizon = 6
    time_set = [0, horizon]
    ntfe = 60  # For a finite element every six seconds
    ntcp = 2
    m = ConcreteModel(name='CSTR model for testing')
    m.fs = FlowsheetBlock(default={
        'dynamic': True,
        'time_set': time_set,
        'time_units': pyunits.minute
    })

    m.fs.properties = AqueousEnzymeParameterBlock()
    m.fs.reactions = EnzymeReactionParameterBlock(
        default={'property_package': m.fs.properties})
    m.fs.cstr = CSTR(
        default={
            "property_package": m.fs.properties,
            "reaction_package": m.fs.reactions,
            "material_balance_type": MaterialBalanceType.componentTotal,
            "energy_balance_type": EnergyBalanceType.enthalpyTotal,
            "momentum_balance_type": MomentumBalanceType.none,
            "has_heat_of_reaction": True
        })

    # Time discretization
    disc = TransformationFactory('dae.collocation')
    disc.apply_to(m,
                  wrt=m.fs.time,
                  nfe=ntfe,
                  ncp=ntcp,
                  scheme='LAGRANGE-RADAU')

    # Fix geometry variables
    m.fs.cstr.volume[0].fix(1.0)

    # Fix initial conditions:
    for p, j in m.fs.properties.phase_list * m.fs.properties.component_list:
        if j == 'Solvent':
            continue
        m.fs.cstr.control_volume.material_holdup[0, p, j].fix(0)

    # Fix inlet conditions
    # This is a huge hack because I didn't know that the proper way to
    # have multiple inlets to a CSTR was to use a mixer.
    # I 'combine' both my inlet streams before sending them to the CSTR.
    for t, j in m.fs.time * m.fs.properties.component_list:
        if t <= 2:
            if j == 'E':
                m.fs.cstr.inlet.conc_mol[t, j].fix(11.91 * 0.1 / 2.2)
            elif j == 'S':
                m.fs.cstr.inlet.conc_mol[t, j].fix(12.92 * 2.1 / 2.2)
            elif j != 'Solvent':
                m.fs.cstr.inlet.conc_mol[t, j].fix(0)
        elif t <= 4:
            if j == 'E':
                m.fs.cstr.inlet.conc_mol[t, j].fix(5.95 * 0.1 / 2.2)
            elif j == 'S':
                m.fs.cstr.inlet.conc_mol[t, j].fix(12.92 * 2.1 / 2.2)
            elif j != 'Solvent':
                m.fs.cstr.inlet.conc_mol[t, j].fix(0)
        else:
            if j == 'E':
                m.fs.cstr.inlet.conc_mol[t, j].fix(8.95 * 0.1 / 2.2)
            elif j == 'S':
                m.fs.cstr.inlet.conc_mol[t, j].fix(16.75 * 2.1 / 2.2)
            elif j != 'Solvent':
                m.fs.cstr.inlet.conc_mol[t, j].fix(0)

    m.fs.cstr.inlet.conc_mol[:, 'Solvent'].fix(1.)

    m.fs.cstr.inlet.flow_vol.fix(2.2)
    m.fs.cstr.inlet.temperature.fix(300)

    # Fix outlet conditions
    m.fs.cstr.outlet.flow_vol.fix(2.2)
    m.fs.cstr.outlet.temperature[m.fs.time.first()].fix(300)

    assert degrees_of_freedom(m) == 0

    initialize_by_time_element(m.fs, m.fs.time, solver=solver)

    assert degrees_of_freedom(m) == 0

    # Assert that the result looks how we expect
    assert m.fs.cstr.outlet.conc_mol[0, 'S'].value == 0
    assert abs(m.fs.cstr.outlet.conc_mol[2, 'S'].value - 11.389) < 1e-2
    assert abs(m.fs.cstr.outlet.conc_mol[4, 'P'].value - 0.2191) < 1e-3
    assert abs(m.fs.cstr.outlet.conc_mol[6, 'E'].value - 0.0327) < 1e-3
    assert abs(m.fs.cstr.outlet.temperature[6].value - 289.7) < 1

    # Assert that model is still fixed and deactivated as expected
    assert (m.fs.cstr.control_volume.material_holdup[m.fs.time.first(), 'aq',
                                                     'S'].fixed)

    for t in m.fs.time:
        if t != m.fs.time.first():
            assert (not m.fs.cstr.control_volume.material_holdup[t, 'aq',
                                                                 'S'].fixed)

            assert not m.fs.cstr.outlet.temperature[t].fixed
        assert (
            m.fs.cstr.control_volume.material_holdup_calculation[t, 'aq',
                                                                 'C'].active)

        assert m.fs.cstr.control_volume.properties_out[t].active
        assert not m.fs.cstr.outlet.conc_mol[t, 'S'].fixed
        assert m.fs.cstr.inlet.conc_mol[t, 'S'].fixed

    # Assert that constraints are feasible after initialization
    for con in m.fs.component_data_objects(Constraint, active=True):
        assert value(con.body) - value(con.upper) < 1e-5
        assert value(con.lower) - value(con.body) < 1e-5

    results = solver.solve(m.fs)
    assert check_optimal_termination(results)
示例#27
0
    def test_ConstraintDatatarget_target_transformed_create_using(self):
        m = self.makeModel()
        m2 = TransformationFactory('core.add_slack_variables').create_using(
            m, targets=[m.rule1[2]])

        self.checkTransformedRule1(m2, 2)
示例#28
0
    def test_ConstraintDatatarget_target_transformed(self):
        m = self.makeModel()
        TransformationFactory('core.add_slack_variables').apply_to(
            m, targets=[m.rule1[2]])

        self.checkTransformedRule1(m, 2)
示例#29
0
 def test_trans_block_name_collision(self):
     m = self.makeModel()
     m._core_add_slack_variables = Block()
     TransformationFactory('core.add_slack_variables').apply_to(m)
     xblock = m.component("_core_add_slack_variables_4")
     self.assertIsInstance(xblock, Block)
示例#30
0
    def test_indexedtarget_nontarget_same_create_using(self):
        m = self.makeModel()
        m2 = TransformationFactory('core.add_slack_variables').create_using(
            m, targets=[m.rule1])

        self.checkRule2(m2)