Projection.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <array>
7 #include <cstddef>
8 #include <functional>
9 #include <ostream>
10 
11 /// \cond
12 class Matrix;
13 template <size_t Dim>
14 class Mesh;
15 /// \endcond
16 
17 namespace Spectral {
18 
19 /// The portion of a mesh covered by a child mesh.
20 enum class ChildSize { Full, UpperHalf, LowerHalf };
21 
22 /// The portion of an element covered by a mortar.
24 
25 std::ostream& operator<<(std::ostream& os, ChildSize mortar_size) noexcept;
26 
27 /// Determine whether data needs to be projected between a child mesh and its
28 /// parent mesh. If no projection is necessary the data may be used as-is.
29 /// Projection is necessary if the child is either p-refined or h-refined
30 /// relative to its parent, or both. This operation is symmetric, i.e. it is
31 /// irrelevant in which order the child and the parent mesh are passed in.
32 template <size_t Dim>
33 bool needs_projection(const Mesh<Dim>& mesh1, const Mesh<Dim>& mesh2,
34  const std::array<ChildSize, Dim>& child_sizes) noexcept;
35 
36 /*!
37  * \brief The projection matrix from a child mesh to its parent.
38  *
39  * The projection matrices returned by this function (and by
40  * projection_matrix_parent_to_child()) define orthogonal projection operators
41  * between the spaces of functions on a parent mesh and its children. These
42  * projections are usually the correct way to transfer data between meshes in
43  * a mesh-refinement hierarchy, as well as between an element face and its
44  * adjacent mortars.
45  *
46  * These functions assume that the `child_mesh` is at least as fine as the
47  * `parent_mesh`, i.e. functions on the `parent_mesh` can be represented exactly
48  * on the `child_mesh`. In practice this means that functions can be projected
49  * to a mortar (the `child_mesh`) from both adjacent element faces (the
50  * `parent_mesh`) without losing accuracy. Similarly, functions in a
51  * mesh-refinement hierarchy don't lose accuracy when an element is split
52  * (h-refined). For this reason, the `projection_matrix_child_to_parent` is
53  * sometimes referred to as a "restriction operator" and the
54  * `projection_matrix_parent_to_child` as a "prolongation operator".
55  *
56  * The half-interval projections are based on an equation derived by
57  * Saul. This shows that the projection from the spectral basis for
58  * the entire interval to the spectral basis for the upper half
59  * interval is
60  * \f{equation*}
61  * T_{jk} = \frac{2 j + 1}{2} 2^j \sum_{n=0}^{j-k} \binom{j}{k+n}
62  * \binom{(j + k + n - 1)/2}{j} \frac{(k + n)!^2}{(2 k + n + 1)! n!}
63  * \f}
64  */
65 const Matrix& projection_matrix_child_to_parent(const Mesh<1>& child_mesh,
66  const Mesh<1>& parent_mesh,
67  ChildSize size) noexcept;
68 
69 /// The projection matrix from a child mesh to its parent, in `Dim` dimensions.
70 template <size_t Dim>
73  const Mesh<Dim>& child_mesh, const Mesh<Dim>& parent_mesh,
74  const std::array<ChildSize, Dim>& child_sizes) noexcept;
75 
76 /// The projection matrix from a parent mesh to one of its children.
77 ///
78 /// \see projection_matrix_child_to_parent()
79 const Matrix& projection_matrix_parent_to_child(const Mesh<1>& parent_mesh,
80  const Mesh<1>& child_mesh,
81  ChildSize size) noexcept;
82 
83 /// The projection matrix from a parent mesh to one of its children, in `Dim`
84 /// dimensions
85 template <size_t Dim>
88  const Mesh<Dim>& parent_mesh, const Mesh<Dim>& child_mesh,
89  const std::array<ChildSize, Dim>& child_sizes) noexcept;
90 
91 } // namespace Spectral
Matrix
A dynamically sized matrix of doubles with column-major storage.
Definition: Matrix.hpp:19
Spectral::needs_projection
bool needs_projection(const Mesh< Dim > &mesh1, const Mesh< Dim > &mesh2, const std::array< ChildSize, Dim > &child_sizes) noexcept
Determine whether data needs to be projected between a child mesh and its parent mesh....
functional
std::ostream
cstddef
Spectral::projection_matrix_parent_to_child
const Matrix & projection_matrix_parent_to_child(const Mesh< 1 > &parent_mesh, const Mesh< 1 > &child_mesh, ChildSize size) noexcept
The projection matrix from a parent mesh to one of its children.
array
Spectral::ChildSize
ChildSize
The portion of a mesh covered by a child mesh.
Definition: Projection.hpp:20
Spectral::projection_matrix_child_to_parent
const Matrix & projection_matrix_child_to_parent(const Mesh< 1 > &child_mesh, const Mesh< 1 > &parent_mesh, ChildSize size) noexcept
The projection matrix from a child mesh to its parent.
Mesh
Holds the number of grid points, basis, and quadrature in each direction of the computational grid.
Definition: Mesh.hpp:48
ostream
dg::mortar_size
MortarSize< Dim - 1 > mortar_size(const ElementId< Dim > &self, const ElementId< Dim > &neighbor, size_t dimension, const OrientationMap< Dim > &orientation) noexcept
Spectral
Functionality associated with a particular choice of basis functions and quadrature for spectral oper...
Definition: ComplexDataView.hpp:13