8#ifndef INCLUDE_EXADG_INCOMPRESSIBLE_NAVIER_STOKES_SPATIAL_DISCRETIZATION_OPERATORS_WEAK_BOUNDARY_CONDITIONS_H_
9#define INCLUDE_EXADG_INCOMPRESSIBLE_NAVIER_STOKES_SPATIAL_DISCRETIZATION_OPERATORS_WEAK_BOUNDARY_CONDITIONS_H_
11#include <exadg/functions_and_boundary_conditions/evaluate_functions.h>
12#include <exadg/incompressible_navier_stokes/user_interface/boundary_descriptor.h>
13#include <exadg/incompressible_navier_stokes/user_interface/enum_types.h>
14#include <exadg/matrix_free/integrators.h>
15#include <exadg/operators/operator_type.h>
40template<
int dim,
typename Number>
41inline DEAL_II_ALWAYS_INLINE
42 dealii::Tensor<1, dim, dealii::VectorizedArray<Number>>
43 calculate_interior_value(
unsigned int const q,
44 FaceIntegrator<dim, dim, Number>
const & integrator,
45 OperatorType
const & operator_type)
48 dealii::Tensor<1, dim, dealii::VectorizedArray<Number>> value_m;
50 if(operator_type == OperatorType::full or operator_type == OperatorType::homogeneous)
52 value_m = integrator.get_value(q);
54 else if(operator_type == OperatorType::inhomogeneous)
60 AssertThrow(
false, dealii::ExcMessage(
"Specified OperatorType is not implemented!"));
66template<
int dim,
typename Number>
67inline DEAL_II_ALWAYS_INLINE
68 dealii::Tensor<1, dim, dealii::VectorizedArray<Number>>
69 calculate_exterior_value(dealii::Tensor<1, dim, dealii::VectorizedArray<Number>>
const & value_m,
71 FaceIntegrator<dim, dim, Number>
const & integrator,
72 OperatorType
const & operator_type,
73 BoundaryTypeU
const & boundary_type,
74 dealii::types::boundary_id
const boundary_id,
75 std::shared_ptr<BoundaryDescriptorU<dim>
const> boundary_descriptor,
79 dealii::Tensor<1, dim, dealii::VectorizedArray<Number>> value_p;
81 if(boundary_type == BoundaryTypeU::Dirichlet or boundary_type == BoundaryTypeU::DirichletCached)
83 if(operator_type == OperatorType::full or operator_type == OperatorType::inhomogeneous)
85 dealii::Tensor<1, dim, dealii::VectorizedArray<Number>> g;
87 if(boundary_type == BoundaryTypeU::Dirichlet)
89 auto bc = boundary_descriptor->dirichlet_bc.find(boundary_id)->second;
90 auto q_points = integrator.quadrature_point(q);
92 g = FunctionEvaluator<1, dim, Number>::value(*bc, q_points, time);
94 else if(boundary_type == BoundaryTypeU::DirichletCached)
96 auto bc = boundary_descriptor->get_dirichlet_cached_data();
97 g = FunctionEvaluator<1, dim, Number>::value(*bc,
98 integrator.get_current_cell_index(),
100 integrator.get_quadrature_index());
104 AssertThrow(
false, dealii::ExcMessage(
"Not implemented."));
107 value_p = -value_m + dealii::Tensor<1, dim, dealii::VectorizedArray<Number>>(2.0 * g);
109 else if(operator_type == OperatorType::homogeneous)
115 AssertThrow(
false, dealii::ExcMessage(
"Specified OperatorType is not implemented!"));
118 else if(boundary_type == BoundaryTypeU::Neumann)
122 else if(boundary_type == BoundaryTypeU::Symmetry)
124 dealii::Tensor<1, dim, dealii::VectorizedArray<Number>> normal_m =
125 integrator.get_normal_vector(q);
127 value_p = value_m - 2.0 * (value_m * normal_m) * normal_m;
131 AssertThrow(
false, dealii::ExcMessage(
"Boundary type of face is invalid or not implemented."));
148template<
int dim,
typename Number>
149inline DEAL_II_ALWAYS_INLINE
150 dealii::Tensor<1, dim, dealii::VectorizedArray<Number>>
151 calculate_exterior_value_nonlinear(
152 dealii::Tensor<1, dim, dealii::VectorizedArray<Number>>
const & u_m,
153 unsigned int const q,
154 FaceIntegrator<dim, dim, Number> & integrator,
155 BoundaryTypeU
const & boundary_type,
156 TypeDirichletBCs
const & type_dirichlet_bc,
157 dealii::types::boundary_id
const boundary_id,
158 std::shared_ptr<BoundaryDescriptorU<dim>
const> boundary_descriptor,
161 dealii::Tensor<1, dim, dealii::VectorizedArray<Number>> u_p;
163 if(boundary_type == BoundaryTypeU::Dirichlet or boundary_type == BoundaryTypeU::DirichletCached)
165 dealii::Tensor<1, dim, dealii::VectorizedArray<Number>> g;
167 if(boundary_type == BoundaryTypeU::Dirichlet)
169 auto bc = boundary_descriptor->dirichlet_bc.find(boundary_id)->second;
170 auto q_points = integrator.quadrature_point(q);
172 g = FunctionEvaluator<1, dim, Number>::value(*bc, q_points, time);
174 else if(boundary_type == BoundaryTypeU::DirichletCached)
176 auto bc = boundary_descriptor->get_dirichlet_cached_data();
177 g = FunctionEvaluator<1, dim, Number>::value(*bc,
178 integrator.get_current_cell_index(),
180 integrator.get_quadrature_index());
184 AssertThrow(
false, dealii::ExcMessage(
"Not implemented."));
187 if(type_dirichlet_bc == TypeDirichletBCs::Mirror)
189 u_p = -u_m + dealii::make_vectorized_array<Number>(2.0) * g;
191 else if(type_dirichlet_bc == TypeDirichletBCs::Direct)
197 AssertThrow(
false, dealii::ExcMessage(
"TypeDirichletBCs is not implemented."));
200 else if(boundary_type == BoundaryTypeU::Neumann)
204 else if(boundary_type == BoundaryTypeU::Symmetry)
206 dealii::Tensor<1, dim, dealii::VectorizedArray<Number>> normal_m =
207 integrator.get_normal_vector(q);
209 u_p = u_m - 2. * (u_m * normal_m) * normal_m;
213 AssertThrow(
false, dealii::ExcMessage(
"Boundary type of face is invalid or not implemented."));
219template<
int dim,
typename Number>
220inline DEAL_II_ALWAYS_INLINE
221 dealii::Tensor<1, dim, dealii::VectorizedArray<Number>>
222 calculate_exterior_value_from_dof_vector(
223 dealii::Tensor<1, dim, dealii::VectorizedArray<Number>>
const & value_m,
224 unsigned int const q,
225 FaceIntegrator<dim, dim, Number>
const & integrator_bc,
226 OperatorType
const & operator_type,
227 BoundaryTypeU
const & boundary_type)
230 dealii::Tensor<1, dim, dealii::VectorizedArray<Number>> value_p;
232 if(boundary_type == BoundaryTypeU::Dirichlet or boundary_type == BoundaryTypeU::DirichletCached)
234 if(operator_type == OperatorType::full or operator_type == OperatorType::inhomogeneous)
236 dealii::Tensor<1, dim, dealii::VectorizedArray<Number>> g = integrator_bc.get_value(q);
238 value_p = -value_m + dealii::make_vectorized_array<Number>(2.0) * g;
240 else if(operator_type == OperatorType::homogeneous)
246 AssertThrow(
false, dealii::ExcMessage(
"Specified OperatorType is not implemented!"));
249 else if(boundary_type == BoundaryTypeU::Neumann)
253 else if(boundary_type == BoundaryTypeU::Symmetry)
255 dealii::Tensor<1, dim, dealii::VectorizedArray<Number>> normal_m =
256 integrator_bc.get_normal_vector(q);
258 value_p = value_m - 2.0 * (value_m * normal_m) * normal_m;
262 AssertThrow(
false, dealii::ExcMessage(
"Boundary type of face is invalid or not implemented."));
285template<
int dim,
typename Number>
286inline DEAL_II_ALWAYS_INLINE
287 dealii::VectorizedArray<Number>
288 calculate_interior_value(
unsigned int const q,
289 FaceIntegrator<dim, 1, Number>
const & integrator,
290 OperatorType
const & operator_type)
293 dealii::VectorizedArray<Number> value_m = dealii::make_vectorized_array<Number>(0.0);
295 if(operator_type == OperatorType::full or operator_type == OperatorType::homogeneous)
297 value_m = integrator.get_value(q);
299 else if(operator_type == OperatorType::inhomogeneous)
305 AssertThrow(
false, dealii::ExcMessage(
"Specified OperatorType is not implemented!"));
312template<
int dim,
typename Number>
313inline DEAL_II_ALWAYS_INLINE
314 dealii::VectorizedArray<Number>
315 calculate_exterior_value(dealii::VectorizedArray<Number>
const & value_m,
316 unsigned int const q,
317 FaceIntegrator<dim, 1, Number>
const & integrator,
318 OperatorType
const & operator_type,
319 BoundaryTypeP
const & boundary_type,
320 dealii::types::boundary_id
const boundary_id,
321 std::shared_ptr<BoundaryDescriptorP<dim>
const> boundary_descriptor,
323 double const & inverse_scaling_factor)
325 dealii::VectorizedArray<Number> value_p = dealii::make_vectorized_array<Number>(0.0);
327 if(boundary_type == BoundaryTypeP::Dirichlet)
329 if(operator_type == OperatorType::full or operator_type == OperatorType::inhomogeneous)
331 auto bc = boundary_descriptor->dirichlet_bc.find(boundary_id)->second;
332 auto q_points = integrator.quadrature_point(q);
334 dealii::VectorizedArray<Number> g =
335 FunctionEvaluator<0, dim, Number>::value(*bc, q_points, time);
337 value_p = -value_m + 2.0 * inverse_scaling_factor * g;
339 else if(operator_type == OperatorType::homogeneous)
345 AssertThrow(
false, dealii::ExcMessage(
"Specified OperatorType is not implemented!"));
348 else if(boundary_type == BoundaryTypeP::Neumann)
354 AssertThrow(
false, dealii::ExcMessage(
"Boundary type of face is invalid or not implemented."));
360template<
int dim,
typename Number>
361inline DEAL_II_ALWAYS_INLINE
362 dealii::VectorizedArray<Number>
363 calculate_exterior_value_from_dof_vector(dealii::VectorizedArray<Number>
const & value_m,
364 unsigned int const q,
365 FaceIntegrator<dim, 1, Number>
const & integrator_bc,
366 OperatorType
const & operator_type,
367 BoundaryTypeP
const & boundary_type,
368 double const & inverse_scaling_factor)
370 dealii::VectorizedArray<Number> value_p = dealii::make_vectorized_array<Number>(0.0);
372 if(boundary_type == BoundaryTypeP::Dirichlet)
374 if(operator_type == OperatorType::full or operator_type == OperatorType::inhomogeneous)
376 dealii::VectorizedArray<Number> g = integrator_bc.get_value(q);
378 value_p = -value_m + 2.0 * inverse_scaling_factor * g;
380 else if(operator_type == OperatorType::homogeneous)
386 AssertThrow(
false, dealii::ExcMessage(
"Specified OperatorType is not implemented!"));
389 else if(boundary_type == BoundaryTypeP::Neumann)
395 AssertThrow(
false, dealii::ExcMessage(
"Boundary type of face is invalid or not implemented."));
433template<
int dim,
typename Number>
434inline DEAL_II_ALWAYS_INLINE
435 dealii::Tensor<1, dim, dealii::VectorizedArray<Number>>
436 calculate_exterior_normal_gradient(
437 dealii::Tensor<1, dim, dealii::VectorizedArray<Number>>
const & normal_gradient_m,
438 unsigned int const q,
439 FaceIntegrator<dim, dim, Number>
const & integrator,
440 OperatorType
const & operator_type,
441 BoundaryTypeU
const & boundary_type,
442 dealii::types::boundary_id
const boundary_id,
443 std::shared_ptr<BoundaryDescriptorU<dim>
const> boundary_descriptor,
445 bool const variable_normal_vector)
447 dealii::Tensor<1, dim, dealii::VectorizedArray<Number>> normal_gradient_p;
449 if(boundary_type == BoundaryTypeU::Dirichlet or boundary_type == BoundaryTypeU::DirichletCached)
451 normal_gradient_p = normal_gradient_m;
453 else if(boundary_type == BoundaryTypeU::Neumann)
455 if(operator_type == OperatorType::full or operator_type == OperatorType::inhomogeneous)
457 auto bc = boundary_descriptor->neumann_bc.find(boundary_id)->second;
458 auto q_points = integrator.quadrature_point(q);
460 dealii::Tensor<1, dim, dealii::VectorizedArray<Number>> h;
461 if(variable_normal_vector ==
false)
463 h = FunctionEvaluator<1, dim, Number>::value(*bc, q_points, time);
467 auto normals_m = integrator.get_normal_vector(q);
468 h = FunctionEvaluator<1, dim, Number>::value(
469 *(std::dynamic_pointer_cast<FunctionWithNormal<dim>>(bc)), q_points, normals_m, time);
472 normal_gradient_p = -normal_gradient_m + 2.0 * h;
474 else if(operator_type == OperatorType::homogeneous)
476 normal_gradient_p = -normal_gradient_m;
480 AssertThrow(
false, dealii::ExcMessage(
"Specified OperatorType is not implemented!"));
483 else if(boundary_type == BoundaryTypeU::Symmetry)
485 auto normal_m = integrator.get_normal_vector(q);
486 normal_gradient_p = -normal_gradient_m + 2.0 * (normal_gradient_m * normal_m) * normal_m;
490 AssertThrow(
false, dealii::ExcMessage(
"Boundary type of face is invalid or not implemented."));
493 return normal_gradient_p;