ExaDG
Loading...
Searching...
No Matches
diffusive_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 CONV_DIFF_DIFFUSIVE_OPERATOR
23#define CONV_DIFF_DIFFUSIVE_OPERATOR
24
25#include <exadg/convection_diffusion/user_interface/boundary_descriptor.h>
26#include <exadg/convection_diffusion/user_interface/parameters.h>
27#include <exadg/operators/interior_penalty_parameter.h>
28#include <exadg/operators/operator_base.h>
29
30
31namespace ExaDG
32{
33namespace ConvDiff
34{
35namespace Operators
36{
38{
39 DiffusiveKernelData() : IP_factor(1.0), diffusivity(1.0)
40 {
41 }
42
43 double IP_factor;
44 double diffusivity;
45};
46
47template<int dim, typename Number>
49{
50private:
51 typedef dealii::LinearAlgebra::distributed::Vector<Number> VectorType;
52
53 typedef dealii::VectorizedArray<Number> scalar;
54 typedef dealii::Tensor<1, dim, dealii::VectorizedArray<Number>> vector;
55
56 typedef CellIntegrator<dim, 1, Number> IntegratorCell;
57 typedef FaceIntegrator<dim, 1, Number> IntegratorFace;
58
59public:
60 DiffusiveKernel() : degree(1), tau(dealii::make_vectorized_array<Number>(0.0))
61 {
62 }
63
64 void
65 reinit(dealii::MatrixFree<dim, Number> const & matrix_free,
66 DiffusiveKernelData const & data_in,
67 unsigned int const dof_index)
68 {
69 data = data_in;
70
71 dealii::FiniteElement<dim> const & fe = matrix_free.get_dof_handler(dof_index).get_fe();
72 degree = fe.degree;
73
74 calculate_penalty_parameter(matrix_free, dof_index);
75
76 AssertThrow(data.diffusivity > (0.0 - std::numeric_limits<double>::epsilon()),
77 dealii::ExcMessage("Diffusivity is not set!"));
78 }
79
80 void
81 calculate_penalty_parameter(dealii::MatrixFree<dim, Number> const & matrix_free,
82 unsigned int const dof_index)
83 {
84 IP::calculate_penalty_parameter<dim, Number>(array_penalty_parameter, matrix_free, dof_index);
85 }
86
88 get_integrator_flags() const
89 {
90 IntegratorFlags flags;
91
92 flags.cell_evaluate = dealii::EvaluationFlags::gradients;
93 flags.cell_integrate = dealii::EvaluationFlags::gradients;
94
95 flags.face_evaluate = dealii::EvaluationFlags::values | dealii::EvaluationFlags::gradients;
96 flags.face_integrate = dealii::EvaluationFlags::values | dealii::EvaluationFlags::gradients;
97
98 return flags;
99 }
100
101 static MappingFlags
102 get_mapping_flags(bool const compute_interior_face_integrals,
103 bool const compute_boundary_face_integrals)
104 {
105 MappingFlags flags;
106
107 flags.cells = dealii::update_gradients | dealii::update_JxW_values;
108 if(compute_interior_face_integrals)
109 flags.inner_faces =
110 dealii::update_gradients | dealii::update_JxW_values | dealii::update_normal_vectors;
111 if(compute_boundary_face_integrals)
112 flags.boundary_faces = dealii::update_gradients | dealii::update_JxW_values |
113 dealii::update_normal_vectors | dealii::update_quadrature_points;
114
115 return flags;
116 }
117
118 void
119 reinit_face(IntegratorFace & integrator_m,
120 IntegratorFace & integrator_p,
121 unsigned int const dof_index) const
122 {
123 tau = std::max(integrator_m.read_cell_data(array_penalty_parameter),
124 integrator_p.read_cell_data(array_penalty_parameter)) *
125 IP::get_penalty_factor<dim, Number>(
126 degree,
128 integrator_m.get_matrix_free().get_dof_handler(dof_index).get_triangulation()),
129 data.IP_factor);
130 }
131
132 void
133 reinit_boundary_face(IntegratorFace & integrator_m, unsigned int const dof_index) const
134 {
135 tau = integrator_m.read_cell_data(array_penalty_parameter) *
136 IP::get_penalty_factor<dim, Number>(
137 degree,
139 integrator_m.get_matrix_free().get_dof_handler(dof_index).get_triangulation()),
140 data.IP_factor);
141 }
142
143 void
144 reinit_face_cell_based(dealii::types::boundary_id const boundary_id,
145 IntegratorFace & integrator_m,
146 IntegratorFace & integrator_p,
147 unsigned int const dof_index) const
148 {
149 if(boundary_id == dealii::numbers::internal_face_boundary_id) // internal face
150 {
151 tau = std::max(integrator_m.read_cell_data(array_penalty_parameter),
152 integrator_p.read_cell_data(array_penalty_parameter)) *
153 IP::get_penalty_factor<dim, Number>(
154 degree,
156 integrator_m.get_matrix_free().get_dof_handler(dof_index).get_triangulation()),
157 data.IP_factor);
158 }
159 else // boundary face
160 {
161 tau = integrator_m.read_cell_data(array_penalty_parameter) *
162 IP::get_penalty_factor<dim, Number>(
163 degree,
165 integrator_m.get_matrix_free().get_dof_handler(dof_index).get_triangulation()),
166 data.IP_factor);
167 }
168 }
169
170
171 inline DEAL_II_ALWAYS_INLINE //
172 scalar
173 calculate_gradient_flux(scalar const & value_m, scalar const & value_p) const
174 {
175 return -0.5 * data.diffusivity * (value_m - value_p);
176 }
177
178 /*
179 * Calculation of gradient flux. Strictly speaking, this value is not a numerical flux since the
180 * flux is multiplied by the normal vector, i.e., "gradient_flux" = numerical_flux * normal, where
181 * normal denotes the normal vector of element e⁻.
182 */
183 inline DEAL_II_ALWAYS_INLINE //
184 scalar
185 calculate_value_flux(scalar const & normal_gradient_m,
186 scalar const & normal_gradient_p,
187 scalar const & value_m,
188 scalar const & value_p) const
189 {
190 return data.diffusivity *
191 (0.5 * (normal_gradient_m + normal_gradient_p) - tau * (value_m - value_p));
192 }
193
194 /*
195 * Volume flux, i.e., the term occurring in the volume integral
196 */
197 inline DEAL_II_ALWAYS_INLINE //
198 vector
199 get_volume_flux(IntegratorCell & integrator, unsigned int const q) const
200 {
201 return integrator.get_gradient(q) * data.diffusivity;
202 }
203
204private:
206
207 unsigned int degree;
208
209 dealii::AlignedVector<scalar> array_penalty_parameter;
210
211 mutable scalar tau;
212};
213
214} // namespace Operators
215
216
217template<int dim>
219{
221 {
222 }
223
225
226 std::shared_ptr<BoundaryDescriptor<dim> const> bc;
227};
228
229
230template<int dim, typename Number>
231class DiffusiveOperator : public OperatorBase<dim, Number, 1>
232{
233private:
235
236 typedef typename Base::IntegratorCell IntegratorCell;
237 typedef typename Base::IntegratorFace IntegratorFace;
238
239 typedef dealii::VectorizedArray<Number> scalar;
240 typedef dealii::Tensor<1, dim, dealii::VectorizedArray<Number>> vector;
241
242public:
243 void
244 initialize(dealii::MatrixFree<dim, Number> const & matrix_free,
245 dealii::AffineConstraints<Number> const & affine_constraints,
246 DiffusiveOperatorData<dim> const & data,
247 std::shared_ptr<Operators::DiffusiveKernel<dim, Number>> kernel);
248
249 void
250 update();
251
252private:
253 void
254 reinit_face_derived(IntegratorFace & integrator_m,
255 IntegratorFace & integrator_p,
256 unsigned int const face) const final;
257
258 void
259 reinit_boundary_face_derived(IntegratorFace & integrator_m, unsigned int const face) const final;
260
261 void
262 reinit_face_cell_based_derived(IntegratorFace & integrator_m,
263 IntegratorFace & integrator_p,
264 unsigned int const cell,
265 unsigned int const face,
266 dealii::types::boundary_id const boundary_id) const final;
267
268 void
269 do_cell_integral(IntegratorCell & integrator) const final;
270
271 void
272 do_face_integral(IntegratorFace & integrator_m, IntegratorFace & integrator_p) const final;
273
274 void
275 do_face_int_integral(IntegratorFace & integrator_m, IntegratorFace & integrator_p) const final;
276
277 void
278 do_face_ext_integral(IntegratorFace & integrator_m, IntegratorFace & integrator_p) const final;
279
280 void
281 do_boundary_integral(IntegratorFace & integrator_m,
282 OperatorType const & operator_type,
283 dealii::types::boundary_id const & boundary_id) const final;
284
285 DiffusiveOperatorData<dim> operator_data;
286
287 std::shared_ptr<Operators::DiffusiveKernel<dim, Number>> kernel;
288};
289} // namespace ConvDiff
290} // namespace ExaDG
291
292#endif
Definition diffusive_operator.h:232
Definition diffusive_operator.h:49
Definition operator_base.h:98
Definition driver.cpp:33
ElementType get_element_type(dealii::Triangulation< dim > const &tria)
Definition grid_data.h:70
Definition diffusive_operator.h:219
Definition diffusive_operator.h:38
Definition integrator_flags.h:30
Definition mapping_flags.h:31
Definition operator_base.h:59