Dynamic Optimization Solvers

Currently 4 backends are exposed for solving dynamic optimization problems using collocation: JuMP, InfiniteOpt, CasADi, and Pyomo.

Please note that there are differences in how to construct the collocation solver for the different cases. For example, the Python based ones, CasADi and Pyomo, expect the solver to be passed in as a string (CasADi and Pyomo come pre-loaded with Ipopt, but other solvers may need to be manually installed using pip or conda), while JuMP/InfiniteOpt expect the optimizer object to be passed in directly:

JuMPCollocation(Ipopt.Optimizer, constructRK4())
CasADiCollocation("ipopt", constructRK4())

JuMP and CasADi collocation accept an optional ODE tableau. These can be constructed by calling the constructX() functions from DiffEqDevTools. The list of tableaus can be found here. If none is passed in, both solvers use the fifth-order, three-stage Radau IIA tableau.

Pyomo and InfiniteOpt each have their own built-in collocation methods.

  1. InfiniteOpt: The list of InfiniteOpt collocation methods can be found in the table on this page. If none is passed in, the solver defaults to FiniteDifference(Backward()), which is effectively implicit Euler.
  2. Pyomo: The list of Pyomo collocation methods can be found at the bottom of this page. If none is passed in, the solver defaults to a LagrangeRadau(5).

Some examples of the latter two collocations:

PyomoCollocation("ipopt", LagrangeRadau(2))
InfiniteOptCollocation(Ipopt.Optimizer, OrthogonalCollocation(3))
ModelingToolkitBase.AbstractCollocationType
AbstractCollocation

Opaque common base type for supported dynamic-optimization collocation descriptors.

Public API Boundary

AbstractCollocation is not a third-party extension interface. It is the common base for the concrete descriptors supported by ModelingToolkitBase's JuMP, InfiniteOpt, CasADi, and Pyomo backends. solve(::AbstractDynamicOptProblem, ::AbstractCollocation) dispatches to backend hooks that are implementation details and not public API.

Do not subtype AbstractCollocation, implement collocation-solving hooks, or otherwise extend collocation solving from an external package. External subtyping and extension are unsupported unless a public interface is defined and documented in a future release.

Usage

Select one of the documented concrete descriptors for the backend used to construct the dynamic-optimization problem:

Pass that descriptor to solve(prob, solver). The problem constructor and descriptor must use the same backend.

See Dynamic Optimization Solvers for constructor arguments and backend-specific options.

source
ModelingToolkitBase.JuMPCollocationFunction
JuMPCollocation(solver, tableau = constructDefault()) -> AbstractCollocation

Configure the collocation descriptor used to solve a JuMPDynamicOptProblem.

Arguments

  • solver: a JuMP optimizer constructor, such as Ipopt.Optimizer.
  • tableau: an ODE Runge-Kutta tableau used to transcribe the dynamics. Defaults to the built-in fifth-order Radau IIA tableau.

Returns

  • AbstractCollocation: a descriptor accepted by solve for a JuMPDynamicOptProblem.

Examples

using ModelingToolkitBase, InfiniteOpt, Ipopt

JuMPCollocation(Ipopt.Optimizer)
source
ModelingToolkitBase.InfiniteOptCollocationFunction
InfiniteOptCollocation(solver, derivative_method = ...) -> AbstractCollocation

Configure the collocation descriptor used to solve an InfiniteOptDynamicOptProblem.

Arguments

  • solver: a JuMP optimizer constructor, such as Ipopt.Optimizer.
  • derivative_method: an InfiniteOpt.AbstractDerivativeMethod used to discretize the independent variable. Defaults to backward finite differences.

Returns

  • AbstractCollocation: a descriptor accepted by solve for an InfiniteOptDynamicOptProblem.

Examples

using ModelingToolkitBase, InfiniteOpt, Ipopt

InfiniteOptCollocation(Ipopt.Optimizer)
source
ModelingToolkitBase.CasADiCollocationFunction
CasADiCollocation(solver, tableau = constructDefault()) -> AbstractCollocation

Configure the collocation descriptor used to solve a CasADiDynamicOptProblem.

