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

Generated by: LCOV version 1.14