Mesh.hpp
Go to the documentation of this file.
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 /// \file
5 /// Defines the class template Mesh.
6 
7 #pragma once
8 
9 #include <array>
10 #include <cstddef>
11 
12 #include "DataStructures/Index.hpp"
14 #include "Options/Options.hpp"
16 #include "Utilities/Gsl.hpp"
17 #include "Utilities/Requires.hpp"
18 #include "Utilities/TypeTraits.hpp" // IWYU pragma: keep
19 #include "Utilities/TypeTraits/IsInteger.hpp"
20 
21 /// \cond
22 namespace PUP {
23 class er;
24 } // namespace PUP
25 /// \endcond
26 
27 /*!
28  * \ingroup DataStructuresGroup
29  * \brief Holds the number of grid points, basis, and quadrature in each
30  * direction of the computational grid.
31  *
32  * \details A mesh encapsulates all information necessary to construct the
33  * placement of grid points in the computational domain. It does so through a
34  * choice of basis functions, quadrature and number of points \f$N\f$ in each
35  * dimension. The grid points are the associated collocation points and can be
36  * obtained from Spectral::collocation_points(const Mesh<1>&):
37  *
38  * \snippet Test_Spectral.cpp get_points_for_mesh
39  *
40  * A simulated physical field can be represented by a DataVector of length
41  * number_of_grid_points() that holds the field value on each point of
42  * the computational grid. These values are identical to the field's nodal
43  * expansion coefficients. They approximate the field by a polynomial of degree
44  * \f$p=N-1\f$ through a linear combination of Lagrange polynomials.
45  *
46  * \tparam Dim the number of dimensions of the computational grid.
47  */
48 template <size_t Dim>
49 class Mesh {
50  public:
51  static constexpr size_t dim = Dim;
52 
53  struct Extents {
54  using type = size_t;
55  static constexpr Options::String help = {
56  "The number of collocation points per dimension"};
57  };
58 
59  struct Basis {
60  using type = Spectral::Basis;
61  static constexpr Options::String help = {
62  "The choice of spectral basis to compute the collocation points"};
63  };
64 
65  struct Quadrature {
66  using type = Spectral::Quadrature;
67  static constexpr Options::String help = {
68  "The choice of quadrature to compute the collocation points"};
69  };
70 
71  using options = tmpl::list<Extents, Basis, Quadrature>;
72 
73  static constexpr Options::String help =
74  "Holds the number of grid points, basis, and quadrature in each "
75  "direction of the computational grid. "
76  "A mesh encapsulates all information necessary to construct the "
77  "placement of grid points in the computational domain. It does so "
78  "through a choice of basis functions, quadrature and number of points "
79  "in each dimension.";
80 
81  Mesh() noexcept = default;
82 
83  /*!
84  * \brief Construct a computational grid with the same number of collocation
85  * points in each dimension.
86  *
87  * \param isotropic_extents The number of collocation points in each
88  * dimension.
89  * \param basis The choice of spectral basis to compute the
90  * collocation points
91  * \param quadrature The choice of quadrature to compute
92  * the collocation points
93  *
94  * \note Because a `Mesh<0>` extends over no dimensions, it has 1 grid point
95  * independent of the value of `isotropic_extents`.
96  */
97  Mesh(const size_t isotropic_extents, const Spectral::Basis basis,
98  const Spectral::Quadrature quadrature) noexcept
99  : extents_(isotropic_extents) {
100  ASSERT(basis != Spectral::Basis::SphericalHarmonic,
101  "SphericalHarmonic is not a valid basis for the Mesh");
102  bases_.fill(basis);
103  quadratures_.fill(quadrature);
104  }
105 
106  /*!
107  * \brief Construct a computational grid where each dimension can have a
108  * different number of collocation points.
109  *
110  * \param extents The number of collocation points per dimension
111  * \param basis The choice of spectral basis to compute the
112  * collocation points
113  * \param quadrature The choice of quadrature to compute
114  * the collocation points
115  */
117  const Spectral::Quadrature quadrature) noexcept
118  : extents_(std::move(extents)) {
119  ASSERT(basis != Spectral::Basis::SphericalHarmonic,
120  "SphericalHarmonic is not a valid basis for the Mesh");
121  bases_.fill(basis);
122  quadratures_.fill(quadrature);
123  }
124 
125  /*!
126  * \brief Construct a computational grid where each dimension can have both a
127  * different number and placement of collocation points.
128  *
129  * \param extents The number of collocation points per dimension
130  * \param bases The choice of spectral bases to compute the
131  * collocation points per dimension
132  * \param quadratures The choice of quadratures to compute
133  * the collocation points per dimension
134  */
136  std::array<Spectral::Quadrature, Dim> quadratures) noexcept
137  : extents_(std::move(extents)), quadratures_(std::move(quadratures)) {
138  for (auto it = bases.begin(); it != bases.end(); it++) {
139  ASSERT(*it != Spectral::Basis::SphericalHarmonic,
140  "SphericalHarmonic is not a valid basis for the Mesh");
141  }
142  bases_ = std::move(bases);
143  }
144 
145  /*!
146  * \brief The number of grid points in each dimension of the grid.
147  */
148  const Index<Dim>& extents() const noexcept { return extents_; }
149 
150  /*!
151  * \brief The number of grid points in dimension \p d of the grid
152  * (zero-indexed).
153  */
154  size_t extents(const size_t d) const noexcept { return extents_[d]; }
155 
156  /*!
157  * \brief The total number of grid points in all dimensions.
158  *
159  * \details `DataVector`s that represent field values on the grid have this
160  * many entries.
161  *
162  * \note A zero-dimensional mesh has one grid point, since it is the slice
163  * through a one-dimensional mesh (a line).
164  */
165  size_t number_of_grid_points() const noexcept { return extents_.product(); }
166 
167  /*!
168  * \brief Returns the 1-dimensional index corresponding to the `Dim`
169  * dimensional `index`.
170  *
171  * The first dimension varies fastest.
172  *
173  * \see collapsed_index()
174  */
175  size_t storage_index(const Index<Dim>& index) const noexcept {
176  return collapsed_index(index, extents_);
177  }
178 
179  /*!
180  * \brief The basis chosen in each dimension of the grid.
181  */
182  const std::array<Spectral::Basis, Dim>& basis() const noexcept {
183  return bases_;
184  }
185 
186  /*!
187  * \brief The basis chosen in dimension \p d of the grid (zero-indexed).
188  */
189  Spectral::Basis basis(const size_t d) const noexcept {
190  return gsl::at(bases_, d);
191  }
192 
193  /*!
194  * \brief The quadrature chosen in each dimension of the grid.
195  */
197  return quadratures_;
198  }
199 
200  /*!
201  * \brief The quadrature chosen in dimension \p d of the grid (zero-indexed).
202  */
203  Spectral::Quadrature quadrature(const size_t d) const noexcept {
204  return gsl::at(quadratures_, d);
205  }
206 
207  /*!
208  * \brief Returns a Mesh with dimension \p d removed (zero-indexed).
209  *
210  * \see slice_through()
211  */
212  // clang-tidy: incorrectly reported redundancy in template expression
213  template <size_t N = Dim, Requires<(N > 0 and N == Dim)> = nullptr> // NOLINT
214  Mesh<Dim - 1> slice_away(size_t d) const noexcept;
215 
216  /*!
217  * \brief Returns a Mesh with the dimensions \p d, ... present (zero-indexed).
218  *
219  * \details Generally you use this method to obtain a lower-dimensional Mesh
220  * by slicing through a subset of the dimensions. However, you can also
221  * reorder dimensions using this method by slicing through the dimensions in
222  * an order you choose.
223  *
224  * \see slice_away()
225  */
226  template <typename... D, Requires<(sizeof...(D) <= Dim)> = nullptr>
227  Mesh<sizeof...(D)> slice_through(D... d) const noexcept {
228  static_assert(std::conjunction_v<tt::is_integer<D>...>,
229  "The dimensions must be integers.");
230  const std::array<size_t, sizeof...(D)> dims{{static_cast<size_t>(d)...}};
231  return slice_through(dims);
232  }
233 
234  /*!
235  * \brief Returns a Mesh with the dimensions \p dims present (zero-indexed).
236  *
237  * \see slice_through() The templated overload of this function
238  */
239  template <size_t SliceDim, Requires<(SliceDim <= Dim)> = nullptr>
240  Mesh<SliceDim> slice_through(
241  const std::array<size_t, SliceDim>& dims) const noexcept;
242 
243  /*!
244  * \brief Returns the Meshes representing 1D slices of this Mesh.
245  *
246  * The is the same as the array filled with `slice_through(d)` for
247  * `d` from `0` to `Dim - 1` except in dimension 0 where
248  * `slice_through(d)` is not defined.
249  */
250  std::array<Mesh<1>, Dim> slices() const noexcept;
251 
252  // clang-tidy: runtime-references
253  void pup(PUP::er& p) noexcept; // NOLINT
254 
255  private:
256  Index<Dim> extents_{};
257  std::array<Spectral::Basis, Dim> bases_{};
258  std::array<Spectral::Quadrature, Dim> quadratures_{};
259 };
260 
261 /// \cond HIDDEN_SYMBOLS
262 template <size_t Dim>
263 bool operator==(const Mesh<Dim>& lhs, const Mesh<Dim>& rhs) noexcept;
264 
265 template <size_t Dim>
266 bool operator!=(const Mesh<Dim>& lhs, const Mesh<Dim>& rhs) noexcept;
267 
268 template <size_t Dim>
269 std::ostream& operator<<(std::ostream& os, const Mesh<Dim>& mesh) noexcept;
270 /// \endcond
gsl::at
constexpr T & at(std::array< T, N > &arr, Size index)
Retrieve a entry from a container, with checks in Debug mode that the index being retrieved is valid.
Definition: Gsl.hpp:125
Spectral::Basis
Basis
The choice of basis functions for computing collocation points and weights.
Definition: Spectral.hpp:70
Options.hpp
Mesh::Mesh
Mesh(std::array< size_t, Dim > extents, std::array< Spectral::Basis, Dim > bases, std::array< Spectral::Quadrature, Dim > quadratures) noexcept
Construct a computational grid where each dimension can have both a different number and placement of...
Definition: Mesh.hpp:135
Mesh::basis
const std::array< Spectral::Basis, Dim > & basis() const noexcept
The basis chosen in each dimension of the grid.
Definition: Mesh.hpp:182
Index
Definition: Index.hpp:31
tt::is_integer
Check if I is an integer type (non-bool, non-character), unlike std::is_integral.
Definition: IsInteger.hpp:33
collapsed_index
size_t collapsed_index(const Index< N > &index, const Index< N > &extents) noexcept
Spectral.hpp
Mesh::Basis
Definition: Mesh.hpp:59
Mesh::Quadrature
Definition: Mesh.hpp:65
Mesh::basis
Spectral::Basis basis(const size_t d) const noexcept
The basis chosen in dimension d of the grid (zero-indexed).
Definition: Mesh.hpp:189
std::ostream
cstddef
Assert.hpp
Mesh::storage_index
size_t storage_index(const Index< Dim > &index) const noexcept
Returns the 1-dimensional index corresponding to the Dim dimensional index.
Definition: Mesh.hpp:175
array
Mesh::number_of_grid_points
size_t number_of_grid_points() const noexcept
The total number of grid points in all dimensions.
Definition: Mesh.hpp:165
Index.hpp
Spectral::Quadrature
Quadrature
The choice of quadrature method to compute integration weights.
Definition: Spectral.hpp:90
Mesh::slice_through
Mesh< sizeof...(D)> slice_through(D... d) const noexcept
Returns a Mesh with the dimensions d, ... present (zero-indexed).
Definition: Mesh.hpp:227
ASSERT
#define ASSERT(a, m)
Assert that an expression should be true.
Definition: Assert.hpp:49
Mesh
Holds the number of grid points, basis, and quadrature in each direction of the computational grid.
Definition: Mesh.hpp:49
Gsl.hpp
Options::String
const char *const String
The string used in option structs.
Definition: Options.hpp:32
Mesh::quadrature
Spectral::Quadrature quadrature(const size_t d) const noexcept
The quadrature chosen in dimension d of the grid (zero-indexed).
Definition: Mesh.hpp:203
Requires.hpp
Mesh::extents
size_t extents(const size_t d) const noexcept
The number of grid points in dimension d of the grid (zero-indexed).
Definition: Mesh.hpp:154
Mesh::quadrature
const std::array< Spectral::Quadrature, Dim > & quadrature() const noexcept
The quadrature chosen in each dimension of the grid.
Definition: Mesh.hpp:196
Requires
typename Requires_detail::requires_impl< B >::template_error_type_failed_to_meet_requirements_on_template_parameters Requires
Express requirements on the template parameters of a function or class, replaces std::enable_if_t
Definition: Requires.hpp:67
Mesh::slice_away
Mesh< Dim - 1 > slice_away(size_t d) const noexcept
Returns a Mesh with dimension d removed (zero-indexed).
Mesh::Extents
Definition: Mesh.hpp:53
Mesh::extents
const Index< Dim > & extents() const noexcept
The number of grid points in each dimension of the grid.
Definition: Mesh.hpp:148
Mesh::Mesh
Mesh(std::array< size_t, Dim > extents, const Spectral::Basis basis, const Spectral::Quadrature quadrature) noexcept
Construct a computational grid where each dimension can have a different number of collocation points...
Definition: Mesh.hpp:116
Spectral
Functionality associated with a particular choice of basis functions and quadrature for spectral oper...
Definition: ComplexDataView.hpp:13