SciMLSolutions

Definition of the AbstractSciMLSolution Interface

AbstractSciMLSolution is a union of four array-like solution families. Time-series solutions and noise processes use RecursiveArrayTools.AbstractDiffEqArray, ensemble solutions use RecursiveArrayTools.AbstractVectorOfArray, and solutions without an independent-variable series subtype AbstractArray directly.

Concrete no-time solutions must expose their result as u. Concrete time-series solutions must expose saved states as u and matching independent-variable values as t; they provide prob, alg, interp, dense, retcode, and stats when those concepts apply. Ensemble and noise-process subtypes follow the contracts in their rendered abstract-type docstrings below.

Generic Usage Rules

Consumers should dispatch on the narrowest abstract solution family they need and use the array and callable interfaces instead of inspecting a concrete solution type. The common contract is:

  • no-time solutions expose u and forward size, getindex, and compatible linear algebra operations to it;
  • time-series solutions expose matching u and t indices, with state components preceding the saved-time index;
  • callers use successful_retcode(sol) rather than comparing only against ReturnCode.Success;
  • callers use isdenseplot(sol) and plottable_indices(x) when selecting plotting behavior instead of assuming dense interpolation or that every state component is plottable;
  • optional fields such as prob, alg, interp, stats, and resid may be absent for a solution family and must be accessed only when that family's contract documents them.

For example, a generic report can work for every no-time solution without knowing whether it came from a linear, nonlinear, integral, or optimization solver:

function solution_report(sol::SciMLBase.AbstractNoTimeSolution)
    return (; size = size(sol), successful = SciMLBase.successful_retcode(sol))
end

Concrete solution types must document their fields, indexing shape, callable interpolation behavior, and any additional mutation or cache guarantees.

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 ith 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 ith component.

Common Field Names

Fields are required only when they apply to the solution family and solver. Concrete solution types must document which optional fields they provide.

  • u: the solution values
  • t: the independent variable values, matching the length of the solution, if applicable
  • resid: the residual of the solution, if applicable
  • original: the solution object from the original solver, if it's a wrapper algorithm
  • retcode: see the documentation section on return codes
  • prob: the problem that was solved
  • alg: 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.ReturnCodeModule
SciMLBase.ReturnCode

SciMLBase.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 SciMLBase.ReturnCode

SciMLBase.ReturnCode uses 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 SciMLBase.ReturnCode.T, and each constituent enum state being accessed as a module property, for example SciMLBase.ReturnCode.Success.

Note About Success Checking

Previous iterations of the interface suggested sol.retcode == :Success. Use SciMLBase.successful_retcode(sol) instead. Several informative codes represent successful outcomes, such as ReturnCode.Terminated after a requested callback termination. The predicate is the canonical way to distinguish successful and unsuccessful solver exits.

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.
source

Return Code Traits

SciMLBase.successful_retcodeFunction
successful_retcode(retcode::ReturnCode.T)::Bool
successful_retcode(sol::AbstractSciMLSolution)::Bool

Return whether a return code represents a successful solver outcome.

The solution form forwards to successful_retcode(sol.retcode). Use this predicate instead of comparing only with ReturnCode.Success, because requested termination and other informative terminal states can also be successful.

The successful codes are ReturnCode.Success, ReturnCode.Terminated, ReturnCode.ExactSolutionLeft, ReturnCode.ExactSolutionRight, ReturnCode.FloatingPointLimit, and ReturnCode.StalledSuccess. ReturnCode.Default is not successful because it means the solve is unfinished or its outcome is unknown. ReturnCode.Stalled and all failure codes are also unsuccessful.

source
SciMLBase.isdenseplotFunction
isdenseplot(sol)

Return whether plotting sol should evaluate its interpolation densely.

Solution packages may extend this for a concrete solution type.

source
SciMLBase.plottable_indicesFunction
plottable_indices(x::AbstractArray) -> Any

Given the first element in a timeseries solution, return an AbstractArray of indices that can be plotted as continuous variables. This is useful for systems that store auxiliary variables in the state vector which are not meant to be used for plotting.

source

Specific Return Codes

SciMLBase.ReturnCode.DefaultConstant
ReturnCode.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 to Default to start and are changed to Success and other return codes upon finishing the solving process or hitting a numerical difficulty.

Properties

  • successful_retcode = false
