Beispiel #1
0
 def test_atan(self):
     m = pe.Block(concrete=True)
     m.x = pe.Var()
     m.c = pe.Constraint(expr=pe.inequality(body=pe.atan(m.x), lower=-0.5, upper=0.5))
     fbbt(m)
     self.assertAlmostEqual(pe.value(m.x.lb), math.tan(-0.5))
     self.assertAlmostEqual(pe.value(m.x.ub), math.tan(0.5))
Beispiel #2
0
    def test_GDP_nonlinear_objective(self):
        m = ConcreteModel()
        m.x = Var(bounds=(-1, 10))
        m.y = Var(bounds=(2, 3))
        m.d = Disjunction(expr=[
            [m.x + m.y >= 5], [m.x - m.y <= 3]
        ])
        m.o = Objective(expr=m.x ** 2)
        SolverFactory('gdpopt').solve(
            m, strategy='LOA',
            mip_solver=mip_solver,
            nlp_solver=nlp_solver
        )
        self.assertAlmostEqual(value(m.o), 0)

        m = ConcreteModel()
        m.x = Var(bounds=(-1, 10))
        m.y = Var(bounds=(2, 3))
        m.d = Disjunction(expr=[
            [m.x + m.y >= 5], [m.x - m.y <= 3]
        ])
        m.o = Objective(expr=-m.x ** 2, sense=maximize)
        SolverFactory('gdpopt').solve(
            m, strategy='LOA',
            mip_solver=mip_solver,
            nlp_solver=nlp_solver
        )
        self.assertAlmostEqual(value(m.o), 0)
Beispiel #3
0
 def test_acos(self):
     m = pe.Block(concrete=True)
     m.x = pe.Var()
     m.c = pe.Constraint(expr=pe.inequality(body=pe.acos(m.x), lower=1, upper=2))
     fbbt(m)
     self.assertAlmostEqual(pe.value(m.x.lb), math.cos(2))
     self.assertAlmostEqual(pe.value(m.x.ub), math.cos(1))
Beispiel #4
0
def save_cost_components(m, outdir):
    """
    Save values for all individual components of total system cost on NPV basis.
    """
    cost_dict = dict()
    for annual_cost in m.Cost_Components_Per_Period:
        cost = getattr(m, annual_cost)
        # note: storing value() instead of the expression may save
        # some memory while this function runs
        cost_dict[annual_cost] = value(sum(
            cost[p] * m.bring_annual_costs_to_base_year[p]
            for p in m.PERIODS
        ))
    for tp_cost in m.Cost_Components_Per_TP:
        cost = getattr(m, tp_cost)
        cost_dict[tp_cost] = value(sum(
            cost[t] * m.tp_weight_in_year[t]
            * m.bring_annual_costs_to_base_year[m.tp_period[t]]
            for t in m.TIMEPOINTS
        ))
    write_table(
        m,
        cost_dict.keys(),
        output_file=os.path.join(outdir, "cost_components.tab"),
        headings=('component', 'npv_cost'),
        values=lambda m, c: (c, cost_dict[c]),
        digits=16
    )
    def test_ignore_nonlinear(self):
        m = ConcreteModel()
        m.v1 = Var()
        m.c1 = Constraint(expr=m.v1 * m.v1 >= 2)

        self.assertEqual(value(m.c1.lower), 2)
        self.assertFalse(m.c1.has_ub())
        TransformationFactory('core.tighten_constraints_from_vars').apply_to(m)
        self.assertEqual(value(m.c1.lower), 2)
        self.assertFalse(m.c1.has_ub())
Beispiel #6
0
 def test_pow(self):
     m = pe.ConcreteModel()
     m.x = pe.Var(initialize=2.0)
     m.y = pe.Var(initialize=3.0)
     e = m.x ** m.y
     derivs = reverse_ad(e)
     symbolic = reverse_sd(e)
     self.assertAlmostEqual(derivs[m.x], pe.value(symbolic[m.x]), tol+3)
     self.assertAlmostEqual(derivs[m.y], pe.value(symbolic[m.y]), tol+3)
     self.assertAlmostEqual(derivs[m.x], approx_deriv(e, m.x), tol)
     self.assertAlmostEqual(derivs[m.y], approx_deriv(e, m.y), tol)
Beispiel #7
0
def approx_deriv(expr, wrt, delta=0.001):
    numerator = 0
    wrt.value += 2*delta
    numerator -= pe.value(expr)
    wrt.value -= delta
    numerator += 8*pe.value(expr)
    wrt.value -= 2*delta
    numerator -= 8*pe.value(expr)
    wrt.value -= delta
    numerator += pe.value(expr)
    wrt.value += 2*delta
    return numerator / (12*delta)
    def test_less_than_constraint(self):
        m = ConcreteModel()
        m.v1 = Var(initialize=7, bounds=(7, 10))
        m.v2 = Var(initialize=2, bounds=(2, 5))
        m.v3 = Var(initialize=6, bounds=(6, 9))
        m.v4 = Var(initialize=1, bounds=(1, 1))
        m.c1 = Constraint(expr=m.v1 <= m.v2 + m.v3 + m.v4)

        self.assertEqual(value(m.c1.upper), 0)
        self.assertFalse(m.c1.has_lb())
        TransformationFactory('core.tighten_constraints_from_vars').apply_to(m)
        self.assertEqual(value(m.c1.upper), 0)
        self.assertEqual(value(m.c1.lower), -8)
    def test_unbounded_var(self):
        """test with unbounded variables"""
        m = ConcreteModel()
        m.v1 = Var(initialize=7)
        m.v2 = Var(initialize=2, bounds=(2, 5))
        m.v3 = Var(initialize=6, bounds=(6, 9))
        m.v4 = Var(initialize=1, bounds=(1, 1))
        m.c1 = Constraint(expr=m.v1 <= 2 * m.v2 + m.v3 + m.v4)

        self.assertEqual(value(m.c1.upper), 0)
        self.assertFalse(m.c1.has_lb())
        TransformationFactory('core.tighten_constraints_from_vars').apply_to(m)
        self.assertEqual(value(m.c1.upper), 0)
        self.assertFalse(m.c1.has_lb())
    def test_unbounded_one_direction(self):
        """Unbounded in one direction"""
        m = ConcreteModel()
        m.v1 = Var(initialize=7, bounds=(-float('inf'), 10))
        m.v2 = Var(initialize=2, bounds=(2, 5))
        m.v3 = Var(initialize=6, bounds=(6, 9))
        m.v4 = Var(initialize=1, bounds=(1, 1))
        m.c1 = Constraint(expr=m.v1 <= 2 * m.v2 + m.v3 + m.v4)

        self.assertEqual(value(m.c1.upper), 0)
        self.assertFalse(m.c1.has_lb())
        TransformationFactory('core.tighten_constraints_from_vars').apply_to(m)
        self.assertEqual(value(m.c1.upper), -1)
        self.assertFalse(m.c1.has_lb())
    def test_constraint_bound_tightening(self):
        # Check for no coefficients
        m = ConcreteModel()
        m.v1 = Var(initialize=7, bounds=(7, 10))
        m.v2 = Var(initialize=2, bounds=(2, 5))
        m.v3 = Var(initialize=6, bounds=(6, 9))
        m.v4 = Var(initialize=1, bounds=(1, 1))
        m.c1 = Constraint(expr=m.v1 >= m.v2 + m.v3 + m.v4 + 1)

        self.assertEqual(value(m.c1.upper), 0)
        self.assertFalse(m.c1.has_lb())
        TransformationFactory('core.tighten_constraints_from_vars').apply_to(m)
        self.assertEqual(value(m.c1.upper), 0)
        self.assertEqual(value(m.c1.lower), 0)
    def test_constraint_with_coef(self):
        """Test with coefficient on constraint."""
        m = ConcreteModel()
        m.v1 = Var(initialize=7, bounds=(7, 10))
        m.v2 = Var(initialize=2, bounds=(2, 5))
        m.v3 = Var(initialize=6, bounds=(6, 9))
        m.v4 = Var(initialize=1, bounds=(1, 1))
        m.c1 = Constraint(expr=m.v1 <= 2 * m.v2 + m.v3 + m.v4)

        self.assertEqual(value(m.c1.upper), 0)
        self.assertFalse(m.c1.has_lb())
        TransformationFactory('core.tighten_constraints_from_vars').apply_to(m)
        self.assertEqual(value(m.c1.upper), -1)
        self.assertEqual(value(m.c1.lower), -13)
Beispiel #13
0
 def test_nested(self):
     m = pe.ConcreteModel()
     m.x = pe.Var(initialize=2)
     m.y = pe.Var(initialize=3)
     m.p = pe.Param(initialize=0.5, mutable=True)
     e = pe.exp(m.x**m.p + 3.2*m.y - 12)
     derivs = reverse_ad(e)
     symbolic = reverse_sd(e)
     self.assertAlmostEqual(derivs[m.x], pe.value(symbolic[m.x]), tol+3)
     self.assertAlmostEqual(derivs[m.y], pe.value(symbolic[m.y]), tol+3)
     self.assertAlmostEqual(derivs[m.p], pe.value(symbolic[m.p]), tol+3)
     self.assertAlmostEqual(derivs[m.x], approx_deriv(e, m.x), tol)
     self.assertAlmostEqual(derivs[m.y], approx_deriv(e, m.y), tol)
     self.assertAlmostEqual(derivs[m.p], approx_deriv(e, m.p), tol)
Beispiel #14
0
 def test_add(self):
     x_bounds = [(-2.5, 2.8), (-2.5, -0.5), (0.5, 2.8), (-2.5, 0), (0, 2.8), (-2.5, -1), (1, 2.8), (-1, -0.5), (0.5, 1)]
     c_bounds = [(-2.5, 2.8), (-2.5, -0.5), (0.5, 2.8), (-2.5, 0), (0, 2.8), (-2.5, -1), (1, 2.8), (-1, -0.5), (0.5, 1)]
     for xl, xu in x_bounds:
         for cl, cu in c_bounds:
             m = pe.Block(concrete=True)
             m.x = pe.Var(bounds=(xl, xu))
             m.y = pe.Var()
             m.p = pe.Param(mutable=True)
             m.p.value = 1
             m.c = pe.Constraint(expr=pe.inequality(body=m.x+m.y+(m.p+1), lower=cl, upper=cu))
             new_bounds = fbbt(m)
             self.assertEqual(new_bounds[m.x], (pe.value(m.x.lb), pe.value(m.x.ub)))
             self.assertEqual(new_bounds[m.y], (pe.value(m.y.lb), pe.value(m.y.ub)))
             x = np.linspace(pe.value(m.x.lb), pe.value(m.x.ub), 100)
             z = np.linspace(pe.value(m.c.lower), pe.value(m.c.upper), 100)
             if m.y.lb is None:
                 yl = -np.inf
             else:
                 yl = m.y.lb
             if m.y.ub is None:
                 yu = np.inf
             else:
                 yu = m.y.ub
             for _x in x:
                 _y = z - _x - m.p.value - 1
                 self.assertTrue(np.all(yl <= _y))
                 self.assertTrue(np.all(yu >= _y))
Beispiel #15
0
    def test_cos(self):
        m = pe.Block(concrete=True)
        m.x = pe.Var(bounds=(0, math.pi))
        m.c = pe.Constraint(expr=pe.inequality(body=pe.cos(m.x), lower=-0.5, upper=0.5))
        fbbt(m)
        self.assertAlmostEqual(pe.value(m.x.lb), math.acos(0.5))
        self.assertAlmostEqual(pe.value(m.x.ub), math.acos(-0.5))

        m = pe.Block(concrete=True)
        m.x = pe.Var()
        m.c = pe.Constraint(expr=pe.inequality(body=pe.cos(m.x), lower=-0.5, upper=0.5))
        fbbt(m)
        self.assertEqual(m.x.lb, None)
        self.assertEqual(m.x.ub, None)
Beispiel #16
0
def get_value(obj):
    """
    Retrieve value of one element of a Variable or Expression, converting
    division-by-zero to nan and uninitialized values to None.
    """
    try:
        val = value(obj)
    except ZeroDivisionError:
        # diagnostic expressions sometimes have 0 denominator,
        # e.g., AverageFuelCosts for unused fuels;
        val = float("nan")
    except ValueError:
        # If variables are not used in constraints or the
        # objective function, they will never get values, and
        # give a ValueError at this point.
        # Note: for variables this could instead use 0 if allowed, or
        # otherwise the closest bound.
        if getattr(obj, 'value', 0) is None:
            val = None
            # Pyomo will print an error before it raises the ValueError,
            # but we say more here to help users figure out what's going on.
            print (
                "WARNING: variable {} has not been assigned a value. This "
                "usually indicates a coding error: either the variable is "
                "not needed or it has accidentally been omitted from all "
                "constraints and the objective function.".format(obj.name)
            )
        else:
            # Caught some other ValueError
            raise
    return val
