Skip to content

Commit

Permalink
Merge pull request #669 from frankschae/CustomController
Browse files Browse the repository at this point in the history
Add custom/abstract controller description
  • Loading branch information
ChrisRackauckas authored Apr 7, 2023
2 parents 6db35b8 + 1d8a248 commit 7b5f414
Showing 1 changed file with 68 additions and 0 deletions.
68 changes: 68 additions & 0 deletions docs/src/extras/timestepping.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,3 +150,71 @@ end
```@docs
PredictiveController
```

## Abstract Controller

The `AbstractController` type allows one to implement custom adaptive
timestepping schemes easily. This can be useful if one wants to use
a priori error estimates, for instance.

To implement a custom controller, subtype `AbstractController` for the
specific DE system.

```julia
struct CustomController <: AbstractController
end
```

and overload

```julia
function stepsize_controller!(integrator, controller::CustomController, alg)
...
nothing
end
function step_accept_controller!(integrator, controller::CustomController, alg)
...
nothing
end
function step_reject_controller!(integrator, controller::CustomController, alg)
...
nothing
end
```

For instance, the PI controller for SDEs can be reproduced by

```julia
struct CustomController <: StochasticDiffEq.AbstractController
end

function StochasticDiffEq.stepsize_controller!(integrator::StochasticDiffEq.SDEIntegrator,
controller::CustomController, alg)
integrator.q11 = DiffEqBase.value(DiffEqBase.fastpow(integrator.EEst, controller.beta1))
integrator.q = DiffEqBase.value(integrator.q11 /
DiffEqBase.fastpow(integrator.qold, controller.beta2))
integrator.q = DiffEqBase.value(max(inv(integrator.opts.qmax),
min(inv(integrator.opts.qmin),
integrator.q / integrator.opts.gamma)))
nothing
end

function StochasticDiffEq.step_accept_controller!(integrator::StochasticDiffEq.SDEIntegrator,
controller::CustomController, alg)
integrator.dtnew = DiffEqBase.value(integrator.dt / integrator.q) *
oneunit(integrator.dt)
nothing
end

function step_reject_controller!(integrator::StochasticDiffEq.SDEIntegrator,
controller::CustomController, alg)
integrator.dtnew = integrator.dt / min(inv(integrator.opts.qmin),
integrator.q11 / integrator.opts.gamma)
end
```

and used via

```julia
sol = solve(prob, EM(), dt = dt, adaptive = true, controller = CustomController())
```

0 comments on commit 7b5f414

Please sign in to comment.