/home/runner/work/DiFfRG_current/DiFfRG_current/DiFfRG/include/DiFfRG/discretization/FV/reconstructor/advection/tvd_reconstructor.hh Source File#

DiFfRG: /home/runner/work/DiFfRG_current/DiFfRG_current/DiFfRG/include/DiFfRG/discretization/FV/reconstructor/advection/tvd_reconstructor.hh Source File
DiFfRG
Discretization Framework for functional Renormalization Group flows
tvd_reconstructor.hh
Go to the documentation of this file.
1#pragma once
2
3// DiFfRG
7
8// deal.II
9#include <deal.II/base/point.h>
10#include <deal.II/base/tensor.h>
11
12// autodiff
13#include <autodiff/forward/real/real.hpp>
14
15// standard library
16#include <array>
17#include <cstddef>
18
19namespace DiFfRG
20{
21 namespace def
22 {
45 template <int dim_, HasSlopeLimiter Limiter, typename NumberType> class TVDReconstructor
46 {
47 using ADNumberType = autodiff::Real<1, NumberType>;
48
49 public:
50 static constexpr int dim = dim_;
51 static constexpr int n_faces = 2 * dim;
52 static constexpr int jacobian_stencil_radius = 2;
53
54 // Expose the Limiter type for use by other templates
55 using LimiterType = Limiter;
73 template <int n_components>
75 compute_gradient(const dealii::Point<dim> &center_pos, const std::array<NumberType, n_components> &u_center,
76 const std::array<dealii::Point<dim>, n_faces> &x_n,
77 const std::array<std::array<NumberType, n_components>, n_faces> &u_n)
78 {
80 for (size_t c = 0; c < static_cast<size_t>(n_components); c++) {
81 const NumberType &u_val = u_center[c];
82 for (int d = 0, i_n_1 = 0, i_n_2 = 1; d < dim; d++, i_n_1 += 2, i_n_2 += 2) {
83
84 const auto &u_n_1 = u_n[i_n_1][c];
85 const auto &u_n_2 = u_n[i_n_2][c];
86
87 const auto dx_1 = x_n[i_n_1] - center_pos;
88 const NumberType du_1 = (u_n_1 - u_val) / dx_1[d];
89 const auto dx_2 = x_n[i_n_2] - center_pos;
90 const NumberType du_2 = (u_n_2 - u_val) / dx_2[d];
91
92 u_grad[c][d] = Limiter::slope_limit(du_1, du_2);
93 }
94 }
95
96 return u_grad;
97 }
98
99 template <int n_components>
101 compute_gradient_at_point(const dealii::Point<dim> &center_pos, const dealii::Point<dim> &x,
102 const std::array<NumberType, n_components> &u_center,
103 const std::array<dealii::Point<dim>, n_faces> &x_n,
104 const std::array<std::array<NumberType, n_components>, n_faces> &u_n)
105 {
107
108 for (size_t c = 0; c < static_cast<size_t>(n_components); ++c) {
109 const NumberType &u_val = u_center[c];
110 for (int d = 0, i_n_1 = 0, i_n_2 = 1; d < dim; ++d, i_n_1 += 2, i_n_2 += 2) {
111 const auto dx_1 = x_n[i_n_1] - center_pos;
112 const NumberType du_1 = (u_n[i_n_1][c] - u_val) / dx_1[d];
113 const auto dx_2 = x_n[i_n_2] - center_pos;
114 const NumberType du_2 = (u_n[i_n_2][c] - u_val) / dx_2[d];
115
116 if (x[d] < center_pos[d])
117 u_grad[c][d] = du_1;
118 else if (x[d] > center_pos[d])
119 u_grad[c][d] = du_2;
120 else
121 u_grad[c][d] = Limiter::slope_limit(du_1, du_2);
122 }
123 }
124
125 return u_grad;
126 }
127
148 template <int n_components>
150 compute_gradient_derivative(const dealii::Point<dim> &center_pos,
151 const std::array<ADNumberType, n_components> &u_center,
152 const std::array<dealii::Point<dim>, n_faces> &x_n,
153 const std::array<std::array<ADNumberType, n_components>, n_faces> &u_n)
154 {
155 double scale = 1.0;
156 for (size_t c = 0; c < n_components; ++c)
157 if (std::abs(autodiff::derivative(u_center[c])) > 1.0e-14)
158 scale = std::max(scale, std::abs(static_cast<NumberType>(u_center[c].val())));
159 for (size_t face = 0; face < n_faces; ++face)
160 for (size_t c = 0; c < n_components; ++c)
161 if (std::abs(autodiff::derivative(u_n[face][c])) > 1.0e-14)
162 scale = std::max(scale, std::abs(static_cast<NumberType>(u_n[face][c].val())));
163
164 const NumberType eps = NumberType(1.0e-8) * scale;
165 std::array<NumberType, n_components> u_center_plus{}, u_center_minus{};
166 std::array<std::array<NumberType, n_components>, n_faces> u_n_plus{}, u_n_minus{};
167
168 for (size_t c = 0; c < n_components; ++c) {
169 const NumberType value = static_cast<NumberType>(u_center[c].val());
170 const NumberType direction = autodiff::derivative(u_center[c]);
171 u_center_plus[c] = value + eps * direction;
172 u_center_minus[c] = value - eps * direction;
173 }
174 for (size_t face = 0; face < n_faces; ++face) {
175 for (size_t c = 0; c < n_components; ++c) {
176 const NumberType value = static_cast<NumberType>(u_n[face][c].val());
177 const NumberType direction = autodiff::derivative(u_n[face][c]);
178 u_n_plus[face][c] = value + eps * direction;
179 u_n_minus[face][c] = value - eps * direction;
180 }
181 }
182
183 const auto u_grad_plus =
184 compute_gradient<n_components>(center_pos, u_center_plus, x_n, u_n_plus);
185 const auto u_grad_minus =
186 compute_gradient<n_components>(center_pos, u_center_minus, x_n, u_n_minus);
187
189 for (size_t c = 0; c < n_components; ++c)
190 for (int d = 0; d < dim; ++d)
191 result[c][d] = (u_grad_plus[c][d] - u_grad_minus[c][d]) / (NumberType(2.0) * eps);
192
193 return result;
194 }
195
196 template <int n_components>
198 compute_gradient_at_point_derivative(const dealii::Point<dim> &center_pos, const dealii::Point<dim> &x,
199 const std::array<ADNumberType, n_components> &u_center,
200 const std::array<dealii::Point<dim>, n_faces> &x_n,
201 const std::array<std::array<ADNumberType, n_components>, n_faces> &u_n)
202 {
203 double scale = 1.0;
204 for (size_t c = 0; c < n_components; ++c)
205 if (std::abs(autodiff::derivative(u_center[c])) > 1.0e-14)
206 scale = std::max(scale, std::abs(static_cast<NumberType>(u_center[c].val())));
207 for (size_t face = 0; face < n_faces; ++face)
208 for (size_t c = 0; c < n_components; ++c)
209 if (std::abs(autodiff::derivative(u_n[face][c])) > 1.0e-14)
210 scale = std::max(scale, std::abs(static_cast<NumberType>(u_n[face][c].val())));
211
212 const NumberType eps = NumberType(1.0e-8) * scale;
213 std::array<NumberType, n_components> u_center_plus{}, u_center_minus{};
214 std::array<std::array<NumberType, n_components>, n_faces> u_n_plus{}, u_n_minus{};
215
216 for (size_t c = 0; c < n_components; ++c) {
217 const NumberType value = static_cast<NumberType>(u_center[c].val());
218 const NumberType direction = autodiff::derivative(u_center[c]);
219 u_center_plus[c] = value + eps * direction;
220 u_center_minus[c] = value - eps * direction;
221 }
222 for (size_t face = 0; face < n_faces; ++face) {
223 for (size_t c = 0; c < n_components; ++c) {
224 const NumberType value = static_cast<NumberType>(u_n[face][c].val());
225 const NumberType direction = autodiff::derivative(u_n[face][c]);
226 u_n_plus[face][c] = value + eps * direction;
227 u_n_minus[face][c] = value - eps * direction;
228 }
229 }
230
231 const auto u_grad_plus =
232 compute_gradient_at_point<n_components>(center_pos, x, u_center_plus, x_n, u_n_plus);
233 const auto u_grad_minus =
234 compute_gradient_at_point<n_components>(center_pos, x, u_center_minus, x_n, u_n_minus);
235
237 for (size_t c = 0; c < n_components; ++c)
238 for (int d = 0; d < dim; ++d)
239 result[c][d] = (u_grad_plus[c][d] - u_grad_minus[c][d]) / (NumberType(2.0) * eps);
240
241 return result;
242 }
243
244 template <int n_components>
246 const std::array<dealii::Point<dim>, 4> &x_stencil,
247 const std::array<std::array<NumberType, n_components>, 4> &u_stencil)
248 {
250 if constexpr (dim == 1) {
251 const auto x0 = x_stencil[0][0];
252 const auto x1 = x_stencil[1][0];
253 const auto x2 = x_stencil[2][0];
254 const auto x3 = x_stencil[3][0];
255 for (size_t c = 0; c < n_components; ++c) {
256 const auto f01 = (u_stencil[1][c] - u_stencil[0][c]) / (x1 - x0);
257 const auto f12 = (u_stencil[2][c] - u_stencil[1][c]) / (x2 - x1);
258 const auto f23 = (u_stencil[3][c] - u_stencil[2][c]) / (x3 - x2);
259 const auto f012 = (f12 - f01) / (x2 - x0);
260 const auto f123 = (f23 - f12) / (x3 - x1);
261 result[c][0][0][0] = NumberType(6.) * (f123 - f012) / (x3 - x0);
262 }
263 }
264 return result;
265 }
266
267 template <int n_components>
269 const std::array<dealii::Point<dim>, 4> &x_stencil,
270 const std::array<std::array<ADNumberType, n_components>, 4> &u_stencil)
271 {
272 const auto third_derivatives_AD =
274 x_stencil, u_stencil);
275
277 for (size_t c = 0; c < n_components; ++c)
278 for (int d0 = 0; d0 < dim; ++d0)
279 for (int d1 = 0; d1 < dim; ++d1)
280 for (int d2 = 0; d2 < dim; ++d2)
281 result[c][d0][d1][d2] = autodiff::derivative(third_derivatives_AD[c][d0][d1][d2]);
282 return result;
283 }
284 };
285
286 // Verify the default instantiation satisfies the concept.
287 static_assert(HasReconstructor<TVDReconstructor<1, MinModLimiter, double>>);
288 static_assert(HasReconstructor<TVDReconstructor<2, MinModLimiter, double>>);
289
290 } // namespace def
291} // namespace DiFfRG
TVD gradient reconstructor parameterised by a slope limiter.
Definition tvd_reconstructor.hh:46
static ThirdDerivativeType< dim, NumberType, n_components > compute_third_derivatives_at_face(const std::array< dealii::Point< dim >, 4 > &x_stencil, const std::array< std::array< NumberType, n_components >, 4 > &u_stencil)
Definition tvd_reconstructor.hh:245
static constexpr int jacobian_stencil_radius
Definition tvd_reconstructor.hh:52
static GradientType< dim, NumberType, n_components > compute_gradient(const dealii::Point< dim > &center_pos, const std::array< NumberType, n_components > &u_center, const std::array< dealii::Point< dim >, n_faces > &x_n, const std::array< std::array< NumberType, n_components >, n_faces > &u_n)
Compute the gradient of u using the injected slope limiter.
Definition tvd_reconstructor.hh:75
static ThirdDerivativeType< dim, NumberType, n_components > compute_third_derivatives_at_face_derivative(const std::array< dealii::Point< dim >, 4 > &x_stencil, const std::array< std::array< ADNumberType, n_components >, 4 > &u_stencil)
Definition tvd_reconstructor.hh:268
static constexpr int dim
Definition tvd_reconstructor.hh:50
static GradientType< dim, NumberType, n_components > compute_gradient_derivative(const dealii::Point< dim > &center_pos, const std::array< ADNumberType, n_components > &u_center, const std::array< dealii::Point< dim >, n_faces > &x_n, const std::array< std::array< ADNumberType, n_components >, n_faces > &u_n)
Compute the derivative of the limited gradient w.r.t. a single stencil DOF.
Definition tvd_reconstructor.hh:150
static GradientType< dim, NumberType, n_components > compute_gradient_at_point_derivative(const dealii::Point< dim > &center_pos, const dealii::Point< dim > &x, const std::array< ADNumberType, n_components > &u_center, const std::array< dealii::Point< dim >, n_faces > &x_n, const std::array< std::array< ADNumberType, n_components >, n_faces > &u_n)
Definition tvd_reconstructor.hh:198
Limiter LimiterType
Definition tvd_reconstructor.hh:55
static constexpr int n_faces
Definition tvd_reconstructor.hh:51
static GradientType< dim, NumberType, n_components > compute_gradient_at_point(const dealii::Point< dim > &center_pos, const dealii::Point< dim > &x, const std::array< NumberType, n_components > &u_center, const std::array< dealii::Point< dim >, n_faces > &x_n, const std::array< std::array< NumberType, n_components >, n_faces > &u_n)
Definition tvd_reconstructor.hh:101
autodiff::Real< 1, NumberType > ADNumberType
Definition tvd_reconstructor.hh:47
std::array< dealii::Tensor< 1, dim, NumberType >, n_components > GradientType
Per-component gradient type: one Tensor<1,dim> per solution component.
Definition types.hh:17
std::array< dealii::Tensor< 3, dim, NumberType >, n_components > ThirdDerivativeType
Per-component third spatial derivative type.
Definition types.hh:23
Definition complex_math.hh:10