Program Listing for File Cluster.hpp

↰ Return to documentation for file (src/core/Cluster.hpp)

#ifndef CLUSTER_HPP
#define CLUSTER_HPP

#include "../interpolation/Interpolator1D.hpp"
#include "../io/SimControls.hpp"
#include "../tracks/TrackCommons.hpp"
#include "../tracks/Tracks2D.hpp"
#include "../utils/RngThread.hpp"
#include <array>
#include <cstddef>
#include <functional>
#include <memory>
#include <utility>
#include <variant>
#include <vector>

namespace yields
{
    class Yields;
} // namespace yields

namespace feedback
{
    class Winds;
} // namespace feedback

namespace core
{

    class Cluster
    {
    public:

        // Shorten type names
        using Segment = interp::Interpolator1D<
            static_cast<size_t>(tracks::FieldIdx::nTrackQty)>;
        using Interp1dPtr = std::vector<std::unique_ptr<Segment>>;
        using Track2DVar = std::variant<tracks::Tracks2D,
            std::shared_ptr<const tracks::Tracks2D>>;

        Cluster(unsigned long uid,
            double mass,
            double time,
            const io::SimControls& controls);

        Cluster(unsigned long uid,
            double mass,
            double time,
            const io::SimControls& controls,
            const utils::RngState& rngState);

        // Observers

        [[nodiscard]] auto rngState() const -> const utils::RngState& { return rngState_; }

        [[nodiscard]] auto uid() const { return uid_; }

        [[nodiscard]] auto targetMass() const { return targetMass_; }

        [[nodiscard]] auto birthMass() const { return birthMass_; }

        [[nodiscard]] auto formTime() const { return formTime_; }

        [[nodiscard]] auto feH() const { return feH_; }

        [[nodiscard]] auto aV() const { return aV_; }

        [[nodiscard]] auto avNeb() const { return avNeb_; }

        [[nodiscard]] auto starMasses() const -> const auto& { return m_; }

        [[nodiscard]] auto deadStarMasses() const -> const auto& { return mDead_; }

        [[nodiscard]] auto starDeathTimes() const -> const auto& { return tDeath_; }

        [[nodiscard]] auto deadStarDeathTimes() const -> const auto& { return tDied_; }

        [[nodiscard]] auto tracks() const -> const tracks::Tracks2D&;

        [[nodiscard]] auto spec() -> const auto&
        {
            if (!specCurrent_) { computeSpec(); specCurrent_ = true; }
            return spec_;
        }

        [[nodiscard]] auto specExtinct() -> const auto&
        {
            if (!specCurrent_) { computeSpec(); specCurrent_ = true; }
            return specExtinct_;
        }

        [[nodiscard]] auto phot() -> const auto&
        {
            if (!photCurrent_) { computePhot(); photCurrent_ = true; }
            return phot_;
        }

        [[nodiscard]] auto photExtinct() -> const auto&
        {
            if (!photCurrent_) { computePhot(); photCurrent_ = true; }
            return photExtinct_;
        }

        [[nodiscard]] auto specNeb() -> const auto&
        {
            if (!specCurrent_) { computeSpec(); specCurrent_ = true; }
            return specNeb_;
        }

        [[nodiscard]] auto specNebExtinct() -> const auto&
        {
            if (!specCurrent_) { computeSpec(); specCurrent_ = true; }
            return specNebExtinct_;
        }

        [[nodiscard]] auto lineLum() -> const auto&
        {
            if (!specCurrent_) { computeSpec(); specCurrent_ = true; }
            return lineLum_;
        }

        [[nodiscard]] auto lineLumExtinct() -> const auto&
        {
            if (!specCurrent_) { computeSpec(); specCurrent_ = true; }
            return lineLumExtinct_;
        }

        [[nodiscard]] auto photNeb() -> const auto&
        {
            if (!photCurrent_) { computePhot(); photCurrent_ = true; }
            return photNeb_;
        }

        [[nodiscard]] auto photNebExtinct() -> const auto&
        {
            if (!photCurrent_) { computePhot(); photCurrent_ = true; }
            return photNebExtinct_;
        }

        [[nodiscard]] auto lbol()
        {
            if (!lbolCurrent_) { computeLbol(); lbolCurrent_ = true; }
            return lbol_;
        }

        [[nodiscard]] auto yields() const -> const auto&
        {
            return yields_;
        }

        [[nodiscard]] auto cumSNe() const -> double
        {
            return static_cast<double>(stochSN_) + nonStochSN_;
        }

        [[nodiscard]] auto mDotWind() -> double
        {
            if (!windsCurrent_) { computeWinds(); windsCurrent_ = true; }
            return mDotWind_;
        }

        [[nodiscard]] auto pDotWind() -> double
        {
            if (!windsCurrent_) { computeWinds(); windsCurrent_ = true; }
            return pDotWind_;
        }

        [[nodiscard]] auto eDotWind() -> double
        {
            if (!windsCurrent_) { computeWinds(); windsCurrent_ = true; }
            return eDotWind_;
        }

        [[nodiscard]] auto isDisrupted() const { return isDisrupted_; }

        void advance(double t);

    private:

        // Data set on creation
        utils::RngState rngState_;
        unsigned long uid_;
        double targetMass_;
        double formTime_;
        double feH_;
        double aV_;
        double avNeb_;
        std::reference_wrapper<const io::SimControls> controls_;

        // Masses
        std::vector<double> m_;
        std::vector<double> mDead_;
        double birthNonStochMass_;
        double birthMass_;
        std::vector<double> tDeath_;

        std::vector<double> tDied_;

        // Times
        double disruptTime_;
        double curTime_;
        // Other state information
        bool isDisrupted_ = false;
        bool advanced_ = false;
        Interp1dPtr isochrone_;
        std::vector<double> spec_;
        std::vector<double> specExtinct_;
        std::vector<double> specNeb_;
        std::vector<double> specNebExtinct_;
        std::vector<double> lineLum_;
        std::vector<double> lineLumExtinct_;
        std::vector<double> phot_;
        std::vector<double> photExtinct_;
        std::vector<double> photNeb_;
        std::vector<double> photNebExtinct_;
        double lbol_ = 0.0;
        std::vector<double> yields_;
        bool specCurrent_ = true;

        bool photCurrent_ = true;

        bool lbolCurrent_ = true;

        bool windsCurrent_ = true;

        double lastYieldTime_ = 0.0;

        double lastFeedbackTime_ = 0.0;

        unsigned long stochSN_ = 0;
        double nonStochSN_ = 0.0;
        double mDotWind_ = 0.0;
        double pDotWind_ = 0.0;
        double eDotWind_ = 0.0;
        Track2DVar tracks_;
        void updateLivingStars();

        void computeSpec();

        void computePhot();

        void computeLbol();

        void computeYields();

        [[nodiscard]] auto nonStochDeadMassRanges(double lastTime) const
            -> std::vector<std::pair<double, double>>;

        void computeFeedback();

        void computeWinds();

        [[nodiscard]] static auto windStar(double m, const Segment& segment,
            const feedback::Winds* winds, double feH) -> std::array<double, 3>;

        [[nodiscard]] static auto lbolStar(double m, const Segment& segment) -> std::array<double, 1>;

        [[nodiscard]] static auto yieldStar(double m, double feH,
            const yields::Yields& yields, bool decomposed,
            const io::SimControls& controls, double curTime, double formTime,
            const tracks::Tracks2D& tracks2D) -> std::vector<double>;

        [[nodiscard]] static auto snStar(double m, const io::SimControls& controls, double feH)
            -> std::vector<double>;

    };

} // namespace core

#endif // CLUSTER_HPP