SciMLSolutions
Definition of the AbstractSciMLSolution Interface
All AbstractSciMLSolution
types are a subset of some AbstractArray
. Types with time series (like ODESolution
) are subtypes of RecursiveArrayTools.AbstractVectorOfArray
and RecursiveArrayTools.AbstractDiffEqArray
where appropriate. Types without a time series (like OptimizationSolution
) are directly subsets of AbstractArray
.
Array Interface
Instead of working on the Vector{uType}
directly, we can use the provided array interface.
sol[j]
to access the value at timestep j
(if the timeseries was saved), and
sol.t[j]
to access the value of t
at timestep j
. For multi-dimensional systems, this will address first by component and lastly by time, and thus
sol[i, j]
will be the i
th component at timestep j
. Hence, sol[j][i] == sol[i, j]
. This is done because Julia is column-major, so the leading dimension should be contiguous in memory. If the independent variables had shape (for example, was a matrix), then i
is the linear index. We can also access solutions with shape:
sol[i, k, j]
gives the [i,k]
component of the system at timestep j
. The colon operator is supported, meaning that
sol[i, :]
gives the timeseries for the i
th component.
Common Field Names
u
: the solution valuest
: the independent variable values, matching the length of the solution, if applicableresid
: the residual of the solution, if applicableoriginal
: the solution object from the original solver, if it's a wrapper algorithmretcode
: see the documentation section on return codesprob
: the problem that was solvedalg
: the algorithm used to solve the problem
Return Codes (RetCodes)
The solution types have a retcode
field which returns a SciMLBase.ReturnCode.T
(from EnumX.jl, see that package for the semantics of handling EnumX types) signifying the error or satisfaction state of the solution.
SciMLBase.ReturnCode
— ModuleSciML.ReturnCode
SciML.ReturnCode
is the standard return code enum interface for the SciML interface. Return codes are notes given by the solvers to indicate the state of the solution, for example whether it successfully solved the equations, whether it failed to solve the equations, and importantly, why it exited.
Using SciML.ReturnCode
SciML.ReturnCode
use the interface of EnumX.jl and thus inherits all of the behaviors of being an EnumX. This includes the Enum type itself being referred to as SciML.ReturnCode.T
, and each of the constituent enum states being referred to via getproperty
, i.e. SciML.ReturnCode.Success
.
Note About Success Checking
Previous iterations of the interface suggested using sol.retcode == :Success
, however, that is now not advised instead should be replaced with SciMLBase.successful_retcode(sol)
. The reason is that there are many different codes that can be interpreted as successful, such as ReturnCode.Terminated
which means successfully used terminate!(integrator)
to end an integration at a user-specified condition. As such, successful_retcode
is the most general way to query for if the solver did not error.
Properties
successful_retcode(retcode::ReturnCode.T)
: Determines whether the output enum is considered a success state of the solver, i.e. the solver successfully solved the equations.ReturnCode.Success
is the most basic form, simply declaring that it was successful, but many more informative success return codes exist as well.
Return Code Traits
SciMLBase.successful_retcode
— Functionsuccessful_retcode(retcode::ReturnCode.T)::Bool
successful_retcode(sol::AbstractSciMLSolution)::Bool
Returns a boolean for whether a return code should be interpreted as a form of success.
Specific Return Codes
SciMLBase.ReturnCode.Default
— ConstantReturnCode.Default
The default state of the solver. If this return code is given, then the solving process is either still in process or the solver library has not been setup with the return code interface and thus the return code is undetermined.
Common Reasons for Seeing this Return Code
- A common reason for
Default
return codes is that a solver is a non-SciML solver which does not fully conform to the interface. Please open an issue if this is seen and it will be improved. - Another common reason for a
Default
return code is if the solver is probed internally before the solving process is done, such as through the callback interface. Return codes are set toDefault
to start and are changed toSuccess
and other return codes upon finishing the solving process or hitting a numerical difficulty.
Properties
successful_retcode
=false
SciMLBase.ReturnCode.Success
— ConstantReturnCode.Success
The success state of the solver. If this return code is given, then the solving process was successful, but no extra information about that success is given.
Common Reasons for Seeing this Return Code
- This is the most common return code and most solvers will give this return code if the solving process went as expected without any errors or detected numerical issues.
Properties
successful_retcode
=true
SciMLBase.ReturnCode.Terminated
— ConstantReturnCode.Terminated
The successful termination state of the solver. If this return code is given, then the solving process was successful at terminating the solve, usually through a callback affect!
via terminate!(integrator)
.
Common Reasons for Seeing this Return Code
- The most common reason for seeing this return code is if a user calls a callback which uses
terminate!(integrator)
to halt the integration at a user-chosen stopping point. - Another common reason for this return code is due to implicit
terminate!
statements in some library callbacks. For example,SteadyStateCallback
usesterminate!
internally, so solutions which reach steady state will have aReturnCode.Terminated
state instead of aReturnCode.Success
state. Similarly, problems solved via SteadyStateDiffEq.jl will have thisReturnCode.Terminated
state if a timestepping method is used to solve to steady state.
Properties
successful_retcode
=true
SciMLBase.ReturnCode.DtNaN
— ConstantReturnCode.DtNaN
A failure exit state of the solver. If this return code is given, then the solving process was unsuccessful and exited early because the dt
of the integration was determined to be NaN
and thus the solver could not continue.
Common Reasons for Seeing this Return Code
- The most common reason for seeing this return code is because the automatic
dt
selection algorithm is used but the starting derivative has aNaN
orInf
derivative term. Double check that thef(u0,p,t0)
term is well-defined withoutNaN
orInf
values. - Another common reason for this return code is because of a user set
dt
which is calculated to be aNaN
. Ifsolve(prob,alg,dt=x)
, double check thatx
is notNaN
.
Properties
successful_retcode
=false
SciMLBase.ReturnCode.MaxIters
— ConstantReturnCode.MaxIters
A failure exit state of the solver. If this return code is given, then the solving process was unsuccessful and exited early because the solver's iterations hit the maxiters
either set by default or by the user in the solve
/init
command.
Note about Nonlinear Optimization
In nonlinear optimization, many solvers (such as OptimizationOptimisers.Adam
) do not have an exit criteria other than iters == maxiters
. In this case, the solvers will iterate until maxiters
and exit with a Success
return code, as that is a successful run of the solver and not considered to be an error state. Solves with early termination criteria, such as Optim.BFGS
exiting when the gradient is sufficiently close to zero, will give ReturnCode.MaxIters
on exits which require the maximum iteration.
Common Reasons for Seeing this Return Code
- This commonly occurs in ODE solving if a non-stiff method (e.g.
Tsit5
) is used in an algorithm choice for a stiff ODE. It is recommended that in such cases, one tries a stiff ODE solver. - This commonly occurs in optimization and nonlinear solvers if the tolerance on
solve
to too low and cannot be achieved due to floating point error or the condition number of the solver matrix. Double check that the chosen tolerance is numerically possible.
Properties
successful_retcode
=false
SciMLBase.ReturnCode.MaxNumSub
— ConstantReturnCode.MaxNumSub
A failure exit state of the solver. If this return code is given, then the solving process was unsuccessful and exited early because during the solver's adaptivity, mesh length exceeded the max_num_subintervals
either set by default or specified by users in the solver.
Common Reasons for Seeing this Return Code
- This commonly occurs in BVP solving if the original mesh are too coarse or the tolerance are too stringent. It is recommended that in such cases, one tries to increase the default
max_num_subintervals
in solvers, or decrease the tolerance.
Properties
successful_retcode
=false
SciMLBase.ReturnCode.DtLessThanMin
— ConstantReturnCode.DtLessThanMin
A failure exit state of the solver. If this return code is given, then the solving process was unsuccessful and exited early because the dt
of the integration was made to be less than dtmin
, i.e. dt < dtmin
.
Common Reasons for Seeing this Return Code
- The most common reason for seeing this return code is because the integration is going unstable. As
f(u,p,t) -> infinity
, the time steps required by the solver to accurately handle the dynamics decreases. When it gets sufficiently small,dtmin
, an exit is thrown as the solution is likely unstable.dtmin
is also chosen to be around the value where floating point issues causet + dt == t
, and thus adt
of that size is impossible at floating point precision. - Another common reason for this return code is if domain constraints are set, such as by using
isoutofdomain
, but the domain constraint is incorrect. For example, if one is solving the ODEf(u,p,t) = -u - 1
, one may think "but I want a solution withu > 0
and thus I will setisoutofdomain(u,p,t) = u < 0
. However, the true solution of this ODE is not positive, and thus what will occur is that the solver will try to decreasedt
until it can give an accurate solution that is positive. As this is impossible, it will continue to shrink thedt
untildt < dtmin
and then exit with this return code.
Properties
successful_retcode
=false
SciMLBase.ReturnCode.Unstable
— ConstantReturnCode.Unstable
A failure exit state of the solver. If this return code is given, then the solving process was unsuccessful and exited early because the unstable_check
function, as given by the unstable_check
common keyword argument (or its default), give a true
at the current state.
Common Reasons for Seeing this Return Code
- The most common reason for seeing this return code is because
u
contains aNaN
orInf
value. The defaultunstable_check
only checks for these values.
Properties
successful_retcode
=false
SciMLBase.ReturnCode.InitialFailure
— ConstantReturnCode.InitialFailure
A failure exit state of the solver. If this return code is given, then the solving process was unsuccessful because the initialization process failed.
Common Reasons for Seeing this Return Code
- The most common reason for seeing this return code is because the initialization process of a DAE solver failed to find consistent initial conditions, which can occur if the differentiation index of the DAE solver is too high. Most DAE solvers only allow for index-1 DAEs, and so an index-2 DAE will fail during this initialization. To solve this kind of problem, use
ModelingToolkit.jl
and itsstructural_simplify
method to reduce the index of the DAE. - Another common reason for this return code is if the initial condition was not suitable for the numerical solve. For example, the initial point had a
NaN
orInf
. Or in optimization, this can occur if the initial point is outside of the bound constraints given by the user.
Properties
successful_retcode
=false
SciMLBase.ReturnCode.ConvergenceFailure
— ConstantReturnCode.ConvergenceFailure
A failure exit state of the solver. If this return code is given, then the solving process was unsuccessful because internal nonlinear solver iterations failed to converge.
Common Reasons for Seeing this Return Code
- The most common reason for seeing this return code is because an inappropriate nonlinear solver was chosen. If fixed point iteration is used on a stiff problem, it will be faster by avoiding the Jacobian but it will make a stiff ODE solver not stable for stiff problems!
- For nonlinear solvers, this can occur if certain threshold was exceeded. For example, in approximate jacobian solvers like Broyden, Klement, etc. if the number of jacobian resets exceeds the threshold, then this return code is given.
Properties
successful_retcode
=false
SciMLBase.ReturnCode.Failure
— ConstantReturnCode.Failure
A failure exit state of the solver. If this return code is given, then the solving process was unsuccessful but no extra information is given.
Common Reasons for Seeing this Return Code
- The most common reason for seeing this return code is because the solver is a wrapped solver (i.e. a Fortran code) which does not provide any extra information about its exit state. If this is from a Julia-based solver, please open an issue.
Properties
successful_retcode
=false
SciMLBase.ReturnCode.ExactSolutionLeft
— ConstantReturnCode.ExactSolutionLeft
The success state of the solver. If this return code is given, then the solving process was successful, and the left solution was given.
Common Reasons for Seeing this Return Code
- The most common reason for this return code is via a bracketing nonlinear solver, such as bisection, iterating to convergence is unable to give the exact
f(x)=0
solution due to floating point precision issues, and thus it gives the first floating point value to the left forx
.
Properties
successful_retcode
=true
SciMLBase.ReturnCode.ExactSolutionRight
— ConstantReturnCode.ExactSolutionRight
The success state of the solver. If this return code is given, then the solving process was successful, and the right solution was given.
Common Reasons for Seeing this Return Code
- The most common reason for this return code is via a bracketing nonlinear solver, such as bisection, iterating to convergence is unable to give the exact
f(x)=0
solution due to floating point precision issues, and thus it gives the first floating point value to the right forx
.
Properties
successful_retcode
=true
SciMLBase.ReturnCode.FloatingPointLimit
— ConstantReturnCode.FloatingPointLimit
The success state of the solver. If this return code is given, then the solving process was successful, and the closest floating point value to the solution was given.
Common Reasons for Seeing this Return Code
- The most common reason for this return code is via a nonlinear solver, such as Falsi, iterating to convergence is unable to give the exact
f(x)=0
solution due to floating point precision issues, and thus it gives the closest floating point value to the true solution forx
.
Properties
successful_retcode
=true
Solution Traits
AbstractSciMLSolution API
Abstract SciML Solutions
SciMLBase.AbstractSciMLSolution
— TypeUnion of all base solution types.
Uses a Union so that solution types can be <: AbstractArray
SciMLBase.AbstractNoTimeSolution
— Typeabstract type AbstractNoTimeSolution{T, N} <: AbstractArray{T, N}
SciMLBase.AbstractTimeseriesSolution
— Typeabstract type AbstractTimeseriesSolution{T, N, A} <: RecursiveArrayTools.AbstractDiffEqArray{T, N, A}
SciMLBase.AbstractNoiseProcess
— Typeabstract type AbstractNoiseProcess{T, N, A, isinplace} <: RecursiveArrayTools.AbstractDiffEqArray{T, N, A}
SciMLBase.AbstractEnsembleSolution
— Typeabstract type AbstractEnsembleSolution{T, N, A} <: RecursiveArrayTools.AbstractVectorOfArray{T, N, A}
SciMLBase.AbstractLinearSolution
— Typeabstract type AbstractLinearSolution{T, N} <: SciMLBase.AbstractNoTimeSolution{T, N}
SciMLBase.AbstractNonlinearSolution
— Typeabstract type AbstractNonlinearSolution{T, N} <: SciMLBase.AbstractNoTimeSolution{T, N}
SciMLBase.AbstractIntegralSolution
— Typeabstract type AbstractIntegralSolution{T, N} <: SciMLBase.AbstractNoTimeSolution{T, N}
SciMLBase.AbstractSteadyStateSolution
— Typeabstract type AbstractNonlinearSolution{T, N} <: SciMLBase.AbstractNoTimeSolution{T, N}
SciMLBase.AbstractAnalyticalSolution
— Typeabstract type AbstractAnalyticalSolution{T, N, S} <: SciMLBase.AbstractTimeseriesSolution{T, N, S}
SciMLBase.AbstractODESolution
— Typeabstract type AbstractODESolution{T, N, S} <: SciMLBase.AbstractTimeseriesSolution{T, N, S}
SciMLBase.AbstractDDESolution
— Typeabstract type AbstractDDESolution{T, N, S} <: SciMLBase.AbstractODESolution{T, N, S}
SciMLBase.AbstractRODESolution
— Typeabstract type AbstractRODESolution{T, N, S} <: SciMLBase.AbstractODESolution{T, N, S}
SciMLBase.AbstractDAESolution
— Typeabstract type AbstractDAESolution{T, N, S} <: SciMLBase.AbstractODESolution{T, N, S}