Beispiel #17
0
    def propagate_solution(self, augmented_model, original_model):

        for avar in augmented_model.component_objects(ctype=aml.Var, descend_into=True):
            cuid = aml.ComponentUID(avar)
            original_v = cuid.find_component_on(original_model)
            for k in avar:
                original_v[k].value = aml.value(avar[k])
Beispiel #18
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)
Beispiel #19
0
    def test_as_good_with_iteration_rand(self):
        # initialize model with data
        m = build_model()

        # create ipopt solver
        optsolver = SolverFactory('ipopt')
        optsolver.solve(m)
        for i in range(10):
            m2 = build_model()
            SolverFactory('multistart').solve(m2, iterations=10)
            m_objectives = m.component_data_objects(Objective, active=True)
            m_obj = next(m_objectives, None)
            m2_objectives = m2.component_data_objects(Objective, active=True)
            m2_obj = next(m2_objectives,None)
            self.assertTrue((value(m2_obj.expr)) >= (value(m_obj.expr) - .001))
            del m2
Beispiel #20
0
def write_table_old(model, *indexes, **kwargs):
    # there may be a way to accept specific named keyword arguments and also an 
    # open-ended list of positional arguments (*indexes), but I don't know what that is.
    output_file = kwargs["output_file"]
    headings = kwargs["headings"]
    values = kwargs["values"]

    print "Writing {file} ...".format(file=output_file),
    sys.stdout.flush()  # display the part line to the user
    start=time.time()

    # create a master indexing set 
    # this is a list of lists, even if only one list was specified
    idx = itertools.product(*indexes)
    with open(output_file, 'wb') as f:
        w = csv.writer(f, dialect="ampl-tab")
        # write header row
        w.writerow(list(headings))
        # write the data
        w.writerows(
            tuple(value(v) for v in values(model, *x)) 
            for x in idx
        )

    print "time taken: {dur:.2f}s".format(dur=time.time()-start)
Beispiel #21
0
 def test_atan(self):
     m = pe.ConcreteModel()
     m.x = pe.Var(initialize=2.0)
     e = pe.atan(m.x)
     derivs = reverse_ad(e)
     symbolic = reverse_sd(e)
     self.assertAlmostEqual(derivs[m.x], pe.value(symbolic[m.x]), tol+3)
     self.assertAlmostEqual(derivs[m.x], approx_deriv(e, m.x), tol)
Beispiel #22
0
    def test_set_expr_inline(self):
        """Test expr= option (inline expression)"""
        model = ConcreteModel()
        model.A = RangeSet(1,4)
        model.x = Var(model.A,initialize=2)
        model.c = Constraint(expr=(0, sum(model.x[i] for i in model.A), 1))

        self.assertEqual(model.c(), 8)
        self.assertEqual(value(model.c.body), 8)
Beispiel #23
0
    def test_fixed_var_propagate(self):
        """Test for transitivity in a variable equality set."""
        m = ConcreteModel()
        m.v1 = Var(initialize=1)
        m.v2 = Var(initialize=2)
        m.v3 = Var(initialize=3)
        m.v4 = Var(initialize=4)
        m.c1 = Constraint(expr=m.v1 == m.v2)
        m.c2 = Constraint(expr=m.v2 == m.v3)
        m.c3 = Constraint(expr=m.v3 == m.v4)
        m.v2.fix()

        m.s = RangeSet(4)
        m.x = Var(m.s, initialize=5)
        m.c = Constraint(m.s)
        m.c.add(1, expr=m.x[1] == m.x[3])
        m.c.add(2, expr=m.x[2] == m.x[4])
        m.c.add(3, expr=m.x[2] == m.x[3])
        m.c.add(4, expr=m.x[1] == 1)

        m.y = Var([1, 2], initialize=3)
        m.c_too = Constraint(expr=m.y[1] == m.y[2])

        m.z1 = Var()
        m.z2 = Var()
        m.ignore_me = Constraint(expr=m.y[1] + m.z1 + m.z2 <= 0)

        TransformationFactory('contrib.propagate_fixed_vars').apply_to(m)
        self.assertTrue(m.v1.fixed)
        self.assertTrue(m.v2.fixed)
        self.assertTrue(m.v3.fixed)
        self.assertTrue(m.v4.fixed)
        self.assertEquals(value(m.v4), 2)

        self.assertTrue(m.x[1].fixed)
        self.assertTrue(m.x[2].fixed)
        self.assertTrue(m.x[3].fixed)
        self.assertTrue(m.x[4].fixed)
        self.assertEquals(value(m.x[4]), 1)

        self.assertFalse(m.y[1].fixed)
        self.assertFalse(m.y[2].fixed)
        self.assertFalse(m.z1.fixed)
        self.assertFalse(m.z2.fixed)
Beispiel #24
0
 def format_row(row):
     row = [value(v) for v in row]
     sig_digits = "{0:." + str(digits) + "g}"
     for (i, v) in enumerate(row):
         if isinstance(v, float):
             if abs(v) < 1e-10:
                 row[i] = 0
             else:
                 row[i] = sig_digits.format(v)
     return tuple(row)
Beispiel #25
0
 def test_log(self):
     c_bounds = [(-2.5, 2.8), (-2.5, -0.5), (0.5, 2.8), (-2.5, 0), (0, 2.8), (-2.5, -1), (1, 2.8), (-1, -0.5), (0.5, 1)]
     for cl, cu in c_bounds:
         m = pe.Block(concrete=True)
         m.x = pe.Var()
         m.c = pe.Constraint(expr=pe.inequality(body=pe.log(m.x), lower=cl, upper=cu))
         fbbt(m)
         z = np.linspace(pe.value(m.c.lower), pe.value(m.c.upper), 100)
         if m.x.lb is None:
             xl = -np.inf
         else:
             xl = pe.value(m.x.lb)
         if m.x.ub is None:
             xu = np.inf
         else:
             xu = pe.value(m.x.ub)
         x = np.exp(z)
         self.assertTrue(np.all(xl <= x))
         self.assertTrue(np.all(xu >= x))
Beispiel #26
0
    def test_LOA_8PP_maxBinary(self):
        """Test logic-based OA with max_binary initialization."""
        exfile = import_file(
            join(exdir, 'eight_process', 'eight_proc_model.py'))
        eight_process = exfile.build_eight_process_flowsheet()
        SolverFactory('gdpopt').solve(
            eight_process, strategy='LOA', init_strategy='max_binary',
            mip_solver=mip_solver,
            nlp_solver=nlp_solver)

        self.assertTrue(fabs(value(eight_process.profit.expr) - 68) <= 1E-2)
Beispiel #27
0
 def test_solve_constant_obj(self):
     m = ConcreteModel()
     m.x = Var(bounds=(-5, 5))
     m.c = Constraint(expr=m.x >= 1)
     m.o = Objective(expr=1)
     output = StringIO()
     with LoggingIntercept(output, 'pyomo.contrib.gdpopt', logging.INFO):
         SolverFactory('gdpopt').solve(m, mip_solver=mip_solver)
         self.assertIn("Your model is an LP (linear program).",
                       output.getvalue().strip())
         self.assertAlmostEqual(value(m.o.expr), 1)
Beispiel #28
0
 def test_GLOA_nonconvex_HENS(self):
     exfile = import_file(join(exdir, 'small_lit', 'nonconvex_HEN.py'))
     model = exfile.build_gdp_model()
     SolverFactory('gdpopt').solve(
         model, strategy='GLOA',
         mip_solver=mip_solver,
         nlp_solver=global_nlp_solver,
         nlp_solver_args=global_nlp_solver_args,
         tee=False)
     objective_value = value(model.objective.expr)
     self.assertAlmostEqual(objective_value * 1E-5, 1.14385, 2)
Beispiel #29
0
 def test_LOA_strip_pack_maxBinary(self):
     """Test LOA with strip packing using max_binary initialization."""
     exfile = import_file(
         join(exdir, 'strip_packing', 'strip_packing_concrete.py'))
     strip_pack = exfile.build_rect_strip_packing_model()
     SolverFactory('gdpopt').solve(
         strip_pack, strategy='LOA', init_strategy='max_binary',
         mip_solver=mip_solver,
         nlp_solver=nlp_solver)
     self.assertTrue(
         fabs(value(strip_pack.total_length.expr) - 11) <= 1E-2)
Beispiel #30
0
 def test_LOA_strip_pack_default_init(self):
     """Test logic-based outer approximation with strip packing."""
     exfile = import_file(
         join(exdir, 'strip_packing', 'strip_packing_concrete.py'))
     strip_pack = exfile.build_rect_strip_packing_model()
     SolverFactory('gdpopt').solve(
         strip_pack, strategy='LOA',
         mip_solver=mip_solver,
         nlp_solver=nlp_solver)
     self.assertTrue(
         fabs(value(strip_pack.total_length.expr) - 11) <= 1E-2)
Beispiel #31
0
    def test_solution(self, btx_ftpz, btx_fctp):

        # liq_out port
        assert (pytest.approx(0.463370, abs=1e-3) == value(
            btx_ftpz.fs.unit.liq_out.flow_mol[0]))
        assert (pytest.approx(0.33313, abs=1e-3) == value(
            btx_ftpz.fs.unit.liq_out.mole_frac_comp[0, "benzene"]))
        assert (pytest.approx(0.66686, abs=1e-3) == value(
            btx_ftpz.fs.unit.liq_out.mole_frac_comp[0, "toluene"]))
        assert (pytest.approx(370.567, abs=1e-3) == value(
            btx_ftpz.fs.unit.liq_out.temperature[0]))
        assert (pytest.approx(101325, abs=1e-3) == value(
            btx_ftpz.fs.unit.liq_out.pressure[0]))

        # vap_out port
        assert (pytest.approx(1.5366, abs=1e-3) == value(
            btx_ftpz.fs.unit.vap_out.flow_mol[0]))
        assert (pytest.approx(0.55031, abs=1e-3) == value(
            btx_ftpz.fs.unit.vap_out.mole_frac_comp[0, "benzene"]))
        assert (pytest.approx(0.44968, abs=1e-3) == value(
            btx_ftpz.fs.unit.vap_out.mole_frac_comp[0, "toluene"]))
        assert (pytest.approx(370.567, abs=1e-3) == value(
            btx_ftpz.fs.unit.vap_out.temperature[0]))
        assert (pytest.approx(101325, abs=1e-3) == value(
            btx_ftpz.fs.unit.vap_out.pressure[0]))

        # liq_out port
        assert (pytest.approx(0.15436, abs=1e-3) == value(
            btx_fctp.fs.unit.liq_out.flow_mol_comp[0, "benzene"]))
        assert (pytest.approx(0.30900, abs=1e-3) == value(
            btx_fctp.fs.unit.liq_out.flow_mol_comp[0, "toluene"]))
        assert (pytest.approx(370.567, abs=1e-3) == value(
            btx_fctp.fs.unit.liq_out.temperature[0]))
        assert (pytest.approx(101325, abs=1e-3) == value(
            btx_fctp.fs.unit.liq_out.pressure[0]))

        # vap_out port
        assert (pytest.approx(0.84560, abs=1e-3) == value(
            btx_fctp.fs.unit.vap_out.flow_mol_comp[0, "benzene"]))
        assert (pytest.approx(0.69097, abs=1e-3) == value(
            btx_fctp.fs.unit.vap_out.flow_mol_comp[0, "toluene"]))
        assert (pytest.approx(370.567, abs=1e-3) == value(
            btx_fctp.fs.unit.vap_out.temperature[0]))
        assert (pytest.approx(101325, abs=1e-3) == value(
            btx_fctp.fs.unit.vap_out.pressure[0]))
