SpECTRE Documentation Coverage Report
Current view: top level - NumericalAlgorithms/SpinWeightedSphericalHarmonics - SwshTags.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 36.0 % 50 18
Test Date: 2026-10-22 17:29:42
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              : template <typename Tag, typename S>
     255              : struct has_spin : std::bool_constant<Tag::type::type::spin == S::value> {};
     256              : 
     257              : template <typename TagList>
     258              : struct spins_in_tag_list;
     259              : 
     260              : template <typename... Tags>
     261              : struct spins_in_tag_list<tmpl::list<Tags...>> {
     262              :   using type = tmpl::sort<tmpl::remove_duplicates<
     263              :       tmpl::list<std::integral_constant<int, Tags::type::type::spin>...>>>;
     264              : };
     265              : }  // namespace detail
     266              : 
     267              : /// \ingroup SwshGroup
     268              : /// \brief A metafunction for determining the coefficient buffers needed by
     269              : /// `angular_derivatives()` to avoid repeatedly allocating space for modal
     270              : /// data each time a derivative is taken.
     271              : /// \note Using these buffers is required to use the batch
     272              : /// `angular_derivatives()` rather than the individual `angular_derivative()`.
     273              : template <typename DerivativeTag>
     274            1 : using coefficient_buffer_tags_for_derivative_tag = tmpl::list<
     275              :     Spectral::Swsh::Tags::SwshTransform<typename DerivativeTag::derivative_of>,
     276              :     Spectral::Swsh::Tags::SwshTransform<DerivativeTag>>;
     277              : 
     278              : /// \ingroup SwshGroup
     279              : /// \brief Get a list of distinct spins appearing in `TagList`.
     280              : ///
     281              : /// \snippet Test_SwshTags.cpp spins_in_tag_list
     282              : template <typename TagList>
     283            1 : using spins_in_tag_list = typename detail::spins_in_tag_list<TagList>::type;
     284              : 
     285              : /// \ingroup SwshGroup
     286              : /// \brief Partition `TagList` into lists with the same spin.
     287              : ///
     288              : /// \snippet Test_SwshTags.cpp partition_tags_by_spin
     289              : template <typename TagList>
     290            1 : using partition_tags_by_spin = tmpl::transform<
     291              :     spins_in_tag_list<TagList>,
     292              :     tmpl::lazy::filter<
     293              :         tmpl::pin<TagList>,
     294              :         tmpl::defer<detail::has_spin<tmpl::_1, tmpl::parent<tmpl::_1>>>>>;
     295              : }  // namespace Swsh
     296              : }  // namespace Spectral
        

Generated by: LCOV version 2.0-1