SpECTRE Documentation Coverage Report
Current view: top level - Evolution/Systems/Cce - PrecomputeCceDependencies.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 17.3 % 52 9
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 <cstddef>
       7              : 
       8              : #include "DataStructures/ComplexDataVector.hpp"
       9              : #include "DataStructures/DataBox/DataBox.hpp"
      10              : #include "DataStructures/SpinWeighted.hpp"
      11              : #include "Evolution/Systems/Cce/IntegrandInputSteps.hpp"
      12              : #include "Evolution/Systems/Cce/OptionTags.hpp"
      13              : #include "Evolution/Systems/Cce/Tags.hpp"
      14              : #include "NumericalAlgorithms/Spectral/Basis.hpp"
      15              : #include "NumericalAlgorithms/Spectral/CollocationPoints.hpp"
      16              : #include "NumericalAlgorithms/Spectral/Quadrature.hpp"
      17              : #include "NumericalAlgorithms/SpinWeightedSphericalHarmonics/SwshCollocation.hpp"
      18              : #include "NumericalAlgorithms/SpinWeightedSphericalHarmonics/SwshTags.hpp"
      19              : #include "Utilities/Gsl.hpp"
      20              : #include "Utilities/TMPL.hpp"
      21              : #include "Utilities/VectorAlgebra.hpp"
      22              : 
      23              : namespace Cce {
      24              : 
      25              : namespace detail {
      26              : // A convenience function for computing the spin-weighted derivatives of \f$R\f$
      27              : // divided by \f$R\f$, which appears often in Jacobians to transform between
      28              : // Bondi coordinates and the numerical coordinates used in CCE.
      29              : template <typename DerivKind>
      30              : void angular_derivative_of_r_divided_by_r_impl(
      31              :     gsl::not_null<
      32              :         SpinWeighted<ComplexDataVector,
      33              :                      Spectral::Swsh::Tags::derivative_spin_weight<DerivKind>>*>
      34              :         d_r_divided_by_r,
      35              :     const SpinWeighted<ComplexDataVector, 0>& boundary_r, size_t l_max,
      36              :     size_t number_of_radial_points);
      37              : 
      38              : }  // namespace detail
      39              : 
      40              : /*!
      41              :  * \brief A set of procedures for computing the set of inputs to the CCE
      42              :  * integrand computations that can be computed before any of the intermediate
      43              :  * integrands are evaluated.
      44              :  *
      45              :  * \details The template specializations of this template are
      46              :  * compatible with acting as a the mutator in a \ref DataBoxGroup
      47              :  * `db::mutate_apply` operation. For flexibility in defining the \ref
      48              :  * DataBoxGroup structure, the tags for `Tensor`s used in these functions are
      49              :  * also organized into type lists:
      50              :  * -  type alias `integration_independent_tags`: with a subset of
      51              :  * `Cce::pre_computation_tags`, used for both input and output.
      52              :  * -  type alias `boundary_values`: with a subset of
      53              :  *   `Cce::pre_computation_boundary_tags`, used only for input.
      54              :  * - type alias `pre_swsh_derivatives` containing hypersurface quantities. For
      55              :  * this struct, it will only ever contain `Cce::Tags::BondiJ`, and is used as
      56              :  * input.
      57              :  *
      58              :  * The `BoundaryPrefix` tag allows easy switching between the
      59              :  * regularity-preserving version and standard CCE
      60              :  *
      61              :  */
      62              : template <template <typename> class BoundaryPrefix, typename Tag>
      63            1 : struct PrecomputeCceDependencies;
      64              : 
      65              : /// Computes \f$1 - y\f$ for the CCE system.
      66              : template <template <typename> class BoundaryPrefix>
      67            1 : struct PrecomputeCceDependencies<BoundaryPrefix, Tags::OneMinusY> {
      68            0 :   using boundary_tags = tmpl::list<>;
      69            0 :   using pre_swsh_derivative_tags = tmpl::list<>;
      70            0 :   using integration_independent_tags = tmpl::list<>;
      71              : 
      72            0 :   using return_tags = tmpl::list<Tags::OneMinusY>;
      73            0 :   using argument_tags = tmpl::list<Tags::LMax, Tags::NumberOfRadialPoints>;
      74              : 
      75            0 :   static void apply(
      76              :       const gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 0>>*>
      77              :           one_minus_y,
      78              :       const size_t l_max, const size_t number_of_radial_points) {
      79              :     const size_t number_of_angular_points =
      80              :         Spectral::Swsh::number_of_swsh_collocation_points(l_max);
      81              :     const DataVector one_minus_y_collocation =
      82              :         1.0 - Spectral::collocation_points<Spectral::Basis::Legendre,
      83              :                                            Spectral::Quadrature::GaussLobatto>(
      84              :                   number_of_radial_points);
      85              :     // iterate through the angular 'chunks' and set them to their 1-y value
      86              :     for (size_t i = 0; i < number_of_radial_points; ++i) {
      87              :       ComplexDataVector angular_view{
      88              :           get(*one_minus_y).data().data() + number_of_angular_points * i,
      89              :           number_of_angular_points};
      90              :       angular_view = one_minus_y_collocation[i];
      91              :     }
      92              :   }
      93              : };
      94              : 
      95              : /// Computes a volume version of Bondi radius of the worldtube \f$R\f$ from its
      96              : /// boundary value (by repeating it over the radial dimension)
      97              : template <template <typename> class BoundaryPrefix>
      98            1 : struct PrecomputeCceDependencies<BoundaryPrefix, Tags::BondiR> {
      99            0 :   using boundary_tags = tmpl::list<BoundaryPrefix<Tags::BondiR>>;
     100            0 :   using pre_swsh_derivative_tags = tmpl::list<>;
     101            0 :   using integration_independent_tags = tmpl::list<>;
     102              : 
     103            0 :   using return_tags = tmpl::list<Tags::BondiR>;
     104            0 :   using argument_tags =
     105              :       tmpl::append<boundary_tags, tmpl::list<Tags::NumberOfRadialPoints>>;
     106              : 
     107            0 :   static void apply(
     108              :       const gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 0>>*> r,
     109              :       const Scalar<SpinWeighted<ComplexDataVector, 0>>& boundary_r,
     110              :       const size_t number_of_radial_points) {
     111              :     fill_with_n_copies(make_not_null(&get(*r).data()), get(boundary_r).data(),
     112              :                        number_of_radial_points);
     113              :   }
     114              : };
     115              : 
     116              : /// Computes \f$\partial_u R / R\f$ from its boundary value (by repeating it
     117              : /// over the radial dimension).
     118              : template <template <typename> class BoundaryPrefix>
     119            1 : struct PrecomputeCceDependencies<BoundaryPrefix, Tags::DuRDividedByR> {
     120            0 :   using boundary_tags = tmpl::list<BoundaryPrefix<Tags::DuRDividedByR>>;
     121            0 :   using pre_swsh_derivative_tags = tmpl::list<>;
     122            0 :   using integration_independent_tags = tmpl::list<>;
     123              : 
     124            0 :   using return_tags = tmpl::list<Tags::DuRDividedByR>;
     125            0 :   using argument_tags =
     126              :       tmpl::append<boundary_tags, tmpl::list<Tags::NumberOfRadialPoints>>;
     127              : 
     128            0 :   static void apply(
     129              :       const gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 0>>*>
     130              :           du_r_divided_by_r,
     131              :       const Scalar<SpinWeighted<ComplexDataVector, 0>>&
     132              :           boundary_du_r_divided_by_r,
     133              :       const size_t number_of_radial_points) {
     134              :     fill_with_n_copies(make_not_null(&get(*du_r_divided_by_r).data()),
     135              :                        get(boundary_du_r_divided_by_r).data(),
     136              :                        number_of_radial_points);
     137              :   }
     138              : };
     139              : 
     140              : /// Computes \f$\eth R / R\f$ by differentiating and repeating the boundary
     141              : /// value of \f$R\f$.
     142              : template <template <typename> class BoundaryPrefix>
     143            1 : struct PrecomputeCceDependencies<BoundaryPrefix, Tags::EthRDividedByR> {
     144            0 :   using boundary_tags = tmpl::list<BoundaryPrefix<Tags::BondiR>>;
     145            0 :   using pre_swsh_derivative_tags = tmpl::list<>;
     146            0 :   using integration_independent_tags = tmpl::list<>;
     147              : 
     148            0 :   using return_tags = tmpl::list<Tags::EthRDividedByR>;
     149            0 :   using argument_tags =
     150              :       tmpl::append<boundary_tags,
     151              :                    tmpl::list<Tags::LMax, Tags::NumberOfRadialPoints>>;
     152              : 
     153            0 :   static void apply(
     154              :       const gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 1>>*>
     155              :           eth_r_divided_by_r,
     156              :       const Scalar<SpinWeighted<ComplexDataVector, 0>>& boundary_r,
     157              :       const size_t l_max, const size_t number_of_radial_points) {
     158              :     detail::angular_derivative_of_r_divided_by_r_impl<
     159              :         Spectral::Swsh::Tags::Eth>(make_not_null(&get(*eth_r_divided_by_r)),
     160              :                                    get(boundary_r), l_max,
     161              :                                    number_of_radial_points);
     162              :   }
     163              : };
     164              : 
     165              : /// Computes \f$\eth \eth R / R\f$ by differentiating and repeating the boundary
     166              : /// value of \f$R\f$.
     167              : template <template <typename> class BoundaryPrefix>
     168            1 : struct PrecomputeCceDependencies<BoundaryPrefix, Tags::EthEthRDividedByR> {
     169            0 :   using boundary_tags = tmpl::list<BoundaryPrefix<Tags::BondiR>>;
     170            0 :   using pre_swsh_derivative_tags = tmpl::list<>;
     171            0 :   using integration_independent_tags = tmpl::list<>;
     172              : 
     173            0 :   using return_tags = tmpl::list<Tags::EthEthRDividedByR>;
     174            0 :   using argument_tags =
     175              :       tmpl::append<boundary_tags,
     176              :                    tmpl::list<Tags::LMax, Tags::NumberOfRadialPoints>>;
     177              : 
     178            0 :   static void apply(
     179              :       const gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 2>>*>
     180              :           eth_eth_r_divided_by_r,
     181              :       const Scalar<SpinWeighted<ComplexDataVector, 0>>& boundary_r,
     182              :       const size_t l_max, const size_t number_of_radial_points) {
     183              :     detail::angular_derivative_of_r_divided_by_r_impl<
     184              :         Spectral::Swsh::Tags::EthEth>(
     185              :         make_not_null(&get(*eth_eth_r_divided_by_r)), get(boundary_r), l_max,
     186              :         number_of_radial_points);
     187              :   }
     188              : };
     189              : 
     190              : /// Computes \f$\eth \bar{\eth} R / R\f$ by differentiating and repeating the
     191              : /// boundary value of \f$R\f$.
     192              : template <template <typename> class BoundaryPrefix>
     193            1 : struct PrecomputeCceDependencies<BoundaryPrefix, Tags::EthEthbarRDividedByR> {
     194            0 :   using boundary_tags = tmpl::list<BoundaryPrefix<Tags::BondiR>>;
     195            0 :   using pre_swsh_derivative_tags = tmpl::list<>;
     196            0 :   using integration_independent_tags = tmpl::list<>;
     197              : 
     198            0 :   using return_tags = tmpl::list<Tags::EthEthbarRDividedByR>;
     199            0 :   using argument_tags =
     200              :       tmpl::append<boundary_tags,
     201              :                    tmpl::list<Tags::LMax, Tags::NumberOfRadialPoints>>;
     202              : 
     203            0 :   static void apply(
     204              :       const gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 0>>*>
     205              :           eth_ethbar_r_divided_by_r,
     206              :       const Scalar<SpinWeighted<ComplexDataVector, 0>>& boundary_r,
     207              :       const size_t l_max, const size_t number_of_radial_points) {
     208              :     detail::angular_derivative_of_r_divided_by_r_impl<
     209              :         Spectral::Swsh::Tags::EthEthbar>(
     210              :         make_not_null(&get(*eth_ethbar_r_divided_by_r)), get(boundary_r), l_max,
     211              :         number_of_radial_points);
     212              :   }
     213              : };
     214              : 
     215              : /// Computes \f$K = \sqrt{1 + J \bar{J}}\f$.
     216              : template <template <typename> class BoundaryPrefix>
     217            1 : struct PrecomputeCceDependencies<BoundaryPrefix, Tags::BondiK> {
     218            0 :   using boundary_tags = tmpl::list<>;
     219            0 :   using pre_swsh_derivative_tags = tmpl::list<Tags::BondiJ>;
     220            0 :   using integration_independent_tags = tmpl::list<>;
     221              : 
     222            0 :   using return_tags = tmpl::list<Tags::BondiK>;
     223            0 :   using argument_tags = tmpl::push_front<pre_swsh_derivative_tags, Tags::LMax>;
     224              : 
     225            0 :   static void apply(
     226              :       const gsl::not_null<Scalar<SpinWeighted<ComplexDataVector, 0>>*> k,
     227              :       const size_t /*l_max*/,
     228              :       const Scalar<SpinWeighted<ComplexDataVector, 2>>& j) {
     229              :     get(*k).data() = sqrt(1.0 + get(j).data() * conj(get(j)).data());
     230              :   }
     231              : };
     232              : 
     233              : /*!
     234              :  * \brief Convenience routine for computing all of the CCE inputs to integrand
     235              :  * computation that do not depend on intermediate integrand results. It should
     236              :  * be executed before moving through the hierarchy of integrands.
     237              :  *
     238              :  * \details Provided a \ref DataBoxGroup with the appropriate tags (including
     239              :  * `Cce::pre_computation_boundary_tags`, `Cce::pre_computation_tags`,
     240              :  * `Cce::Tags::BondiJ` and `Tags::LMax`), this function will
     241              :  * apply all of the necessary mutations to update the
     242              :  * `Cce::pre_computation_tags` to their correct values for the current values
     243              :  * for the remaining (input) tags.
     244              :  *
     245              :  * The `BoundaryPrefix` template template parameter is to be passed a prefix
     246              :  * tag associated with the boundary value prefix used in the computation (e.g.
     247              :  * `Cce::Tags::BoundaryValue`), and allows easy switching between the
     248              :  * regularity-preserving version and standard CCE.
     249              :  */
     250              : template <template <typename> class BoundaryPrefix, typename DataBoxType>
     251            1 : void mutate_all_precompute_cce_dependencies(
     252              :     const gsl::not_null<DataBoxType*> box) {
     253              :   tmpl::for_each<pre_computation_tags>([&box](auto x) {
     254              :     using integration_independent_tag = typename decltype(x)::type;
     255              :     using mutation =
     256              :         PrecomputeCceDependencies<BoundaryPrefix, integration_independent_tag>;
     257              :     db::mutate_apply<mutation>(box);
     258              :   });
     259              : }
     260              : }  // namespace Cce
        

Generated by: LCOV version 2.0-1