2025-07-14 14:50:49 -04:00
# include "gridfire/engine/procedures/construction.h"
# include <ranges>
# include <stdexcept>
# include "gridfire/reaction/reaction.h"
# include "gridfire/reaction/reaclib.h"
# include "fourdst/composition/composition.h"
# include "fourdst/logging/logging.h"
# include "quill/Logger.h"
# include "quill/LogMacros.h"
namespace gridfire {
using reaction : : ReactionSet ;
using reaction : : Reaction ;
using fourdst : : composition : : Composition ;
using fourdst : : atomic : : Species ;
2025-08-14 13:33:46 -04:00
ReactionSet build_reaclib_nuclear_network (
2025-07-14 14:50:49 -04:00
const Composition & composition ,
BuildDepthType maxLayers ,
bool reverse
) {
int depth ;
if ( std : : holds_alternative < NetworkBuildDepth > ( maxLayers ) ) {
depth = static_cast < int > ( std : : get < NetworkBuildDepth > ( maxLayers ) ) ;
} else {
depth = std : : get < int > ( maxLayers ) ;
}
auto logger = fourdst : : logging : : LogManager : : getInstance ( ) . getLogger ( " log " ) ;
if ( depth = = 0 ) {
LOG_ERROR ( logger , " Network build depth is set to 0. No reactions will be collected. " ) ;
throw std : : logic_error ( " Network build depth is set to 0. No reactions will be collected. " ) ;
}
2025-08-14 13:33:46 -04:00
const auto & allReactions = reaclib : : get_all_reaclib_reactions ( ) ;
std : : vector < Reaction * > remainingReactions ;
2025-07-14 14:50:49 -04:00
for ( const auto & reaction : allReactions ) {
2025-08-14 13:33:46 -04:00
if ( reaction - > is_reverse ( ) = = reverse ) {
remainingReactions . push_back ( reaction . get ( ) ) ;
2025-07-14 14:50:49 -04:00
}
}
if ( depth = = static_cast < int > ( NetworkBuildDepth : : Full ) ) {
LOG_INFO ( logger , " Building full nuclear network with a total of {} reactions. " , allReactions . size ( ) ) ;
const ReactionSet reactionSet ( remainingReactions ) ;
2025-08-14 13:33:46 -04:00
return reaction : : packReactionSet ( reactionSet ) ;
2025-07-14 14:50:49 -04:00
}
std : : unordered_set < Species > availableSpecies ;
for ( const auto & entry : composition | std : : views : : values ) {
if ( entry . mass_fraction ( ) > 0.0 ) {
availableSpecies . insert ( entry . isotope ( ) ) ;
}
}
2025-08-14 13:33:46 -04:00
std : : vector < Reaction * > collectedReactions ;
2025-07-14 14:50:49 -04:00
LOG_INFO ( logger , " Starting network construction with {} available species. " , availableSpecies . size ( ) ) ;
for ( int layer = 0 ; layer < depth & & ! remainingReactions . empty ( ) ; + + layer ) {
LOG_TRACE_L1 ( logger , " Collecting reactions for layer {} with {} remaining reactions. Currently there are {} available species " , layer , remainingReactions . size ( ) , availableSpecies . size ( ) ) ;
2025-08-14 13:33:46 -04:00
std : : vector < Reaction * > reactionsForNextPass ;
2025-07-14 14:50:49 -04:00
std : : unordered_set < Species > newProductsThisLayer ;
bool newReactionsAdded = false ;
reactionsForNextPass . reserve ( remainingReactions . size ( ) ) ;
for ( const auto & reaction : remainingReactions ) {
bool allReactantsAvailable = true ;
2025-08-14 13:33:46 -04:00
for ( const auto & reactant : reaction - > reactants ( ) ) {
2025-07-14 14:50:49 -04:00
if ( ! availableSpecies . contains ( reactant ) ) {
allReactantsAvailable = false ;
break ;
}
}
if ( allReactantsAvailable ) {
collectedReactions . push_back ( reaction ) ;
newReactionsAdded = true ;
2025-08-14 13:33:46 -04:00
for ( const auto & product : reaction - > products ( ) ) {
2025-07-14 14:50:49 -04:00
newProductsThisLayer . insert ( product ) ;
}
} else {
reactionsForNextPass . push_back ( reaction ) ;
}
}
if ( ! newReactionsAdded ) {
LOG_INFO ( logger , " No new reactions added in layer {}. Stopping network construction with {} reactions collected. " , layer , collectedReactions . size ( ) ) ;
break ;
}
LOG_TRACE_L1 ( logger , " Layer {}: Collected {} reactions. New products this layer: {} " , layer , collectedReactions . size ( ) , newProductsThisLayer . size ( ) ) ;
availableSpecies . insert ( newProductsThisLayer . begin ( ) , newProductsThisLayer . end ( ) ) ;
remainingReactions = std : : move ( reactionsForNextPass ) ;
}
LOG_INFO ( logger , " Network construction completed with {} reactions collected. " , collectedReactions . size ( ) ) ;
const ReactionSet reactionSet ( collectedReactions ) ;
2025-08-14 13:33:46 -04:00
return reaction : : packReactionSet ( reactionSet ) ;
2025-07-14 14:50:49 -04:00
}
}