Beispiel #32
0
    def check_recycle_model(self, m, rel=False):
        for arc in m.component_data_objects(Arc):
            self.assertTrue(self.is_converged(arc, rel=rel))

        for port in m.component_data_objects(Port):
            self.assertTrue(
                self.intensive_equal(port,
                                     temperature=value(
                                         m.feed.outlet.temperature),
                                     pressure=value(m.feed.outlet.pressure)))

        if rel:
            # in == out
            for i in m.feed.outlet.flow:
                s = value(m.prod.inlet.flow[i])
                d = value(m.feed.outlet.flow[i])
                self.assertAlmostEqual((s - d) / s, 0, places=5)
            for i in m.feed.outlet.expr_idx:
                s = value(m.prod.inlet.expr_idx[i])
                d = value(m.feed.outlet.expr_idx[i])
                self.assertAlmostEqual((s - d) / s, 0, places=5)
            s = value(m.prod.inlet.expr)
            d = value(m.feed.outlet.expr)
            self.assertAlmostEqual((s - d) / s, 0, places=5)

            # check the expressions work, should be negative in prod
            for i in m.feed.outlet.expr_idx:
                s = value(-m.prod.actual_var_idx_in[i])
                d = value(m.feed.expr_var_idx_out[i])
                self.assertAlmostEqual((s - d) / s, 0, places=5)
            s = value(-m.prod.actual_var_in)
            d = value(m.feed.expr_var_out)
            self.assertAlmostEqual((s - d) / s, 0, places=5)
        else:
            # in == out
            for i in m.feed.outlet.flow:
                self.assertAlmostEqual(value(m.prod.inlet.flow[i]),
                                       value(m.feed.outlet.flow[i]),
                                       places=5)
            for i in m.feed.outlet.expr_idx:
                self.assertAlmostEqual(value(m.prod.inlet.expr_idx[i]),
                                       value(m.feed.outlet.expr_idx[i]),
                                       places=5)
            self.assertAlmostEqual(value(m.prod.inlet.expr),
                                   value(m.feed.outlet.expr),
                                   places=5)

            # check the expressions work, should be negative in prod
            for i in m.feed.outlet.expr_idx:
                self.assertAlmostEqual(value(-m.prod.actual_var_idx_in[i]),
                                       value(m.feed.expr_var_idx_out[i]),
                                       places=5)
            self.assertAlmostEqual(value(-m.prod.actual_var_in),
                                   value(m.feed.expr_var_out),
                                   places=5)
Beispiel #33
0
    def test_external_grey_box_react_example_maximize_cb_outputs_scaling(self):
        ex = import_file(
            os.path.join(example_dir, 'external_grey_box', 'react_example',
                         'maximize_cb_ratio_residuals.py'))
        aoptions = {
            'nlp_scaling_method': 'user-scaling',
            'output_file': '_cyipopt-external-greybox-react-scaling.log',
            'file_print_level': 10
        }
        m = ex.maximize_cb_ratio_residuals_with_output_scaling(
            additional_options=aoptions)
        self.assertAlmostEqual(pyo.value(m.reactor.inputs['sv']),
                               1.26541996,
                               places=3)
        self.assertAlmostEqual(pyo.value(m.reactor.inputs['cb']),
                               1071.7410089,
                               places=2)
        self.assertAlmostEqual(pyo.value(m.reactor.outputs['cb_ratio']),
                               0.15190409266,
                               places=3)

        with open('_cyipopt-external-greybox-react-scaling.log', 'r') as fd:
            solver_trace = fd.read()
        os.remove('_cyipopt-external-greybox-react-scaling.log')

        self.assertIn('nlp_scaling_method = user-scaling', solver_trace)
        self.assertIn(
            'output_file = _cyipopt-external-greybox-react-scaling.log',
            solver_trace)
        self.assertIn('objective scaling factor = 1', solver_trace)
        self.assertIn('x scaling provided', solver_trace)
        self.assertIn('c scaling provided', solver_trace)
        self.assertIn('d scaling provided', solver_trace)
        self.assertIn('DenseVector "x scaling vector" with 7 elements:',
                      solver_trace)
        self.assertIn('x scaling vector[    2]= 1.2000000000000000e+00',
                      solver_trace)
        self.assertIn('x scaling vector[    7]= 1.7000000000000000e+00',
                      solver_trace)
        self.assertIn('x scaling vector[    6]= 1.1000000000000001e+00',
                      solver_trace)
        self.assertIn('x scaling vector[    1]= 1.3000000000000000e+00',
                      solver_trace)
        self.assertIn('x scaling vector[    3]= 1.3999999999999999e+00',
                      solver_trace)
        self.assertIn('x scaling vector[    4]= 1.5000000000000000e+00',
                      solver_trace)
        self.assertIn('x scaling vector[    5]= 1.6000000000000001e+00',
                      solver_trace)
        self.assertIn('DenseVector "c scaling vector" with 6 elements:',
                      solver_trace)
        self.assertIn('c scaling vector[    1]= 4.2000000000000000e+01',
                      solver_trace)
        self.assertIn('c scaling vector[    2]= 1.0000000000000001e-01',
                      solver_trace)
        self.assertIn('c scaling vector[    3]= 2.0000000000000001e-01',
                      solver_trace)
        self.assertIn('c scaling vector[    4]= 2.9999999999999999e-01',
                      solver_trace)
        self.assertIn('c scaling vector[    5]= 4.0000000000000002e-01',
                      solver_trace)
        self.assertIn('c scaling vector[    6]= 1.0000000000000000e+01',
                      solver_trace)
Beispiel #34
0
def _set_rate_rxn_scaling(rxn_params, unit, min_scale=1e-3):
    for i in rxn_params.rate_reaction_idx:
        scale = value(unit.control_volume.reactions[0.0].reaction_rate[i].expr)
        iscale.set_scaling_factor(
            unit.control_volume.rate_reaction_extent[0.0, i], 1000 / scale)
Beispiel #35
0
    def test_vars(self, frame):
        # Check that all necessary variables have been constructed and have
        # the correct values
        assert isinstance(frame.props[1].flow_mol, Expression)
        assert value(frame.props[1].flow_mol) == 300

        assert isinstance(frame.props[1].flow_mol_comp, Var)
        assert len(frame.props[1].flow_mol_comp) == 3
        for i in frame.props[1].flow_mol_comp:
            assert i in frame.props[1].params.component_list
            assert frame.props[1].flow_mol_comp[i].value == 100
            assert frame.props[1].flow_mol_comp[i].lb == 0
            assert frame.props[1].flow_mol_comp[i].ub == 200
        assert check_units_equivalent(frame.props[1].flow_mol_comp,
                                      pyunits.mol / pyunits.s)

        assert isinstance(frame.props[1].mole_frac_comp, Var)
        assert len(frame.props[1].mole_frac_comp) == 3
        for i in frame.props[1].mole_frac_comp:
            assert i in frame.props[1].params.component_list
            assert frame.props[1].mole_frac_comp[i].value == 1 / 3
        assert check_units_equivalent(frame.props[1].mole_frac_comp, None)

        assert isinstance(frame.props[1].pressure, Var)
        assert frame.props[1].pressure.value == 3e5
        assert frame.props[1].pressure.lb == 1e5
        assert frame.props[1].pressure.ub == 5e5
        assert check_units_equivalent(frame.props[1].pressure, pyunits.Pa)

        assert isinstance(frame.props[1].temperature, Var)
        assert frame.props[1].temperature.value == 345
        assert frame.props[1].temperature.lb == 290
        assert frame.props[1].temperature.ub == 400
        assert check_units_equivalent(frame.props[1].temperature, pyunits.K)

        assert isinstance(frame.props[1].flow_mol_phase, Var)
        assert len(frame.props[1].flow_mol_phase) == 3
        for i in frame.props[1].flow_mol_phase:
            assert i in frame.props[1].params.phase_list
            assert frame.props[1].flow_mol_phase[i].value == 100 / 3
            assert frame.props[1].flow_mol_phase[i].lb == 0
            assert frame.props[1].flow_mol_phase[i].ub == 200
        assert check_units_equivalent(frame.props[1].flow_mol_phase,
                                      pyunits.mol / pyunits.s)

        assert isinstance(frame.props[1].phase_frac, Var)
        assert len(frame.props[1].phase_frac) == 3
        for i in frame.props[1].phase_frac:
            assert i in frame.props[1].params.phase_list
            assert frame.props[1].phase_frac[i].value == 1 / 3
        assert check_units_equivalent(frame.props[1].phase_frac, None)

        assert isinstance(frame.props[1].mole_frac_phase_comp, Var)
        assert len(frame.props[1].mole_frac_phase_comp) == 9
        for i in frame.props[1].mole_frac_phase_comp:
            assert i in [("p1", "c1"), ("p1", "c2"), ("p1", "c3"),
                         ("p2", "c1"), ("p2", "c2"), ("p2", "c3"),
                         ("p3", "c1"), ("p3", "c2"), ("p3", "c3")]
            assert frame.props[1].mole_frac_phase_comp[i].value == 1 / 3
        assert check_units_equivalent(frame.props[1].mole_frac_phase_comp,
                                      None)
Beispiel #36
0
    def xhat_closest_to_xbar(self, verbose=False, restore_nonants=True):
        """ Get a truncated z score and look for the closest overall.

        Returns:
            obj (float or None): objective value, none if infeasible.
            snamedict (str): closest scenarios
        """
        def _vb(msg):
            if verbose and self.rank == 0:
                print("(rank0) xhat_looper: " + msg)

        localmindist = np.zeros(1, dtype='d')
        globalmindist = np.zeros(1, dtype='d')
        localwinnername = None
        for k, s in self.opt.local_scenarios.items():
            dist = 0
            for ndn_i, xvar in s._nonant_indexes.items():
                diff = pyo.value(xvar)
                variance = pyo.value(s._xsqbars[ndn_i]) \
                  - pyo.value(s._xbars[ndn_i])*pyo.value(s._xbars[ndn_i])
                if variance > 0:
                    stdev = np.sqrt(variance)
                    dist += min(3, abs(diff) / stdev)
            if localwinnername is None:
                localmindist[0] = dist
                localwinnername = k
            elif dist < localmindist[0]:
                localmindist[0] = dist
                localwinnername = k

        self.comms["ROOT"].Allreduce([localmindist, mpi.DOUBLE],
                                     [globalmindist, mpi.DOUBLE],
                                     op=mpi.MIN)
        # ties are possible, so break the tie
        localwinrank = np.zeros(1, dtype='d')  # could use a python variable.
        globalwinrank = np.zeros(1, dtype='d')
        if globalmindist[0] < localmindist[0]:
            localwinrank[0] = -1  # we lost
        else:
            localwinrank[0] = self.rank
        self.comms["ROOT"].Allreduce([localwinrank, mpi.DOUBLE],
                                     [globalwinrank, mpi.DOUBLE],
                                     op=mpi.MAX)

        # We only used the rank to break a possible tie.
        if self.rank == int(globalwinrank[0]):
            globalwinnername = localwinnername
        else:
            globalwinnername = None

        sroot = globalwinrank[0]

        sname = self.comms["ROOT"].bcast(globalwinnername, root=sroot)
        _vb("Trying scenario " + sname)
        _vb("   Solver options=" + str(self.solver_options))
        # xxx TBD mult-stage
        snamedict = {"ROOT": sname}
        obj = self._try_one(snamedict,
                            solver_options=self.solver_options,
                            verbose=False,
                            restore_nonants=restore_nonants)
        if obj is None:
            _vb("    Infeasible")
        else:
            _vb("    Feasible, returning " + str(obj))

        return obj, snamedict
Beispiel #37
0
def propagate_state(destination=None, source=None, arc=None,
        direction="forward", overwrite_fixed=False):
    """
    This method propagates values between Ports along Arcs. Values can be
    propagated in either direction using the direction argument.

    Args:
        destination (Port): Port to copy values to or None if specifying arc
        source (Port): Port to copy values from or None if specifying arc
        arc (Arc): If arc is provided, use arc to define source and destination
        direction (str): Direction in which to propagate values.
                Default = 'forward' Valid values: 'forward', 'backward'.
        overwrite_fixed (bool): If True overwrite fixed values, otherwise do not
            overwrite fixed values.

    Returns:
        None
    """
    _log = idaeslog.getLogger(__name__)
    # Allow an arc to be passed as a positional arg
    if destination is not None and source is None and destination.ctype is Arc:
        arc = destination
        if source in ("forward", "backward"):
            direction = source
        destination = None
        source = None
    # Check that only arc or source and destination are passed
    if arc is None and (destination is None or source is None):
        raise RuntimeError(
            "In propagate_state(), must provide source and destination or arc")
    if arc is not None:
        if destination is not None or source is not None:
            raise RuntimeError("In propagate_state(), provide only arc or "
                    "source and destination")
        try:
            source = arc.src
            destination = arc.dest
        except AttributeError:
            _log.error("In propagate_state(), unexpected type of arc "
                    "argument. Value must be a Pyomo Arc")
            raise

    if direction == "forward":
        pass
    elif direction == "backward":
        source, destination = destination, source
    else:
        raise ValueError("Unexpected value for direction argument: ({}). "
                         "Value must be either 'forward' or 'backward'."
                         .format(direction))

    try:
        destination_vars = destination.vars
    except AttributeError:
        _log.error("In propagate_state(), unexpected type of destination "
                "port argument. Value must be a Pyomo Port")
        raise
    try:
        source_vars = source.vars
    except AttributeError:
        _log.error("In propagate_state(), unexpected type of destination "
                "source argument. Value must be a Pyomo Port")
        raise

    # Copy values
    for k, v in destination_vars.items():
        try:
            for i in v:
                if v[i].is_variable_type() and ((not v[i].fixed) or overwrite_fixed):
                    v[i].value = value(source_vars[k][i])
                elif not v[i].is_variable_type():
                    raise TypeError(
                        f"propagate_state() is can only change the value of "
                        f"variables and cannot set a {v[i].ctype}.  This "
                        f"likely indicates either a malformed port or a misuse "
                        f"of propagate_state.")
        except KeyError as e:
            raise KeyError(
                "In propagate_state, variables have incompatible index sets") from e
