Skip to content

Commit 41ef9b1

Browse files
authored
Merge pull request #36 from WIAS-PDELib/jf/LinearSolve_2_36
Support new precs API of LinearSolve
2 parents 3ae210d + 02cf5cf commit 41ef9b1

25 files changed

+519
-97
lines changed

Diff for: .github/workflows/ci.yml

+4-4
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ jobs:
1515
fail-fast: false
1616
matrix:
1717
version:
18-
- '1.9' # Replace this with the minimum Julia version that your package supports. E.g. if your package requires Julia 1.5 or higher, change this to '1.5'.
18+
- 'lts' # Replace this with the minimum Julia version that your package supports. E.g. if your package requires Julia 1.5 or higher, change this to '1.5'.
1919
- '1' # Leave this line unchanged. '1' will automatically expand to the latest stable 1.x release of Julia.
20-
# - 'nightly'
20+
- 'nightly'
2121
os:
2222
- ubuntu-latest
2323
- windows-latest
@@ -34,7 +34,7 @@ jobs:
3434
arch: x64
3535
steps:
3636
- uses: actions/checkout@v4
37-
- uses: julia-actions/setup-julia@v1
37+
- uses: julia-actions/setup-julia@v2
3838
with:
3939
version: ${{ matrix.version }}
4040
arch: ${{ matrix.arch }}
@@ -59,7 +59,7 @@ jobs:
5959
runs-on: ubuntu-latest
6060
steps:
6161
- uses: actions/checkout@v4
62-
- uses: julia-actions/setup-julia@v1
62+
- uses: julia-actions/setup-julia@v2
6363
with:
6464
version: '1'
6565
- run: |

Diff for: CHANGELOG.md

+11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
11
# Changelog
22

3+
## [2.0.0] - Planned
4+
5+
### Breaking
6+
- remove solver + precon API which is not based on precs or directly overloading `\`.
7+
Fully rely on LinearSolve (besides `\`)
8+
- Move AMGBuilder, ILUZeroBuilder etc. to the correspondig packages (depending on the PRs)
9+
- remove "old" SparseMatrixLNK (need to benchmark before)
10+
11+
## [1.6.0] - WIP
12+
- Support precs API of LinearSolve.jl
13+
314
## [1.5.3] - 2024-10-07
415
- Moved repo to WIAS-PDELib organization
516

Diff for: Project.toml

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "ExtendableSparse"
22
uuid = "95c220a8-a1cf-11e9-0c77-dbfce5f500b3"
33
authors = ["Juergen Fuhrmann <[email protected]>"]
4-
version = "1.5.3"
4+
version = "1.6.0"
55

66
[deps]
77
AMGCLWrap = "4f76b812-4ba5-496d-b042-d70715554288"
@@ -19,20 +19,23 @@ Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
1919
AMGCLWrap = "4f76b812-4ba5-496d-b042-d70715554288"
2020
AlgebraicMultigrid = "2169fc97-5a83-5252-b627-83903c6c433c"
2121
IncompleteLU = "40713840-3770-5561-ab4c-a76e7d0d7895"
22+
LinearSolve = "7ed4a6bd-45f5-4d41-b270-4a48e9bafcae"
2223
Pardiso = "46dd5b70-b6fb-5a00-ae2d-e8fea33afaf2"
2324

2425
[extensions]
2526
ExtendableSparseAMGCLWrapExt = "AMGCLWrap"
2627
ExtendableSparseAlgebraicMultigridExt = "AlgebraicMultigrid"
2728
ExtendableSparseIncompleteLUExt = "IncompleteLU"
2829
ExtendableSparsePardisoExt = "Pardiso"
30+
ExtendableSparseLinearSolveExt = "LinearSolve"
2931

3032
[compat]
31-
AMGCLWrap = "0.4,1"
33+
AMGCLWrap = "2"
3234
AlgebraicMultigrid = "0.4,0.5,0.6"
3335
DocStringExtensions = "0.8, 0.9"
3436
ILUZero = "0.2"
3537
IncompleteLU = "^0.2.1"
38+
LinearSolve = "2.36.0"
3639
Pardiso = "0.5.1"
3740
Sparspak = "0.3.6"
3841
StaticArrays = "1.5.24"

Diff for: docs/Project.toml

+2
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@ ILUZero = "88f59080-6952-5380-9ea5-54057fb9a43f"
99
IncompleteLU = "40713840-3770-5561-ab4c-a76e7d0d7895"
1010
IterativeSolvers = "42fd0dbc-a981-5370-80f2-aaf504508153"
1111
LinearSolve = "7ed4a6bd-45f5-4d41-b270-4a48e9bafcae"
12+
MultiFloats = "bdf0d083-296b-4888-a5b6-7498122e68a5"
1213
Sparspak = "e56a9233-b9d6-4f03-8d0f-1825330902ac"
1314

1415
[compat]
1516
Documenter = "1.0"
1617
IterativeSolvers = "0.9"
18+
LinearSolve = "2.36.0"

Diff for: docs/make.jl

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
push!(LOAD_PATH, "../src/")
21
using Documenter, ExtendableSparse, AlgebraicMultigrid, IncompleteLU, Sparspak, LinearAlgebra
32

43
function mkdocs()
@@ -12,10 +11,10 @@ function mkdocs()
1211
pages = [
1312
"Home" => "index.md",
1413
"example.md",
15-
"linearsolve.md",
1614
"extsparse.md",
17-
"iter.md",
15+
"linearsolve.md",
1816
"internal.md",
17+
"iter.md",
1918
"changes.md",
2019
])
2120
end

Diff for: docs/src/extsparse.md

+4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## Matrix creation and update API
44

5+
```@docs
6+
ExtendableSparseMatrix
7+
```
8+
59
```@autodocs
610
Modules = [ExtendableSparse]
711
Pages = ["extendable.jl"]

