25 m_ENDF_MT( a_ENDF_MT ),
26 m_fissionGenre( a_fissionGenre ),
28 m_crossSectionThreshold( 0.0 ),
29 m_twoBodyThreshold( 0.0 ),
30 m_isPairProduction( false ),
31 m_isPhotoAtomicIncoherentScattering( false ),
32 m_RutherfordScatteringPresent( false ),
33 m_onlyRutherfordScatteringPresent( false ),
34 m_nuclearPlusInterferencePresent( false ),
35 m_decayPositronium( false ),
69 m_crossSectionThreshold( 0.0 ),
70 m_twoBodyThreshold( 0.0 ),
71 m_isPairProduction( false ),
72 m_isPhotoAtomicIncoherentScattering( false ),
73 m_RutherfordScatteringPresent( false ),
74 m_onlyRutherfordScatteringPresent( false ),
75 m_nuclearPlusInterferencePresent( false ),
76 m_decayPositronium( false ),
82 m_outputChannel( nullptr ) {
84 m_isPairProduction =
label( ).find(
"pair production" ) != std::string::npos;
85 m_decayPositronium = m_isPairProduction && a_construction.
decayPositronium( );
86 m_isPhotoAtomicIncoherentScattering =
false;
87 if( m_doubleDifferentialCrossSection.size( ) > 0 )
90 m_doubleDifferentialCrossSection.setAncestor(
this );
91 m_crossSection.setAncestor(
this );
92 m_availableEnergy.setAncestor(
this );
93 m_availableMomentum.setAncestor(
this );
97 a_internalPoPs, a_styles,
hasFission( ),
true );
98 m_outputChannel->setAncestor(
this );
102 m_RutherfordScatteringPresent =
true;
103 m_onlyRutherfordScatteringPresent =
true;
112 if( m_ENDL_C == 20 ) {
114 if(
product->particle( ).ID( ) ==
"H1" ) m_ENDL_C = 21;
116 else if( m_ENDL_C == 22 ) {
118 if(
product->particle( ).ID( ) ==
"H2" ) m_ENDL_C = 35;
123 Form const &QForm = *(m_outputChannel->Q( ).get<Form>( 0 ));
124 switch( QForm.
type( ) ) {
137 throw Exception(
"Reaction::Reaction: unsupported Q form " + QForm.
label( ) );
141 if( _Q <= 0.0 ) _Q = 0.0;
150 if( m_crossSection.has( griddedCrossSection.
label( ) ) ) {
152 m_crossSectionThreshold =
grid[ys1d.
start( )];
155 if( m_crossSectionThreshold == 0.0 ) {
156 m_crossSectionThreshold = m_QThreshold;
159 if( m_twoBodyThreshold > 0.0 ) m_twoBodyThreshold = m_crossSectionThreshold;
168 if( m_outputChannel !=
nullptr )
delete m_outputChannel;
182 if( m_decayPositronium ) {
184 std::set<std::string> ids;
185 m_outputChannel->productIDs( ids, a_particles, a_transportablesOnly );
186 for(
auto iterId = ids.begin( ); iterId != ids.end( ); ++iterId ) {
188 a_ids.insert( *iterId );
192 m_outputChannel->productIDs( a_ids, a_particles, a_transportablesOnly );
212 return( m_outputChannel->maximumLegendreOrder( a_smr, a_settings, a_temperatureInfo, a_productID ) );
231 if( m_decayPositronium ) {
234 vector += m_outputChannel->multiGroupMultiplicity( a_smr, a_settings, a_temperatureInfo, a_productID );
248 if( m_ENDF_MT == 18 )
return(
true );
249 if( m_ENDF_MT == 19 )
return(
true );
250 if( m_ENDF_MT == 20 )
return(
true );
251 if( m_ENDF_MT == 21 )
return(
true );
252 if( m_ENDF_MT == 38 )
return(
true );
265 m_outputChannel = a_outputChannel;
278 m_crossSection.modifiedMultiGroupElasticForTNSL( a_maximumTNSL_MultiGroupIndex );
279 m_availableEnergy.modifiedMultiGroupElasticForTNSL( a_maximumTNSL_MultiGroupIndex );
280 m_availableMomentum.modifiedMultiGroupElasticForTNSL( a_maximumTNSL_MultiGroupIndex );
281 m_outputChannel->modifiedMultiGroupElasticForTNSL( a_maximumTNSL_MultiGroupIndex );
333 if(
hasFission( ) || m_isPhotoAtomicIncoherentScattering )
return(
false );
335 return( m_outputChannel->areAllProductsTracked( a_particles ) );
355 a_settings.
form( a_smr, m_crossSection, a_temperatureInfo,
"cross section", a_label ) );
356 if( form !=
nullptr ) vector = form->
data( );
376 if( m_decayPositronium )
return(
Vector { 0 } );
378 return( m_outputChannel->multiGroupQ( a_smr, a_settings, a_temperatureInfo, a_final ) );
397 std::size_t a_order )
const {
401 if( m_decayPositronium ) {
405 std::map<std::string, GIDI::Transporting::Particle>
const &particles = a_particles.
particles( );
406 std::map<std::string, GIDI::Transporting::Particle>::const_iterator particle = particles.find(
PoPI::IDs::photon );
409 Matrix matrix2( productionCrossSection.
size( ), productionCrossSection.
size( ) );
411 for( std::size_t i1 = 0; i1 < productionCrossSection.
size( ); ++i1 ) {
412 matrix2.
set( i1,
static_cast<std::size_t
>( multiGroupIndexFromEnergy ), productionCrossSection[i1] );
418 matrix += m_outputChannel->multiGroupProductMatrix( a_smr, a_settings, a_temperatureInfo, a_particles, a_productID, a_order );
461 if( form !=
nullptr ) vector = form->
data( );
463 if( m_decayPositronium )
464 vector -= m_outputChannel->multiGroupQ( a_smr, a_settings, a_temperatureInfo,
false );
486 if( m_decayPositronium ) {
489 vector += m_outputChannel->multiGroupAverageEnergy( a_smr, a_settings, a_temperatureInfo, a_productID );
512 std::map<std::string, Transporting::Particle>
const &products = a_particles.
particles( );
523 for( std::map<std::string, Transporting::Particle>::const_iterator iter = products.begin( ); iter != products.end( ); ++iter ) {
527 for( std::size_t index = 0; index <
availableEnergy.size( ); ++index ) {
528 if( std::fabs( vector[index] ) < std::fabs( 1e-14 *
availableEnergy[index] ) ) vector[index] = 0.0;
550 if( form !=
nullptr ) vector = form->
data( );
570 if( !m_isPairProduction ) vector += m_outputChannel->multiGroupAverageMomentum( a_smr, a_settings, a_temperatureInfo, a_productID );
592 std::map<std::string, Transporting::Particle>
const &products = a_particles.
particles( );
599 for( std::map<std::string, Transporting::Particle>::const_iterator iter = products.begin( ); iter != products.end( ); ++iter ) {
621 Styles::TemperatureInfo const &a_temperatureInfo, std::string
const &a_productID, std::string
const &a_projectileID )
const {
638 if( m_outputChannel !=
nullptr ) m_outputChannel->delayedNeutronProducts( a_delayedNeutronProducts );
650 if( m_outputChannel !=
nullptr ) m_outputChannel->incompleteParticles( a_settings, a_incompleteParticles );
667 double &a_productGain,
bool a_ignoreIncompleteParticles )
const {
669 a_productEnergy = 0.0;
670 a_productMomentum = 0.0;
675 if( m_outputChannel !=
nullptr )
676 m_outputChannel->continuousEnergyProductData( a_settings, a_particleID, a_energy, a_productEnergy, a_productMomentum, a_productGain,
677 a_ignoreIncompleteParticles );
694 std::vector<double>
const &a_energies, std::size_t a_offset, std::vector<double> &a_productEnergies, std::vector<double> &a_productMomenta,
695 std::vector<double> &a_productGains,
bool a_ignoreIncompleteParticles )
const {
699 if( m_outputChannel !=
nullptr )
700 m_outputChannel->mapContinuousEnergyProductData( a_settings, a_particleID, a_energies, a_offset, a_productEnergies,
701 a_productMomenta, a_productGains, a_ignoreIncompleteParticles );
732 if( offset1->
size( ) == 0 ) {
733 if( slope1->size( ) == 0 ) {
734 if( a_offset ==
nullptr )
delete offset1;
735 if( a_slope ==
nullptr )
delete slope1;
739 if( a_offset ==
nullptr )
delete offset1;
741 else if( slope1->size( ) == 0 ) {
743 if( a_slope ==
nullptr )
delete slope1;
749 if( domainMin != slope1->domainMin( ) )
throw Exception(
"GIDI::Reaction::modifyCrossSection: offset and slope domainMins differ." );
750 if( domainMax != slope1->domainMax( ) )
throw Exception(
"GIDI::Reaction::modifyCrossSection: offset and slope domainMaxs differ." );
755 m_crossSection.findInstanceOfTypeInLineage( styles, temperatureInfos[0].heatedCrossSection( ),
GIDI_XYs1dChars ) );
756 if( xys1d ==
nullptr )
throw Exception(
"GIDI::Reaction::modifyCrossSection: could not find XYs1d cross section." );
759 if( a_offset ==
nullptr )
delete offset1;
760 if( a_slope ==
nullptr )
delete slope1;
764 double crossSectionDomainMax = xys1d->
domainMax( );
766 if( crossSectionDomainMax < domainMax ) domainMax = crossSectionDomainMax;
770 if( a_offset ==
nullptr )
delete offset1;
771 if( a_slope ==
nullptr )
delete slope1;
773 for(
auto temperatureInfo = temperatureInfos.begin( ); temperatureInfo != temperatureInfos.end( ); ++temperatureInfo ) {
775 m_crossSection.findInstanceOfTypeInLineage( styles, temperatureInfo->heatedCrossSection( ),
GIDI_XYs1dChars ) );
779 xys1dSliced = (*temp);
788 for( index1 = 0, p1 = ptwXY->
points; index1 < length; ++index1, ++p1 ) {
789 if( p1->
x < domainMin )
continue;
790 if( p1->
x >= domainMax ) {
791 if( ( p1->
x != domainMax ) || ( p1->
x != crossSectionDomainMax ) )
break;
797 std::vector<double> &Ys = ys1d->
Ys( );
799 nf_Buffer<double>
const &
grid = griddedCrossSection.
grid( ).
values( );
800 std::size_t start = ys1d->
start( ), size = ys1d->
size( ), index2;
801 for( index2 = 0; index2 < size; ++index2, ++start ) {
802 double xValue =
grid[start];
804 if( xValue < domainMin )
continue;
805 if( xValue >= domainMax ) {
806 if( ( xValue != domainMax ) || ( xValue != crossSectionDomainMax ) )
break;
808 Ys[index2] = modified.
evaluate( xValue );
839 if( styles.
find( heatedMultiGroupLabel ) == styles.
end( ) )
return;
847 double energies[2] = { groupBoundaries[0], groupBoundaries.back( ) };
848 double fluxValues[2] = { 1.0, 1.0 };
850 flux.addFluxOrder( flux_order );
853 calculateMultiGroupData( a_protare, a_temperatureInfo, heatedMultiGroupLabel, multiGroupCalulationInformation );
873 std::vector<double> flatValues { multiGroup[0], 1.0, multiGroup[multiGroup.size( ) - 1], 1.0 };
883 if( m_outputChannel !=
nullptr )
884 m_outputChannel->calculateMultiGroupData( a_protare, a_temperatureInfo, a_heatedMultiGroupLabel, a_multiGroupCalulationInformation, *crossSectionXYs1d );
897 std::string attributes;
904 m_doubleDifferentialCrossSection.toXMLList( a_writeInfo, indent2 );
905 m_crossSection.toXMLList( a_writeInfo, indent2 );
906 if( m_outputChannel !=
nullptr ) m_outputChannel->toXMLList( a_writeInfo, indent2 );
907 m_availableEnergy.toXMLList( a_writeInfo, indent2 );
908 m_availableMomentum.toXMLList( a_writeInfo, indent2 );
925 int MT1_50ToC[] = { 1, 10, -3, 11, -5, 0, 0, 0, 0, -10,
926 32, 0, 0, 0, 0, 12, 13, 15, 15, 15,
927 15, 26, 36, 33, -25, 0, -27, 20, 27, -30,
928 0, 22, 24, 25, -35, -36, 14, 15, 0, 0,
929 29, 16, 0, 17, 34, 0, 0, 0, 0 };
930 int MT100_200ToC[] = { -101, 46, 40, 41, 42, 44, 45, 37, -109, 0,
931 18, 48, -113, -114, 19, 39, 47, 0, 0, 0,
932 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
933 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
934 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
935 0, -152, -153, -154, 43, -156, -157, 23, 31, -160,
936 -161, -162, -163, -164, -165, -166, -167, -168, -169, -170,
937 -171, -172, -173, -174, -175, -176, -177, -178, -179, -180,
938 -181, -182, -183, -184, -185, -186, -187, -188, 28, -190,
939 -191, -192, 38, -194, -195, -196, -197, -198, -199, -200 };
946 if( ENDF_MT > 1572 )
return( 1 );
948 *ENDL_C = MT1_50ToC[ENDF_MT - 1]; }
949 else if( ENDF_MT <= 91 ) {
951 if( ENDF_MT != 91 ) *ENDL_S = 1; }
952 else if( ( ENDF_MT > 100 ) && ( ENDF_MT <= 200 ) ) {
953 *ENDL_C = MT100_200ToC[ENDF_MT - 101]; }
954 else if( ( ENDF_MT == 452 ) || ( ENDF_MT == 455 ) || ( ENDF_MT == 456 ) || ( ENDF_MT == 458 ) ) {
956 if( ENDF_MT == 455 ) *ENDL_S = 7; }
957 else if( ( ENDF_MT >= 502 ) && ( ENDF_MT <= 572 ) ) {
958 if( ENDF_MT == 502 ) {
960 else if( ENDF_MT == 504 ) {
962 else if( ( ENDF_MT >= 515 ) && ( ENDF_MT <= 517 ) ) {
964 else if( ENDF_MT == 522 ) {
966 else if( ( ENDF_MT >= 534 ) && ( ENDF_MT <= 572 ) ) {
968 else if( ENDF_MT >= 600 ) {
969 if( ENDF_MT < 650 ) {
971 if( ENDF_MT != 649 ) *ENDL_S = 1; }
972 else if( ENDF_MT < 700 ) {
974 if( ENDF_MT != 699 ) *ENDL_S = 1; }
975 else if( ENDF_MT < 750 ) {
977 if( ENDF_MT != 749 ) *ENDL_S = 1; }
978 else if( ENDF_MT < 800 ) {
980 if( ENDF_MT != 799 ) *ENDL_S = 1; }
981 else if( ENDF_MT < 850 ) {
983 if( ENDF_MT != 849 ) *ENDL_S = 1; }
984 else if( ( ENDF_MT >= 875 ) && ( ENDF_MT <= 891 ) ) {
986 if( ENDF_MT != 891 ) *ENDL_S = 1; }
987 else if( ( ENDF_MT >= 1534 ) && (ENDF_MT <= 1572 ) ) {
G4ThreadLocal T * G4GeomSplitter< T >::offset
#define GIDI_crossSectionChars
#define GIDI_nuclearPlusInterferenceChars
#define GIDI_ENDF_MT_Chars
#define GIDI_griddedCrossSectionStyleChars
#define GIDI_availableMomentumChars
#define GIDI_outputChannelChars
#define GIDI_orphanProductChars
#define GIDI_RutherfordScatteringChars
#define GIDI_reactionChars
#define GIDI_fissionGenreChars
#define GIDI_availableEnergyChars
#define GIDI_doubleDifferentialCrossSectionChars
#define GIDI_topLevelChars
#define GIDI_CoulombPlusNuclearElasticChars
#define PoPI_electronMass_MeV_c2
ParseMode parseMode() const
bool decayPositronium() const
Vector const & data() const
double evaluate(double a_x1) const
ptwXYPoints const * ptwXY() const
XYs1d domainSlice(double a_domainMin, double a_domainMax, bool a_fill) const
XYs1d * asXYs1d(bool a_asLinlin, double a_accuray, double a_lowerEps, double a_upperEps) const
static XYs1d * makeConstantXYs1d(Axes const &a_axes, double a_domainMin, double a_domainMax, double a_value)
std::vector< double > const & Ys() const
std::size_t start() const
nf_Buffer< double > const & values() const
void set(std::size_t a_row, std::size_t a_column, double a_value)
std::string const & ID() const
virtual Styles::Suite & styles()=0
virtual double thresholdFactor() const =0
ParticleInfo const & projectile() const
bool areAllProductsTracked(Transporting::Particles const &a_particles) const
friend class ProtareSingle
Matrix multiGroupFissionMatrix(LUPI::StatusMessageReporting &a_smr, Transporting::MG const &a_settings, Styles::TemperatureInfo const &a_temperatureInfo, Transporting::Particles const &a_particles, std::size_t a_order) const
bool modifyCrossSection(Functions::XYs1d const *a_offset, Functions::XYs1d const *a_slope, bool a_updateMultiGroup=false)
Vector multiGroupQ(LUPI::StatusMessageReporting &a_smr, Transporting::MG const &a_settings, Styles::TemperatureInfo const &a_temperatureInfo, bool a_final) const
Vector multiGroupAvailableEnergy(LUPI::StatusMessageReporting &a_smr, Transporting::MG const &a_settings, Styles::TemperatureInfo const &a_temperatureInfo) const
Vector multiGroupAvailableMomentum(LUPI::StatusMessageReporting &a_smr, Transporting::MG const &a_settings, Styles::TemperatureInfo const &a_temperatureInfo) const
void recalculateMultiGroupData(ProtareSingle const *a_protare, Styles::TemperatureInfo const &a_temperatureInfo)
void continuousEnergyProductData(Transporting::Settings const &a_settings, std::string const &a_particleID, double a_energy, double &a_productEnergy, double &a_productMomentum, double &a_productGain, bool a_ignoreIncompleteParticles) const
void toXMLList(GUPI::WriteInfo &a_writeInfo, std::string const &a_indent="") const
bool modifiedCrossSection(Functions::XYs1d const *a_offset, Functions::XYs1d const *a_slope)
Reaction(int a_ENDF_MT, std::string const &a_fissionGenre)
Vector multiGroupDepositionMomentum(LUPI::StatusMessageReporting &a_smr, Transporting::MG const &a_settings, Styles::TemperatureInfo const &a_temperatureInfo, Transporting::Particles const &a_particles) const
int maximumLegendreOrder(LUPI::StatusMessageReporting &a_smr, Transporting::MG const &a_settings, Styles::TemperatureInfo const &a_temperatureInfo, std::string const &a_productID) const
void mapContinuousEnergyProductData(Transporting::Settings const &a_settings, std::string const &a_particleID, std::vector< double > const &a_energies, std::size_t a_offset, std::vector< double > &a_productEnergies, std::vector< double > &a_productMomenta, std::vector< double > &a_productGains, bool a_ignoreIncompleteParticles) const
Vector multiGroupCrossSection(LUPI::StatusMessageReporting &a_smr, Transporting::MG const &a_settings, Styles::TemperatureInfo const &a_temperatureInfo, std::string const &a_label="") const
void calculateMultiGroupData(ProtareSingle const *a_protare, Styles::TemperatureInfo const &a_temperatureInfo, std::string const &a_heatedMultiGroupLabel, MultiGroupCalulationInformation const &a_multiGroupCalulationInformation)
void setOutputChannel(OutputChannel *a_outputChannel)
Matrix multiGroupProductMatrix(LUPI::StatusMessageReporting &a_smr, Transporting::MG const &a_settings, Styles::TemperatureInfo const &a_temperatureInfo, Transporting::Particles const &a_particles, std::string const &a_productID, std::size_t a_order) const
void modifiedMultiGroupElasticForTNSL(std::map< std::string, std::size_t > const &a_maximumTNSL_MultiGroupIndex)
void incompleteParticles(Transporting::Settings const &a_settings, std::set< std::string > &a_incompleteParticles) const
Vector multiGroupAverageEnergy(LUPI::StatusMessageReporting &a_smr, Transporting::MG const &a_settings, Styles::TemperatureInfo const &a_temperatureInfo, std::string const &a_productID) const
GUPI::Ancestry * findInAncestry3(std::string const &a_item)
void productIDs(std::set< std::string > &a_ids, Transporting::Particles const &a_particles, bool a_transportablesOnly) const
Component & availableEnergy()
Vector multiGroupDepositionEnergy(LUPI::StatusMessageReporting &a_smr, Transporting::MG const &a_settings, Styles::TemperatureInfo const &a_temperatureInfo, Transporting::Particles const &a_particles) const
Vector multiGroupGain(LUPI::StatusMessageReporting &a_smr, Transporting::MG const &a_settings, Styles::TemperatureInfo const &a_temperatureInfo, std::string const &a_productID, std::string const &a_projectileID) const
void delayedNeutronProducts(DelayedNeutronProducts &a_delayedNeutronProducts) const
Vector multiGroupAverageMomentum(LUPI::StatusMessageReporting &a_smr, Transporting::MG const &a_settings, Styles::TemperatureInfo const &a_temperatureInfo, std::string const &a_productID) const
Vector multiGroupMultiplicity(LUPI::StatusMessageReporting &a_smr, Transporting::MG const &a_settings, Styles::TemperatureInfo const &a_temperatureInfo, std::string const &a_productID) const
std::string const & label() const
Grid const & grid() const
std::vector< double > groupBoundaries(std::string const &a_ID) const
PhysicalQuantity const & temperature() const
std::string const & heatedMultiGroup() const
std::string const & heatedCrossSection() const
std::vector< iterator > findAllOfMoniker(std::string const &a_moniker)
T * get(std::size_t a_Index)
iterator find(std::string const &a_label, bool a_convertLazyParsingHelperForm=false)
Styles::Suite const * styles()
Form const * form(LUPI::StatusMessageReporting &a_smr, GIDI::Suite const &a_suite, Styles::TemperatureInfo const &a_temperatureInfo, std::string a_dataType, std::string const &a_label="") const
std::map< std::string, Particle > & particles()
bool zeroDepositionIfAllProductsTracked() const
void setMoniker(std::string const &a_moniker)
void setAncestor(Ancestry *a_ancestor)
std::string const & moniker() const
void addNodeEnder(std::string const &a_moniker)
std::string incrementalIndent(std::string const &indent)
void addNodeStarter(std::string const &indent, std::string const &a_moniker, std::string const &a_attributes="")
std::string addAttribute(std::string const &a_name, std::string const &a_value) const
Node child(const char *name) const
std::vector< Styles::TemperatureInfo > TemperatureInfos
Form * parseCrossSectionSuite(Construction::Settings const &a_construction, Suite *parent, HAPI::Node const &a_node, SetupInfo &a_setupInfo, PoPI::Database const &a_pop, PoPI::Database const &a_internalPoPs, std::string const &a_name, Styles::Suite const *a_styles)
@ incoherentPhotonScattering
void calculate1dMultiGroupDataInComponent(ProtareSingle const *a_protare, std::string const &a_heatedMultiGroupLabel, MultiGroupCalulationInformation const &a_multiGroupCalulationInformation, Component &a_component, Functions::XYs1d const &a_crossSection)
Form * parseAvailableSuite(Construction::Settings const &a_construction, Suite *a_parent, HAPI::Node const &a_node, SetupInfo &a_setupInfo, PoPI::Database const &a_pops, PoPI::Database const &a_internalPoPs, std::string const &a_name, Styles::Suite const *a_styles)
Form * parseDoubleDifferentialCrossSectionSuite(Construction::Settings const &a_construction, Suite *a_parent, HAPI::Node const &a_node, SetupInfo &a_setupInfo, PoPI::Database const &a_pops, PoPI::Database const &a_internalPoPs, std::string const &a_name, Styles::Suite const *a_styles)
int ENDL_CFromENDF_MT(int ENDF_MT, int *ENDL_C, int *ENDL_S)
std::string intToString(int a_value)
std::vector< DelayedNeutronProduct > DelayedNeutronProducts
bool compareSpecialParticleIDs(std::string const &a_id1, std::string const &a_id2)
@ ptwXY_interpolationLinLin
struct ptwXYPoints_s ptwXYPoints
int64_t ptwXY_length(statusMessageReporting *smr, ptwXYPoints *ptwXY)
struct ptwXYPoint_s ptwXYPoint
static std::string const anti
static std::string const photon
static std::string const neutron
static std::string const electron