Skip to content

Commit 7fbe805

Browse files
Move GlobalDiffEq.jl into the monorepo as lib/GlobalDiffEq
Repo transfer of SciML/GlobalDiffEq.jl (GlobalRichardson), keeping its name, UUID, and version lineage. The umbrella OrdinaryDiffEq dependency is replaced by OrdinaryDiffEqTsit5 (precompile workload and tests only), path sources point at the sibling sublibraries, tests read ODEDIFFEQ_TEST_GROUP, and the rendered-API-docs QA check points at the monorepo docs with reexported DiffEqBase names excluded. Adds the Global Error Control docs section and the docs env wiring. Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
1 parent aa895b5 commit 7fbe805

16 files changed

Lines changed: 344 additions & 0 deletions

docs/Project.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
DiffEqBase = "2b5f629d-d688-5b77-993f-72d75c75574e"
33
DiffEqDevTools = "f3b72e0c-5b89-59e1-b016-84e28bfd966d"
44
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
5+
GlobalDiffEq = "1d72d19b-84cc-4cb7-a099-7cbdb9ccc67c"
56
ImplicitDiscreteSolve = "3263718b-31ed-49cf-8a0f-35a466e8af96"
67
OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed"
78
OrdinaryDiffEqAMF = "08082164-f6a1-4363-b3df-3aa6fcf571ad"
@@ -39,6 +40,7 @@ OrdinaryDiffEqVerner = "79d7bb75-1356-48c1-b8c0-6832512096c2"
3940
[sources]
4041
DiffEqBase = {path = "../lib/DiffEqBase"}
4142
DiffEqDevTools = {path = "../lib/DiffEqDevTools"}
43+
GlobalDiffEq = {path = "../lib/GlobalDiffEq"}
4244
ImplicitDiscreteSolve = {path = "../lib/ImplicitDiscreteSolve"}
4345
OrdinaryDiffEqAMF = {path = "../lib/OrdinaryDiffEqAMF"}
4446
OrdinaryDiffEqAdamsBashforthMoulton = {path = "../lib/OrdinaryDiffEqAdamsBashforthMoulton"}
@@ -76,6 +78,7 @@ OrdinaryDiffEqVerner = {path = "../lib/OrdinaryDiffEqVerner"}
7678
DiffEqBase = "7.6.1"
7779
DiffEqDevTools = "3, 4.0"
7880
Documenter = "0.27, 1"
81+
GlobalDiffEq = "1.2.1"
7982
ImplicitDiscreteSolve = "2"
8083
OrdinaryDiffEq = "7"
8184
OrdinaryDiffEqAMF = "2"

docs/make.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ using OrdinaryDiffEqStabilizedRK
3636
using OrdinaryDiffEqSymplecticRK
3737
using OrdinaryDiffEqTsit5
3838
using OrdinaryDiffEqVerner
39+
using GlobalDiffEq
3940

4041
cp(joinpath(@__DIR__, "Manifest.toml"), joinpath(@__DIR__, "src", "assets", "Manifest.toml"), force = true)
4142
cp(joinpath(@__DIR__, "Project.toml"), joinpath(@__DIR__, "src", "assets", "Project.toml"), force = true)
@@ -83,6 +84,7 @@ makedocs(
8384
OrdinaryDiffEqAMF,
8485
ImplicitDiscreteSolve,
8586
DiffEqDevTools,
87+
GlobalDiffEq,
8688
],
8789
linkcheck_ignore = [r"https://github.com/JuliaDiff/ForwardDiff.jl"],
8890
warnonly = [:docs_block, :missing_docs, :eval_block],