source
SciMLBase.ReturnCode.SuccessConstant
ReturnCode.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
source
SciMLBase.ReturnCode.TerminatedConstant
ReturnCode.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 uses terminate! internally, so solutions which reach steady state will have a ReturnCode.Terminated state instead of a ReturnCode.Success state. Similarly, problems solved via SteadyStateDiffEq.jl will have this ReturnCode.Terminated state if a timestepping method is used to solve to steady state.

Properties

  • successful_retcode = true
source
SciMLBase.ReturnCode.DtNaNConstant
ReturnCode.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 a NaN or Inf derivative term. Double check that the f(u0,p,t0) term is well-defined without NaN or Inf values.
  • Another common reason for this return code is because of a user set dt which is calculated to be a NaN. If solve(prob,alg,dt=x), double check that x is not NaN.

Properties

  • successful_retcode = false
source
SciMLBase.ReturnCode.MaxItersConstant
ReturnCode.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
source
SciMLBase.ReturnCode.MaxNumSubConstant
ReturnCode.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
source
SciMLBase.ReturnCode.MaxTimeConstant
ReturnCode.MaxTime

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 timer hit maxtime either set by default or by the user in the solve/init command.

Properties

  • successful_retcode = false
source
SciMLBase.ReturnCode.DtLessThanMinConstant
ReturnCode.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 cause t + dt == t, and thus a dt 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 ODE f(u,p,t) = -u - 1, one may think "but I want a solution with u > 0 and thus I will set isoutofdomain(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 decrease dt until it can give an accurate solution that is positive. As this is impossible, it will continue to shrink the dt until dt < dtmin and then exit with this return code.

Properties

  • successful_retcode = false
source
SciMLBase.ReturnCode.UnstableConstant
ReturnCode.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 a NaN or Inf value. The default unstable_check only checks for these values.

Properties

  • successful_retcode = false
source
SciMLBase.ReturnCode.InitialFailureConstant
ReturnCode.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 its structural_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 or Inf. Or in optimization, this can occur if the initial point is outside of the bound constraints given by the user.

Properties

  • successful_retcode = false
source
SciMLBase.ReturnCode.ConvergenceFailureConstant
ReturnCode.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
source
SciMLBase.ReturnCode.FailureConstant
ReturnCode.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
source
SciMLBase.ReturnCode.ExactSolutionLeftConstant
ReturnCode.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 for x.

Properties

  • successful_retcode = true
source
SciMLBase.ReturnCode.ExactSolutionRightConstant
ReturnCode.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 for x.

Properties

  • successful_retcode = true
source
SciMLBase.ReturnCode.FloatingPointLimitConstant
ReturnCode.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 for x.

Properties

  • successful_retcode = true
source
SciMLBase.ReturnCode.InternalLinearSolveFailedConstant
ReturnCode.InternalLinearSolveFailed

The linear problem inside another problem (for example inside a NonlinearProblem) could not be solved.

Common Reasons for Seeing this Return Code

  • If a rank-deficient matrix originated inside the nonlinear solve and the provided linear solver is incapable of handling those cases.

Properties

  • successful_retcode = false
source
SciMLBase.ReturnCode.APosterioriSafetyFailureConstant
ReturnCode.APosterioriSafetyFailure

A failure exit state of the solver. If this return code is given, then the solver completed execution but an a posteriori error check detected that the computed solution is likely inaccurate due to numerical issues. This is distinct from ReturnCode.Failure which indicates the solver itself failed to complete.

Common Reasons for Seeing this Return Code

  • A linear solver (e.g. LU factorization) succeeded but a post-solve residual check ‖A*x - b‖ found the residual to be unacceptably large, indicating numerical instability from a near-singular or ill-conditioned matrix.
  • This return code is used when residualsafety = true is set on an LU algorithm and the residual exceeds the safety threshold.

Properties

  • successful_retcode = false
source
SciMLBase.ReturnCode.StalledConstant
ReturnCode.Stalled

The solution has stalled. This is only returned by algorithms for which stalling is a failure mode, such as on a NonlinearProblem where the found solution is larger than the accepted tolerance.

Properties

  • successful_retcode = false
source
SciMLBase.ReturnCode.StalledSuccessConstant

ReturnCode.StalledSuccess

The solution process has stalled, but the stall is not considered a failure of the solver. For example, a nonlinear optimizer may have stalled, that is its steps went to zero, which is a valid local minima.

