Source code for pyomo.scripting.plugins.solve

#  ___________________________________________________________________________
#
#  Pyomo: Python Optimization Modeling Objects
#  Copyright (c) 2008-2024
#  National Technology and Engineering Solutions of Sandia, LLC
#  Under the terms of Contract DE-NA0003525 with National Technology and
#  Engineering Solutions of Sandia, LLC, the U.S. Government retains certain
#  rights in this software.
#  This software is distributed under the 3-clause BSD License.
#  ___________________________________________________________________________

import json
import sys
import argparse

from pyomo.opt import SolverFactory, UnknownSolver
from pyomo.scripting.pyomo_parser import add_subparser, CustomHelpFormatter


[docs] def create_parser(parser=None): # # Setup command-line options. The '--solver' option creates # all subsequent options... # if parser is None: parser = argparse.ArgumentParser( usage='%(prog)s [options] <model_or_config_file> [<data_files>]' ) parser.add_argument('--solver', action='store', dest='solver', default=None) parser.add_argument( '--solver-manager', action='store', dest='solver_manager', default='serial' ) parser.add_argument( '--generate-config-template', action='store', dest='template', default=None ) return parser
[docs] def create_temporary_parser(solver=False, generate=False): # # We create a dummy parser and subparser, to help make the 'help' # output seem sensible. # parser = argparse.ArgumentParser(formatter_class=CustomHelpFormatter) _subparsers = parser.add_subparsers() _parser = _subparsers.add_parser('solve') _parser.formatter_class = CustomHelpFormatter if generate: # # Adding documentation about the two options that are # defined in the initial parser. # _parser.add_argument( '--generate-config-template', action='store', dest='template', default=None, help='Create a configuration template file in YAML or JSON and exit.', ) if solver: _parser.add_argument( '--solver', action='store', dest='solver', default=None, help='Solver name. This option is required unless the solver name is' 'specified in a configuration file.', ) _parser.usage = '%(prog)s [options] <model_or_config_file> [<data_files>]' _parser.epilog = """ Description: The 'pyomo solve' subcommand optimizes a Pyomo model. The --solver option is required because the specific steps executed are solver dependent. The standard steps executed by this subcommand are: - Apply pre-solve operations (e.g. import Python packages) - Create the model - Apply model transformations - Perform optimization - Apply post-solve operations (e.g. save optimal solutions) This subcommand can be executed with or without a configuration file. The command-line options can be used to perform simple optimization steps. For example: pyomo solve --solver=glpk model.py model.dat This uses the 'glpk' solver to optimize the model define in 'model.py' using the Pyomo data file 'pyomo.dat'. Solver-specific command-line options can be listed by specifying the '--solver' option and the '--help' (or '-h') option: pyomo solve --solver=glpk --help A yaml or json configuration file can also be used to specify options used by the solver. For example: pyomo solve --solver=glpk config.yaml No other command-line options are required! Further, the '--solver' option can be omitted if the solver name is specified in the configuration file. Configuration options are also solver-specific; a template configuration file can be generated with the '--generate-config-template' option: pyomo solve --solver=glpk --generate-config-template=template.yaml pyomo solve --solver=glpk --generate-config-template=template.json Note that yaml template files contain comments that describe the configuration options. Also, configuration files will generally support more configuration options than are available with command-line options. """ # _parser.add_argument( 'model_or_config_file', action='store', nargs='?', default='', help="A Python module that defines a Pyomo model, or a configuration file " "that defines options for 'pyomo solve' (in either YAML or JSON format)", ) _parser.add_argument( 'data_files', action='store', nargs='*', default=[], help='Pyomo data files that defined data used to initialize the model ' '(specified in the first argument)', ) # return _parser
[docs] def solve_exec(args, unparsed): import pyomo.scripting.util # solver_manager = getattr(args, 'solver_manager', None) solver = getattr(args, 'solver', None) # if solver is None: # # Get configuration values if no solver has been specified # try: val = pyomo.scripting.util.get_config_values(unparsed[-1]) except IndexError: val = None except IOError: val = None # # Try to get the solver name # if not val is None: try: solver = val['solvers'][0]['solver name'] except: solver = None # # If no luck, then generate an error # if solver is None: if not ('-h' in unparsed or '--help' in unparsed): print("ERROR: No solver specified!") print("") parser = create_temporary_parser(solver=True, generate=True) parser.parse_args(args=unparsed + ['-h']) sys.exit(1) config = None _solver = solver if solver_manager == 'serial' else 'asl' with SolverFactory(_solver) as opt: if opt is None or isinstance(opt, UnknownSolver): print("ERROR: Unknown solver '%s'!" % solver) sys.exit(1) # # Generate a template file # if not args.template is None: config = opt.config_block(init=True) OUTPUT = open(args.template, 'w') if args.template.endswith('json'): OUTPUT.write(json.dumps(config.value(), indent=2)) else: OUTPUT.write(config.generate_yaml_template()) OUTPUT.close() print(" Created template file '%s'" % args.template) sys.exit(0) # # Parse previously unparsed options # config = opt.config_block() if '-h' in unparsed or '--help' in unparsed: _parser = create_temporary_parser(generate=True) else: _parser = create_temporary_parser() config.initialize_argparse(_parser) _parser.usage = '%(prog)s [options] <model_or_config_file> [<data_files>]' _options = _parser.parse_args(args=unparsed) # # Import the parsed values into the config block, then # create an Options object # config.import_argparse(_options) config.solvers[0].solver_name = getattr(args, 'solver', None) if _options.model_or_config_file.endswith('.py'): config.model.filename = _options.model_or_config_file config.data.files = _options.data_files else: val = pyomo.scripting.util.get_config_values(_options.model_or_config_file) config.set_value(val) if config is None: raise RuntimeError("Failed to create config object") config.solvers[0].solver_name = solver config.solvers[0].manager = solver_manager from pyomo.scripting.pyomo_command import run_pyomo # # Note that we pass-in pre-parsed options. The run_command() # function knows to not perform a parse, but instead to simply # used these parsed values. # return pyomo.scripting.util.run_command( command=run_pyomo, parser=_parser, options=config, name='pyomo solve' )
# # Add a subparser for the solve command # solve_parser = create_parser( add_subparser( 'solve', func=solve_exec, help='Optimize a model', add_help=False, description='This pyomo subcommand is used to analyze optimization models.', ) )