Beispiel #38
0
    def initialize(
        self,
        state_args={},
        outlvl=idaeslog.NOTSET,
        solver="ipopt",
        optarg={
            "tol": 1e-6,
            "max_iter": 30
        },
        calculate_cf=False,
    ):
        """
        Initialize the inlet turbine stage model.  This deactivates the
        specialized constraints, then does the isentropic turbine initialization,
        then reactivates the constraints and solves. This initializtion uses a
        flow value guess, so some reasonable flow guess should be sepecified prior
        to initializtion.

        Args:
            state_args (dict): Initial state for property initialization
            outlvl (int): Amount of output (0 to 3) 0 is lowest
            solver (str): Solver to use for initialization
            optarg (dict): Solver arguments dictionary
            calculate_cf (bool): If True, use the flow and pressure ratio to
                calculate the flow coefficient.
        """
        init_log = idaeslog.getInitLogger(self.name, outlvl, tag="unit")
        solve_log = idaeslog.getSolveLogger(self.name, outlvl, tag="unit")

        # sp is what to save to make sure state after init is same as the start
        sp = StoreSpec.value_isfixed_isactive(only_fixed=True)
        istate = to_json(self, return_dict=True, wts=sp)

        # Setup for initializtion step 1
        self.inlet_flow_constraint.deactivate()
        self.efficiency_correlation.deactivate()
        self.eff_nozzle.fix()
        self.blade_reaction.fix()
        self.flow_coeff.fix()
        self.blade_velocity.fix()
        self.inlet.fix()
        self.outlet.unfix()

        for t in self.flowsheet().config.time:
            self.efficiency_isentropic[t] = 0.9
        super().initialize(outlvl=outlvl, solver=solver, optarg=optarg)

        # Free eff_isen and activate sepcial constarints
        self.inlet_flow_constraint.activate()
        self.efficiency_correlation.activate()

        if calculate_cf:
            self.ratioP.fix()
            self.flow_coeff.unfix()

            for t in self.flowsheet().config.time:
                g = self.control_volume.properties_in[t].heat_capacity_ratio
                mw = self.control_volume.properties_in[t].mw
                flow = self.control_volume.properties_in[t].flow_mol
                Tin = self.control_volume.properties_in[t].temperature
                Pin = self.control_volume.properties_in[t].pressure
                Pratio = self.ratioP[t]
                self.flow_coeff[t].value = value(flow * mw * sqrt(
                    (Tin - 273.15) /
                    (g / (g - 1) *
                     (Pratio**(2.0 / g) - Pratio**((g + 1) / g)))) / Pin)

        slvr = SolverFactory(solver)
        slvr.options = optarg
        with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc:
            res = slvr.solve(self, tee=slc.tee)
        init_log.info("Initialization Complete: {}".format(
            idaeslog.condition(res)))
        # reload original spec
        if calculate_cf:
            cf = {}
            for t in self.flowsheet().config.time:
                cf[t] = value(self.flow_coeff[t])

        from_json(self, sd=istate, wts=sp)
        if calculate_cf:
            # cf was probably fixed, so will have to set the value agian here
            # if you ask for it to be calculated.
            for t in self.flowsheet().config.time:
                self.flow_coeff[t] = cf[t]
Beispiel #39
0
    def test_conservation(self, iron_oc):
        # Conservation of material check
        dt, T = 36, 3600  # size of time interval and time domain
        # first, check if Final Mass - Initial Mass = Total Amount Reacted
        mbal_solid_total = value(
                (iron_oc.fs.unit.mass_solids[T] -
                 iron_oc.fs.unit.mass_solids[0]) -
                (sum(iron_oc.fs.unit.reactions[t].reaction_rate[r] *
                     iron_oc.fs.unit.config.reaction_package
                     .rate_reaction_stoichiometry[r, "Sol", j] *
                     iron_oc.fs.unit.solids[t]._params.mw_comp[j] *
                     iron_oc.fs.unit.volume_solid[t] * dt
                     for t in list(iron_oc.fs.time)[1:]
                     for j in ('Al2O3', 'Fe2O3', 'Fe3O4')
                     for r in iron_oc.fs.unit.config.reaction_package
                     .rate_reaction_idx)))
        assert abs(mbal_solid_total) <= 1e-2

        # second, check if Change in Mass = Amount Reacted at each time t
        mbal_solid = []
        for t in list(iron_oc.fs.time)[1:]:  # skip t = 0
            mbal_solid.append(value(
                (iron_oc.fs.unit.mass_solids[t] -
                 iron_oc.fs.unit.mass_solids[t - dt]) -
                (sum(iron_oc.fs.unit.reactions[t].reaction_rate[r] *
                     iron_oc.fs.unit.config.reaction_package
                     .rate_reaction_stoichiometry[r, "Sol", j] *
                     iron_oc.fs.unit.solids[t]._params.mw_comp[j] *
                     iron_oc.fs.unit.volume_solid[t] * dt
                     for j in ('Al2O3', 'Fe2O3', 'Fe3O4')
                     for r in iron_oc.fs.unit.config.reaction_package
                     .rate_reaction_idx))))
        for val in mbal_solid:
            assert abs(val) <= 1e-2

        # Reaction stoichiometric ratio (gas is fixed, can only check solids)
        # Overall reducer reactions for methane combustion:
        # CH4 + 12Fe2O3 => 8Fe3O4 + CO2 + 2H2O
        fe2o3_reacted = value(
            (iron_oc.fs.unit.mass_solids[0] *
             iron_oc.fs.unit.solids[0].mass_frac_comp['Fe2O3'] -
             iron_oc.fs.unit.mass_solids[T] *
             iron_oc.fs.unit.solids[T].mass_frac_comp['Fe2O3']) /
            iron_oc.fs.unit.solids[0]._params.mw_comp['Fe2O3'])
        fe3o4_produced = value(
            (iron_oc.fs.unit.mass_solids[T] *
             iron_oc.fs.unit.solids[T].mass_frac_comp['Fe3O4'] -
             iron_oc.fs.unit.mass_solids[0] *
             iron_oc.fs.unit.solids[0].mass_frac_comp['Fe3O4']) /
            iron_oc.fs.unit.solids[0]._params.mw_comp['Fe3O4'])
        stoichiometric_ratio = fe2o3_reacted/fe3o4_produced
        assert (pytest.approx(1.5, abs=1e-6) == stoichiometric_ratio)

        # Conservation of energy check
        # first, check if Final Energy - Initial Energy = Reaction Enthalpy
        ebal_solid_total = value(
                (iron_oc.fs.unit.mass_solids[T] *
                 iron_oc.fs.unit.solids[T].enth_mass -
                 iron_oc.fs.unit.mass_solids[0] *
                 iron_oc.fs.unit.solids[0].enth_mass) -
                (-sum(iron_oc.fs.unit.reactions[t].reaction_rate[r] *
                      iron_oc.fs.unit.reactions[t].dh_rxn[r] *
                      iron_oc.fs.unit.volume_solid[t] * dt
                      for t in list(iron_oc.fs.time)[1:]
                      for r in iron_oc.fs.unit.config.reaction_package.
                      rate_reaction_idx)))
        assert abs(ebal_solid_total) <= 1e-2

        # second, check if Change in Energy = Change in Holdup at each time t
        ebal_solid = []
        for t in list(iron_oc.fs.time)[1:]:  # skip t = 0
            ebal_solid.append(value(
                (iron_oc.fs.unit.mass_solids[t] *
                 iron_oc.fs.unit.solids[t].enth_mass -
                 iron_oc.fs.unit.mass_solids[t - dt] *
                 iron_oc.fs.unit.solids[t - dt].enth_mass) -
                (-sum(iron_oc.fs.unit.reactions[t].reaction_rate[r] *
                      iron_oc.fs.unit.reactions[t].dh_rxn[r] *
                      iron_oc.fs.unit.volume_solid[t] * dt
                      for r in iron_oc.fs.unit.config.reaction_package.
                      rate_reaction_idx))))
        for val in ebal_solid:
            assert abs(val) <= 1e-2
    def test_solution(self, frame):
        m = frame

        # specified conditions
        assert pytest.approx(0.035, rel=1e-3) == value(m.fs.stream[0].flow_mass_phase_comp['Liq', 'TDS'])
        assert pytest.approx(0.965, rel=1e-3) == value(m.fs.stream[0].flow_mass_phase_comp['Liq', 'H2O'])
        assert pytest.approx(273.15 + 25, rel=1e-3) == value(m.fs.stream[0].temperature)
        assert pytest.approx(101325, rel=1e-3) == value(m.fs.stream[0].pressure)

        # calculated properties
        assert pytest.approx(0.035, rel=1e-3) == value(m.fs.stream[0].mass_frac_phase_comp['Liq', 'TDS'])
        assert pytest.approx(0.965, rel=1e-3) == value(m.fs.stream[0].mass_frac_phase_comp['Liq', 'H2O'])
        assert pytest.approx(1023.6, rel=1e-3) == value(m.fs.stream[0].dens_mass_phase['Liq'])
        assert pytest.approx(996, rel=1e-3) == value(m.fs.stream[0].dens_mass_solvent)
        assert pytest.approx(9.770e-4, rel=1e-3) == value(m.fs.stream[0].flow_vol_phase['Liq'])
        assert pytest.approx(9.770e-4, rel=1e-3) == value(m.fs.stream[0].flow_vol)
        assert pytest.approx(987.7, rel=1e-3) == value(m.fs.stream[0].conc_mass_phase_comp['Liq', 'H2O'])
        assert pytest.approx(35.82, rel=1e-3) == value(m.fs.stream[0].conc_mass_phase_comp['Liq', 'TDS'])
        assert pytest.approx(53.57, rel=1e-3) == value(m.fs.stream[0].flow_mol_phase_comp['Liq', 'H2O'])
        assert pytest.approx(1.1145, rel=1e-3) == value(m.fs.stream[0].flow_mol_phase_comp['Liq', 'TDS'])
        assert pytest.approx(0.9796, rel=1e-3) == value(m.fs.stream[0].mole_frac_phase_comp['Liq', 'H2O'])
        assert pytest.approx(0.02038, rel=1e-3) == value(m.fs.stream[0].mole_frac_phase_comp['Liq', 'TDS'])
        assert pytest.approx(1.1549, rel=1e-3) == value(m.fs.stream[0].molality_comp['TDS'])
        assert pytest.approx(9.588e-4, rel=1e-3) == value(m.fs.stream[0].visc_d_phase['Liq'])
        assert pytest.approx(0.9068, rel=1e-3) == value(m.fs.stream[0].osm_coeff)
        assert pytest.approx(2.588e6, rel=1e-3) == value(m.fs.stream[0].pressure_osm)
        assert pytest.approx(9.974e4, rel=1e-3) == value(m.fs.stream[0].enth_mass_phase['Liq'])
        assert pytest.approx(9.974e4, rel=1e-3) == value(m.fs.stream[0].enth_flow)
        assert pytest.approx(3111, rel=1e-3) == value(m.fs.stream[0].pressure_sat)
        assert pytest.approx(4000.77, rel=1e-3) == value(m.fs.stream[0].cp_phase['Liq'])
        assert pytest.approx(0.6086, rel=1e-3) == value(m.fs.stream[0].therm_cond_phase['Liq'])
        assert pytest.approx(2.356e6, rel=1e-3) == value(m.fs.stream[0].dh_vap)
