25 const Composition &composition,
30 if (std::holds_alternative<NetworkBuildDepth>(maxLayers)) {
31 depth =
static_cast<int>(std::get<NetworkBuildDepth>(maxLayers));
33 depth = std::get<int>(maxLayers);
35 auto logger = fourdst::logging::LogManager::getInstance().getLogger(
"log");
37 LOG_ERROR(logger,
"Network build depth is set to 0. No reactions will be collected.");
38 throw std::logic_error(
"Network build depth is set to 0. No reactions will be collected.");
42 std::vector<Reaction> remainingReactions;
43 for (
const auto&
reaction : allReactions) {
44 if (
reaction.is_reverse() == reverse) {
45 remainingReactions.push_back(
reaction);
50 LOG_INFO(logger,
"Building full nuclear network with a total of {} reactions.", allReactions.size());
55 std::unordered_set<Species> availableSpecies;
56 for (
const auto &entry: composition | std::views::values) {
57 if (entry.mass_fraction() > 0.0) {
58 availableSpecies.insert(entry.isotope());
63 std::vector<Reaction> collectedReactions;
65 LOG_INFO(logger,
"Starting network construction with {} available species.", availableSpecies.size());
66 for (
int layer = 0; layer < depth && !remainingReactions.empty(); ++layer) {
67 LOG_TRACE_L1(logger,
"Collecting reactions for layer {} with {} remaining reactions. Currently there are {} available species", layer, remainingReactions.size(), availableSpecies.size());
68 std::vector<Reaction> reactionsForNextPass;
69 std::unordered_set<Species> newProductsThisLayer;
70 bool newReactionsAdded =
false;
72 reactionsForNextPass.reserve(remainingReactions.size());
74 for (
const auto &
reaction : remainingReactions) {
75 bool allReactantsAvailable =
true;
76 for (
const auto& reactant :
reaction.reactants()) {
77 if (!availableSpecies.contains(reactant)) {
78 allReactantsAvailable =
false;
83 if (allReactantsAvailable) {
84 collectedReactions.push_back(
reaction);
85 newReactionsAdded =
true;
87 for (
const auto& product :
reaction.products()) {
88 newProductsThisLayer.insert(product);
91 reactionsForNextPass.push_back(
reaction);
95 if (!newReactionsAdded) {
96 LOG_INFO(logger,
"No new reactions added in layer {}. Stopping network construction with {} reactions collected.", layer, collectedReactions.size());
100 LOG_TRACE_L1(logger,
"Layer {}: Collected {} reactions. New products this layer: {}", layer, collectedReactions.size(), newProductsThisLayer.size());
101 availableSpecies.insert(newProductsThisLayer.begin(), newProductsThisLayer.end());
103 remainingReactions = std::move(reactionsForNextPass);
106 LOG_INFO(logger,
"Network construction completed with {} reactions collected.", collectedReactions.size());
reaction::LogicalReactionSet build_reaclib_nuclear_network(const fourdst::composition::Composition &composition, BuildDepthType maxLayers=NetworkBuildDepth::Full, bool reverse=false)
Builds a nuclear reaction network from the Reaclib library based on an initial composition.