Nonlinear Model Predictive Control¶
Nonlinear Model Predictive Control (NMPC) is control strategy in which control inputs are determined by the solution of an optimization problem every time the plant is sampled.
An explanation of the optimization problem solved in this implementation of NMPC is forthcoming.
Class for performing NMPC simulations of IDAES flowsheets
NMPCSim(plant_model=None, plant_time_set=None, controller_model=None, controller_time_set=None, inputs_at_t0=None, sample_time=None, **kwargs)¶
Main class for NMPC simulations of Pyomo models.
Adds the _NMPC_NAMESPACE block a model with a given time set. All necessary model-specific attributes, including constraints and objectives, will be added to this block.
- model – Model to which to add the namespace
- time – Set to treat as time in the given model
add_objective_function(model, name='objective', state_weight=1, control_weight=1, **kwargs)¶
Adds an objective function based on already calculated weights and setpoint values to the _NMPC_NAMESPACE of a model.
- model – Model to which to add objective function
- name – Name of objective function to add
- state_weight – Additional weight factor to apply to each state term in the objective function. Intended for a user that wants to weigh states and controls differently
- control_weight – Addtional weight factor to apply to each control term in the objective function. Intended for a user that wants to weigh states and controls differently
User-facing function for the addition of a setpoint to the controller. Assumes the controller model’s setpoint attributes have been populated with desired values. This function first calculates weights, then adds an objective function based on those weights and existing setpoint values.
Parameters: objective_name – Name to use for the objective function added
calculate_error_between_states(mod1, mod2, t1, t2, Q_matrix=, categories=[<VariableCategory.DIFFERENTIAL: 51>], **kwargs)¶
Calculates the normalized (by the weighting matrix already calculated) error between the differential variables in different models and at different points in time.
- mod1 – First flowsheet model
- mod2 – Second flowsheet model (may be same as the first)
- t1 – Time point of interest in first model
- t2 – Time point of interest in second model
- Q_matrix – List of weights by which to weigh the error for each state. Default is to use the same weights calculated for the controller objective function.
calculate_full_state_setpoint(setpoint, require_steady=True, **kwargs)¶
Given a user-defined setpoint, i.e. a list of VarData, value tuples, calculates a full-state setpoint to be used in the objective function of the dynamic optimization problem. This is done by solving a single- time point optimization problem with the user’s setpoint in the objective function.
The solve is performed in the first time point blocks/constraints of the controller model. The procedure is:
- Populate controller setpoint attributes with user-defined values
- Record which constraints were originally active
- Deactivate constraints except at time.first()
- Check for consistent initial conditions. Attempt to solve for constraint satisfaction if necessary
- Populate reference attributes with (now consistent) initial conditions
- Calculate objective weights for values provided by user
- Add objective function based on these weights and setpoint values
- Unfix initial conditions and fix inputs (and derivatives if steady-state is required)
- Solve “projected” optimization problem
- Refix initial conditions (unfix derivatives if they were fixed)
- Deactivate just-created objective
- Transfer variable values to setpoint attributes
- Reactivate model at non-initial time
- setpoint – List of VarData, value tuples to be used in the objective function of the single-time point optimization problem
- require_steady – Bool telling whether or not to fix derivatives to zero when performing optimization
Function to add piecewise constant (PWC) constraints to controller model. Requires model’s _NMPC_NAMESPACE to know about input vars and to have as an attribute a sample points list.
construct_objective_weights(model, categories=[<VariableCategory.DIFFERENTIAL: 51>, <VariableCategory.ALGEBRAIC: 52>, <VariableCategory.DERIVATIVE: 53>, <VariableCategory.INPUT: 54>], **kwargs)¶
Constructs the objective weight values for the specified variable categories of a specified model. Weights are calculated for each variable in each group by taking the difference between the initial value and the setpoint value, making sure it is above a tolerance, and taking its reciprocal. Weights can be overridden by a list of VarData, value tuples passed in as the “objective_weight_override” config argument.
- model – Model whose variables will be accessed to calculate weights, and whose weight attributes will be set.
- categories – List of VariableCategory enum items for which to calculate weights. Default is DIFFERENTIAL, ALGEBRAIC, DERIVATIVE, and INPUT
get_inconsistent_initial_conditions(model, time, tol=1e-06, **kwargs)¶
Finds equations of a model at the first time point (or in a block that is at the first time point) that are not satisfied to within a tolerance.
- model – Pyomo model (or Block) to check for inconsistency
- time – Set to treat as time
- tol – Tolerance within which a constraint will be considered consistent
List of constraint data objects found to be inconsistent
initialize_by_solving_elements(model, time, input_type=<ElementInitializationInputOption.SET_POINT: 21>, objective_name='tracking_objective', **kwargs)¶
Initializes the controller model by solving (a square simulation for) each time element.
- model – Model to initialize
- time – Set to treat as time
- input_type – ElementInitializationInputOption enum item telling how to fix the inputs for the simulation
Function to initialize the controller model before solving the optimal control problem. Possible strategies are to use the initial conditions, to perform a simulation, or to use the results of the previous solve. Initialization from a previous (optimization) solve can only be done if an optimization solve has been performed since the last initialization. The strategy may be passed in as the control_init_option keyword (config) argument, otherwise the default will be used.
initialize_from_initial_conditions(model, categories=[<VariableCategory.DERIVATIVE: 53>, <VariableCategory.DIFFERENTIAL: 51>, <VariableCategory.ALGEBRAIC: 52>], **kwargs)¶
Set values of differential, algebraic, and derivative variables to their values at the initial conditions. An implicit assumption here is that the initial conditions are consistent.
- model – Flowsheet model whose variables are initialized
- categories – List of VariableCategory enum items to initialize. Default contains DERIVATIVE, DIFFERENTIAL, and ALGEBRAIC.
initialize_from_previous_sample(model, categories=[<VariableCategory.DIFFERENTIAL: 51>, <VariableCategory.ALGEBRAIC: 52>, <VariableCategory.DERIVATIVE: 53>, <VariableCategory.INPUT: 54>], **kwargs)¶
Re-initializes values of variables in model to the values one sampling time in the future. Values for the last sampling time are currently set to values in the steady state model, assumed to be the set point.
- model – Flowsheet model to initialize
- categories – List of VariableCategory enum items to initialize. Default contains DIFFERENTIAL, ALGEBRAIC, DERIVATIVE, and INPUT
Injects input variables from the first sampling time in the controller model to the sampling period in the plant model that starts at the specified time, adding noise if desired.
Parameters: t_plant – First time point in plant model where inputs will be applied.
Builds lists of lower bound, upper bound tuples as attributes of the input model, based on the current bounds (and domains) of differential, algebraic, and input variables.
Parameters: model – Model whose variables will be checked for bounds.
Sets the values in the reference list of an NMPCVarGroup from the values of the group’s variables at t0
- vargroup – NMPCVarGroup instance whose reference values to set
- t0 – Point in time at which variable values will be used to set reference values
Function for simulating plant model for one sampling period after inputs have been assigned from solve of controller model.
Parameters: t_start – Beginning of timespan over which to simulate
Function for solving optimal control problem, which calculates control inputs for the plant.
Function to solve for consistent initial conditions in the provided flowsheet model.
Parameters: model – Flowsheet model whose initial conditions are solved
Transfers bounds from source model’s bound lists to target model’s differential, algebraic, and input variables, and sets domain to Reals.
- tgt_model – Model whose variables bounds will be transferred to
- src_model – Model whose bound lists will be used to set bounds.
Transfers values of the initial condition variables at a specified time in the plant model to the initial time point of the controller model, adding noise if desired.
Parameters: t_plant – Time point in plant model whose values will be transferred
Makes sure that assumptions regarding fixedness for different points in time are valid. Differential, algebraic, and derivative variables may be fixed only at t0, only if they are initial conditions. Fixed variables must be fixed at all points in time, except possibly initial conditions.
Expects to find “alg,” “diff,” “deriv,” and “fixed” vars on each model’s _NMPC_NAMESPACE, as well as a var_locator ComponentMap.
Parameters: models – Models for which to validate fixedness
validate_initial_inputs(tgt_model, src_model, src_inputs=None, **kwargs)¶
Uses initial inputs in the source model to find variables of the same name in a target model.
- tgt_model – Flowsheet model to search for input variables
- src_model – Flowsheet model containing inputs to search for
- src_inputs – List of input variables at the initial time point to find in target model. If not provided, the initial_inputs attribute will be used.
List of variables (time-only slices) in the target model corresponding to the inputs in the source model
Makes sure the two models are instances of Pyomo Blocks and do not have the same top-level model.
- m1 – First model (Pyomo Block)
- m2 – Second model (Pyomo Block)
True if models are valid
validate_sample_time(sample_time, *models, **kwargs)¶
Makes sure sample points, or integer multiple of sample time-offsets from time.first() lie on finite element boundaries, and that horizon of each model is an integer multiple of sample time. Assembles a list of sample points and a dictionary mapping sample points to the number of finite elements in the preceding sampling period, and adds them as attributes to _NMPC_NAMESPACE.
- sample_time – Sample time to check
- models – List of flowsheet models to check
validate_slices(tgt_model, src_model, src_time, src_slices)¶
Given list of time-only slices in a source model, attempts to find each of them in the target model and returns a list of the found slices in the same order. Expects to find a var_locator ComponentMap attribute in the _NMPC_NAMESPACE of the target model.
- tgt_model – Model to search for time-slices
- src_model – Model containing the slices to search for
- src_slices – List of time-only slices of variables in the source model
List of time-only slices to same-named variables in the target model