示例#1
0
    def test_solve4(self):
        model = ConcreteModel()
        model.A = RangeSet(1, 4)
        model.x = Var(model.A, bounds=(-1, 1))

        def obj_rule(model):
            return sum_product(model.x)

        model.obj = Objective(rule=obj_rule)

        def c_rule(model):
            expr = 0
            for i in model.A:
                expr += i * model.x[i]
            return expr == 0

        model.c = Constraint(rule=c_rule)
        opt = SolverFactory('glpk')
        results = opt.solve(model, symbolic_solver_labels=True)
        model.solutions.store_to(results)
        results.write(filename=join(currdir, 'solve4.out'), format='json')
        self.assertMatchesJsonBaseline(join(currdir, "solve4.out"),
                                       join(currdir, "solve1.txt"),
                                       tolerance=1e-4)
示例#2
0
    def Xtest_pyomo_Set_dat_file_domain(self):
        self.model = AbstractModel()
        self.model.s = Set()
        self.model.y = Var([1, 2], within=self.model.s)

        def obj_rule(model):
            return sum(model.y[i] * (-1)**(i - 1) for i in model.y)

        self.model.obj = Objective(
            rule=obj_rule
        )  #sum(self.model.y[i]*(-1)**(i-1) for i in self.model.y))
        self.model.con = Constraint([1, 2],
                                    rule=lambda model, i: model.y[i] *
                                    (-1)**(i - 1) >= (1.1)**(2 - i) *
                                    (-2.9)**(i - 1))

        self.instance = self.model.create_instance(currdir +
                                                   "vars_dat_file.dat")
        self.opt = SolverFactory("glpk")
        self.results = self.opt.solve(self.instance)
        self.instance.load(self.results)

        self.assertEqual(self.instance.y[1], 2)
        self.assertEqual(self.instance.y[2], 2)
示例#3
0
    def test_RIC_8PP_fixed_disjuncts(self):
        """Test RIC with 8PP using fixed disjuncts initialization."""
        exfile = import_file(
            join(exdir, 'eight_process', 'eight_proc_model.py'))
        eight_process = exfile.build_eight_process_flowsheet()
        initialize = [
            # Use units 1, 4, 7, 8
            eight_process.use_unit_1or2.disjuncts[0],
            eight_process.use_unit_3ornot.disjuncts[1],
            eight_process.use_unit_4or5ornot.disjuncts[0],
            eight_process.use_unit_6or7ornot.disjuncts[1],
            eight_process.use_unit_8ornot.disjuncts[0]
        ]
        for disj in eight_process.component_data_objects(Disjunct):
            if disj in initialize:
                disj.indicator_var.set_value(1)
            else:
                disj.indicator_var.set_value(0)
        SolverFactory('gdpopt').solve(
            eight_process, strategy='RIC', init_strategy='fix_disjuncts',
            mip_solver=mip_solver,
            nlp_solver=nlp_solver)

        self.assertTrue(fabs(value(eight_process.profit.expr) - 68) <= 1E-2)
示例#4
0
    def test_clone_gsl_function(self):
        DLL = find_GSL()
        if not DLL:
            self.skipTest("Could not find the amplgsl.dll library")
        m = ConcreteModel()
        m.z_func = ExternalFunction(library=DLL, function="gsl_sf_gamma")
        self.assertIsInstance(m.z_func, AMPLExternalFunction)
        m.x = Var(initialize=3, bounds=(1e-5, None))
        m.o = Objective(expr=m.z_func(m.x))

        opt = SolverFactory('ipopt')

        # Test a simple clone...
        model2 = m.clone()
        res = opt.solve(model2, tee=True)
        self.assertAlmostEqual(value(model2.o), 0.885603194411, 7)

        # Trigger the library to be loaded.  This tests that the CDLL
        # objects that are created when the SO/DLL are loaded do not
        # interfere with cloning the model.
        self.assertAlmostEqual(value(m.o), 2)
        model3 = m.clone()
        res = opt.solve(model3, tee=True)
        self.assertAlmostEqual(value(model3.o), 0.885603194411, 7)
示例#5
0
def test_battery_solve_2():
    m = ConcreteModel()
    m.fs = FlowsheetBlock(default={"dynamic": False})
    m.fs.battery = BatteryStorage()

    m.fs.battery.nameplate_power.set_value(5)
    m.fs.battery.nameplate_energy.fix(20)
    m.fs.battery.dt.set_value(1)

    m.fs.battery.elec_in.fix(5)
    m.fs.battery.elec_out.fix(0)
    m.fs.battery.state_of_charge.fix(5.0)
    m.fs.battery.energy_throughput.fix(2.5)

    assert_units_consistent(m)

    solver = SolverFactory('ipopt')
    results = solver.solve(m.fs)

    assert results.solver.termination_condition == TerminationCondition.optimal
    assert results.solver.status == SolverStatus.ok

    assert m.fs.battery.initial_state_of_charge.value == 0
    assert m.fs.battery.initial_energy_throughput.value == 0
示例#6
0
    def initialize(self, *args, **kwargs):
        """
        Use the regular heat exchanger initilization, with the extraction rate
        constraint deactivated; then it activates the constraint and calculates
        a steam inlet flow rate.
        """
        self.extraction_rate_constraint.deactivate()
        super().initialize(*args, **kwargs)
        self.extraction_rate_constraint.activate()

        solver = kwargs.get("solver", "ipopt")
        optarg = kwargs.get("oparg", {})
        outlvl = kwargs.get("outlvl", 0)

        opt = SolverFactory(solver)
        opt.options = optarg
        tee = True if outlvl >= 3 else False
        sp = StoreSpec.value_isfixed_isactive(only_fixed=True)
        istate = to_json(self, return_dict=True, wts=sp)

        self.area.fix()
        self.overall_heat_transfer_coefficient.fix()
        self.inlet_1.fix()
        self.inlet_2.fix()
        self.outlet_1.unfix()
        self.outlet_2.unfix()
        self.inlet_1.flow_mol.unfix()
        results = opt.solve(self, tee=tee)

        if results.solver.termination_condition == TerminationCondition.optimal:
            if outlvl >= 2:
                _log.info('{} Initialization Failed.'.format(self.name))
        else:
            _log.warning('{} Initialization Failed.'.format(self.name))

        from_json(self, sd=istate, wts=sp)
示例#7
0
    def solve(self, options, print_file=False):
        """
        Solve the problem.
        """
        model = get_model()
        data = self.get_input_data()

        if options is None:
            options = {}
        if "timeLimit" in options:
            if "SOLVER_PARAMETERS" in options:
                options["SOLVER_PARAMETERS"]["sec"] = options["timeLimit"]
            else:
                options["SOLVER_PARAMETERS"] = {"sec": options["timeLimit"]}
        else:
            options["SOLVER_PARAMETERS"] = SOLVER_PARAMETERS

        model_instance = model.create_instance(data, report_timing=False)
        opt = SolverFactory('cbc')
        opt.options.update(options["SOLVER_PARAMETERS"])
        result = opt.solve(model_instance, tee=False)

        self.status = get_status(result)
        self.model_solution = model_instance
        obj = model_instance.f_obj()
        print("Status: {} Objective value: {}".format(self.status, obj))

        if is_feasible(self.status):
            if print_file:
                self.print_instance()
            data = self.format_solution()
            self.solution = Solution(data)
        else:
            self.solution = Solution({})

        return get_status_value(self.status)
