1302 std::size_t a_reactionsToExcludeOffset,
bool a_allowFixedGrid ) :
1304 m_interaction( a_protare.
interaction( ).c_str( ) ),
1306 m_hasURR_probabilityTables( false ),
1307 m_URR_domainMin( -1.0 ),
1308 m_URR_domainMax( -1.0 ),
1309 m_domainHash( a_domainHash ),
1313 m_projectileMultiGroupBoundaries( 0 ),
1314 m_projectileMultiGroupBoundariesCollapsed( 0 ),
1316 m_orphanProducts( 0 ),
1318 m_heatedCrossSections( ),
1319 m_heatedMultigroupCrossSections( ) {
1325 std::set<std::string> incompleteParticles;
1326 a_protare.incompleteParticles( a_settings, incompleteParticles );
1327 for( auto particle = a_particles.particles( ).begin( ); particle != a_particles.particles( ).end( ); ++particle ) {
1328 if( incompleteParticles.count( particle->first ) != 0 ) {
1329 std::string message =
"Requested particle '" + particle->first +
"' is incomplete in '" + a_protare.realFileName( ) +
"'.";
1330 if( a_settings.throwOnError( ) ) {
1331 throw std::runtime_error( message.c_str( ) ); }
1333 smr_setReportError2p( a_smr.smr( ), 0, 0, message.c_str( ) );
1339 SetupInfo setupInfo( *
this, a_protare, a_pops, pops );
1341 setupInfo.m_GRIN_continuumGammas = a_protare.GRIN_continuumGammas2( );
1344 for( std::map<std::string, GIDI::Transporting::Particle>::const_iterator particle = a_particles.particles( ).begin( ); particle != a_particles.particles( ).end( ); ++particle ) {
1345 setupInfo.m_particleIntids[particle->first] =
MCGIDI_popsIntid( pops, particle->first );
1346 setupInfo.m_particleIndices[particle->first] =
MCGIDI_popsIndex( a_pops, particle->first );
1350 particles.
add( particle->second );
1354 multiGroupSettings.setThrowOnError( a_settings.throwOnError( ) );
1356 setupInfo.m_distributionLabel = a_temperatureInfos[0].griddedCrossSection( );
1358 a_settings.styles( &a_protare.
styles( ) );
1360 switch( a_settings.crossSectionLookupMode( ) ) {
1362 m_continuousEnergy =
true;
1365 m_continuousEnergy =
false;
1373 throw std::runtime_error(
"ProtareSingle::ProtareSingle: invalid lookupMode" );
1375 m_fixedGrid = a_allowFixedGrid && ( a_protare.
projectile( ).ID( ) ==
PoPI::IDs::photon ) && ( a_settings.fixedGridPoints( ).size( ) > 0 );
1377 setupNuclideGammaBranchStateInfos( setupInfo, a_protare, a_settings.makePhotonEmissionProbabilitiesOne( ),
1378 a_settings.zeroNuclearLevelEnergyWidth( ) );
1384 GIDI::Suite
const *transportables =
nullptr;
1385 if( setupInfo.m_formatVersion.major( ) > 1 ) {
1386 GIDI::Styles::HeatedMultiGroup
const &heatedMultiGroup = *a_protare.
styles( ).
get<GIDI::Styles::HeatedMultiGroup>( a_settings.label( ) );
1391 if( tags.size( ) != 1 )
throw std::runtime_error(
"MCGIDI::ProtareSingle::ProtareSingle: What is going on here?" );
1392 GIDI::Styles::MultiGroup
const &
multiGroup =
static_cast<GIDI::Styles::MultiGroup
const &
>( **tags[0] );
1393 transportables = &
multiGroup.transportables( );
1397 m_projectileMultiGroupBoundaries =
transportable.groupBoundaries( );
1398 GIDI::Transporting::Particle
const *particle = a_particles.particle( a_protare.
projectile( ).
ID( ) );
1402 std::vector<GIDI::Reaction const *> GIDI_reactions;
1403 std::set<std::string> product_ids;
1404 std::set<std::string> product_ids_transportable;
1405 GIDI::Reaction
const *nuclearPlusCoulombInterferenceReaction =
nullptr;
1406 if( a_settings.nuclearPlusCoulombInterferenceOnly( ) ) nuclearPlusCoulombInterferenceReaction = a_protare.nuclearPlusCoulombInterferenceOnlyReaction( );
1408 for( std::size_t reactionIndex = 0; reactionIndex < a_protare.reactions( ).size( ); ++reactionIndex ) {
1409 if( a_reactionsToExclude.find( reactionIndex + a_reactionsToExcludeOffset ) != a_reactionsToExclude.end( ) )
continue;
1411 GIDI::Reaction
const *GIDI_reaction = a_protare.
reaction( reactionIndex );
1413 if( !GIDI_reaction->
active( ) )
continue;
1415 if( m_continuousEnergy ) {
1418 GIDI::Vector multi_group_cross_section = GIDI_reaction->
multiGroupCrossSection( a_smr, multiGroupSettings, a_temperatureInfos[0] );
1419 GIDI::Vector vector =
GIDI::collapse( multi_group_cross_section, a_settings, a_particles, 0.0 );
1422 for( ; i1 < vector.
size( ); ++i1 )
if( vector[i1] != 0.0 )
break;
1423 if( i1 == vector.
size( ) )
continue;
1425 if( a_settings.ignoreENDF_MT5( ) && ( GIDI_reaction->
ENDF_MT( ) == 5 ) && ( a_reactionsToExclude.size( ) == 0 ) )
continue;
1427 GIDI_reaction->
productIDs( product_ids, particles,
false );
1428 GIDI_reaction->
productIDs( product_ids_transportable, particles,
true );
1431 if( nuclearPlusCoulombInterferenceReaction !=
nullptr ) GIDI_reactions.push_back( nuclearPlusCoulombInterferenceReaction ); }
1433 GIDI_reactions.push_back( GIDI_reaction );
1437 bool zeroReactions = GIDI_reactions.size( ) == 0;
1438 if( zeroReactions ) GIDI_reactions.push_back( a_protare.
reaction( 0 ) );
1441 m_reactions.reserve( GIDI_reactions.size( ) );
1442 for(
auto GIDI_reaction = GIDI_reactions.begin( ); GIDI_reaction != GIDI_reactions.end( ); ++GIDI_reaction ) {
1443 setupInfo.m_reaction = *GIDI_reaction;
1444 setupInfo.m_isPairProduction = (*GIDI_reaction)->isPairProduction( );
1445 setupInfo.m_isPhotoAtomicIncoherentScattering = (*GIDI_reaction)->isPhotoAtomicIncoherentScattering( );
1446 setupInfo.m_initialStateIndex = -1;
1448 setupInfo.m_initialStateIndices[(*GIDI_reaction)->label( )] = setupInfo.m_initialStateIndex;
1449 reaction->updateProtareSingleInfo(
this, m_reactions.size( ) );
1450 m_reactions.push_back( reaction );
1453 std::set<int> product_intids;
1454 std::set<int> product_indices;
1455 for( std::set<std::string>::iterator iter = product_ids.begin( ); iter != product_ids.end( ); ++iter ) {
1459 std::set<int> product_intids_transportable;
1460 std::set<int> product_indices_transportable;
1461 for( std::set<std::string>::iterator iter = product_ids_transportable.begin( ); iter != product_ids_transportable.end( ); ++iter ) {
1465 productIntidsAndIndices( product_intids, product_intids_transportable, product_indices, product_indices_transportable );
1469 m_orphanProducts.reserve( a_protare.orphanProducts( ).size( ) );
1470 std::vector< std::vector<std::size_t> > associatedOrphanProductIndices( m_reactions.size( ) );
1472 for( std::size_t orphanProductIndex = 0; orphanProductIndex < a_protare.orphanProducts( ).size( ); ++orphanProductIndex ) {
1473 GIDI::Reaction
const *GIDI_reaction = a_protare.
orphanProduct( orphanProductIndex );
1477 setupInfo.m_reaction = GIDI_reaction;
1478 Reaction *orphanProductReaction =
new Reaction( *GIDI_reaction, setupInfo, a_settings, particles, a_temperatureInfos );
1479 orphanProductReaction->updateProtareSingleInfo(
this, m_orphanProducts.size( ) );
1480 m_orphanProducts.push_back( orphanProductReaction );
1482 GIDI::Functions::Reference1d
const *reference( GIDI_reaction->
crossSection( ).
get<GIDI::Functions::Reference1d>( 0 ) );
1483 std::string xlink = reference->xlink( );
1484 GUPI::Ancestry
const *ancestry = a_protare.
findInAncestry( xlink );
1485 if( ancestry ==
nullptr )
throw std::runtime_error(
"Could not find xlink for orphan product - 1." );
1487 if( ancestry ==
nullptr )
throw std::runtime_error(
"Could not find xlink for orphan product - 2." );
1490 if( ancestry ==
nullptr )
throw std::runtime_error(
"Could not find xlink for orphan product - 3." );
1492 GIDI::Sums::CrossSectionSum
const *
crossSectionSum =
static_cast<GIDI::Sums::CrossSectionSum
const *
>( ancestry );
1494 for( std::size_t i1 = 0; i1 <
summands.size( ); ++i1 ) {
1495 GIDI::Sums::Summand::Base
const *summand =
summands[i1];
1498 if( ancestry ==
nullptr )
throw std::runtime_error(
"Could not find href for summand - 1." );
1500 if( ancestry ==
nullptr )
throw std::runtime_error(
"Could not find href for summand - 2." );
1502 GIDI::Reaction
const *GIDI_reaction2 =
static_cast<GIDI::Reaction
const *
>( ancestry );
1503 for( std::size_t reactionIndex = 0; reactionIndex < m_reactions.size( ); ++reactionIndex ) {
1504 std::string label( m_reactions[reactionIndex]->label( ).c_str( ) );
1506 if( label == GIDI_reaction2->
label( ) ) {
1507 associatedOrphanProductIndices[reactionIndex].push_back( m_orphanProducts.size( ) - 1 );
1514 for( std::size_t reactionIndex = 0; reactionIndex < m_reactions.size( ); ++reactionIndex ) {
1516 std::size_t size = associatedOrphanProductIndices[reactionIndex].size( );
1518 std::vector<Product *> associatedOrphanProducts;
1519 for( std::size_t index1 = 0; index1 < size; ++index1 ) {
1520 std::size_t associatedOrphanProductIndex = associatedOrphanProductIndices[reactionIndex][index1];
1521 m_orphanProducts[associatedOrphanProductIndex]->addOrphanProductToProductList( associatedOrphanProducts );
1523 reaction->setOrphanProductData( associatedOrphanProductIndices[reactionIndex], associatedOrphanProducts );
1528 std::vector<GIDI::Reaction const *> GIDI_orphanProducts;
1529 for( std::size_t reactionIndex = 0; reactionIndex < a_protare.orphanProducts( ).size( ); ++reactionIndex ) {
1530 GIDI::Reaction
const *GIDI_reaction = a_protare.
orphanProduct( reactionIndex );
1533 GIDI_orphanProducts.push_back( GIDI_reaction );
1536 bool removeContinuousEnergyData =
false;
1537 if( m_continuousEnergy ) {
1538 m_heatedCrossSections.update( a_smr, setupInfo, a_settings, particles, a_domainHash, a_temperatureInfos, GIDI_reactions, GIDI_orphanProducts,
1539 m_fixedGrid, zeroReactions );
1540 m_hasURR_probabilityTables = m_heatedCrossSections.hasURR_probabilityTables( );
1541 m_URR_domainMin = m_heatedCrossSections.URR_domainMin( );
1542 m_URR_domainMax = m_heatedCrossSections.URR_domainMax( ); }
1544 m_heatedMultigroupCrossSections.update( a_smr, a_protare, setupInfo, a_settings, particles, a_temperatureInfos, GIDI_reactions,
1545 GIDI_orphanProducts, zeroReactions, a_reactionsToExclude );
1547 if( ( a_settings.upscatterModelAGroupBoundaries().size( ) > 0 ) ||
1549 removeContinuousEnergyData =
true;
1550 m_heatedCrossSections.update( a_smr, setupInfo, a_settings, particles, a_domainHash, a_temperatureInfos, GIDI_reactions, GIDI_orphanProducts,
1551 m_fixedGrid, zeroReactions );
1556 std::vector<double>
const &upscatterModelAGroupBoundaries = a_settings.upscatterModelAGroupBoundaries( );
1557 if( upscatterModelAGroupBoundaries.size( ) == 0 ) {
1558 GIDI::Styles::Base
const *
style = a_protare.
styles( ).
get<GIDI::Styles::Base>( a_temperatureInfos[0].heatedMultiGroup( ) );
1563 GIDI::Styles::HeatedMultiGroup
const &heatedMultiGroup = *
static_cast<GIDI::Styles::HeatedMultiGroup
const *
>(
style );
1566 m_upscatterModelAGroupEnergies.resize( boundaries.size( ) );
1567 m_upscatterModelAGroupVelocities.resize( boundaries.size( ) );
1568 for( std::size_t i1 = 0; i1 < boundaries.size( ); ++i1 ) {
1569 m_upscatterModelAGroupEnergies[i1] = boundaries[i1];
1570 m_upscatterModelAGroupVelocities[i1] =
MCGIDI_particleBeta( projectileMass( ), boundaries[i1] );
1574 auto upscatterModelACrossSectionForm = a_protare.
multiGroupCrossSection( a_smr, multiGroupSettings, a_temperatureInfos[0],
1575 reactionsToExclude, a_temperatureInfos[0].heatedMultiGroup( ) );
1576 m_upscatterModelACrossSection.
resize( upscatterModelACrossSectionForm.size( ) );
1577 for( std::size_t i1 = 0; i1 < upscatterModelACrossSectionForm.size( ); ++i1 )
1578 m_upscatterModelACrossSection[i1] = upscatterModelACrossSectionForm[i1]; }
1581 m_upscatterModelAGroupEnergies.reserve( upscatterModelAGroupBoundaries.size( ) );
1582 m_upscatterModelAGroupVelocities.reserve( upscatterModelAGroupBoundaries.size( ) );
1583 for(
auto iter = upscatterModelAGroupBoundaries.begin( ); iter != upscatterModelAGroupBoundaries.end( ); ++iter ) {
1584 m_upscatterModelAGroupEnergies.push_back( *iter );
1585 m_upscatterModelAGroupVelocities.push_back(
MCGIDI_particleBeta( projectileMass( ), *iter ) );
1588 GIDI::Transporting::MultiGroup boundaries(
"Model A", upscatterModelAGroupBoundaries );
1590 GIDI::Functions::XYs1d crossSectionXYs1d = m_heatedCrossSections.crossSectionAsGIDI_XYs1d( 0.0 );
1592 GIDI::Transporting::Flux
flux(
"Model A", 0.0 );
1593 std::vector<double> energies,
fluxes;
1594 energies.push_back( upscatterModelAGroupBoundaries[0] );
1595 energies.push_back( upscatterModelAGroupBoundaries.back( ) );
1598 flux.addFluxOrder( GIDI::Transporting::Flux_order( 0, energies, fluxes ) );
1600 GIDI::Vector crossSectionVector =
multiGroupXYs1d( boundaries, crossSectionXYs1d, flux );
1601 m_upscatterModelACrossSection.resize( crossSectionVector.
size( ) );
1602 for( std::size_t index = 0; index < crossSectionVector.
size( ); ++index )
1603 m_upscatterModelACrossSection[index] = crossSectionVector[index];
1605 if( !m_continuousEnergy ) m_multiGroupHash =
MultiGroupHash( m_projectileMultiGroupBoundariesCollapsed );
1609 std::size_t reactionIndex = 0;
1610 for(
auto reactionIter = m_reactions.begin( ); reactionIter != m_reactions.end( ); ++reactionIter, ++reactionIndex ) {
1611 if( (*reactionIter)->ENDF_MT( ) == 2 ) {
1616 = heatedCrossSectionContinuousEnergy->reactionCrossSection( reactionIndex );
1618 Vector<double> const &energies = heatedCrossSectionContinuousEnergy->energies( );
1619 Vector<MCGIDI_FLOAT> const &crossSectionsFloat = heatedReactionCrossSectionContinuousEnergy->crossSections( );
1621 std::size_t index = 0;
1622 for(
auto iter = crossSectionsFloat.begin( ); iter != crossSectionsFloat.end( ); ++iter, ++index )
1623 crossSections[index] = *iter;
1627 reaction->setModelDBRC_data( modelDBRC_data );
1632 if( removeContinuousEnergyData ) {
1633 m_heatedCrossSections.clear( );
1974 std::size_t vectorSize;
1982 m_domainHash.serialize( a_buffer, a_mode );
1989 m_multiGroupHash.serialize( a_buffer, a_mode );
1991 vectorSize = m_nuclideGammaBranchStateInfos.size( );
1992 int vectorSizeInt = (int) vectorSize;
1994 vectorSize = (std::size_t) vectorSizeInt;
1997 m_nuclideGammaBranchStateInfos.resize( vectorSize, &(workingBuffer->
m_placement) );
1998 for( std::size_t vectorIndex = 0; vectorIndex < vectorSize; ++vectorIndex ) {
2009 a_buffer.
m_placement += m_nuclideGammaBranchStateInfos.internalSize();
2012 for( std::size_t vectorIndex = 0; vectorIndex < vectorSize; ++vectorIndex ) {
2013 m_nuclideGammaBranchStateInfos[vectorIndex]->serialize( *workingBuffer, a_mode );
2016 vectorSize = m_branches.size( );
2017 vectorSizeInt = (int) vectorSize;
2019 vectorSize = (std::size_t) vectorSizeInt;
2022 m_branches.resize( vectorSize, &(workingBuffer->
m_placement) );
2023 for( std::size_t vectorIndex = 0; vectorIndex < vectorSize; ++vectorIndex ) {
2034 a_buffer.
m_placement += m_branches.internalSize();
2037 for( std::size_t vectorIndex = 0; vectorIndex < vectorSize; ++vectorIndex ) {
2038 m_branches[vectorIndex]->serialize( *workingBuffer, a_mode );
2041 vectorSize = m_reactions.size( );
2042 vectorSizeInt = (int) vectorSize;
2044 vectorSize = (std::size_t) vectorSizeInt;
2047 m_reactions.resize( vectorSize, &(workingBuffer->
m_placement) );
2048 for( std::size_t vectorIndex = 0; vectorIndex < vectorSize; ++vectorIndex ) {
2054 m_reactions[vectorIndex] =
new Reaction;
2059 a_buffer.
m_placement += m_reactions.internalSize();
2062 for( std::size_t vectorIndex = 0; vectorIndex < vectorSize; ++vectorIndex ) {
2063 m_reactions[vectorIndex]->serialize( *workingBuffer, a_mode );
2064 m_reactions[vectorIndex]->updateProtareSingleInfo(
this, vectorIndex );
2067 vectorSize = m_orphanProducts.size( );
2068 vectorSizeInt = (int) vectorSize;
2070 vectorSize = (std::size_t) vectorSizeInt;
2073 m_orphanProducts.resize( vectorSize, &(workingBuffer->
m_placement) );
2074 for( std::size_t vectorIndex = 0; vectorIndex < vectorSize; ++vectorIndex ) {
2080 m_orphanProducts[vectorIndex] =
new Reaction;
2086 a_buffer.
m_placement += m_orphanProducts.internalSize( );
2090 for( std::size_t vectorIndex = 0; vectorIndex < vectorSize; ++vectorIndex ) {
2091 m_orphanProducts[vectorIndex]->serialize( *workingBuffer, a_mode );
2092 m_orphanProducts[vectorIndex]->updateProtareSingleInfo(
this, vectorIndex );
2096 for(
auto reactionIter = m_reactions.begin( ); reactionIter != m_reactions.end( ); ++reactionIter ) {
2097 (*reactionIter)->addOrphanProductToProductList( m_orphanProducts );
2104 m_heatedCrossSections.serialize( *workingBuffer, a_mode );
2105 m_heatedMultigroupCrossSections.serialize( *workingBuffer, a_mode );