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