示例#8
0
def calculate_cafaro_coefficients(area1, area2, exponent):
    """Calculate the coefficients for the Cafaro approximation.

    Gives the coefficients k and b to approximate a function x^exponent such
    that at the given areas, the following relations apply:

    area1 ^ exponent = k * ln(b * area1 + 1)
    area2 ^ exponent = k * ln(b * area2 + 1)

    Args:
        area1 (float): area to use as the first regression point
        area2 (float): area to use as the second regression point
        exponent (float): exponent to approximate
    """
    m = ConcreteModel()
    m.k = Var(domain=NonNegativeReals)
    m.b = Var(domain=NonNegativeReals)

    m.c1 = Constraint(expr=area1**exponent == m.k * log(m.b * area1 + 1))
    m.c2 = Constraint(expr=area2**exponent == m.k * log(m.b * area2 + 1))

    SolverFactory('ipopt').solve(m)

    return value(m.k), value(m.b)
示例#9
0
def main():
    """
    Make the flowsheet object, fix some variables, and solve the problem
    """
    # Create a Concrete Model as the top level object
    m = ConcreteModel()

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

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

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

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

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

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

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

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

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

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

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

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

    # For testing purposes
    return (m, results)
示例#10
0
Author: John Eslick
"""
import pytest

from pyomo.environ import ConcreteModel, SolverFactory, TransformationFactory

from idaes.core import FlowsheetBlock
from idaes.unit_models.power_generation import SteamValve
from idaes.property_models import iapws95
from idaes.core.util.model_statistics import (degrees_of_freedom,
                                              activated_equalities_generator)

prop_available = iapws95.iapws95_available()

# See if ipopt is available and set up solver
if SolverFactory('ipopt').available():
    solver = SolverFactory('ipopt')
    solver.options = {'tol': 1e-6}
else:
    solver = None


@pytest.fixture()
def build_valve_vapor():
    m = ConcreteModel()
    m.fs = FlowsheetBlock(default={"dynamic": False})
    m.fs.properties = iapws95.Iapws95ParameterBlock()
    m.fs.valve = SteamValve(default={"property_package": m.fs.properties})
    return m

示例#11
0
    print('scenario ' + ss + ' solved in ' + str(time.time() - tt) +
          ' seconds')
    return output


#%% Start parallel solving of problems
#Create folders
if not os.path.exists(ResultFolderPath):
    os.makedirs(ResultFolderPath)

#Choose solver
if NEOS == 1:  #use neos server
    solver = SolverManagerFactory('neos')
else:
    solver = SolverFactory(
        SOLVER,
        executable=SOLVERPATH) if SOLVERPATH != 0 else SolverFactory(SOLVER)
    #if solver.name == 'ipopt':
    #solver.options['linear_solver']='ma97'
    #solver.options['mu_strategy']='adaptive'
    #solver.options['bound_relax_factor']=10**-12
    if solver.name == 'cplex' and PARALLEL_scenario == 1:
        solver.options['threads'] = 1  #limit the number of parallel computing

if __name__ == '__main__':
    scenarios = parameters.val['nscenario']
    if PARALLEL_scenario == 1:
        pool = mp.Pool(min(npll, len(scenarios)))
        parallelresults = pool.starmap(ScenarioAnalysis,
                                       [(ss, parameters, solver)
                                        for ss in scenarios])
示例#12
0
    def initialize(self,
                   state_args_1=None,
                   state_args_2=None,
                   outlvl=0,
                   solver='ipopt',
                   optarg={'tol': 1e-6},
                   duty=1000):
        """
        Heat exchanger initialization method.

        Args:
            state_args_1 : a dict of arguments to be passed to the property
                initialization for shell (see documentation of the specific
                property package) (default = {}).
            state_args_2 : a dict of arguments to be passed to the property
                initialization for tube (see documentation of the specific
                property package) (default = {}).
            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 which solver to use during
                     initialization (default = 'ipopt')
            duty : an initial guess for the amount of heat transfered
                (default = 10000)

        Returns:
            None

        """
        # Set solver options
        tee = True if outlvl >= 3 else False
        opt = SolverFactory(solver)
        opt.options = optarg
        flags1 = self.shell.initialize(outlvl=outlvl - 1,
                                       optarg=optarg,
                                       solver=solver,
                                       state_args=state_args_1)

        if outlvl > 0:
            _log.info('{} Initialization Step 1a (shell) Complete.'.format(
                self.name))

        flags2 = self.tube.initialize(outlvl=outlvl - 1,
                                      optarg=optarg,
                                      solver=solver,
                                      state_args=state_args_2)

        if outlvl > 0:
            _log.info('{} Initialization Step 1b (tube) Complete.'.format(
                self.name))
        # ---------------------------------------------------------------------
        # Solve unit without heat transfer equation
        self.heat_transfer_equation.deactivate()
        self.tube.heat.fix(duty)
        results = opt.solve(self, tee=tee, symbolic_solver_labels=True)
        if outlvl > 0:
            if results.solver.termination_condition == \
                    TerminationCondition.optimal:
                _log.info('{} Initialization Step 2 Complete.'.format(
                    self.name))
            else:
                _log.warning('{} Initialization Step 2 Failed.'.format(
                    self.name))
        self.tube.heat.unfix()
        self.heat_transfer_equation.activate()
        # ---------------------------------------------------------------------
        # Solve unit
        results = opt.solve(self, tee=tee, symbolic_solver_labels=True)
        if outlvl > 0:
            if results.solver.termination_condition == \
                    TerminationCondition.optimal:
                _log.info('{} Initialization Step 3 Complete.'.format(
                    self.name))
            else:
                _log.warning('{} Initialization Step 3 Failed.'.format(
                    self.name))
        # ---------------------------------------------------------------------
        # Release Inlet state
        self.shell.release_state(flags1, outlvl - 1)
        self.tube.release_state(flags2, outlvl - 1)

        if outlvl > 0:
            _log.info('{} Initialization Complete.'.format(self.name))
示例#13
0
def solve(instance, parsed_arguments):
    """
    :param instance: the compiled problem instance
    :param parsed_arguments: the user-defined arguments (parsed)
    :return: the problem results

    Send the compiled problem instance to the solver and solve.
    """
    # Start with solver name specified on command line
    solver_name = parsed_arguments.solver

    # Get any user-requested solver options
    scenario_directory = determine_scenario_directory(
        scenario_location=parsed_arguments.scenario_location,
        scenario_name=parsed_arguments.scenario)
    solver_options = dict()
    solver_options_file = os.path.join(scenario_directory,
                                       "solver_options.csv")
    if os.path.exists(solver_options_file):
        with open(solver_options_file) as f:
            _reader = reader(f, delimiter=",")
            for row in _reader:
                solver_options[row[0]] = row[1]

        # Check the the solver specified is the same as that given from the
        # command line (if any)
        if parsed_arguments.solver is not None:
            if parsed_arguments.solver == solver_options["solver"]:
                pass
            else:
                raise UserWarning(
                    "ERROR! Solver specified on command line ({}) and solver "
                    "in solver_options.csv ({}) do not match.".format(
                        parsed_arguments.solver, solver_options["solver"]))

        # If we make it here, set the solver name from the
        # solver_options.csv file
        solver_name = solver_options["solver"]
    else:
        if parsed_arguments.solver is None:
            solver_name = "cbc"

    # Get solver
    # If a solver executable is specified, pass it to Pyomo
    if parsed_arguments.solver_executable is not None:
        solver = SolverFactory(solver_name,
                               executable=parsed_arguments.solver_executable)
    # Otherwise, only pass the solver name; Pyomo will look for the
    # executable in the PATH
    else:
        solver = SolverFactory(solver_name)

    # Apply the solver options (if any)
    for opt in solver_options.keys():
        if opt == "solver":
            pass  # this is just the solver name, not actually an 'option'
        else:
            solver.options[opt] = solver_options[opt]

    # Solve
    # Note: Pyomo moves the results to the instance object by default.
    # If you want the results to stay into a results object, set the
    # load_solutions argument to False:
    # >>> results = solver.solve(instance, load_solutions=False)

    results = solver.solve(instance,
                           tee=not parsed_arguments.mute_solver_output,
                           keepfiles=parsed_arguments.keepfiles,
                           symbolic_solver_labels=parsed_arguments.symbolic)

    # Can optionally log infeasibilities but this has resulted in false
    # positives due to rounding errors larger than the default tolerance
    # of 1E-6.
    # log_infeasible_constraints(instance)

    return results
示例#14
0
if __name__ == '__main__':

    suffix = "v07"

    memory_log_filename = f"memory-{suffix}.log"
    gurobi_log_filename = f"gurobi-{suffix}.log"

    with memory_logger(filename=memory_log_filename, interval=1.) as mem:

        m = prepare_model()

        # This emulates what the pyomo command-line tools does
        options = {"threads": 4, "method": 2,
                   "crossover": 0, "BarConvTol": 1.e-3,
                   "FeasibilityTol": 1.e-5, "AggFill": 0,
                   "PreDual": 0, "GURO_PAR_BARDENSETHRESH": 200}
        opt = SolverFactory('gurobi', options=options)

        logger.info("start solving")
        results = opt.solve(m, logfile=gurobi_log_filename, options=options)
        logger.info("solving completed")

        # sends results to stdout
        results.write()
        print("\nDisplaying Solution\n" + '-'*60)

        pyomo_postprocess(options, m, results)

    logger.info("Maximum memory usage: {}".format(mem.mem_usage))
示例#15
0
model.no_cross_pair = ConstraintList()
for i in range(1, n + 1):
    for j in range(i, n + 1):
        for h in range(1, i):
            for k in range(i + 1, j):
                model.no_cross_pair.add(no_cross_rule(model, i, j, h, k))
                model.no_cross_pair.add(no_cross_rule(model, j, i, h, k))
                model.no_cross_pair.add(no_cross_rule(model, i, j, k, h))
                model.no_cross_pair.add(no_cross_rule(model, j, i, k, h))

#obj function
model.obj = Objective(expr=sum(model.P[i, j] for i in model.I
                               for j in model.J),
                      sense=maximize)

sol = SolverFactory('glpk').solve(model)
sol_json = sol.json_repn()

if sol_json['Solver'][0]['Status'] != 'ok':
    print("Problem unsolved")
if sol_json['Solver'][0]['Termination condition'] != 'optimal':
    print("Problem unsolved")

for i in range(1, n + 1):
    for j in range(1, n + 1):
        if model.P[i, j] == 1:
            print(i, j)

#try a plot
示例#16
0
class TestGDPoptUnit(unittest.TestCase):
    """Real unit tests for GDPopt"""
    @unittest.skipUnless(
        SolverFactory(mip_solver).available(), "MIP solver not available")
    def test_solve_linear_GDP_unbounded(self):
        m = ConcreteModel()
        m.GDPopt_utils = Block()
        m.x = Var(bounds=(-1, 10))
        m.y = Var(bounds=(2, 3))
        m.z = Var()
        m.d = Disjunction(expr=[[m.x + m.y >= 5], [m.x - m.y <= 3]])
        m.o = Objective(expr=m.z)
        m.GDPopt_utils.variable_list = [m.x, m.y, m.z]
        m.GDPopt_utils.disjunct_list = [
            m.d._autodisjuncts[0], m.d._autodisjuncts[1]
        ]
        output = StringIO()
        with LoggingIntercept(output, 'pyomo.contrib.gdpopt', logging.WARNING):
            solve_linear_GDP(m, GDPoptSolveData(),
                             GDPoptSolver.CONFIG(dict(mip_solver=mip_solver)))
            self.assertIn(
                "Linear GDP was unbounded. Resolving with arbitrary bound values",
                output.getvalue().strip())

    @unittest.skipUnless(
        SolverFactory(mip_solver).available(), "MIP solver not available")
    def test_solve_lp(self):
        m = ConcreteModel()
        m.x = Var(bounds=(-5, 5))
        m.c = Constraint(expr=m.x >= 1)
        m.o = Objective(expr=m.x)
        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)

    @unittest.skipUnless(
        SolverFactory(nlp_solver).available(), 'NLP solver not available')
    def test_solve_nlp(self):
        m = ConcreteModel()
        m.x = Var(bounds=(-5, 5))
        m.c = Constraint(expr=m.x >= 1)
        m.o = Objective(expr=m.x**2)
        output = StringIO()
        with LoggingIntercept(output, 'pyomo.contrib.gdpopt', logging.INFO):
            SolverFactory('gdpopt').solve(m, nlp_solver=nlp_solver)
            self.assertIn("Your model is an NLP (nonlinear program).",
                          output.getvalue().strip())
            self.assertAlmostEqual(value(m.o.expr), 1)

    @unittest.skipUnless(
        SolverFactory(mip_solver).available(), "MIP solver not available")
    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)

    @unittest.skipUnless(
        SolverFactory(nlp_solver).available(), 'NLP solver not available')
    def test_no_objective(self):
        m = ConcreteModel()
        m.x = Var(bounds=(-5, 5))
        m.c = Constraint(expr=m.x**2 >= 1)
        output = StringIO()
        with LoggingIntercept(output, 'pyomo.contrib.gdpopt', logging.WARNING):
            SolverFactory('gdpopt').solve(m, nlp_solver=nlp_solver)
            self.assertIn(
                "Model has no active objectives. Adding dummy objective.",
                output.getvalue().strip())

    def test_multiple_objectives(self):
        m = ConcreteModel()
        m.x = Var()
        m.o = Objective(expr=m.x)
        m.o2 = Objective(expr=m.x + 1)
        with self.assertRaisesRegexp(ValueError,
                                     "Model has multiple active objectives"):
            SolverFactory('gdpopt').solve(m)

    def test_is_feasible_function(self):
        m = ConcreteModel()
        m.x = Var(bounds=(0, 3), initialize=2)
        m.c = Constraint(expr=m.x == 2)
        self.assertTrue(is_feasible(m, GDPoptSolver.CONFIG()))

        m.c2 = Constraint(expr=m.x <= 1)
        self.assertFalse(is_feasible(m, GDPoptSolver.CONFIG()))

        m = ConcreteModel()
        m.x = Var(bounds=(0, 3), initialize=2)
        m.c = Constraint(expr=m.x >= 5)
        self.assertFalse(is_feasible(m, GDPoptSolver.CONFIG()))

        m = ConcreteModel()
        m.x = Var(bounds=(3, 3), initialize=2)
        self.assertFalse(is_feasible(m, GDPoptSolver.CONFIG()))

        m = ConcreteModel()
        m.x = Var(bounds=(0, 1), initialize=2)
        self.assertFalse(is_feasible(m, GDPoptSolver.CONFIG()))

        m = ConcreteModel()
        m.x = Var(bounds=(0, 1), initialize=2)
        m.d = Disjunct()
        with self.assertRaisesRegexp(NotImplementedError,
                                     "Found active disjunct"):
            is_feasible(m, GDPoptSolver.CONFIG())
示例#17
0
    def initialize(blk, outlvl=6, optarg={}, solver="ipopt", hold_state=False):
        """
        Initialization routine for mixer (default solver ipopt)

        Keyword Arguments:
            outlvl : sets output level of initialization routine
            optarg : solver options dictionary object (default={})
            solver : str indicating whcih solver to use during
                     initialization (default = 'ipopt')
            hold_state : flag indicating whether the initialization routine
                     should unfix any state variables fixed during
                     initialization, **default** - False. **Valid values:**
                     **True** - states variables are not unfixed, and a dict of
                     returned containing flags for which states were fixed
                     during initialization, **False** - state variables are
                     unfixed after initialization by calling the release_state
                     method.

        Returns:
            If hold_states is True, returns a dict containing flags for which
            states were fixed during initialization.
        """
        init_log = idaeslog.getInitLogger(blk.name, outlvl, tag="unit")
        solve_log = idaeslog.getSolveLogger(blk.name, outlvl, tag="unit")

        # Set solver options
        opt = SolverFactory(solver)
        opt.options = optarg

        # Initialize inlet state blocks
        flags = {}
        inlet_list = blk.create_inlet_list()
        i_block_list = []
        for i in inlet_list:
            i_block = getattr(blk, i + "_state")
            i_block_list.append(i_block)
            flags[i] = {}
            flags[i] = i_block.initialize(
                outlvl=outlvl,
                optarg=optarg,
                solver=solver,
                hold_state=True,
            )

        # Initialize mixed state block
        if blk.config.mixed_state_block is None:
            mblock = blk.mixed_state
        else:
            mblock = blk.config.mixed_state_block

        o_flags = {}
        # Calculate initial guesses for mixed stream state
        for t in blk.flowsheet().config.time:
            # Iterate over state vars as defined by property package
            s_vars = mblock[t].define_state_vars()
            for s in s_vars:
                i_vars = []
                for k in s_vars[s]:
                    # Record whether variable was fixed or not
                    o_flags[t, s, k] = s_vars[s][k].fixed

                    # If fixed, use current value
                    # otherwise calculate guess from mixed state
                    if not s_vars[s][k].fixed:
                        for i in range(len(i_block_list)):
                            i_vars.append(
                                getattr(i_block_list[i][t],
                                        s_vars[s].local_name)
                            )

                        if s == "pressure":
                            # If pressure, use minimum as initial guess
                            mblock[t].pressure.value = min(
                                i_block_list[i][t].pressure.value
                                for i in range(len(i_block_list))
                            )
                        elif "flow" in s:
                            # If a "flow" variable (i.e. extensive), sum inlets
                            for k in s_vars[s]:
                                s_vars[s][k].value = sum(
                                    i_vars[i][k].value for i in range(
                                        len(i_block_list))
                                )
                        else:
                            # Otherwise use average of inlets
                            for k in s_vars[s]:
                                s_vars[s][k].value = sum(
                                    i_vars[i][k].value for i in range(
                                        len(i_block_list))
                                ) / len(i_block_list)

        mblock.initialize(
            outlvl=outlvl,
            optarg=optarg,
            solver=solver,
            hold_state=False,
        )

        # Revert fixed status of variables to what they were before
        for t in blk.flowsheet().config.time:
            s_vars = mblock[t].define_state_vars()
            for s in s_vars:
                for k in s_vars[s]:
                    s_vars[s][k].fixed = o_flags[t, s, k]

        if blk.config.mixed_state_block is None:
            if (
                hasattr(blk, "pressure_equality_constraints")
                and blk.pressure_equality_constraints.active is True
            ):
                blk.pressure_equality_constraints.deactivate()
                for t in blk.flowsheet().config.time:
                    sys_press = getattr(
                        blk,
                        blk.create_inlet_list()[0] + "_state")[t].pressure
                    blk.mixed_state[t].pressure.fix(sys_press.value)
                with idaeslog.solver_log(solve_log, idaeslog.DEBUG)as slc:
                    res = opt.solve(blk, tee=slc.tee)
                blk.pressure_equality_constraints.activate()
                for t in blk.flowsheet().config.time:
                    blk.mixed_state[t].pressure.unfix()
            else:
                with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc:
                    res = opt.solve(blk, tee=slc.tee)

            init_log.info(
                "Initialization Complete: {}".format(idaeslog.condition(res))
            )
        else:
            init_log.info("Initialization Complete.")

        if hold_state is True:
            return flags
        else:
            blk.release_state(flags, outlvl=outlvl)
示例#18
0
    def initialize(self, state_args={}, outlvl=0, solver='ipopt',
        optarg={'tol': 1e-6, 'max_iter':30}):
        """
        Initialize the inlet 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.inlet_flow_constraint.deactivate()
        self.isentropic_enthalpy.deactivate()
        self.efficiency_correlation.deactivate()
        self.deltaP.unfix()
        self.ratioP.unfix()

        # Fix turbine parameters + eff_isen
        self.eff_nozzle.fix()
        self.blade_reaction.fix()
        self.flow_coeff.fix()
        self.blade_velocity.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 efficeny 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.98 or value(Pout/Pin) < 0.3:
                if value(self.ratioP[t]) < 0.98 and value(self.ratioP[t]) > 0.3:
                    Pout.fix(value(Pin*self.ratioP))
                elif prdp < 0.98 and prdp > 0.3:
                    Pout.fix(value(prdp*Pin))
                else:
                    Pout.fix(value(Pin*0.8))
            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(TurbineInletStageData, 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.inlet_flow_constraint.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)
