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