docs/pages.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ pages = [
5353
"Misc Solvers" => [
5454
"misc.md",
5555
],
56+
"Global Error Control" => [
57+
"globalerrorcontrol/GlobalDiffEq.md",
58+
],
5659
"APIs" => [
5760
"api/diffeqbase.md",
5861
"api/ordinarydiffeqcore.md",
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# GlobalDiffEq: Global Error Estimation and Control
2+
3+
Standard adaptive ODE solvers control the *local* error of each step. The
4+
local tolerances only indirectly control the *global* (accumulated) error of
5+
the solution, which can grow arbitrarily large over long integrations or on
6+
unstable problems even when every step satisfies its local tolerance. The
7+
GlobalDiffEq sublibrary provides solvers and solver wrappers that estimate
8+
the global error, and in several cases control it to a requested global
9+
tolerance.
10+
11+
To use these methods:
12+
13+
```julia
14+
using GlobalDiffEq
15+
```
16+
17+
[`GlobalRichardson`](@ref) wraps any fixed-step method in global Richardson
18+
extrapolation over whole solves, interpreting `abstol` and `reltol` as global
19+
tolerances. It is the most robust and most expensive option.
20+
21+
## Global error controlling wrappers
22+
23+
```@docs
24+
GlobalRichardson
25+
```

lib/GlobalDiffEq/LICENSE.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2020 Chris Rackauckas <accounts@chrisrackauckas.com> and contributors
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

lib/GlobalDiffEq/Project.toml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
name = "GlobalDiffEq"
2+
uuid = "1d72d19b-84cc-4cb7-a099-7cbdb9ccc67c"
3+
authors = ["Chris Rackauckas <accounts@chrisrackauckas.com> and contributors"]
4+
version = "1.2.1"
5+
6+
[deps]
7+
DiffEqBase = "2b5f629d-d688-5b77-993f-72d75c75574e"
8+
OrdinaryDiffEqTsit5 = "b1df2697-797e-41e3-8120-5422d3b24e4a"
9+
PrecompileTools = "aea7be01-6a6a-4083-8856-8a6e6704d82a"
10+
Reexport = "189a3867-3050-52da-a836-e630ba90ab69"
11+
Richardson = "708f8203-808e-40c0-ba2d-98a6953ed40d"
12+
SciMLBase = "0bca4576-84f4-4d90-8ffe-ffa030f20462"
13+
14+
[sources]
15+
DiffEqBase = {path = "../DiffEqBase"}
16+
OrdinaryDiffEqTsit5 = {path = "../OrdinaryDiffEqTsit5"}
17+
18+
[compat]
19+
DiffEqBase = "7"
20+
LinearAlgebra = "1"
21+
OrdinaryDiffEqSSPRK = "2"
22+
OrdinaryDiffEqTsit5 = "2"
23+
PrecompileTools = "1.1"
24+
Reexport = "0.2, 1.0"
25+
Richardson = "1.2"
26+
SafeTestsets = "0.0.1, 0.1"
27+
SciMLBase = "3"
28+
SciMLTesting = "2.1"
29+
Test = "1"
30+
julia = "1.10"
31+
32+
[extras]
33+
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
34+
OrdinaryDiffEqSSPRK = "669c94d9-1f4b-4b64-b377-1aa079aa2388"
35+
OrdinaryDiffEqTsit5 = "b1df2697-797e-41e3-8120-5422d3b24e4a"
36+
SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f"
37+
SciMLTesting = "09d9d899-5365-40a9-917a-5f67fddea283"
38+
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
39+
40+
[targets]
41+
test = ["LinearAlgebra", "OrdinaryDiffEqSSPRK", "OrdinaryDiffEqTsit5", "SafeTestsets", "SciMLTesting", "Test"]

lib/GlobalDiffEq/README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# GlobalDiffEq
2+
3+
Differential equation solvers and solver wrappers with global (accumulated)
4+
error estimates and global error control for the
5+
[DifferentialEquations.jl common solver interface](https://docs.sciml.ai/DiffEqDocs/stable/).
6+
Formerly the standalone [GlobalDiffEq.jl](https://github.com/SciML/GlobalDiffEq.jl)
7+
repository, now maintained as a sublibrary of OrdinaryDiffEq.jl.
8+
9+
Standard adaptive ODE solvers control the *local* error of each step, which
10+
does not bound the error accumulated over the whole integration. This package
11+
provides:
12+
13+
- `GlobalRichardson`: global Richardson extrapolation of whole solves of any
14+
fixed-step method, interpreting `abstol`/`reltol` as global tolerances.
15+
16+
See the [OrdinaryDiffEq.jl documentation](https://docs.sciml.ai/OrdinaryDiffEq/stable/)
17+
for the full API reference.
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
module GlobalDiffEq
2+
3+
using Reexport: @reexport
4+
@reexport using DiffEqBase
5+
6+
import OrdinaryDiffEqTsit5, Richardson, SciMLBase
7+
using PrecompileTools: @setup_workload, @compile_workload
8+
9+
abstract type GlobalDiffEqAlgorithm <: SciMLBase.AbstractODEAlgorithm end
10+
11+
include("richardson.jl")
12+
13+
export GlobalRichardson
14+
15+
@setup_workload begin
16+
# Simple test ODE: exponential decay du/dt = -u
17+
function f!(du, u, p, t)
18+
du[1] = -u[1]
19+
end
20+
u0 = [1.0]
21+
tspan = (0.0, 1.0)
22+
prob = ODEProblem(f!, u0, tspan)
23+
24+
@compile_workload begin
25+
solve(
26+
prob, GlobalRichardson(OrdinaryDiffEqTsit5.Tsit5()),
27+
dt = 0.1, reltol = 1.0e-3, abstol = 1.0e-6
28+
)
29+
end
30+
end
31+
32+
end

lib/GlobalDiffEq/src/richardson.jl

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
"""
2+
GlobalRichardson(alg)
3+
4+
Wrap an ODE algorithm with global Richardson extrapolation.
5+
"""
6+
struct GlobalRichardson{A <: SciMLBase.AbstractODEAlgorithm} <: GlobalDiffEqAlgorithm
7+
alg::A
8+
end
9+
10+
# Forward algorithm traits to the wrapped algorithm
11+
# This allows GlobalRichardson to inherit capabilities from the inner algorithm
12+
SciMLBase.allows_arbitrary_number_types(alg::GlobalRichardson) =
13+
SciMLBase.allows_arbitrary_number_types(alg.alg)
14+
SciMLBase.allowscomplex(alg::GlobalRichardson) =
15+
SciMLBase.allowscomplex(alg.alg)
16+
SciMLBase.isautodifferentiable(alg::GlobalRichardson) =
17+
SciMLBase.isautodifferentiable(alg.alg)
18+
19+
function SciMLBase.__solve(
20+
prob::Union{SciMLBase.AbstractODEProblem, SciMLBase.AbstractDAEProblem},
21+
alg::GlobalRichardson, args...;
22+
dt, kwargs...
23+
)
24+
opt = Dict(kwargs)
25+
otheropts = delete!(copy(opt), :dt)
26+
tstops = get(opt, :tstops, range(prob.tspan[1], stop = prob.tspan[2], step = dt))
27+
local sol
28+
val,
29+
err = Richardson.extrapolate(
30+
dt, rtol = get(opt, :reltol, 1.0e-3),
31+
atol = get(opt, :abstol, 1.0e-6), contract = 0.5
32+
) do _dt
33+
sol = solve(prob, alg.alg, args...; dt = _dt, adaptive = false, otheropts...)
34+
# Convert Vector{Vector{T}} to Matrix{T} for Richardson.jl compatibility
35+
reduce(hcat, sol.(tstops))
36+
end
37+
return sol
38+
end
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using GlobalDiffEq, OrdinaryDiffEqTsit5
2+
using OrdinaryDiffEqSSPRK
3+
using Test
4+
import DiffEqBase: SciMLBase
5+
6+
@testset "Algorithm traits forwarding" begin
7+
alg_inner = SSPRK33()
8+
alg = GlobalRichardson(alg_inner)
9+
10+
@test SciMLBase.allows_arbitrary_number_types(alg) ==
11+
SciMLBase.allows_arbitrary_number_types(alg_inner)
12+
@test SciMLBase.allowscomplex(alg) == SciMLBase.allowscomplex(alg_inner)
13+
@test SciMLBase.isautodifferentiable(alg) == SciMLBase.isautodifferentiable(alg_inner)
14+
end

0 commit comments

Comments
 (0)