def _apply_solver(self): if not self._save_results: for block in self._pyomo_model.block_data_objects( descend_into=True, active=True): for var in block.component_data_objects( ctype=pyomo.core.base.var.Var, descend_into=False, active=True, sort=False): var.stale = True if self._tee: self._solver_model.setParam('OutputFlag', 1) else: self._solver_model.setParam('OutputFlag', 0) self._solver_model.setParam('LogFile', self._log_file) if self._keepfiles: print("Solver log file: " + self._log_file) # Options accepted by gurobi (case insensitive): # ['Cutoff', 'IterationLimit', 'NodeLimit', 'SolutionLimit', 'TimeLimit', # 'FeasibilityTol', 'IntFeasTol', 'MarkowitzTol', 'MIPGap', 'MIPGapAbs', # 'OptimalityTol', 'PSDTol', 'Method', 'PerturbValue', 'ObjScale', 'ScaleFlag', # 'SimplexPricing', 'Quad', 'NormAdjust', 'BarIterLimit', 'BarConvTol', # 'BarCorrectors', 'BarOrder', 'Crossover', 'CrossoverBasis', 'BranchDir', # 'Heuristics', 'MinRelNodes', 'MIPFocus', 'NodefileStart', 'NodefileDir', # 'NodeMethod', 'PumpPasses', 'RINS', 'SolutionNumber', 'SubMIPNodes', 'Symmetry', # 'VarBranch', 'Cuts', 'CutPasses', 'CliqueCuts', 'CoverCuts', 'CutAggPasses', # 'FlowCoverCuts', 'FlowPathCuts', 'GomoryPasses', 'GUBCoverCuts', 'ImpliedCuts', # 'MIPSepCuts', 'MIRCuts', 'NetworkCuts', 'SubMIPCuts', 'ZeroHalfCuts', 'ModKCuts', # 'Aggregate', 'AggFill', 'PreDual', 'DisplayInterval', 'IISMethod', 'InfUnbdInfo', # 'LogFile', 'PreCrush', 'PreDepRow', 'PreMIQPMethod', 'PrePasses', 'Presolve', # 'ResultFile', 'ImproveStartTime', 'ImproveStartGap', 'Threads', 'Dummy', 'OutputFlag'] for key, option in self.options.items(): self._solver_model.setParam(key, option) if self._version_major >= 5: for suffix in self._suffixes: if re.match(suffix, "dual"): self._solver_model.setParam( self._gurobipy.GRB.Param.QCPDual, 1) self._solver_model.optimize() self._solver_model.setParam('LogFile', 'default') # FIXME: can we get a return code indicating if Gurobi had a significant failure? return Bunch(rc=None, log=None)