ExaDG
Loading...
Searching...
No Matches
check_multigrid.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_UTILITIES_CHECK_MULTIGRID_H_
23#define EXADG_SOLVERS_AND_PRECONDITIONERS_UTILITIES_CHECK_MULTIGRID_H_
24
25// C/C++
26#include <fstream>
27
28// deal.II
29#include <deal.II/lac/la_parallel_block_vector.h>
30#include <deal.II/numerics/data_out.h>
31
32// ExaDG
33#include <exadg/postprocessor/output_data_base.h>
34#include <exadg/postprocessor/write_output.h>
35
36namespace ExaDG
37{
38template<int dim, typename Number, typename Operator, typename Preconditioner>
39class CheckMultigrid
40{
41public:
42 typedef dealii::LinearAlgebra::distributed::Vector<Number> VectorType;
43
44 typedef dealii::LinearAlgebra::distributed::Vector<typename Preconditioner::MultigridNumber>
45 VectorTypeMG;
46
47 CheckMultigrid(Operator const & underlying_operator_in,
48 std::shared_ptr<Preconditioner> preconditioner_in,
49 MPI_Comm const & mpi_comm_in)
50 : underlying_operator(underlying_operator_in),
51 preconditioner(preconditioner_in),
52 mpi_comm(mpi_comm_in)
53 {
54 }
55
56 /*
57 * Function that verifies the multigrid algorithm,
58 * especially the smoothing (on the finest level) via
59 * applying the whole multigrid cycle to a random solution vector
60 *
61 *
62 * Richardson iteration: x^{k+1} = x^{k} + M^{-1} * ( b - A*x^{k} )
63 *
64 * A: system matrix
65 * M^{-1}: preconditioner (should approximate A^{-1})
66 *
67 * rhs vector b: b = 0 (-> x_ex = 0)
68 * initial guess x^{0} = rand()
69 *
70 * --> calculate x^{1} = x^{0} - M^{-1}*A*x^{0}
71 * --> If multigrid cycle works well, x^{1} should be small (entries < 0.1)
72 */
73 void
74 check()
75 {
76 /*
77 * Whole MG Cycle
78 */
79 VectorType initial_solution;
80 underlying_operator.initialize_dof_vector(initial_solution);
81 VectorType solution_after_mg_cycle(initial_solution), tmp(initial_solution);
82
83 for(unsigned int i = 0; i < initial_solution.locally_owned_size(); ++i)
84 initial_solution.local_element(i) = (double)rand() / RAND_MAX;
85
86 underlying_operator.vmult(tmp, initial_solution);
87 tmp *= -1.0;
88 preconditioner->vmult(solution_after_mg_cycle, tmp);
89 solution_after_mg_cycle += initial_solution;
90
91 /*
92 * Smoothing
93 */
94
95 VectorTypeMG initial_solution_float;
96 initial_solution_float = initial_solution;
97 VectorTypeMG solution_after_smoothing, tmp_float;
98 solution_after_smoothing = initial_solution;
99 tmp_float = tmp;
100
101 preconditioner->apply_smoother_on_fine_level(solution_after_smoothing, tmp_float);
102 solution_after_smoothing += initial_solution_float;
103
104 /*
105 * Output
106 */
107 write_output(initial_solution, solution_after_mg_cycle, solution_after_smoothing);
108
109 /*
110 * Terminate simulation
111 */
112 // std::abort();
113 }
114
115 void
116 write_output(VectorType const & initial_solution,
117 VectorType const & solution_after_mg_cycle,
118 VectorTypeMG const & solution_after_smoothing) const
119 {
120 OutputDataBase output_data;
121 output_data.filename = "smoothing";
122 unsigned int const dof_index = underlying_operator.get_dof_index();
123 output_data.degree =
124 underlying_operator.get_matrix_free().get_dof_handler(dof_index).get_fe().degree;
125
126 VectorWriter<dim, Number> vector_writer(output_data, 0 /* output_counter */, mpi_comm);
127
128 unsigned int const n_components =
129 underlying_operator.get_matrix_free().get_dof_handler(dof_index).get_fe().n_components();
130 dealii::DoFHandler<dim> const & dof_handler =
131 underlying_operator.get_matrix_free().get_dof_handler(dof_index);
132 if(n_components == 1)
133 {
134 vector_writer.add_data_vector(initial_solution, dof_handler, {"initial"});
135 vector_writer.add_data_vector(solution_after_mg_cycle, dof_handler, {"after_mg_cycle"});
136 vector_writer.add_data_vector(solution_after_smoothing, dof_handler, {"after_smoothing"});
137 }
138 else
139 {
140 std::vector<bool> component_is_part_of_vector(dim, true);
141 std::vector<std::string> component_names(dim, "initial");
142
143 vector_writer.add_data_vector(initial_solution,
144 dof_handler,
145 component_names,
146 component_is_part_of_vector);
147
148 std::fill(component_names.begin(), component_names.end(), "after_mg_cycle");
149 vector_writer.add_data_vector(solution_after_mg_cycle,
150 dof_handler,
151 component_names,
152 component_is_part_of_vector);
153
154 std::fill(component_names.begin(), component_names.end(), "after_smoothing");
155 vector_writer.add_data_vector(solution_after_smoothing,
156 dof_handler,
157 component_names,
158 component_is_part_of_vector);
159 }
160
161 vector_writer.write_pvtu();
162 }
163
164private:
165 Operator const & underlying_operator;
166
167 std::shared_ptr<Preconditioner> preconditioner;
168
169 MPI_Comm mpi_comm;
170};
171
172} // namespace ExaDG
173
174#endif /* EXADG_SOLVERS_AND_PRECONDITIONERS_UTILITIES_CHECK_MULTIGRID_H_ */
Definition write_output.h:161
Definition driver.cpp:33
Definition output_data_base.h:32