SpECTRE Documentation Coverage Report
Current view: top level - NumericalAlgorithms/Spectral - Projection.hpp Hit Total Coverage
Commit: 1f2210958b4f38fdc0400907ee7c6d5af5111418 Lines: 8 12 66.7 %
Date: 2025-12-05 05:03:31
Legend: Lines: hit not hit

          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 <functional>
       9             : #include <ostream>
      10             : 
      11             : #include "NumericalAlgorithms/Spectral/SegmentSize.hpp"
      12             : #include "Utilities/ConstantExpressions.hpp"
      13             : 
      14             : /// \cond
      15             : class Matrix;
      16             : template <size_t Dim>
      17             : class Mesh;
      18             : /// \endcond
      19             : 
      20             : namespace Spectral {
      21             : /// Determine whether data needs to be projected between a child mesh and its
      22             : /// parent mesh. If no projection is necessary the data may be used as-is.
      23             : /// Projection is necessary if the child is either p-refined or h-refined
      24             : /// relative to its parent, or both. This operation is symmetric, i.e. it is
      25             : /// irrelevant in which order the child and the parent mesh are passed in.
      26             : template <size_t Dim>
      27           1 : bool needs_projection(const Mesh<Dim>& mesh1, const Mesh<Dim>& mesh2,
      28             :                       const std::array<SegmentSize, Dim>& child_sizes);
      29             : 
      30             : /*!
      31             :  * \brief The projection matrix from a child mesh to its parent.
      32             :  *
      33             :  * The projection matrices returned by this function (and by
      34             :  * projection_matrix_parent_to_child()) define orthogonal projection operators
      35             :  * between the spaces of functions on a parent mesh and its children. These
      36             :  * projections are usually the correct way to transfer data between meshes in
      37             :  * a mesh-refinement hierarchy, as well as between an element face and its
      38             :  * adjacent mortars.
      39             :  *
      40             :  * These functions assume that the `child_mesh` is at least as fine as the
      41             :  * `parent_mesh`, i.e. functions on the `parent_mesh` can be represented exactly
      42             :  * on the `child_mesh`. In practice this means that functions can be projected
      43             :  * to a mortar (the `child_mesh`) from both adjacent element faces (the
      44             :  * `parent_mesh`) without losing accuracy. Similarly, functions in a
      45             :  * mesh-refinement hierarchy don't lose accuracy when an element is split
      46             :  * (h-refined). For this reason, the `projection_matrix_child_to_parent` is
      47             :  * sometimes referred to as a "restriction operator" and the
      48             :  * `projection_matrix_parent_to_child` as a "prolongation operator".
      49             :  *
      50             :  * \par Massive quantities
      51             :  * If the quantity that should be projected is not a function over the
      52             :  * computational grid but a "massive" residual, i.e. a quantity
      53             :  * \f$\int_{\Omega_k} f(x) \psi_p(x) \mathrm{d}V\f$ where \f$\psi_p\f$ are the
      54             :  * basis functions on the mesh, then pass `true` for the parameter
      55             :  * `operand_is_massive` (default is `false`). The restriction operator for this
      56             :  * case is just the transpose of the prolongation operator, i.e. just an
      57             :  * interpolation matrix transpose. Note that the "massive" residual already
      58             :  * takes the difference in element size between parent and children into account
      59             :  * by including a Jacobian in the volume element of the integral.
      60             :  *
      61             :  * \par Implementation details
      62             :  * The half-interval projections are based on an equation derived by
      63             :  * Saul.  This shows that the projection from the spectral basis for
      64             :  * the entire interval to the spectral basis for the upper half
      65             :  * interval is
      66             :  * \f{equation*}
      67             :  * T_{jk} = \frac{2 j + 1}{2} 2^j \sum_{n=0}^{j-k} \binom{j}{k+n}
      68             :  * \binom{(j + k + n - 1)/2}{j} \frac{(k + n)!^2}{(2 k + n + 1)! n!}
      69             :  * \f}
      70             :  */
      71           1 : const Matrix& projection_matrix_child_to_parent(
      72             :     const Mesh<1>& child_mesh, const Mesh<1>& parent_mesh, SegmentSize size,
      73             :     bool operand_is_massive = false);
      74             : 
      75             : /// The projection matrix from a child mesh to its parent, in `Dim` dimensions.
      76             : template <size_t Dim>
      77             : std::array<std::reference_wrapper<const Matrix>, Dim>
      78           1 : projection_matrix_child_to_parent(
      79             :     const Mesh<Dim>& child_mesh, const Mesh<Dim>& parent_mesh,
      80             :     const std::array<SegmentSize, Dim>& child_sizes,
      81             :     bool operand_is_massive = false);
      82             : 
      83             : /// The projection matrix from a parent mesh to one of its children.
      84             : ///
      85             : /// \see projection_matrix_child_to_parent()
      86           1 : const Matrix& projection_matrix_parent_to_child(const Mesh<1>& parent_mesh,
      87             :                                                 const Mesh<1>& child_mesh,
      88             :                                                 SegmentSize size);
      89             : 
      90             : /// The projection matrix from a parent mesh to one of its children, in `Dim`
      91             : /// dimensions
      92             : template <size_t Dim>
      93             : std::array<std::reference_wrapper<const Matrix>, Dim>
      94           1 : projection_matrix_parent_to_child(
      95             :     const Mesh<Dim>& parent_mesh, const Mesh<Dim>& child_mesh,
      96             :     const std::array<SegmentSize, Dim>& child_sizes);
      97             : 
      98             : /// The projection matrices from a source mesh to a target mesh
      99             : /// covering given portions of an element
     100             : template <size_t Dim>
     101           1 : std::array<std::reference_wrapper<const Matrix>, Dim> projection_matrices(
     102             :     const Mesh<Dim>& source_mesh, const Mesh<Dim>& target_mesh,
     103             :     const std::array<SegmentSize, Dim>& source_sizes,
     104             :     const std::array<SegmentSize, Dim>& target_sizes);
     105             : 
     106             : /// The projection matrices from a source mesh to a target mesh where the
     107             : /// meshes cover the same physical volume
     108             : template <size_t Dim>
     109           1 : std::array<std::reference_wrapper<const Matrix>, Dim> p_projection_matrices(
     110             :     const Mesh<Dim>& source_mesh, const Mesh<Dim>& target_mesh);
     111             : 
     112             : /// @{
     113             : /// \brief Performs a perfect hash of the mortars into $2^{d-1}$ slots on the
     114             : /// range $[0, 2^{d-1})$.
     115             : ///
     116             : /// This is particularly useful when hashing into statically-sized maps based
     117             : /// on the number of dimensions.
     118             : template <size_t DimMinusOne>
     119           1 : size_t hash(const std::array<Spectral::SegmentSize, DimMinusOne>& mortar_size);
     120             : 
     121             : template <size_t Dim>
     122           0 : struct MortarSizeHash {
     123             :   template <size_t MaxSize>
     124           0 :   static constexpr bool is_perfect = MaxSize == two_to_the(Dim);
     125             : 
     126           0 :   size_t operator()(
     127             :       const std::array<Spectral::SegmentSize, Dim - 1>& mortar_size);
     128             : };
     129             : /// @}
     130             : }  // namespace Spectral

Generated by: LCOV version 1.14