Common Reasons for Seeing this Return Code

  • For nonlinear least squares optimizations, this is given for local minima which exceed the chosen tolerance, i.e. f(x)=resid where ||resid||>tol so it's not considered ReturnCode.Success but it is still considered a successful return of the solver since it's a valid local minima (and there no minima which achieves the tolerance).

Properties

  • successful_retcode = true
source

Plotting

Solution types include Plots.jl recipes. All the core plotting functionality (dense interpolation, idxs variable selection, tspan, plotdensity, etc.) is documented in the RecursiveArrayTools.jl plotting docs, since solutions are subtypes of AbstractDiffEqArray.

Solution objects add the following on top of the base AbstractDiffEqArray recipe:

KeywordDefaultDescription
denseplotautomaticEnabled when sol.dense is true or the problem is discrete, except for AbstractRODESolution and SensitivityInterpolation.
plotdensitymin(100_000, max(1000, 10 * length(sol.t)))For a complete continuous solution. The multiplier is 100 for a discrete problem; when sol.tslocation != 0, the uncapped density is 1000 * sol.tslocation.
plot_analyticfalseOverlay the analytical solution (requires prob.f.analytic).

Additionally, solutions support:

  • Discrete parameter variables: Time-varying parameters from ParameterTimeseriesCollection are plotted as step functions with dashed lines and markers.
  • Symbolic observed variables: Derived quantities from ModelingToolkit systems can be plotted directly via idxs = :observed_var.

Callable Interface (Interpolation)

Solutions support callable syntax for interpolation:

sol(t)                       # all state variables at time t
sol(t; idxs = 1)             # single component
sol(t; idxs = [:x, :y])     # symbolic variables
sol(t, Val{1})               # first derivative
sol([0.1, 0.5, 0.9])        # returns a DiffEqArray

The returned DiffEqArray objects carry the interpolation, so they are themselves callable:

result = sol([0.0, 1.0])    # DiffEqArray with interp
result(0.5)                  # interpolate the sub-result

Symbolic save_idxs

Symbolic problems may save a subset of state variables or time-series parameters while still preserving symbolic indexing on the returned solution. The solver-author contract is documented in Symbolic save_idxs and Saved Subsystems.

Solution Traits

SciMLBase.has_statsFunction
has_stats(i::DEIntegrator)

Return whether i exposes mutable solve statistics through its integrator interface.

Solver integrators that maintain counters such as function evaluations, rejected steps, nonlinear iterations, or linear solves should overload this trait to return true and provide the corresponding statistics through their documented integrator fields. The default is false, which tells generic code not to assume that a stats field or stats update path exists.

source

AbstractSciMLSolution API

Abstract SciML Solutions

SciMLBase.AbstractSciMLSolutionType
AbstractSciMLSolution

Union of all base SciML solution interfaces: AbstractTimeseriesSolution, AbstractNoTimeSolution, AbstractEnsembleSolution, and AbstractNoiseProcess.

This is a union rather than an abstract supertype so each solution family can subtype the appropriate array interface directly. Use it for dispatch that accepts any SciML solution, and use the narrower abstract solution types when a method requires a time-series, no-time, ensemble, or noise-process contract.

source
SciMLBase.AbstractNoTimeSolutionType
abstract type AbstractNoTimeSolution{T, N} <: AbstractArray{T, N}

Abstract supertype for solutions whose result has no saved independent-variable axis. Concrete subtypes represent terminal outputs such as linear solves, nonlinear solves, integrals, optimization solves, and other problems where the primary result is the object stored in sol.u.

Interface

Concrete subtypes must provide a u field. The array interface forwards to this field: size(sol) == size(sol.u), sol[i] == sol.u[i], multidimensional integer indexing is forwarded to sol.u, sol[:] returns sol.u[:], and A * sol forwards to A * sol.u for matrix-like A.

Subtypes that support mutation through the solution object should make sol[i] = value update sol.u[i]. Symbolic state indexing is available when the associated problem or cache implements the SymbolicIndexingInterface metadata; parameter indexing should use sol.ps.

Common optional fields are retcode, prob, alg, resid, original, and stats. Solver-specific solution types should document which of these fields they provide.

source
SciMLBase.AbstractTimeseriesSolutionType
abstract type AbstractTimeseriesSolution{T, N, A} <: RecursiveArrayTools.AbstractDiffEqArray{T, N, A}

