ExaDG
Loading...
Searching...
No Matches
continuity_penalty_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_INCOMPRESSIBLE_NAVIER_STOKES_SPATIAL_DISCRETIZATION_OPERATORS_CONTINUITY_PENALTY_OPERATOR_H_
23#define EXADG_INCOMPRESSIBLE_NAVIER_STOKES_SPATIAL_DISCRETIZATION_OPERATORS_CONTINUITY_PENALTY_OPERATOR_H_
24
25// ExaDG
26#include <exadg/grid/calculate_characteristic_element_length.h>
27#include <exadg/incompressible_navier_stokes/user_interface/boundary_descriptor.h>
28#include <exadg/incompressible_navier_stokes/user_interface/parameters.h>
29#include <exadg/matrix_free/integrators.h>
30#include <exadg/operators/integrator_flags.h>
31#include <exadg/operators/mapping_flags.h>
32#include <exadg/operators/operator_type.h>
33
34namespace ExaDG
35{
36namespace IncNS
37{
38/*
39 * Continuity penalty operator:
40 *
41 * ( v_h , tau_conti * jump(u_h) )_dOmega^e
42 *
43 * where
44 *
45 * v_h : test function
46 * u_h : solution
47 *
48 * jump(u_h) = u_h^{-} - u_h^{+} or ( (u_h^{-} - u_h^{+})*normal ) * normal
49 *
50 * where "-" denotes interior information and "+" exterior information
51 *
52 * tau_conti: continuity penalty factor
53 *
54 * use convective term: tau_conti_conv = K * ||U||_mean
55 *
56 * use viscous term: tau_conti_viscous = K * nu / h
57 *
58 * where h_eff = h / (k_u+1) with a characteristic
59 * element length h derived from the element volume V_e
60 *
61 * use both terms: tau_conti = tau_conti_conv + tau_conti_viscous
62 */
63
64namespace Operators
65{
66struct ContinuityPenaltyKernelData
67{
68 ContinuityPenaltyKernelData()
69 : type_penalty_parameter(TypePenaltyParameter::ConvectiveTerm),
70 which_components(ContinuityPenaltyComponents::Normal),
71 viscosity(0.0),
72 degree(1),
73 penalty_factor(1.0)
74 {
75 }
76
77 // type of penalty parameter (viscous and/or convective terms)
78 TypePenaltyParameter type_penalty_parameter;
79
80 // the continuity penalty term can be applied to all velocity components or to the normal
81 // component only
82 ContinuityPenaltyComponents which_components;
83
84 // viscosity, needed for computation of penalty factor
85 double viscosity;
86
87 // degree of finite element shape functions
88 unsigned int degree;
89
90 // the penalty term can be scaled by 'penalty_factor'
91 double penalty_factor;
92};
93
94template<int dim, typename Number>
95class ContinuityPenaltyKernel
96{
97private:
98 typedef CellIntegrator<dim, dim, Number> IntegratorCell;
99 typedef FaceIntegrator<dim, dim, Number> IntegratorFace;
100
101 typedef dealii::LinearAlgebra::distributed::Vector<Number> VectorType;
102
103 typedef dealii::VectorizedArray<Number> scalar;
104 typedef dealii::Tensor<1, dim, dealii::VectorizedArray<Number>> vector;
105
106public:
107 ContinuityPenaltyKernel()
108 : matrix_free(nullptr), dof_index(0), quad_index(0), array_penalty_parameter(0)
109 {
110 }
111
112 void
113 reinit(dealii::MatrixFree<dim, Number> const & matrix_free,
114 unsigned int const dof_index,
115 unsigned int const quad_index,
116 ContinuityPenaltyKernelData const & data)
117 {
118 this->matrix_free = &matrix_free;
119
120 this->dof_index = dof_index;
121 this->quad_index = quad_index;
122
123 this->data = data;
124
125 unsigned int n_cells = matrix_free.n_cell_batches() + matrix_free.n_ghost_cell_batches();
126 array_penalty_parameter.resize(n_cells);
127 }
128
130 get_data()
131 {
132 return this->data;
133 }
134
136 get_integrator_flags() const
137 {
138 IntegratorFlags flags;
139
140 // no cell integrals
141
142 flags.face_evaluate = dealii::EvaluationFlags::values;
143 flags.face_integrate = dealii::EvaluationFlags::values;
144
145 return flags;
146 }
147
148 static MappingFlags
149 get_mapping_flags()
150 {
151 MappingFlags flags;
152
153 // no cell integrals
154
155 flags.inner_faces = dealii::update_JxW_values | dealii::update_normal_vectors;
156 flags.boundary_faces =
157 dealii::update_JxW_values | dealii::update_normal_vectors | dealii::update_quadrature_points;
158
159 return flags;
160 }
161
162 void
163 calculate_penalty_parameter(VectorType const & velocity)
164 {
165 velocity.update_ghost_values();
166
167 IntegratorCell integrator(*matrix_free, dof_index, quad_index);
168
169 dealii::AlignedVector<scalar> JxW_values(integrator.n_q_points);
170
171 ElementType const element_type =
172 get_element_type(matrix_free->get_dof_handler(dof_index).get_triangulation());
173
174 unsigned int n_cells = matrix_free->n_cell_batches() + matrix_free->n_ghost_cell_batches();
175 for(unsigned int cell = 0; cell < n_cells; ++cell)
176 {
177 integrator.reinit(cell);
178 integrator.read_dof_values(velocity);
179 integrator.evaluate(dealii::EvaluationFlags::values);
180 scalar volume = dealii::make_vectorized_array<Number>(0.0);
181 scalar norm_U_mean = dealii::make_vectorized_array<Number>(0.0);
182
183 for(unsigned int q = 0; q < integrator.n_q_points; ++q)
184 {
185 volume += integrator.JxW(q);
186 norm_U_mean += integrator.JxW(q) * integrator.get_value(q).norm();
187 }
188
189 norm_U_mean /= volume;
190
191 scalar tau_convective = norm_U_mean;
192 scalar h = calculate_characteristic_element_length(volume, dim, element_type);
193 scalar h_eff = calculate_high_order_element_length(h, data.degree, true);
194 scalar tau_viscous = dealii::make_vectorized_array<Number>(data.viscosity) / h_eff;
195
196 if(data.type_penalty_parameter == TypePenaltyParameter::ConvectiveTerm)
197 {
198 array_penalty_parameter[cell] = data.penalty_factor * tau_convective;
199 }
200 else if(data.type_penalty_parameter == TypePenaltyParameter::ViscousTerm)
201 {
202 array_penalty_parameter[cell] = data.penalty_factor * tau_viscous;
203 }
204 else if(data.type_penalty_parameter == TypePenaltyParameter::ViscousAndConvectiveTerms)
205 {
206 array_penalty_parameter[cell] = data.penalty_factor * (tau_convective + tau_viscous);
207 }
208 }
209 }
210
211 void
212 reinit_face(IntegratorFace & integrator_m, IntegratorFace & integrator_p) const
213 {
214 tau = 0.5 * (integrator_m.read_cell_data(array_penalty_parameter) +
215 integrator_p.read_cell_data(array_penalty_parameter));
216 }
217
218 void
219 reinit_boundary_face(IntegratorFace & integrator_m) const
220 {
221 tau = integrator_m.read_cell_data(array_penalty_parameter);
222 }
223
224 void
225 reinit_face_cell_based(dealii::types::boundary_id const boundary_id,
226 IntegratorFace & integrator_m,
227 IntegratorFace & integrator_p) const
228 {
229 if(boundary_id == dealii::numbers::internal_face_boundary_id) // internal face
230 {
231 tau = 0.5 * (integrator_m.read_cell_data(array_penalty_parameter) +
232 integrator_p.read_cell_data(array_penalty_parameter));
233 }
234 else // boundary face
235 {
236 tau = integrator_m.read_cell_data(array_penalty_parameter);
237 }
238 }
239
240 inline DEAL_II_ALWAYS_INLINE //
241 vector
242 calculate_flux(vector const & u_m, vector const & u_p, vector const & normal_m) const
243 {
244 vector jump_value = u_m - u_p;
245
246 vector flux;
247
248 if(data.which_components == ContinuityPenaltyComponents::All)
249 {
250 // penalize all velocity components
251 flux = tau * jump_value;
252 }
253 else if(data.which_components == ContinuityPenaltyComponents::Normal)
254 {
255 flux = tau * (jump_value * normal_m) * normal_m;
256 }
257 else
258 {
259 AssertThrow(false, dealii::ExcMessage("not implemented."));
260 }
261
262 return flux;
263 }
264
265
266private:
267 dealii::MatrixFree<dim, Number> const * matrix_free;
268
269 unsigned int dof_index;
270 unsigned int quad_index;
271
273
274 dealii::AlignedVector<scalar> array_penalty_parameter;
275
276 mutable scalar tau;
277};
278
279} // namespace Operators
280
281template<int dim>
282struct ContinuityPenaltyData
283{
284 ContinuityPenaltyData() : dof_index(0), quad_index(0), use_boundary_data(false)
285 {
286 }
287
288 unsigned int dof_index;
289
290 unsigned int quad_index;
291
292 bool use_boundary_data;
293
294 std::shared_ptr<BoundaryDescriptorU<dim> const> bc;
295};
296
297template<int dim, typename Number>
298class ContinuityPenaltyOperator
299{
300private:
301 typedef ContinuityPenaltyOperator<dim, Number> This;
302
303 typedef dealii::LinearAlgebra::distributed::Vector<Number> VectorType;
304
305 typedef dealii::Tensor<1, dim, dealii::VectorizedArray<Number>> vector;
306
307 typedef std::pair<unsigned int, unsigned int> Range;
308
309 typedef FaceIntegrator<dim, dim, Number> IntegratorFace;
310
312
313public:
314 ContinuityPenaltyOperator();
315
316 void
317 initialize(dealii::MatrixFree<dim, Number> const & matrix_free,
318 ContinuityPenaltyData<dim> const & data,
319 std::shared_ptr<Kernel> const kernel);
320
321 void
322 update(VectorType const & velocity);
323
324 // homogeneous operator
325 void
326 apply(VectorType & dst, VectorType const & src) const;
327
328 void
329 apply_add(VectorType & dst, VectorType const & src) const;
330
331 // inhomogeneous operator
332 void
333 rhs(VectorType & dst, Number const evaluation_time) const;
334
335 void
336 rhs_add(VectorType & dst, Number const evaluation_time) const;
337
338 // full operator, i.e., homogeneous and inhomogeneous contributions
339 void
340 evaluate(VectorType & dst, VectorType const & src, Number const evaluation_time) const;
341
342 void
343 evaluate_add(VectorType & dst, VectorType const & src, Number const evaluation_time) const;
344
345private:
346 void
347 cell_loop_empty(dealii::MatrixFree<dim, Number> const & matrix_free,
348 VectorType & dst,
349 VectorType const & src,
350 Range const & range) const;
351
352 void
353 face_loop(dealii::MatrixFree<dim, Number> const & matrix_free,
354 VectorType & dst,
355 VectorType const & src,
356 Range const & face_range) const;
357
358 void
359 face_loop_empty(dealii::MatrixFree<dim, Number> const & matrix_free,
360 VectorType & dst,
361 VectorType const & src,
362 Range const & face_range) const;
363
364 void
365 boundary_face_loop_hom(dealii::MatrixFree<dim, Number> const & matrix_free,
366 VectorType & dst,
367 VectorType const & src,
368 Range const & face_range) const;
369
370 void
371 boundary_face_loop_full(dealii::MatrixFree<dim, Number> const & matrix_free,
372 VectorType & dst,
373 VectorType const & src,
374 Range const & face_range) const;
375
376 void
377 boundary_face_loop_inhom(dealii::MatrixFree<dim, Number> const & matrix_free,
378 VectorType & dst,
379 VectorType const & src,
380 Range const & face_range) const;
381
382 void
383 do_face_integral(IntegratorFace & integrator_m, IntegratorFace & integrator_p) const;
384
385 void
386 do_boundary_integral(IntegratorFace & integrator_m,
387 OperatorType const & operator_type,
388 dealii::types::boundary_id const & boundary_id) const;
389
390 dealii::MatrixFree<dim, Number> const * matrix_free;
391
393
394 mutable double time;
395
396 std::shared_ptr<Operators::ContinuityPenaltyKernel<dim, Number>> kernel;
397};
398
399} // namespace IncNS
400} // namespace ExaDG
401
402#endif /* EXADG_INCOMPRESSIBLE_NAVIER_STOKES_SPATIAL_DISCRETIZATION_OPERATORS_CONTINUITY_PENALTY_OPERATOR_H_ \
403 */
Definition continuity_penalty_operator.h:96
Definition driver.cpp:33
ElementType get_element_type(dealii::Triangulation< dim > const &tria)
Definition grid_data.h:70
Number calculate_high_order_element_length(Number const element_length, unsigned int const fe_degree, bool const is_dg)
Definition calculate_characteristic_element_length.h:108
Number calculate_characteristic_element_length(Number const element_volume, unsigned int const dim, ElementType const &element_type)
Definition calculate_characteristic_element_length.h:68
Definition continuity_penalty_operator.h:283
Definition continuity_penalty_operator.h:67
Definition integrator_flags.h:31
Definition mapping_flags.h:31