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.
- 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. - 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.AbstractCollocation — Type
AbstractCollocationOpaque 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:
JuMPCollocationfor the JuMP backend.InfiniteOptCollocationfor the InfiniteOpt backend.CasADiCollocationfor the CasADi backend.PyomoCollocationfor the Pyomo backend.
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.
ModelingToolkitBase.JuMPCollocation — Function
JuMPCollocation(solver, tableau = constructDefault()) -> AbstractCollocationConfigure the collocation descriptor used to solve a JuMPDynamicOptProblem.
Arguments
solver: a JuMP optimizer constructor, such asIpopt.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 bysolvefor aJuMPDynamicOptProblem.
Examples
using ModelingToolkitBase, InfiniteOpt, Ipopt
JuMPCollocation(Ipopt.Optimizer)ModelingToolkitBase.InfiniteOptCollocation — Function
InfiniteOptCollocation(solver, derivative_method = ...) -> AbstractCollocationConfigure the collocation descriptor used to solve an InfiniteOptDynamicOptProblem.
Arguments
solver: a JuMP optimizer constructor, such asIpopt.Optimizer.derivative_method: anInfiniteOpt.AbstractDerivativeMethodused to discretize the independent variable. Defaults to backward finite differences.
Returns
AbstractCollocation: a descriptor accepted bysolvefor anInfiniteOptDynamicOptProblem.
Examples
using ModelingToolkitBase, InfiniteOpt, Ipopt
InfiniteOptCollocation(Ipopt.Optimizer)ModelingToolkitBase.CasADiCollocation — Function
CasADiCollocation(solver, tableau = constructDefault()) -> AbstractCollocationConfigure the collocation descriptor used to solve a CasADiDynamicOptProblem.
Arguments
solver: the name of a CasADi solver plugin, supplied as aStringorSymbol, 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 bysolvefor aCasADiDynamicOptProblem.
Examples
using ModelingToolkitBase, CasADi
CasADiCollocation("ipopt")ModelingToolkitBase.PyomoCollocation — Function
PyomoCollocation(solver, derivative_method = LagrangeRadau(5)) -> AbstractCollocationConfigure the collocation descriptor used to solve a PyomoDynamicOptProblem.
Arguments
solver: the name of a Pyomo solver plugin, supplied as aStringorSymbol, such as"ipopt".derivative_method: aPyomo.DiscretizationMethodused to transcribe the dynamics. Defaults toLagrangeRadau(5).
Returns
AbstractCollocation: a descriptor accepted bysolvefor aPyomoDynamicOptProblem.
Examples
using ModelingToolkitBase, Pyomo
PyomoCollocation("ipopt", Pyomo.LagrangeRadau(3))ModelingToolkitBase.DynamicOptSolution — Type
DynamicOptSolution(model, sol, input_sol)Solution wrapper returned by dynamic-optimization backends.
Fields
model: backend-specific optimization model.sol: state trajectory as anODESolution.input_sol: controller/input trajectory as anODESolution, ornothingwhen the backend does not return one.
CommonSolve.solve — Method
solve(prob::AbstractDynamicOptProblem, solver::AbstractCollocation; verbose = false, kwargs...)- kwargs are used for other options. For example, the
plugin_optionsandsolver_optionswill propagated to the Opti object in CasADi.
Problem constructors
ModelingToolkitBase.JuMPDynamicOptProblem — Function
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.
ModelingToolkitBase.InfiniteOptDynamicOptProblem — Function
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.
ModelingToolkitBase.CasADiDynamicOptProblem — Function
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.
ModelingToolkitBase.PyomoDynamicOptProblem — Function
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.