Skip to content

Optimizer

Ricky Concepcion edited this page Apr 17, 2020 · 1 revision

Optimizer

Optimizer models are those derived from an abstract base class, Optimizer. This blueprint lays out a skeleton for creating derived classes that describe more specific optimization problems. Additionally, the Optimizer base class passes common functionality to its derived classes via inheritance. The end result is the Optimizer family of Python classes that abstract away the details of optimization modeling in Pyomo while providing well-defined interfaces for users to interact with the encapsulated models.

Overview

Generally, a family of optimization models based on this design pattern consist of:

  • A class derived from the Optimizer base class
  • An ExpressionsBlock class that composes its companion Optimizer-derived class

The Optimizer-derived class can generally handle the composition process; the existence of a discrete ExpressionsBlock class is for separating objective function and constraint logic.

Usage of an Optimizer-derived class for optimization modeling is as follows:

  1. Create an instance of the class.
  2. Populate it with data and parameters via exposed interfaces.
  3. Solve the resulting model with a simple run() command.
  4. Obtain results from the instance using appropriate interfaces.

Example: BtmOptimizer

This is an example of how the BtmOptimizer class is used in the QuESt BTM time-of-use cost savings wizard.

from es_gui.tools.btm.btm_optimizer import BtmOptimizer

op = BtmOptimizer()
op.tou_energy_schedule = tou_energy_schedule
op.tou_demand_schedule = tou_demand_schedule
op.load_profile = load_profileparams = {‘Power_rating’: 100, ‘Energy_capacity’: 400}
op.set_model_parameters(**params)
op.run()
op.results.to_csv(‘results.csv’)
  1. The class definition is imported.
  2. An instance of the class is created and input data and parameters are assigned to the instance using the appropriate interfaces.
    • In this case, data is assigned directly to attributes of the instance.
    • It is also possible to provide data to the instance constructor.
  3. A run() method is invoked to solve the optimization problem.
  4. The results attribute is accessed, which returns a Pandas DataFrame. The to_csv() method of that object is used to export the DataFrame to a .csv file.

Optimizer structure

The Optimizer is an abstract base class. The abstract characterization is enforced using the abc Python module by giving the class the abstract base class metaclass.

Concrete attributes

These attributes are passed along to derived classes via inheritance and are not required (nor recommended) to be overridden.

  • Constructor
  • Pyomo ConcreteModel
  • Solver name
  • A method to solve the model
  • A method to run the model (returns results directly)
  • A method to set model parameters directly on the Pyomo ConcreteModel
  • A method to reprocess results (e.g., for recomputing objective function with different parameters)

Abstract attributes

  • A method for defining and assigning model parameters
  • A method for defining decision variables
  • A method for instantiating the Pyomo ConcreteModel
  • A method for populating the Pyomo ConcreteModel
  • A method for processing the results after optimization
  • A method for returning the results

These attributes must be overridden by derived class due to the @abstractmethod decorator. Essentially, they are the necessary components to fill in the optimization framework defined by the Optimizer class.

Example implementation: BtmOptimizer

Here is an example of how the BtmOptimizer class overrides the abstract methods of the Optimizer base class. It fills in the methods with the logic specific to the optimization model(s) that is describing.

  • _set_model_param()
    • Check if model parameters defined; if not, assign default values.
      • Power_rating, State_of_charge_init, etc.
    • Compute functional min and max state of charge
  • _set_model_var()
    • Define, initialize, and bound decision variables.
      • State of charge
      • Charge & discharge power at each time step
      • Peak demand for month and for each period
  • instantiate_model()
    • Compute the number of time steps, TOU demand periods, net power each time step
  • populate_model()
    • Initialize objective function value, call _set_model_param() and _set_model_var()
    • Assign ExpressionsBlock object containing objective function and constraint definitions
  • _process_results()
    • Compute demand/energy/NEM charges with and without energy storage
    • Arrange solution time series into a DataFrame
    • Assign demand/energy/NEM charges to BtmOptimizer properties for access

Clone this wiki locally