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 <cstddef> 8 : 9 : #include "NumericalAlgorithms/FiniteDifference/Reconstruct.hpp" 10 : #include "Utilities/ForceInline.hpp" 11 : #include "Utilities/Gsl.hpp" 12 : 13 : /// \cond 14 : template <size_t Dim, typename T> 15 : class DirectionMap; 16 : template <size_t Dim> 17 : class Index; 18 : /// \endcond 19 : 20 : namespace fd::reconstruction { 21 : namespace detail { 22 : template <size_t Degree> 23 : struct UnlimitedReconstructor { 24 : static_assert(Degree == 2 or Degree == 4 or Degree == 6 or Degree == 8); 25 : SPECTRE_ALWAYS_INLINE static std::array<double, 2> pointwise( 26 : const double* const q, const int stride) { 27 : if constexpr (Degree == 2) { 28 : // quadratic polynomial 29 : return {{0.375 * q[-stride] + 0.75 * q[0] - 0.125 * q[stride], 30 : -0.125 * q[-stride] + 0.75 * q[0] + 0.375 * q[stride]}}; 31 : } else if constexpr (Degree == 4) { 32 : // quintic polynomial 33 : return {{-0.0390625 * q[-2 * stride] + 0.46875 * q[-stride] + 34 : 0.703125 * q[0] - 0.15625 * q[stride] + 35 : 0.0234375 * q[2 * stride], 36 : 0.0234375 * q[-2 * stride] - 0.15625 * q[-stride] + 37 : 0.703125 * q[0] + 0.46875 * q[stride] - 38 : 0.0390625 * q[2 * stride]}}; 39 : } else if constexpr (Degree == 6) { 40 : return {{-0.1708984375 * q[stride] + 0.041015625 * q[2 * stride] - 41 : 0.0048828125 * q[3 * stride] + 0.5126953125 * q[-stride] - 42 : 0.068359375 * q[-2 * stride] + 43 : 0.0068359375 * q[-3 * stride] + 0.68359375 * q[0], 44 : 0.5126953125 * q[stride] - 0.068359375 * q[2 * stride] + 45 : 0.0068359375 * q[3 * stride] - 0.1708984375 * q[-stride] + 46 : 0.041015625 * q[-2 * stride] - 47 : 0.0048828125 * q[-3 * stride] + 0.68359375 * q[0]}}; 48 : } else if constexpr (Degree == 8) { 49 : return { 50 : {-0.179443359375 * q[stride] + 0.0538330078125 * q[2 * stride] - 51 : 0.010986328125 * q[3 * stride] + 52 : 0.001068115234375 * q[4 * stride] + 0.538330078125 * q[-stride] - 53 : 0.0897216796875 * q[-2 * stride] + 54 : 0.015380859375 * q[-3 * stride] - 55 : 0.001373291015625 * q[-4 * stride] + 0.67291259765625 * q[0], 56 : 0.538330078125 * q[stride] - 0.0897216796875 * q[2 * stride] + 57 : 0.015380859375 * q[3 * stride] - 58 : 0.001373291015625 * q[4 * stride] - 0.179443359375 * q[-stride] + 59 : 0.0538330078125 * q[-2 * stride] - 60 : 0.010986328125 * q[-3 * stride] + 61 : 0.001068115234375 * q[-4 * stride] + 0.67291259765625 * q[0]}}; 62 : } 63 : } 64 : 65 : SPECTRE_ALWAYS_INLINE static constexpr size_t stencil_width() { 66 : return Degree + 1; 67 : } 68 : }; 69 : } // namespace detail 70 : 71 : /*! 72 : * \ingroup FiniteDifferenceGroup 73 : * \brief Performs unlimited reconstruction on the `vars` in each direction. 74 : * 75 : * On a 1d mesh with spacing \f$\Delta x\f$ we denote the solution at the 76 : * \f$j\f$th point by \f$u_j\f$. The degree 2 reconstruction is 77 : * 78 : * \f{align}{ 79 : * u_{j+1/2} &= -\frac{1}{8} u_{j-1} + \frac{3}{4} u_j + \frac{3}{8} u_{j+1}, \\ 80 : * u_{j-1/2} &= \frac{3}{8} u_{j-1} + \frac{3}{4} u_j - \frac{1}{8} u_{j+1}. 81 : * \f} 82 : * 83 : * The degree 4 reconstruction is 84 : * 85 : * \f{align}{ 86 : * u_{j-1/2} &= - \frac{5}{128}u_{j-2} + \frac{15}{32}u_{j-1} + 87 : * \frac{45}{64}u_{j} -\frac{5}{32}u_{j+1} + \frac{3}{128}u_{j+2}, \\ 88 : * u_{j+1/2} &= \frac{3}{128}u_{j-2} - \frac{5}{32}u_{j-1} + \frac{45}{64}u_{j} 89 : * + \frac{15}{32}u_{j+1} - \frac{5}{128}u_{j+2}. 90 : * \f} 91 : * 92 : * Degree 6 and 8 reconstruction is also supported. 93 : */ 94 : template <size_t Degree, size_t Dim> 95 1 : void unlimited( 96 : const gsl::not_null<std::array<gsl::span<double>, Dim>*> 97 : reconstructed_upper_side_of_face_vars, 98 : const gsl::not_null<std::array<gsl::span<double>, Dim>*> 99 : reconstructed_lower_side_of_face_vars, 100 : const gsl::span<const double>& volume_vars, 101 : const DirectionMap<Dim, gsl::span<const double>>& ghost_cell_vars, 102 : const Index<Dim>& volume_extents, const size_t number_of_variables) { 103 : detail::reconstruct<detail::UnlimitedReconstructor<Degree>>( 104 : reconstructed_upper_side_of_face_vars, 105 : reconstructed_lower_side_of_face_vars, volume_vars, ghost_cell_vars, 106 : volume_extents, number_of_variables); 107 : } 108 : } // namespace fd::reconstruction