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 : #include <utility> // for std::pair
9 :
10 : #include "Domain/Structure/Side.hpp"
11 : #include "Utilities/Gsl.hpp"
12 :
13 : /// \cond
14 : class DataVector;
15 : template <size_t Dim>
16 : class Direction;
17 : template <size_t Dim, typename T>
18 : class DirectionMap;
19 : template <size_t Dim>
20 : class Index;
21 : /// \endcond
22 :
23 : namespace fd {
24 : /*!
25 : * \ingroup FiniteDifferenceGroup
26 : * \brief Variable and flux vector splitting reconstruction schemes for finite
27 : * difference methods.
28 : *
29 : * Implementations of reconstruction methods must call the function
30 : * `fd::reconstruction::detail::reconstruct` to perform the reconstruction.
31 : * This function performs the actual loops taking into account strides and ghost
32 : * zones for the reconstruction method. The `reconstruct` function has the
33 : * following signature:
34 : *
35 : * \code
36 : * template <typename Reconstructor, typename... ArgsForReconstructor, size_t
37 : * Dim>
38 : * void reconstruct(
39 : * const gsl::not_null<std::array<gsl::span<double>, Dim>*>
40 : * reconstructed_upper_side_of_face_vars,
41 : * const gsl::not_null<std::array<gsl::span<double>, Dim>*>
42 : * reconstructed_lower_side_of_face_vars,
43 : * const gsl::span<const double>& volume_vars,
44 : * const DirectionMap<Dim, gsl::span<const double>>& ghost_cell_vars,
45 : * const Index<Dim>& volume_extents, const size_t number_of_variables,
46 : * const ArgsForReconstructor&... args_for_reconstructor);
47 : * \endcode
48 : *
49 : * The type of reconstruction done is specified with the `Reconstructor`
50 : * explicit template parameter. Parameters for the reconstruction scheme, such
51 : * as the linear weights and the epsilon tolerance in a CWENO reconstruction
52 : * scheme, are forwarded along using the `args_for_reconstruction` parameter
53 : * pack.
54 : *
55 : * `Reconstructor` classes must define:
56 : * - a `static constexpr size_t stencil_width()` function that
57 : * returns the size of the stencil, e.g. 3 for minmod, and 5 for 5-point
58 : * reconstruction.
59 : * - a
60 : * \code
61 : * SPECTRE_ALWAYS_INLINE static std::array<double, 2> pointwise(
62 : * const double* const u, const int stride)
63 : * \endcode
64 : * function that optionally takes the additional arguments.
65 : * The `u` are the cell-centered values to reconstruct. The value \f$u_i\f$ in
66 : * the current FD cell is located at `u[0]`, the value at neighbor cell
67 : * \f$u_{i+1}\f$ is at `u[stride]`, and the value at neighbor cell
68 : * \f$u_{i-1}\f$ is at `u[-stride]`. The returned values are the
69 : * reconstructed solution on the lower and upper side of the cell.
70 : *
71 : * \note Currently the stride is always one because we transpose the data before
72 : * reconstruction. However, it may be faster to have a non-unit stride without
73 : * the transpose. We have the `stride` parameter in the reconstruction schemes
74 : * to make testing performance easier in the future.
75 : *
76 : * Here is an ASCII illustration of the names of various quantities and where in
77 : * the cells they are:
78 : *
79 : * \code
80 : * reconstructed_upper_side_of_face_vars v
81 : * reconstructed_lower_side_of_face_vars v
82 : * volume_vars (at the cell-center) v
83 : * | x |
84 : * ^ reconstructed_upper_side_of_face_vars
85 : * ^ reconstructed_lower_side_of_face_vars
86 : * \endcode
87 : *
88 : * Notice that the `reconstructed_upper_side_of_face_vars` are actually on the
89 : * lower side of the cells, while the `reconstructed_lower_side_of_face_vars`
90 : * are on the upper side of the cells. The `upper` and `lower` here refers to
91 : * which side of the interface the quantity is on, not from the perspective of
92 : * each cells.
93 : */
94 : namespace reconstruction {
95 : namespace detail {
96 : template <typename Reconstructor, size_t Dim, typename... ArgsForReconstructor>
97 : void reconstruct(
98 : gsl::not_null<std::array<gsl::span<double>, Dim>*>
99 : reconstructed_upper_side_of_face_vars,
100 : gsl::not_null<std::array<gsl::span<double>, Dim>*>
101 : reconstructed_lower_side_of_face_vars,
102 : const gsl::span<const double>& volume_vars,
103 : const DirectionMap<Dim, gsl::span<const double>>& ghost_cell_vars,
104 : const Index<Dim>& volume_extents, size_t number_of_variables,
105 : const ArgsForReconstructor&... args_for_reconstructor);
106 :
107 : // Overload used to get the reconstruction order used in each cell.
108 : template <typename Reconstructor, size_t Dim, typename... ArgsForReconstructor>
109 : void reconstruct(
110 : gsl::not_null<std::array<gsl::span<double>, Dim>*>
111 : reconstructed_upper_side_of_face_vars,
112 : gsl::not_null<std::array<gsl::span<double>, Dim>*>
113 : reconstructed_lower_side_of_face_vars,
114 : gsl::not_null<std::optional<std::array<gsl::span<std::uint8_t>, Dim>>*>
115 : reconstruction_order,
116 : const gsl::span<const double>& volume_vars,
117 : const DirectionMap<Dim, gsl::span<const double>>& ghost_cell_vars,
118 : const Index<Dim>& volume_extents, size_t number_of_variables,
119 : const ArgsForReconstructor&... args_for_reconstructor);
120 : } // namespace detail
121 :
122 : /*!
123 : * \ingroup FiniteDifferenceGroup
124 : * \brief In a given direction, reconstruct the cells in the neighboring Element
125 : * (or cluster of cells) nearest to the shared boundary between the current and
126 : * neighboring Element (or cluster of cells).
127 : *
128 : * This is needed if one is sending reconstruction and flux data separately, or
129 : * if one is using DG-FD hybrid schemes. Below is an ASCII diagram of what is
130 : * reconstructed.
131 : *
132 : * ```
133 : * Self | Neighbor
134 : * x x x x x | o o o
135 : * ^+
136 : * Reconstruct to right/+ side of the interface
137 : * ```
138 : */
139 : template <Side LowerOrUpperSide, typename Reconstructor,
140 : bool UseExteriorCell = true,
141 : size_t NumberOfGhostPoints = (Reconstructor::stencil_width() / 2 + 1),
142 : size_t Dim, typename... ArgsForReconstructor>
143 1 : void reconstruct_neighbor(
144 : gsl::not_null<DataVector*> face_data, const DataVector& volume_data,
145 : const DataVector& neighbor_data, const Index<Dim>& volume_extents,
146 : const Index<Dim>& ghost_data_extents,
147 : const Direction<Dim>& direction_to_reconstruct,
148 : const ArgsForReconstructor&... args_for_reconstructor);
149 : } // namespace reconstruction
150 : } // namespace fd
|