Skip to content

Commit 3fbb0f8

Browse files
Create SCCNonlinearSolve
1 parent b534b0c commit 3fbb0f8

File tree

6 files changed

+235
-0
lines changed

6 files changed

+235
-0
lines changed

lib/SCCNonlinearSolve/LICENSE

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) 2024 SciML
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/SCCNonlinearSolve/Project.toml

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
name = "SCCNonlinearSolve"
2+
uuid = "9dfe8606-65a1-4bb3-9748-cb89d1561431"
3+
authors = ["Avik Pal <[email protected]> and contributors"]
4+
version = "1.0.0"
5+
6+
[deps]
7+
CommonSolve = "38540f10-b2f7-11e9-35d8-d573e4eb0ff2"
8+
MaybeInplace = "bb5d69b7-63fc-4a16-80bd-7e42200c7bdb"
9+
NonlinearSolveBase = "be0214bd-f91f-a760-ac4e-3421ce2b2da0"
10+
PrecompileTools = "aea7be01-6a6a-4083-8856-8a6e6704d82a"
11+
Reexport = "189a3867-3050-52da-a836-e630ba90ab69"
12+
SciMLBase = "0bca4576-84f4-4d90-8ffe-ffa030f20462"
13+
14+
[compat]
15+
Aqua = "0.8"
16+
BenchmarkTools = "1.5.0"
17+
CommonSolve = "0.2.4"
18+
ExplicitImports = "1.5"
19+
Hwloc = "3"
20+
InteractiveUtils = "<0.0.1, 1"
21+
MaybeInplace = "0.1.4"
22+
NonlinearProblemLibrary = "0.1.2"
23+
NonlinearSolveBase = "1.1"
24+
Pkg = "1.10"
25+
PrecompileTools = "1.2"
26+
ReTestItems = "1.24"
27+
Reexport = "1"
28+
SciMLBase = "2.58"
29+
StableRNGs = "1"
30+
StaticArrays = "1.9.8"
31+
Test = "1.10"
32+
julia = "1.10"
33+
34+
[extras]
35+
Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
36+
BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf"
37+
ExplicitImports = "7d51a73a-1435-4ff3-83d9-f097790105c7"
38+
Hwloc = "0e44f5e4-bd66-52a0-8798-143a42290a1d"
39+
InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
40+
NonlinearProblemLibrary = "b7050fa9-e91f-4b37-bcee-a89a063da141"
41+
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
42+
ReTestItems = "817f1d60-ba6b-4fd5-9520-3cf149f6a823"
43+
StableRNGs = "860ef19b-820b-49d6-a774-d7a799459cd3"
44+
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
45+
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
46+
47+
[targets]
48+
test = ["Aqua", "BenchmarkTools", "ExplicitImports", "Hwloc", "InteractiveUtils", "NonlinearProblemLibrary", "Pkg", "ReTestItems", "StableRNGs", "StaticArrays", "Test"]
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
module SCCNonlinearSolve
2+
3+
import SciMLBase
4+
5+
function SciMLBase.solve(prob::SciMLBase.SCCNonlinearProblem, alg; kwargs...)
6+
numscc = length(prob.probs)
7+
sols = [SciMLBase.build_solution(prob, nothing, prob.u0, convert(eltype(prob.u0),NaN)*prob.u0) for prob in prob.probs]
8+
u = reduce(vcat,[prob.u0 for prob in prob.probs])
9+
resid = copy(u)
10+
11+
earlyexit = false
12+
lasti = 1
13+
for i in 1:numscc
14+
prob.explictfuns![i](prob.probs[i].p[1],sols)
15+
sol = SciMLBase.solve(prob.probs[i], alg; kwargs...)
16+
_sol = SciMLBase.build_solution(prob.probs[i], nothing, sol.u, sol.resid, retcode = sol.retcode)
17+
sols[i] = _sol
18+
19+
if !SciMLBase.successful_retcode(_sol)
20+
earlyexit = true
21+
lasti = i
22+
break
23+
end
24+
end
25+
26+
# TODO: fix allocations with a lazy concatenation
27+
u .= reduce(vcat,sols)
28+
resid .= reduce(vcat,getproperty.(sols,:resid))
29+
30+
if earlyexit
31+
retcode = sols[lasti].retcode
32+
else
33+
retcode = SciMLBase.ReturnCode.Success
34+
end
35+
36+
SciMLBase.build_solution(prob, alg, u, resid; retcode, original = sols)
37+
end
38+
39+
end
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
@testsetup module CoreRootfindTesting
2+
3+
include("../../../common/common_rootfind_testing.jl")
4+
5+
end
6+
7+
@testitem "Manual SCC" setup=[CoreRootfindTesting] tags=[:core] begin
8+
function f(du,u,p)
9+
du[1] = cos(u[2]) - u[1]
10+
du[2] = sin(u[1] + u[2]) + u[2]
11+
du[3] = 2u[4] + u[3] + 1.0
12+
du[4] = u[5]^2 + u[4]
13+
du[5] = u[3]^2 + u[5]
14+
du[6] = u[1] + u[2] + u[3] + u[4] + u[5] + 2.0u[6] + 2.5u[7] + 1.5u[8]
15+
du[7] = u[1] + u[2] + u[3] + 2.0u[4] + u[5] + 4.0u[6] - 1.5u[7] + 1.5u[8]
16+
du[8] = u[1] + 2.0u[2] + 3.0u[3] + 5.0u[4] + 6.0u[5] + u[6] - u[7] - u[8]
17+
end
18+
prob = NonlinearProblem(f, zeros(8))
19+
sol = solve(prob)
20+
21+
u0 = zeros(2)
22+
cache = zeros(3)
23+
24+
function f1(du,u,(cache,p))
25+
du[1] = cos(u[2]) - u[1]
26+
du[2] = sin(u[1] + u[2]) + u[2]
27+
end
28+
explicitfun1(cache,sols) = nothing
29+
prob1 = NonlinearProblem(NonlinearFunction{true, SciMLBase.NoSpecialize}(f1), zeros(2),(cache,nothing))
30+
sol1 = solve(prob1, NewtonRaphson())
31+
32+
function f2(du,u,(cache,p))
33+
du[1] = 2u[2] + u[1] + 1.0
34+
du[2] = u[3]^2 + u[2]
35+
du[3] = u[1]^2 + u[3]
36+
end
37+
explicitfun2(cache,sols) = nothing
38+
prob2 = NonlinearProblem(NonlinearFunction{true, SciMLBase.NoSpecialize}(f2), zeros(3),(cache,nothing))
39+
sol2 = solve(prob2, NewtonRaphson())
40+
41+
function f3(du,u,(cache,p))
42+
du[1] = cache[1] + 2.0u[1] + 2.5u[2] + 1.5u[3]
43+
du[2] = cache[2] + 4.0u[1] - 1.5u[2] + 1.5u[3]
44+
du[3] = cache[3] + + u[1] - u[2] - u[3]
45+
end
46+
prob3 = NonlinearProblem(NonlinearFunction{true, SciMLBase.NoSpecialize}(f3), zeros(3),(cache,nothing))
47+
function explicitfun3(cache,sols)
48+
cache[1] = sols[1][1] + sols[1][2] + sols[2][1] + sols[2][2] + sols[2][3]
49+
cache[2] = sols[1][1] + sols[1][2] + sols[2][1] + 2.0sols[2][2] + sols[2][3]
50+
cache[3] = sols[1][1] + 2.0sols[1][2] + 3.0sols[2][1] + 5.0sols[2][2] + 6.0sols[2][3]
51+
end
52+
explicitfun3(cache,[sol1,sol2])
53+
sol3 = solve(prob3, NewtonRaphson())
54+
manualscc = [sol1; sol2; sol3]
55+
56+
function SciMLBase.solve(prob::SciMLBase.SCCNonlinearProblem, alg; kwargs...)
57+
numscc = length(prob.probs)
58+
sols = [SciMLBase.build_solution(prob, nothing, prob.u0, convert(eltype(u0),NaN)*prob.u0) for prob in prob.probs]
59+
u = reduce(vcat,[prob.u0 for prob in prob.probs])
60+
resid = copy(u)
61+
62+
for i in 1:numscc
63+
prob.explictfuns![i](prob.probs[i].p[1],sols)
64+
sol = solve(prob.probs[i], alg)
65+
_sol = SciMLBase.build_solution(prob.probs[i], nothing, sol.u, sol.resid, retcode = sol.retcode)
66+
sols[i] = _sol
67+
end
68+
69+
# TODO: fix allocations with a lazy concatenation
70+
u .= reduce(vcat,sols)
71+
resid .= reduce(vcat,getproperty.(sols,:resid))
72+
73+
SciMLBase.build_solution(prob, alg, u, resid, original = sols)
74+
end
75+
76+
sccprob = SciMLBase.SCCNonlinearProblem([prob1,prob2,prob3], SciMLBase.Void{Any}.([explicitfun1,explicitfun2,explicitfun3]))
77+
scc_sol = solve(sccprob, NewtonRaphson())
78+
sol manualscc scc_sol
79+
80+
end
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
@testitem "Aqua" tags=[:core] begin
2+
using Aqua, SCCNonlinearSolve
3+
4+
Aqua.test_all(
5+
SCCNonlinearSolve;
6+
piracies = false, ambiguities = false, stale_deps = false, deps_compat = false
7+
)
8+
Aqua.test_stale_deps(SCCNonlinearSolve; ignore = [:SciMLJacobianOperators])
9+
Aqua.test_deps_compat(SCCNonlinearSolve; ignore = [:SciMLJacobianOperators])
10+
Aqua.test_piracies(SCCNonlinearSolve)
11+
Aqua.test_ambiguities(SCCNonlinearSolve; recursive = false)
12+
end
13+
14+
@testitem "Explicit Imports" tags=[:core] begin
15+
using ExplicitImports, SCCNonlinearSolve
16+
17+
@test check_no_implicit_imports(
18+
SCCNonlinearSolve; skip = (Base, Core, SciMLBase)
19+
) === nothing
20+
@test check_no_stale_explicit_imports(SCCNonlinearSolve) === nothing
21+
@test check_all_qualified_accesses_via_owners(SCCNonlinearSolve) === nothing
22+
end
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using ReTestItems, SCCNonlinearSolve, Hwloc, InteractiveUtils, Pkg
2+
3+
@info sprint(InteractiveUtils.versioninfo)
4+
5+
const GROUP = lowercase(get(ENV, "GROUP", "All"))
6+
7+
const RETESTITEMS_NWORKERS = parse(
8+
Int, get(ENV, "RETESTITEMS_NWORKERS",
9+
string(min(ifelse(Sys.iswindows(), 0, Hwloc.num_physical_cores()), 4))
10+
)
11+
)
12+
const RETESTITEMS_NWORKER_THREADS = parse(Int,
13+
get(
14+
ENV, "RETESTITEMS_NWORKER_THREADS",
15+
string(max(Hwloc.num_virtual_cores() ÷ max(RETESTITEMS_NWORKERS, 1), 1))
16+
)
17+
)
18+
19+
@info "Running tests for group: $(GROUP) with $(RETESTITEMS_NWORKERS) workers"
20+
21+
ReTestItems.runtests(
22+
SCCNonlinearSolve; tags = (GROUP == "all" ? nothing : [Symbol(GROUP)]),
23+
nworkers = RETESTITEMS_NWORKERS, nworker_threads = RETESTITEMS_NWORKER_THREADS,
24+
testitem_timeout = 3600
25+
)

0 commit comments

Comments
 (0)