Abstract supertype for solutions that save a time series or another ordered independent-variable series. Concrete subtypes are array-like views of the saved states and store the raw saved values in sol.u with matching independent-variable values in sol.t.

Interface

Concrete subtypes must provide u and t fields with matching saved-value indices. sol[j] is the saved state at sol.t[j]. Component indexing places state indices before the saved-value index, so sol[i, j] is the ith component of sol.u[j], sol[i, :] is the time series of the ith component, and higher-dimensional states follow the same rule, e.g. sol[i, k, j].

The array dimensions describe the component axes plus the saved-value axis. For multi-component states this means length(sol) can differ from length(sol.t); use length(sol.t) or eachindex(sol.t) when iterating over saved times.

Time-series solutions should provide prob, alg, interp, dense, retcode, and stats fields when those concepts apply. Dense or piecewise interpolation is exposed through callable syntax such as sol(t) and sol(t; idxs) when the stored interpolation supports it. Symbolic state, observed-variable, and parameter access is delegated through the SymbolicIndexingInterface metadata on the solution's problem, with time-varying parameter support supplied through sol.discretes and sol.saved_subsystem when present.

source
SciMLBase.AbstractNoiseProcessType
abstract type AbstractNoiseProcess{T, N, A, isinplace} <: RecursiveArrayTools.AbstractDiffEqArray{T, N, A}

Abstract supertype for saved stochastic noise processes. Noise processes are AbstractDiffEqArrays so that saved noise values can be indexed consistently with differential equation solutions while also carrying enough state for stochastic solvers to replay, interpolate, or extend the noise path.

Interface

Concrete subtypes are expected to expose the saved noise values through the AbstractDiffEqArray interface and to be callable at an independent-variable value when the process supports interpolation. The isinplace parameter records whether the process updates supplied storage in-place. Solver code may also rely on noise-process fields such as the current time and current noise value, so concrete noise process types should document their own state fields and mutation/reset semantics.

source
SciMLBase.AbstractEnsembleSolutionType
abstract type AbstractEnsembleSolution{T, N, A} <: RecursiveArrayTools.AbstractVectorOfArray{T, N, A}

Abstract supertype for solutions from ensemble solves. An ensemble solution stores a collection of trajectory results or summary trajectories in sol.u and uses the RecursiveArrayTools.AbstractVectorOfArray interface so trajectories can be indexed and plotted as a single array-like object.

Interface

Concrete subtypes must provide a u field containing the trajectory solutions or trajectory-like arrays. Standard ensemble solutions also provide elapsedTime, converged, and optionally stats. Calling an ensemble solution forwards the call to each trajectory in sol.u, so sol(args...; kwargs...) returns the collection [trajectory(args...; kwargs...) for trajectory in sol.u] when the stored trajectories are callable.

Analysis and plotting utilities assume that each element of sol.u is either an AbstractSciMLSolution or follows the corresponding array/callable solution interface closely enough for the requested operation.

source
SciMLBase.AbstractLinearSolutionType
abstract type AbstractLinearSolution{T, N} <: SciMLBase.AbstractNoTimeSolution{T, N}

Abstract interface for no-time solutions of linear systems. Concrete subtypes store the computed solution in u and should follow the AbstractNoTimeSolution array-forwarding contract. Linear solve solutions commonly include resid, alg, retcode, iters, cache, and stats fields so callers can inspect convergence and reuse solver caches.

source
SciMLBase.AbstractEigenvalueSolutionType
abstract type AbstractEigenvalueSolution{T, N} <: SciMLBase.AbstractNoTimeSolution{T, N}

Abstract interface for no-time eigenvalue problem solutions. Concrete subtypes store the computed eigenvalues in u, follow the AbstractNoTimeSolution contract, and should document where eigenvectors, residuals, the original problem, algorithm, return code, and solver statistics are stored.

source
SciMLBase.AbstractNonlinearSolutionType
abstract type AbstractNonlinearSolution{T, N} <: SciMLBase.AbstractNoTimeSolution{T, N}

Abstract interface for no-time nonlinear equation solutions. Concrete subtypes store the root or fixed point in u and the residual in a solver-specific resid field when available. These solutions follow the AbstractNoTimeSolution contract and commonly provide prob, alg, retcode, original, bracket endpoints for interval methods, and stats.

