ExaDG
Loading...
Searching...
No Matches
jacobi_smoother.h
1/* ______________________________________________________________________
2 *
3 * ExaDG - High-Order Discontinuous Galerkin for the Exa-Scale
4 *
5 * Copyright (C) 2021 by the ExaDG authors
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 * ______________________________________________________________________
20 */
21
22#ifndef EXADG_SOLVERS_AND_PRECONDITIONERS_MULTIGRID_SMOOTHERS_JACOBI_SMOOTHER_H_
23#define EXADG_SOLVERS_AND_PRECONDITIONERS_MULTIGRID_SMOOTHERS_JACOBI_SMOOTHER_H_
24
25// ExaDG
26#include <exadg/solvers_and_preconditioners/multigrid/multigrid_parameters.h>
27#include <exadg/solvers_and_preconditioners/multigrid/smoothers/smoother_base.h>
28#include <exadg/solvers_and_preconditioners/preconditioners/additive_schwarz_preconditioner.h>
29#include <exadg/solvers_and_preconditioners/preconditioners/block_jacobi_preconditioner.h>
30#include <exadg/solvers_and_preconditioners/preconditioners/jacobi_preconditioner.h>
31
32namespace ExaDG
33{
34template<typename Operator, typename VectorType>
35class JacobiSmoother : public SmootherBase<VectorType>
36{
37public:
38 JacobiSmoother() : underlying_operator(nullptr), preconditioner(nullptr)
39 {
40 }
41
42 ~JacobiSmoother()
43 {
44 delete preconditioner;
45 preconditioner = nullptr;
46 }
47
48 JacobiSmoother(JacobiSmoother const &) = delete;
49
50 JacobiSmoother &
51 operator=(JacobiSmoother const &) = delete;
52
54 {
59 : preconditioner(PreconditionerSmoother::PointJacobi),
60 number_of_smoothing_steps(5),
61 damping_factor(1.0)
62 {
63 }
64
65 // preconditioner
66 PreconditionerSmoother preconditioner;
67
68 // number of iterations per smoothing step
69 unsigned int number_of_smoothing_steps;
70
71 // damping factor
72 double damping_factor;
73 };
74
75 void
76 setup(Operator const & operator_in,
77 bool const initialize_preconditioner,
78 AdditionalData const & additional_data_in)
79 {
80 underlying_operator = &operator_in;
81
82 data = additional_data_in;
83
84 if(data.preconditioner == PreconditionerSmoother::PointJacobi)
85 {
86 preconditioner =
87 new JacobiPreconditioner<Operator>(*underlying_operator, initialize_preconditioner);
88 }
89 else if(data.preconditioner == PreconditionerSmoother::BlockJacobi)
90 {
91 preconditioner =
92 new BlockJacobiPreconditioner<Operator>(*underlying_operator, initialize_preconditioner);
93 }
94 else if(data.preconditioner == PreconditionerSmoother::AdditiveSchwarz)
95 {
96 preconditioner = new AdditiveSchwarzPreconditioner<Operator>(*underlying_operator,
97 initialize_preconditioner);
98 }
99 else
100 {
101 AssertThrow(data.preconditioner == PreconditionerSmoother::PointJacobi or
102 data.preconditioner == PreconditionerSmoother::BlockJacobi,
103 dealii::ExcMessage(
104 "Specified type of preconditioner for Jacobi smoother not implemented."));
105 }
106 }
107
108 void
109 update() final
110 {
111 if(preconditioner != nullptr)
112 preconditioner->update();
113 }
114
115 /*
116 * Approximately solve linear system of equations (b=src, x=dst)
117 *
118 * A*x = b (r=b-A*x)
119 *
120 * using the iteration
121 *
122 * x^{k+1} = x^{k} + omega * P^{-1} * r^{k}
123 *
124 * where
125 *
126 * omega: damping factor
127 * P: preconditioner
128 */
129 void
130 vmult(VectorType & dst, VectorType const & src) const final
131 {
132 dst = 0;
133
134 VectorType tmp(src), residual(src);
135
136 for(unsigned int k = 0; k < data.number_of_smoothing_steps; ++k)
137 {
138 if(k > 0)
139 {
140 // calculate residual r^{k} = src - A * x^{k}
141 underlying_operator->vmult(residual, dst);
142 residual.sadd(-1.0, 1.0, src);
143 }
144 else // we do not have to evaluate the residual for k=0 since dst = 0
145 {
146 residual = src;
147 }
148
149 // apply preconditioner: tmp = P^{-1} * residual
150 preconditioner->vmult(tmp, residual);
151
152 // x^{k+1} = x^{k} + damping_factor * tmp
153 dst.add(data.damping_factor, tmp);
154 }
155 }
156
157 void
158 step(VectorType & dst, VectorType const & src) const final
159 {
160 VectorType tmp(src), residual(src);
161
162 for(unsigned int k = 0; k < data.number_of_smoothing_steps; ++k)
163 {
164 // calculate residual r^{k} = src - A * x^{k}
165 underlying_operator->vmult(residual, dst);
166 residual.sadd(-1.0, 1.0, src);
167
168 // apply preconditioner: tmp = P^{-1} * residual
169 preconditioner->vmult(tmp, residual);
170
171 // x^{k+1} = x^{k} + damping_factor * tmp
172 dst.add(data.damping_factor, tmp);
173 }
174 }
175
176private:
177 Operator const * underlying_operator;
178
179 AdditionalData data;
180
181 PreconditionerBase<typename Operator::value_type> * preconditioner;
182};
183
184} // namespace ExaDG
185
186#endif /* EXADG_SOLVERS_AND_PRECONDITIONERS_MULTIGRID_SMOOTHERS_JACOBI_SMOOTHER_H_ */
Definition jacobi_preconditioner.h:35
Definition smoother_base.h:29
Definition driver.cpp:33
Definition jacobi_smoother.h:54
AdditionalData()
Definition jacobi_smoother.h:58