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