source
SciMLBase.AbstractIntegralSolutionType
abstract type AbstractIntegralSolution{T, N} <: SciMLBase.AbstractNoTimeSolution{T, N}

Abstract interface for no-time integral or quadrature solutions. Concrete subtypes store the estimated integral in u, follow the AbstractNoTimeSolution contract, and commonly provide resid, prob, alg, retcode, chi, and stats fields for solver diagnostics.

source
SciMLBase.AbstractOptimizationSolutionType
abstract type AbstractOptimizationSolution{T, N} <: SciMLBase.AbstractNoTimeSolution{T, N}

Abstract interface for no-time optimization solutions. Concrete subtypes store the optimizer or minimizer in u and follow the AbstractNoTimeSolution contract. Optimization solutions commonly expose alg, objective, retcode, original, stats, and a cache that supplies the problem function and parameters for symbolic indexing.

source
SciMLBase.AbstractAnalyticalSolutionType
abstract type AbstractAnalyticalSolution{T, N, S} <: SciMLBase.AbstractTimeseriesSolution{T, N, S}

Abstract interface for analytical time-series solutions. These solutions follow the AbstractTimeseriesSolution contract and are used when the solution values are generated from or compared against an analytical representation of the problem. Plotting and error-calculation code may use analytical solution metadata stored on the concrete solution or its problem.

source
SciMLBase.AbstractODESolutionType
abstract type AbstractODESolution{T, N, S} <: SciMLBase.AbstractTimeseriesSolution{T, N, S}

Abstract interface for ordinary differential equation time-series solutions. Concrete subtypes follow the AbstractTimeseriesSolution contract and typically provide saved states u, saved times t, interpolation data interp, the original problem prob, the algorithm alg, solver stats, a retcode, and optional analytical values, dense-output data, discrete parameter time-series, residuals, and wrapped-solver output.

source
SciMLBase.AbstractDDESolutionType
abstract type AbstractDDESolution{T, N, S} <: SciMLBase.AbstractODESolution{T, N, S}

Abstract interface for delay differential equation time-series solutions. These solutions follow the AbstractODESolution contract and add delay-system semantics through their problem, history function, and interpolation data.

source
SciMLBase.AbstractRODESolutionType
abstract type AbstractRODESolution{T, N, S} <: SciMLBase.AbstractODESolution{T, N, S}

Abstract interface for random ordinary differential equation time-series solutions. These solutions follow the AbstractODESolution contract and also carry the saved or reconstructible noise path used by the RODE, commonly through a field or callable object such as sol.W.

source
SciMLBase.AbstractDAESolutionType
abstract type AbstractDAESolution{T, N, S} <: SciMLBase.AbstractODESolution{T, N, S}

Abstract interface for differential-algebraic equation time-series solutions. These solutions follow the AbstractODESolution contract while representing states that satisfy both differential and algebraic residual conditions. Concrete subtypes should document any stored residuals, initialization data, or consistent-initial-condition metadata they expose.

source
SciMLBase.AbstractPDETimeSeriesSolutionType
abstract type AbstractPDETimeSeriesSolution{T, N, S, D} <: SciMLBase.AbstractTimeseriesSolution{T, N, S}

Abstract interface for PDE solutions with a saved time axis. These solutions follow the AbstractTimeseriesSolution contract and additionally carry discretization metadata. Concrete subtypes should provide disc_data, original_sol, ivdomain, ivs, and dvs fields so downstream discretizer packages can recover the PDE variables, domains, and original discretized solve. Callable interpolation is discretizer-specific and should be implemented by the package that owns the metadata type.

source
SciMLBase.AbstractPDENoTimeSolutionType
abstract type AbstractPDENoTimeSolution{T, N, S, D} <: SciMLBase.AbstractNoTimeSolution{T, N}

Abstract interface for PDE solutions without a saved time axis. These solutions follow the AbstractNoTimeSolution contract and additionally carry discretization metadata. Concrete subtypes should provide disc_data, original_sol, ivdomain, ivs, and dvs fields so downstream discretizer packages can recover the PDE variables, domains, and original discretized solve. Callable evaluation is discretizer-specific and should be implemented by the package that owns the metadata type.

source
SciMLBase.AbstractSensitivitySolutionType
abstract type AbstractSensitivitySolution{T, N, S} <: SciMLBase.AbstractTimeseriesSolution{T, N, S}

