ExaDG
Loading...
Searching...
No Matches
divergence_penalty_operator.h
1/*
2 * divergence_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_DIVERGENCE_PENALTY_OPERATOR_H_
9#define INCLUDE_EXADG_INCOMPRESSIBLE_NAVIER_STOKES_SPATIAL_DISCRETIZATION_OPERATORS_DIVERGENCE_PENALTY_OPERATOR_H_
10
11#include <exadg/grid/calculate_characteristic_element_length.h>
12#include <exadg/incompressible_navier_stokes/user_interface/parameters.h>
13#include <exadg/matrix_free/integrators.h>
14#include <exadg/operators/integrator_flags.h>
15#include <exadg/operators/mapping_flags.h>
16
17namespace ExaDG
18{
19namespace IncNS
20{
21/*
22 * Divergence penalty operator:
23 *
24 * ( div(v_h) , tau_div * div(u_h) )_Omega^e
25 *
26 * where
27 *
28 * v_h : test function
29 * u_h : solution
30 * tau_div: divergence penalty factor
31 *
32 * use convective term: tau_div_conv = K * ||U||_mean * h_eff
33 *
34 * where h_eff = h / (k_u+1) with a characteristic
35 * element length h derived from the element volume V_e
36 *
37 * use viscous term: tau_div_viscous = K * nu
38 *
39 * use both terms: tau_div = tau_div_conv + tau_div_viscous
40 *
41 */
42
43namespace Operators
44{
46{
48 : type_penalty_parameter(TypePenaltyParameter::ConvectiveTerm),
49 viscosity(0.0),
50 degree(1),
51 penalty_factor(1.0)
52 {
53 }
54
55 // type of penalty parameter (viscous and/or convective terms)
56 TypePenaltyParameter type_penalty_parameter;
57
58 // viscosity, needed for computation of penalty factor
59 double viscosity;
60
61 // degree of finite element shape functions
62 unsigned int degree;
63
64 // the penalty term can be scaled by 'penalty_factor'
65 double penalty_factor;
66};
67
68template<int dim, typename Number>
70{
71private:
72 typedef CellIntegrator<dim, dim, Number> IntegratorCell;
73
74 typedef dealii::LinearAlgebra::distributed::Vector<Number> VectorType;
75
76 typedef dealii::VectorizedArray<Number> scalar;
77
78public:
80 : matrix_free(nullptr), dof_index(0), quad_index(0), array_penalty_parameter(0)
81 {
82 }
83
84 void
85 reinit(dealii::MatrixFree<dim, Number> const & matrix_free,
86 unsigned int const dof_index,
87 unsigned int const quad_index,
88 DivergencePenaltyKernelData const & data)
89 {
90 this->matrix_free = &matrix_free;
91
92 this->dof_index = dof_index;
93 this->quad_index = quad_index;
94
95 this->data = data;
96
97 unsigned int n_cells = matrix_free.n_cell_batches() + matrix_free.n_ghost_cell_batches();
98 array_penalty_parameter.resize(n_cells);
99 }
100
102 get_data()
103 {
104 return this->data;
105 }
106
108 get_integrator_flags() const
109 {
110 IntegratorFlags flags;
111
112 flags.cell_evaluate = dealii::EvaluationFlags::gradients;
113 flags.cell_integrate = dealii::EvaluationFlags::gradients;
114
115 // no face integrals
116
117 return flags;
118 }
119
120 static MappingFlags
121 get_mapping_flags()
122 {
123 MappingFlags flags;
124
125 flags.cells = dealii::update_JxW_values | dealii::update_gradients;
126
127 // no face integrals
128
129 return flags;
130 }
131
132 void
133 calculate_penalty_parameter(VectorType const & velocity)
134 {
135 velocity.update_ghost_values();
136
137 IntegratorCell integrator(*matrix_free, dof_index, quad_index);
138
139 dealii::AlignedVector<scalar> JxW_values(integrator.n_q_points);
140
141 ElementType const element_type =
142 get_element_type(matrix_free->get_dof_handler(dof_index).get_triangulation());
143
144 unsigned int n_cells = matrix_free->n_cell_batches() + matrix_free->n_ghost_cell_batches();
145 for(unsigned int cell = 0; cell < n_cells; ++cell)
146 {
147 scalar tau_convective = dealii::make_vectorized_array<Number>(0.0);
148 scalar tau_viscous = dealii::make_vectorized_array<Number>(data.viscosity);
149
150 if(data.type_penalty_parameter == TypePenaltyParameter::ConvectiveTerm or
151 data.type_penalty_parameter == TypePenaltyParameter::ViscousAndConvectiveTerms)
152 {
153 integrator.reinit(cell);
154 integrator.read_dof_values(velocity);
155 integrator.evaluate(dealii::EvaluationFlags::values);
156
157 scalar volume = dealii::make_vectorized_array<Number>(0.0);
158 scalar norm_U_mean = dealii::make_vectorized_array<Number>(0.0);
159 for(unsigned int q = 0; q < integrator.n_q_points; ++q)
160 {
161 volume += integrator.JxW(q);
162 norm_U_mean += integrator.JxW(q) * integrator.get_value(q).norm();
163 }
164 norm_U_mean /= volume;
165
166 scalar h = calculate_characteristic_element_length(volume, dim, element_type);
167 scalar h_eff = calculate_high_order_element_length(h, data.degree, true);
168
169 tau_convective = norm_U_mean * h_eff;
170 }
171
172 if(data.type_penalty_parameter == TypePenaltyParameter::ConvectiveTerm)
173 {
174 array_penalty_parameter[cell] = data.penalty_factor * tau_convective;
175 }
176 else if(data.type_penalty_parameter == TypePenaltyParameter::ViscousTerm)
177 {
178 array_penalty_parameter[cell] = data.penalty_factor * tau_viscous;
179 }
180 else if(data.type_penalty_parameter == TypePenaltyParameter::ViscousAndConvectiveTerms)
181 {
182 array_penalty_parameter[cell] = data.penalty_factor * (tau_convective + tau_viscous);
183 }
184 }
185 }
186
187 void
188 reinit_cell(IntegratorCell & integrator) const
189 {
190 tau = integrator.read_cell_data(array_penalty_parameter);
191 }
192
193 /*
194 * Volume flux, i.e., the term occurring in the volume integral
195 */
196 inline DEAL_II_ALWAYS_INLINE //
197 scalar
198 get_volume_flux(IntegratorCell const & integrator, unsigned int const q) const
199 {
200 return tau * integrator.get_divergence(q);
201 }
202
203private:
204 dealii::MatrixFree<dim, Number> const * matrix_free;
205
206 unsigned int dof_index;
207 unsigned int quad_index;
208
210
211 dealii::AlignedVector<scalar> array_penalty_parameter;
212
213 mutable scalar tau;
214};
215
216} // namespace Operators
217
219{
220 DivergencePenaltyData() : dof_index(0), quad_index(0)
221 {
222 }
223
224 unsigned int dof_index;
225 unsigned int quad_index;
226};
227
228template<int dim, typename Number>
230{
231private:
233
234 typedef dealii::LinearAlgebra::distributed::Vector<Number> VectorType;
235
236 typedef std::pair<unsigned int, unsigned int> Range;
237
238 typedef CellIntegrator<dim, dim, Number> IntegratorCell;
239
241
242public:
244
245 void
246 initialize(dealii::MatrixFree<dim, Number> const & matrix_free,
247 DivergencePenaltyData const & data,
248 std::shared_ptr<Kernel> const kernel);
249
250 void
251 update(VectorType const & velocity);
252
253 void
254 apply(VectorType & dst, VectorType const & src) const;
255
256 void
257 apply_add(VectorType & dst, VectorType const & src) const;
258
259private:
260 void
261 cell_loop(dealii::MatrixFree<dim, Number> const & matrix_free,
262 VectorType & dst,
263 VectorType const & src,
264 Range const & range) const;
265
266 void
267 do_cell_integral(IntegratorCell & integrator) const;
268
269 dealii::MatrixFree<dim, Number> const * matrix_free;
270
272
273 std::shared_ptr<Operators::DivergencePenaltyKernel<dim, Number>> kernel;
274};
275
276} // namespace IncNS
277} // namespace ExaDG
278
279#endif /* INCLUDE_EXADG_INCOMPRESSIBLE_NAVIER_STOKES_SPATIAL_DISCRETIZATION_OPERATORS_DIVERGENCE_PENALTY_OPERATOR_H_ \
280 */
Definition divergence_penalty_operator.h:230
Definition divergence_penalty_operator.h:70
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 divergence_penalty_operator.h:219
Definition divergence_penalty_operator.h:46
Definition integrator_flags.h:30
Definition mapping_flags.h:31