示例#19
0
#  rights in this software.
#  This software is distributed under the 3-clause BSD License.
#  ___________________________________________________________________________
"""Tests the induced linearity module."""
import pyutilib.th as unittest
from pyomo.contrib.preprocessing.plugins.induced_linearity import (
    _bilinear_expressions, detect_effectively_discrete_vars,
    determine_valid_values)
from pyomo.common.collections import ComponentSet, Bunch
from pyomo.environ import (Binary, ConcreteModel, Constraint, ConstraintList,
                           Integers, RangeSet, SolverFactory,
                           TransformationFactory, Var, exp)
from pyomo.gdp import Disjunct, Disjunction
from pyomo.repn import generate_standard_repn

glpk_available = SolverFactory('glpk').available()


class TestInducedLinearity(unittest.TestCase):
    """Tests induced linearity."""
    def test_detect_bilinear_vars(self):
        m = ConcreteModel()
        m.x = Var()
        m.y = Var()
        m.z = Var()
        m.c = Constraint(expr=(m.x - 3) * (m.y + 2) - (m.z + 4) * m.y +
                         (m.x + 2)**2 + exp(m.y**2) * m.x <= m.z)
        m.c2 = Constraint(expr=m.x * m.y == 3)
        bilinear_map = _bilinear_expressions(m)
        self.assertEqual(len(bilinear_map), 3)
        self.assertEqual(len(bilinear_map[m.x]), 2)
