.. _program_listing_file_src_specsyn_SpecsynLib.hpp: Program Listing for File SpecsynLib.hpp ======================================= |exhale_lsh| :ref:`Return to documentation for file ` (``src/specsyn/SpecsynLib.hpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #ifndef SPECSYNLIB_HPP #define SPECSYNLIB_HPP #include "../utils/ThreadVec.hpp" #include "Specsyn.hpp" #include "SpecsynCommons.hpp" #include #include // NOLINT(misc-include-cleaner) #include #include namespace io { class SimControls; } // namespace io namespace specsyn { template class SpecsynLib : public Specsyn { public: explicit SpecsynLib(const io::SimControls& controls) : Specsyn(controls) { } [[nodiscard]] auto spec(const StarData& props, double feh) const -> std::vector override = 0; virtual void resample(const std::vector& wlNew); [[nodiscard]] static auto resample(const std::vector& wl, const std::vector& wlNew, const std::vector& spectrum) -> std::vector; protected: using SpectraGrid = std::mdspan, std::dextents>; // NOLINT(misc-include-cleaner) -- is already included above; clang-tidy-18's libc++-18 header-mapping data doesn't yet recognize it as std::mdspan/std::dextents' canonical header [[nodiscard]] virtual auto spec(double d1, double d2, double d3) const -> std::vector; [[nodiscard]] static auto outOfBoundsResult(const std::string& message) -> std::vector; std::vector dim1_; std::vector dim2_; std::vector dim3_; std::vector> spectra_; SpectraGrid grid_; private: // Cached bracket indices for search acceleration, one per // tensor-grid axis, exactly as interp::Mesh2DGrid caches // iSave_/jSave_: the common calling pattern is a long series // of spec() queries at (d1, d2, d3) points that are sorted or // nearly sorted along each axis (e.g. a series of stars fed // through in Teff/logg order), so the bracket found for one // query is usually still correct, or nearly so, for the next // one. Caching it lets findBracket (utils::findBracket, in // src/utils/GridBracket.cpp) skip the binary search entirely // on a cache hit, and narrow its search range on a miss, rather than // always searching the full axis from scratch. ThreadVec's, // rather than plain size_t's, so that each OpenMP thread gets // its own private cached index -- without this, concurrent // calls from different threads would race to update a single // shared cache. spec(double, double, double) must bind a // local reference to the element private to the calling // thread (e.g. "dim1Cache_()") before passing it to // findBracket, exactly as Mesh2DGrid's own methods do with // iSave_/jSave_. dim2Cache_/dim3Cache_ are protected, rather // than private like dim1Cache_, so that SpecsynLib2D's own 2D // spec(double, double) -- which never touches dim1_ at all -- // can reuse them directly instead of keeping a redundant cache // of its own. mutable utils::ThreadVec dim1Cache_; protected: mutable utils::ThreadVec dim2Cache_; mutable utils::ThreadVec dim3Cache_; }; } // namespace specsyn #endif // SPECSYNLIB_HPP