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/GeneralizedHarmonic/Tags.hpp"
10 : #include "NumericalAlgorithms/SphericalHarmonics/ApplyTensorYlmFilter.hpp"
11 : #include "NumericalAlgorithms/SphericalHarmonics/TensorYlm.hpp"
12 : #include "PointwiseFunctions/GeneralRelativity/Tags.hpp"
13 : #include "Utilities/Gsl.hpp"
14 :
15 : /// \cond
16 : class DataVector;
17 : namespace ylm {
18 : class Spherepack;
19 : } // namespace ylm
20 : /// \endcond
21 :
22 : namespace ylm::TensorYlm {
23 :
24 : /// Defines tags and functions used internally in filtering, but
25 : /// tested independently in the unit tests.
26 : namespace filter_detail {
27 :
28 : /// Defines tags for internal use in filtering.
29 : namespace Tags {
30 :
31 : /// The time-time part of the metric.
32 : template <typename DataType>
33 : struct Metric00 : db::SimpleTag {
34 : using type = Scalar<DataType>;
35 : };
36 :
37 : /// The time-time part of the generalized harmonic variable \f$Pi\f$
38 : template <typename DataType>
39 : struct Pi00 : db::SimpleTag {
40 : using type = Scalar<DataType>;
41 : };
42 :
43 : /// The time-space part of the metric.
44 : template <typename DataType, size_t Dim, typename Frame>
45 : struct Metrick0 : db::SimpleTag {
46 : using type = tnsr::i<DataType, Dim, Frame>;
47 : };
48 :
49 : /// The time-space part of the generalized harmonic variable \f$Pi\f$
50 : template <typename DataType, size_t Dim, typename Frame>
51 : struct Pik0 : db::SimpleTag {
52 : using type = tnsr::i<DataType, Dim, Frame>;
53 : };
54 :
55 : /// The space-space part of the metric.
56 : template <typename DataType, size_t Dim, typename Frame>
57 : struct Metrickj : db::SimpleTag {
58 : using type = tnsr::ii<DataType, Dim, Frame>;
59 : };
60 :
61 : /// The space-space part of the generalized harmonic variable \f$Pi\f$
62 : template <typename DataType, size_t Dim, typename Frame>
63 : struct Pikj : db::SimpleTag {
64 : using type = tnsr::ii<DataType, Dim, Frame>;
65 : };
66 :
67 : /// \f$\Phi_{k00}, where \f$\Phi\f$ is the generalized harmonic variable.
68 : template <typename DataType, size_t Dim, typename Frame>
69 : struct Phik00 : db::SimpleTag {
70 : using type = tnsr::i<DataType, Dim, Frame>;
71 : };
72 :
73 : /// \f$\Phi_{ki0}, where \f$\Phi\f$ is the generalized harmonic variable.
74 : template <typename DataType, size_t Dim, typename Frame>
75 : struct Phiki0 : db::SimpleTag {
76 : using type = tnsr::ij<DataType, Dim, Frame>;
77 : };
78 :
79 : /// \f$\Phi_{kij}, where \f$\Phi\f$ is the generalized harmonic variable.
80 : template <typename DataType, size_t Dim, typename Frame>
81 : struct Phikij : db::SimpleTag {
82 : using type = tnsr::ijj<DataType, Dim, Frame>;
83 : };
84 :
85 : } // namespace Tags
86 :
87 : using gh_spacetime_vars_list =
88 : tmpl::list<::gr::Tags::SpacetimeMetric<DataVector, 3, Frame::Inertial>,
89 : ::gh::Tags::Pi<DataVector, 3, Frame::Inertial>,
90 : ::gh::Tags::Phi<DataVector, 3, Frame::Inertial>>;
91 :
92 : template <typename Frame>
93 : using gh_spatial_vars_list = tmpl::list<
94 : Tags::Metric00<DataVector>, Tags::Metrick0<DataVector, 3, Frame>,
95 : Tags::Metrickj<DataVector, 3, Frame>, Tags::Pi00<DataVector>,
96 : Tags::Pik0<DataVector, 3, Frame>, Tags::Pikj<DataVector, 3, Frame>,
97 : Tags::Phik00<DataVector, 3, Frame>, Tags::Phiki0<DataVector, 3, Frame>,
98 : Tags::Phikij<DataVector, 3, Frame>>;
99 :
100 : /*!
101 : * \brief Copies spacetime variables into their spatial pieces.
102 : *
103 : * For example, if one of the spacetime variables is the metric
104 : * $g_{ab}$, then the corresponding spatial variables are a spatial
105 : * scalar $g_{00}$, a spatial vector $g_{i0}$, and a spatial symmetric
106 : * 2-tensor $g_{ij}$.
107 : *
108 : * The arguments must already be allocated to their correct sizes; no
109 : * memory allocation is done.
110 : *
111 : * \param spatial_vars Points to a Variables containing spatial pieces.
112 : * \param spacetime_vars A Variables containing the spacetime variables.
113 : */
114 : void break_spacetime_vars_into_spatial_pieces(
115 : gsl::not_null<Variables<gh_spatial_vars_list<Frame::Inertial>>*>
116 : spatial_vars,
117 : const Variables<gh_spacetime_vars_list>& spacetime_vars);
118 :
119 : /*!
120 : * \brief Copies spatial pieces into the corresponding spacetime variables.
121 : *
122 : * This is the inverse of break_spacetime_vars_into_spatial_pieces.
123 : *
124 : * \param spatial_vars A Variables containing spatial pieces.
125 : * \param spacetime_vars A Variables containing the spacetime variables.
126 : */
127 : void assemble_spacetime_vars_from_spatial_pieces(
128 : gsl::not_null<Variables<gh_spacetime_vars_list>*> spacetime_vars,
129 : const Variables<gh_spatial_vars_list<Frame::Inertial>>& spatial_vars);
130 :
131 : /*!
132 : * \brief Transforms spatial tensors into a different frame, ignoring hessians.
133 : *
134 : * This is done for filtering, where having the correct (i.e. with hessians)
135 : * transformation doesn't matter; all that matters is that the tensor
136 : * indices correspond to the coordinates (or in other words, no dual frame).
137 : *
138 : * Assumes that all the variables have lower indices.
139 : *
140 : * Takes special care to re-use memory. The Variables arguments must
141 : * already be allocated to their correct sizes; no memory allocation
142 : * is done.
143 : *
144 : * \tparam SrcFrame Source frame.
145 : * \tparam DestFrame Destination frame.
146 : * \param dest A Variables for the destination spatial variables.
147 : * \param src A Variables containing the source spatial variables.
148 : * \param jac The jacobian dx^src/dx^dest
149 : */
150 : template <typename SrcFrame, typename DestFrame>
151 : void transform_spatial_tensors_to_different_frame_without_hessians(
152 : gsl::not_null<Variables<gh_spatial_vars_list<DestFrame>>*> dest,
153 : const Variables<gh_spatial_vars_list<SrcFrame>>& src,
154 : const InverseJacobian<DataVector, 3, SrcFrame, DestFrame>& jac);
155 :
156 : } // namespace filter_detail
157 :
158 : /*!
159 : * \brief Applies TensorYlm filter in place to Generalized Harmonic variables.
160 : *
161 : * When radial_extents is 1, gh_vars and temp_storage are assumed to
162 : * be defined on a spherical slice, with number of grid points
163 : * corresponding to a spherical-harmonic grid of ell_max, and the
164 : * filter happens only on that slice.
165 : *
166 : * When radial_extents is > 1, gh_vars and temp_storage are assumed to
167 : * be defined on a spherical shell of topology I1 x S2. The filter
168 : * happens in the entire volume, internally iterating over each
169 : * spherical slice at a time.
170 : *
171 : * For performance reasons, apply_tensor_ylm_filter does not allocate
172 : * or deallocate memory, but it does take a temp_storage buffer. The
173 : * size of temp_storage should at least
174 : * radial_extents*spectral_size*num_components, where num_components
175 : * is the total number of independent components in the GH variable
176 : * list (i.e. 30), and spectral_size is the size of the S2 Spherepack
177 : * spectral coefficient array for ell_max, as obtained from the member
178 : * function ylm::Spherepack::spectral_size(). Note that for S2 on
179 : * Spherepack, the number of collocation points is different than the
180 : * number of spectral coefficients, and both are different than the
181 : * size of the Spherepack storage array.
182 : *
183 : * \param gh_vars Generalized Harmonic variables at collocation points.
184 : * \param temp_storage Temporary storage for generalized harmonic variables,
185 : * allocated outside apply_tensor_ylm_filter. See above for size requirements.
186 : * \param jac_inertial_to_grid Jacobian taking V_x from inertial to grid.
187 : * \param jac_grid_to_inertial Jacobian taking V_x from grid to inertial.
188 : * \param filter_matrix_scalar The scalar filter matrix computed by fill_filter.
189 : * \param filter_matrix_i The Rank-1 matrix computed by fill_filter.
190 : * \param filter_matrix_ii The Rank-2 symmetric matrix computed by fill_filter.
191 : * \param filter_matrix_ij The Rank-2 matrix computed by fill_filter.
192 : * \param filter_matrix_kii The Rank-3 matrix computed by fill_filter.
193 : * \param ell_max The maximum ylm ell.
194 : * \param radial_extents The number of radial grid points, can be 1 for slices.
195 : */
196 1 : void apply_tensor_ylm_filter(
197 : gsl::not_null<Variables<filter_detail::gh_spacetime_vars_list>*> gh_vars,
198 : gsl::not_null<Variables<filter_detail::gh_spacetime_vars_list>*>
199 : temp_storage,
200 : const InverseJacobian<DataVector, 3, Frame::Inertial, Frame::Grid>&
201 : jac_inertial_to_grid,
202 : const InverseJacobian<DataVector, 3, Frame::Grid, Frame::Inertial>&
203 : jac_grid_to_inertial,
204 : const SimpleSparseMatrix& filter_matrix_scalar,
205 : const SimpleSparseMatrix& filter_matrix_i,
206 : const SimpleSparseMatrix& filter_matrix_ii,
207 : const SimpleSparseMatrix& filter_matrix_ij,
208 : const SimpleSparseMatrix& filter_matrix_kii, size_t ell_max,
209 : size_t radial_extents);
210 : } // namespace ylm::TensorYlm
|