示例#20
0
        sum(model.works[worker, 'Sat', shift]
            for shift in days_shifts['Sat']) -
        sum(model.works[worker, 'Sun', shift]
            for shift in days_shifts['Sun']) <= model.no_pref[worker])

# My additional experiments

# 6. Add a constraint that W1, W2 and W3 can never work the same shift (say they don't cooperate well :( ).
for day in days:
    for shift in days_shifts[day]:
        model.constraints.add(
            model.works['W1', day, shift] + model.works['W2', day, shift] +
            model.works['W3', day, shift] <= 1)

# We will use coin or branch and cut solver
opt = SolverFactory('cbc')

# We will use neos server to solve
solver_manager = SolverManagerFactory('neos')

results = solver_manager.solve(model, opt=opt)


def get_workers_needed(needed):
    """Extract to a list the needed workers for the optimal solution."""
    workers_needed = []
    for worker in workers:
        if needed[worker].value == 1:
            workers_needed.append(worker)
    return workers_needed
示例#21
0
"""Tests for the GDPbb solver plugin."""
from math import fabs
from os.path import abspath, dirname, join, normpath

import pyutilib.th as unittest
from pyutilib.misc import import_file

from pyomo.contrib.satsolver.satsolver import _z3_available
from pyomo.environ import SolverFactory, value

