ExaDG
Loading...
Searching...
No Matches
boundary_descriptor.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_USER_INTERFACE_BOUNDARY_DESCRIPTOR_H_
23#define INCLUDE_EXADG_INCOMPRESSIBLE_NAVIER_STOKES_USER_INTERFACE_BOUNDARY_DESCRIPTOR_H_
24
25// C/C++
26#include <set>
27
28// deal.II
29#include <deal.II/base/function.h>
30#include <deal.II/base/types.h>
31
32// ExaDG
33#include <exadg/functions_and_boundary_conditions/container_interface_data.h>
34#include <exadg/functions_and_boundary_conditions/verify_boundary_conditions.h>
35
36namespace ExaDG
37{
38namespace IncNS
39{
40//clang-format off
41/*
42 *
43 * Boundary conditions:
44 *
45 * +----------------------+---------------------------+------------------------------------------------+
46 * | example | velocity | pressure |
47 * +----------------------+---------------------------+------------------------------------------------+
48 * | inflow, no-slip | Dirichlet(Cached): | Neumann: |
49 * | | prescribe g_u | no BCs to be prescribed |
50 * +----------------------+---------------------------+------------------------------------------------+
51 * | symmetry | Symmetry: | Neumann: |
52 * | | no BCs to be prescribed | no BCs to be prescribed |
53 * +----------------------+---------------------------+------------------------------------------------+
54 * | outflow | Neumann: | Dirichlet: |
55 * | | prescribe F(u)*n | prescribe g_p |
56 * +----------------------+---------------------------+------------------------------------------------+
57 *
58 * Divergence formulation: F(u) = F_nu(u) / nu = ( grad(u) + grad(u)^T )
59 * Laplace formulation: F(u) = F_nu(u) / nu = grad(u)
60 */
61//clang-format on
62
63enum class BoundaryTypeU
64{
65 Undefined,
66 Dirichlet,
67 DirichletCached,
68 Neumann,
69 Symmetry
70};
71
72enum class BoundaryTypeP
73{
74 Undefined,
75 Dirichlet,
76 Neumann
77};
78
79template<int dim>
81{
82 // Dirichlet: prescribe all components of the velocity
83 std::map<dealii::types::boundary_id, std::shared_ptr<dealii::Function<dim>>> dirichlet_bc;
84
85 // another type of Dirichlet boundary condition where the Dirichlet value comes
86 // from the solution on another domain that is in contact with the actual domain
87 // of interest at the given boundary (this type of Dirichlet boundary condition
88 // is required for fluid-structure interaction problems)
89 std::set<dealii::types::boundary_id> dirichlet_cached_bc;
90
91 // Neumann: prescribe all components of the velocity gradient in normal direction
92 std::map<dealii::types::boundary_id, std::shared_ptr<dealii::Function<dim>>> neumann_bc;
93
94 // Symmetry: A boundary condition prescribing "symmetry" for planar surfaces. Using this boundary
95 // condition, the velocity normal to boundary is set to zero
96 //
97 // u*n=0 (1)
98 //
99 // and the surface stress vector in tangential directions is set to zero
100 //
101 // F(u)*n - [(F(u)*n)*n] n = 0 , (2a)
102 //
103 // where F(u) = grad(u) (Laplace formulation) or F(u) = grad(u) + grad(u)^T (divergence
104 // formulation). For both types of formulation of the viscous term, this implies that the
105 // gradient of tangential velocity components in the direction normal to the boundary is
106 // set to zero
107 //
108 // grad(u)*n - [(grad(u)*n)*n] n = 0 . (2b)
109 //
110 // For the Laplace formulation, equation (2b) follows immediately from equation (2a). For
111 // the divergence formulation, one can show that the grad(u)^T terms in equation (2a) drop
112 // out if (u*n)=0 and if the normal vector is constant, i.e. for a planar surface
113 //
114 // u*n=0, n=const => grad(u)^T*n - [(grad(u)^T*n)*n] n = 0 => (2a) implies (2b)
115 //
116 // Note that the user does not have to prescribe data for this symmetry boundary condition;
117 // so one can simply use ZeroFunction<dim> (the function is not relevant because it will not
118 // be evaluated by the code).
119 std::map<dealii::types::boundary_id, std::shared_ptr<dealii::Function<dim>>> symmetry_bc;
120
121 // add more types of boundary conditions
122
123
124 // return the boundary type
125 inline DEAL_II_ALWAYS_INLINE //
126 BoundaryTypeU
127 get_boundary_type(dealii::types::boundary_id const & boundary_id) const
128 {
129 if(this->dirichlet_bc.find(boundary_id) != this->dirichlet_bc.end())
130 return BoundaryTypeU::Dirichlet;
131 else if(this->dirichlet_cached_bc.find(boundary_id) != this->dirichlet_cached_bc.end())
132 return BoundaryTypeU::DirichletCached;
133 else if(this->neumann_bc.find(boundary_id) != this->neumann_bc.end())
134 return BoundaryTypeU::Neumann;
135 else if(this->symmetry_bc.find(boundary_id) != this->symmetry_bc.end())
136 return BoundaryTypeU::Symmetry;
137
138 AssertThrow(false, dealii::ExcMessage("Boundary type of face is invalid or not implemented."));
139
140 return BoundaryTypeU::Undefined;
141 }
142
143 inline DEAL_II_ALWAYS_INLINE //
144 void
145 verify_boundary_conditions(
146 dealii::types::boundary_id const boundary_id,
147 std::set<dealii::types::boundary_id> const & periodic_boundary_ids) const
148 {
149 unsigned int counter = 0;
150 if(this->dirichlet_bc.find(boundary_id) != this->dirichlet_bc.end())
151 counter++;
152
153 if(this->dirichlet_cached_bc.find(boundary_id) != this->dirichlet_cached_bc.end())
154 counter++;
155
156 if(this->neumann_bc.find(boundary_id) != this->neumann_bc.end())
157 counter++;
158
159 if(this->symmetry_bc.find(boundary_id) != this->symmetry_bc.end())
160 counter++;
161
162 if(periodic_boundary_ids.find(boundary_id) != periodic_boundary_ids.end())
163 counter++;
164
165 AssertThrow(counter == 1,
166 dealii::ExcMessage("Boundary face with non-unique boundary type found."));
167 }
168
169 void
170 set_dirichlet_cached_data(
171 std::shared_ptr<ContainerInterfaceData<1, dim, double> const> interface_data) const
172 {
173 dirichlet_cached_data = interface_data;
174 }
175
176 std::shared_ptr<ContainerInterfaceData<1, dim, double> const>
177 get_dirichlet_cached_data() const
178 {
179 AssertThrow(dirichlet_cached_data.get(),
180 dealii::ExcMessage("Pointer to ContainerInterfaceData has not been initialized."));
181
182 return dirichlet_cached_data;
183 }
184
185private:
186 mutable std::shared_ptr<ContainerInterfaceData<1, dim, double> const> dirichlet_cached_data;
187};
188
189template<int dim>
191{
192 // Dirichlet: prescribe pressure value
193 std::map<dealii::types::boundary_id, std::shared_ptr<dealii::Function<dim>>> dirichlet_bc;
194
195 // Neumann: only the boundary IDs are stored but no inhomogeneous boundary conditions are
196 // prescribed
197 std::set<dealii::types::boundary_id> neumann_bc;
198
199 // add more types of boundary conditions
200
201
202 // return the boundary type
203 inline DEAL_II_ALWAYS_INLINE //
204 BoundaryTypeP
205 get_boundary_type(dealii::types::boundary_id const & boundary_id) const
206 {
207 if(this->dirichlet_bc.find(boundary_id) != this->dirichlet_bc.end())
208 return BoundaryTypeP::Dirichlet;
209 else if(this->neumann_bc.find(boundary_id) != this->neumann_bc.end())
210 return BoundaryTypeP::Neumann;
211
212 AssertThrow(false, dealii::ExcMessage("Boundary type of face is invalid or not implemented."));
213
214 return BoundaryTypeP::Undefined;
215 }
216
217 inline DEAL_II_ALWAYS_INLINE //
218 void
219 verify_boundary_conditions(
220 dealii::types::boundary_id const boundary_id,
221 std::set<dealii::types::boundary_id> const & periodic_boundary_ids) const
222 {
223 unsigned int counter = 0;
224 if(this->dirichlet_bc.find(boundary_id) != this->dirichlet_bc.end())
225 counter++;
226
227 if(this->neumann_bc.find(boundary_id) != this->neumann_bc.end())
228 counter++;
229
230 if(periodic_boundary_ids.find(boundary_id) != periodic_boundary_ids.end())
231 counter++;
232
233 AssertThrow(counter == 1,
234 dealii::ExcMessage("Boundary face with non-unique boundary type found."));
235 }
236};
237
238template<int dim>
240{
242 {
243 velocity = std::make_shared<BoundaryDescriptorU<dim>>();
244 pressure = std::make_shared<BoundaryDescriptorP<dim>>();
245 }
246
247 std::shared_ptr<BoundaryDescriptorU<dim>> velocity;
248 std::shared_ptr<BoundaryDescriptorP<dim>> pressure;
249};
250
251template<int dim>
252inline void
253verify_boundary_conditions(BoundaryDescriptor<dim> const & boundary_descriptor,
254 Grid<dim> const & grid)
255{
256 ExaDG::verify_boundary_conditions(*boundary_descriptor.velocity, grid);
257 ExaDG::verify_boundary_conditions(*boundary_descriptor.pressure, grid);
258}
259
260} // namespace IncNS
261} // namespace ExaDG
262
263#endif /* INCLUDE_EXADG_INCOMPRESSIBLE_NAVIER_STOKES_USER_INTERFACE_BOUNDARY_DESCRIPTOR_H_ */
Definition container_interface_data.h:45
Definition grid.h:40
Definition driver.cpp:33
Definition boundary_descriptor.h:191
Definition boundary_descriptor.h:81
Definition boundary_descriptor.h:240