2025-07-23 16:26:30 -04:00
# include <pybind11/pybind11.h>
# include <pybind11/stl.h> // Needed for vectors, maps, sets, strings
2025-08-14 13:33:46 -04:00
# include <pybind11/stl_bind.h> // Needed for binding std::vector, std::map etc. if needed directly
2025-07-23 16:26:30 -04:00
# include <string_view>
# include <vector>
# include "bindings.h"
# include "gridfire/reaction/reaction.h"
# include "gridfire/reaction/reaclib.h"
namespace py = pybind11 ;
void register_reaction_bindings ( py : : module & m ) {
py : : class_ < gridfire : : reaction : : RateCoefficientSet > ( m , " RateCoefficientSet " )
. def ( py : : init < double , double , double , double , double , double , double > ( ) ,
py : : arg ( " a0 " ) , py : : arg ( " a1 " ) , py : : arg ( " a2 " ) , py : : arg ( " a3 " ) ,
py : : arg ( " a4 " ) , py : : arg ( " a5 " ) , py : : arg ( " a6 " ) ,
" Construct a RateCoefficientSet with the given parameters. "
) ;
using fourdst : : atomic : : Species ;
2025-08-14 13:33:46 -04:00
py : : class_ < gridfire : : reaction : : ReaclibReaction > ( m , " ReaclibReaction " )
. def (
py : : init <
const std : : string_view ,
const std : : string_view ,
int ,
const std : : vector < Species > & ,
const std : : vector < Species > & ,
double , std : : string_view ,
gridfire : : reaction : : RateCoefficientSet ,
bool
> ( ) ,
py : : arg ( " id " ) ,
py : : arg ( " peName " ) ,
py : : arg ( " chapter " ) ,
py : : arg ( " reactants " ) ,
py : : arg ( " products " ) ,
py : : arg ( " qValue " ) ,
py : : arg ( " label " ) ,
py : : arg ( " sets " ) ,
py : : arg ( " reverse " ) = false ,
" Construct a Reaction with the given parameters. "
)
. def (
" calculate_rate " ,
[ ] ( const gridfire : : reaction : : ReaclibReaction & self , const double T9 , const double rho , const std : : vector < double > & Y ) - > double {
2025-10-30 15:05:08 -04:00
return self . calculate_rate ( T9 , rho , 0 , { } , Y , { } ) ;
2025-08-14 13:33:46 -04:00
} ,
py : : arg ( " T9 " ) ,
py : : arg ( " rho " ) ,
py : : arg ( " Y " ) ,
" Calculate the reaction rate at a given temperature T9 (in units of 10^9 K). "
)
. def (
" peName " ,
& gridfire : : reaction : : ReaclibReaction : : peName ,
" Get the reaction name in (projectile, ejectile) notation (e.g., 'p(p,g)d'). "
)
. def (
" chapter " ,
& gridfire : : reaction : : ReaclibReaction : : chapter ,
" Get the REACLIB chapter number defining the reaction structure. "
)
. def (
" sourceLabel " ,
& gridfire : : reaction : : ReaclibReaction : : sourceLabel ,
" Get the source label for the rate data (e.g., 'wc12w', 'st08'). "
)
. def (
" rateCoefficients " ,
& gridfire : : reaction : : ReaclibReaction : : rateCoefficients ,
" get the set of rate coefficients. "
)
. def (
" contains " ,
& gridfire : : reaction : : ReaclibReaction : : contains ,
py : : arg ( " species " ) ,
" Check if the reaction contains a specific species. "
)
. def (
" contains_reactant " ,
& gridfire : : reaction : : ReaclibReaction : : contains_reactant ,
" Check if the reaction contains a specific reactant species. "
)
. def (
" contains_product " ,
& gridfire : : reaction : : ReaclibReaction : : contains_product ,
" Check if the reaction contains a specific product species. "
)
. def (
" all_species " ,
& gridfire : : reaction : : ReaclibReaction : : all_species ,
" Get all species involved in the reaction (both reactants and products) as a set. "
)
. def (
" reactant_species " ,
& gridfire : : reaction : : ReaclibReaction : : reactant_species ,
" Get the reactant species of the reaction as a set. "
)
. def (
" product_species " ,
& gridfire : : reaction : : ReaclibReaction : : product_species ,
" Get the product species of the reaction as a set. "
)
. def (
" num_species " ,
& gridfire : : reaction : : ReaclibReaction : : num_species ,
" Count the number of species in the reaction. "
)
. def (
" stoichiometry " ,
[ ] ( const gridfire : : reaction : : ReaclibReaction & self , const Species & species ) - > int {
return self . stoichiometry ( species ) ;
} ,
2025-07-23 16:26:30 -04:00
py : : arg ( " species " ) ,
2025-08-14 13:33:46 -04:00
" Get the stoichiometry of the reaction as a map from species to their coefficients. "
)
. def (
" stoichiometry " ,
[ ] ( const gridfire : : reaction : : ReaclibReaction & self ) - > std : : unordered_map < Species , int > {
return self . stoichiometry ( ) ;
} ,
" Get the stoichiometry of the reaction as a map from species to their coefficients. "
)
. def (
" id " ,
& gridfire : : reaction : : ReaclibReaction : : id ,
" Get the unique identifier of the reaction. "
)
. def (
" qValue " ,
& gridfire : : reaction : : ReaclibReaction : : qValue ,
" Get the Q-value of the reaction in MeV. "
)
. def (
" reactants " ,
& gridfire : : reaction : : ReaclibReaction : : reactants ,
" Get a list of reactant species in the reaction. "
)
. def (
" products " ,
& gridfire : : reaction : : ReaclibReaction : : products ,
" Get a list of product species in the reaction. "
)
. def (
" is_reverse " ,
& gridfire : : reaction : : ReaclibReaction : : is_reverse ,
" Check if this is a reverse reaction rate. "
)
. def (
" excess_energy " ,
& gridfire : : reaction : : ReaclibReaction : : excess_energy ,
" Calculate the excess energy from the mass difference of reactants and products. "
)
. def (
" __eq__ " ,
& gridfire : : reaction : : ReaclibReaction : : operator = = ,
" Equality operator for reactions based on their IDs. "
)
. def (
" __neq__ " ,
& gridfire : : reaction : : ReaclibReaction : : operator ! = ,
" Inequality operator for reactions based on their IDs. "
)
. def (
" hash " ,
& gridfire : : reaction : : ReaclibReaction : : hash ,
2025-07-23 16:26:30 -04:00
py : : arg ( " seed " ) = 0 ,
2025-08-14 13:33:46 -04:00
" Compute a hash for the reaction based on its ID. "
)
. def (
" __repr__ " ,
[ ] ( const gridfire : : reaction : : ReaclibReaction & self ) {
std : : stringstream ss ;
ss < < self ; // Use the existing operator<< for Reaction
return ss . str ( ) ;
}
) ;
2025-07-23 16:26:30 -04:00
2025-08-14 13:33:46 -04:00
py : : class_ < gridfire : : reaction : : LogicalReaclibReaction , gridfire : : reaction : : ReaclibReaction > ( m , " LogicalReaclibReaction " )
. def (
2025-11-27 14:34:20 -05:00
py : : init < const std : : vector < std : : unique_ptr < gridfire : : reaction : : ReaclibReaction > > > ( ) ,
2025-07-23 16:26:30 -04:00
py : : arg ( " reactions " ) ,
2025-10-30 15:05:08 -04:00
" Construct a LogicalReaclibReaction from a vector of ReaclibReaction objects. "
)
. def (
2025-11-27 14:34:20 -05:00
py : : init < const std : : vector < std : : unique_ptr < gridfire : : reaction : : ReaclibReaction > > , bool > ( ) ,
2025-10-30 15:05:08 -04:00
py : : arg ( " reactions " ) ,
py : : arg ( " is_reverse " ) ,
" Construct a LogicalReaclibReaction from a vector of ReaclibReaction objects. "
2025-08-14 13:33:46 -04:00
)
. def (
" add_reaction " ,
& gridfire : : reaction : : LogicalReaclibReaction : : add_reaction ,
2025-07-23 16:26:30 -04:00
py : : arg ( " reaction " ) ,
2025-08-14 13:33:46 -04:00
" Add another Reaction source to this logical reaction. "
)
. def (
" size " ,
& gridfire : : reaction : : LogicalReaclibReaction : : size ,
" Get the number of source rates contributing to this logical reaction. "
)
. def (
" __len__ " ,
& gridfire : : reaction : : LogicalReaclibReaction : : size ,
" Overload len() to return the number of source rates. "
)
. def (
" sources " ,
& gridfire : : reaction : : LogicalReaclibReaction : : sources ,
" Get the list of source labels for the aggregated rates. "
)
. def (
" calculate_rate " ,
2025-10-30 15:05:08 -04:00
[ ] (
const gridfire : : reaction : : LogicalReaclibReaction & self ,
const double T9 ,
const double rho ,
const double Ye ,
const double mue ,
const std : : vector < double > & Y ,
const std : : unordered_map < size_t , Species > & index_to_species_map
) - > double {
return self . calculate_rate ( T9 , rho , Ye , mue , Y , index_to_species_map ) ;
2025-08-14 13:33:46 -04:00
} ,
py : : arg ( " T9 " ) ,
2025-10-30 15:05:08 -04:00
py : : arg ( " rho " ) ,
py : : arg ( " Ye " ) ,
py : : arg ( " mue " ) ,
py : : arg ( " Y " ) ,
py : : arg ( " index_to_species_map " ) ,
" Calculate the reaction rate at a given temperature T9 (in units of 10^9 K). Note that for a reaclib reaction only T9 is actually used, all other parameters are there for interface compatibility. "
2025-08-14 13:33:46 -04:00
)
. def (
" calculate_forward_rate_log_derivative " ,
2025-10-30 15:05:08 -04:00
& gridfire : : reaction : : LogicalReaclibReaction : : calculate_log_rate_partial_deriv_wrt_T9 ,
2025-08-14 13:33:46 -04:00
py : : arg ( " T9 " ) ,
2025-10-30 15:05:08 -04:00
py : : arg ( " rho " ) ,
py : : arg ( " Ye " ) ,
py : : arg ( " mue " ) ,
py : : arg ( " Composition " ) ,
2025-08-14 13:33:46 -04:00
" Calculate the forward rate log derivative at a given temperature T9 (in units of 10^9 K). "
) ;
2025-07-23 16:26:30 -04:00
2025-08-14 13:33:46 -04:00
py : : class_ < gridfire : : reaction : : ReactionSet > ( m , " ReactionSet " )
. def (
2025-10-30 15:05:08 -04:00
py : : init < const std : : vector < gridfire : : reaction : : Reaction * > > ( ) ,
2025-07-23 16:26:30 -04:00
py : : arg ( " reactions " ) ,
2025-10-30 15:05:08 -04:00
py : : keep_alive < 1 , 2 > ( ) , // Keep arg 2 (reactions) alive as long as arg 1 (self) is alive. This helps mitigate use-after-free errors
2025-08-14 13:33:46 -04:00
" Construct a LogicalReactionSet from a vector of LogicalReaclibReaction objects. "
)
2025-10-30 15:05:08 -04:00
. def_static (
" from_clones " ,
[ ] ( const std : : vector < gridfire : : reaction : : Reaction * > & py_reactions ) {
std : : vector < std : : unique_ptr < gridfire : : reaction : : Reaction > > cpp_reactions ;
cpp_reactions . reserve ( py_reactions . size ( ) ) ;
for ( const auto & reaction : py_reactions ) {
cpp_reactions . emplace_back ( reaction - > clone ( ) ) ;
}
return std : : make_unique < gridfire : : reaction : : ReactionSet > ( std : : move ( cpp_reactions ) ) ;
} ,
py : : arg ( " reactions " ) ,
" Create a ReactionSet that takes ownership of the reactions by cloning the input reactions. "
)
2025-08-14 13:33:46 -04:00
. def (
py : : init < > ( ) ,
" Default constructor for an empty LogicalReactionSet. "
)
. def (
py : : init < const gridfire : : reaction : : ReactionSet & > ( ) ,
2025-07-23 16:26:30 -04:00
py : : arg ( " other " ) ,
2025-08-14 13:33:46 -04:00
" Copy constructor for LogicalReactionSet. "
)
. def (
" add_reaction " ,
py : : overload_cast < const gridfire : : reaction : : Reaction & > ( & gridfire : : reaction : : ReactionSet : : add_reaction ) ,
2025-07-23 16:26:30 -04:00
py : : arg ( " reaction " ) ,
2025-08-14 13:33:46 -04:00
" Add a LogicalReaclibReaction to the set. "
)
. def (
" remove_reaction " ,
& gridfire : : reaction : : ReactionSet : : remove_reaction ,
2025-07-23 16:26:30 -04:00
py : : arg ( " reaction " ) ,
2025-08-14 13:33:46 -04:00
" Remove a LogicalReaclibReaction from the set. "
)
. def (
" contains " ,
py : : overload_cast < const std : : string_view & > ( & gridfire : : reaction : : ReactionSet : : contains , py : : const_ ) ,
2025-07-23 16:26:30 -04:00
py : : arg ( " id " ) ,
2025-08-14 13:33:46 -04:00
" Check if the set contains a specific LogicalReaclibReaction. "
)
. def (
" contains " ,
py : : overload_cast < const gridfire : : reaction : : Reaction & > ( & gridfire : : reaction : : ReactionSet : : contains , py : : const_ ) ,
2025-07-23 16:26:30 -04:00
py : : arg ( " reaction " ) ,
2025-08-14 13:33:46 -04:00
" Check if the set contains a specific Reaction. "
)
. def (
" size " ,
& gridfire : : reaction : : ReactionSet : : size ,
" Get the number of LogicalReactions in the set. "
)
. def (
" __len__ " , & gridfire : : reaction : : ReactionSet : : size ,
" Overload len() to return the number of LogicalReactions. "
)
. def (
" clear " ,
& gridfire : : reaction : : ReactionSet : : clear ,
" Remove all LogicalReactions from the set. "
)
. def ( " contains_species " ,
& gridfire : : reaction : : ReactionSet : : contains_species ,
2025-07-23 16:26:30 -04:00
py : : arg ( " species " ) ,
2025-08-14 13:33:46 -04:00
" Check if any reaction in the set involves the given species. "
)
. def (
" contains_reactant " ,
& gridfire : : reaction : : ReactionSet : : contains_reactant ,
2025-07-23 16:26:30 -04:00
py : : arg ( " species " ) ,
2025-08-14 13:33:46 -04:00
" Check if any reaction in the set has the species as a reactant. "
)
. def (
" contains_product " ,
& gridfire : : reaction : : ReactionSet : : contains_product ,
2025-07-23 16:26:30 -04:00
py : : arg ( " species " ) ,
2025-08-14 13:33:46 -04:00
" Check if any reaction in the set has the species as a product. "
)
. def (
" __getitem__ " ,
py : : overload_cast < size_t > ( & gridfire : : reaction : : ReactionSet : : operator [ ] , py : : const_ ) ,
2025-11-10 10:40:03 -05:00
py : : return_value_policy : : reference ,
2025-07-23 16:26:30 -04:00
py : : arg ( " index " ) ,
2025-08-14 13:33:46 -04:00
" Get a LogicalReaclibReaction by index. "
)
. def (
" __getitem___ " ,
py : : overload_cast < const std : : string_view & > ( & gridfire : : reaction : : ReactionSet : : operator [ ] , py : : const_ ) ,
2025-11-10 10:40:03 -05:00
py : : return_value_policy : : reference ,
2025-07-23 16:26:30 -04:00
py : : arg ( " id " ) ,
2025-08-14 13:33:46 -04:00
" Get a LogicalReaclibReaction by its ID. "
)
. def (
" __eq__ " ,
& gridfire : : reaction : : ReactionSet : : operator = = ,
2025-07-23 16:26:30 -04:00
py : : arg ( " LogicalReactionSet " ) ,
2025-08-14 13:33:46 -04:00
" Equality operator for LogicalReactionSets based on their contents. "
)
. def (
" __ne__ " ,
& gridfire : : reaction : : ReactionSet : : operator ! = ,
2025-07-23 16:26:30 -04:00
py : : arg ( " LogicalReactionSet " ) ,
2025-08-14 13:33:46 -04:00
" Inequality operator for LogicalReactionSets based on their contents. "
)
. def (
" hash " ,
& gridfire : : reaction : : ReactionSet : : hash ,
py : : arg ( " seed " ) = 0 ,
" Compute a hash for the LogicalReactionSet based on its contents. "
)
. def (
" __repr__ " ,
[ ] ( const gridfire : : reaction : : ReactionSet & self ) {
std : : stringstream ss ;
ss < < self ;
return ss . str ( ) ;
}
)
. def (
" getReactionSetSpecies " ,
& gridfire : : reaction : : ReactionSet : : getReactionSetSpecies ,
" Get all species involved in the reactions of the set as a set of Species objects. "
) ;
2025-07-23 16:26:30 -04:00
2025-08-14 13:33:46 -04:00
m . def (
" packReactionSet " ,
& gridfire : : reaction : : packReactionSet ,
2025-07-23 16:26:30 -04:00
py : : arg ( " reactionSet " ) ,
" Convert a ReactionSet to a LogicalReactionSet by aggregating reactions with the same peName. "
) ;
2025-08-14 13:33:46 -04:00
m . def (
" get_all_reactions " ,
& gridfire : : reaclib : : get_all_reaclib_reactions ,
" Get all reactions from the REACLIB database. "
) ;
2025-07-23 16:26:30 -04:00
}