ExaDG
Loading...
Searching...
No Matches
laplace_operator.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_POISSON_SPATIAL_DISCRETIZATION_LAPLACE_OPERATOR_H_
23#define EXADG_POISSON_SPATIAL_DISCRETIZATION_LAPLACE_OPERATOR_H_
24
25// ExaDG
26#include <exadg/grid/grid_data.h>
27#include <exadg/operators/interior_penalty_parameter.h>
28#include <exadg/operators/operator_base.h>
29#include <exadg/operators/operator_type.h>
30#include <exadg/poisson/user_interface/boundary_descriptor.h>
31
32namespace ExaDG
33{
34namespace Poisson
35{
36namespace Operators
37{
38struct LaplaceKernelData
39{
40 LaplaceKernelData() : IP_factor(1.0)
41 {
42 }
43
44 double IP_factor;
45};
46
47template<int dim, typename Number, int n_components = 1>
48class LaplaceKernel
49{
50private:
51 typedef dealii::LinearAlgebra::distributed::Vector<Number> VectorType;
52
53 typedef dealii::VectorizedArray<Number> scalar;
54
55 typedef FaceIntegrator<dim, n_components, Number> IntegratorFace;
56
57public:
58 LaplaceKernel() : degree(1), tau(dealii::make_vectorized_array<Number>(0.0))
59 {
60 }
61
62 void
63 reinit(dealii::MatrixFree<dim, Number> const & matrix_free,
64 LaplaceKernelData const & data_in,
65 unsigned int const dof_index)
66 {
67 data = data_in;
68
69 dealii::FiniteElement<dim> const & fe = matrix_free.get_dof_handler(dof_index).get_fe();
70 degree = fe.degree;
71
72 calculate_penalty_parameter(matrix_free, dof_index);
73 }
74
75 void
76 calculate_penalty_parameter(dealii::MatrixFree<dim, Number> const & matrix_free,
77 unsigned int const dof_index)
78 {
79 IP::calculate_penalty_parameter<dim, Number>(array_penalty_parameter, matrix_free, dof_index);
80 }
81
83 get_integrator_flags(bool const is_dg) const
84 {
85 IntegratorFlags flags;
86
87 flags.cell_evaluate = dealii::EvaluationFlags::gradients;
88 flags.cell_integrate = dealii::EvaluationFlags::gradients;
89
90 if(is_dg)
91 {
92 flags.face_evaluate = dealii::EvaluationFlags::values | dealii::EvaluationFlags::gradients;
93 flags.face_integrate = dealii::EvaluationFlags::values | dealii::EvaluationFlags::gradients;
94 }
95 else
96 {
97 // evaluation of Neumann BCs for continuous elements
98 flags.face_evaluate = dealii::EvaluationFlags::nothing;
99 flags.face_integrate = dealii::EvaluationFlags::values;
100 }
101
102 return flags;
103 }
104
105 static MappingFlags
106 get_mapping_flags(bool const compute_interior_face_integrals,
107 bool const compute_boundary_face_integrals)
108 {
109 MappingFlags flags;
110
111 flags.cells = dealii::update_gradients | dealii::update_JxW_values;
112
113 if(compute_interior_face_integrals)
114 {
115 flags.inner_faces =
116 dealii::update_gradients | dealii::update_JxW_values | dealii::update_normal_vectors;
117 }
118
119 if(compute_boundary_face_integrals)
120 {
121 flags.boundary_faces = dealii::update_gradients | dealii::update_JxW_values |
122 dealii::update_normal_vectors | dealii::update_quadrature_points;
123 }
124
125 return flags;
126 }
127
128 void
129 reinit_face(IntegratorFace & integrator_m,
130 IntegratorFace & integrator_p,
131 unsigned int const dof_index) const
132 {
133 tau = std::max(integrator_m.read_cell_data(array_penalty_parameter),
134 integrator_p.read_cell_data(array_penalty_parameter)) *
135 IP::get_penalty_factor<dim, Number>(
136 degree,
138 integrator_m.get_matrix_free().get_dof_handler(dof_index).get_triangulation()),
139 data.IP_factor);
140 }
141
142 void
143 reinit_boundary_face(IntegratorFace & integrator_m, unsigned int const dof_index) const
144 {
145 tau = integrator_m.read_cell_data(array_penalty_parameter) *
146 IP::get_penalty_factor<dim, Number>(
147 degree,
149 integrator_m.get_matrix_free().get_dof_handler(dof_index).get_triangulation()),
150 data.IP_factor);
151 }
152
153 void
154 reinit_face_cell_based(dealii::types::boundary_id const boundary_id,
155 IntegratorFace & integrator_m,
156 IntegratorFace & integrator_p,
157 unsigned int const dof_index) const
158 {
159 if(boundary_id == dealii::numbers::internal_face_boundary_id) // internal face
160 {
161 tau = std::max(integrator_m.read_cell_data(array_penalty_parameter),
162 integrator_p.read_cell_data(array_penalty_parameter)) *
163 IP::get_penalty_factor<dim, Number>(
164 degree,
166 integrator_m.get_matrix_free().get_dof_handler(dof_index).get_triangulation()),
167 data.IP_factor);
168 }
169 else // boundary face
170 {
171 tau = integrator_m.read_cell_data(array_penalty_parameter) *
172 IP::get_penalty_factor<dim, Number>(
173 degree,
175 integrator_m.get_matrix_free().get_dof_handler(dof_index).get_triangulation()),
176 data.IP_factor);
177 }
178 }
179
180 template<typename T>
181 inline DEAL_II_ALWAYS_INLINE //
182 T
183 calculate_gradient_flux(T const & value_m, T const & value_p) const
184 {
185 return -0.5 * (value_m - value_p);
186 }
187
188 template<typename T>
189 inline DEAL_II_ALWAYS_INLINE //
190 T
191 calculate_value_flux(T const & normal_gradient_m,
192 T const & normal_gradient_p,
193 T const & value_m,
194 T const & value_p) const
195 {
196 return 0.5 * (normal_gradient_m + normal_gradient_p) - tau * (value_m - value_p);
197 }
198
199private:
201
202 unsigned int degree;
203
204 dealii::AlignedVector<scalar> array_penalty_parameter;
205
206 mutable scalar tau;
207};
208
209} // namespace Operators
210
211template<int rank, int dim>
212struct LaplaceOperatorData : public OperatorBaseData
213{
214 LaplaceOperatorData() : OperatorBaseData(), quad_index_gauss_lobatto(0)
215 {
216 }
217
219
220 // continuous FE:
221 // for DirichletCached boundary conditions, another quadrature rule
222 // is needed to set the constrained DoFs.
223 unsigned int quad_index_gauss_lobatto;
224
225 std::shared_ptr<BoundaryDescriptor<rank, dim> const> bc;
226};
227
228template<int dim, typename Number, int n_components>
229class LaplaceOperator : public OperatorBase<dim, Number, n_components>
230{
231private:
232 static unsigned int const rank =
233 (n_components == 1) ? 0 : ((n_components == dim) ? 1 : dealii::numbers::invalid_unsigned_int);
234
235 typedef OperatorBase<dim, Number, n_components> Base;
237
238 typedef typename Base::IntegratorCell IntegratorCell;
239 typedef typename Base::IntegratorFace IntegratorFace;
240
241 typedef typename Base::Range Range;
242
243 typedef dealii::Tensor<rank, dim, dealii::VectorizedArray<Number>> value;
244
245 typedef typename Base::VectorType VectorType;
246
247public:
248 typedef Number value_type;
249
250 void
251 initialize(dealii::MatrixFree<dim, Number> const & matrix_free,
252 dealii::AffineConstraints<Number> const & affine_constraints,
253 LaplaceOperatorData<rank, dim> const & data);
254
256 get_data() const
257 {
258 return operator_data;
259 }
260
261 void
262 calculate_penalty_parameter(dealii::MatrixFree<dim, Number> const & matrix_free,
263 unsigned int const dof_index);
264
265 void
266 update_penalty_parameter();
267
268 // continuous FE: This function sets the inhomogeneous Dirichlet boundary values for Dirichlet
269 // degrees of freedom.
270 void
271 set_inhomogeneous_boundary_values(VectorType & solution) const final;
272
273 // only relevant for discontinuous Galerkin discretization (DG):
274 // Some more functionality on top of what is provided by the base class.
275 // This function evaluates the inhomogeneous boundary face integrals in DG where the
276 // Dirichlet boundary condition is extracted from a dof vector instead of a dealii::Function<dim>.
277 void
278 rhs_add_dirichlet_bc_from_dof_vector(VectorType & dst, VectorType const & src) const;
279
280private:
281 void
282 reinit_face_derived(IntegratorFace & integrator_m,
283 IntegratorFace & integrator_p,
284 unsigned int const face) const final;
285
286 void
287 reinit_boundary_face_derived(IntegratorFace & integrator_m, unsigned int const face) const final;
288
289 void
290 reinit_face_cell_based_derived(IntegratorFace & integrator_m,
291 IntegratorFace & integrator_p,
292 unsigned int const cell,
293 unsigned int const face,
294 dealii::types::boundary_id const boundary_id) const final;
295
296 void
297 do_cell_integral(IntegratorCell & integrator) const final;
298
299 void
300 do_face_integral(IntegratorFace & integrator_m, IntegratorFace & integrator_p) const final;
301
302 void
303 do_face_int_integral(IntegratorFace & integrator_m, IntegratorFace & integrator_p) const final;
304
305 void
306 do_face_ext_integral(IntegratorFace & integrator_m, IntegratorFace & integrator_p) const final;
307
308 void
309 do_boundary_integral(IntegratorFace & integrator_m,
310 OperatorType const & operator_type,
311 dealii::types::boundary_id const & boundary_id) const final;
312
313 void
314 cell_loop_empty(dealii::MatrixFree<dim, Number> const & matrix_free,
315 VectorType & dst,
316 VectorType const & src,
317 Range const & range) const;
318
319 void
320 face_loop_empty(dealii::MatrixFree<dim, Number> const & matrix_free,
321 VectorType & dst,
322 VectorType const & src,
323 Range const & range) const;
324
325 // only relevant for discontinuous Galerkin discretization (DG)
326 void
327 boundary_face_loop_inhom_operator_dirichlet_bc_from_dof_vector(
328 dealii::MatrixFree<dim, Number> const & matrix_free,
329 VectorType & dst,
330 VectorType const & src,
331 Range const & range) const;
332
333 // only relevant for discontinuous Galerkin discretization (DG)
334 void
335 do_boundary_integral_dirichlet_bc_from_dof_vector(
336 IntegratorFace & integrator_m,
337 OperatorType const & operator_type,
338 dealii::types::boundary_id const & boundary_id) const;
339
340 // continuous FE: calculates Neumann boundary integral
341 void
342 do_boundary_integral_continuous(IntegratorFace & integrator_m,
343 dealii::types::boundary_id const & boundary_id) const final;
344
345 LaplaceOperatorData<rank, dim> operator_data;
346
348};
349
350} // namespace Poisson
351} // namespace ExaDG
352
353#endif /* EXADG_POISSON_SPATIAL_DISCRETIZATION_LAPLACE_OPERATOR_H_ */
Definition laplace_operator.h:230
Definition laplace_operator.h:49
Definition driver.cpp:33
ElementType get_element_type(dealii::Triangulation< dim > const &tria)
Definition grid_data.h:70
Definition integrator_flags.h:31
Definition mapping_flags.h:31
Definition laplace_operator.h:213
Definition laplace_operator.h:39