ExaDG
Loading...
Searching...
No Matches
weak_boundary_conditions.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_CONVECTION_DIFFUSION_SPATIAL_DISCRETIZATION_OPERATORS_WEAK_BOUNDARY_CONDITIONS_H_
23#define EXADG_CONVECTION_DIFFUSION_SPATIAL_DISCRETIZATION_OPERATORS_WEAK_BOUNDARY_CONDITIONS_H_
24
25// ExaDG
26#include <exadg/convection_diffusion/user_interface/boundary_descriptor.h>
27#include <exadg/functions_and_boundary_conditions/evaluate_functions.h>
28#include <exadg/matrix_free/integrators.h>
29#include <exadg/operators/operator_type.h>
30
31namespace ExaDG
32{
33namespace ConvDiff
34{
35/*
36 * The following two functions calculate the interior_value/exterior_value
37 * depending on the operator type, the type of the boundary face
38 * and the given boundary conditions.
39 *
40 * +----------------------+--------------------+
41 * | Dirichlet boundaries | Neumann boundaries |
42 * +-------------------------+----------------------+--------------------+
43 * | full operator | phi⁺ = -phi⁻ + 2g | phi⁺ = phi⁻ |
44 * +-------------------------+----------------------+--------------------+
45 * | homogeneous operator | phi⁺ = -phi⁻ | phi⁺ = phi⁻ |
46 * +-------------------------+----------------------+--------------------+
47 * | inhomogeneous operator | phi⁻ = 0, phi⁺ = 2g | phi⁻ = 0, phi⁺ = 0 |
48 * +-------------------------+----------------------+--------------------+
49 */
50template<int dim, typename Number>
51inline DEAL_II_ALWAYS_INLINE //
52 dealii::VectorizedArray<Number>
53 calculate_interior_value(unsigned int const q,
54 FaceIntegrator<dim, 1, Number> const & integrator,
55 OperatorType const & operator_type)
56{
57 dealii::VectorizedArray<Number> value_m = dealii::make_vectorized_array<Number>(0.0);
58
59 if(operator_type == OperatorType::full or operator_type == OperatorType::homogeneous)
60 {
61 value_m = integrator.get_value(q);
62 }
63 else if(operator_type == OperatorType::inhomogeneous)
64 {
65 // do nothing (value_m already initialized with 0.0)
66 }
67 else
68 {
69 AssertThrow(false, dealii::ExcMessage("Specified OperatorType is not implemented!"));
70 }
71
72 return value_m;
73}
74
75template<int dim, typename Number>
76inline DEAL_II_ALWAYS_INLINE //
77 dealii::VectorizedArray<Number>
78 calculate_exterior_value(dealii::VectorizedArray<Number> const & value_m,
79 unsigned int const q,
80 FaceIntegrator<dim, 1, Number> const & integrator,
81 OperatorType const & operator_type,
82 BoundaryType const & boundary_type,
83 dealii::types::boundary_id const boundary_id,
84 std::shared_ptr<BoundaryDescriptor<dim> const> boundary_descriptor,
85 double const & time)
86{
87 dealii::VectorizedArray<Number> value_p = dealii::make_vectorized_array<Number>(0.0);
88
89 if(boundary_type == BoundaryType::Dirichlet)
90 {
91 if(operator_type == OperatorType::full or operator_type == OperatorType::inhomogeneous)
92 {
93 dealii::VectorizedArray<Number> g;
94
95 auto bc = boundary_descriptor->dirichlet_bc.find(boundary_id)->second;
96 auto q_points = integrator.quadrature_point(q);
97
98 g = FunctionEvaluator<0, dim, Number>::value(*bc, q_points, time);
99
100 value_p = -value_m + 2.0 * g;
101 }
102 else if(operator_type == OperatorType::homogeneous)
103 {
104 value_p = -value_m;
105 }
106 else
107 {
108 AssertThrow(false, dealii::ExcMessage("Specified OperatorType is not implemented!"));
109 }
110 }
111 else if(boundary_type == BoundaryType::Neumann)
112 {
113 value_p = value_m;
114 }
115 else
116 {
117 AssertThrow(false, dealii::ExcMessage("Boundary type of face is invalid or not implemented."));
118 }
119
120 return value_p;
121}
122
123// clang-format off
124 /*
125 * The following two functions calculate the interior/exterior gradient
126 * in normal direction depending on the operator type, the type of the boundary face
127 * and the given boundary conditions.
128 *
129 * +-----------------------------------------------+------------------------------------------------------+
130 * | Dirichlet boundaries | Neumann boundaries |
131 * +-------------------------+-----------------------------------------------+------------------------------------------------------+
132 * | full operator | grad(phi⁺)*n = grad(phi⁻)*n | grad(phi⁺)*n = -grad(phi⁻)*n + 2h |
133 * +-------------------------+-----------------------------------------------+------------------------------------------------------+
134 * | homogeneous operator | grad(phi⁺)*n = grad(phi⁻)*n | grad(phi⁺)*n = -grad(phi⁻)*n |
135 * +-------------------------+-----------------------------------------------+------------------------------------------------------+
136 * | inhomogeneous operator | grad(phi⁺)*n = grad(phi⁻)*n, grad(phi⁻)*n = 0 | grad(phi⁺)*n = -grad(phi⁻)*n + 2h, grad(phi⁻)*n = 0 |
137 * +-------------------------+-----------------------------------------------+------------------------------------------------------+
138 *
139 * +-----------------------------------------------+------------------------------------------------------+
140 * | Dirichlet boundaries | Neumann boundaries |
141 * +-------------------------+-----------------------------------------------+------------------------------------------------------+
142 * | full operator | {{grad(phi)}}*n = grad(phi⁻)*n | {{grad(phi)}}*n = h |
143 * +-------------------------+-----------------------------------------------+------------------------------------------------------+
144 * | homogeneous operator | {{grad(phi)}}*n = grad(phi⁻)*n | {{grad(phi)}}*n = 0 |
145 * +-------------------------+-----------------------------------------------+------------------------------------------------------+
146 * | inhomogeneous operator | {{grad(phi)}}*n = 0 | {{grad(phi)}}*n = h |
147 * +-------------------------+-----------------------------------------------+------------------------------------------------------+
148 */
149// clang-format on
150template<int dim, typename Number>
151inline DEAL_II_ALWAYS_INLINE //
152 dealii::VectorizedArray<Number>
153 calculate_interior_normal_gradient(unsigned int const q,
154 FaceIntegrator<dim, 1, Number> const & integrator,
155 OperatorType const & operator_type)
156{
157 dealii::VectorizedArray<Number> normal_gradient_m = dealii::make_vectorized_array<Number>(0.0);
158
159 if(operator_type == OperatorType::full or operator_type == OperatorType::homogeneous)
160 {
161 normal_gradient_m = integrator.get_normal_derivative(q);
162 }
163 else if(operator_type == OperatorType::inhomogeneous)
164 {
165 // do nothing (normal_gradient_m already initialized with 0.0)
166 }
167 else
168 {
169 AssertThrow(false, dealii::ExcMessage("Specified OperatorType is not implemented!"));
170 }
171
172 return normal_gradient_m;
173}
174
175template<int dim, typename Number>
176inline DEAL_II_ALWAYS_INLINE //
177 dealii::VectorizedArray<Number>
178 calculate_exterior_normal_gradient(
179 dealii::VectorizedArray<Number> const & normal_gradient_m,
180 unsigned int const q,
181 FaceIntegrator<dim, 1, Number> const & integrator,
182 OperatorType const & operator_type,
183 BoundaryType const & boundary_type,
184 dealii::types::boundary_id const boundary_id,
185 std::shared_ptr<BoundaryDescriptor<dim> const> boundary_descriptor,
186 double const & time)
187{
188 dealii::VectorizedArray<Number> normal_gradient_p = dealii::make_vectorized_array<Number>(0.0);
189
190 if(boundary_type == BoundaryType::Dirichlet)
191 {
192 normal_gradient_p = normal_gradient_m;
193 }
194 else if(boundary_type == BoundaryType::Neumann)
195 {
196 if(operator_type == OperatorType::full or operator_type == OperatorType::inhomogeneous)
197 {
198 auto bc = boundary_descriptor->neumann_bc.find(boundary_id)->second;
199 auto q_points = integrator.quadrature_point(q);
200
201 auto h = FunctionEvaluator<0, dim, Number>::value(*bc, q_points, time);
202
203 normal_gradient_p = -normal_gradient_m + 2.0 * h;
204 }
205 else if(operator_type == OperatorType::homogeneous)
206 {
207 normal_gradient_p = -normal_gradient_m;
208 }
209 else
210 {
211 AssertThrow(false, dealii::ExcMessage("Specified OperatorType is not implemented!"));
212 }
213 }
214 else
215 {
216 AssertThrow(false, dealii::ExcMessage("Boundary type of face is invalid or not implemented."));
217 }
218
219 return normal_gradient_p;
220}
221
222} // namespace ConvDiff
223} // namespace ExaDG
224
225#endif /* EXADG_CONVECTION_DIFFUSION_SPATIAL_DISCRETIZATION_OPERATORS_WEAK_BOUNDARY_CONDITIONS_H_ \
226 */
Definition driver.cpp:33
Definition boundary_descriptor.h:46