Abstract interface for time-series solutions that store sensitivity quantities. Sensitivity solutions follow the AbstractTimeseriesSolution contract, but their saved values represent derivatives or augmented sensitivity states rather than only the primal state. Concrete subtypes should document which sensitivity method produced the values, how the sensitivity axes are arranged in u, and whether interpolation supports derivative queries.

source

Concrete Solution Reference

See Concrete Solution Types for the concrete result containers returned by linear, nonlinear, integral, optimization, and differential-equation solvers. Ensemble and PDE solution types are documented with their respective interfaces.

Solution Statistics

SciMLBase.DEStatsType
mutable struct DEStats

Counters collected by a differential equation solver while constructing a solution.

DEStats is stored in the stats field of differential equation solutions when the solver reports work counters. The counters are intended for diagnostics and performance analysis; they are not part of the mathematical solution. Solvers that do not track a counter should leave it at the package's documented default, commonly 0 or the DEStats() sentinel value.

Fields

  • nf: Number of function evaluations. For split functions such as an implicit-explicit SplitFunction, this counts evaluations of the first function.
  • nf2: Number of evaluations of the second function for split functions. This is usually zero for non-split problems.
  • nw: Number of W = I - gamma*J or W = I/gamma - J matrices constructed during the solving process.
  • nsolve: Number of linear solves required during the integration.
  • njacs: Number of Jacobians constructed during the integration.
  • nnonliniter: Total nonlinear solver iterations.
  • nnonlinconvfail: Number of nonlinear solver convergence failures.
  • nfpiter: Total fixed-point solver iterations.
  • nfpconvfail: Number of fixed-point solver convergence failures.
  • ncondition: Number of callback condition-function calls.
  • naccept: Number of accepted steps.
  • nreject: Number of rejected steps.
  • maxeig: Maximum eigenvalue estimate recorded by algorithms that compute one, such as some auto-switching methods.
source
SciMLBase.NLStatsType
mutable struct NLStats

Counters collected by a nonlinear equation solver while constructing a solution.

NLStats is stored in the stats field of nonlinear and steady-state solutions when the solver reports work counters. The fields are intended for diagnostics, benchmarking, and convergence analysis. Solver packages should document whether a counter is exact, unavailable, or accumulated across nested solves.

Fields

  • nf: Number of function evaluations.
  • njacs: Number of Jacobians created during the solve.
  • nfactors: Number of factorizations of Jacobians or linear-system matrices.
  • nsolve: Number of linear solves required by the nonlinear method.
  • nsteps: Total number of nonlinear solver iterations or accepted nonlinear steps, according to the solver's iteration model.
source
SciMLBase.OptimizationStatsType
struct OptimizationStats

Stores the optimization run's statistics that is returned in the stats field of the OptimizationResult.

Fields

  • iterations: number of iterations
  • time: time taken to run the solver
  • fevals: number of function evaluations
  • gevals: number of gradient evaluations
  • hevals: number of hessian evaluations

Default values for all the field are set to 0 and hence even when you might expect non-zero values due to unavailability of the information from the solver it would be 0.

source

Solution Construction and Errors

SciMLBase.build_solutionFunction
build_solution(prob, alg, args...; kwargs...)

Construct the solution object returned by a SciML solver for prob solved with alg.

Solver packages extend build_solution for the problem and algorithm families they own so that direct solver implementations can share the same solution construction path. Methods should attach the original problem, algorithm, ReturnCode, residual or error information, solver statistics, dense interpolation data, and saved values expected by the corresponding AbstractSciMLSolution interface.

The accepted positional arguments are problem-family specific. Implementations should document the argument order they expect and should preserve common SciML solution behavior such as array indexing, symbolic indexing, and retcode inspection.

source
SciMLBase.calculate_solution_errors!Function
calculate_solution_errors!(sol; fill_uanalytic = true, timeseries_errors = true, dense_errors = true)

Compute the error estimates of a solution against the analytical solution of its problem (sol.prob.f.analytic) and store them in sol.errors. With fill_uanalytic = true, the analytical solution values are first filled into sol.u_analytic. timeseries_errors controls computation of errors at the saved time points and dense_errors controls computation of errors using the dense interpolation. Used by solutions that have a known analytic solution (e.g. for convergence testing).

source
SciMLBase.solution_new_retcodeFunction
solution_new_retcode(sol, retcode)