Beispiel #41
0
def export_results(scenario_directory, subproblem, stage, m, d):
    """

    :param scenario_directory:
    :param subproblem:
    :param stage:
    :param m:
    :param d:
    :return:
    """

    df = pd.read_csv(
        os.path.join(scenario_directory, str(subproblem), str(stage), "inputs",
                     "transmission_lines.tab"),
        sep="\t",
        usecols=["TRANSMISSION_LINES", "tx_capacity_type",
                 "tx_operational_type"]
    )

    # Required capacity modules are the unique set of tx capacity types
    # This list will be used to know which capacity modules to load
    # Module-specific results
    required_tx_capacity_modules = df.tx_capacity_type.unique()

    # Import needed transmission capacity type modules for expression rules
    imported_tx_capacity_modules = load_tx_capacity_type_modules(
        required_tx_capacity_modules
    )

    # Add model components for each of the transmission capacity modules
    for op_m in required_tx_capacity_modules:
        if hasattr(imported_tx_capacity_modules[op_m],
                   "export_module_specific_results"):
            imported_tx_capacity_modules[op_m].export_module_specific_results(
                m, d, scenario_directory, subproblem, stage
            )
        else:
            pass

    # Export transmission capacity
    with open(os.path.join(scenario_directory, str(subproblem), str(stage), "results",
                           "transmission_capacity.csv"), "w", newline="") as f:
        writer = csv.writer(f)
        writer.writerow(["tx_line", "period", "load_zone_from", "load_zone_to",
                         "transmission_min_capacity_mw",
                         "transmission_max_capacity_mw"])
        for (tx_line, p) in m.TX_OPR_PRDS:
            writer.writerow([
                tx_line,
                p,
                m.load_zone_from[tx_line],
                m.load_zone_to[tx_line],
                value(m.Tx_Min_Capacity_MW[tx_line, p]),
                value(m.Tx_Max_Capacity_MW[tx_line, p])
            ])

    # Export transmission capacity costs
    with open(os.path.join(scenario_directory, str(subproblem), str(stage), "results",
              "costs_transmission_capacity.csv"), "w", newline="") as f:
        writer = csv.writer(f)
        writer.writerow(
            ["tx_line", "period", "hours_in_full_period",
             "hours_in_subproblem_period", "load_zone_from",
             "load_zone_to", "capacity_cost"]
        )
        for (l, p) in m.TX_OPR_PRDS:
            writer.writerow([
                l,
                p,
                m.hours_in_full_period[p],
                m.hours_in_subproblem_period[p],
                m.load_zone_from[l],
                m.load_zone_to[l],
                value(m.Tx_Capacity_Cost_in_Prd[l, p])
            ])
def test_boiler_hx():
    m = ConcreteModel()
    m.fs = FlowsheetBlock(default={"dynamic": False})

    m.fs.properties = PhysicalParameterTestBlock()
    m.fs.prop_steam = iapws95.Iapws95ParameterBlock()
    m.fs.prop_fluegas = FlueGasParameterBlock()

    m.fs.unit = BoilerHeatExchanger(
        default={
            "side_1_property_package": m.fs.prop_steam,
            "side_2_property_package": m.fs.prop_fluegas,
            "has_pressure_change": True,
            "has_holdup": False,
            "delta_T_method": DeltaTMethod.counterCurrent,
            "tube_arrangement": TubeArrangement.inLine,
            "side_1_water_phase": "Liq",
            "has_radiation": True
        })

    #   Set inputs
    h = value(iapws95.htpx(773.15 * pyunits.K, 2.5449e7 * pyunits.Pa))
    print(h)
    m.fs.unit.side_1_inlet.flow_mol[0].fix(24678.26)  # mol/s
    m.fs.unit.side_1_inlet.enth_mol[0].fix(h)  # J/mol
    m.fs.unit.side_1_inlet.pressure[0].fix(2.5449e7)  # Pascals

    # FLUE GAS Inlet from Primary Superheater
    FGrate = 28.3876e3 * 0.18  # mol/s equivalent of ~1930.08 klb/hr
    # Use FG molar composition to set component flow rates (baseline report)
    m.fs.unit.side_2_inlet.flow_mol_comp[0, "H2O"].fix(FGrate * 8.69 / 100)
    m.fs.unit.side_2_inlet.flow_mol_comp[0, "CO2"].fix(FGrate * 14.49 / 100)
    m.fs.unit.side_2_inlet.flow_mol_comp[0, "N2"].fix(FGrate * 74.34 / 100)
    m.fs.unit.side_2_inlet.flow_mol_comp[0, "O2"].fix(FGrate * 2.47 / 100)
    m.fs.unit.side_2_inlet.flow_mol_comp[0, "NO"].fix(FGrate * 0.0006)
    m.fs.unit.side_2_inlet.flow_mol_comp[0, "SO2"].fix(FGrate * 0.002)
    m.fs.unit.side_2_inlet.temperature[0].fix(1102.335)
    m.fs.unit.side_2_inlet.pressure[0].fix(100145)

    # Primary Superheater
    ITM = 0.0254  # inch to meter conversion
    m.fs.unit.tube_di.fix((2.5 - 2 * 0.165) * ITM)
    m.fs.unit.tube_thickness.fix(0.165 * ITM)
    m.fs.unit.pitch_x.fix(3 * ITM)
    # gas path transverse width 54.78 ft / number of columns
    m.fs.unit.pitch_y.fix(54.78 / 108 * 12 * ITM)
    m.fs.unit.tube_length.fix(53.13 * 12 * ITM)
    m.fs.unit.tube_nrow.fix(20 * 2)
    m.fs.unit.tube_ncol.fix(108)
    m.fs.unit.nrow_inlet.fix(4)
    m.fs.unit.delta_elevation.fix(50)
    m.fs.unit.tube_r_fouling = 0.000176  # (0.001 h-ft^2-F/BTU)
    m.fs.unit.tube_r_fouling = 0.003131  # (0.03131 - 0.1779 h-ft^2-F/BTU)
    if m.fs.unit.config.has_radiation is True:
        m.fs.unit.emissivity_wall.fix(0.7)  # wall emissivity
    # correction factor for overall heat transfer coefficient
    m.fs.unit.fcorrection_htc.fix(1.5)
    # correction factor for pressure drop calc tube side
    m.fs.unit.fcorrection_dp_tube.fix(1.0)
    # correction factor for pressure drop calc shell side
    m.fs.unit.fcorrection_dp_shell.fix(1.0)

    assert degrees_of_freedom(m) == 0

    m.fs.unit.initialize()
    # Create a solver
    solver = SolverFactory('ipopt')
    results = solver.solve(m)
    # Check for optimal solution
    assert results.solver.termination_condition == \
        TerminationCondition.optimal
    assert results.solver.status == SolverStatus.ok
    assert value(m.fs.unit.side_1.properties_out[0].temperature) == \
        pytest.approx(588.07, 1)
    assert value(m.fs.unit.side_2.properties_out[0].temperature) == \
        pytest.approx(573.07, 1)
Beispiel #43
0
    def test_midpoint_var_init(self):
        """Test midpoint initialization."""
        m = ConcreteModel()
        m.v1 = Var()
        m.v2 = Var()
        m.v3 = Var()
        m.v4 = Var()
        m.v5 = Var(initialize=2)
        m.v5.fix()
        m.v6 = Var(initialize=3)
        m.v2.setlb(2)
        m.v3.setub(2)
        m.v4.setlb(0)
        m.v4.setub(2)

        TransformationFactory('contrib.init_vars_midpoint').apply_to(m)
        self.assertEquals(value(m.v1), 0)
        self.assertEquals(value(m.v2), 2)
        self.assertEquals(value(m.v3), 2)
        self.assertEquals(value(m.v4), 1)
        self.assertEquals(value(m.v5), 2)
        self.assertEquals(value(m.v6), 3)

        TransformationFactory('contrib.init_vars_midpoint').apply_to(
            m, overwrite=True)
        self.assertEquals(value(m.v1), 0)
        self.assertEquals(value(m.v2), 2)
        self.assertEquals(value(m.v3), 2)
        self.assertEquals(value(m.v4), 1)
        self.assertEquals(value(m.v5), 2)
        self.assertEquals(value(m.v6), 0)
Beispiel #44
0
def _build_pw_mccormick_relaxation(b,
                                   x,
                                   y,
                                   w,
                                   x_pts,
                                   relaxation_side=RelaxationSide.BOTH):
    """
    This function creates piecewise envelopes to relax "w = x*y". Note that the partitioning is done on "x" only.
    This is the "nf4r" from Gounaris, Misener, and Floudas (2009).

    Parameters
    ----------
    b: pyo.ConcreteModel or pyo.Block
    x: pyomo.core.base.var._GeneralVarData
        The "x" variable in x*y
    y: pyomo.core.base.var._GeneralVarData
        The "y" variable in x*y
    w: pyomo.core.base.var._GeneralVarData
        The "w" variable that is replacing x*y
    x_pts: list of floats
        A list of floating point numbers to define the points over which the piecewise representation will generated.
        This list must be ordered, and it is expected that the first point (x_pts[0]) is equal to x.lb and the
        last point (x_pts[-1]) is equal to x.ub
    relaxation_side : minlp.minlp_defn.RelaxationSide
        Provide the desired side for the relaxation (OVER, UNDER, or BOTH)

    """
    xlb = pyo.value(x.lb)
    xub = pyo.value(x.ub)
    ylb = pyo.value(y.lb)
    yub = pyo.value(y.ub)

    check_var_pts(x, x_pts=x_pts)
    check_var_pts(y)

    if x.is_fixed() and y.is_fixed():
        b.xy_fixed_eq = pyo.Constraint(expr=w == pyo.value(x) * pyo.value(y))
    elif x.is_fixed():
        b.x_fixed_eq = pyo.Constraint(expr=w == pyo.value(x) * y)
    elif y.is_fixed():
        b.y_fixed_eq = pyo.Constraint(expr=w == x * pyo.value(y))
    elif len(x_pts) == 2:
        _build_mccormick_relaxation(b,
                                    x=x,
                                    y=y,
                                    w=w,
                                    relaxation_side=relaxation_side)
    else:
        # create the lambda variables (binaries for the pw representation)
        b.interval_set = pyo.Set(initialize=range(1, len(x_pts)))
        b.lam = pyo.Var(b.interval_set, within=pyo.Binary)

        # create the delta y variables
        b.delta_y = pyo.Var(b.interval_set, bounds=(0, None))

        # create the "sos1" constraint
        b.lam_sos1 = pyo.Constraint(expr=sum(b.lam[n]
                                             for n in b.interval_set) == 1.0)

        # create the x interval constraints
        b.x_interval_lb = pyo.Constraint(
            expr=sum(x_pts[n - 1] * b.lam[n] for n in b.interval_set) <= x)
        b.x_interval_ub = pyo.Constraint(
            expr=x <= sum(x_pts[n] * b.lam[n] for n in b.interval_set))

        # create the y constraints
        b.y_con = pyo.Constraint(expr=y == ylb + sum(b.delta_y[n]
                                                     for n in b.interval_set))

        def delta_yn_ub_rule(m, n):
            return b.delta_y[n] <= (yub - ylb) * b.lam[n]

        b.delta_yn_ub = pyo.Constraint(b.interval_set, rule=delta_yn_ub_rule)

        # create the relaxation constraints
        if relaxation_side == RelaxationSide.UNDER or relaxation_side == RelaxationSide.BOTH:
            b.w_lb1 = pyo.Constraint(
                expr=(w >= yub * x + sum(x_pts[n] * b.delta_y[n]
                                         for n in b.interval_set) -
                      (yub - ylb) * sum(x_pts[n] * b.lam[n]
                                        for n in b.interval_set)))
            b.w_lb2 = pyo.Constraint(
                expr=w >= ylb * x + sum(x_pts[n - 1] * b.delta_y[n]
                                        for n in b.interval_set))

        if relaxation_side == RelaxationSide.OVER or relaxation_side == RelaxationSide.BOTH:
            b.w_ub1 = pyo.Constraint(
                expr=(w <= yub * x + sum(x_pts[n - 1] * b.delta_y[n]
                                         for n in b.interval_set) -
                      (yub - ylb) * sum(x_pts[n - 1] * b.lam[n]
                                        for n in b.interval_set)))
            b.w_ub2 = pyo.Constraint(
                expr=w <= ylb * x + sum(x_pts[n] * b.delta_y[n]
                                        for n in b.interval_set))
Beispiel #45
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})

    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 results.solver.termination_condition == TerminationCondition.optimal
 def check(_T, _rho, func, val, rel=1e-4):
     val = pytest.approx(val, rel=rel)
     assert value(func(delta(_rho), tau(_T))) == val
