Skip to content

Commit

Permalink
Merge pull request #177 from avik-pal/ap/terminate
Browse files Browse the repository at this point in the history
TerminateSteadyState: Add an option to not wrap the test function
  • Loading branch information
ChrisRackauckas authored Nov 17, 2023
2 parents 69c684c + b81e493 commit f590f6a
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 6 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "DiffEqCallbacks"
uuid = "459566f4-90b8-5000-8ac3-15dfb0a30def"
authors = ["Chris Rackauckas <accounts@chrisrackauckas.com>"]
version = "2.33.1"
version = "2.34.0"

[deps]
DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
Expand Down
16 changes: 11 additions & 5 deletions src/terminatesteadystate.jl
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,8 @@ end
# test function must take integrator, time, followed by absolute
# and relative tolerance and return true/false
"""
```julia
TerminateSteadyState(abstol = 1e-8, reltol = 1e-6, test = allDerivPass; min_t = nothing)
```
TerminateSteadyState(abstol = 1e-8, reltol = 1e-6, test = allDerivPass; min_t = nothing,
wrap_test::Val = Val(true))
`TerminateSteadyState` can be used to solve the problem for the steady-state
by running the solver until the derivatives of the problem converge to 0 or
Expand All @@ -54,15 +53,22 @@ the [Steady State Solvers](https://docs.sciml.ai/DiffEqDocs/stable/solvers/stead
condition is that all derivatives should become smaller than `abstol` and the states times
`reltol`. The user can pass any other function to implement a different termination condition.
Such function should take four arguments: `integrator`, `abstol`, `reltol`, and `min_t`.
- `wrap_test` can be set to `Val(false)`, in which case `test` must have the definition
`test(u, t, integrator)`. Otherwise, `test` must have the definition
`test(integrator, abstol, reltol, min_t)`.
## Keyword Arguments
- `min_t` specifies an optional minimum `t` before the steady state calculations are allowed
to terminate.
"""
function TerminateSteadyState(abstol = 1e-8, reltol = 1e-6, test = allDerivPass;
min_t = nothing)
condition = (u, t, integrator) -> test(integrator, abstol, reltol, min_t)
min_t = nothing, wrap_test::Val{WT} = Val(true)) where {WT}
condition = if WT
(u, t, integrator) -> test(integrator, abstol, reltol, min_t)
else
test
end
affect! = (integrator) -> terminate!(integrator)
DiscreteCallback(condition, affect!; save_positions = (true, false))
end
Expand Down
13 changes: 13 additions & 0 deletions test/terminatesteadystate_test.jl
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,16 @@ sim = solve(prob, Tsit5(), callback = TerminateSteadyState())

@test all(sim(sim.t[end], Val{1}) .< 1e-8)
@test sim.t[end] < tspan[2]

# Don't wrap function
test_func = (u, t, integrator) -> DiffEqCallbacks.allDerivPass(integrator, 1e-6, 1e-6,
nothing)

@test_throws MethodError solve(prob, Tsit5(), callback = TerminateSteadyState(1e-6, 1e-6,
test_func))

sim = solve(prob, Tsit5(), callback = TerminateSteadyState(1e-6, 1e-6, test_func,
wrap_test = Val(false)))

@test all(sim(sim.t[end], Val{1}) .< 1e-8)
@test sim.t[end] < tspan[2]

0 comments on commit f590f6a

Please sign in to comment.