Return a copy of the solution sol with its return code replaced by retcode. The solution is otherwise left unchanged; this is used to update the retcode of an existing solution (e.g. when an integrator finishes and the final status becomes known).

Solver packages extend this generic for the solution types they own. Methods should return the same solution type with its return code replaced and preserve its other data.

source
SciMLBase.sensitivity_solutionFunction
sensitivity_solution(sol, u)
sensitivity_solution(sol, u, t)

Return a solution with state values replaced by sensitivity-compatible values.

Arguments

  • sol: A nonlinear, ODE, or RODE solution whose solver metadata should be preserved.
  • u: Replacement state values, ordered consistently with the returned solution's saved values.
  • t: Replacement saved times for time-dependent solutions. This argument is not used by nonlinear solutions.

Returns

A solution of the same family as sol, preserving problem, algorithm, return-code, and solver metadata while replacing its state values and, for time-dependent solutions, saved times. Time-dependent solutions enable interpolation sensitivity mode.

Developer Interface

Sensitivity packages call this after differentiating a solve to construct a result that retains the original solution's SciML interface. Methods must preserve all metadata not explicitly replaced and must require u and t to have compatible saved-value layouts. Packages defining a new public solution family may add a narrowly dispatched method when that family has a distinct reconstruction invariant.

source

Interpolation Types

SciMLBase.AbstractDiffEqInterpolationType
abstract type AbstractDiffEqInterpolation

Base interface for interpolation objects carried by SciML solutions. Concrete interpolation types describe how saved values are reconstructed between stored solution points.

Concrete subtypes should document the interpolation order, whether derivatives are available, the cache data they need from the solution, and which interpolation or interpolation! methods they implement. Interpolation objects are usually solver-owned implementation details, but solution types use this supertype to expose consistent stripping and summary behavior.

source
SciMLBase.ConstantInterpolationType
struct ConstantInterpolation{T1, T2} <: SciMLBase.AbstractDiffEqInterpolation

Piecewise constant interpolation data for time-series SciML solutions.

ConstantInterpolation stores saved independent-variable values t and saved solution values u. It reconstructs values by holding the selected saved value constant across each interval, with the interval side controlled by the interpolation continuity argument. Derivative requests return zero for the piecewise constant reconstruction where supported.

The sensitivitymode flag records whether sensitivity-aware behavior has been enabled for the interpolation object. Constant interpolation is useful for discrete-time states, zero-order-hold outputs, and solution objects whose saved values should not be smoothed between time points.

source
SciMLBase.LinearInterpolationType
struct LinearInterpolation{T1, T2} <: SciMLBase.AbstractDiffEqInterpolation

First-order linear interpolation data for time-series SciML solutions.

LinearInterpolation stores saved independent-variable values t and saved solution values u. It reconstructs values between adjacent saved points with piecewise linear interpolation and supports first-derivative requests by returning the segment slope where that operation is defined.

The sensitivitymode flag records whether sensitivity-aware behavior has been enabled for the interpolation object. Linear interpolation is the standard fallback when dense solver-specific interpolation is unavailable but saved values can still be connected between time points.

source
SciMLBase.HermiteInterpolationType
struct HermiteInterpolation{T1, T2, T3} <: SciMLBase.AbstractDiffEqInterpolation

Third-order Hermite interpolation data for time-series SciML solutions.

HermiteInterpolation stores saved independent-variable values t, saved solution values u, and saved derivatives du. It is callable through the solution interpolation interface and supports derivative requests up to the cubic polynomial's third derivative. Differential equation solvers use this when they can provide derivative information at saved points and want solution calls such as sol(t) to use Hermite reconstruction.

The sensitivitymode flag records whether the interpolation object has been marked for sensitivity-aware behavior. Sensitivity handling may restrict which interpolation paths are available; callers usually set this indirectly through solver or sensitivity-algorithm options rather than constructing it manually.

source
SciMLBase.BasicInterpolationType
struct BasicInterpolation{tType, uType, duType} <: SciMLBase.AbstractDiffEqInterpolation

Runtime-switched fallback interpolation for time-series SciML solutions.

BasicInterpolation is a single concrete type that covers both dense and non-dense solutions, choosing the reconstruction at runtime through the dense field rather than by the object's type: when dense is true it reconstructs values with third-order Hermite interpolation (using the stored derivatives du), and when dense is false it uses piecewise linear interpolation. It stores saved independent-variable values t, saved solution values u, and saved derivatives du, and it is callable through the standard solution interpolation interface.