def create_model(thermo_config=None, reaction_config=None):
    # Create a pyomo model object
    model = ConcreteModel()

    # Add an idaes flowsheet object to that model
    model.fs = FlowsheetBlock(default={"dynamic": False})

    # Add the generic properties object to that flowsheet
    #       and pass the custom configuation dictionary to it
    model.fs.thermo_params = GenericParameterBlock(default=thermo_config)

    # Add the generic reactions object to that flowsheet
    #   and pass the corresponding properties/params object to it
    #   along with the reaction_config dictionary
    model.fs.rxn_params = GenericReactionParameterBlock(
        default={
            "property_package": model.fs.thermo_params,
            **reaction_config
        })

    # Add the unit model for an Equilibrium Reactor to the flowsheet
    model.fs.unit = EquilibriumReactor(
        default={
            "property_package": model.fs.thermo_params,
            "reaction_package": model.fs.rxn_params,
            "has_rate_reactions": False,
            "has_equilibrium_reactions": True,
            "has_heat_transfer": False,
            "has_heat_of_reaction": False,
            "has_pressure_change": False
        })

    ## Use this function to ensure the units and unit conversions are all correct
    ##   This will throw an error if things are wrong
    #assert_units_consistent(model)

    print("Degrees of freedom = " + str(degrees_of_freedom(model)))

    # After building this model, there will be 9 degrees of freedom that MUST be
    #   fixed before calling the solver. Those degrees of freedom are based on
    #   the 'state_definition' defined in the 'thermo_config' dictionary and
    #   the number of components declared.
    #
    # For our problem:
    # ---------------
    #   'state_definition' == 'FTPx'
    #           Corresponds to:
    #           ---------------
    #                   model.fs.unit.inlet.flow_mol    -   mol/s
    #                   model.fs.unit.inlet.pressure    -   Pa
    #                   model.fs.unit.inlet.temperature -   K
    #                   model.fs.unit.inlet.mole_frac_comp[0, "name_of_component"]
    #                       (This one is repeated for each named component in 'thermo_config')
    #                       (The first value is the time stamp associated with the inlet,
    #                           which in our case is 0 because we are not a dynamic flowsheet)
    #
    #   'components' == ['H2O', 'H +', 'OH -', 'H2CO3', 'HCO3 -', 'CO3 2-']
    #           Corresponds to:
    #           ---------------
    #                   model.fs.unit.inlet.mole_frac_comp[0, "H2O"]    -   unitless
    #                   model.fs.unit.inlet.mole_frac_comp[0, "CO2"]    -   unitless
    #                       (Sum of all mole_frac_comp should equal 1.)
    model.fs.unit.inlet.flow_mol.fix(10)
    model.fs.unit.inlet.pressure.fix(101325.0)
    model.fs.unit.inlet.temperature.fix(300.0)

    # Set molefractions for ions... (this may change later)
    model.fs.unit.inlet.mole_frac_comp[0, "H +"].fix(0.)
    model.fs.unit.inlet.mole_frac_comp[0, "OH -"].fix(0.)
    model.fs.unit.inlet.mole_frac_comp[0, "HCO3 -"].fix(0.)
    model.fs.unit.inlet.mole_frac_comp[0, "CO3 2-"].fix(0.)

    # To come up with molefractions, we can start be pulling the water density from
    #   our thermo_config as follows (NOTE: it will have same units as before)
    #       [This approximation is valid for all aqueous chemistry]
    #
    #       Units:  kmol/m**3 == mol/L
    total_carbonate = 0.00206
    total_molar_density = calc_water_density(300)

    model.fs.unit.inlet.mole_frac_comp[0, "H2CO3"].fix(total_carbonate /
                                                       total_molar_density)

    # Perform a summation of all non-H2O molefractions to find the H2O molefraction
    sum = 0
    for i in model.fs.unit.inlet.mole_frac_comp:
        # NOTE: i will be a tuple with format (time, component)
        if i[1] != "H2O":
            sum += value(model.fs.unit.inlet.mole_frac_comp[i[0], i[1]])

    # Fix the inlet H2O molefraction based on remaining fraction
    model.fs.unit.inlet.mole_frac_comp[0, "H2O"].fix(1 - sum)

    #Setup scaling factors (optional)

    model.fs.thermo_params.default_scaling_factor[("mole_frac_comp",
                                                   "H +")] = 1e7
    model.fs.thermo_params.default_scaling_factor[("mole_frac_comp",
                                                   "OH -")] = 1e7
    model.fs.thermo_params.default_scaling_factor[("mole_frac_comp",
                                                   "HCO3 -")] = 1e7
    model.fs.thermo_params.default_scaling_factor[("mole_frac_comp",
                                                   "CO3 2-")] = 1e7
    model.fs.thermo_params.default_scaling_factor[("mole_frac_comp",
                                                   "H2CO3")] = 1e7
    model.fs.thermo_params.default_scaling_factor[("mole_frac_comp",
                                                   "H2O")] = 1

    # # TODO: ERROR! Cannot use this simple method to calculate scaling factors
    #           Model does not like it when I do this. I believe I have to give
    #           scaling factors for everything in the model for it to work properly.
    #iscale.calculate_scaling_factors(model.fs.unit)

    print("Degrees of freedom = " + str(degrees_of_freedom(model)))

    return model
    def test_solve_sat_density(self, model):
        """ The density calculations should be tested by the thermo expression
        tests, but they are pretty fundimental to everything else, so test them
        a little more on their own.
        """
        # test saturated liquid and vapor density solve (critical part of the
        # phase equlibrium calc)
        te = model.te
        data = read_sat_data(self.pdata_sat, self.mw)
        for i, T in enumerate(data["T"]):
            if T > self.Tc - 0.1:
                # if this goes over the critical temperature this makes no
                # sense
                # also really close to the critical temperature for various
                # reasons we'll diverge a bit from what we are comparing to
                pass
            else:
                tol = 1e-2
                # test p, x spec
                rhol = value(te.rho_liq(p=data["P"][i] * pyunits.Pa, x=0))
                rhov = value(te.rho_vap(p=data["P"][i] * pyunits.Pa, x=1))
                assert rhol == pytest.approx(value(data["rhol"][i]), rel=tol)
                assert rhov == pytest.approx(value(data["rhov"][i]), rel=tol)
                # test t, x spec
                rhol = value(te.rho_liq(T=T * pyunits.K, x=0))
                rhov = value(te.rho_vap(T=T * pyunits.K, x=1))
                assert rhol == pytest.approx(value(data["rhol"][i]), rel=tol)
                assert rhov == pytest.approx(value(data["rhov"][i]), rel=tol)

            # Ignore the phase equilibrium and use T,P data to calc densities
            if T > 296:
                tol = 1e-1  # data needs more sig fig
            rhol = value(
                te.rho_liq(p=data["P"][i] * pyunits.Pa, T=T * pyunits.K, x=0))
            rhov = value(
                te.rho_vap(p=data["P"][i] * pyunits.Pa, T=T * pyunits.K, x=1))
            assert rhol == pytest.approx(value(data["rhol"][i]), rel=tol)
            assert rhov == pytest.approx(value(data["rhov"][i]), rel=tol)
Beispiel #49
0
import pyomo.environ as pyo
from pyomo.opt import SolverFactory
model = pyo.ConcreteModel()
model.nVars = pyo.Param(initialize=4)
model.N = pyo.RangeSet(model.nVars)
model.x = pyo.Var(model.N, within=pyo.Binary)
model.obj = pyo.Objective(expr=pyo.summation(model.x), sense=minimize)
model.cuts = pyo.ConstraintList()
opt = SolverFactory('glpk')
opt.solve(model)

# Iterate, adding a cut to exclude the previously found solution
for i in range(5):
    expr = 0
    for j in model.x:
        if pyo.value(model.x[j]) < 0.5:
            expr += model.x[j]
        else:
            expr += (1 - model.x[j])
    model.cuts.add(expr >= min(i, 4))
    results = opt.solve(model)
    print("\n===== iteration", i)
    model.display()
    
    online_cb.receive_data(p_t={"p_t":p_t_samples[i],"RHS":RHS_t_samples[i]},x_t=x_t_samples[i])
    
    ## The next few statements do some basic checks.  They aren't comprehensive, but ##
    ## they are useful to showcase because they indicate some approaches to debugging pyomo models ##
    ## See documentation for sources regarding the pyomo package and its documentation (and some sites I found helpful) ##
    
    # Asserting that the parameters p_t and RHS_t both gets put into the BMPS_subproblem #
    assert online_cb.BMPS_subproblem.A.extract_values() == p_t_samples[i]
    assert online_cb.BMPS_subproblem.b.extract_values() == RHS_t_samples[i]
    
    # Doing Some constraint Checking #
    for constr in online_cb.BMPS_subproblem.component_objects(pyo.Constraint):
        assert constr._constructed == True, "Error in constraint construction (body)"
        for c in constr:
            lb = pyo.value(constr[c].lower)
            ub = pyo.value(constr[c].upper)
            assert ((lb is not None) or (ub is not None)), "Error in constraint construction (LHS/RHS)"
    
    ### Step 4: Finish out the Iteration by "solving subproblem", "performing gradient ###
    ### descent step", and calculating the learning rate (BMPS, 2018)
    
    online_cb.next_iteration(part_for_BMPS=2)
    #pdb.set_trace()
    
    ## Save some data ##
    c_t_dict_vecs[i] = copy.deepcopy(online_cb.c_t_BMPS)
    xbar_dict_vecs[i] = copy.deepcopy(online_cb.xbar_t_BMPS)

    
print("Run time (seconds) for the script: ")             
# define variables
model.x = pyo.Var(bounds=(0, 10))
model.y = pyo.Var(bounds=(0, 10))
x = model.x
y = model.y

# define constraints
model.C1 = pyo.Constraint(expr=-x + 2 * y * x <= 8)
model.C2 = pyo.Constraint(expr=2 * x + y <= 14)
model.C3 = pyo.Constraint(expr=2 * x - y <= 10)

# define objective function
model.obj = pyo.Objective(expr=x + y * x, sense=maximize)

# solver selection and run
opt = SolverFactory('ipopt')
opt.solve(model)

# print model
model.pprint()

# collect results
x_value = pyo.value(x)
y_value = pyo.value(y)

# display results
print(
    '\n---------------------------------------------------------------------')