currdir = dirname(abspath(__file__))
exdir = normpath(join(currdir, '..', '..', '..', 'examples', 'gdp'))

minlp_solver = 'baron'
minlp_args = dict()
solver_available = SolverFactory(minlp_solver).available()
license_available = SolverFactory(
    minlp_solver).license_is_valid() if solver_available else False


@unittest.skipUnless(solver_available,
                     "Required subsolver %s is not available" %
                     (minlp_solver, ))
class TestGDPBB(unittest.TestCase):
    """Tests for logic-based branch and bound."""
    @unittest.skipUnless(license_available,
                         "Problem is too big for unlicensed BARON.")
    def test_LBB_8PP(self):
        """Test the logic-based branch and bound algorithm."""
        exfile = import_file(
            join(exdir, 'eight_process', 'eight_proc_model.py'))
示例#22
0
    def test_solve_with_pickle_then_clone(self):
        # This tests github issue Pyomo-#65
        model = ConcreteModel()
        model.A = RangeSet(1, 4)
        model.b = Block()
        model.b.x = Var(model.A, bounds=(-1, 1))
        model.b.obj = Objective(expr=sum_product(model.b.x))
        model.c = Constraint(expr=model.b.x[1] >= 0)
        opt = SolverFactory('glpk')
        self.assertEqual(len(model.solutions), 0)
        results = opt.solve(model, symbolic_solver_labels=True)
        self.assertEqual(len(model.solutions), 1)
        #
        self.assertEqual(model.solutions[0].gap, 0.0)
        #self.assertEqual(model.solutions[0].status, SolutionStatus.feasible)
        self.assertEqual(model.solutions[0].message, None)
        #
        buf = pickle.dumps(model)
        tmodel = pickle.loads(buf)
        self.assertEqual(len(tmodel.solutions), 1)
        self.assertEqual(tmodel.solutions[0].gap, 0.0)
        #self.assertEqual(tmodel.solutions[0].status, SolutionStatus.feasible)
        self.assertEqual(tmodel.solutions[0].message, None)
        self.assertIn(id(tmodel.b.obj),
                      tmodel.solutions[0]._entry['objective'])
        self.assertIs(
            tmodel.b.obj,
            tmodel.solutions[0]._entry['objective'][id(tmodel.b.obj)][0]())

        inst = tmodel.clone()

        # make sure the clone has all the attributes
        self.assertTrue(hasattr(inst, 'A'))
        self.assertTrue(hasattr(inst, 'b'))
        self.assertTrue(hasattr(inst.b, 'x'))
        self.assertTrue(hasattr(inst.b, 'obj'))
        self.assertTrue(hasattr(inst, 'c'))
        # and that they were all copied
        self.assertIsNot(inst.A, tmodel.A)
        self.assertIsNot(inst.b, tmodel.b)
        self.assertIsNot(inst.b.x, tmodel.b.x)
        self.assertIsNot(inst.b.obj, tmodel.b.obj)
        self.assertIsNot(inst.c, tmodel.c)

        # Make sure the solution is on the new model
        self.assertTrue(hasattr(inst, 'solutions'))
        self.assertEqual(len(inst.solutions), 1)
        self.assertEqual(inst.solutions[0].gap, 0.0)
        #self.assertEqual(inst.solutions[0].status, SolutionStatus.feasible)
        self.assertEqual(inst.solutions[0].message, None)

        # Spot-check some components and make sure all the weakrefs in
        # the ModelSOlution got updated
        self.assertIn(id(inst.b.obj), inst.solutions[0]._entry['objective'])
        _obj = inst.solutions[0]._entry['objective'][id(inst.b.obj)]
        self.assertIs(_obj[0](), inst.b.obj)

        for v in [1, 2, 3, 4]:
            self.assertIn(id(inst.b.x[v]),
                          inst.solutions[0]._entry['variable'])
            _v = inst.solutions[0]._entry['variable'][id(inst.b.x[v])]
            self.assertIs(_v[0](), inst.b.x[v])
示例#23
0
"""Tests for the MindtPy solver."""
import pyomo.core.base.symbolic
import pyomo.common.unittest as unittest
from pyomo.contrib.mindtpy.tests.eight_process_problem import \
    EightProcessFlowsheet
from pyomo.contrib.mindtpy.tests.MINLP_simple import SimpleMINLP as SimpleMINLP
from pyomo.contrib.mindtpy.tests.MINLP2_simple import SimpleMINLP as SimpleMINLP2
from pyomo.contrib.mindtpy.tests.MINLP3_simple import SimpleMINLP as SimpleMINLP3
from pyomo.contrib.mindtpy.tests.from_proposal import ProposalModel
from pyomo.contrib.mindtpy.tests.constraint_qualification_example import ConstraintQualificationExample
from pyomo.contrib.mindtpy.tests.online_doc_example import OnlineDocExample
from pyomo.environ import SolverFactory, value
from pyomo.opt import TerminationCondition

required_solvers = ('ipopt', 'cplex_persistent')
if all(SolverFactory(s).available(False) for s in required_solvers):
    subsolvers_available = True
else:
    subsolvers_available = False


@unittest.skipIf(not subsolvers_available,
                 "Required subsolvers %s are not available" %
                 (required_solvers, ))
@unittest.skipIf(not pyomo.core.base.symbolic.differentiate_available,
                 "Symbolic differentiation is not available")
class TestMindtPy(unittest.TestCase):
    """Tests for the MindtPy solver plugin."""

    # lazy callback tests
示例#24
0
from pyomo.gdp import Disjunct, Disjunction
from pyutilib.misc import import_file
from pyomo.contrib.mcpp.pyomo_mcpp import mcpp_available
from pyomo.opt import TerminationCondition

from pyomo.common.fileutils import PYOMO_ROOT_DIR
exdir = normpath(join(PYOMO_ROOT_DIR, 'examples', 'gdp'))

mip_solver = 'glpk'
nlp_solver = 'ipopt'
global_nlp_solver = 'baron'
global_nlp_solver_args = dict()
minlp_solver = 'baron'
LOA_solvers = (mip_solver, nlp_solver)
GLOA_solvers = (mip_solver, global_nlp_solver, minlp_solver)
LOA_solvers_available = all(SolverFactory(s).available() for s in LOA_solvers)
GLOA_solvers_available = all(
    SolverFactory(s).available() for s in GLOA_solvers)
