Line data Source code
1 0 : // Distributed under the MIT License. 2 : // See LICENSE.txt for details. 3 : 4 : #pragma once 5 : 6 : #include "DataStructures/SimpleSparseMatrix.hpp" 7 : #include "DataStructures/Tensor/TypeAliases.hpp" 8 : #include "DataStructures/Variables.hpp" 9 : #include "Evolution/Systems/CurvedScalarWave/Tags.hpp" 10 : #include "NumericalAlgorithms/SphericalHarmonics/ApplyTensorYlmFilter.hpp" 11 : #include "NumericalAlgorithms/SphericalHarmonics/TensorYlm.hpp" 12 : #include "Utilities/Gsl.hpp" 13 : 14 : /// \cond 15 : class DataVector; 16 : namespace ylm { 17 : class Spherepack; 18 : } // namespace ylm 19 : /// \endcond 20 : 21 1 : namespace ylm::TensorYlm { 22 : 23 : /// Defines tags and functions used internally in filtering, but 24 : /// tested independently in the unit tests. 25 : namespace filter_detail { 26 : 27 : template <typename Frame> 28 : using sw_vars_list = 29 : tmpl::list<::CurvedScalarWave::Tags::Psi, ::CurvedScalarWave::Tags::Pi, 30 : ::CurvedScalarWave::Tags::Phi<3, Frame>>; 31 : 32 : /*! 33 : * \brief Transforms spatial tensors into a different frame, ignoring hessians. 34 : * 35 : * This is done for filtering, where having the correct (i.e. with hessians) 36 : * transformation doesn't matter; all that matters is that the tensor 37 : * indices correspond to the coordinates (or in other words, no dual frame). 38 : * 39 : * Assumes that all the variables have lower indices. 40 : * 41 : * Takes special care to re-use memory. The Variables arguments must 42 : * already be allocated to their correct sizes; no memory allocation 43 : * is done. 44 : * 45 : * \tparam SrcFrame Source frame. 46 : * \tparam DestFrame Destination frame. 47 : * \param dest A Variables for the destination spatial variables. 48 : * \param src A Variables containing the source spatial variables. 49 : * \param jac The jacobian dx^src/dx^dest 50 : */ 51 : template <typename SrcFrame, typename DestFrame> 52 : void transform_spatial_tensors_to_different_frame_without_hessians( 53 : gsl::not_null<Variables<sw_vars_list<DestFrame>>*> dest, 54 : const Variables<sw_vars_list<SrcFrame>>& src, 55 : const InverseJacobian<DataVector, 3, SrcFrame, DestFrame>& jac); 56 : 57 : } // namespace filter_detail 58 : 59 : /*! 60 : * \brief Applies TensorYlm filter in place to Curved Scalar Wave variables. 61 : * 62 : * When radial_extents is 1, sw_vars and temp_storage are assumed to 63 : * be defined on a spherical slice, with number of grid points 64 : * corresponding to a spherical-harmonic grid of ell_max, and the 65 : * filter happens only on that slice. 66 : * 67 : * When radial_extents is > 1, sw_vars and temp_storage are assumed to 68 : * be defined on a spherical shell of topology I1 x S2. The filter 69 : * happens in the entire volume, internally iterating over each 70 : * spherical slice at a time. 71 : * 72 : * For performance reasons, apply_tensor_ylm_filter does not allocate 73 : * or deallocate memory, but it does take a temp_storage buffer. The 74 : * size of temp_storage should at least 75 : * radial_extents*spectral_size*num_components, where num_components 76 : * is the total number of independent components in the SW variable 77 : * list (i.e. 5), and spectral_size is the size of the S2 Spherepack 78 : * spectral coefficient array for ell_max, as obtained from the member 79 : * function ylm::Spherepack::spectral_size(). Note that for S2 on 80 : * Spherepack, the number of collocation points is different than the 81 : * number of spectral coefficients, and both are different than the 82 : * size of the Spherepack storage array. 83 : * 84 : * \param sw_vars Scalar wave variables at collocation points. 85 : * \param temp_storage Temporary storage for scalar wave variables, 86 : * allocated outside apply_tensor_ylm_filter. See above for size requirements. 87 : * \param jac_inertial_to_grid Jacobian taking V_x from inertial to grid. 88 : * \param jac_grid_to_inertial Jacobian taking V_x from grid to inertial. 89 : * \param filter_matrix_scalar The scalar filter matrix computed by fill_filter. 90 : * \param filter_matrix_i The Rank-1 matrix computed by fill_filter. 91 : * \param ell_max The maximum ylm ell. 92 : * \param radial_extents The number of radial grid points, can be 1 for slices. 93 : */ 94 1 : void apply_tensor_ylm_filter( 95 : gsl::not_null<Variables<filter_detail::sw_vars_list<Frame::Inertial>>*> 96 : sw_vars, 97 : gsl::not_null<Variables<filter_detail::sw_vars_list<Frame::Inertial>>*> 98 : temp_storage, 99 : const InverseJacobian<DataVector, 3, Frame::Inertial, Frame::Grid>& 100 : jac_inertial_to_grid, 101 : const InverseJacobian<DataVector, 3, Frame::Grid, Frame::Inertial>& 102 : jac_grid_to_inertial, 103 : const SimpleSparseMatrix& filter_matrix_scalar, 104 : const SimpleSparseMatrix& filter_matrix_i, size_t ell_max, 105 : size_t radial_extents); 106 : 107 : } // namespace ylm::TensorYlm