.. _program_listing_file_src_specsyn_Specsyn.hpp: Program Listing for File Specsyn.hpp ==================================== |exhale_lsh| :ref:`Return to documentation for file ` (``src/specsyn/Specsyn.hpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #ifndef SPECSYN_HPP #define SPECSYN_HPP #include "../interpolation/Interpolator1D.hpp" #include "../pdfs/PDF.hpp" #include "../tracks/TrackCommons.hpp" #include "../utils/Constants.hpp" #include #include #include #include #include #include #include #include #include #include namespace io { class SimControls; } // namespace io namespace specsyn { class Specsyn { public: // Shorten type names: Segment is a single isochrone segment // (an element of the Isochrone returned by // Tracks2D::getIsochrone -- an isochrone can have more than // one disjoint segment for non-monotonic tracks), and // StarData is the type returned by evaluating a Segment at a // given mass using Segment = interp::Interpolator1D(tracks::FieldIdx::nTrackQty)>; using Isochrone = std::vector>; using StarData = std::array(tracks::FieldIdx::nTrackQty)>; explicit Specsyn(const io::SimControls& controls) : controls_(controls) { } virtual ~Specsyn() = default; // Copyable and movable (matching the C++ reference semantics // of controls_, which just gets rebound to the same referent // on copy), but never actually copied/assigned in practice -- // every Specsyn is held via unique_ptr (see SimControls's own // specsyn_ and SpecsynLibChained's libs_) Specsyn(const Specsyn&) = default; Specsyn(Specsyn&&) = default; auto operator=(const Specsyn&) -> Specsyn& = delete; auto operator=(Specsyn&&) -> Specsyn& = delete; [[nodiscard]] auto wl() const -> const std::vector& { return wl_; } [[nodiscard]] auto controls() const -> const io::SimControls& { return controls_; } [[nodiscard]] auto wlObs() const -> std::vector; [[nodiscard]] virtual auto fehMin() const -> double { return -std::numeric_limits::infinity(); } [[nodiscard]] virtual auto fehMax() const -> double { return std::numeric_limits::infinity(); } [[nodiscard]] auto requestedFehMin() const -> double { return requestedFehMin_; } [[nodiscard]] auto requestedFehMax() const -> double { return requestedFehMax_; } [[nodiscard]] virtual auto loggMin() const -> double { return -std::numeric_limits::infinity(); } [[nodiscard]] virtual auto loggMax() const -> double { return std::numeric_limits::infinity(); } [[nodiscard]] virtual auto spec(const StarData& props, double feh) const -> std::vector = 0; [[nodiscard]] virtual auto specForce(const StarData& props, double feh) const -> std::vector { auto result = spec(props, feh); if (result.empty()) { throw std::runtime_error( "Specsyn::specForce: unable to force a spectrum for this star"); } return result; } [[nodiscard]] virtual auto specForIntegration(const StarData& props, double feh) const -> std::vector { return spec(props, feh); } [[nodiscard]] auto spec(double m, const Segment& segment, double feh) const -> std::vector { return spec(segment(m), feh); } [[nodiscard]] auto specWl(double m, const Segment& segment, double feh) const -> std::vector { auto result = spec(m, segment, feh); for (std::size_t i = 0; i < result.size(); ++i) { result[i] *= wl_[i]; // NOLINT(cppcoreguidelines-pro-bounds-avoid-unchecked-container-access) -- result has the same size as wl_ (one entry per wavelength), and i is bounded by result.size() } return result; } [[nodiscard]] auto specWlForIntegration(const StarData& props, double feh) const -> std::vector { auto result = specForIntegration(props, feh); for (std::size_t i = 0; i < result.size(); ++i) { result[i] *= wl_[i]; // NOLINT(cppcoreguidelines-pro-bounds-avoid-unchecked-container-access) -- result has the same size as wl_ (one entry per wavelength), and i is bounded by result.size() } return result; } [[nodiscard]] virtual auto specCts( const Isochrone& isochrone, const pdfs::PDF& imf, double mTot, double mMin, double mMax, double feh ) const -> std::vector; [[nodiscard]] auto specCts( const pdfs::PDF& sfr, const pdfs::PDF& imf, const pdfs::PDF& fehDist, double curTime, double fCluster, double mMin, double mMax ) const -> std::vector; [[nodiscard]] auto specAndLbolCts( const pdfs::PDF& sfr, const pdfs::PDF& imf, const pdfs::PDF& fehDist, double curTime, double fCluster, double mMin, double mMax ) const -> std::pair, double>; [[nodiscard]] auto intRelTol() const -> double; [[nodiscard]] auto intAbsTol() const -> double; [[nodiscard]] auto intMaxIter() const -> std::size_t; protected: [[nodiscard]] static auto describeStar(const StarData& props, double feh) -> std::string; [[nodiscard]] static auto getSAandLogg(const StarData& props) -> std::pair { constexpr double pi = std::numbers::pi_v; const double logL = props[static_cast(tracks::FieldIdx::logL)]; // NOLINT(cppcoreguidelines-pro-bounds-avoid-unchecked-container-access) -- StarData is a fixed-size std::array, and logL is one of its compile-time-known indices const double logTeff = props[static_cast(tracks::FieldIdx::logTe)]; // NOLINT(cppcoreguidelines-pro-bounds-avoid-unchecked-container-access) -- see above const double mass = props[static_cast(tracks::FieldIdx::mass)]; // Msun // NOLINT(cppcoreguidelines-pro-bounds-avoid-unchecked-container-access) -- see above const double temperature = std::pow(10.0, logTeff); // K const double luminosity = std::pow(10.0, logL) * utils::Lsun; // erg/s const double temperature4 = temperature * temperature * temperature * temperature; const double radius = std::sqrt(luminosity / (4.0 * pi * utils::sigmaSB * temperature4)); // cm const double area = 4.0 * pi * radius * radius; // cm^2 const double g = utils::G * mass * utils::Msun / (radius * radius); // cm/s^2 const double logg = std::log10(g); return { area, logg }; } const io::SimControls& controls_; // NOLINT(cppcoreguidelines-avoid-const-or-ref-data-members) -- deliberately a live reference, not a copy: see this member's own comment for why (controls_'s own tolerances/redshift must be readable live, not snapshotted). This class is only ever used through the same non-copyable, non-movable ownership pattern (unique_ptr in SimControls's own specsyn_) as every other class with a reference member in this codebase (e.g. SpecsynLibNoWind's FeH_/logg_/logTeff_), so the usual objection (disabling implicit copy/move assignment) doesn't apply in practice. std::vector wl_; void setRequestedFehRange(const double fehMin, const double fehMax) { requestedFehMin_ = fehMin; requestedFehMax_ = fehMax; } private: double requestedFehMin_ = -std::numeric_limits::infinity(); double requestedFehMax_ = std::numeric_limits::infinity(); [[nodiscard]] auto specCtsImpl( const Isochrone& isochrone, const pdfs::PDF& imf, double mTot, double mMin, double mMax, double feh, bool forIntegration, bool computeLbol ) const -> std::vector; [[nodiscard]] auto specCtsHelper( const pdfs::PDF& sfr, const pdfs::PDF& imf, const pdfs::PDF& fehDist, double curTime, double fCluster, double mMin, double mMax, bool computeLbol ) const -> std::vector; [[nodiscard]] auto continuousSpecIntegrand( double age, const pdfs::PDF& imf, double mMin, double mMax, bool computeLbol, double feh) const -> std::vector; }; } // namespace specsyn #endif // SPECSYN_HPP