license_available = SolverFactory(
    global_nlp_solver).license_is_valid() if GLOA_solvers_available else False


class TestGDPoptUnit(unittest.TestCase):
    """Real unit tests for GDPopt"""
    @unittest.skipUnless(
        SolverFactory(mip_solver).available(), "MIP solver not available")
    def test_solve_linear_GDP_unbounded(self):
        m = ConcreteModel()
        m.GDPopt_utils = Block()
        m.x = Var(bounds=(-1, 10))
        m.y = Var(bounds=(2, 3))
示例#25
0
        "energy_mixing_type": MixingType.extensive,
        "momentum_mixing_type": MomentumMixingType.none
    })

m.fs.Mixer.feed_1.flow_mass[0].fix(0.5)
m.fs.Mixer.feed_1.mass_frac[0].fix(0.1)
m.fs.Mixer.feed_1.temperature[0].fix(273.15 + 50)
m.fs.Mixer.feed_2.flow_mass[0].fix(0.5)
m.fs.Mixer.feed_2.mass_frac[0].fix(0.035)
m.fs.Mixer.feed_2.temperature[0].fix(273.15 + 25)
# m.fs.Mixer.outlet.temperature[0].fix(273.15 + 40)
# m.fs.Mixer.mixed_state[0].dens_mass
# m.fs.Mixer.mixed_state[0].viscosity
# m.fs.Mixer.mixed_state[0].dens_mass_comp
m.fs.Mixer.mixed_state[0].pressure_osm
# m.fs.Mixer.mixed_state[0].osm_coeff
# m.fs.Mixer.mixed_state[0].enth_mass_liq
m.fs.Mixer.initialize(outlvl=0)
print("Degrees of Freedom =", degrees_of_freedom(m))
assert degrees_of_freedom(m) == 0

solver = SolverFactory('ipopt')
solver.options = {'tol': 1e-6, 'max_iter': 5000}
results = solver.solve(m, tee=False)
assert results.solver.termination_condition == TerminationCondition.optimal
# m.display()
#
m.fs.Mixer.display()
for p in m.fs.Mixer.component_objects(Port, descend_into=True):
    p.display()
# m.fs.Mixer.pprint()
示例#26
0
class TestGDPopt(unittest.TestCase):
    """Tests for the GDPopt solver plugin."""
    def test_infeasible_GDP(self):
        """Test for infeasible GDP."""
        m = ConcreteModel()
        m.x = Var(bounds=(0, 2))
        m.d = Disjunction(
            expr=[[m.x**2 >= 3, m.x >= 3], [m.x**2 <= -1, m.x <= -1]])
        m.o = Objective(expr=m.x)
        output = StringIO()
        with LoggingIntercept(output, 'pyomo.contrib.gdpopt', logging.WARNING):
            SolverFactory('gdpopt').solve(m,
                                          strategy='LOA',
                                          mip_solver=mip_solver,
                                          nlp_solver=nlp_solver)
            self.assertIn("Set covering problem was infeasible.",
                          output.getvalue().strip())

    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)

    def test_LOA_8PP_default_init(self):
        """Test logic-based outer approximation with 8PP."""
        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',
                                      mip_solver=mip_solver,
                                      nlp_solver=nlp_solver,
                                      tee=False)
        self.assertTrue(fabs(value(eight_process.profit.expr) - 68) <= 1E-2)

    @unittest.skipUnless(
        SolverFactory('gams').available(exception_flag=False),
        'GAMS solver not available')
    def test_LOA_8PP_gams_solver(self):
        # Make sure that the duals are still correct
        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',
                                      mip_solver=mip_solver,
                                      nlp_solver='gams',
                                      max_slack=0,
                                      tee=False)
        self.assertTrue(fabs(value(eight_process.profit.expr) - 68) <= 1E-2)

    def test_LOA_8PP_force_NLP(self):
        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',
                                      mip_solver=mip_solver,
                                      nlp_solver=nlp_solver,
                                      force_subproblem_nlp=True,
                                      tee=False)
        self.assertTrue(fabs(value(eight_process.profit.expr) - 68) <= 1E-2)

    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)

    def test_LOA_constrained_layout_default_init(self):
        """Test LOA with constrained layout."""
        exfile = import_file(
            join(exdir, 'constrained_layout', 'cons_layout_model.py'))
        cons_layout = exfile.build_constrained_layout_model()
        SolverFactory('gdpopt').solve(
            cons_layout,
            strategy='LOA',
            mip_solver=mip_solver,
            nlp_solver=nlp_solver,
            iterlim=120,
            max_slack=5,  # problem is convex, so can decrease slack
        )
        objective_value = value(cons_layout.min_dist_cost.expr)
        self.assertTrue(
            fabs(objective_value - 41573) <= 200,
            "Objective value of %s instead of 41573" % objective_value)

    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)

    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)

    def test_LOA_8PP_fixed_disjuncts(self):
        """Test LOA with 8PP using fixed disjuncts initialization."""
        exfile = import_file(
            join(exdir, 'eight_process', 'eight_proc_model.py'))
        eight_process = exfile.build_eight_process_flowsheet()
        initialize = [
            # Use units 1, 4, 7, 8
            eight_process.use_unit_1or2.disjuncts[0],
            eight_process.use_unit_3ornot.disjuncts[1],
            eight_process.use_unit_4or5ornot.disjuncts[0],
            eight_process.use_unit_6or7ornot.disjuncts[1],
            eight_process.use_unit_8ornot.disjuncts[0]
        ]
        for disj in eight_process.component_data_objects(Disjunct):
            if disj in initialize:
                disj.indicator_var.set_value(1)
            else:
                disj.indicator_var.set_value(0)
        SolverFactory('gdpopt').solve(eight_process,
                                      strategy='LOA',
                                      init_strategy='fix_disjuncts',
                                      mip_solver=mip_solver,
                                      nlp_solver=nlp_solver)

        self.assertTrue(fabs(value(eight_process.profit.expr) - 68) <= 1E-2)

    def test_LOA_custom_disjuncts(self):
        """Test logic-based OA with custom disjuncts initialization."""
        exfile = import_file(
            join(exdir, 'eight_process', 'eight_proc_model.py'))
        eight_process = exfile.build_eight_process_flowsheet()
        initialize = [
            # Use units 1, 4, 7, 8
            [
                eight_process.use_unit_1or2.disjuncts[0],
                eight_process.use_unit_3ornot.disjuncts[1],
                eight_process.use_unit_4or5ornot.disjuncts[0],
                eight_process.use_unit_6or7ornot.disjuncts[1],
                eight_process.use_unit_8ornot.disjuncts[0]
            ],
            # Use units 2, 4, 6, 8
            [
                eight_process.use_unit_1or2.disjuncts[1],
                eight_process.use_unit_3ornot.disjuncts[1],
                eight_process.use_unit_4or5ornot.disjuncts[0],
                eight_process.use_unit_6or7ornot.disjuncts[0],
                eight_process.use_unit_8ornot.disjuncts[0]
            ]
        ]

        def assert_correct_disjuncts_active(nlp_model, solve_data):
            if solve_data.master_iteration >= 1:
                return  # only checking initialization
            iter_num = solve_data.nlp_iteration
            disjs_should_be_active = initialize[iter_num - 1]
            for orig_disj, soln_disj in zip(
                    solve_data.original_model.GDPopt_utils.disjunct_list,
                    nlp_model.GDPopt_utils.disjunct_list):
                if orig_disj in disjs_should_be_active:
                    self.assertTrue(soln_disj.indicator_var.value == 1)

        SolverFactory('gdpopt').solve(
            eight_process,
            strategy='LOA',
            init_strategy='custom_disjuncts',
            custom_init_disjuncts=initialize,
            mip_solver=mip_solver,
            nlp_solver=nlp_solver,
            call_after_subproblem_feasible=assert_correct_disjuncts_active)

        self.assertTrue(fabs(value(eight_process.profit.expr) - 68) <= 1E-2)