print('x=', x_value)
print('y=', y_value)
Beispiel #52
0
def tpid(form):
    """This test is pretty course-grained, but it should cover everything"""

    # First calculate the two steady states that should be achieved in the test
    # don't worry these steady state problems solve super fast
    m_steady, solver = create_model()
    m_steady.fs.tank_pressure[0].fix(3e5)
    m_steady.fs.valve_1.valve_opening[0].unfix()
    solver.solve(m_steady, tee=True)
    s1_valve = pyo.value(m_steady.fs.valve_1.valve_opening[0])
    solver.solve(m_steady, tee=True)
    m_steady.fs.valve_1.inlet.pressure.fix(5.5e5)
    solver.solve(m_steady, tee=True)
    s2_valve = pyo.value(m_steady.fs.valve_1.valve_opening[0])

    # Next create a model for the 0 to 5 sec time period
    m_dynamic, solver = create_model(
        steady_state=False,
        time_set=[0, 5],
        nfe=10,
        calc_integ=True,
        form=form,
    )

    # Turn on control and solve since the setpoint is different than the
    # steady-state solution, stuff happens, also pressure step at t=5
    m_dynamic.fs.ctrl.activate()
    m_dynamic.fs.valve_1.valve_opening.unfix()
    m_dynamic.fs.valve_1.valve_opening[0].fix()

    # Add a step change right at the end of the interval, to make sure we can
    # get a continuous solution across the two models
    _add_inlet_pressure_step(m_dynamic, time=4.5, value=5.5e5)
    iscale.calculate_scaling_factors(m_dynamic)
    solver.solve(m_dynamic, tee=True)

    # Now create a model for the 5 to 10 second interval and set the inital
    # conditions of the first model to the final (unsteady) state of the
    # previous time interval model
    m_dynamic2, solver = create_model(
        steady_state=False,
        time_set=[5, 10],
        nfe=10,
        calc_integ=False,
        form=form,
    )

    m_dynamic2.fs.valve_1.valve_opening.fix(
        m_dynamic.fs.valve_1.valve_opening[5].value)
    m_dynamic2.fs.valve_1.inlet.enth_mol.fix(
        m_dynamic.fs.valve_1.inlet.enth_mol[5].value)
    m_dynamic2.fs.valve_1.inlet.pressure.fix(
        m_dynamic.fs.valve_1.inlet.pressure[5].value)
    for i in m_dynamic2.fs.tank.control_volume.material_accumulation:
        if i[0] == 5:
            m_dynamic2.fs.tank.control_volume.material_accumulation[i].value =\
                m_dynamic.fs.tank.control_volume.material_accumulation[i].value
    for i in m_dynamic2.fs.tank.control_volume.energy_accumulation:
        if i[0] == 5:
            m_dynamic2.fs.tank.control_volume.energy_accumulation[i].value =\
                m_dynamic.fs.tank.control_volume.energy_accumulation[i].value
    m_dynamic2.fs.ctrl.err_d0.fix(pyo.value(m_dynamic.fs.ctrl.err_d[5]))
    m_dynamic2.fs.ctrl.err_i0.fix(pyo.value(m_dynamic.fs.ctrl.err_i_end))

    iscale.calculate_scaling_factors(m_dynamic2)
    # As a lazy form of initialization, solve the steady state problem before
    # turning on the controller.
    solver.solve(m_dynamic2, tee=True)

    # Now turn on control and solve again.
    m_dynamic2.fs.ctrl.activate()
    m_dynamic2.fs.valve_1.valve_opening.unfix()
    m_dynamic2.fs.valve_1.valve_opening[5].fix()
    solver.solve(m_dynamic2, tee=True)

    # Check that the model hit steady state about. The tolerance is loose
    # because I used a low nfe in an attempt to speed it up
    t = m_dynamic.fs.time.get_lower_element_boundary(4.45)
    assert s1_valve == pytest.approx(pyo.value(
        m_dynamic.fs.valve_1.valve_opening[t]),
                                     abs=5e-3)

    # The second should hit steady state pretty quick if the two models
    # line up smoothly.
    t = m_dynamic2.fs.time.get_lower_element_boundary(7)
    assert s2_valve == pytest.approx(pyo.value(
        m_dynamic2.fs.valve_1.valve_opening[t]),
                                     abs=5e-3)

    stitch_time = stitch_dynamic(m_dynamic.fs.time, m_dynamic2.fs.time)
    stitch_valve = stitch_dynamic(m_dynamic.fs.valve_1.valve_opening,
                                  m_dynamic2.fs.valve_1.valve_opening)

    # test the stitch function used to plot time dependent variables across
    # the two models
    for i, t in enumerate(m_dynamic.fs.time):
        assert t == stitch_time[i]
        assert m_dynamic.fs.valve_1.valve_opening[t] == stitch_valve[i]
    for j, t in enumerate(m_dynamic2.fs.time):
        i = j + len(m_dynamic.fs.time)
        assert t == stitch_time[i]
        assert m_dynamic2.fs.valve_1.valve_opening[t] == stitch_valve[i]
Beispiel #53
0
    def initialize(blk, state_args={}, outlvl=idaeslog.NOTSET,
                   solver='ipopt', optarg={'tol': 1e-6}):
        '''
        water tank initialization routine.

        Keyword Arguments:
            state_args : a dict of arguments to be passed to the property
                           package(s) for the control_volume of the model to
                           provide an initial state for initialization
                           (see documentation of the specific property package)
                           (default = None).
            outlvl : sets output level of initialisation routine

                     * 0 = no output (default)
                     * 1 = return solver state for each step in routine
                     * 2 = return solver state for each step in subroutines
                     * 3 = include solver output infomation (tee=True)

            optarg : solver options dictionary object (default={'tol': 1e-6})
            solver : str indicating whcih solver to use during
                     initialization (default = 'ipopt')

        Returns:
            None
        '''
        init_log = idaeslog.getInitLogger(blk.name, outlvl, tag="unit")
        solve_log = idaeslog.getSolveLogger(blk.name, outlvl, tag="unit")

        opt = SolverFactory(solver)
        opt.options = optarg

        init_log.info_low("Starting initialization...")

        flags = blk.control_volume.initialize(state_args=state_args,
                                              outlvl=outlvl,
                                              optarg=optarg,
                                              solver=solver)
        init_log.info_high("Initialization Step 1 Complete.")

        # Fix outlet pressure
        for t in blk.flowsheet().config.time:
            blk.control_volume.properties_out[t].pressure.\
                fix(value(blk.control_volume.properties_in[t].pressure))
        blk.pressure_change_eqn.deactivate()

        # solve model
        with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc:
            res = opt.solve(blk, tee=slc.tee)
        init_log.info_high(
                "Initialization Step 2 {}.".format(idaeslog.condition(res))
            )

        # Unfix outlet pressure
        for t in blk.flowsheet().config.time:
            blk.control_volume.properties_out[t].pressure.unfix()
        blk.pressure_change_eqn.activate()

        with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc:
            res = opt.solve(blk, tee=slc.tee)
        init_log.info_high(
                "Initialization Step 3 {}.".format(idaeslog.condition(res))
            )

        blk.control_volume.release_state(flags, outlvl)
        init_log.info("Initialization Complete.")
Beispiel #54
0
    def test_build(self):
        model = ConcreteModel()
        model.params = GenericParameterBlock(default=configuration)

        assert isinstance(model.params.phase_list, Set)
        assert len(model.params.phase_list) == 2
        for i in model.params.phase_list:
            assert i in ["Liq", "Vap"]
        assert model.params.Liq.is_liquid_phase()
        assert model.params.Vap.is_vapor_phase()

        assert isinstance(model.params.component_list, Set)
        assert len(model.params.component_list) == 2
        for i in model.params.component_list:
            assert i in ['benzene', 'toluene']
            assert isinstance(model.params.get_component(i), Component)

        assert isinstance(model.params._phase_component_set, Set)
        assert len(model.params._phase_component_set) == 4
        for i in model.params._phase_component_set:
            assert i in [("Liq", "benzene"), ("Liq", "toluene"),
                         ("Vap", "benzene"), ("Vap", "toluene")]

        assert model.params.config.state_definition == FTPx

        assertStructuredAlmostEqual(
            model.params.config.state_bounds, {
                "flow_mol": (0, 100, 1000, pyunits.mol / pyunits.s),
                "temperature": (273.15, 300, 450, pyunits.K),
                "pressure": (5e4, 1e5, 1e6, pyunits.Pa)
            },
            item_callback=lambda x: value(x) *
            (pyunits.get_units(x) or pyunits.dimensionless)._get_pint_unit())

        assert model.params.config.phase_equilibrium_state == {
            ("Vap", "Liq"): SmoothVLE
        }

        assert isinstance(model.params.phase_equilibrium_idx, Set)
        assert len(model.params.phase_equilibrium_idx) == 2
        for i in model.params.phase_equilibrium_idx:
            assert i in ["PE1", "PE2"]

        assert model.params.phase_equilibrium_list == {
            "PE1": {
                "benzene": ("Vap", "Liq")
            },
            "PE2": {
                "toluene": ("Vap", "Liq")
            }
        }

        assert model.params.pressure_ref.value == 1e5
        assert model.params.temperature_ref.value == 300

        assert model.params.benzene.mw.value == 78.1136E-3
        assert model.params.benzene.pressure_crit.value == 48.9e5
        assert model.params.benzene.temperature_crit.value == 562.2

        assert model.params.toluene.mw.value == 92.1405E-3
        assert model.params.toluene.pressure_crit.value == 41e5
        assert model.params.toluene.temperature_crit.value == 591.8

        assert_units_consistent(model)
    def test_thermo_expression_writter(self, model):
        te = model.te

        data = read_data(self.pdata, self.mw)
        for i, T in enumerate(data["T"]):
            p = data["P"][i] * pyunits.Pa
            h = data["H"][i] * pyunits.J / pyunits.mol
            s = data["S"][i] * pyunits.J / pyunits.mol / pyunits.K
            u = data["U"][i] * pyunits.J / pyunits.mol
            if data["phase"][i] == "vapor":
                x = 1
            else:
                x = 0

            if value(p) < self.Pmin or value(p) > self.Pmax:
                continue
            if T < self.Tmin or T > self.Tmax:
                continue
            if i % self.onein:
                continue

            # Test state variable with P in the set, these are pretty reliable
            assert value(te.s(h=h, p=p)) == pytest.approx(value(s), rel=0.05)
            assert value(te.h(u=u, p=p)) == pytest.approx(value(h), rel=0.05)
            assert value(te.h(T=T * pyunits.K, p=p,
                              x=x)) == pytest.approx(value(h), rel=0.05)
            assert value(te.h(s=s, p=p)) == pytest.approx(value(h), rel=0.05)
            if value(p) < 2e6 or T < 290:
                # need data with more significant figure to test here
                # generally p(s, T) prbably isn't that useful for liquids
                # so I'll come back to it later with high precision data.
                continue
            assert value(te.p(s=s, T=T * pyunits.K)) == pytest.approx(value(p),
                                                                      rel=0.1)
Beispiel #56
0
    def CTT_week(self,events:dict,timeslots:Dict[str,List[int]],week: int):
        m = pe.ConcreteModel()
        #Only include timeslots that are not banned
        T = [item for key,sublist in timeslots.items() for item in sublist if item not in self.banned_keys]
        E = [key for key in events]
        R = [key for key in self.rooms]
        Index_old = [(e,t,r) for e in E for t in T for r in R]
        #Remove unnecessary indexes
        Index = self.remove_busy_room(self.remove_var_close_to_banned(Index_old))

        #minimize teacher duties per day
        m.x = pe.Var(Index, domain = pe.Binary)
        A = self.teacher_conflict_graph.get("week "+str(week))
        teacher_duties = set([event for t in A for event in t])
        teacher_expr = sum(sum(m.x[e,t,r] for t in times for e in teacher_duties for r in R if (e,t,r) in Index)-1 for times in timeslots.values())


        # #One event per day per course:
        # m.one_event_one_day = pe.ConstraintList()
        # for course_events in self.courses.values():
        #     for day in timeslots.values():
        #         if any((e,t,r) in Index for e in course_events for t in day for r in R):
        #             m.one_event_one_day.add(sum(m.x[e,t,r] for e in course_events for t in day for r in R if (e,t,r) in Index)<=1)

        #
        def obj_rule(m):
            A = self.student_conflict_graph.get("week "+str(week))
            starting_index = self.split_timeslots.get("week "+str(week)).get("day 0")[0]
            expr = 0
            for u,v in A:
                for t in T:
                    if any((u,l,r) in Index and (v,l,r) in Index for r in R for l in range(max(starting_index,t-self.events.get(u).get("duration")+1),t+1)):
                        expr += sum(m.x[u,l,r]+m.x[v,l,r] for r in R for l in range(max(starting_index,t-self.events.get(u).get("duration")+1),t+1) if (u,l,r) in Index and (v,l,r) in Index)
            return expr

        m.obj=pe.Objective(rule=obj_rule,sense = pe.minimize)
        # m.obj=pe.Objective(expr = teacher_expr, sense = pe.minimize)
        # m.obj=pe.Objective(expr = 0, sense = pe.minimize)

        #All events must happen
        m.events_must_happen = pe.ConstraintList()
        for e in E:
            m.events_must_happen.add(sum(m.x[e,t,r] for _,t,r in list(filter(lambda x: e == x[0],Index)))==1)

        #No teacher conflicts
        m.teacher_conflict = pe.ConstraintList()
        starting_index = self.split_timeslots.get("week "+str(week)).get("day 0")[0]
        print("Start: ",starting_index)
        for u,v in A:
            for t in T:
                if any((u,l,r) in Index and (v,l,r) in Index for r in R for l in range(max(starting_index,t-self.events.get(u).get("duration")+1),t+1)):
                    m.teacher_conflict.add(sum(m.x[u,l,r]+m.x[v,l,r] for r in R for l in range(max(starting_index,t-self.events.get(u).get("duration")+1),t+1) if (u,l,r) in Index and (v,l,r) in Index) <= 1)


        # #One event per day per course:
        # m.one_event_one_day = pe.ConstraintList()
        # for course_events in self.courses.values():
        #     for day in timeslots.values():
        #         if any((e,t,r) in Index for e in course_events for t in day for r in R):
        #             m.one_event_one_day.add(sum(m.x[e,t,r] for e in course_events for t in day for r in R if (e,t,r) in Index)<=1)

        #Room conflicts
        def room_conf(m,t,r):
            starting_index = self.split_timeslots.get("week "+str(week)).get("day 0")[0]
            if any((e,l,r) in Index for e in E for l in range(max(starting_index,t-self.events.get(e).get("duration")+1),t+1)):
                return sum(m.x[e,l,r] for e in E for l in range(max(starting_index,t-self.events.get(e).get("duration")+1),t+1) if (e,l,r) in Index) <= 1
            else:
                return pe.Constraint.Skip
        m.room_conflicts = pe.Constraint(T,R,rule=room_conf)


        #Precedence constraints
        m.precedence = pe.ConstraintList()
        for u,v in self.precedence_graph.get("week "+str(week)):
            for t in T:
                if any((u,l,r) in Index for l in range(timeslots.get("day 0")[0],t) for r in R):
                    m.precedence.add(sum(m.x[u,l,r]-m.x[v,l,r] for l in range(timeslots.get("day 0")[0],t+1) for r in R if (v,l,r) in Index and (u,l,r) in Index) >= 0)

        solver = pyomo.opt.SolverFactory('glpk')
        results = solver.solve(m,tee=True)
        print("HERE: ",pe.value(m.obj))
        for e in E:
            print("HERE: ",pe.value(m.x[e,timeslots["day 4"][0],0]))
        return [(e,t,r) for e,t,r in Index if pe.value(m.x[e,t,r]) ==1]
