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)
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)
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)
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)
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
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)
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)
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)
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)
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
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])
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))
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
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))
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
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())
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)
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)
# 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)
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
"""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'))
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])
"""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
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))
"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()
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)
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)
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()
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]])