Skip to content

Commit e4d871b

Browse files
committed
Add dirichlet node elimination
1 parent b2fc788 commit e4d871b

File tree

7 files changed

+129
-1
lines changed

7 files changed

+129
-1
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
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 <juergen.fuhrmann@wias-berlin.de>"]
4-
version = "1.3.1"
4+
version = "1.4"
55

66
[deps]
77
AMGCLWrap = "4f76b812-4ba5-496d-b042-d70715554288"

docs/src/extsparse.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,13 @@ LinearAlgebra.lu!
1313
LinearAlgebra.ldiv!
1414
```
1515

16+
## Handling of homogeneous Dirichlet BC
17+
```@docs
18+
mark_dirichlet
19+
eliminate_dirichlet!
20+
eliminate_dirichlet
21+
```
22+
1623
## Test matrix creation
1724

1825
```@autodocs

src/ExtendableSparse.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ include("matrix/extendable.jl")
2828
export SparseMatrixLNK,
2929
ExtendableSparseMatrix, flush!, nnz, updateindex!, rawupdateindex!, colptrs, sparse
3030

31+
export eliminate_dirichlet, eliminate_dirichlet!, mark_dirichlet
32+
3133
include("factorizations/factorizations.jl")
3234

3335
export JacobiPreconditioner,

src/matrix/extendable.jl

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -596,3 +596,20 @@ function pointblock(A0::ExtendableSparseMatrix{Tv,Ti},blocksize) where {Tv,Ti}
596596
flush!(Ab)
597597
end
598598

599+
600+
function mark_dirichlet(A::ExtendableSparseMatrix;penalty=1.0e20)
601+
flush!(A)
602+
mark_dirichlet(A.cscmatrix;penalty)
603+
end
604+
605+
function eliminate_dirichlet(A::ExtendableSparseMatrix,dirichlet)
606+
flush!(A)
607+
ExtendableSparseMatrix(eliminate_dirichlet(A.cscmatrix,dirichlet))
608+
end
609+
610+
function eliminate_dirichlet!(A::ExtendableSparseMatrix,dirichlet)
611+
flush!(A)
612+
eliminate_dirichlet!(A.cscmatrix,dirichlet)
613+
A
614+
end
615+

src/matrix/sparsematrixcsc.jl

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,73 @@ end
8888
function pointblock(A::SparseMatrixCSC,blocksize)
8989
SparseMatrixCSC(pointblock(ExtendableSparseMatrix(A),blocksize))
9090
end
91+
92+
"""
93+
mark_dirichlet(A; penalty=1.0e20)
94+
95+
Return boolean vector marking Dirichlet nodes, known by `A[i,i]>=penalty`
96+
"""
97+
function mark_dirichlet(A::SparseMatrixCSC; penalty=1.0e20)
98+
(;colptr,rowval,nzval,n)=A
99+
dirichlet=zeros(Bool,n)
100+
for i=1:n
101+
for j=colptr[i]:colptr[i+1]-1
102+
if rowval[j]==i && nzval[j]>=penalty
103+
dirichlet[i]=true
104+
end
105+
end
106+
end
107+
dirichlet
108+
end
109+
110+
"""
111+
eliminate_dirichlet!(A,dirichlet_marker)
112+
113+
Eliminate dirichlet nodes in matrix by setting
114+
```julia
115+
A[:,i]=0; A[i,:]=0; A[i,i]=1
116+
```
117+
for a node `i` marked as Dirichlet.
118+
119+
Returns A.
120+
"""
121+
function eliminate_dirichlet!(A::SparseMatrixCSC,dirichlet)
122+
(;colptr,rowval,nzval,n)=A
123+
for i=1:n
124+
# set off-diagonal column indiced to zero
125+
if !iszero(dirichlet[i])
126+
for j=colptr[i]:colptr[i+1]-1
127+
if rowval[j]==i
128+
nzval[j]=1
129+
else
130+
nzval[j]=0
131+
end
132+
end
133+
end
134+
# set off-diagonal row indices to zero
135+
for j=colptr[i]:colptr[i+1]-1
136+
if rowval[j]!=i && !iszero(dirichlet[rowval[j]])
137+
nzval[j]=0
138+
end
139+
end
140+
end
141+
A
142+
end
143+
144+
"""
145+
eliminate_dirichlet(A,dirichlet_marker)
146+
147+
Create a copy B of A sharing the sparsity pattern.
148+
Eliminate dirichlet nodes in B by setting
149+
```julia
150+
B[:,i]=0; B[i,:]=0; B[i,i]=1
151+
```
152+
for a node `i` marked as Dirichlet.
153+
154+
Returns B.
155+
"""
156+
function eliminate_dirichlet(A::SparseMatrixCSC,dirichlet)
157+
(;m,n,colptr,rowval,nzval)=A
158+
B=SparseMatrixCSC(m,n,colptr,rowval,copy(nzval))
159+
eliminate_dirichlet!(B,dirichlet)
160+
end

test/runtests.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ using ForwardDiff
2424

2525
@testset "Backslash" begin include("test_backslash.jl") end
2626

27+
@testset "Dirichlet" begin include("test_dirichlet.jl") end
28+
2729
@testset "LinearSolve" begin include("test_linearsolve.jl") end
2830

2931
@testset "Preconditioners" begin include("test_preconditioners.jl") end

test/test_dirichlet.jl

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
module test_dirichlet
2+
using Test
3+
using ExtendableSparse
4+
using SparseArrays
5+
using LinearAlgebra
6+
7+
function tdirichlet(A)
8+
n=size(A,1)
9+
for i=1:10:n
10+
A[i,i]=1.0e30
11+
end
12+
f=ones(n)
13+
u=A\f
14+
diri=mark_dirichlet(A)
15+
fD=f.* (1 .-diri)
16+
AD=eliminate_dirichlet(A,diri)
17+
uD=AD\fD
18+
norm(uD-u,Inf) < 1.0e-20
19+
end
20+
21+
@test tdirichlet(fdrand(1000; matrixtype = SparseMatrixCSC))
22+
@test tdirichlet(fdrand(1000; matrixtype = ExtendableSparseMatrix))
23+
24+
@test tdirichlet(fdrand(20,20; matrixtype = SparseMatrixCSC))
25+
@test tdirichlet(fdrand(20,20; matrixtype = ExtendableSparseMatrix))
26+
27+
@test tdirichlet(fdrand(10,10,10, matrixtype = SparseMatrixCSC))
28+
@test tdirichlet(fdrand(10,10,10; matrixtype = ExtendableSparseMatrix))
29+
30+
end

0 commit comments

Comments
 (0)