Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <array>
7 : #include <cmath>
8 : #include <cstddef>
9 : #include <utility>
10 :
11 : #include "NumericalAlgorithms/FiniteDifference/Reconstruct.hpp"
12 : #include "Utilities/ForceInline.hpp"
13 : #include "Utilities/Gsl.hpp"
14 : #include "Utilities/Math.hpp"
15 : #include "Utilities/TMPL.hpp"
16 :
17 : /// \cond
18 : template <size_t Dim>
19 : class Direction;
20 : template <size_t Dim>
21 : class Index;
22 : /// \endcond
23 :
24 : namespace fd::reconstruction {
25 : namespace detail {
26 : struct MinmodReconstructor {
27 : SPECTRE_ALWAYS_INLINE static std::array<double, 2> pointwise(
28 : const double* const q, const int stride) {
29 : using std::min;
30 : using std::abs;
31 : // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
32 : const double a = q[stride] - q[0];
33 : // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
34 : const double b = q[0] - q[-stride];
35 : const double slope = 0.5 * (sgn(a) + sgn(b)) * min(abs(a), abs(b));
36 : // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
37 : return {{q[0] - 0.5 * slope, q[0] + 0.5 * slope}};
38 : }
39 :
40 : SPECTRE_ALWAYS_INLINE static constexpr size_t stencil_width() { return 3; }
41 : };
42 : } // namespace detail
43 :
44 : /*!
45 : * \ingroup FiniteDifferenceGroup
46 : * \brief Performs minmod reconstruction on the `volume_vars` in each direction.
47 : *
48 : * On a 1d mesh with spacing \f$\Delta x\f$ we denote the solution at the
49 : * \f$j\f$th point by \f$u_j\f$. The minmod reconstruction \cite RezzollaBook
50 : * first computes:
51 : *
52 : * \f{align}
53 : * \sigma_j\equiv \textrm{minmod}\left(\frac{u_j-u_{j-1}}{\Delta x},
54 : * \frac{u_{j+1}-u_j}{\Delta x}\right)
55 : * \f}
56 : *
57 : * where
58 : *
59 : * \f{align}
60 : * \mathrm{minmod}(a,b)=
61 : * \left\{
62 : * \begin{array}{ll}
63 : * \mathrm{sgn}(a)\min(\lvert a\rvert, \lvert b\rvert)
64 : * & \mathrm{if} \; \mathrm{sgn}(a)=\mathrm{sgn}(b) \\
65 : * 0 & \mathrm{otherwise}
66 : * \end{array}\right.
67 : * \f}
68 : *
69 : * The reconstructed solution \f$u_j(x)\f$ in the \f$j\f$th cell is given by
70 : *
71 : * \f{align}
72 : * u_j(x)=u_j + \sigma_j (x-x_j),
73 : * \f}
74 : *
75 : * where \f$x_j\f$ is the coordinate \f$x\f$ at the center of the cell.
76 : */
77 : template <size_t Dim>
78 1 : void minmod(const gsl::not_null<std::array<gsl::span<double>, Dim>*>
79 : reconstructed_upper_side_of_face_vars,
80 : const gsl::not_null<std::array<gsl::span<double>, Dim>*>
81 : reconstructed_lower_side_of_face_vars,
82 : const gsl::span<const double>& volume_vars,
83 : const DirectionMap<Dim, gsl::span<const double>>& ghost_cell_vars,
84 : const Index<Dim>& volume_extents,
85 : const size_t number_of_variables) {
86 : detail::reconstruct<detail::MinmodReconstructor>(
87 : reconstructed_upper_side_of_face_vars,
88 : reconstructed_lower_side_of_face_vars, volume_vars, ghost_cell_vars,
89 : volume_extents, number_of_variables);
90 : }
91 : } // namespace fd::reconstruction
|