### Example: Conditional stopping Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/api-reference/callbacks.md This example demonstrates how to use DiscreteCallback to terminate the ODE solve when a certain condition is met. ```APIDOC ## Example: Conditional stopping ```julia function condition_stop(u, t, integrator) return t >= 5.0 # Stop at t=5.0 end function affect_stop!(integrator) terminate!(integrator) end cb = DiscreteCallback(condition_stop, affect_stop!) sol = solve(prob, Tsit5(), callback=cb) ``` ``` -------------------------------- ### Example: Simple DAE System Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/api-reference/other_problems.md Demonstrates solving a simple DAE system using DAEProblem. The example defines a system where one equation is differential (u1' = 2u1) and the other is algebraic (u2 = u1² - 1). ```julia using DifferentialEquations # Simple DAE: u1' = 2u1, u2 = u1² - 1 function f(out, du, u, p, t) out[1] = du[1] - 2*u[1] out[2] = u[2] - u[1]^2 + 1 end u0 = [1.0, 0.0] du0 = [2.0, 0.0] prob = DAEProblem(f, du0, u0, (0.0, 1.0)) sol = solve(prob, Rodas5P()) ``` -------------------------------- ### Example: Trigger at specific times Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/api-reference/callbacks.md This example shows how to trigger a callback at a predefined set of discrete time points. ```APIDOC ## Example: Trigger at specific times ```julia # Trigger at t = 0.5, 1.0, 1.5, ..., 10.0 target_times = 0.5:0.5:10.0 time_index = 1 function condition_at_times(u, t, integrator) global time_index if time_index <= length(target_times) && t >= target_times[time_index] return true end return false end function affect_at_times!(integrator) global time_index println("Event at t=$(integrator.t)") time_index += 1 end cb = DiscreteCallback(condition_at_times, affect_at_times!) sol = solve(prob, Tsit5(), callback=cb) ``` ``` -------------------------------- ### Continuous Callback with Rootfinding Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/types.md Example of using ContinuousCallback with a specified rootfinding behavior. Requires DifferentialEquations and SciMLBase. ```julia using DifferentialEquations, SciMLBase condition(u, t, integrator) = u - 1.0 affect!(integrator) = println("Root found at $(integrator.t)") # Find root with left-limit behavior cb = ContinuousCallback( condition, affect!, rootfind=SciMLBase.LeftRootFind ) sol = solve(prob, Tsit5(), callback=cb) ``` -------------------------------- ### Event-Driven Integration Setup Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/configuration.md Configure event-driven integration using callbacks. Define a condition and an affect function to handle events. Specify tstops to force integration stops. ```julia using DifferentialEquations condition(u, t, integrator) = u - 1.0 function affect!(integrator) println("Event at $(integrator.t)") set_proposed_dt!(integrator, 0.01) end cb = ContinuousCallback(condition, affect!) sol = solve( prob, Tsit5(), callback=cb, tstops=[0.5, 1.5] # Force stops at these times ) ``` -------------------------------- ### Example: Damped Oscillator with SecondOrderODEProblem Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/api-reference/other_problems.md Illustrates solving a damped oscillator using SecondOrderODEProblem. The example defines the second derivative function and sets initial conditions and parameters for the damping ratio and natural frequency. ```julia using DifferentialEquations # Damped oscillator: d²u/dt² = -2ζω₀(du/dt) - ω₀²u function f(ddu, du, u, p, t) ζ, ω₀ = p ddu .= -2 * ζ * ω₀ * du .- ω₀^2 * u end u0 = 1.0 # Initial displacement du0 = 0.0 # Initial velocity tspan = (0.0, 10.0) p = (0.5, 1.0) # Damping ratio, natural frequency prob = SecondOrderODEProblem(f, du0, u0, tspan, p) sol = solve(prob, Tsit5()) ``` -------------------------------- ### Solve Stiff ODE with Rodas5P Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/api-reference/algorithms.md Example of solving a stiff ODE problem using the Rodas5P solver. This demonstrates setting up an ODEProblem and then solving it with the specified stiff solver. ```julia function rober!(du, u, p, t) y₁, y₂, y₃ = u k₁, k₂, k₃ = p du[1] = -k₁*y₁ + k₃*y₂*y₃ du[2] = k₁*y₁ - k₂*y₂^2 - k₃*y₂*y₃ du[3] = k₂*y₂^2 end prob = ODEProblem(rober!, [1.0, 0.0, 0.0], (0.0, 1e5), (0.04, 3e7, 1e4)) sol = solve(prob, Rodas5P()) ``` -------------------------------- ### Example: Linear + Nonlinear Split ODE Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/api-reference/other_problems.md Shows how to solve an ODE with additive splitting using SplitODEProblem. The example separates a linear term (-u) and a nonlinear term (u^2). ```julia using DifferentialEquations # Linear + nonlinear splitting f1(u, p, t) = -u # Linear part f2(u, p, t) = u^2 # Nonlinear part u0 = 0.5 prob = SplitODEProblem(f1, f2, u0, (0.0, 1.0)) sol = solve(prob, Tsit5()) ``` -------------------------------- ### Quick Start ODE Problem Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/INDEX.md This snippet demonstrates the basic workflow for solving an Ordinary Differential Equation (ODE) using DifferentialEquations.jl. It involves defining the ODE function, setting up an ODEProblem, choosing an algorithm (Tsit5), and solving the problem. ```julia using DifferentialEquations f(u, p, t) = 1.01 * u prob = ODEProblem(f, 0.5, (0.0, 1.0)) sol = solve(prob, Tsit5()) ``` -------------------------------- ### Example: Trigger every N steps Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/api-reference/callbacks.md This example demonstrates how to use DiscreteCallback to trigger an affect function every N timesteps by checking a counter. ```APIDOC ## Example: Trigger every N steps ```julia using DifferentialEquations f(u, p, t) = 1.01 * u prob = ODEProblem(f, 0.5, (0.0, 10.0)) counter = 0 function discrete_condition(u, t, integrator) global counter counter += 1 return counter % 100 == 0 # Trigger every 100 steps end function discrete_affect!(integrator) println("Step $(integrator.step_number) at t=$(integrator.t)") end cb = DiscreteCallback(discrete_condition, discrete_affect!) sol = solve(prob, Tsit5(), callback=cb) ``` ``` -------------------------------- ### Example: Ensemble Problem with Parameter Variation Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/api-reference/other_problems.md Illustrates creating and solving an EnsembleProblem where the parameter `p` is varied for each trajectory. This example uses `EnsembleThreads()` for parallel execution. ```julia using DifferentialEquations f(u, p, t) = p * u u0 = 1.0 tspan = (0.0, 1.0) # Template problem prob = ODEProblem(f, u0, tspan, 1.01) # Vary parameters function prob_func(prob, i, repeat) remake(prob, p=1.0 + 0.01*i) end ensemble_prob = EnsembleProblem( prob, trajectories=10, prob_func=prob_func ) # Solve ensemble sols = solve(ensemble_prob, Tsit5(), EnsembleThreads()) ``` -------------------------------- ### Example: Harmonic Oscillator with DynamicalODEProblem Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/api-reference/other_problems.md Demonstrates solving a harmonic oscillator using DynamicalODEProblem. This involves defining the dynamics for velocity and position separately and then solving the problem. ```julia using DifferentialEquations # Harmonic oscillator: d²u/dt² = -u function f1(dv, v, u, p, t) # velocity dynamics dv .= -u end function f2(du, v, u, p, t) # position dynamics du .= v end u0 = [1.0] # Initial position v0 = [0.0] # Initial velocity tspan = (0.0, 2π) prob = DynamicalODEProblem(f1, f2, v0, u0, tspan) sol = solve(prob, Tsit5()) ``` -------------------------------- ### Handling DtNaN Return Code Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/errors.md Demonstrates how to check for and handle the `ReturnCode.DtNaN` which occurs when the timestep becomes NaN. Includes an example of a problematic function and its fix. ```julia using DifferentialEquations # Problematic function function bad_f(u, p, t) sqrt(u - 1) # Returns NaN for u < 1 end # Check initial condition u0 = 0.5 p = 1.0 t0 = 0.0 # bad_f(u0, p, t0) # This returns NaN! # Fixed function function good_f(u, p, t) max(sqrt(u - 1), 0) # Clamp to prevent NaN end prob = ODEProblem(good_f, u0, (0.0, 1.0), p) sol = solve(prob, Tsit5()) if sol.retcode == ReturnCode.DtNaN println("ERROR: dt became NaN") println("Check f(u0, p, t0) for NaN or Inf values") end ``` -------------------------------- ### Handling NoConvergence Return Code with Custom Jacobian Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/errors.md Demonstrates how to address `ReturnCode.NoConvergence` by providing an accurate Jacobian function for stiff solvers. This code snippet shows the setup for an ODE problem with a custom Jacobian. ```julia using DifferentialEquations # For stiff solvers, provide accurate Jacobian function f(u, p, t) [p[1]*u[1]; -p[2]*u[2]] end function jac(u, p, t) [p[1] 0; 0 -p[2]] end ff = ODEFunction(f, jac=jac) prob = ODEProblem(ff, [1.0, 1.0], (0.0, 1.0), [0.5, 2.0]) sol = solve(prob, Rodas5P()) if sol.retcode == ReturnCode.NoConvergence println("Failed to converge") # Try with explicit Jacobian or different solver end ``` -------------------------------- ### Instantiate AbstractODEProblem Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/types.md Example of creating an ODEProblem, which is a subtype of AbstractODEProblem. The type parameters indicate the types of u0, tspan, and whether the function is in-place. ```julia using DifferentialEquations f(u, p, t) = -u u0 = 1.0 tspan = (0.0, 1.0) prob::AbstractODEProblem = ODEProblem(f, u0, tspan) # Type is ODEProblem{Float64, Tuple{Float64, Float64}, false, ...} ``` -------------------------------- ### Check ODESolution Return Code Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/api-reference/odesolution.md After solving an ODEProblem, check the `sol.retcode` field to determine the outcome of the solver. This example shows how to check for common return codes like Success, Terminated, DtNaN, and MaxIters. ```julia using DifferentialEquations sol = solve(prob, Tsit5()) if sol.retcode == ReturnCode.Success println("Solve succeeded") elseif sol.retcode == ReturnCode.Terminated println("Solve terminated by callback") elseif sol.retcode == ReturnCode.DtNaN println("Timestep became NaN") elseif sol.retcode == ReturnCode.MaxIters println("Maximum iterations exceeded") end ``` ```julia # Or check if any successful code if SciMLBase.successful_retcode(sol) println("Success (any successful outcome)") end ``` -------------------------------- ### Use Stiff Solvers for Stiff Problems Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/errors.md Explains how stiffness can lead to `MaxIters` or slow integration when a non-stiff solver is used. Demonstrates the fix by switching to an appropriate stiff solver. ```julia # Stiff problem with non-stiff solver prob = ODEProblem(stiff_f, u0, tspan) sol = solve(prob, Tsit5()) # Wrong choice # Fix: Use stiff solver sol = solve(prob, Rodas5P()) ``` -------------------------------- ### init Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/api-reference/utilities.md Initializes the integrator for solving differential equations. ```APIDOC ## init ### Description Initialize integrator. ### Method Not specified (likely a function call in the library) ### Endpoint Not applicable (library function) ### Parameters Not specified in the source text. ### Request Example Not applicable. ### Response Not specified in the source text. ``` -------------------------------- ### Initialize FBDF Solver Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/api-reference/algorithms.md Initializes the FBDF solver, a variable-order (up to 5) multistep stiff solver based on Backward Differentiation Formulas. It is efficient for moderately stiff problems over long time intervals and requires Jacobian computation. ```julia FBDF() ``` -------------------------------- ### init Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/api-reference/utilities.md Initializes an integrator object for step-by-step integration, allowing for manual control over the solving process. ```APIDOC ## init Initialize an integrator object for step-by-step integration. ### Function Signature ```julia integrator = init(prob, alg; kwargs...) ``` ### Parameters - `prob` (Problem): Problem to solve. - `alg` (Algorithm): Solver algorithm. - `kwargs` (Keyword args): Same options as `solve`. ### Return Integrator object for manual stepping. ### Example ```julia using DifferentialEquations f(u, p, t) = 1.01 * u prob = ODEProblem(f, 0.5, (0.0, 1.0)) # Initialize integrator integrator = init(prob, Tsit5()) # Check initial state println("t0 = ", integrator.t) println("u0 = ", integrator.u) # Take steps manually for i in 1:10 step!(integrator) println("Step ", i, ": t=", integrator.t, ", u=", integrator.u) end ``` ``` -------------------------------- ### Interpolate ODE Solution at Time t Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/api-reference/odesolution.md Call the solution object with a time `t` to get the interpolated solution. Requires `dense=true` which is the default for most algorithms. ```julia u_at_t = sol(t) # Interpolate at time t ``` -------------------------------- ### Initialize Rodas5P Solver Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/api-reference/algorithms.md Initializes the Rodas5P solver, a 5th order Rosenbrock method recommended for stiff ODE problems. It requires Jacobian computation and offers good dense output support. ```julia Rodas5P() ``` -------------------------------- ### In-place Jacobian Specification Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/api-reference/odefunction.md Example of defining an in-place ODE function and its Jacobian for use with ODEFunction. In-place functions modify their arguments directly, which can be more efficient. ```julia using DifferentialEquations function f!(du, u, p, t) du[1] = 1.01*u[1] du[2] = -0.2*u[2] end function jac!(J, u, p, t) J[1,1] = 1.01 J[1,2] = 0 J[2,1] = 0 J[2,2] = -0.2 end ff = ODEFunction(f!, jac=jac!) prob = ODEProblem(ff, [1.0, 0.5], (0.0, 1.0)) sol = solve(prob, Rodas5P()) ``` -------------------------------- ### Out-of-place Jacobian Specification Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/api-reference/odefunction.md Example of defining an out-of-place ODE function and its Jacobian for use with ODEFunction. This allows solvers to utilize optimized Jacobian-based methods. ```julia using DifferentialEquations f(u, p, t) = [1.01*u[1]; -0.2*u[2]] function jac(u, p, t) [1.01 0 0 -0.2] end ff = ODEFunction(f, jac=jac) prob = ODEProblem(ff, [1.0, 0.5], (0.0, 1.0)) sol = solve(prob, Rodas5P()) ``` -------------------------------- ### init() Function Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/COMPLETION_SUMMARY.txt Initializes the state of the differential equation solver without performing the full solve. ```APIDOC ## init() init(prob, alg, args...; kwargs...) ### Description Initializes the state of the differential equation solver. ### Method `init` ### Parameters Similar to `solve`, `init` accepts a problem, algorithm, and various keyword arguments for configuration. #### Problem Definition - **prob** (ODEProblem, DAEProblem, etc.) - The differential equation problem. - **alg** (AbstractAlgorithm) - The algorithm to use. #### Solver Options (kwargs) - **dt** (Float64) - Initial time step. - **abstol** (Float64) - Absolute tolerance. - **reltol** (Float64) - Relative tolerance. ### Return - **uip** (AbstractODEIntegrator) - The initialized integrator object. ### Request Example ```julia using DifferentialEquations function f(du, u, p, t) du .= u end prob = ODEProblem(f, [1.0], (0.0, 1.0)) integrator = init(prob, Tsit5(), abstol=1e-8, reltol=1e-8) ``` ### Response #### Success Response (200) - **integrator** (AbstractODEIntegrator) - The initialized integrator. ``` -------------------------------- ### Get Solution Statistics Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/api-reference/odesolution.md Access statistics about the ODE solution process, such as the number of function evaluations and accepted steps. Useful for understanding solver performance. ```julia using DifferentialEquations sol = solve(prob, Tsit5()) # Check solution statistics stats = sol.destats println("Number of steps: $(stats.nf)") # Function evaluations println("Accepted steps: $(stats.naccept)") ``` -------------------------------- ### AutoTsit5 Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/api-reference/algorithms.md AutoTsit5() is an adaptive non-stiff solver selector that automatically switches between Tsit5 and higher-order methods based on accuracy requirements. The 'pad' parameter controls the transition criterion and it is useful when the problem's stiffness is unknown. ```APIDOC ## AutoTsit5 ### Description An adaptive non-stiff solver selector that automatically switches between `Tsit5` and higher-order methods based on accuracy requirements. The `pad` parameter controls the transition criterion, making it useful when the problem stiffness is unknown. ### Method `AutoTsit5(; pad=0.5)` ### Parameters - **pad** (Float64) - Optional - Controls the transition criterion for switching methods. Defaults to 0.5. ### Request Example ```julia # Example usage within solve function sol = solve(prob, AutoTsit5(pad=0.7)) ``` ### Response - **sol** (ODESolution) - The solution object containing the time series of the solution. ``` -------------------------------- ### Algorithm Selection for Stiff Problems Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/api-reference/solve.md This section details the algorithms available for solving stiff ordinary differential equations (ODEs). It highlights `Rodas5P()` as the recommended choice for stiff ODEs requiring dense output, `Rosenbrock23()` for a lower-order stiff solver, and `FBDF()` which is a multistep stiff method based on backward differentiation formulas. ```APIDOC ## Algorithm Selection for Stiff Problems ### Recommended for Dense Output - **`Rodas5P()`**: The recommended solver for stiff ODEs, especially when dense output is needed. ### Lower-Order Stiff Solver - **`Rosenbrock23()`**: A lower-order solver for stiff problems. ### Backward Differentiation Formula (BDF) - **`FBDF()`**: Implements a multistep stiff solver using backward differentiation formulas. ``` -------------------------------- ### Integrator Interface Functions Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/api-reference/callbacks.md Within callback affect! or condition functions, you can use these integrator functions to control the integration process. For example, terminate the integration or adjust the timestep. ```julia terminate!(integrator) # Stop integration at current point set_proposed_dt!(integrator, dt) # Request new timestep for next step add_tstop!(integrator, t) # Add a time to stop at later ``` -------------------------------- ### Handling InitializationFailure Return Code for DAEs Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/errors.md Illustrates how to handle `ReturnCode.InitializationFailure`, particularly for Differential-Algebraic Equations (DAEs). It emphasizes checking for consistent initial conditions. ```julia using DifferentialEquations # For DAE problems, ensure consistent initial conditions # F(du0, u0, p, t0) = 0 # Check consistency before solving u0 = [1.0, 0.0, 0.0] du0 = [2.0, 0.0, 0.0] # Verify: F(du0, u0, p, t0) ≈ 0 residual = dae_function(du0, u0, p, t0) if any(residual .!= 0) println("WARNING: Initial condition may be inconsistent") end prob = DAEProblem(f, du0, u0, tspan, p) sol = solve(prob, Rodas5P()) if sol.retcode == ReturnCode.InitializationFailure println("Could not initialize problem") # Try different initial conditions end ``` -------------------------------- ### Handling Generic Failure Return Code Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/errors.md Shows the basic handling for `ReturnCode.Failure`, a generic error code. It suggests enabling verbosity to get more detailed information about the failure. ```julia using DifferentialEquations sol = solve(prob, Tsit5()) if sol.retcode == ReturnCode.Failure println("Generic solver failure: $(sol.retcode)") # Enable verbosity for more information sol = solve(prob, Tsit5(), verbose=true) end ``` -------------------------------- ### Analyze ODE Solution Components and Interpolation Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/api-reference/odesolution.md Demonstrates how to extract individual component trajectories from an ODE solution and interpolate the solution at a fine grid of time points. Also shows how to find minimum and maximum values for a component. ```julia using DifferentialEquations f(u, p, t) = [-p[1]*u[1]; p[2]*u[2]] u0 = [1.0; 1.0] prob = ODEProblem(f, u0, (0.0, 10.0), [0.5; 0.3]) sol = solve(prob, Tsit5(), dense=true) # Analyze solution # Get component trajectories comp1 = [sol.u[i][1] for i in 1:length(sol.u)] comp2 = [sol.u[i][2] for i in 1:length(sol.u)] # Interpolate at fine grid t_fine = range(0.0, 10.0, length=1000) u1_fine = [sol(t)[1] for t in t_fine] u2_fine = [sol(t)[2] for t in t_fine] # Find min/max min_u1 = minimum(comp1) max_u1 = maximum(comp1) ``` -------------------------------- ### Initialize Rosenbrock23 Solver Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/api-reference/algorithms.md Initializes the Rosenbrock23 solver, a lower-order stiff solver that is more robust for very stiff problems or when higher-order methods encounter convergence issues. It requires Jacobian computation. ```julia Rosenbrock23() ``` -------------------------------- ### In-place vector ODE (Lorenz system) Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/api-reference/odeproblem.md Defines and solves the Lorenz system, a classic example of a chaotic system, using an in-place function definition. Requires the DifferentialEquations package. ```julia using DifferentialEquations function lorenz!(du, u, p, t) σ, ρ, β = p du[1] = σ * (u[2] - u[1]) du[2] = u[1] * (ρ - u[3]) - u[2] du[3] = u[1] * u[2] - β * u[3] end u0 = [1.0, 0.0, 0.0] tspan = (0.0, 100.0) p = (10.0, 28.0, 8/3) prob = ODEProblem(lorenz!, u0, tspan, p) sol = solve(prob, Tsit5()) ``` -------------------------------- ### ContinuousCallback: Event at Fixed Time Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/api-reference/callbacks.md This example demonstrates triggering a ContinuousCallback when the simulation time `t` crosses a specific value (1.0). The `affect!` function modifies the solution by doubling it at the event time. ```julia using DifferentialEquations f(u, p, t) = 1.01 * u u0 = 0.5 prob = ODEProblem(f, u0, (0.0, 2.0)) # Trigger when t crosses 1.0 condition(u, t, integrator) = t - 1.0 function affect!(integrator) println("Event at t=$(integrator.t), u=$(integrator.u)") integrator.u *= 2 # Double the solution at t=1.0 end cb = ContinuousCallback(condition, affect!) sol = solve(prob, Tsit5(), callback=cb) ``` -------------------------------- ### step! Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/api-reference/utilities.md Steps the integrator forward by one step. ```APIDOC ## step! ### Description Step integrator. ### Method Not specified (likely a function call in the library) ### Endpoint Not applicable (library function) ### Parameters Not specified in the source text. ### Request Example Not applicable. ### Response Not specified in the source text. ``` -------------------------------- ### ContinuousCallback: Event at Specific Solution Value Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/api-reference/callbacks.md This example shows how to trigger a ContinuousCallback when a component of the solution `u` reaches a specific value (1.0). The `affect!` function terminates the integration when the condition is met. ```julia # Trigger when u equals 1.0 condition(u, t, integrator) = u - 1.0 function affect!(integrator) println("u reached 1.0 at t=$(integrator.t)") terminate!(integrator) # Stop integration end cb = ContinuousCallback(condition, affect!) sol = solve(prob, Tsit5(), callback=cb) ``` -------------------------------- ### AutoTsit5() Adaptive Non-Stiff Solver Selector Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/api-reference/algorithms.md AutoTsit5() automatically switches between Tsit5 and higher-order methods based on accuracy requirements. The 'pad' parameter controls the transition criterion. ```julia AutoTsit5(; pad=0.5) ``` -------------------------------- ### Initialize Integrator with init Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/api-reference/utilities.md Initialize an integrator object for step-by-step integration using `init`. This allows for manual control over the integration process. Requires a Problem and a solver Algorithm. ```julia using DifferentialEquations f(u, p, t) = 1.01 * u prob = ODEProblem(f, 0.5, (0.0, 1.0)) # Initialize integrator integrator = init(prob, Tsit5()) # Check initial state println("t0 = $(integrator.t)") println("u0 = $(integrator.u)") # Take steps manually for i in 1:10 step!(integrator) println("Step $i: t=$(integrator.t), u=$(integrator.u)") end ``` -------------------------------- ### ODEProblem with solver options via kwargs Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/api-reference/odeproblem.md Demonstrates how to pass solver options directly to the ODEProblem constructor using keyword arguments. These options are applied by default in subsequent solve calls. ```julia prob = ODEProblem( f, u0, tspan, p; callback = ContinuousCallback(condition, affect!), saveat = 0.1, dense = true, maxiters = 1000 ) ``` -------------------------------- ### Solve Non-stiff ODE Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/INDEX.md Use Tsit5 for non-stiff ODEs. Ensure correct setup of the ODEProblem with function, initial conditions, time span, and parameters. Access solution times and values, or interpolate at specific points. ```julia using DifferentialEquations f(u, p, t) = p * u u0 = 1.0 tspan = (0.0, 10.0) p = 0.5 prob = ODEProblem(f, u0, tspan, p) sol = solve(prob, Tsit5(), reltol=1e-6, abstol=1e-8) # Access solution println(sol.t) # Times println(sol.u) # Values at times u_at_5 = sol(5.0) # Interpolate at t=5.0 ``` -------------------------------- ### ODEProblem with Implicit and Explicit Parameters Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/types.md Demonstrates creating an ODEProblem with implicit (NullParameters) and explicit parameters. The 'p' field holds the parameters. ```julia using DifferentialEquations f(u, p, t) = u # p not used # Implicit parameters prob1 = ODEProblem(f, 1.0, (0.0, 1.0)) # prob1.p is NullParameters() # Explicit parameters prob2 = ODEProblem(f, 1.0, (0.0, 1.0), [1.0, 2.0]) # prob2.p is [1.0, 2.0] ``` -------------------------------- ### step! Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/api-reference/utilities.md Advances the integrator by one time step. Allows for manual control over the integration process, including specifying the timestep and whether to stop at tstops. ```APIDOC ## step! ### Description Advances the integrator by one time step. Allows for manual control over the integration process, including specifying the timestep and whether to stop at tstops. ### Method ```julia step!(integrator, dt=integrator.dt, stop_at_tstop=false) ``` ### Parameters #### Path Parameters - `integrator` (Integrator) - Required - Integrator object from `init` - `dt` (Float) - Optional - Timestep (uses internal choice if not specified) - `stop_at_tstop` (Bool) - Optional - Stop at planned tstop times ### Example ```julia using DifferentialEquations f(u, p, t) = 1.01 * u prob = ODEProblem(f, 0.5, (0.0, 1.0)) integrator = init(prob, Tsit5()) # Manually step through integration times = [integrator.t] solutions = [integrator.u] while integrator.t < 1.0 step!(integrator) push!(times, integrator.t) push!(solutions, integrator.u) end println("Integrated from t=$(times[1]) to t=$(times[end])") println("Number of steps: $(length(times)-1)") ``` ``` -------------------------------- ### ContinuousCallback: Different Behavior on Up/Down Crossing Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/api-reference/callbacks.md This example demonstrates using separate `affect!` functions for upward and downward crossings of the condition. It uses the Lorenz system as the ODE problem and triggers when the first component `u[1]` crosses 10.0. ```julia function lorenz!(du, u, p, t) du[1] = 10.0 * (u[2] - u[1]) du[2] = u[1] * (28.0 - u[3]) - u[2] du[3] = u[1] * u[2] - (8/3) * u[3] end prob = ODEProblem(lorenz!, [1.0, 0.0, 0.0], (0.0, 10.0)) # Trigger when x-component equals 10 condition(u, t, integrator) = u[1] - 10.0 function affect_up!(integrator) println("Upward crossing at t=$(integrator.t)") end function affect_down!(integrator) println("Downward crossing at t=$(integrator.t)") end cb = ContinuousCallback(condition, affect_up!, affect_down!) sol = solve(prob, Tsit5(), callback=cb) ``` -------------------------------- ### Profile ODE Solver Performance Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/configuration.md Use `@time` and `@benchmark` to measure the execution time and performance of ODE solvers. Check solution statistics for detailed information. ```julia using DifferentialEquations using BenchmarkTools prob = ODEProblem(f, u0, tspan, p) # Benchmark solve @time sol = solve(prob, Tsit5()) # More detailed @benchmark solve($prob, Tsit5()) # Check statistics println(sol.destats) ``` -------------------------------- ### Return Codes and Success Check Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/api-reference/solve.md This section explains how to check the return code of a solution object (`sol.retcode`) to understand the outcome of the `solve` operation. It provides examples of checking for success, maximum iterations exceeded, and NaN timesteps, along with a helper function `SciMLBase.successful_retcode()` for a general success check. ```APIDOC ## Return Codes Check `sol.retcode` against `ReturnCode` constants to determine the solution status. ### Example Usage ```julia using DifferentialEquations sol = solve(prob, Tsit5()) if sol.retcode == ReturnCode.Success println("Solution succeeded") elseif sol.retcode == ReturnCode.MaxIters println("Iteration limit exceeded") elseif sol.retcode == ReturnCode.DtNaN println("Timestep became NaN") end # Using a helper function for general success check if SciMLBase.successful_retcode(sol) println("Success (any successful code)") end ``` ``` -------------------------------- ### Algorithm Selection for Non-stiff Problems Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/api-reference/solve.md This section outlines the recommended algorithms for solving non-stiff ordinary differential equations (ODEs). It includes the default `Tsit5()`, higher-order methods like `Vern6()` to `Vern9()` for smooth problems requiring high accuracy, and `AutoTsit5()` for automatic selection. ```APIDOC ## Algorithm Selection for Non-stiff Problems ### Recommended Defaults - **`Tsit5()`**: The recommended default solver for most non-stiff ODEs. ### Higher-Order Methods - **`Vern6()`, `Vern7()`, `Vern8()`, `Vern9()`**: These are higher-order methods suitable for smooth problems where high accuracy is critical. ### Automatic Selection - **`AutoTsit5()`**: This option automatically selects the most appropriate non-stiff method based on the problem characteristics. ``` -------------------------------- ### Solve and Analyze Non-stiff ODE Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/api-reference/odesolution.md Demonstrates solving a non-stiff ODE, accessing solution components, interpolating values, and plotting the results. Requires the Plots package for visualization. ```julia using DifferentialEquations, Plots f(u, p, t) = -p * u u0 = 1.0 tspan = (0.0, 10.0) p = 0.1 prob = ODEProblem(f, u0, tspan, p) sol = solve(prob, Tsit5()) # Access solution println("t = $(sol.t)") println("u = $(sol.u)") println("Status: $(sol.retcode)") # Interpolate u_at_5 = sol(5.0) println("u(5.0) = $u_at_5") # Plot plot(sol) ``` -------------------------------- ### Inspect Statistics on Failure Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/errors.md Shows how to inspect differential equation solver statistics, such as steps taken, accepted/rejected steps, and function evaluations, when a solution fails to converge. ```julia using DifferentialEquations sol = solve(prob, Tsit5()) if !successful_retcode(sol) println("Failed") println("Steps taken: $(sol.destats.naccept + sol.destats.nreject)") println("Accepted: $(sol.destats.naccept)") println("Rejected: $(sol.destats.nreject)") println("Function evals: $(sol.destats.nf)") end ``` -------------------------------- ### Ensure Consistent Initial Conditions for DAEs Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/errors.md Details the `InitializationFailure` error for Differential Algebraic Equations (DAEs), caused by inconsistent initial conditions with algebraic constraints. Shows how to fix by ensuring the initial state satisfies the constraints. ```julia # Inconsistent with algebraic constraint u0 = [1.0, 0.0] # But constraint: u[2] = u[1]^2 # Should have u0 = [1.0, 1.0] prob = DAEProblem(f, du0, u0, tspan) sol = solve(prob, Rodas5P()) # Fails # Fix: Ensure F(du0, u0, p, t0) = 0 u0 = [1.0, 1.0] # Consistent ``` -------------------------------- ### Utilities Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/INDEX.md Helper functions for manipulating problems, integrators, and controlling the integration process. ```APIDOC ## Utilities Utility functions for managing and controlling differential equation solves. ### `remake` **Purpose:** Create modified copy of problem. ### `reinit!` **Purpose:** Reset integrator state. ### `set_proposed_dt!` **Purpose:** Suggest timestep in callback. ### `add_tstop!` **Purpose:** Add future stop time. ### `terminate!` **Purpose:** Stop integration. ### `derivative_discontinuity!` **Purpose:** Mark discontinuity in solution. ``` -------------------------------- ### Step Through Integration Manually Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/api-reference/utilities.md Use `step!` to advance the integrator by one time step. This is useful for manual control over the integration process or for debugging. ```julia using DifferentialEquations f(u, p, t) = 1.01 * u prob = ODEProblem(f, 0.5, (0.0, 1.0)) integrator = init(prob, Tsit5()) # Manually step through integration times = [integrator.t] solutions = [integrator.u] while integrator.t < 1.0 step!(integrator) push!(times, integrator.t) push!(solutions, integrator.u) end println("Integrated from t=$(times[1]) to t=$(times[end])") println("Number of steps: $(length(times)-1)") ``` -------------------------------- ### Fast Non-Stiff Solve Configuration Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/configuration.md Achieve a fast solution for non-stiff problems by using loose tolerances and disabling dense output and saving every step. ```julia using DifferentialEquations # Loose tolerances for quick solution sol = solve( prob, Tsit5(), reltol=1e-4, abstol=1e-6, dense=false, save_everystep=false ) ``` -------------------------------- ### Enable Verbose Output for ODE Integration Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/errors.md Enable verbose logging during the ODE solution process to see step-by-step integration progress. This is useful for debugging. ```julia using DifferentialEquations sol = solve(prob, Tsit5(), verbose=true) # Shows step-by-step integration progress ``` -------------------------------- ### Set Reasonable Tolerances Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/errors.md Addresses issues like `MaxIters` or excessive runtime caused by setting integration tolerances too low, below machine epsilon. Shows the correct way to specify `reltol` and `abstol`. ```julia # Impossible tolerance to achieve sol = solve(prob, Tsit5(), reltol=1e-20) # Below machine epsilon # Fix: Use reasonable tolerances sol = solve(prob, Tsit5(), reltol=1e-8, abstol=1e-10) ``` -------------------------------- ### Handle Integration Termination with ReturnCode.Terminated Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/errors.md This snippet demonstrates how to handle cases where integration is halted by a callback, such as reaching a steady state or a specific event condition. It shows how to access the solution state at the point of termination. ```julia using DifferentialEquations condition(u, t, integrator) = u - 1.0 function affect!(integrator) println("Target reached at t=$(integrator.t)") terminate!(integrator) end cb = ContinuousCallback(condition, affect!) sol = solve(prob, Tsit5(), callback=cb) if sol.retcode == ReturnCode.Terminated println("Integration stopped by callback") final_time = sol.t[end] final_state = sol.u[end] end ``` -------------------------------- ### Algorithms Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/INDEX.md Details various numerical integration algorithms available for solving different types of differential equations, categorized by stiffness and accuracy. ```APIDOC ## Algorithms Numerical integration algorithms for solving differential equations. ### `Tsit5` **Type:** Explicit RK5(4) **Use Case:** Non-stiff (recommended) ### `Vern6`, `Vern7`, `Vern8`, `Vern9` **Type:** Explicit RK 6-9 **Use Case:** High-accuracy non-stiff ### `AutoTsit5` **Type:** Adaptive selector **Use Case:** Non-stiff, unknown precision ### `Rodas5P` **Type:** Rosenbrock 5 **Use Case:** Stiff (recommended) ### `Rosenbrock23` **Type:** Rosenbrock 2/3 **Use Case:** Very stiff ### `FBDF` **Type:** Backward differentiation **Use Case:** Very long integrations ``` -------------------------------- ### Tsit5 Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/api-reference/algorithms.md The Tsit5() solver is the default recommendation for most non-stiff ODE problems. It is a 5th order explicit Runge-Kutta method with a 4th order embedded method for error estimation, offering excellent efficiency on smooth problems with adaptive timestepping and dense output support. ```APIDOC ## Tsit5 ### Description A 5th order explicit Runge-Kutta method with a 4th order embedded method for error estimation. It is the default recommendation for most non-stiff ODE problems, known for its efficiency on smooth problems and support for adaptive timestepping and dense output. ### Method `Tsit5()` ### Parameters This method does not take any specific parameters beyond the standard `solve` function arguments. ### Request Example ```julia using DifferentialEquations f(u, p, t) = 1.01 * u prob = ODEProblem(f, 0.5, (0.0, 1.0)) sol = solve(prob, Tsit5()) ``` ### Response - **sol** (ODESolution) - The solution object containing the time series of the solution. ``` -------------------------------- ### Check Solver Return Code Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/types.md Demonstrates how to check the specific return code of a solver's solution. Ensure DifferentialEquations is imported. ```julia using DifferentialEquations sol = solve(prob, Tsit5()) # Check specific code if sol.retcode == ReturnCode.Success println("Solve succeeded") end # Check if any success code if SciMLBase.successful_retcode(sol) println("Success or controlled termination") end # Alternative syntax if sol.retcode == ReturnCode.Success # Process solution end ``` -------------------------------- ### Solve Stiff ODE with Event Detection Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/api-reference/odesolution.md Solves a stiff ODE system using Rodas5P and implements event detection with a ContinuousCallback to terminate integration when a condition is met. Useful for simulations that need to stop at specific states. ```julia using DifferentialEquations function rober!(du, u, p, t) y₁, y₂, y₃ = u k₁, k₂, k₃ = p du[1] = -k₁*y₁ + k₃*y₂*y₃ du[2] = k₁*y₁ - k₂*y₂^2 - k₃*y₂*y₃ du[3] = k₂*y₂^2 end u0 = [1.0, 0.0, 0.0] tspan = (0.0, 1e5) p = (0.04, 3e7, 1e4) # Callback to stop at specific value condition(u, t, integrator) = u[2] - 0.001 affect!(integrator) = terminate!(integrator) cb = ContinuousCallback(condition, affect!) prob = ODEProblem(rober!, u0, tspan, p) sol = solve(prob, Rodas5P(), callback=cb) if sol.retcode == ReturnCode.Terminated println("Integration stopped by callback") println("Final time: $(sol.t[end])") println("Final state: $(sol.u[end])") end ``` -------------------------------- ### Test ODE Solution Success and Properties Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/errors.md Verify that an ODE integration was successful by checking the return code and ensuring the solution contains valid, finite values and has more than one time point. ```julia using DifferentialEquations sol = solve(prob, Tsit5()) # Check return code @assert successful_retcode(sol) "Integration failed: $(sol.retcode)" # Verify solution properties @assert all(isfinite.(sol.u)) "Solution contains NaN/Inf" @assert length(sol.t) > 1 "Solution is empty" ``` -------------------------------- ### Solving Source: https://github.com/sciml/differentialequations.jl/blob/master/_autodocs/INDEX.md Core functions for initiating and controlling the integration process of differential equations. ```APIDOC ## Solving Functions for solving and managing the integration of differential equations. ### `solve` **Purpose:** Main solver function. ### `init` **Purpose:** Initialize integrator for manual stepping. ### `step!` **Purpose:** Take one integration step. ```