示例#27
0
    def initialize(blk, outlvl=0, optarg={}, solver='ipopt', hold_state=False):
        '''
        Initialisation routine for separator (default solver ipopt)

        Keyword Arguments:
            outlvl : sets output level of initialisation routine. **Valid
                     values:** **0** - no output (default), **1** - return
                     solver state for each step in routine, **2** - include
                     solver output infomation (tee=True)
            optarg : solver options dictionary object (default=None)
            solver : str indicating whcih solver to use during
                     initialization (default = 'ipopt')
            hold_state : flag indicating whether the initialization routine
                     should unfix any state variables fixed during
                     initialization, **default** - False. **Valid values:**
                     **True** - states variables are not unfixed, and a dict of
                     returned containing flags for which states were fixed
                     during initialization, **False** - state variables are
                     unfixed after initialization by calling the release_state
                     method.

        Returns:
            If hold_states is True, returns a dict containing flags for which
            states were fixed during initialization.
        '''
        # Set solver options
        if outlvl > 1:
            stee = True
        else:
            stee = False

        opt = SolverFactory(solver)
        opt.options = optarg

        # Initialize mixed state block
        if blk.config.mixed_state_block is not None:
            mblock = blk.config.mixed_state_block
        else:
            mblock = blk.mixed_state
        flags = mblock.initialize(outlvl=outlvl - 1,
                                  optarg=optarg,
                                  solver=solver,
                                  hold_state=True)

        if blk.config.ideal_separation:
            # If using ideal splitting, initialisation should be complete
            return flags

        # Initialize outlet StateBlocks
        outlet_list = blk.create_outlet_list()

        for o in outlet_list:
            # Get corresponding outlet StateBlock
            o_block = getattr(blk, o + "_state")

            for t in blk.flowsheet().config.time:

                # Calculate values for state variables
                s_vars = o_block[t].define_state_vars()

                for v in s_vars:
                    m_var = getattr(mblock[t], s_vars[v].local_name)

                    if "flow" in v:
                        # If a "flow" variable, is extensive
                        # Apply split fraction
                        try:
                            for k in s_vars[v]:
                                if (k is None or blk.config.split_basis
                                        == SplittingType.totalFlow):
                                    s_vars[v][k].value = value(
                                        m_var[k] * blk.split_fraction[(t, o)])
                                else:
                                    s_vars[v][k].value = value(
                                        m_var[k] *
                                        blk.split_fraction[(t, o) + k])
                        except KeyError:
                            raise KeyError(
                                "{} state variable and split fraction "
                                "indexing sets do not match. The in-built"
                                " initialization routine for Separators "
                                "relies on the split fraction and state "
                                "variable indexing sets matching to "
                                "calculate initial guesses for extensive "
                                "variables. In other cases users will "
                                "need to provide their own initial "
                                "guesses".format(blk.name))
                    else:
                        # Otherwise intensive, equate to mixed stream
                        for k in s_vars[v]:
                            s_vars[v][k].value = m_var[k].value

                # Call initialization routine for outlet StateBlock
                o_block.initialize(outlvl=outlvl - 1,
                                   optarg=optarg,
                                   solver=solver,
                                   hold_state=False)

        if blk.config.mixed_state_block is None:
            results = opt.solve(blk, tee=stee)

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

        if hold_state is True:
            return flags
        else:
            blk.release_state(flags, outlvl=outlvl - 1)