The point of this type is type invariance: the concrete type of a BasicInterpolation does not depend on whether the solve was dense. A solver wrapper that emits BasicInterpolation for both dense and non-dense solves produces solutions whose concrete type is identical across those save settings, so downstream code can hold a concretely-typed solution field and reassign it across re-solves with different save arguments (for example checkpointing in adjoint sensitivity analysis) without a type change.

Preserving that invariance requires that du always be the same container type regardless of dense. When constructing a non-dense BasicInterpolation, pass an empty container of the same type that a dense solve would use (e.g. an empty Vector of the derivative element type) rather than nothing, so that typeof is stable across dense and non-dense solutions of the same problem. The non-dense path never reads du, so its contents are irrelevant when dense = false; only its type matters.

The sensitivitymode flag records whether sensitivity-aware behavior has been enabled; as with the other interpolation types it is normally set indirectly through solver or sensitivity-algorithm options rather than manually.

Both modes evaluate the same interpolation kernels used by HermiteInterpolation and LinearInterpolation, so results are identical to using those types directly in the corresponding mode. The dense branch happens inside the interpolation methods — no wrapper object is constructed and both branches return values of the same type, so calls are type-stable and allocation-free on the in-place paths.

The guesser field holds a FindFirstFunctions.Guesser over t that warm-starts the interval search of scalar interpolation calls (its only state is a Ref, so the struct stays immutable and the concrete type still depends only on the container types). Correlated access patterns — adjoint solves sweeping time monotonically, saveat post-processing — thereby skip the per-call bisection. The guesser decides at construction whether t is evenly spaced enough for a linear-extrapolation guess; either way every lookup returns exact searchsortedfirst results, so the guess quality only affects speed, never values. Constructors build it automatically; pass one explicitly only to share state across reconstructions (as enable_interpolation_sensitivitymode does).

source
SciMLBase.SensitivityInterpolationType
struct SensitivityInterpolation

Marker type indicating that a solution's standard dense interpolation was disabled because the solution was produced during sensitivity analysis.

Some non-AD sensitivity algorithms cannot safely differentiate through the solver's native dense interpolation. Such solutions use SensitivityInterpolation as their interp field so interpolation attempts can produce a targeted error message instead of silently returning values from an unsupported interpolation path. Save the needed time points directly with saveat, use dense = false when linear or constant interpolation is sufficient, or choose a sensitivity algorithm that differentiates through the solver when dense interpolation is required.

source
SciMLBase.enable_interpolation_sensitivitymodeFunction
enable_interpolation_sensitivitymode(interp)

Return an interpolation object configured for sensitivity analysis.

Solver packages that own a concrete AbstractDiffEqInterpolation subtype may specialize this hook when sensitivity analysis requires a different interpolation behavior. Preserve the interpolation data where possible, but mark or replace paths that are invalid for a reconstructed adjoint solution. The fallback leaves interpolation types without sensitivity-specific behavior unchanged; nothing passes through as nothing.

Developer API, not user API

Sensitivity implementations may extend this hook. Application code should select a sensitivity algorithm rather than call it directly.

Example

function SciMLBase.enable_interpolation_sensitivitymode(interp::MyInterpolation)
    return MyInterpolation(interp.t, interp.u; sensitivitymode = true)
end
source

Symbolic Utilities

SciMLBase.getindepsymFunction
getindepsym(prob_or_sol_or_integrator)

Return the primary symbolic independent variable for a problem, solution, or integrator.

For problems, this queries SymbolicIndexingInterface.independent_variable_symbols on the problem's function and returns the first symbol when one is available. For solutions and integrators, the query delegates to the underlying problem. If no symbolic independent variable is defined, the result is nothing.

Use getindepsym_defaultt when caller code needs a plotting or display fallback for time-dependent solutions that do not carry symbolic metadata.

source
SciMLBase.getindepsym_defaulttFunction
getindepsym_defaultt(sol)

Return the primary symbolic independent variable, falling back to :t.

This is a display and plotting helper for code paths that historically assumed a time variable is always present. It returns getindepsym(sol) when symbolic metadata defines an independent variable and :t otherwise. Use getindepsym when nothing is the correct representation for "no symbolic independent variable".

source