Arguments

  • solver: the name of a CasADi solver plugin, supplied as a String or Symbol, such as "ipopt".
  • tableau: an ODE Runge-Kutta tableau used to transcribe the dynamics. Defaults to the built-in fifth-order Radau IIA tableau.

Returns

  • AbstractCollocation: a descriptor accepted by solve for a CasADiDynamicOptProblem.

Examples

using ModelingToolkitBase, CasADi

CasADiCollocation("ipopt")
source
ModelingToolkitBase.PyomoCollocationFunction
PyomoCollocation(solver, derivative_method = LagrangeRadau(5)) -> AbstractCollocation

Configure the collocation descriptor used to solve a PyomoDynamicOptProblem.

Arguments

  • solver: the name of a Pyomo solver plugin, supplied as a String or Symbol, such as "ipopt".
  • derivative_method: a Pyomo.DiscretizationMethod used to transcribe the dynamics. Defaults to LagrangeRadau(5).

Returns

  • AbstractCollocation: a descriptor accepted by solve for a PyomoDynamicOptProblem.

Examples

using ModelingToolkitBase, Pyomo

PyomoCollocation("ipopt", Pyomo.LagrangeRadau(3))
source
ModelingToolkitBase.DynamicOptSolutionType
DynamicOptSolution(model, sol, input_sol)

Solution wrapper returned by dynamic-optimization backends.

Fields

  • model: backend-specific optimization model.
  • sol: state trajectory as an ODESolution.
  • input_sol: controller/input trajectory as an ODESolution, or nothing when the backend does not return one.
source
CommonSolve.solveMethod
solve(prob::AbstractDynamicOptProblem, solver::AbstractCollocation; verbose = false, kwargs...)
  • kwargs are used for other options. For example, the plugin_options and solver_options will propagated to the Opti object in CasADi.
source

Problem constructors

ModelingToolkitBase.JuMPDynamicOptProblemFunction
JuMPDynamicOptProblem(sys::System, op, tspan; dt, steps, guesses, kwargs...)

Convert a System representing an optimal control system into a JuMP model for solving using optimization. Must provide either dt, the timestep between collocation points (which, along with the timespan, determines the number of points), or directly provide the number of points as steps.

To construct the problem, please load InfiniteOpt along with ModelingToolkitBase.

source
ModelingToolkitBase.InfiniteOptDynamicOptProblemFunction
InfiniteOptDynamicOptProblem(sys::System, op, tspan; dt)

Convert a System representing an optimal control system into a InfiniteOpt model for solving using optimization. Must provide dt for determining the length of the interpolation arrays.

Related to JuMPDynamicOptProblem, but directly adds the differential equations of the system as derivative constraints, rather than using a solver tableau.

Each dynamics constraint is emitted as a residual scaled by the state's nominal value, (∂x - tₛ*f(x)) / nominal ~ 0, so that states of different magnitudes produce comparable residuals. The nominal value is taken from the variable's nominal metadata (see getnominal; 1.0 if unset) and can be overridden per state with the nominal_values keyword, a map from states to their typical magnitudes.

To construct the problem, please load InfiniteOpt along with ModelingToolkitBase.

source
ModelingToolkitBase.CasADiDynamicOptProblemFunction
CasADiDynamicOptProblem(sys::System, op, tspan; dt, steps, guesses, kwargs...)

Convert a System representing an optimal control system into a CasADi model for solving using optimization. Must provide either dt, the timestep between collocation points (which, along with the timespan, determines the number of points), or directly provide the number of points as steps.

To construct the problem, please load CasADi along with ModelingToolkitBase.

source
ModelingToolkitBase.PyomoDynamicOptProblemFunction
PyomoDynamicOptProblem(sys::System, op, tspan; dt, steps)

Convert a System representing an optimal control system into a Pyomo model for solving using optimization. Must provide either dt, the timestep between collocation points (which, along with the timespan, determines the number of points), or directly provide the number of points as steps.

Each dynamics constraint is emitted as a residual scaled by the state's nominal value, (∂x - tₛ*f(x)) / nominal ~ 0, so that states of different magnitudes produce comparable residuals. The nominal value is taken from the variable's nominal metadata (see getnominal; 1.0 if unset) and can be overridden per state with the nominal_values keyword, a map from states to their typical magnitudes.

To construct the problem, please load Pyomo along with ModelingToolkitBase.

source