SpECTRE Documentation Coverage Report
Current view: top level - NumericalAlgorithms/SpinWeightedSphericalHarmonics - SwshTags.hpp Hit Total Coverage
Commit: bcc6763cee2b3f1593fb35e61fb83412a3313e95 Lines: 20 37 54.1 %
Date: 2024-09-16 17:23:19
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 <string>
       7             : 
       8             : #include "DataStructures/ComplexDataVector.hpp"
       9             : #include "DataStructures/ComplexModalVector.hpp"
      10             : #include "DataStructures/DataBox/Tag.hpp"
      11             : #include "DataStructures/DataBox/TagName.hpp"
      12             : #include "DataStructures/SpinWeighted.hpp"
      13             : #include "DataStructures/Tensor/Tensor.hpp"
      14             : #include "DataStructures/Tensor/TypeAliases.hpp"
      15             : #include "Utilities/TMPL.hpp"
      16             : #include "Utilities/TypeTraits.hpp"
      17             : 
      18             : namespace Spectral {
      19             : namespace Swsh {
      20             : /// \cond
      21             : class SwshInterpolator;
      22             : /// \endcond
      23             : 
      24           0 : namespace Tags {
      25             : 
      26             : /// \ingroup SwshGroup
      27             : /// \brief Struct for labeling the \f$\eth\f$ spin-weighted derivative in tags
      28           1 : struct Eth {};
      29             : /// \ingroup SwshGroup
      30             : /// \brief Struct for labeling the \f$\bar{\eth}\f$ spin-weighted derivative in
      31             : /// tags
      32           1 : struct Ethbar {};
      33             : /// \ingroup SwshGroup
      34             : /// \brief Struct for labeling the \f$\eth^2\f$ spin-weighted derivative in tags
      35           1 : struct EthEth {};
      36             : /// \ingroup SwshGroup
      37             : /// \brief Struct for labeling the \f$\bar{\eth} \eth\f$ spin-weighted
      38             : /// derivative in tags
      39           1 : struct EthbarEth {};
      40             : /// \ingroup SwshGroup
      41             : /// \brief Struct for labeling the \f$\eth \bar{\eth}\f$ spin-weighted
      42             : /// derivative in tags
      43           1 : struct EthEthbar {};
      44             : /// \ingroup SwshGroup
      45             : /// \brief Struct for labeling the \f$\bar{\eth}^2\f$ spin-weighted derivative
      46             : /// in tags
      47           1 : struct EthbarEthbar {};
      48             : 
      49             : /// \ingroup SwshGroup
      50             : /// \brief Struct for labeling the inverse \f$\eth^{-1}\f$ spin-weighted
      51             : /// derivative in tags
      52           1 : struct InverseEth {};
      53             : /// \ingroup SwshGroup
      54             : /// \brief Struct for labeling the inverse\f$\bar{\eth}^{-1}\f$ spin-weighted
      55             : /// derivative in tags
      56           1 : struct InverseEthbar {};
      57             : 
      58             : /// \brief Struct which acts as a placeholder for a spin-weighted derivative
      59             : /// label in the spin-weighted derivative utilities, but represents a 'no-op':
      60             : /// no derivative is taken.
      61           1 : struct NoDerivative {};
      62             : 
      63             : namespace detail {
      64             : template <typename DerivativeKind>
      65             : inline constexpr int derivative_spin_weight_impl() {
      66             :   if (std::is_same_v<DerivativeKind, Eth> or
      67             :       std::is_same_v<DerivativeKind, InverseEthbar>) {
      68             :     return 1;
      69             :   } else if (std::is_same_v<DerivativeKind, Ethbar> or
      70             :              std::is_same_v<DerivativeKind, InverseEth>) {
      71             :     return -1;
      72             :   } else if (std::is_same_v<DerivativeKind, EthEth>) {
      73             :     return 2;
      74             :   } else if (std::is_same_v<DerivativeKind, EthbarEthbar>) {
      75             :     return -2;
      76             :   }
      77             :   return 0;
      78             : }
      79             : }  // namespace detail
      80             : 
      81             : // utility function for determining the change of spin after a spin-weighted
      82             : // derivative has been applied.
      83             : template <typename DerivativeKind>
      84           0 : constexpr int derivative_spin_weight =
      85             :     detail::derivative_spin_weight_impl<DerivativeKind>();
      86             : 
      87             : namespace detail {
      88             : // The below tags are used to find the new type represented by the spin-weighted
      89             : // derivative of a spin-weighted quantity. The derivatives alter the spin
      90             : // weights, and so the utility `adjust_spin_weight_t<Tag, DerivativeKind>` is a
      91             : // metafunction that determines the correct spin-weighted type for the
      92             : // spin-weighted derivative `DerivativeKind` of `Tag`.
      93             : //
      94             : // if there is no `Tag::type::spin`, but the internal type is a compatible
      95             : // complex vector type, the spin associated with `Tag` is assumed to be 0.
      96             : template <typename DataType, typename DerivativeKind>
      97             : struct adjust_spin_weight {
      98             :   using type =
      99             :       Scalar<SpinWeighted<DataType, derivative_spin_weight<DerivativeKind>>>;
     100             : };
     101             : 
     102             : // case for if there is a `Tag::type::spin`
     103             : template <typename DataType, int Spin, typename DerivativeKind>
     104             : struct adjust_spin_weight<SpinWeighted<DataType, Spin>, DerivativeKind> {
     105             :   using type = Scalar<
     106             :       SpinWeighted<DataType, Spin + derivative_spin_weight<DerivativeKind>>>;
     107             : };
     108             : 
     109             : template <typename Tag, typename DerivativeKind>
     110             : using adjust_spin_weight_t =
     111             :     typename adjust_spin_weight<typename Tag::type::type, DerivativeKind>::type;
     112             : 
     113             : // Helper function for creating an appropriate prefix tag name from one of the
     114             : // spin-weighted derivative types and an existing tag name
     115             : template <typename DerivativeKind>
     116             : std::string compose_spin_weighted_derivative_name(const std::string& suffix);
     117             : 
     118             : }  // namespace detail
     119             : 
     120             : /// Convenience metafunction for accessing the tag from which a `Derivative` was
     121             : /// derived.
     122             : template <typename Tag>
     123           1 : using derived_from = typename Tag::derived_from;
     124             : 
     125             : /// \ingroup SwshGroup
     126             : /// \brief Prefix tag representing the spin-weighted derivative of a
     127             : /// spin-weighted scalar.
     128             : ///
     129             : /// Template Parameters:
     130             : /// - `Tag`: The tag to prefix
     131             : /// - `DerivativeKind`: The type of spin-weighted derivative. This may be any of
     132             : ///   the labeling structs: `Eth`, `Ethbar`, `EthEth`, `EthbarEth`, `EthEthbar`,
     133             : ///   `EthbarEthbar`, or `NoDerivative`.
     134             : ///
     135             : /// Type Aliases and static values:
     136             : /// - `type`: Always a `SpinWeighted<Scalar<ComplexDataVector>, Spin>`, where
     137             : ///   `Spin` is the spin weight after the derivative `DerivativeKind` has been
     138             : ///   applied.
     139             : /// - `tag`: An alias to the wrapped tag `Tag`. Provided for applicability to
     140             : ///   general `db::PrefixTag` functionality.
     141             : /// - `derivative_of`: Another alias to the wrapped tag `Tag`. Provided so that
     142             : ///   utilities that use this prefix for taking derivatives can have a more
     143             : ///   expressive code style.
     144             : /// - `derivative_kind`: Type alias to `DerivativeKind`, represents the kind of
     145             : ///   spin-weighted derivative applied to `Tag`
     146             : /// - `spin`: The spin weight of the scalar after the derivative has been
     147             : ///   applied.
     148             : template <typename Tag, typename DerivativeKind>
     149           1 : struct Derivative : db::PrefixTag, db::SimpleTag {
     150           0 :   using type = detail::adjust_spin_weight_t<Tag, DerivativeKind>;
     151           0 :   using tag = Tag;
     152             :   // derivative_of is provided as a second alias so that utilities that assume a
     153             :   // derivative prefix tag fail earlier during compilation
     154           0 :   using derivative_of = Tag;
     155           0 :   using derivative_kind = DerivativeKind;
     156           0 :   const static int spin = type::type::spin;
     157           0 :   static std::string name() {
     158             :     return detail::compose_spin_weighted_derivative_name<DerivativeKind>(
     159             :         db::tag_name<Tag>());
     160             :   }
     161             : };
     162             : 
     163             : /// \ingroup SwshGroup
     164             : /// \brief Prefix tag representing the spin-weighted spherical harmonic
     165             : /// transform of a spin-weighted scalar.
     166             : ///
     167             : /// Template Parameters:
     168             : /// - `Tag`: The tag to prefix.
     169             : ///
     170             : /// Type aliases and static values:
     171             : /// - `type`: Always a `SpinWeighted<Scalar<ComplexModalVector>, Spin>`, where
     172             : ///   `Spin` is the same spin weight of the pre-transformed `Tag`, and 0 if
     173             : ///   provided a `Tag` with a `Type` that is not `SpinWeighted`
     174             : /// - `tag`: An alias to the wrapped tag `Tag`. Provided for applicability to
     175             : ///   general `db::PrefixTag` functionality
     176             : /// - `transform_of`: Another alias to the wrapped tag `Tag`. Provided so that
     177             : ///   utilities that use this prefix for taking transforms can have a more
     178             : ///   expressive code style.
     179             : template <typename Tag>
     180           1 : struct SwshTransform : db::PrefixTag, db::SimpleTag {
     181           0 :   using type = Scalar<SpinWeighted<
     182             :       ComplexModalVector,
     183             :       detail::adjust_spin_weight_t<Tag, NoDerivative>::type::spin>>;
     184           0 :   using tag = Tag;
     185             :   // transform_of is provided as a second alias so that utilities that assume a
     186             :   // derivative prefix tag fail earlier during compilation
     187           0 :   using transform_of = Tag;
     188           0 :   const static int spin = type::type::spin;
     189             : };
     190             : 
     191             : /// \ingroup SwshGroup
     192             : /// \brief Base Tag for the maximum spin-weighted spherical harmonic l; sets
     193             : /// angular resolution.
     194           1 : struct LMaxBase : db::BaseTag {};
     195             : 
     196             : /// \ingroup SwshGroup
     197             : /// \brief Tag for the maximum spin-weighted spherical harmonic l; sets angular
     198             : /// resolution.
     199           1 : struct LMax : db::SimpleTag, LMaxBase {
     200           0 :   using type = size_t;
     201             : };
     202             : 
     203             : /// \ingroup SwshGroup
     204             : /// \brief Base Tag for the number of radial grid points in the
     205             : /// three-dimensional representation of radially concentric spherical shells.
     206           1 : struct NumberOfRadialPointsBase : db::BaseTag {};
     207             : 
     208             : /// \ingroup SwshGroup
     209             : /// \brief Tag for the number of radial grid points in the three-dimensional
     210             : /// representation of radially concentric spherical shells
     211           1 : struct NumberOfRadialPoints : db::SimpleTag, NumberOfRadialPointsBase {
     212           0 :   using type = size_t;
     213             : };
     214             : 
     215             : /// \ingroup SwshGroup
     216             : /// \brief Tag for a SwshInterpolator associated with a particular set
     217             : /// of angular coordinates.
     218             : ///
     219             : /// \details It is recommended to use this to store a `SwshInterpolator` in the
     220             : /// \ref DataBoxGroup of a parallel component, as interpolations can be
     221             : /// significantly faster if they don't have to re-construct the
     222             : /// `SwhsInterpolator` as frequently.
     223             : template <typename Tag>
     224           1 : struct SwshInterpolator : db::SimpleTag, db::PrefixTag {
     225           0 :   using tag = Tag;
     226           0 :   using type = ::Spectral::Swsh::SwshInterpolator;
     227             : };
     228             : 
     229             : }  // namespace Tags
     230             : 
     231             : namespace detail {
     232             : // implementation for get_tags_with_spin
     233             : template <typename Tag, typename S>
     234             : struct has_spin : std::bool_constant<Tag::type::type::spin == S::value> {};
     235             : 
     236             : template <typename PrefixTag, typename S>
     237             : struct wrapped_has_spin : has_spin<typename PrefixTag::tag, S> {};
     238             : 
     239             : }  // namespace detail
     240             : 
     241             : /// \ingroup SwshGroup
     242             : /// \brief A metafunction for determining the coefficient buffers needed by
     243             : /// `angular_derivatives()` to avoid repeatedly allocating space for modal
     244             : /// data each time a derivative is taken.
     245             : /// \note Using these buffers is required to use the batch
     246             : /// `angular_derivatives()` rather than the individual `angular_derivative()`.
     247             : template <typename DerivativeTag>
     248           1 : using coefficient_buffer_tags_for_derivative_tag = tmpl::list<
     249             :     Spectral::Swsh::Tags::SwshTransform<typename DerivativeTag::derivative_of>,
     250             :     Spectral::Swsh::Tags::SwshTransform<DerivativeTag>>;
     251             : 
     252             : /// \ingroup SwshGroup
     253             : /// \brief Extract from `TagList` the subset of those tags that have a static
     254             : /// int member `spin` equal to the template parameter `Spin`.
     255             : ///
     256             : /// \snippet Test_SwshTags.cpp get_tags_with_spin
     257             : template <int Spin, typename TagList>
     258           1 : using get_tags_with_spin = tmpl::remove_duplicates<tmpl::filter<
     259             :     TagList, detail::has_spin<tmpl::_1, std::integral_constant<int, Spin>>>>;
     260             : 
     261             : /// \ingroup SwshGroup
     262             : /// \brief Extract from `TagList` the subset of  those tags that wrap a tag
     263             : /// that has a static int member `spin` equal to the template parameter `Spin`.
     264             : ///
     265             : /// \snippet Test_SwshTags.cpp get_prefix_tags_that_wrap_tags_with_spin
     266             : template <int Spin, typename TagList>
     267           1 : using get_prefix_tags_that_wrap_tags_with_spin =
     268             :     tmpl::filter<TagList, tmpl::bind<detail::wrapped_has_spin, tmpl::_1,
     269             :                                      std::integral_constant<int, Spin>>>;
     270             : 
     271             : }  // namespace Swsh
     272             : }  // namespace Spectral

Generated by: LCOV version 1.14