Beispiel #57
0
        start = time.time()
        #try:
        SolverFactory('mindtpy').solve(filename1.m, strategy='OA', iterlim=5)
        end = time.time()
        sys.stdout = old_stdout
        f.write(mystdout.getvalue())
        deltat = end - start
        f.write("\nTime elapsed: {}".format(dt))
        f.close()
        timetable.append([filename, end - start])
        subprocess.call(['mv ' + newname + ' ../' + solvername + 'results'],
                        shell=True)
        trcdata = filename + ', MindtPy, IPOPT, Gurobi' + str(
            dt
        ) + ', 0, eqnum?, varnum?, dvarnum?, nznum?, nlnz?, 0, modelstatus?, solvestatus?,' + str(
            value(filename1.m.obj)) + ', objest?,' + str(
                deltat) + ', 5, domviolations, numnodes,' + 'user'
        trcname = name + '_' + solvername + '.trc'
        with open(trcname, "w+") as trace:
            trace.write(trcdata)
        subprocess.call(['mv ' + trcname + ' ../' + solvername + 'results'],
                        shell=True)
        #except Exception as inst:
        #    errortable.append([filename, inst])
        #    continue

with open('1-instancetable' + solvername + '.csv', 'w+') as table:
    writer = csv.writer(table)
    [writer.writerow(r) for r in timetable]

with open('2-errortable' + solvername + '.csv', 'w+') as errors:
Beispiel #58
0
    def initialize(self,
                   state_args={},
                   outlvl=0,
                   solver='ipopt',
                   optarg={
                       'tol': 1e-6,
                       'max_iter': 30
                   }):
        """
        Initialize the outlet turbine stage model.  This deactivates the
        specialized constraints, then does the isentropic turbine initialization,
        then reactivates the constraints and solves.

        Args:
            state_args (dict): Initial state for property initialization
            outlvl (int): Amount of output (0 to 3) 0 is lowest
            solver (str): Solver to use for initialization
            optarg (dict): Solver arguments dictionary
        """
        stee = True if outlvl >= 3 else False
        # sp is what to save to make sure state after init is same as the start
        #   saves value, fixed, and active state, doesn't load originally free
        #   values, this makes sure original problem spec is same but initializes
        #   the values of free vars
        sp = StoreSpec.value_isfixed_isactive(only_fixed=True)
        istate = to_json(self, return_dict=True, wts=sp)
        # Deactivate special constraints
        self.stodola_equation.deactivate()
        self.isentropic_enthalpy.deactivate()
        self.efficiency_correlation.deactivate()
        self.deltaP.unfix()
        self.ratioP.unfix()
        # Fix turbine parameters + eff_isen
        self.eff_dry.fix()
        self.design_exhaust_flow_vol.fix()
        self.flow_coeff.fix()

        # fix inlet and free outlet
        for t in self.flowsheet().config.time:
            for k, v in self.inlet.vars.items():
                v[t].fix()
            for k, v in self.outlet.vars.items():
                v[t].unfix()
            # If there isn't a good guess for efficiency or outlet pressure
            # provide something reasonable.
            eff = self.efficiency_isentropic[t]
            eff.fix(
                eff.value if value(eff) > 0.3 and value(eff) < 1.0 else 0.8)
            # for outlet pressure try outlet pressure, pressure ratio, delta P,
            # then if none of those look reasonable use a pressure ratio of 0.8
            # to calculate outlet pressure
            Pout = self.outlet.pressure[t]
            Pin = self.inlet.pressure[t]
            prdp = value((self.deltaP[t] - Pin) / Pin)
            if value(Pout / Pin) > 0.9 or value(Pout / Pin) < 0.01:
                if value(self.ratioP[t]) < 0.9 and value(
                        self.ratioP[t]) > 0.01:
                    Pout.fix(value(Pin * self.ratioP))
                elif prdp < 0.9 and prdp > 0.01:
                    Pout.fix(value(prdp * Pin))
                else:
                    Pout.fix(value(Pin * 0.3))
            else:
                Pout.fix()
        self.deltaP[:] = value(Pout - Pin)
        self.ratioP[:] = value(Pout / Pin)

        for t in self.flowsheet().config.time:
            self.properties_isentropic[t].pressure.value = \
                value(self.outlet.pressure[t])
            self.properties_isentropic[t].flow_mol.value = \
                value(self.inlet.flow_mol[t])
            self.properties_isentropic[t].enth_mol.value = \
                value(self.inlet.enth_mol[t]*0.95)
            self.outlet.flow_mol[t].value = \
                value(self.inlet.flow_mol[t])
            self.outlet.enth_mol[t].value = \
                value(self.inlet.enth_mol[t]*0.95)

        # Make sure the initialization problem has no degrees of freedom
        # This shouldn't happen here unless there is a bug in this
        dof = degrees_of_freedom(self)
        try:
            assert (dof == 0)
        except:
            _log.exception("degrees_of_freedom = {}".format(dof))
            raise

        # one bad thing about reusing this is that the log messages aren't
        # really compatible with being nested inside another initialization
        super(TurbineOutletStageData, self).initialize(state_args=state_args,
                                                       outlvl=outlvl,
                                                       solver=solver,
                                                       optarg=optarg)

        # Free eff_isen and activate sepcial constarints
        self.efficiency_isentropic.unfix()
        self.outlet.pressure.unfix()
        self.stodola_equation.activate()
        self.isentropic_enthalpy.activate()
        self.efficiency_correlation.activate()

        slvr = SolverFactory(solver)
        slvr.options = optarg
        res = slvr.solve(self, tee=stee)

        if outlvl > 0:
            if res.solver.termination_condition == TerminationCondition.optimal:
                _log.info("{} Initialization Complete.".format(self.name))
            else:
                _log.warning(
                    """{} Initialization Failed. The most likely cause of initialization failure for
the Turbine inlet stages model is that the flow coefficient is not compatible
with flow rate guess.""".format(self.name))

        # reload original spec
        from_json(self, sd=istate, wts=sp)
Beispiel #59
0
    def test_T350_P1_x5(self):
        m = ConcreteModel()

        m.fs = FlowsheetBlock(default={'dynamic': False})

        m.fs.props = BT_PR.BTParameterBlock(
            default={'valid_phase': ('Vap', 'Liq')})

        m.fs.state = m.fs.props.build_state_block(
            default={'defined_state': True})

        m.fs.state.flow_mol.fix(100)
        m.fs.state.mole_frac_comp["benzene"].fix(0.5)
        m.fs.state.mole_frac_comp["toluene"].fix(0.5)
        m.fs.state.temperature.fix(350)
        m.fs.state.pressure.fix(1e5)

        # Trigger build of enthalpy and entropy
        m.fs.state.enth_mol_phase
        m.fs.state.entr_mol_phase

        m.fs.state.initialize(outlvl=0)

        solver.solve(m)

        assert pytest.approx(value(m.fs.state._teq), abs=1e-1) == 365
        assert 0.0035346 == pytest.approx(
            value(m.fs.state.compress_fact_phase["Liq"]), 1e-5)
        assert 0.966749 == pytest.approx(
            value(m.fs.state.compress_fact_phase["Vap"]), 1e-5)
        assert pytest.approx(
            value(m.fs.state.fug_coeff_phase_comp["Liq", "benzene"]),
            1e-5) == 0.894676
        assert pytest.approx(
            value(m.fs.state.fug_coeff_phase_comp["Liq", "toluene"]),
            1e-5) == 0.347566
        assert pytest.approx(
            value(m.fs.state.fug_coeff_phase_comp["Vap", "benzene"]),
            1e-5) == 0.971072
        assert pytest.approx(
            value(m.fs.state.fug_coeff_phase_comp["Vap", "toluene"]),
            1e-5) == 0.959791

        assert pytest.approx(
            value(m.fs.state.mole_frac_phase_comp["Liq", "benzene"]),
            1e-5) == 0.5
        assert pytest.approx(
            value(m.fs.state.mole_frac_phase_comp["Liq", "toluene"]),
            1e-5) == 0.5
        assert pytest.approx(
            value(m.fs.state.mole_frac_phase_comp["Vap", "benzene"]),
            1e-5) == 0.70584
        assert pytest.approx(
            value(m.fs.state.mole_frac_phase_comp["Vap", "toluene"]),
            1e-5) == 0.29416

        assert pytest.approx(value(m.fs.state.enth_mol_phase["Liq"]),
                             1e-5) == 38942.8
        assert pytest.approx(value(m.fs.state.enth_mol_phase["Vap"]),
                             1e-5) == 78048.7
        assert pytest.approx(value(m.fs.state.entr_mol_phase["Liq"]),
                             1e-5) == -367.558
        assert pytest.approx(value(m.fs.state.entr_mol_phase["Vap"]),
                             1e-5) == -269.0553
    def test_solution_equilibrium(self, equilibrium_reactions_config):
        model = equilibrium_reactions_config

        assert pytest.approx(297.9, rel=1e-5) == value(
            model.fs.unit.outlet.temperature[0])
        assert pytest.approx(10.0002, rel=1e-5) == value(
            model.fs.unit.outlet.flow_mol[0])
        assert pytest.approx(101325, rel=1e-5) == value(
            model.fs.unit.outlet.pressure[0])

        total_molar_density = \
            value(model.fs.unit.control_volume.properties_out[0.0].dens_mol_phase['Liq'])/1000
        assert pytest.approx(54.612040964248116,
                             rel=1e-5) == total_molar_density

        total_salt = value(model.fs.unit.outlet.mole_frac_comp[
            0, "Na_+"]) * total_molar_density * 23
        total_salt += value(model.fs.unit.outlet.mole_frac_comp[
            0, "Cl_-"]) * total_molar_density * 35.44
        total_salt += value(model.fs.unit.outlet.mole_frac_comp[
            0, "NaHCO3"]) * total_molar_density * 84
        psu = total_salt / (total_molar_density * 18) * 1000
        assert pytest.approx(32.66105, rel=1e-5) == psu

        total_carbonate = value(model.fs.unit.outlet.mole_frac_comp[
            0, "NaHCO3"]) * total_molar_density
        total_carbonate += value(
            model.fs.unit.outlet.mole_frac_comp[0,
                                                "H2CO3"]) * total_molar_density
        total_carbonate += value(model.fs.unit.outlet.mole_frac_comp[
            0, "HCO3_-"]) * total_molar_density
        total_carbonate += value(model.fs.unit.outlet.mole_frac_comp[
            0, "CO3_2-"]) * total_molar_density
        assert pytest.approx(0.0020528746175810923,
                             rel=1e-5) == total_carbonate

        carbonate_alk = value(model.fs.unit.outlet.mole_frac_comp[
            0, "HCO3_-"]) * total_molar_density
        carbonate_alk += 2 * value(model.fs.unit.outlet.mole_frac_comp[
            0, "CO3_2-"]) * total_molar_density
        carbonate_alk += value(
            model.fs.unit.outlet.mole_frac_comp[0,
                                                "OH_-"]) * total_molar_density
        carbonate_alk -= value(
            model.fs.unit.outlet.mole_frac_comp[0,
                                                "H_+"]) * total_molar_density
        carbonate_alk = carbonate_alk * 50000
        assert pytest.approx(79.389737, rel=1e-4) == carbonate_alk

        pH = -value(
            log10(model.fs.unit.outlet.mole_frac_comp[0, "H_+"] *
                  total_molar_density))
        pOH = -value(
            log10(model.fs.unit.outlet.mole_frac_comp[0, "OH_-"] *
                  total_molar_density))
        assert pytest.approx(8.31763834, rel=1e-4) == pH
        assert pytest.approx(5.6916662, rel=1e-4) == pOH