Diff for: docs/src/internal.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ Pages = ["sparsematrixcsc.jl"]
1515
```
1616
## New API
1717
Under development - aimed at multithreading
18-
```@autodocs
18+
```@autodocs; canonical = false
1919
Modules = [ExtendableSparse]
2020
Pages = ["abstractsparsematrixextension.jl",
2121
"abstractextendablesparsematrixcsc.jl",

Diff for: docs/src/iter.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# Factorizations & Preconditioners
22

3-
This functionality probably will be reduced in favor of LinearSolve.jl.
3+
This functionality is deprecated as of version 1.6 an will be removed
4+
with version 2.0. Use the [integration with LinearSolve.jl](/linearsolve/#Integration-with-LinearSolve.jl).
5+
46

57
## Factorizations
68

Diff for: docs/src/linearsolve.md

+115-26
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,152 @@
1-
# Integration with LinearSolve.jl
1+
# Linear System solution
2+
3+
## The `\` operator
4+
The packages overloads `\` for the ExtendableSparseMatrix type.
5+
The following example uses [`fdrand`](@ref) to create a test matrix and solve
6+
the corresponding linear system of equations.
7+
8+
```@example
9+
using ExtendableSparse
10+
A = fdrand(10, 10, 10; matrixtype = ExtendableSparseMatrix)
11+
x = ones(1000)
12+
b = A * x
13+
y = A \ b
14+
sum(y)
15+
```
16+
17+
This works as well for number types besides `Float64` and related, in this case,
18+
by default a LU factorization based on Sparspak ist used.
19+
20+
```@example
21+
using ExtendableSparse
22+
using MultiFloats
23+
A = fdrand(Float64x2, 10, 10, 10; matrixtype = ExtendableSparseMatrix)
24+
x = ones(Float64x2,1000)
25+
b = A * x
26+
y = A \ b
27+
sum(y)
28+
```
29+
30+
## Solving with LinearSolve.jl
231

332
Starting with version 0.9.6, ExtendableSparse is compatible
433
with [LinearSolve.jl](https://github.com/SciML/LinearSolve.jl).
534
Since version 0.9.7, this is facilitated via the
6-
AbstractSparseMatrixCSC interface.
35+
AbstractSparseMatrixCSC interface.
736

8-
```@autodocs
9-
Modules = [ExtendableSparse]
10-
Pages = ["linearsolve.jl"]
11-
```
1237

13-
We can create a test problem and solve it with the `\` operator.
38+
The same problem can be solved via `LinearSolve.jl`:
1439

1540
```@example
16-
using ExtendableSparse # hide
41+
using ExtendableSparse
42+
using LinearSolve
1743
A = fdrand(10, 10, 10; matrixtype = ExtendableSparseMatrix)
1844
x = ones(1000)
1945
b = A * x
20-
y = A \ b
46+
y = solve(LinearProblem(A, b)).u
2147
sum(y)
2248
```
2349

24-
The same problem can be solved by the tools available via `LinearSolve.jl`:
50+
```@example
51+
using ExtendableSparse
52+
using LinearSolve
53+
using MultiFloats
54+
A = fdrand(Float64x2, 10, 10, 10; matrixtype = ExtendableSparseMatrix)
55+
x = ones(Float64x2,1000)
56+
b = A * x
57+
y = solve(LinearProblem(A, b), SparspakFactorization()).u
58+
sum(y)
59+
```
60+
61+
## Preconditioned Krylov solvers with LinearSolve.jl
62+
63+
Since version 1.6, preconditioner constructors can be passed to iterative solvers via the [`precs`
64+
keyword argument](https://docs.sciml.ai/LinearSolve/stable/basics/Preconditioners/#prec)
65+
to the iterative solver specification.
2566

2667
```@example
27-
using ExtendableSparse # hide
28-
using LinearSolve # hide
68+
using ExtendableSparse
69+
using LinearSolve
70+
using ExtendableSparse: ILUZeroPreconBuilder
2971
A = fdrand(10, 10, 10; matrixtype = ExtendableSparseMatrix)
3072
x = ones(1000)
3173
b = A * x
32-
y = solve(LinearProblem(A, b), SparspakFactorization()).u
74+
y = LinearSolve.solve(LinearProblem(A, b),
75+
KrylovJL_CG(; precs=ILUZeroPreconBuilder())).u
3376
sum(y)
3477
```
3578

36-
Also, the iterative method interface works with ExtendableSparse.
79+
## Available preconditioners
80+
ExtendableSparse provides constructors for preconditioners wich can be used as `precs`.
81+
These generally return a tuple `(Pl,I)` of a left preconditioner and a trivial right preconditioner.
82+
83+
ExtendableSparse has a number of package extensions which construct preconditioners
84+
from some other packages. In the future, these packages may provide this functionality on their own.
85+
86+
```@docs
87+
ExtendableSparse.ILUZeroPreconBuilder
88+
ExtendableSparse.ILUTPreconBuilder
89+
ExtendableSparse.SmoothedAggregationPreconBuilder
90+
ExtendableSparse.RugeStubenPreconBuilder
91+
```
92+
93+
In addition, ExtendableSparse implements some preconditioners:
94+
95+
```@docs
96+
ExtendableSparse.JacobiPreconBuilder
97+
```
98+
99+
LU factorizations of matrices from previous iteration steps may be good
100+
preconditioners for Krylov solvers called during a nonlinear solve via
101+
Newton's method. For this purpose, ExtendableSparse provides a preconditioner constructor
102+
which wraps sparse LU factorizations supported by LinearSolve.jl
103+
```@docs
104+
ExtendableSparse.LinearSolvePreconBuilder
105+
```
106+
107+
108+
Block preconditioner constructors are provided as well
109+
```@docs; canonical=false
110+
ExtendableSparse.BlockPreconBuilder
111+
```
112+
37113

114+
The example beloww shows how to create a block Jacobi preconditioner where the blocks are defined by even and odd
115+
degrees of freedom, and the diagonal blocks are solved using UMFPACK.
38116
```@example
39-
using ExtendableSparse # hide
40-
using LinearSolve # hide
41-
using SparseArrays # hide
42-
using ILUZero # hide
117+
using ExtendableSparse
118+
using LinearSolve
119+
using ExtendableSparse: LinearSolvePreconBuilder, BlockPreconBuilder
43120
A = fdrand(10, 10, 10; matrixtype = ExtendableSparseMatrix)
44121
x = ones(1000)
45122
b = A * x
46-
y = LinearSolve.solve(LinearProblem(A, b), KrylovJL_CG();
47-
Pl = ILUZero.ilu0(SparseMatrixCSC(A))).u
123+
partitioning=A->[1:2:size(A,1), 2:2:size(A,1)]
124+
umfpackprecs=LinearSolvePreconBuilder(UMFPACKFactorization())
125+
blockprecs=BlockPreconBuilder(;precs=umfpackprecs, partitioning)
126+
y = LinearSolve.solve(LinearProblem(A, b), KrylovJL_CG(; precs=blockprecs)).u
48127
sum(y)
49128
```
129+
`umpfackpreconbuilder` e.g. could be replaced by `SmoothedAggregationPreconBuilder()`. Moreover, this approach
130+
works for any `AbstractSparseMatrixCSC`.
131+
132+
133+
## Deprecated API
134+
Passing a preconditioner via the `Pl` or `Pr` keyword arguments
135+
will be deprecated in LinearSolve. ExtendableSparse used to
136+
export a number of wrappers for preconditioners from other packages
137+
for this purpose. This approach is deprecated as of v1.6 and will be removed
138+
with v2.0.
50139

51-
However, ExtendableSparse provides a number of wrappers around preconditioners
52-
from various Julia packages.
53140
```@example
54-
using ExtendableSparse # hide
55-
using LinearSolve # hide
56-
using ILUZero # hide
141+
using ExtendableSparse
142+
using LinearSolve
143+
using SparseArray
144+
using ILUZero
57145
A = fdrand(10, 10, 10; matrixtype = ExtendableSparseMatrix)
58146
x = ones(1000)
59147
b = A * x
60148
y = LinearSolve.solve(LinearProblem(A, b), KrylovJL_CG();
61-
Pl = ILUZeroPreconditioner(A)).u
149+
Pl = ILUZero.ilu0(SparseMatrixCSC(A))).u
62150
sum(y)
63151
```
152+

Diff for: ext/ExtendableSparseAMGCLWrapExt.jl

+6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# The whole extension is deprecated
2+
# TODO remove in v2.0
13
module ExtendableSparseAMGCLWrapExt
24
using ExtendableSparse
35
using AMGCLWrap
@@ -10,6 +12,8 @@ mutable struct AMGCL_AMGPreconditioner <: AbstractPreconditioner
1012
factorization::AMGCLWrap.AMGPrecon
1113
kwargs
1214
function ExtendableSparse.AMGCL_AMGPreconditioner(; kwargs...)
15+
Base.depwarn("AMGCL_AMGPreconditioner() is deprecated. Use LinearSolve with `precs=AMGCLWrap.AMGPreconBuilder()` instead.",
16+
:AMGCL_AMGPreconditioner)
1317
precon = new()
1418
precon.kwargs = kwargs
1519
precon
@@ -35,6 +39,8 @@ mutable struct AMGCL_RLXPreconditioner <: AbstractPreconditioner
3539
factorization::AMGCLWrap.RLXPrecon
3640
kwargs
3741
function ExtendableSparse.AMGCL_RLXPreconditioner(; kwargs...)
42+
Base.depwarn("AMGCL_RLXPreconditioner() is deprecated. Use LinearSolve with `precs=AMGCLWrap.RLXPreconBuilder()` instead.",
43+
:AMGCL_RLXPreconditioner)
3844
precon = new()
3945
precon.kwargs = kwargs
4046
precon

0 commit comments

Comments
 (0)