Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <array>
7 : #include <cstddef>
8 : #include <vector>
9 :
10 : #include "DataStructures/DataVector.hpp"
11 : #include "Utilities/Gsl.hpp"
12 :
13 : namespace ylm::Spherepack_detail {
14 :
15 : /// Holds the various constant 'work' arrays for Spherepack.
16 : /// These are computed only once during ylm::Spherepack construction
17 : /// and are re-used over and over again.
18 : class ConstStorage {
19 : public:
20 : ConstStorage(const size_t l_max, const size_t m_max);
21 : ~ConstStorage() = default;
22 : ConstStorage(const ConstStorage& rhs);
23 : ConstStorage& operator=(const ConstStorage& rhs);
24 : ConstStorage(ConstStorage&& rhs);
25 : ConstStorage& operator=(ConstStorage&& rhs);
26 :
27 : std::vector<size_t> work_interp_index;
28 : // The following are vectors because they are returnable by
29 : // member functions.
30 : std::vector<double> quadrature_weights, theta, phi;
31 : // All other storage is allocated in a single DataVector and then
32 : // pointed to by gsl::spans.
33 : DataVector storage_;
34 : gsl::span<double> work_phys_to_spec, work_scalar_spec_to_phys;
35 : gsl::span<double> work_vector_spec_to_phys;
36 : gsl::span<double> sin_theta, cos_theta, cosec_theta, cot_theta;
37 : gsl::span<double> sin_phi, cos_phi;
38 : gsl::span<double> work_interp_alpha, work_interp_beta, work_interp_pmm;
39 :
40 : private:
41 : size_t l_max_;
42 : size_t m_max_;
43 : void point_spans_to_data_vector(const bool allocate = false);
44 : };
45 :
46 : /// This is a quick way of providing temporary space that is
47 : /// re-utilized many times without the expense of mallocs. This
48 : /// turned out to be important for optimizing SpEC (because
49 : /// ylm::Spherepack is used for the basis functions in the most
50 : /// expensive subdomains) but may or may not be important for SpECTRE.
51 : class MemoryPool {
52 : public:
53 : MemoryPool() = default;
54 : std::vector<double>& get(size_t n_pts);
55 : void free(const std::vector<double>& to_be_freed);
56 : void free(gsl::not_null<double*> to_be_freed);
57 : void clear();
58 :
59 : private:
60 : struct StorageAndAvailability {
61 : std::vector<double> storage;
62 : bool currently_in_use{false};
63 : };
64 : // It turns out that the maximum number of temporaries needed in a
65 : // single ylm::Spherepack calculation is 9.
66 : static const constexpr size_t num_temps_ = 9;
67 : std::array<StorageAndAvailability, num_temps_> memory_pool_;
68 : };
69 : } // namespace ylm::Spherepack_detail
|