diff --git a/docs/pages.jl b/docs/pages.jl index 1b6f547e..c8f3d72e 100644 --- a/docs/pages.jl +++ b/docs/pages.jl @@ -3,6 +3,7 @@ pages = [ "Home" => "index.md", "output_saving.md", + "integrating.md", "timed_callbacks.md", "steady_state.md", "step_control.md", diff --git a/docs/src/integrating.md b/docs/src/integrating.md new file mode 100644 index 00000000..2cd7a74a --- /dev/null +++ b/docs/src/integrating.md @@ -0,0 +1,30 @@ +# Numerical Integration Callbacks + +Sometimes one may want to solve an integral simultaniously to the solution of a differential equation. For example, +assume we want to solve: + +```math +u^\prime = f(u,p,t) +h = \int_{t_0}^{t_f} g(u,p,t) dt +``` + +While one can use the ODE solver's dense solution to call an integration scheme on `sol(t)` after the solve, this can +be memory intensive. Another way one can solve this problem is by extending the system, i.e.: + +```math +u^\prime = f(u,p,t) +h^\prime = g(u,p,t) +``` + +with $h(t_0) = 0$, so then $h(t_f)$ would be the solution to the integral. However, many differential equation solvers +scale superlinearly with the equation size and thus this could add an extra cost to the solver process. + +The `IntegratingCallback` allows one to be able to solve such definite integrals in a way that is both memory and compute +efficient. It uses the free local interpolation of a given step in order to approximate the Gaussian quadrature for a given +step to the order of the numerical differential equation solve, thus achieving accuracy while not requiring the post-solution +dense interpolation to be saved. By doing this via a callback, this method is able to easily integrate with functionality +that introduces discontinuities, like other callbacks, in a way that is more accurate than a direct integration post solve. + +```@docs +IntegratingCallback +``` \ No newline at end of file diff --git a/src/integrating.jl b/src/integrating.jl index bb133b14..3d802e64 100644 --- a/src/integrating.jl +++ b/src/integrating.jl @@ -189,10 +189,14 @@ returns Integral(integrand_func(u(t),t)dt over the problem tspan. `integrand_func(t, u, integrator)::integrandType`. It's specified via `IntegrandValues(integrandType)`, i.e. give the type that `integrand_func` will output (or higher compatible type). - - `gauss_points` are the Gauss-Legendre points, scaled for the correct limits of integration The outputted values are saved into `integrand_values`. Time points are found via `integrand_values.t` and the values are `integrand_values.integrand`. + +!!! note + + This method is currently limited to ODE solvers of order 10 or lower. Open an issue if other + solvers are required. """ function IntegratingCallback(integrand_func, integrand_values::IntegrandValues) affect! = SavingIntegrandAffect(integrand_func, integrand_values)