This repository has been archived by the owner on Mar 1, 2023. It is now read-only.
/
preconditioners.jl
140 lines (119 loc) · 3.24 KB
/
preconditioners.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
export AbstractPreconditioner,
ColumnwiseLUPreconditioner,
NoPreconditioner,
preconditioner_update!,
preconditioner_solve!,
preconditioner_counter_update!
"""
Abstract base type for all preconditioners.
"""
abstract type AbstractPreconditioner end
"""
mutable struct NoPreconditioner
end
Do nothing
"""
mutable struct NoPreconditioner <: AbstractPreconditioner end
"""
Do nothing, when there is no preconditioner, preconditioner = Nothing
"""
function preconditioner_update!(
op,
dg,
preconditioner::NoPreconditioner,
args...,
) end
"""
Do nothing, when there is no preconditioner, preconditioner = Nothing
"""
function preconditioner_solve!(preconditioner::NoPreconditioner, Q) end
"""
Do nothing, when there is no preconditioner, preconditioner = Nothing
"""
function preconditioner_counter_update!(preconditioner::NoPreconditioner) end
"""
mutable struct ColumnwiseLUPreconditioner{AT}
A::DGColumnBandedMatrix
Q::AT
PQ::AT
counter::Int
update_freq::Int
end
...
# Arguments
- `A`: the lu factor of the precondition (approximated Jacobian), in the DGColumnBandedMatrix format
- `Q`: MPIArray container, used to update A
- `PQ`: MPIArray container, used to update A
- `counter`: count the number of Newton, when counter > update_freq or counter < 0, update precondition
- `update_freq`: preconditioner update frequency
...
"""
mutable struct ColumnwiseLUPreconditioner{AT} <: AbstractPreconditioner
A::DGColumnBandedMatrix
Q::AT
PQ::AT
counter::Int
update_freq::Int
end
"""
ColumnwiseLUPreconditioner constructor
build an empty ColumnwiseLUPreconditioner
...
# Arguments
- `dg`: DG model, use only the grid information
- `Q0`: MPIArray, use only its size
- `counter`: = -1, which indicates the preconditioner is empty
- `update_freq`: preconditioner update frequency
...
"""
function ColumnwiseLUPreconditioner(dg, Q0, update_freq = 100)
single_column = false
Q = similar(Q0)
PQ = similar(Q0)
A = empty_banded_matrix(dg, Q; single_column = single_column)
# counter = -1, which indicates the preconditioner is empty
ColumnwiseLUPreconditioner(A, Q, PQ, -1, update_freq)
end
"""
update the DGColumnBandedMatrix by the finite difference approximation
...
# Arguments
- `op`: operator used to compute the finte difference information
- `dg`: the DG model, use only the grid information
...
"""
function preconditioner_update!(
op,
dg,
preconditioner::ColumnwiseLUPreconditioner,
args...,
)
# preconditioner.counter < 0, means newly constructed empty preconditioner
if preconditioner.counter >= 0 &&
(preconditioner.counter < preconditioner.update_freq)
return
end
A = preconditioner.A
Q = preconditioner.Q
PQ = preconditioner.PQ
update_banded_matrix!(A, op, dg, Q, PQ, args...)
band_lu!(A)
preconditioner.counter = 0
end
"""
Inplace applying the preconditioner
Q = P⁻¹ * Q
"""
function preconditioner_solve!(preconditioner::ColumnwiseLUPreconditioner, Q)
A = preconditioner.A
band_forward!(Q, A)
band_back!(Q, A)
end
"""
Update the preconditioner counter, after each Newton iteration
"""
function preconditioner_counter_update!(
preconditioner::ColumnwiseLUPreconditioner,
)
preconditioner.counter += 1
end