/home/runner/work/DiFfRG_current/DiFfRG_current/DiFfRG/include/DiFfRG/model/fv_boundaries.hh Source File#

DiFfRG: /home/runner/work/DiFfRG_current/DiFfRG_current/DiFfRG/include/DiFfRG/model/fv_boundaries.hh Source File
DiFfRG
Discretization Framework for functional Renormalization Group flows
fv_boundaries.hh
Go to the documentation of this file.
1#pragma once
2
3// standard library
4#include <array>
5#include <cmath>
6
7// external libraries
8#include <deal.II/base/geometry_info.h>
9#include <deal.II/base/point.h>
10#include <deal.II/base/tensor.h>
11#include <deal.II/base/types.h>
12
13namespace DiFfRG
14{
15 namespace def
16 {
17 using namespace dealii;
18 template <int dim, typename NumberType, std::size_t n_components>
19 using BoundaryStencilValues = std::array<std::array<NumberType, n_components>, 2 * dim + 3>;
20
21 template <int dim> using BoundaryStencilPoints = std::array<Point<dim>, 2 * dim + 3>;
22
23 namespace BoundaryStencilIndex
24 {
25 constexpr size_t lower_outer = 0;
26 constexpr size_t lower_inner = 1;
27 constexpr size_t physical_cell = 2;
28 constexpr size_t upper_inner = 3;
29 constexpr size_t upper_outer = 4;
30 } // namespace BoundaryStencilIndex
31
32 namespace BoundaryStencilDetail
33 {
34 enum class BoundarySide { lower, upper };
35
36 template <int dim> struct BoundaryStencilGeometry;
37
38 template <> struct BoundaryStencilGeometry<1>
39 {
40 static unsigned int active_axis(const BoundaryStencilPoints<1> &, const Point<1> &) { return 0; }
41 };
42
43 template <> struct BoundaryStencilGeometry<2>
44 {
45 static unsigned int active_axis(const BoundaryStencilPoints<2> &x_stencil, const Point<2> &x_face)
46 {
47 using namespace BoundaryStencilIndex;
48 const double distance_0 = std::abs(x_face[0] - x_stencil[physical_cell][0]);
49 const double distance_1 = std::abs(x_face[1] - x_stencil[physical_cell][1]);
50 return distance_1 > distance_0 ? 1U : 0U;
51 }
52 };
53
54 template <int dim>
55 BoundarySide boundary_side(const unsigned int axis, const BoundaryStencilPoints<dim> &x_stencil,
56 const Point<dim> &x_face)
57 {
58 return x_face[axis] <= x_stencil[BoundaryStencilIndex::physical_cell][axis] ? BoundarySide::lower
60 }
61
62 template <int dim>
63 double boundary_delta(const unsigned int axis, const BoundarySide side,
64 const BoundaryStencilPoints<dim> &x_stencil)
65 {
66 using namespace BoundaryStencilIndex;
67 return side == BoundarySide::lower ? (x_stencil[upper_inner][axis] - x_stencil[physical_cell][axis])
68 : (x_stencil[physical_cell][axis] - x_stencil[lower_inner][axis]);
69 }
70
71 template <int dim, typename NumberType, size_t n_components>
72 void apply_affine_two_ghost_extrapolation(const unsigned int axis, const BoundarySide side,
75 {
76 using namespace BoundaryStencilIndex;
77 const double delta = boundary_delta(axis, side, x_stencil);
78
79 if (side == BoundarySide::lower) {
80 x_stencil[lower_inner] = x_stencil[physical_cell];
81 x_stencil[lower_outer] = x_stencil[physical_cell];
82 x_stencil[lower_inner][axis] = x_stencil[physical_cell][axis] - delta;
83 x_stencil[lower_outer][axis] = x_stencil[physical_cell][axis] - 2.0 * delta;
84 for (size_t c = 0; c < n_components; ++c) {
85 u_stencil[lower_inner][c] = NumberType(2.0) * u_stencil[physical_cell][c] - u_stencil[upper_inner][c];
86 u_stencil[lower_outer][c] =
87 NumberType(3.0) * u_stencil[physical_cell][c] - NumberType(2.0) * u_stencil[upper_inner][c];
88 }
89 return;
90 }
91
92 x_stencil[upper_inner] = x_stencil[physical_cell];
93 x_stencil[upper_outer] = x_stencil[physical_cell];
94 x_stencil[upper_inner][axis] = x_stencil[physical_cell][axis] + delta;
95 x_stencil[upper_outer][axis] = x_stencil[physical_cell][axis] + 2.0 * delta;
96 for (size_t c = 0; c < n_components; ++c) {
97 u_stencil[upper_inner][c] = NumberType(2.0) * u_stencil[physical_cell][c] - u_stencil[lower_inner][c];
98 u_stencil[upper_outer][c] =
99 NumberType(3.0) * u_stencil[physical_cell][c] - NumberType(2.0) * u_stencil[lower_inner][c];
100 }
101 }
102 } // namespace BoundaryStencilDetail
103
110 template <typename Model> class FVDefaultBoundaries
111 {
112 public:
113 template <int dim, typename NumberType, size_t n_components>
115 BoundaryStencilPoints<dim> &x_stencil, const Point<dim> &x_face) const
116 {
117 static_assert(dim == 1 || dim == 2,
118 "FV KT default boundary stencils currently support one- and two-dimensional FV domains.");
119
120 const unsigned int axis = BoundaryStencilDetail::BoundaryStencilGeometry<dim>::active_axis(x_stencil, x_face);
121 const auto side = BoundaryStencilDetail::boundary_side(axis, x_stencil, x_face);
122 BoundaryStencilDetail::apply_affine_two_ghost_extrapolation(axis, side, u_stencil, x_stencil);
123 return true;
124 }
125 };
126
134 template <typename Model> class RhoSymmetricLinearExtrapolationBoundaries
135 {
136 public:
137 template <int dim, typename NumberType, size_t n_components>
139 BoundaryStencilPoints<dim> &x_stencil, const Point<dim> &x_face) const
140 {
141 static_assert(dim == 1,
142 "RhoSymmetricLinearExtrapolationBoundaries currently supports only 1D FV domains.");
143
144 using namespace BoundaryStencilIndex;
145 const bool lower_boundary = x_face[0] <= x_stencil[physical_cell][0];
146 const double delta = lower_boundary ? (x_stencil[upper_inner][0] - x_stencil[physical_cell][0])
147 : (x_stencil[physical_cell][0] - x_stencil[lower_inner][0]);
148
149 if (lower_boundary) {
150 x_stencil[lower_inner][0] = x_stencil[physical_cell][0] - delta;
151 x_stencil[lower_outer][0] = x_stencil[physical_cell][0] - 2.0 * delta;
152 for (size_t c = 0; c < n_components; ++c) {
153 u_stencil[lower_inner][c] = u_stencil[physical_cell][c];
154 u_stencil[lower_outer][c] = u_stencil[upper_inner][c];
155 }
156 return true;
157 }
158
159 x_stencil[upper_inner][0] = x_stencil[physical_cell][0] + delta;
160 x_stencil[upper_outer][0] = x_stencil[physical_cell][0] + 2.0 * delta;
161 for (size_t c = 0; c < n_components; ++c) {
162 u_stencil[upper_inner][c] = NumberType(2.0) * u_stencil[physical_cell][c] - u_stencil[lower_inner][c];
163 u_stencil[upper_outer][c] =
164 NumberType(3.0) * u_stencil[physical_cell][c] - NumberType(2.0) * u_stencil[lower_inner][c];
165 }
166 return true;
167 }
168 };
169
180 template <typename Model> class OriginOddLinearExtrapolationBoundaries
181 {
182 public:
183 template <int dim, typename NumberType, size_t n_components>
185 BoundaryStencilPoints<dim> &x_stencil, const Point<dim> &x_face) const
186 {
187 static_assert(dim == 1 || dim == 2,
188 "OriginOddLinearExtrapolationBoundaries supports one- and two-dimensional FV domains.");
189 if constexpr (dim == 2) {
190 static_assert(n_components == dim,
191 "OriginOddLinearExtrapolationBoundaries requires one flow component per dimension in 2D.");
192 }
193
194 using namespace BoundaryStencilIndex;
195 const unsigned int axis = BoundaryStencilDetail::BoundaryStencilGeometry<dim>::active_axis(x_stencil, x_face);
196 const auto side = BoundaryStencilDetail::boundary_side(axis, x_stencil, x_face);
198 BoundaryStencilDetail::apply_affine_two_ghost_extrapolation(axis, side, u_stencil, x_stencil);
199 return true;
200 }
201
202 const double delta = BoundaryStencilDetail::boundary_delta(axis, side, x_stencil);
203 x_stencil[lower_inner] = x_stencil[physical_cell];
204 x_stencil[lower_outer] = x_stencil[physical_cell];
205 x_stencil[lower_inner][axis] = x_stencil[physical_cell][axis] - delta;
206 x_stencil[lower_outer][axis] = x_stencil[physical_cell][axis] - 2.0 * delta;
207
208 if constexpr (dim == 1) {
209 for (size_t c = 0; c < n_components; ++c) {
210 u_stencil[lower_inner][c] = -u_stencil[upper_inner][c];
211 u_stencil[lower_outer][c] = -u_stencil[upper_outer][c];
212 u_stencil[physical_cell][c] = NumberType(0.0);
213 }
214 } else {
215 const size_t odd_component = axis;
216 const size_t even_component = 1U - axis;
217 u_stencil[lower_inner][odd_component] = -u_stencil[upper_inner][odd_component];
218 u_stencil[lower_outer][odd_component] = -u_stencil[upper_outer][odd_component];
219 u_stencil[physical_cell][odd_component] = NumberType(0.0);
220 u_stencil[lower_inner][even_component] = u_stencil[physical_cell][even_component];
221 u_stencil[lower_outer][even_component] = u_stencil[upper_inner][even_component];
222 }
223
224 return true;
225 }
226 };
227
233 template <typename Model> class OriginShiftedOddLinearExtrapolationBoundaries
234 {
235 static bool is_lower_boundary_1d(const Point<1> &x_face, const BoundaryStencilPoints<1> &x_stencil)
236 {
237 return x_face[0] <= x_stencil[BoundaryStencilIndex::physical_cell][0];
238 }
239
240 public:
241 template <int dim, typename NumberType, size_t n_components>
243 BoundaryStencilPoints<dim> &x_stencil, const Point<dim> &x_face) const
244 {
245 static_assert(dim == 1, "OriginShiftedOddLinearExtrapolationBoundaries currently supports only 1D FV domains.");
246
247 const bool lower_boundary = is_lower_boundary_1d(x_face, x_stencil);
248 using namespace BoundaryStencilIndex;
249 const double delta = lower_boundary ? (x_stencil[upper_inner][0] - x_stencil[physical_cell][0])
250 : (x_stencil[physical_cell][0] - x_stencil[lower_inner][0]);
251
252 if (lower_boundary) {
253 const auto origin_values =
254 static_cast<const Model &>(*this).template origin_odd_reflection_values<NumberType, n_components>();
255
256 x_stencil[lower_inner][0] = x_stencil[physical_cell][0] - delta;
257 x_stencil[lower_outer][0] = x_stencil[physical_cell][0] - 2.0 * delta;
258 for (size_t c = 0; c < n_components; ++c) {
259 const NumberType b = origin_values[c];
260 u_stencil[lower_inner][c] = NumberType(2.0) * b - u_stencil[upper_inner][c];
261 u_stencil[lower_outer][c] = NumberType(2.0) * b - u_stencil[upper_outer][c];
262 u_stencil[physical_cell][c] = b;
263 }
264 return true;
265 }
266
267 x_stencil[upper_inner][0] = x_stencil[physical_cell][0] + delta;
268 x_stencil[upper_outer][0] = x_stencil[physical_cell][0] + 2.0 * delta;
269 for (size_t c = 0; c < n_components; ++c) {
270 u_stencil[upper_inner][c] = NumberType(2.0) * u_stencil[physical_cell][c] - u_stencil[lower_inner][c];
271 u_stencil[upper_outer][c] =
272 NumberType(3.0) * u_stencil[physical_cell][c] - NumberType(2.0) * u_stencil[lower_inner][c];
273 }
274 return true;
275 }
276 };
277 } // namespace def
278} // namespace DiFfRG
Default FV boundary strategy used by the Kurganov-Tadmor assembler.
Definition fv_boundaries.hh:111
bool apply_boundary_stencil(BoundaryStencilValues< dim, NumberType, n_components > &u_stencil, BoundaryStencilPoints< dim > &x_stencil, const Point< dim > &x_face) const
Definition fv_boundaries.hh:114
FV boundary strategy using odd reflection at the origin and linear extrapolation at the outer boundar...
Definition fv_boundaries.hh:181
bool apply_boundary_stencil(BoundaryStencilValues< dim, NumberType, n_components > &u_stencil, BoundaryStencilPoints< dim > &x_stencil, const Point< dim > &x_face) const
Definition fv_boundaries.hh:184
FV boundary strategy using odd reflection around a model-provided origin value.
Definition fv_boundaries.hh:234
static bool is_lower_boundary_1d(const Point< 1 > &x_face, const BoundaryStencilPoints< 1 > &x_stencil)
Definition fv_boundaries.hh:235
bool apply_boundary_stencil(BoundaryStencilValues< dim, NumberType, n_components > &u_stencil, BoundaryStencilPoints< dim > &x_stencil, const Point< dim > &x_face) const
Definition fv_boundaries.hh:242
FV boundary strategy for rho-coordinate models with an even lower-boundary symmetry.
Definition fv_boundaries.hh:135
bool apply_boundary_stencil(BoundaryStencilValues< dim, NumberType, n_components > &u_stencil, BoundaryStencilPoints< dim > &x_stencil, const Point< dim > &x_face) const
Definition fv_boundaries.hh:138
double boundary_delta(const unsigned int axis, const BoundarySide side, const BoundaryStencilPoints< dim > &x_stencil)
Definition fv_boundaries.hh:63
BoundarySide boundary_side(const unsigned int axis, const BoundaryStencilPoints< dim > &x_stencil, const Point< dim > &x_face)
Definition fv_boundaries.hh:55
BoundarySide
Definition fv_boundaries.hh:34
void apply_affine_two_ghost_extrapolation(const unsigned int axis, const BoundarySide side, BoundaryStencilValues< dim, NumberType, n_components > &u_stencil, BoundaryStencilPoints< dim > &x_stencil)
Definition fv_boundaries.hh:72
constexpr size_t upper_outer
Definition fv_boundaries.hh:29
constexpr size_t lower_outer
Definition fv_boundaries.hh:25
constexpr size_t upper_inner
Definition fv_boundaries.hh:28
constexpr size_t lower_inner
Definition fv_boundaries.hh:26
constexpr size_t physical_cell
Definition fv_boundaries.hh:27
std::array< std::array< NumberType, n_components >, 2 *dim+3 > BoundaryStencilValues
Definition fv_boundaries.hh:19
std::array< Point< dim >, 2 *dim+3 > BoundaryStencilPoints
Definition fv_boundaries.hh:21
Definition complex_math.hh:10
static unsigned int active_axis(const BoundaryStencilPoints< 1 > &, const Point< 1 > &)
Definition fv_boundaries.hh:40
static unsigned int active_axis(const BoundaryStencilPoints< 2 > &x_stencil, const Point< 2 > &x_face)
Definition fv_boundaries.hh:45