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