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 velocity.zero_out_ghost_values();
211 }
212
213 void
214 reinit_face(IntegratorFace & integrator_m, IntegratorFace & integrator_p) const
215 {
216 tau = 0.5 * (integrator_m.read_cell_data(array_penalty_parameter) +
217 integrator_p.read_cell_data(array_penalty_parameter));
218 }
219
220 void
221 reinit_boundary_face(IntegratorFace & integrator_m) const
222 {
223 tau = integrator_m.read_cell_data(array_penalty_parameter);
224 }
225
226 void
227 reinit_face_cell_based(dealii::types::boundary_id const boundary_id,
228 IntegratorFace & integrator_m,
229 IntegratorFace & integrator_p) const
230 {
231 if(boundary_id == dealii::numbers::internal_face_boundary_id) // internal face
232 {
233 tau = 0.5 * (integrator_m.read_cell_data(array_penalty_parameter) +
234 integrator_p.read_cell_data(array_penalty_parameter));
235 }
236 else // boundary face
237 {
238 tau = integrator_m.read_cell_data(array_penalty_parameter);
239 }
240 }
241
242 inline DEAL_II_ALWAYS_INLINE //
243 vector
244 calculate_flux(vector const & u_m, vector const & u_p, vector const & normal_m) const
245 {
246 vector jump_value = u_m - u_p;
247
248 vector flux;
249
250 if(data.which_components == ContinuityPenaltyComponents::All)
251 {
252 // penalize all velocity components
253 flux = tau * jump_value;
254 }
255 else if(data.which_components == ContinuityPenaltyComponents::Normal)
256 {
257 flux = tau * (jump_value * normal_m) * normal_m;
258 }
259 else
260 {
261 AssertThrow(false, dealii::ExcMessage("not implemented."));
262 }
263
264 return flux;
265 }
266
267
268private:
269 dealii::MatrixFree<dim, Number> const * matrix_free;
270
271 unsigned int dof_index;
272 unsigned int quad_index;
273
275
276 dealii::AlignedVector<scalar> array_penalty_parameter;
277
278 mutable scalar tau;
279};
280
281} // namespace Operators
282
283template<int dim>
284struct ContinuityPenaltyData
285{
286 ContinuityPenaltyData() : dof_index(0), quad_index(0), use_boundary_data(false)
287 {
288 }
289
290 unsigned int dof_index;
291
292 unsigned int quad_index;
293
294 bool use_boundary_data;
295
296 std::shared_ptr<BoundaryDescriptorU<dim> const> bc;
297};
298
299template<int dim, typename Number>
300class ContinuityPenaltyOperator
301{
302private:
303 typedef ContinuityPenaltyOperator<dim, Number> This;
304
305 typedef dealii::LinearAlgebra::distributed::Vector<Number> VectorType;
306
307 typedef dealii::Tensor<1, dim, dealii::VectorizedArray<Number>> vector;
308
309 typedef std::pair<unsigned int, unsigned int> Range;
310
311 typedef FaceIntegrator<dim, dim, Number> IntegratorFace;
312
314
315public:
316 ContinuityPenaltyOperator();
317
318 void
319 initialize(dealii::MatrixFree<dim, Number> const & matrix_free,
320 ContinuityPenaltyData<dim> const & data,
321 std::shared_ptr<Kernel> const kernel);
322
323 void
324 update(VectorType const & velocity);
325
326 // homogeneous operator
327 void
328 apply(VectorType & dst, VectorType const & src) const;
329
330 void
331 apply_add(VectorType & dst, VectorType const & src) const;
332
333 // inhomogeneous operator
334 void
335 rhs(VectorType & dst, Number const evaluation_time) const;
336
337 void
338 rhs_add(VectorType & dst, Number const evaluation_time) const;
339
340 // full operator, i.e., homogeneous and inhomogeneous contributions
341 void
342 evaluate(VectorType & dst, VectorType const & src, Number const evaluation_time) const;
343
344 void
345 evaluate_add(VectorType & dst, VectorType const & src, Number const evaluation_time) const;
346
347private:
348 void
349 cell_loop_empty(dealii::MatrixFree<dim, Number> const & matrix_free,
350 VectorType & dst,
351 VectorType const & src,
352 Range const & range) const;
353
354 void
355 face_loop(dealii::MatrixFree<dim, Number> const & matrix_free,
356 VectorType & dst,
357 VectorType const & src,
358 Range const & face_range) const;
359
360 void
361 face_loop_empty(dealii::MatrixFree<dim, Number> const & matrix_free,
362 VectorType & dst,
363 VectorType const & src,
364 Range const & face_range) const;
365
366 void
367 boundary_face_loop_hom(dealii::MatrixFree<dim, Number> const & matrix_free,
368 VectorType & dst,
369 VectorType const & src,
370 Range const & face_range) const;
371
372 void
373 boundary_face_loop_full(dealii::MatrixFree<dim, Number> const & matrix_free,
374 VectorType & dst,
375 VectorType const & src,
376 Range const & face_range) const;
377
378 void
379 boundary_face_loop_inhom(dealii::MatrixFree<dim, Number> const & matrix_free,
380 VectorType & dst,
381 VectorType const & src,
382 Range const & face_range) const;
383
384 void
385 do_face_integral(IntegratorFace & integrator_m, IntegratorFace & integrator_p) const;
386
387 void
388 do_boundary_integral(IntegratorFace & integrator_m,
389 OperatorType const & operator_type,
390 dealii::types::boundary_id const & boundary_id) const;
391
392 dealii::MatrixFree<dim, Number> const * matrix_free;
393
395
396 mutable double time;
397
398 std::shared_ptr<Operators::ContinuityPenaltyKernel<dim, Number>> kernel;
399};
400
401} // namespace IncNS
402} // namespace ExaDG
403
404#endif /* EXADG_INCOMPRESSIBLE_NAVIER_STOKES_SPATIAL_DISCRETIZATION_OPERATORS_CONTINUITY_PENALTY_OPERATOR_H_ \
405 */
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:285
Definition continuity_penalty_operator.h:67
Definition integrator_flags.h:31
Definition mapping_flags.h:31