• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

sxs-collaboration / spectre / 4257217601

pending completion
4257217601

Pull #4769

github

GitHub
Merge b2daae033 into ea8e72f24
Pull Request #4769: Allow the control system to use NS centers of mass as measurements

27 of 27 new or added lines in 4 files covered. (100.0%)

63958 of 66672 relevant lines covered (95.93%)

424069.18 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

86.75
/src/NumericalAlgorithms/Spectral/SwshTransform.cpp
1
// Distributed under the MIT License.
2
// See LICENSE.txt for details.
3

4
#include "NumericalAlgorithms/Spectral/SwshTransform.hpp"
5

6
#include <cmath>
7

8
#include "DataStructures/ComplexDataVector.hpp"
9
#include "DataStructures/ComplexModalVector.hpp"
10
#include "DataStructures/SpinWeighted.hpp"  // IWYU pragma: keep
11
#include "Utilities/GenerateInstantiations.hpp"
12

13
// IWYU pragma: no_forward_declare SpinWeighted
14

15
namespace Spectral::Swsh {
16

17
namespace detail {
18
template <ComplexRepresentation Representation>
19
void append_libsharp_collocation_pointers(
22,746✔
20
    const gsl::not_null<std::vector<double*>*> collocation_data,
21
    const gsl::not_null<std::vector<ComplexDataView<Representation>>*>
22
        collocation_views,
23
    const gsl::not_null<ComplexDataVector*> vector, const size_t l_max,
24
    const bool positive_spin) {
25
  const size_t number_of_angular_points =
26
      Spectral::Swsh::number_of_swsh_collocation_points(l_max);
22,746✔
27
  const size_t number_of_radial_points =
22,746✔
28
      vector->size() / number_of_angular_points;
22,746✔
29

30
  for (size_t i = 0; i < number_of_radial_points; ++i) {
46,403✔
31
    collocation_views->push_back(detail::ComplexDataView<Representation>{
23,657✔
32
        vector, number_of_angular_points, i * number_of_angular_points});
33
    collocation_data->push_back(collocation_views->back().real_data());
23,657✔
34
    // alteration needed because libsharp doesn't support negative spins
35
    if (not positive_spin) {
23,657✔
36
      collocation_views->back().conjugate();
501✔
37
    }
38
    collocation_data->push_back(collocation_views->back().imag_data());
23,657✔
39
  }
40
}
22,746✔
41

42
void append_libsharp_coefficient_pointers(
22,746✔
43
    const gsl::not_null<std::vector<std::complex<double>*>*> coefficient_data,
44
    const gsl::not_null<ComplexModalVector*> vector, const size_t l_max) {
45
  const size_t number_of_coefficients =
46
      Spectral::Swsh::size_of_libsharp_coefficient_vector(l_max);
22,746✔
47
  const size_t number_of_radial_points =
48
      vector->size() / number_of_coefficients;
22,746✔
49

50
  for (size_t i = 0; i < number_of_radial_points; ++i) {
46,403✔
51
    // coefficients associated with the real part
52
    coefficient_data->push_back(vector->data() + i * number_of_coefficients);
23,657✔
53
    // coefficients associated with the imaginary part
54
    coefficient_data->push_back(vector->data() +
47,314✔
55
                                (2 * i + 1) * (number_of_coefficients / 2));
23,657✔
56
  }
57
}
22,746✔
58

59
template <ComplexRepresentation Representation>
60
void execute_libsharp_transform_set(
20,821✔
61
    const sharp_jobtype& jobtype, const int spin,
62
    const gsl::not_null<std::vector<std::complex<double>*>*> coefficient_data,
63
    const gsl::not_null<std::vector<double*>*> collocation_data,
64
    const gsl::not_null<const CollocationMetadata<Representation>*>
65
        collocation_metadata,
66
    const sharp_alm_info* alm_info, const size_t num_transforms) {
67
  // libsharp considers two arrays per transform when spin is not zero.
68
  const size_t number_of_arrays_per_transform = (spin == 0 ? 1 : 2);
20,821✔
69
  // libsharp has an internal flag for the maximum number of transforms, so if
70
  // we have more than max_libsharp_transforms, we have to do them in chunks
71
  // of max_libsharp_transforms.
72
  for (size_t transform_block = 0;
41,642✔
73
       transform_block <
41,642✔
74
       (num_transforms + max_libsharp_transforms - 1) / max_libsharp_transforms;
41,642✔
75
       ++transform_block) {
76
    if (transform_block < (num_transforms / max_libsharp_transforms)) {
20,821✔
77
      // clang-tidy cppcoreguidelines-pro-bounds-pointer-arithmetic
78
      sharp_execute(jobtype, abs(spin),
×
79
                    coefficient_data->data() +  // NOLINT
×
80
                        number_of_arrays_per_transform *
81
                            max_libsharp_transforms * transform_block,
×
82
                    collocation_data->data() +  // NOLINT
×
83
                        number_of_arrays_per_transform *
84
                            max_libsharp_transforms * transform_block,
×
85
                    collocation_metadata->get_sharp_geom_info(), alm_info,
86
                    max_libsharp_transforms, SHARP_DP, nullptr, nullptr);
87
    } else {
88
      // clang-tidy cppcoreguidelines-pro-bounds-pointer-arithmetic
89
      sharp_execute(jobtype, abs(spin),
20,821✔
90
                    coefficient_data->data() +  // NOLINT
20,821✔
91
                        number_of_arrays_per_transform *
92
                            max_libsharp_transforms * transform_block,
20,821✔
93
                    collocation_data->data() +  // NOLINT
20,821✔
94
                        number_of_arrays_per_transform *
95
                            max_libsharp_transforms * transform_block,
20,821✔
96
                    collocation_metadata->get_sharp_geom_info(), alm_info,
97
                    num_transforms % max_libsharp_transforms, SHARP_DP, nullptr,
20,821✔
98
                    nullptr);
99
    }
100
  }
101
}
20,821✔
102
}  // namespace detail
103

104
template <ComplexRepresentation Representation, int Spin>
105
SpinWeighted<ComplexModalVector, Spin> swsh_transform(
11,265✔
106
    const size_t l_max, const size_t number_of_radial_points,
107
    const SpinWeighted<ComplexDataVector, Spin>& collocation) {
108
  SpinWeighted<ComplexModalVector, Spin> result_vector{};
11,265✔
109
  swsh_transform<Representation, Spin>(l_max, number_of_radial_points,
11,265✔
110
                                       make_not_null(&result_vector),
111
                                       collocation);
112
  return result_vector;
11,265✔
113
}
114

115
template <ComplexRepresentation Representation, int Spin>
116
SpinWeighted<ComplexDataVector, Spin> inverse_swsh_transform(
64✔
117
    const size_t l_max, const size_t number_of_radial_points,
118
    const SpinWeighted<ComplexModalVector, Spin>& libsharp_coefficients) {
119
  SpinWeighted<ComplexDataVector, Spin> result_vector{};
64✔
120
  inverse_swsh_transform<Representation, Spin>(l_max, number_of_radial_points,
64✔
121
                                               make_not_null(&result_vector),
122
                                               libsharp_coefficients);
123
  return result_vector;
64✔
124
}
125

126
template <int Spin>
127
void interpolate_to_collocation(
3✔
128
    const gsl::not_null<SpinWeighted<ComplexDataVector, Spin>*> target,
129
    const SpinWeighted<ComplexDataVector, Spin>& source,
130
    const size_t target_l_max, const size_t source_l_max,
131
    const size_t number_of_radial_points) {
132
  const auto source_modes =
6✔
133
      swsh_transform(source_l_max, number_of_radial_points, source);
134
  SpinWeighted<ComplexModalVector, Spin> target_modes{
3✔
135
      size_of_libsharp_coefficient_vector(target_l_max) *
3✔
136
      number_of_radial_points};
137

138
  const auto& target_coefficient_metadata =
139
      cached_coefficients_metadata(target_l_max);
3✔
140
  for (size_t i = 0; i < number_of_radial_points; ++i) {
9✔
141
    auto source_coefficient_metadata_iterator =
142
        cached_coefficients_metadata(source_l_max).begin();
6✔
143
    for (const auto coefficient : target_coefficient_metadata) {
218✔
144
      // first, we advance `source_coefficient_metadata_iterator` to the same
145
      // mode that is represented by `coefficient`, or to the next mode
146
      // following `coefficient` that is present in the source resolution, or to
147
      // the iterator end if neither exists. Note: this assumes the libsharp
148
      // coefficient ordering for optimizations
149
      while (source_coefficient_metadata_iterator !=
530✔
150
                 cached_coefficients_metadata(source_l_max).end() and
954✔
151
             ((*source_coefficient_metadata_iterator).m < coefficient.m or
318✔
152
              ((*source_coefficient_metadata_iterator).l < coefficient.l and
180✔
153
               (*source_coefficient_metadata_iterator).m == coefficient.m))) {
392✔
154
        ++source_coefficient_metadata_iterator;
212✔
155
      }
156
      // assign the current coefficient if present in both the source and the
157
      // target
158
      if (source_coefficient_metadata_iterator !=
106✔
159
              cached_coefficients_metadata(source_l_max).end() and
106✔
160
          coefficient.l == (*source_coefficient_metadata_iterator).l and
212✔
161
          coefficient.m == (*source_coefficient_metadata_iterator).m) {
212✔
162
        target_modes
106✔
163
            .data()[i * size_of_libsharp_coefficient_vector(target_l_max) +
106✔
164
                    coefficient.transform_of_real_part_offset] =
106✔
165
            source_modes
166
                .data()[i * size_of_libsharp_coefficient_vector(source_l_max) +
212✔
167
                        (*source_coefficient_metadata_iterator)
106✔
168
                            .transform_of_real_part_offset];
106✔
169
        target_modes
106✔
170
            .data()[i * size_of_libsharp_coefficient_vector(target_l_max) +
106✔
171
                    coefficient.transform_of_imag_part_offset] =
106✔
172
            source_modes
173
                .data()[i * size_of_libsharp_coefficient_vector(source_l_max) +
212✔
174
                        (*source_coefficient_metadata_iterator)
212✔
175
                            .transform_of_imag_part_offset];
106✔
176
      } else {
177
        // assign 0.0 if the coefficient is present in the target and not in the
178
        // source representation
179
        target_modes
×
180
            .data()[i * size_of_libsharp_coefficient_vector(target_l_max) +
×
181
                    coefficient.transform_of_real_part_offset] =
×
182
            std::complex<double>(0.0, 0.0);
183
        target_modes
×
184
            .data()[i * size_of_libsharp_coefficient_vector(target_l_max) +
×
185
                    coefficient.transform_of_imag_part_offset] =
×
186
            std::complex<double>(0.0, 0.0);
187
      }
188
    }
189
  }
190
  inverse_swsh_transform(target_l_max, number_of_radial_points, target,
3✔
191
                         target_modes);
192
}
3✔
193

194
#define GET_REPRESENTATION(data) BOOST_PP_TUPLE_ELEM(0, data)
195
#define GET_SPIN(data) BOOST_PP_TUPLE_ELEM(1, data)
196

197
#define SWSH_TRANSFORM_INSTANTIATION(r, data)                              \
198
  template SpinWeighted<ComplexModalVector, GET_SPIN(data)>                \
199
  swsh_transform<GET_REPRESENTATION(data), GET_SPIN(data)>(                \
200
      const size_t l_max, const size_t number_of_radial_points,            \
201
      const SpinWeighted<ComplexDataVector, GET_SPIN(data)>& collocation); \
202
  template SpinWeighted<ComplexDataVector, GET_SPIN(data)>                 \
203
  inverse_swsh_transform<GET_REPRESENTATION(data), GET_SPIN(data)>(        \
204
      const size_t l_max, const size_t number_of_radial_points,            \
205
      const SpinWeighted<ComplexModalVector, GET_SPIN(data)>& coefficients);
206

207
#define SWSH_TRANSFORM_UTILITIES_INSTANTIATION(r, data)                   \
208
  template void append_libsharp_collocation_pointers(                     \
209
      const gsl::not_null<std::vector<double*>*> collocation_data,        \
210
      const gsl::not_null<                                                \
211
          std::vector<ComplexDataView<GET_REPRESENTATION(data)>>*>        \
212
          collocation_views,                                              \
213
      const gsl::not_null<ComplexDataVector*> vector, const size_t l_max, \
214
      const bool positive_spin);                                          \
215
  template void execute_libsharp_transform_set(                           \
216
      const sharp_jobtype& jobtype, const int spin,                       \
217
      const gsl::not_null<std::vector<std::complex<double>*>*>            \
218
          coefficient_data,                                               \
219
      const gsl::not_null<std::vector<double*>*> collocation_data,        \
220
      const gsl::not_null<                                                \
221
          const CollocationMetadata<GET_REPRESENTATION(data)>*>           \
222
          collocation_metadata,                                           \
223
      const sharp_alm_info* alm_info, const size_t num_transforms);
224

225
namespace detail {
226
GENERATE_INSTANTIATIONS(SWSH_TRANSFORM_UTILITIES_INSTANTIATION,
227
                        (ComplexRepresentation::Interleaved,
228
                         ComplexRepresentation::RealsThenImags))
229
}  // namespace detail
230

231
GENERATE_INSTANTIATIONS(SWSH_TRANSFORM_INSTANTIATION,
232
                        (ComplexRepresentation::Interleaved,
233
                         ComplexRepresentation::RealsThenImags),
234
                        (-2, -1, 0, 1, 2))
235

236
#undef GET_REPRESENTATION
237
#undef GET_SPIN
238

239
#define GET_SPIN(data) BOOST_PP_TUPLE_ELEM(0, data)
240

241
#define SWSH_INTERPOLATION_INSTANTIATION(r, data)                           \
242
  template void interpolate_to_collocation<GET_SPIN(data)>(                 \
243
      const gsl::not_null<SpinWeighted<ComplexDataVector, GET_SPIN(data)>*> \
244
          target,                                                           \
245
      const SpinWeighted<ComplexDataVector, GET_SPIN(data)>& source,        \
246
      const size_t target_l_max, const size_t source_l_max,                 \
247
      const size_t number_of_radial_points);
248

249
GENERATE_INSTANTIATIONS(SWSH_INTERPOLATION_INSTANTIATION, (-2, -1, 0, 1, 2))
250

251
#undef GET_SPIN
252
#undef SWSH_INTERPOLATION_INSTANTIATION
253
#undef SWSH_TRANSFORM_INSTANTIATION
254
#undef SWSH_TRANSFORM_UTILITIES_INSTANTIATION
255

256
}  // namespace Spectral::Swsh
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc