Matrix Free Solver 1.0.0
A matrix free solver for the Advection Diffusion Reaction problem implemented with deal.II
Loading...
Searching...
No Matches
DTR_mf.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <deal.II/base/multithread_info.h>
4#include <deal.II/base/quadrature_lib.h>
5#include <deal.II/base/function.h>
6#include <deal.II/base/timer.h>
7
8#include <deal.II/lac/affine_constraints.h>
9#include <deal.II/lac/solver_cg.h>
10#include <deal.II/lac/la_parallel_vector.h>
11#include <deal.II/lac/precondition.h>
12
13#include <deal.II/fe/fe_q.h>
14#include <deal.II/fe/mapping_q1.h>
15
16#include <deal.II/grid/tria.h>
17#include <deal.II/grid/grid_generator.h>
18#include <deal.II/grid/grid_in.h>
19
20#include <deal.II/multigrid/multigrid.h>
21#include <deal.II/multigrid/mg_transfer_matrix_free.h>
22#include <deal.II/multigrid/mg_tools.h>
23#include <deal.II/multigrid/mg_coarse.h>
24#include <deal.II/multigrid/mg_smoother.h>
25#include <deal.II/multigrid/mg_matrix.h>
26
27#include <deal.II/numerics/data_out.h>
28#include <deal.II/numerics/vector_tools.h>
29
30// Include the matrix-free headers
31#include <deal.II/matrix_free/matrix_free.h>
32#include <deal.II/matrix_free/operators.h>
33#include <deal.II/matrix_free/fe_evaluation.h>
34
35#include <filesystem>
36#include <iostream>
37#include <fstream>
38
39const std::string output_dir = "./output_mf/";
40
41namespace DTR_mf
42{
43 using namespace dealii;
44
45 // To be efficient matrix-free implementation require knowledge of loop lengths at compile time
46 const unsigned int dim = 2;
47 const char bcs[4] = {'D', 'N', 'D', 'N'}; // left, right, bottom, top
48
49 template <int dim>
50 class DiffusionCoefficient : public Function<dim>
51 {
52 public:
53 virtual double value(const Point<dim> &p, const unsigned int component = 0) const override
54 {
55 return value<double>(p, component);
56 }
57
58 template <typename number>
59 number value(const Point<dim, number> & /*p*/, const unsigned int /*component*/ = 0) const
60 {
61 return 1.;
62 }
63 };
64
65 template <int dim>
66 class TransportCoefficient : public Function<dim>
67 {
68 public:
69 virtual void vector_value(const Point<dim> &p, Vector<double> &values) const override
70 {
71 return vector_value<double>(p, values);
72 }
73
74 template <typename number>
75 void vector_value(const Point<dim, number> & /*p*/, Vector<number> &values) const
76 {
77 values[0] = 1.;
78 values[1] = 0.;
79 }
80
81 virtual double value(const Point<dim> &p, const unsigned int component = 0) const override
82 {
83 return value<double>(p, component);
84 }
85
86 template <typename number>
87 number value(const Point<dim, number> & /*p*/, const unsigned int component = 0) const
88 {
89 if (component == 0)
90 return 1.;
91 else
92 return 0.;
93 }
94
95 template <typename number>
96 void tensor_value(const Point<dim, number> & /*p*/, Tensor<1, dim, number> &values) const
97 {
98 values[0] = 1.;
99 values[1] = 0.;
100 }
101 };
102
103 template <int dim>
104 class ReactionCoefficient : public Function<dim>
105 {
106 public:
107 virtual double value(const Point<dim> &p, const unsigned int component = 0) const override
108 {
109 return value<double>(p, component);
110 }
111
112 template <typename number>
113 number value(const Point<dim, number> & /*p*/, const unsigned int /*component*/ = 0) const
114 {
115 return 1.;
116 }
117 };
118
119 template <int dim>
120 class ForcingTerm : public Function<dim>
121 {
122 public:
123 virtual double value(const Point<dim> &p, const unsigned int component = 0) const override
124 {
125 return value<double>(p, component);
126 }
127
128 template <typename number>
129 number value(const Point<dim, number> &p, const unsigned int /*component*/ = 0) const
130 {
131 return number(1.) - number(2.) * exp(p[0]);
132 }
133 };
134
135 class DirichletBC1 : public Function<dim>
136 {
137 public:
138 virtual double value(const Point<dim> &p, const unsigned int component = 0) const override
139 {
140 return value<double>(p, component);
141 }
142 template <typename number>
143 double value(const Point<dim, number> & p, const unsigned int /*component*/ = 0) const
144 {
145 return number(2.)*exp(p[1]) - number(1.);
146 }
147 };
148
149 class DirichletBC2 : public Function<dim>
150 {
151 public:
152 virtual double value(const Point<dim> &p, const unsigned int component = 0) const override
153 {
154 return value<double>(p, component);
155 }
156 template <typename number>
157 double value(const Point<dim, number> & p, const unsigned int /*component*/ = 0) const
158 {
159 return number(2.)*exp(p[0]) - number(1.);
160 }
161 };
162
163 class NeumannBC1 : public Function<dim>
164 {
165 public:
166 virtual double value(const Point<dim> &p, const unsigned int component = 0) const override
167 {
168 return value<double>(p, component);
169 }
170
171 template <typename number>
172 number value(const Point<dim, number> &p, const unsigned int /*component*/ = 0) const
173 {
174 return number(2.)*exp(p[0]) * (number(2.)*exp(p[1]) - number(1.));
175 }
176 };
177
178 class NeumannBC2 : public Function<dim>
179 {
180 public:
181 virtual double value(const Point<dim> &p, const unsigned int component = 0) const override
182 {
183 return value<double>(p, component);
184 }
185
186 template <typename number>
187 number value(const Point<dim, number> &p, const unsigned int /*component*/ = 0) const
188 {
189 return number(2.)*exp(p[1]) * (number(2.)*exp(p[0]) - number(1.));
190 }
191 };
192
193 class ExactSolution : public Function<dim>
194 {
195 public:
196 virtual double value(const Point<dim> &p, const unsigned int /*component*/ = 0) const override
197 {
198 return (2.*exp(p[0]) - 1.)*(2.*exp(p[1]) - 1.);
199 }
200
201 virtual Tensor<1, dim> gradient(const Point<dim> &p, const unsigned int /*component*/ = 0) const override
202 {
203 Tensor<1, dim> result;
204
205 result[0] = 2.*exp(p[0]) * (2.*exp(p[1]) - 1.);
206 result[1] = 2.*exp(p[1]) * (2.*exp(p[0]) - 1.);
207
208 return result;
209 }
210 };
211
212 // The following class implements the DTR linear operation that is needed at each
213 // iteration of the linear solver. The fe_degree template argument is provided to the
214 // FEEvaluation class that needs it for efficiency
215 template <int dim, int fe_degree, typename number>
217 : public MatrixFreeOperators::
218 Base<dim, LinearAlgebra::distributed::Vector<number>>
219 {
220 public:
221 using value_type = number;
222
224
225 void clear() override;
226
227 void evaluate_coefficients(const DiffusionCoefficient<dim> &diffusion_function,
228 const TransportCoefficient<dim> &transport_function,
229 const ReactionCoefficient<dim> &reaction_function,
230 const ForcingTerm<dim> &forcing_term_function);
231
232 virtual void compute_diagonal() override;
233
234 const Table<2, VectorizedArray<number>> &get_diffusion_coefficient() const
235 {
236 return diffusion_coefficient;
237 }
238
239 const Table<2, Tensor<1, dim, VectorizedArray<number>>> &get_transport_coefficient() const
240 {
241 return transport_coefficient;
242 }
243
244 const Table<2, VectorizedArray<number>> &get_reaction_coefficient() const
245 {
246 return reaction_coefficient;
247 }
248
249 const Table<2, VectorizedArray<number>> &get_forcing_term_coefficient() const
250 {
251 return forcing_term_coefficient;
252 }
253
254 private:
255 virtual void apply_add(
256 LinearAlgebra::distributed::Vector<number> &dst,
257 const LinearAlgebra::distributed::Vector<number> &src) const override;
258
259 void
260 local_apply(const MatrixFree<dim, number> &data,
261 LinearAlgebra::distributed::Vector<number> &dst,
262 const LinearAlgebra::distributed::Vector<number> &src,
263 const std::pair<unsigned int, unsigned int> &cell_range) const;
264
265 void local_compute_diagonal(
266 const MatrixFree<dim, number> &data,
267 LinearAlgebra::distributed::Vector<number> &dst,
268 const unsigned int &dummy,
269 const std::pair<unsigned int, unsigned int> &cell_range) const;
270
271 Table<2, VectorizedArray<number>> diffusion_coefficient;
272 Table<2, Tensor<1, dim, VectorizedArray<number>>> transport_coefficient;
273 Table<2, VectorizedArray<number>> reaction_coefficient;
274 Table<2, VectorizedArray<number>> forcing_term_coefficient;
275 };
276
277 template <int dim, int degree_finite_element = 2>
279 {
280 public:
281 DTRProblem(bool verbose = true);
282 DTRProblem(std::ofstream& dimension_time_file, bool verbose = true);
283
294 void run(unsigned int n_initial_refinements = 3, unsigned int n_cycles = 9);
295 double compute_error(const VectorTools::NormType &norm_type) const;
296
297 unsigned int get_cells() const { return triangulation.n_global_active_cells(); }
298 unsigned int get_dofs() const { return dof_handler.n_dofs(); }
299 unsigned int get_fe_degree() const { return degree_finite_element; }
300
301 private:
302 void setup_system();
303 void assemble_rhs();
304 void solve();
305 void output_results(const unsigned int cycle) const;
306
307#ifdef DEAL_II_WITH_P4EST
308 parallel::distributed::Triangulation<dim> triangulation;
309#else
310 Triangulation<dim> triangulation;
311#endif
312
313 FE_Q<dim> fe;
314 DoFHandler<dim> dof_handler;
315
316 // Mapping with polynomial degree=1
317 MappingQ1<dim> mapping;
318
319 AffineConstraints<double> constraints;
320 using SystemMatrixType =
322 SystemMatrixType system_matrix;
323
324 MGConstrainedDoFs mg_constrained_dofs;
326 MGLevelObject<LevelMatrixType> mg_matrices;
327
328 LinearAlgebra::distributed::Vector<double> solution;
329 LinearAlgebra::distributed::Vector<double> lifting;
330 LinearAlgebra::distributed::Vector<double> system_rhs;
331
332 double setup_time;
333 ConditionalOStream pcout;
334 ConditionalOStream time_details;
335
336 DirichletBC1 dirichletBC1;
337 DirichletBC2 dirichletBC2;
338 NeumannBC1 neumannBC1;
339 NeumannBC2 neumannBC2;
340 };
341}
342
343#include "DTR_mf.cpp"
The DTROperation class implements the DTR linear operation needed at each iteration of the linear sol...
Definition DTR_mf.hpp:219
virtual void compute_diagonal() override
void clear() override
const Table< 2, Tensor< 1, dim, VectorizedArray< number > > > & get_transport_coefficient() const
Definition DTR_mf.hpp:239
void evaluate_coefficients(const problem_data::DiffusionCoefficient< dim > &diffusion_function, const problem_data::TransportCoefficient< dim > &transport_function, const problem_data::ReactionCoefficient< dim > &reaction_function, const problem_data::ForcingTerm< dim > &forcing_term_function)
Evaluate the coefficients of the DTR problem.
Definition DTR_mf.cpp:27
const Table< 2, VectorizedArray< number > > & get_diffusion_coefficient() const
Definition DTR_mf.hpp:234
number value_type
Definition DTR_mf.hpp:67
const Table< 2, VectorizedArray< number > > & get_forcing_term_coefficient() const
Definition DTR_mf.hpp:249
const Table< 2, VectorizedArray< number > > & get_reaction_coefficient() const
Definition DTR_mf.hpp:244
The DTRProblem class represents the DTR problem and provides methods to solve it.
Definition DTR_mf.hpp:279
DTRProblem(std::ofstream &dimension_time_file, bool verbose=true)
unsigned int get_cells() const
Definition DTR_mf.hpp:297
double compute_error(const VectorTools::NormType &norm_type) const
unsigned int get_dofs() const
Definition DTR_mf.hpp:298
DTRProblem(bool verbose=true)
void run(unsigned int n_initial_refinements=3, unsigned int n_cycles=9)
Compute the solution of the ADR problem. It executes the setup, rhs assembly, solve,...
unsigned int get_fe_degree() const
Definition DTR_mf.hpp:299
Definition DTR_mf.hpp:51
number value(const Point< dim, number > &, const unsigned int=0) const
Definition DTR_mf.hpp:59
virtual double value(const Point< dim > &p, const unsigned int component=0) const override
Definition DTR_mf.hpp:53
Definition DTR_mf.hpp:136
double value(const Point< dim, number > &p, const unsigned int=0) const
Definition DTR_mf.hpp:143
virtual double value(const Point< dim > &p, const unsigned int component=0) const override
Definition DTR_mf.hpp:138
Definition DTR_mf.hpp:150
double value(const Point< dim, number > &p, const unsigned int=0) const
Definition DTR_mf.hpp:157
virtual double value(const Point< dim > &p, const unsigned int component=0) const override
Definition DTR_mf.hpp:152
Definition DTR_mf.hpp:194
virtual Tensor< 1, dim > gradient(const Point< dim > &p, const unsigned int=0) const override
Definition DTR_mf.hpp:201
virtual double value(const Point< dim > &p, const unsigned int=0) const override
Definition DTR_mf.hpp:196
Definition DTR_mf.hpp:121
virtual double value(const Point< dim > &p, const unsigned int component=0) const override
Definition DTR_mf.hpp:123
number value(const Point< dim, number > &p, const unsigned int=0) const
Definition DTR_mf.hpp:129
Definition DTR_mf.hpp:164
virtual double value(const Point< dim > &p, const unsigned int component=0) const override
Definition DTR_mf.hpp:166
number value(const Point< dim, number > &p, const unsigned int=0) const
Definition DTR_mf.hpp:172
Definition DTR_mf.hpp:179
number value(const Point< dim, number > &p, const unsigned int=0) const
Definition DTR_mf.hpp:187
virtual double value(const Point< dim > &p, const unsigned int component=0) const override
Definition DTR_mf.hpp:181
Definition DTR_mf.hpp:105
number value(const Point< dim, number > &, const unsigned int=0) const
Definition DTR_mf.hpp:113
virtual double value(const Point< dim > &p, const unsigned int component=0) const override
Definition DTR_mf.hpp:107
Definition DTR_mf.hpp:67
number value(const Point< dim, number > &, const unsigned int component=0) const
Definition DTR_mf.hpp:87
virtual void vector_value(const Point< dim > &p, Vector< double > &values) const override
Definition DTR_mf.hpp:69
void vector_value(const Point< dim, number > &, Vector< number > &values) const
Definition DTR_mf.hpp:75
void tensor_value(const Point< dim, number > &, Tensor< 1, dim, number > &values) const
Definition DTR_mf.hpp:96
virtual double value(const Point< dim > &p, const unsigned int component=0) const override
Definition DTR_mf.hpp:81
const std::string output_dir
Definition DTR_mf.hpp:41
Definition DTR_mf.hpp:44
const char bcs[4]
Definition DTR_mf.hpp:47
const unsigned int dim
Definition DTR_mf.hpp:48