9#include <deal.II/base/point.h>
10#include <deal.II/base/tensor.h>
13#include <autodiff/forward/real/real.hpp>
45 template <
int dim_, HasSlopeLimiter Limiter,
typename NumberType>
class TVDReconstructor
50 static constexpr int dim = dim_;
73 template <
int n_components>
75 compute_gradient(
const dealii::Point<dim> ¢er_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)
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) {
84 const auto &u_n_1 = u_n[i_n_1][c];
85 const auto &u_n_2 = u_n[i_n_2][c];
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];
92 u_grad[c][d] = Limiter::slope_limit(du_1, du_2);
99 template <
int n_components>
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)
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];
116 if (x[d] < center_pos[d])
118 else if (x[d] > center_pos[d])
121 u_grad[c][d] = Limiter::slope_limit(du_1, du_2);
148 template <
int n_components>
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)
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())));
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{};
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;
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;
183 const auto u_grad_plus =
185 const auto u_grad_minus =
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);
196 template <
int n_components>
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)
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())));
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{};
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;
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;
231 const auto u_grad_plus =
233 const auto u_grad_minus =
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);
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)
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);
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)
272 const auto third_derivatives_AD =
274 x_stencil, u_stencil);
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]);
287 static_assert(HasReconstructor<TVDReconstructor<1, MinModLimiter, double>>);
288 static_assert(HasReconstructor<TVDReconstructor<2, MinModLimiter, double>>);
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 > ¢er_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 > ¢er_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 > ¢er_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 > ¢er_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