Program Listing for File Yields.hpp

↰ Return to documentation for file (src/yields/Yields.hpp)

#ifndef YIELDS_HPP
#define YIELDS_HPP

#include "../elem/DecayChain.hpp"
#include "../elem/ElemCommons.hpp"
#include "YieldChannel.hpp"
#include "YieldCommons.hpp"
#include <algorithm>
#include <cstddef>
#include <limits>
#include <mdspan> // NOLINT(misc-include-cleaner)
#include <memory>
#include <optional>
#include <span>
#include <string>
#include <utility>
#include <vector>

namespace io
{
    class SimControls;
} // namespace io

namespace yields
{
    class Yields
    {
    public:

        using Array2D = std::mdspan<const double, std::dextents<std::size_t, 2>>; // NOLINT(misc-include-cleaner)

        Yields(const io::SimControls& controls,
            std::string registryName = defaultRegistry);

        // Movable (moving yieldChannels_'s own ownership, and rebinding
        // controls_ to the same referent) but not assignable (controls_
        // can't be reseated, matching Extinct's/Specsyn's own identical
        // controls_ members -- see either one's own comment).
        // Deliberately kept non-copyable too, even though
        // yieldChannels_'s own shared_ptr<YieldChannel> elements are
        // themselves freely copyable: a shallow copy would leave two
        // Yields instances sharing the same live YieldChannel objects
        // while each computes its own, independent isotopes_ from them
        // -- calling rebuildYieldGrid() on one would silently remap the
        // shared channels' own yield grids out from under the other.
        Yields(const Yields&) = delete;
        Yields(Yields&&) = default;
        auto operator=(const Yields&) -> Yields& = delete;
        auto operator=(Yields&&) -> Yields& = delete;
        ~Yields() = default;

        void addChannel(const YieldChannelDescriptor& descriptor);

        void addChannel(std::unique_ptr<YieldChannel> channel);

        void checkInstalledCoverage(double candMin, double candMax) const;

        void deleteChannel(std::size_t index);

        void setChannels(std::vector<std::unique_ptr<YieldChannel>> channels);

        void setChannels(const std::vector<YieldChannelDescriptor>& descriptors);

        void rebuildYieldGrid(const elem::IsotopeList& isotopes = {});

        [[nodiscard]] auto controls() const -> const io::SimControls& { return controls_; }

        [[nodiscard]] auto registryName() const -> const std::string& { return registryName_; }

        [[nodiscard]] auto yieldChannels() const -> const std::vector<std::shared_ptr<YieldChannel>>&
        {
            return yieldChannels_;
        }

        [[nodiscard]] auto isotopes() const -> const elem::IsotopeList& { return isotopes_; }

        [[nodiscard]] auto skippedIsotopes() const -> const elem::IsotopeList& { return skippedIsotopes_; }

        [[nodiscard]] auto requestedIsotopes() const -> const elem::IsotopeList& { return requestedIsotopes_; }

        [[nodiscard]] auto requestedFehMin() const -> double
        {
            double result = -std::numeric_limits<double>::infinity();
            for (const auto& channel : yieldChannels_) { result = std::max(result, channel->requestedFehMin()); }
            return result;
        }

        [[nodiscard]] auto requestedFehMax() const -> double
        {
            double result = std::numeric_limits<double>::infinity();
            for (const auto& channel : yieldChannels_) { result = std::min(result, channel->requestedFehMax()); }
            return result;
        }

        [[nodiscard]] auto yield(double mass, double feH, double dtDecay = 0.0) const
            -> std::pair<Array2D, std::vector<double>>;

        [[nodiscard]] auto yieldSum(double mass, double feH, double dtDecay = 0.0) const -> std::vector<double>;

        [[nodiscard]] auto hasYield(double mass, Channel channel) const -> bool;

        [[nodiscard]] auto hasYield(double mass, double feH, Channel channel) const -> bool;

        void applyDecay(double dtDecay, std::span<double> values) const;

        void applyDecay(double dtDecay, std::span<double> values, bool decomposed) const;

    private:

        const io::SimControls& controls_; // NOLINT(cppcoreguidelines-avoid-const-or-ref-data-members) -- deliberately a live reference, not a copy, matching Extinct's/Specsyn's own identical controls_ members exactly -- see either one's own comment for why. Only ever used through the same shared_ptr ownership pattern (shared_ptr<Yields> in SimControls's own yields_) as those, so the usual objection (disabling implicit copy/move assignment) doesn't apply in practice.
        std::string registryName_;
        std::vector<std::shared_ptr<YieldChannel>> yieldChannels_;
        elem::IsotopeList isotopes_;
        elem::IsotopeList skippedIsotopes_;
        elem::IsotopeList requestedIsotopes_;
        std::optional<elem::DecayChain> decayChain_;
    };

} // namespace yields

#endif // YIELDS_HPP