示例#28
0
def homotopy(model,
             variables,
             targets,
             max_solver_iterations=50,
             max_solver_time=10,
             step_init=0.1,
             step_cut=0.5,
             iter_target=4,
             step_accel=0.5,
             max_step=1,
             min_step=0.05,
             max_eval=200):
    """
    Homotopy meta-solver routine using Ipopt as the non-linear solver. This
    routine takes a model along with a list of fixed variables in that model
    and a list of target values for those variables. The routine then tries to
    iteratively move the values of the fixed variables to their target values
    using an adaptive step size.

    Args:
        model : model to be solved
        variables : list of Pyomo Var objects to be varied using homotopy.
                    Variables must be fixed.
        targets : list of target values for each variable
        max_solver_iterations : maximum number of solver iterations per
                    homotopy step (default=50)
        max_solver_time : maximum cpu time for the solver per homotopy step
                    (default=10)
        step_init : initial homotopy step size (default=0.1)
        step_cut : factor by which to reduce step size on failed step
                    (default=0.5)
        step_accel : acceleration factor for adjusting step size on successful
                     step (default=0.5)
        iter_target : target number of solver iterations per homotopy step
                    (default=4)
        max_step : maximum homotopy step size (default=1)
        min_step : minimum homotopy step size (default=0.05)
        max_eval : maximum number of homotopy evaluations (both successful and
                   unsuccessful) (default=200)

    Returns:
        Termination Condition : A Pyomo TerminationCondition Enum indicating
            how the meta-solver terminated (see documentation)
        Solver Progress : a fraction indication how far the solver progressed
            from the initial values to the target values
        Number of Iterations : number of homotopy evaluations before solver
            terminated
    """
    eps = 1e-3  # Tolerance for homotopy step convergence to 1

    # Get model logger
    _log = logging.getLogger(__name__)

    # Validate model is an instance of Block
    if not isinstance(model, Block):
        raise TypeError("Model provided was not a valid Pyomo model object "
                        "(instance of Block). Please provide a valid model.")
    if degrees_of_freedom(model) != 0:
        raise ConfigurationError(
            "Degrees of freedom in model are not equal to zero. Homotopy "
            "should not be used on probelms which are not well-defined.")

    # Validate variables and targets
    if len(variables) != len(targets):
        raise ConfigurationError(
            "Number of variables and targets do not match.")
    for i in range(len(variables)):
        v = variables[i]
        t = targets[i]

        if not isinstance(v, _VarData):
            raise TypeError("Variable provided ({}) was not a valid Pyomo Var "
                            "component.".format(v))

        # Check that v is part of model
        parent = v.parent_block()
        while parent != model:
            if parent is None:
                raise ConfigurationError(
                    "Variable {} is not part of model".format(v))
            parent = parent.parent_block()

        # Check that v is fixed
        if not v.fixed:
            raise ConfigurationError(
                "Homotopy metasolver provided with unfixed variable {}."
                "All variables must be fixed.".format(v.name))

        # Check bounds on v (they don't really matter, but check for sanity)
        if v.ub is not None:
            if v.value > v.ub:
                raise ConfigurationError(
                    "Current value for variable {} is greater than the "
                    "upper bound for that variable. Please correct this "
                    "before continuing.".format(v.name))
            if t > v.ub:
                raise ConfigurationError(
                    "Target value for variable {} is greater than the "
                    "upper bound for that variable. Please correct this "
                    "before continuing.".format(v.name))
        if v.lb is not None:
            if v.value < v.lb:
                raise ConfigurationError(
                    "Current value for variable {} is less than the "
                    "lower bound for that variable. Please correct this "
                    "before continuing.".format(v.name))
            if t < v.lb:
                raise ConfigurationError(
                    "Target value for variable {} is less than the "
                    "lower bound for that variable. Please correct this "
                    "before continuing.".format(v.name))

    # TODO : Should we be more restrictive on these values to avoid users
    # TODO : picking numbers that are less likely to solve (but still valid)?
    # Validate homotopy parameter selections
    if not 0.05 <= step_init <= 0.8:
        raise ConfigurationError("Invalid value for step_init ({}). Must lie "
                                 "between 0.05 and 0.8.".format(step_init))
    if not 0.1 <= step_cut <= 0.9:
        raise ConfigurationError("Invalid value for step_cut ({}). Must lie "
                                 "between 0.1 and 0.9.".format(step_cut))
    if step_accel < 0:
        raise ConfigurationError(
            "Invalid value for step_accel ({}). Must be "
            "greater than or equal to 0.".format(step_accel))
    if iter_target < 1:
        raise ConfigurationError(
            "Invalid value for iter_target ({}). Must be "
            "greater than or equal to 1.".format(iter_target))
    if not isinstance(iter_target, int):
        raise ConfigurationError("Invalid value for iter_target ({}). Must be "
                                 "an an integer.".format(iter_target))
    if not 0.05 <= max_step <= 1:
        raise ConfigurationError("Invalid value for max_step ({}). Must lie "
                                 "between 0.05 and 1.".format(max_step))
    if not 0.01 <= min_step <= 0.1:
        raise ConfigurationError("Invalid value for min_step ({}). Must lie "
                                 "between 0.01 and 0.1.".format(min_step))
    if not min_step <= max_step:
        raise ConfigurationError("Invalid argumnets: step_min must be less "
                                 "or equal to step_max.")
    if not min_step <= step_init <= max_step:
        raise ConfigurationError("Invalid arguments: step_init must lie "
                                 "between min_step and max_step.")
    if max_eval < 1:
        raise ConfigurationError(
            "Invalid value for max_eval ({}). Must be "
            "greater than or equal to 1.".format(step_accel))
    if not isinstance(max_eval, int):
        raise ConfigurationError("Invalid value for max_eval ({}). Must be "
                                 "an an integer.".format(iter_target))

    # Create solver object
    solver_obj = SolverFactory('ipopt')

    # Perform initial solve of model to confirm feasible initial solution
    results, solved, sol_iter, sol_time, sol_reg = ipopt_solve_with_stats(
        model, solver_obj, max_solver_iterations, max_solver_time)

    if not solved:
        _log.exception("Homotopy Failed - initial solution infeasible.")
        return TerminationCondition.infeasible, 0, 0
    elif sol_reg != "-":
        _log.warning(
            "Homotopy - initial solution converged with regularization.")
        return TerminationCondition.other, 0, 0
    else:
        _log.info("Homotopy - initial point converged")

    # Set up homotopy variables
    # Get initial values and deltas for all variables
    v_init = []
    for i in range(len(variables)):
        v_init.append(variables[i].value)

    n_0 = 0.0  # Homotopy progress variable
    s = step_init  # Set step size to step_init
    iter_count = 0  # Counter for homotopy iterations

    # Save model state to dict
    # TODO : for very large models, it may be necessary to dump this to a file
    current_state = to_json(model, return_dict=True)

    while n_0 < 1.0:
        iter_count += 1  # Increase iter_count regardless of success or failure

        # Calculate next n value given current step size
        if n_0 + s >= 1.0 - eps:
            n_1 = 1.0
        else:
            n_1 = n_0 + s

        _log.info("Homotopy Iteration {}. Next Step: {} (Current: {})".format(
            iter_count, n_1, n_0))

        # Update values for all variables using n_1
        for i in range(len(variables)):
            variables[i].fix(targets[i] * n_1 + v_init[i] * (1 - n_1))

        # Solve model at new state
        results, solved, sol_iter, sol_time, sol_reg = ipopt_solve_with_stats(
            model, solver_obj, max_solver_iterations, max_solver_time)

        # Check solver output for convergence
        if solved:
            # Step succeeded - accept current state
            current_state = to_json(model, return_dict=True)

            # Update n_0 to accept current step
            n_0 = n_1

            # Check solver iterations and calculate next step size
            s_proposed = s * (1 + step_accel * (iter_target / sol_iter - 1))

            if s_proposed > max_step:
                s = max_step
            elif s_proposed < min_step:
                s = min_step
            else:
                s = s_proposed
        else:
            # Step failed - reload old state
            from_json(model, current_state)

            # Try to cut back step size
            if s > min_step:
                # Step size can be cut
                s = max(min_step, s * step_cut)
            else:
                # Step is already at minimum size, terminate homotopy
                _log.exception(
                    "Homotopy failed - could not converge at minimum step "
                    "size. Current progress is {}".format(n_0))
                return TerminationCondition.minStepLength, n_0, iter_count

        if iter_count >= max_eval:  # Use greater than or equal to to be safe
            _log.exception("Homotopy failed - maximum homotopy iterations "
                           "exceeded. Current progress is {}".format(n_0))
            return TerminationCondition.maxEvaluations, n_0, iter_count

    if sol_reg == "-":
        _log.info("Homotopy successful - converged at target values in {} "
                  "iterations.".format(iter_count))
        return TerminationCondition.optimal, n_0, iter_count
    else:
        _log.exception("Homotopy failed - converged at target values with "
                       "regularization in {} iterations.".format(iter_count))
        return TerminationCondition.other, n_0, iter_count
from pyomo.environ import SolverFactory
from concrete1 import model

model.pprint()

instance = model.create()
instance.pprint()

opt = SolverFactory("glpk")
results = opt.solve(instance)

results.write()
示例#30
0
from pyomo.gdp import Disjunct, Disjunction
from pyutilib.misc import import_file
from pyomo.contrib.mcpp.pyomo_mcpp import mcpp_available
from pyomo.opt import TerminationCondition

currdir = dirname(abspath(__file__))
exdir = normpath(join(currdir, '..', '..', '..', '..', 'examples', 'gdp'))

mip_solver = 'glpk'
nlp_solver = 'ipopt'
global_nlp_solver = 'baron'
global_nlp_solver_args = dict()
minlp_solver = 'baron'
LOA_solvers = (mip_solver, nlp_solver)
GLOA_solvers = (mip_solver, global_nlp_solver, minlp_solver)
LOA_solvers_available = all(SolverFactory(s).available() for s in LOA_solvers)
GLOA_solvers_available = all(
    SolverFactory(s).available() for s in GLOA_solvers)


class TestGDPoptUnit(unittest.TestCase):
    """Real unit tests for GDPopt"""
    @unittest.skipUnless(
        SolverFactory(mip_solver).available(), "MIP solver not available")
    def test_solve_linear_GDP_unbounded(self):
        m = ConcreteModel()
        m.GDPopt_utils = Block()
        m.x = Var(bounds=(-1, 10))
        m.y = Var(bounds=(2, 3))
        m.z = Var()
        m.d = Disjunction(expr=[[m.x + m.y >= 5], [m.x - m.y <= 3]])