ExaDG
Loading...
Searching...
No Matches
chebyshev_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 INCLUDE_SOLVERS_AND_PRECONDITIONERS_CHEBYSHEVSMOOTHER_H_
23#define INCLUDE_SOLVERS_AND_PRECONDITIONERS_CHEBYSHEVSMOOTHER_H_
24
25// deal.II
26#include <deal.II/lac/precondition.h>
27
28// ExaDG
29#include <exadg/solvers_and_preconditioners/multigrid/multigrid_parameters.h>
30#include <exadg/solvers_and_preconditioners/multigrid/smoothers/smoother_base.h>
31#include <exadg/solvers_and_preconditioners/preconditioners/additive_schwarz_preconditioner.h>
32#include <exadg/solvers_and_preconditioners/preconditioners/block_jacobi_preconditioner.h>
33#include <exadg/solvers_and_preconditioners/preconditioners/jacobi_preconditioner.h>
34
35namespace ExaDG
36{
37template<typename Operator, typename VectorType>
38class ChebyshevSmoother : public SmootherBase<VectorType>
39{
40public:
41 typedef dealii::PreconditionChebyshev<Operator, VectorType, JacobiPreconditioner<Operator>>
42 ChebyshevPointJacobi;
43 typedef dealii::PreconditionChebyshev<Operator, VectorType, BlockJacobiPreconditioner<Operator>>
44 ChebyshevBlockJacobi;
45 typedef dealii::
46 PreconditionChebyshev<Operator, VectorType, AdditiveSchwarzPreconditioner<Operator>>
47 ChebyshevAdditiveSchwarz;
48
49 ChebyshevSmoother() : underlying_operator(nullptr)
50 {
51 }
52
54 {
59 : preconditioner(PreconditionerSmoother::PointJacobi),
60 smoothing_range(20),
61 degree(5),
62 iterations_eigenvalue_estimation(20)
63 {
64 }
65
66 // preconditioner
67 PreconditionerSmoother preconditioner;
68
69 // sets the smoothing range (range of eigenvalues to be smoothed)
70 double smoothing_range;
71
72 // degree of Chebyshev smoother
73 unsigned int degree;
74
75 // number of CG iterations for estimation of eigenvalues
76 unsigned int iterations_eigenvalue_estimation;
77 };
78
79 void
80 vmult(VectorType & dst, VectorType const & src) const final
81 {
82 if(data.preconditioner == PreconditionerSmoother::PointJacobi)
83 {
84 chebyshev_point_jacobi->vmult(dst, src);
85 }
86 else if(data.preconditioner == PreconditionerSmoother::BlockJacobi)
87 {
88 chebyshev_block_jacobi->vmult(dst, src);
89 }
90 else if(data.preconditioner == PreconditionerSmoother::AdditiveSchwarz)
91 {
92 chebyshev_additive_schwarz->vmult(dst, src);
93 }
94 else
95 {
96 AssertThrow(false, dealii::ExcNotImplemented());
97 }
98 }
99
100 void
101 step(VectorType & dst, VectorType const & src) const final
102 {
103 if(data.preconditioner == PreconditionerSmoother::PointJacobi)
104 {
105 chebyshev_point_jacobi->step(dst, src);
106 }
107 else if(data.preconditioner == PreconditionerSmoother::BlockJacobi)
108 {
109 chebyshev_block_jacobi->step(dst, src);
110 }
111 else if(data.preconditioner == PreconditionerSmoother::AdditiveSchwarz)
112 {
113 chebyshev_additive_schwarz->step(dst, src);
114 }
115 else
116 {
117 AssertThrow(false, dealii::ExcNotImplemented());
118 }
119 }
120
121 void
122 update() final
123 {
124 AssertThrow(underlying_operator != nullptr,
125 dealii::ExcMessage("Pointer underlying_operator is uninitialized."));
126
127 if(data.preconditioner == PreconditionerSmoother::PointJacobi)
128 {
129 preconditioner_point_jacobi->update();
130 chebyshev_point_jacobi->initialize(*underlying_operator, additional_data_point);
131 }
132 else if(data.preconditioner == PreconditionerSmoother::BlockJacobi)
133 {
134 preconditioner_block_jacobi->update();
135 chebyshev_block_jacobi->initialize(*underlying_operator, additional_data_block);
136 }
137 else if(data.preconditioner == PreconditionerSmoother::AdditiveSchwarz)
138 {
139 preconditioner_additive_schwarz->update();
140 chebyshev_additive_schwarz->initialize(*underlying_operator,
141 additional_data_additive_schwarz);
142 }
143 else
144 {
145 AssertThrow(false, dealii::ExcNotImplemented());
146 }
147 }
148
149 void
150 setup(Operator const & operator_in,
151 bool const initialize_preconditioner,
152 AdditionalData const & additional_data)
153 {
154 underlying_operator = &operator_in;
155 data = additional_data;
156
157 if(data.preconditioner == PreconditionerSmoother::PointJacobi)
158 {
159 preconditioner_point_jacobi =
160 std::make_shared<JacobiPreconditioner<Operator>>(*underlying_operator,
161 initialize_preconditioner);
162
163 additional_data_point.preconditioner = preconditioner_point_jacobi;
164 additional_data_point.smoothing_range = data.smoothing_range;
165 additional_data_point.degree = data.degree;
166 additional_data_point.eig_cg_n_iterations = data.iterations_eigenvalue_estimation;
167
168 chebyshev_point_jacobi = std::make_shared<ChebyshevPointJacobi>();
169
170 if(initialize_preconditioner)
171 chebyshev_point_jacobi->initialize(*underlying_operator, additional_data_point);
172 }
173 else if(data.preconditioner == PreconditionerSmoother::BlockJacobi)
174 {
175 preconditioner_block_jacobi =
176 std::make_shared<BlockJacobiPreconditioner<Operator>>(*underlying_operator,
177 initialize_preconditioner);
178
179 additional_data_block.preconditioner = preconditioner_block_jacobi;
180 additional_data_block.smoothing_range = data.smoothing_range;
181 additional_data_block.degree = data.degree;
182 additional_data_block.eig_cg_n_iterations = data.iterations_eigenvalue_estimation;
183
184 chebyshev_block_jacobi = std::make_shared<ChebyshevBlockJacobi>();
185
186 if(initialize_preconditioner)
187 chebyshev_block_jacobi->initialize(*underlying_operator, additional_data_block);
188 }
189 else if(data.preconditioner == PreconditionerSmoother::AdditiveSchwarz)
190 {
191 preconditioner_additive_schwarz =
192 std::make_shared<AdditiveSchwarzPreconditioner<Operator>>(*underlying_operator,
193 initialize_preconditioner);
194
195 additional_data_additive_schwarz.preconditioner = preconditioner_additive_schwarz;
196 additional_data_additive_schwarz.smoothing_range = data.smoothing_range;
197 additional_data_additive_schwarz.degree = data.degree;
198 additional_data_additive_schwarz.eig_cg_n_iterations = data.iterations_eigenvalue_estimation;
199
200 chebyshev_additive_schwarz = std::make_shared<ChebyshevAdditiveSchwarz>();
201
202 if(initialize_preconditioner)
203 chebyshev_additive_schwarz->initialize(*underlying_operator,
204 additional_data_additive_schwarz);
205 }
206 else
207 {
208 AssertThrow(false, dealii::ExcNotImplemented());
209 }
210 }
211
212private:
213 Operator const * underlying_operator;
214 AdditionalData data;
215
216 std::shared_ptr<ChebyshevPointJacobi> chebyshev_point_jacobi;
217 std::shared_ptr<ChebyshevBlockJacobi> chebyshev_block_jacobi;
218 std::shared_ptr<ChebyshevAdditiveSchwarz> chebyshev_additive_schwarz;
219
220 std::shared_ptr<JacobiPreconditioner<Operator>> preconditioner_point_jacobi;
221 std::shared_ptr<BlockJacobiPreconditioner<Operator>> preconditioner_block_jacobi;
222 std::shared_ptr<AdditiveSchwarzPreconditioner<Operator>> preconditioner_additive_schwarz;
223
224 typename ChebyshevPointJacobi::AdditionalData additional_data_point;
225 typename ChebyshevBlockJacobi::AdditionalData additional_data_block;
226 typename ChebyshevAdditiveSchwarz::AdditionalData additional_data_additive_schwarz;
227};
228
229} // namespace ExaDG
230
231#endif /* INCLUDE_SOLVERS_AND_PRECONDITIONERS_CHEBYSHEVSMOOTHER_H_ */
Definition chebyshev_smoother.h:39
Definition smoother_base.h:29
Definition driver.cpp:33
Definition chebyshev_smoother.h:54
AdditionalData()
Definition chebyshev_smoother.h:58