def prep_model_for_k_aug(self): """This function prepares the optimization models with required suffixes. Args: model_object (pyomo model): The model of the system Retuns: None """ self.model_object.dual = Suffix(direction=Suffix.IMPORT_EXPORT) # self.model_object.ipopt_zL_out = Suffix(direction=Suffix.IMPORT) # self.model_object.ipopt_zU_out = Suffix(direction=Suffix.IMPORT) # self.model_object.ipopt_zL_in = Suffix(direction=Suffix.EXPORT) # self.model_object.ipopt_zU_in = Suffix(direction=Suffix.EXPORT) # self.model_object.red_hessian = Suffix(direction=Suffix.EXPORT) # self.model_object.dof_v = Suffix(direction=Suffix.EXPORT) # self.model_object.rh_name = Suffix(direction=Suffix.IMPORT) count_vars = 1 for k, v in self.model_object.P.items(): self.model_object.dof_v[k] = count_vars count_vars += 1 self.model_object.npdp = Suffix(direction=Suffix.EXPORT) return None
def _prep_model_for_optimization(self, model): """This function prepares the optimization models with required suffixes. This is here because I don't know if this is already in KIPET somewhere else. Args: model (pyomo model): The model of the system Retuns: None """ model.dual = Suffix(direction=Suffix.IMPORT_EXPORT) model.ipopt_zL_out = Suffix(direction=Suffix.IMPORT) model.ipopt_zU_out = Suffix(direction=Suffix.IMPORT) model.ipopt_zL_in = Suffix(direction=Suffix.EXPORT) model.ipopt_zU_in = Suffix(direction=Suffix.EXPORT) model.red_hessian = Suffix(direction=Suffix.EXPORT) model.dof_v = Suffix(direction=Suffix.EXPORT) model.rh_name = Suffix(direction=Suffix.IMPORT) count_vars = 1 for k, v in model.P.items(): model.dof_v[k] = 1 count_vars += 1 model.npdp = Suffix(direction=Suffix.EXPORT) return None
def _prep_models(self): """Prepare the model suffixes for NSD algorithm. """ for model in self.models_dict.values(): model.dual = Suffix(direction=Suffix.IMPORT_EXPORT) model.ipopt_zL_out = Suffix(direction=Suffix.IMPORT) model.ipopt_zU_out = Suffix(direction=Suffix.IMPORT) model.ipopt_zL_in = Suffix(direction=Suffix.EXPORT) model.ipopt_zU_in = Suffix(direction=Suffix.EXPORT) return None
def build(self): """Callable method for Block construction.""" super().build() self.scaling_factor = Suffix(direction=Suffix.EXPORT) # Add state variables self.flow_mol_phase_comp = Var( self.params.phase_list, self.params.component_list, initialize=100, #todo: revisit bounds=(1e-8, None), domain=NonNegativeReals, units=pyunits.mol/pyunits.s, doc='Mole flow rate') self.temperature = Var( initialize=298.15, bounds=(273.15, 373.15), domain=NonNegativeReals, units=pyunits.K, doc='State temperature') self.pressure = Var( initialize=101325, bounds=(1e5, 5e7), domain=NonNegativeReals, units=pyunits.Pa, doc='State pressure')
def build(self): """Callable method for Block construction.""" super(PropStateBlockData, self).build() self.scaling_factor = Suffix(direction=Suffix.EXPORT) seawater_mass_frac_dict = { ('Liq', 'NaCl'): 2.827e-2, ('Liq', 'CaSO4'): 1.298e-3, ('Liq', 'MgSO4'): 1.529e-3, ('Liq', 'MgCl2'): 4.251e-3, ('Liq', 'H2O'): 0.9647 } # Add state variables self.flow_mass_phase_comp = Var(self.params.phase_list, self.params.component_list, initialize=seawater_mass_frac_dict, bounds=(1e-8, 100), domain=NonNegativeReals, units=pyunits.kg / pyunits.s, doc='Mass flow rate') self.temperature = Var(initialize=298.15, bounds=(273.15, 1000), domain=NonNegativeReals, units=pyunits.degK, doc='State temperature') self.pressure = Var(initialize=101325, bounds=(1e5, 5e7), domain=NonNegativeReals, units=pyunits.Pa, doc='State pressure')
def ScenarioAnalysis(ss, parameters): #Create model print('formulating scenario: ' + ss) HOM = HydroeconomicOptimization(parameters, scenario=ss) HOM.model.dual = Suffix(direction=Suffix.IMPORT) #Solve scenario print('...solving scenario ' + ss) solver = SolverFactory('cplex') #choose solver solverstatus = solver.solve(HOM.model) #Collect and export results print('...saving and exporting results of ' + ss) results = ResultAnalysis() if SAVEALL == 1: #Collect and export all results for individual scenario if parameters.val['sExportExcel'][ss] != 0: results.readresults(HOM.model, parameters, solverstatus, PRINT=0, scenario=ss) OutPath = ResultFolderPath + os.sep + ss + '.xlsx' results.exportresults(OutPath, HOM.model, NEWSHEET=1) if parameters.val['sExportPython'][ss] != 0: Result = ResultFolderPath + os.sep + ss + '.txt' pickle.dump(results, open(Result, "wb")) #Save selected results for scenario analysis results.selectedresults(HOM.model, parameters, scenario=ss) output = { 'EconomicBalance': results.EconomicBalance, 'EconomicBalance_co': results.EconomicBalance_co, 'WaterEconomicBalance_co': results.WaterEconomicBalance_co, 'EnergyEconomicBalance_co': results.EnergyEconomicBalance_co, 'AgricultureEconomicBalance_co': results.AgricultureEconomicBalance_co, 'AgricultureEconomicBalance2_co': results.AgricultureEconomicBalance2_co, 'HydropowerProduction_co': results.HydropowerProd_co, 'GrossCultivatedArea_co': results.GrossCulArea_co, 'NetIrrArea_co': results.NetIrrArea_co, 'IrrigNetCons_co': results.IrrigNetCons_co, 'EnergyValue_co': results.EnergyValue_co, 'CropValue_co': results.CropValue_co, 'OtherIndicators': results.OtherIndicators } if HOM.model.Options['Energy market'] == 1: output['EnergyExportBenefit_co'] = results.EnergyExportBenefit_co output['EnergyExports_co'] = results.EnergyExports_co output['EnergyCapacityConst_co'] = results.EnergyCapacityConst_co output['SolarCapacityConst_co'] = results.SolarCapacityConst_co output['CO2Emission_co'] = results.CO2Emission_co output['CropExpBenefit_co'] = results.CropExpBenefit_co output['EnergyConsSurplus_co'] = results.EgyConsSurplus_co output['EnergyProdSurplus_co'] = results.EgyProdSurplus_co if HOM.model.Options['Crop market'] == 1: output['AgricultureConsSurplus_co'] = results.AgrConsSurplus_co output['AgricultureProdSurplus_co'] = results.AgrProdSurplus_co return output
def main(): m = build_column(min_trays=8, max_trays=17, xD=0.95, xB=0.95) # Fix feed conditions m.feed['benzene'].fix(50) m.feed['toluene'].fix(50) m.T_feed.fix(368) m.feed_vap_frac.fix(0.40395) # Initial values of reflux and reboil ratios m.reflux_ratio.set_value(1.4) m.reboil_ratio.set_value(1.3) # Fix to be total condenser m.partial_cond.deactivate() m.total_cond.indicator_var.fix(1) # Give initial values of the tray existence/absence for t in m.conditional_trays: m.tray[t].indicator_var.set_value(1) m.no_tray[t].indicator_var.set_value(0) # Run custom initialization routine initialize(m) m.BigM = Suffix(direction=Suffix.LOCAL) m.BigM[None] = 100 SolverFactory('gdpopt').solve(m, tee=True, init_strategy='fix_disjuncts', mip_solver='glpk') log_infeasible_constraints(m, tol=1E-3) display_column(m) return m
def test_invalid_suffix(self): m = ConcreteModel() m.x = Var(within=Binary) m.y = Var([1, 2, 3], within=Binary) m.c = Constraint(expr=m.y[1] * m.y[2] - 2 * m.x >= 0) m.obj = Objective(expr=m.y[1] + m.y[2], sense=maximize) m.priorities = Suffix(direction=Suffix.EXPORT) m.priorities[m.x] = 1 m.priorities[m.y] = 2 with self.assertRaisesRegex( ValueError, "The BARON writer can not export suffix " "with name 'priorities'. Either remove it from " "the model or deactivate it."): m.write(StringIO(), format='bar') m._name = 'TestModel' with self.assertRaisesRegex( ValueError, "The BARON writer can not export suffix " "with name 'priorities'. Either remove it from " "the model 'TestModel' or deactivate it."): m.write(StringIO(), format='bar') p = m.priorities del m.priorities m.blk = Block() m.blk.sub = Block() m.blk.sub.priorities = p with self.assertRaisesRegex( ValueError, "The BARON writer can not export suffix " "with name 'priorities'. Either remove it from " "the block 'blk.sub' or deactivate it."): m.write(StringIO(), format='bar')
def _model_preparation(self): """Helper function that should prepare the models when called from the main function. Includes the experimental data, sets the objectives, simulates to warm start the models if no data is provided, sets up the reduced hessian model with "fake data", and discretizes all models :return: None """ if not hasattr(self.model, 'objective'): self.model.objective = self._rule_objective(self.model) # The model needs to be discretized model_pe = ParameterEstimator(self.model) model_pe.apply_discretization('dae.collocation', ncp=self.ncp, nfe=self.nfe, scheme='LAGRANGE-RADAU') # Here is where the parameters are scaled if self.scaled: scale_parameters(self.model) set_scaled_parameter_bounds(self.model, rho=self.rho) else: check_initial_parameter_values(self.model) if self.use_duals: self.model.dual = Suffix(direction=Suffix.IMPORT_EXPORT) return None
def build(self): """Callable method for Block construction.""" super(NaClStateBlockData, self).build() self.scaling_factor = Suffix(direction=Suffix.EXPORT) # Add state variables self.flow_mass_phase_comp = Var(self.params.phase_list, self.params.component_list, initialize=1, bounds=(1e-8, None), domain=NonNegativeReals, units=pyunits.kg / pyunits.s, doc='Mass flow rate') self.temperature = Var(initialize=298.15, bounds=(273.15, 1000), domain=NonNegativeReals, units=pyunits.degK, doc='State temperature') self.pressure = Var(initialize=101325, bounds=(1e5, 5e7), domain=NonNegativeReals, units=pyunits.Pa, doc='State pressure')
def index_variable_mapping(model_dict, components, parameter_names, mee_obj=None): """This adds the needed suffixes for the reduced hessian to the model object used in covariance predictions :param ConcreteModel model_dict: The model from the parameter estimator or the MEE :param list components: The list of absorbing components :param list parameter_names: The list of parameter names :param mee_obj: An MEE instance, default None :return: index_to_variables :rtype: dict """ if mee_obj is not None: model_obj = mee_obj else: model_obj = model_dict model_obj.red_hessian = Suffix(direction=Suffix.IMPORT_EXPORT) index_to_variables = define_reduce_hess_order(model_dict, components, parameter_names) for k, v in index_to_variables.items(): model_obj.red_hessian[v] = k return index_to_variables
def define_components(model): model.carbon_cap_tco2_per_yr = Param( model.PERIODS, default=float('inf'), doc=("Emissions from this model must be less than this cap. " "This is specified in metric tonnes of CO2 per year.")) model.Enforce_Carbon_Cap = Constraint( model.PERIODS, rule=lambda m, p: m.AnnualEmissions[p] <= m.carbon_cap_tco2_per_yr[p], doc=("Enforces the carbon cap for generation-related emissions.")) # Make sure the model has a dual suffix for determining implicit carbon costs if not hasattr(model, "dual"): model.dual = Suffix(direction=Suffix.IMPORT) model.carbon_cost_dollar_per_tco2 = Param( model.PERIODS, default=0.0, doc= "The cost adder applied to emissions, in future dollars per metric tonne of CO2." ) model.EmissionsCosts = Expression(model.PERIODS, rule=lambda model, period: \ model.AnnualEmissions[period] * model.carbon_cost_dollar_per_tco2[period], doc=("Enforces the carbon cap for generation-related emissions.")) model.Cost_Components_Per_Period.append('EmissionsCosts')
def _model_preparation(self, scaled=True, use_duals=True): """Helper function that should prepare the models when called from the main function. Includes the experimental data, sets the objectives, simulates to warm start the models if no data is provided, sets up the reduced hessian model with "fake data", and discretizes all models """ for model in self.model_list: if not hasattr(model, 'objective'): model.objective = self._rule_objective(model) # The model needs to be discretized model_pe = ParameterEstimator(model) model_pe.apply_discretization( 'dae.collocation', ncp=3, #self.ncp, nfe=50, #self.nfe, scheme='LAGRANGE-RADAU') # Here is where the parameters are scaled #if scaled: # scale_parameters(model) # set_scaled_parameter_bounds(model, rho=10) #self.rho) #else: #check_initial_parameter_values(model) if use_duals: model.dual = Suffix(direction=Suffix.IMPORT_EXPORT) model.ipopt_zL_out = Suffix(direction=Suffix.IMPORT) model.ipopt_zU_out = Suffix(direction=Suffix.IMPORT) model.ipopt_zL_in = Suffix(direction=Suffix.EXPORT) model.ipopt_zU_in = Suffix(direction=Suffix.EXPORT) # model.red_hessian = Suffix(direction=Suffix.EXPORT) # model.dof_v = Suffix(direction=Suffix.EXPORT) # model.rh_name = Suffix(direction=Suffix.IMPORT) # count_vars = 1 # for k, v in model.P.items(): # model.dof_v[k] = count_vars # count_vars += 1 # model.npdp = Suffix(direction=Suffix.EXPORT) return None
def _generateModel(): model = ConcreteModel() model.x = Var(within=Binary) model.y = Var() model.c1 = Constraint(expr=model.y >= model.x) model.c2 = Constraint(expr=model.y >= 1.5 - model.x) model.obj = Objective(expr=model.y) model.dual = Suffix(direction=Suffix.IMPORT_EXPORT) return model
def _add_sensitivity_suffixes(block): suffix_dict = {} suffix_dict.update(_SIPOPT_SUFFIXES) suffix_dict.update(_K_AUG_SUFFIXES) for name, direction in suffix_dict.items(): if block.component(name) is None: # Only add suffix if it doesn't already exist. # If something of this name does already exist, just # assume it is the proper suffix and move on. block.add_component(name, Suffix(direction=direction))
def create_objective(self): # @@ Objective # Minimise capital, variable and fixed costs of system self.m.FSCost = Expression(expr=0) self.m.SSCost = Expression(rule=obj_cost) # objective: minimise all other objectives self.m.Obj = Objective(expr=self.m.FSCost + self.m.SSCost) # Short run marginal prices self.m.dual = Suffix(direction=Suffix.IMPORT)
def build(self): """Callable method for Block construction.""" super(CoagulationStateBlockData, self).build() self.scaling_factor = Suffix(direction=Suffix.EXPORT) # first we create the state variables # note: the following dictionaries are used for providing initial values # to state variables and on-demand variables self.seawater_mass_frac_dict = { ("Liq", "TSS"): 0.01, ("Liq", "H2O"): 1, ("Liq", "TDS"): 0.01, ("Liq", "Sludge"): 0.001, } self.seawater_mass_flow_dict = { ("Liq", "TSS"): 0.01, ("Liq", "H2O"): 1, ("Liq", "TDS"): 0.01, ("Liq", "Sludge"): 0.001, } self.seawater_mass_conc_dict = { ("Liq", "TSS"): 0.01 * 1000, ("Liq", "H2O"): 1 * 1000, ("Liq", "TDS"): 0.01 * 1000, ("Liq", "Sludge"): 0.001 * 1000, } self.flow_mass_phase_comp = Var( self.seawater_mass_frac_dict.keys(), initialize=self.seawater_mass_flow_dict, bounds=(1e-16, None), domain=NonNegativeReals, units=pyunits.kg / pyunits.s, doc="Mass flow rate", ) self.temperature = Var( initialize=298.15, bounds=(273.15, 700), domain=NonNegativeReals, units=pyunits.degK, doc="State temperature", ) self.pressure = Var( initialize=101325, bounds=(0.9e5, 3e7), domain=NonNegativeReals, units=pyunits.Pa, doc="State pressure", )
def test_getattr1(self): """ Verify the behavior of non-standard suffixes with simple variable """ model = AbstractModel() model.a = Var() model.suffix = Suffix(datatype=Suffix.INT) instance = model.create_instance() self.assertEqual(instance.suffix.get(instance.a), None) instance.suffix.set_value(instance.a, True) self.assertEqual(instance.suffix.get(instance.a), True)
def test_branching_priorities(self): m = ConcreteModel() m.x = Var(within=Binary) m.y = Var([1, 2, 3], within=Binary) m.c = Constraint(expr=m.y[1] * m.y[2] - 2 * m.x >= 0) m.obj = Objective(expr=m.y[1] + m.y[2], sense=maximize) m.priority = Suffix(direction=Suffix.EXPORT) m.priority[m.x] = 1 # Note this checks that y[3] is filtered out m.priority[m.y] = 2 self._check_baseline(m)
def test_expected_two_segment_cut_inf_norm(self): m = models.twoSegments_SawayaGrossmann() # make sure this is fine if dual Suffix is already on model m.dual = Suffix(direction=Suffix.IMPORT) # have to make M big for the bigm relaxation to be the box 0 <= x <= 3, # 0 <= Y <= 1 (in the limit) TransformationFactory('gdp.cuttingplane').apply_to( m, bigM=1e6, norm=float('inf'), post_process_cut=None) self.check_expected_two_segment_cut(m)
def build(self): super().build() # this creates blank scaling factors, which are populated later self.scaling_factor = Suffix(direction=Suffix.EXPORT) # Next, get the base units of measurement from the property definition units_meta = self.config.property_package.get_metadata( ).get_derived_units # Add control volume self.control_volume = ControlVolume0DBlock( default={ "dynamic": False, "has_holdup": False, "property_package": self.config.property_package, "property_package_args": self.config.property_package_args, }) self.control_volume.add_state_blocks(has_phase_equilibrium=False) # complete condensation mass balance @self.control_volume.Constraint( self.flowsheet().time, self.config.property_package.component_list, doc="Mass balance", ) def mass_balance(b, t, j): lb = b.properties_out[t].get_material_flow_terms("Vap", j).lb b.properties_out[t].get_material_flow_terms("Vap", j).fix(lb) return b.properties_in[t].get_material_flow_terms( "Vap", j) + b.properties_in[t].get_material_flow_terms( "Liq", j) == b.properties_out[t].get_material_flow_terms( "Liq", j) self.control_volume.add_energy_balances( balance_type=self.config.energy_balance_type, has_heat_transfer=True) self.control_volume.add_momentum_balances( balance_type=self.config.momentum_balance_type) # # Add constraints @self.Constraint(self.flowsheet().time, doc="Saturation pressure constraint") def eq_condenser_pressure_sat(b, t): return (b.control_volume.properties_out[t].pressure >= b.control_volume.properties_out[t].pressure_sat) # Add ports self.add_port(name="inlet", block=self.control_volume.properties_in) self.add_port(name="outlet", block=self.control_volume.properties_out)
def initialize_model(m, nfe): u_profile = {0: -0.06} m.u_input = Suffix(direction=Suffix.LOCAL) m.u_input[m.u] = u_profile sim = Simulator(m, package='scipy') tsim, profiles = sim.simulate(numpoints=100, varying_inputs=m.u_input) discretizer = TransformationFactory('dae.collocation') discretizer.apply_to(m, nfe=nfe, ncp=1, scheme='LAGRANGE-RADAU') sim.initialize_model()
def add_ipopt_suffixes(self): """ Adds suffixes for communicating dual variables with IPOPT """ # Maybe there should be some helper class to do solver-specific # stuff like this... self.ipopt_zL_out = Suffix(direction=Suffix.IMPORT) self.ipopt_zU_out = Suffix(direction=Suffix.IMPORT) self.ipopt_zL_in = Suffix(direction=Suffix.EXPORT) self.ipopt_zU_in = Suffix(direction=Suffix.EXPORT) self.dual = Suffix(direction=Suffix.IMPORT_EXPORT)
def down_linker(b, c, d, j): # print("In down linker") m = b.model() ems_power_in_j = sum(m.power[d, j] for d in m.d) ems_power_deviation = ems_power_in_j - m.commitment_quantity[c, j] # try: # print(value(ems_power_deviation)) # except: # pass b.linker = Constraint(expr=m.price[c, j] == m.down_price[c, j]) b.constr = Constraint(expr=ems_power_deviation <= 0) b.BigM = Suffix(direction=Suffix.LOCAL) b.BigM[b.linker] = 10e5 return
def initialize_model(m, n_sim, n_nfe, n_ncp): vp_profile = {0: 0.75} vt_profile = {0: 0.75} m.u_input = Suffix(direction=Suffix.LOCAL) m.u_input[m.vp] = vp_profile m.u_input[m.vt] = vt_profile sim = Simulator(m, package='scipy') tsim, profiles = sim.simulate(numpoints=n_sim, varying_inputs=m.u_input) discretizer = TransformationFactory('dae.collocation') discretizer.apply_to(m, nfe=n_nfe, ncp=n_ncp, scheme='LAGRANGE-RADAU') sim.initialize_model()
def test_rc_signs(self): m = ConcreteModel() m.x = Var(bounds=(-1, 1)) m.obj = Objective(expr=m.x) m.rc = Suffix(direction=Suffix.IMPORT) opt = SolverFactory('cbc') res = opt.solve(m) self.assertAlmostEqual(res.problem.lower_bound, -1) self.assertAlmostEqual(res.problem.upper_bound, -1) self.assertAlmostEqual(m.rc[m.x], 1) m.obj.sense = maximize res = opt.solve(m) self.assertAlmostEqual(res.problem.lower_bound, 1) self.assertAlmostEqual(res.problem.upper_bound, 1) self.assertAlmostEqual(m.rc[m.x], 1)
def test_getattr2(self): """ Verify the behavior of non-standard suffixes with an array of variables """ model = AbstractModel() model.X = Set(initialize=[1, 3, 5]) model.a = Var(model.X) model.suffix = Suffix(datatype=Suffix.INT) try: self.assertEqual(model.a.suffix, None) self.fail("Expected AttributeError") except AttributeError: pass instance = model.create_instance() self.assertEqual(instance.suffix.get(instance.a[1]), None) instance.suffix.set_value(instance.a[1], True) self.assertEqual(instance.suffix.get(instance.a[1]), True)
def test_assert_units_consistent_all_components(self): # test all scalar components consistent u = units m = self._create_model_and_vars() m.obj = Objective(expr=m.dx / m.t - m.vx) m.con = Constraint(expr=m.dx / m.t == m.vx) # vars already added m.exp = Expression(expr=m.dx / m.t - m.vx) m.suff = Suffix(direction=Suffix.LOCAL) # params already added # sets already added m.rs = RangeSet(5) m.disj1 = Disjunct() m.disj1.constraint = Constraint(expr=m.dx / m.t <= m.vx) m.disj2 = Disjunct() m.disj2.constraint = Constraint(expr=m.dx / m.t <= m.vx) m.disjn = Disjunction(expr=[m.disj1, m.disj2]) # block tested as part of model m.extfn = ExternalFunction(python_callback_function, units=u.m / u.s, arg_units=[u.m, u.s]) m.conext = Constraint(expr=m.extfn(m.dx, m.t) - m.vx == 0) m.cset = ContinuousSet(bounds=(0, 1)) m.svar = Var(m.cset, units=u.m) m.dvar = DerivativeVar(sVar=m.svar, units=u.m / u.s) def prt1_rule(m): return {'avar': m.dx} def prt2_rule(m): return {'avar': m.dy} m.prt1 = Port(rule=prt1_rule) m.prt2 = Port(rule=prt2_rule) def arcrule(m): return dict(source=m.prt1, destination=m.prt2) m.arc = Arc(rule=arcrule) # complementarities do not work yet # The expression system removes the u.m since it is multiplied by zero. # We need to change the units_container to allow 0 when comparing units # m.compl = Complementarity(expr=complements(m.dx/m.t >= m.vx, m.dx == 0*u.m)) assert_units_consistent(m)
def test_update_contset_indexed_component_other(self): m = ConcreteModel() m.t = ContinuousSet(bounds=(0, 10)) m.junk = Suffix() m.s = Set(initialize=[1, 2, 3]) m.v = Var(m.s) def _obj(m): return sum(m.v[i] for i in m.s) m.obj = Objective(rule=_obj) expansion_map = ComponentMap generate_finite_elements(m.t, 5) update_contset_indexed_component(m.junk, expansion_map) update_contset_indexed_component(m.s, expansion_map) update_contset_indexed_component(m.obj, expansion_map)
def run_scenario(self, solver_name="cplex", executable=""): """ runs the input model scenario Keyword Arguments: solver_name {str} -- name of your solver (default: {'cplex'}) executable {str} -- path of your CPLEX. Default assumes solver on your path (default: {""}) """ self.executable = executable self.solver_name = solver_name if self.load_init: self.scenario_createinputs_directory = os.path.join( self.dir_str.INIT_DIRECTORY) else: self.scenario_createinputs_directory = None # Write logs to this directory TempfileManager.tempdir = self.scenario_logs_directory # Create problem instance self.instance = self.create_problem_instance() # Create a 'dual' suffix component on the instance, so the solver plugin will know which suffixes to collect self.instance.dual = Suffix(direction=Suffix.IMPORT) if self.is_MPEC: self.solution_type = "MIP" self.solution = self.solve(self.solution_type) else: self.solution_type = "LP" self.solution = self.solve( self.solution_type ) # solve LP, storage dispatch now linearized # self.instance.storagebool.fix() # relaxes to lp after mip solve if needed # self.solution = self.solve(self.solution_type) # export results to csvs write_results_competitive.export_results( self.instance, self.solution, self.scenario_results_directory, self.is_MPEC, debug_mode=1, )