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