Geant4 11.4.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
MCGIDI_reaction.cc
Go to the documentation of this file.
1/*
2# <<BEGIN-copyright>>
3# Copyright 2019, Lawrence Livermore National Security, LLC.
4# This file is part of the gidiplus package (https://github.com/LLNL/gidiplus).
5# gidiplus is licensed under the MIT license (see https://opensource.org/licenses/MIT).
6# SPDX-License-Identifier: MIT
7# <<END-copyright>>
8*/
9
10#include "MCGIDI.hpp"
11
12namespace MCGIDI {
13
14/*! \class Reaction
15 * Class representing a **GNDS** <**reaction**> node with only data needed for Monte Carlo transport.
16 */
17
18/* *********************************************************************************************************//**
19 * Default constructor used when broadcasting a Reaction as needed by MPI or GPUs.
20 ***********************************************************************************************************/
21
23 m_protareSingle( nullptr ),
24 m_reactionIndex( MCGIDI_nullReaction ),
25 m_GIDI_reactionIndex( MCGIDI_nullReaction ),
26 m_label( ),
27 m_ENDF_MT( 0 ),
28 m_ENDL_C( 0 ),
29 m_ENDL_S( 0 ),
30 m_initialStateIndex( -1 ),
31 m_neutronIndex( -1 ),
32 m_hasFission( false ),
33 m_projectileMass( 0.0 ),
34 m_targetMass( 0.0 ),
35 m_crossSectionThreshold( 0.0 ),
36 m_twoBodyThreshold( 0.0 ),
37 m_hasFinalStatePhotons( false ),
38 m_fissionResiduaIntid( -1 ),
39 m_fissionResiduaIndex( -1 ),
40 m_fissionResiduaUserIndex( -1 ),
41 m_fissionResiduals( GIDI::Construction::FissionResiduals::none ),
42 m_fissionResidualMass( 0.0 ),
43 m_totalDelayedNeutronMultiplicity( nullptr ),
44#ifdef MCGIDI_USE_OUTPUT_CHANNEL
45 m_outputChannel( nullptr ),
46#endif
47
48// GRIN extras:
49 m_GRIN_specialSampleProducts( false ),
50 m_GRIN_inelasticThreshold( 0.0 ),
51 m_GRIN_maximumCaptureIncidentEnergy( 0.0 ),
52 m_GRIN_inelastic( nullptr ),
53 m_GRIN_capture( nullptr ) {
54}
55
56/* *********************************************************************************************************//**
57 * @param a_reaction [in] The GIDI::Reaction whose data is to be used to construct *this*.
58 * @param a_setupInfo [in] Used internally when constructing a Protare to pass information to other constructors.
59 * @param a_settings [in] Used to pass user options to the *this* to instruct it which data are desired.
60 * @param a_particles [in] List of transporting particles and their information (e.g., multi-group boundaries and fluxes).
61 * @param a_temperatureInfos [in] The list of temperature data to extract from *a_protare*.
62 ***********************************************************************************************************/
63
64LUPI_HOST Reaction::Reaction( GIDI::Reaction const &a_reaction, SetupInfo &a_setupInfo, Transporting::MC const &a_settings,
65 GIDI::Transporting::Particles const &a_particles, LUPI_maybeUnused GIDI::Styles::TemperatureInfos const &a_temperatureInfos ) :
66 m_protareSingle( nullptr ),
67 m_reactionIndex( MCGIDI_nullReaction ),
68 m_GIDI_reactionIndex( a_reaction.reactionIndex( ) ),
69 m_label( a_reaction.label( ).c_str( ) ),
70 m_ENDF_MT( a_reaction.ENDF_MT( ) ),
71 m_ENDL_C( a_reaction.ENDL_C( ) ),
72 m_ENDL_S( a_reaction.ENDL_S( ) ),
73 m_initialStateIndex( -1 ),
74 m_neutronIndex( a_setupInfo.m_neutronIndex ),
75 m_hasFission( a_reaction.hasFission( ) ),
76 m_projectileMass( a_setupInfo.m_protare.projectileMass( ) ),
77 m_targetMass( a_setupInfo.m_protare.targetMass( ) ),
78 m_crossSectionThreshold( a_reaction.crossSectionThreshold( ) ),
79 m_twoBodyThreshold( a_reaction.twoBodyThreshold( ) ),
80 m_fissionResiduaIntid( -1 ),
81 m_fissionResiduaIndex( -1 ),
82 m_fissionResiduaUserIndex( -1 ),
83 m_fissionResiduals( GIDI::Construction::FissionResiduals::none ),
84 m_fissionResidualMass( 0.0 ),
85
86// GRIN extras:
87 m_GRIN_specialSampleProducts( false ),
88 m_GRIN_inelasticThreshold( 0.0 ),
89 m_GRIN_maximumCaptureIncidentEnergy( 0.0 ),
90 m_GRIN_inelastic( nullptr ),
91 m_GRIN_capture( nullptr ) {
92
93 a_setupInfo.m_hasFinalStatePhotons = false;
94#ifndef MCGIDI_USE_OUTPUT_CHANNEL
95 OutputChannel *m_outputChannel;
96#endif
97 m_outputChannel = new OutputChannel( a_reaction.outputChannel( ), a_setupInfo, a_settings, a_particles );
98
99 std::set<std::string> product_ids;
100
101 a_reaction.productIDs( product_ids, a_particles, false );
102 m_productIntids.reserve( product_ids.size( ) );
103 m_productIndices.reserve( product_ids.size( ) );
104 m_userProductIndices.reserve( product_ids.size( ) );
105 m_productMultiplicities.reserve( product_ids.size( ) );
106 for( std::set<std::string>::iterator iter = product_ids.begin( ); iter != product_ids.end( ); ++iter ) {
107 m_productIntids.push_back( MCGIDI_popsIntid( a_setupInfo.m_pops, *iter ) );
108 m_productIndices.push_back( static_cast<int>( a_setupInfo.m_popsUser[*iter] ) );
109 m_userProductIndices.push_back( -1 );
110 m_productMultiplicities.push_back( a_reaction.productMultiplicity( *iter ) );
111 }
112
113 product_ids.clear( );
114 a_reaction.productIDs( product_ids, a_particles, true );
115 m_productIntidsTransportable.reserve( product_ids.size( ) );
116 m_productIndicesTransportable.reserve( product_ids.size( ) );
117 m_userProductIndicesTransportable.reserve( product_ids.size( ) );
118 for( std::set<std::string>::iterator iter = product_ids.begin( ); iter != product_ids.end( ); ++iter ) {
119 m_productIntidsTransportable.push_back( MCGIDI_popsIntid( a_setupInfo.m_pops, *iter ) );
120 m_productIndicesTransportable.push_back( static_cast<int>( a_setupInfo.m_popsUser[*iter] ) );
121 m_userProductIndicesTransportable.push_back( -1 );
122 }
123
124 m_hasFinalStatePhotons = a_setupInfo.m_hasFinalStatePhotons;
125 m_fissionResiduals = a_reaction.outputChannel( )->fissionResiduals( );
126 if( m_fissionResiduals == GIDI::Construction::FissionResiduals::ENDL99120 ) {
127 m_fissionResiduaIntid = PoPI::Intids::FissionProductENDL99120;
128 m_fissionResiduaIndex = MCGIDI_popsIndex( a_setupInfo.m_popsUser, PoPI::IDs::FissionProductENDL99120 ); }
129 else if( m_fissionResiduals == GIDI::Construction::FissionResiduals::ENDL99125 ) {
130 m_fissionResiduaIntid = PoPI::Intids::FissionProductENDL99125;
131 m_fissionResiduaIndex = MCGIDI_popsIndex( a_setupInfo.m_popsUser, PoPI::IDs::FissionProductENDL99125 );
132 }
133 m_fissionResidualMass = 117.5 * PoPI_AMU2MeV_c2; // Hardwired for now as MeV. Only used if m_fissionResiduaIntid != -1.
134
135#ifndef MCGIDI_USE_OUTPUT_CHANNEL
136 std::vector<Product *> products;
137 std::vector<DelayedNeutron *> delayedNeutrons;
138 std::vector<Functions::Function1d_d1 *> Qs;
139
140 m_totalDelayedNeutronMultiplicity = nullptr;
141 m_outputChannel->moveProductsEtAlToReaction( products, &m_totalDelayedNeutronMultiplicity, delayedNeutrons, Qs );
142
143 m_products.resize( products.size( ) );
144 for( std::size_t index = 0; index < products.size( ); ++index ) m_products[index] = products[index];
145
146 m_delayedNeutrons.resize( delayedNeutrons.size( ) );
147 for( std::size_t index = 0; index < delayedNeutrons.size( ); ++index ) m_delayedNeutrons[index] = delayedNeutrons[index];
148
149 m_Qs.resize( Qs.size( ) );
150 for( std::size_t index = 0; index < Qs.size( ); ++index ) m_Qs[index] = Qs[index];
151
152 delete m_outputChannel;
153#endif
154
155 GIDI::GRIN::GRIN_continuumGammas const *GRIN_continuumGammas = a_setupInfo.m_GRIN_continuumGammas;
156 if( GRIN_continuumGammas != nullptr ) {
157 if( m_ENDF_MT == 102 ) {
158 if( GRIN_continuumGammas->captureLevelProbabilities( ).size( ) > 0 ) {
159 m_GRIN_specialSampleProducts = true;
160 m_GRIN_maximumCaptureIncidentEnergy = GRIN_continuumGammas->maximumCaptureIncidentEnergy( ).value( );
161 m_GRIN_capture = new GRIN_capture( a_setupInfo, *GRIN_continuumGammas );
162 } }
163 else if( m_ENDF_MT == 91 ) {
164 GIDI::Suite const &inelasticIncidentEnergies = GRIN_continuumGammas->inelasticIncidentEnergies( );
165 if( inelasticIncidentEnergies.size( ) > 0 ) {
166 m_GRIN_specialSampleProducts = true;
167 GIDI::GRIN::InelasticIncidentEnergy const *inelasticIncidentEnergy = inelasticIncidentEnergies.get<GIDI::GRIN::InelasticIncidentEnergy const>( 0 );
168 m_GRIN_inelasticThreshold = inelasticIncidentEnergy->energy( );
169 m_GRIN_inelastic = new GRIN_inelastic( a_setupInfo, *GRIN_continuumGammas );
170 }
171 }
172 }
173}
174
175/* *********************************************************************************************************//**
176 ***********************************************************************************************************/
177
179
180#ifdef MCGIDI_USE_OUTPUT_CHANNEL
181 delete m_outputChannel;
182#else
183 delete m_totalDelayedNeutronMultiplicity;
184 for( auto iter = m_products.begin( ); iter != m_products.end( ); ++iter ) delete *iter;
185 for( auto iter = m_delayedNeutrons.begin( ); iter != m_delayedNeutrons.end( ); ++iter ) delete *iter;
186 for( auto iter = m_Qs.begin( ); iter != m_Qs.end( ); ++iter ) delete *iter;
187#endif
188}
189/* *********************************************************************************************************//**
190 * Returns the Q-value for projectile energy *a_energy*.
191 *
192 * @param a_URR_protareInfos [in] URR information.
193 * @param a_hashIndex [in] Specifies the continuous energy or multi-group index.
194 * @param a_temperature [in] The temperature of the target.
195 * @param a_energy_in [in] The energy of the projectile.
196 ***********************************************************************************************************/
197
198LUPI_HOST_DEVICE double Reaction::finalQ( double a_energy ) const {
199
200#ifdef MCGIDI_USE_OUTPUT_CHANNEL
201 return( m_outputChannel->finalQ( a_energy ) );
202#else
203 double Q = 0.0;
204 for( auto Q_iter = m_Qs.begin( ); Q_iter != m_Qs.end( ); ++Q_iter ) Q += (*Q_iter)->evaluate( a_energy );
205
206 return( Q );
207#endif
208}
209
210/* *********************************************************************************************************//**
211 * Returns the reaction's cross section for target temperature *a_temperature* and projectile energy *a_energy_in*.
212 *
213 * @param a_URR_protareInfos [in] URR information.
214 * @param a_hashIndex [in] Specifies the continuous energy or multi-group index.
215 * @param a_temperature [in] The temperature of the target.
216 * @param a_energy_in [in] The energy of the projectile.
217 ***********************************************************************************************************/
218
219LUPI_HOST_DEVICE double Reaction::crossSection( URR_protareInfos const &a_URR_protareInfos, std::size_t a_hashIndex, double a_temperature, double a_energy_in ) const {
220
221 return( m_protareSingle->reactionCrossSection( m_reactionIndex, a_URR_protareInfos, a_hashIndex, a_temperature, a_energy_in, false ) );
222}
223
224/* *********************************************************************************************************//**
225 * Returns the reaction's cross section for target temperature *a_temperature* and projectile energy *a_energy_in*.
226 *
227 * @param a_URR_protareInfos [in] URR information.
228 * @param a_temperature [in] The temperature of the target.
229 * @param a_energy_in [in] The energy of the projectile.
230 ***********************************************************************************************************/
231
232LUPI_HOST_DEVICE double Reaction::crossSection( URR_protareInfos const &a_URR_protareInfos, double a_temperature, double a_energy_in ) const {
233
234 return( m_protareSingle->reactionCrossSection( m_reactionIndex, a_URR_protareInfos, a_temperature, a_energy_in ) );
235}
236
237/* *********************************************************************************************************//**
238 * Returns the reaction's cross section as a pointer to a GIDI::Functions::XYs1d instance.
239 *
240 * @returns A GIDI::Functions::XYs1d instance.
241 ***********************************************************************************************************/
242
244
245 return( m_protareSingle->heatedCrossSections( ).reactionCrossSectionAsGIDI_XYs1d( m_reactionIndex, a_temperature ) );
246}
247
248/* *********************************************************************************************************//**
249 * Returns the multiplicity for outgoing particle with pops index *a_index*. If the multiplicity is energy dependent,
250 * the returned value is -1. For energy dependent multiplicities it is better to use the method **productAverageMultiplicity**.
251 *
252 * @param a_index [in] The PoPs index of the requested particle.
253 *
254 * @return The multiplicity value for the requested particle.
255 ***********************************************************************************************************/
256
258
259 std::size_t i1 = 0;
260
261 for( Vector<int>::iterator iter = m_productIndices.begin( ); iter != m_productIndices.end( ); ++iter, ++i1 ) {
262 if( *iter == a_index ) return( m_productMultiplicities[i1] );
263 }
264
265 return( 0 );
266}
267/* *********************************************************************************************************//**
268 * Returns the multiplicity for outgoing particle with pops intid *a_intid*. If the multiplicity is energy dependent,
269 * the returned value is -1. For energy dependent multiplicities it is better to use the method **productAverageMultiplicity**.
270 *
271 * @param a_intid [in] The PoPs intid of the requested particle.
272 *
273 * @return The multiplicity value for the requested particle.
274 ***********************************************************************************************************/
275
277
278 std::size_t i1 = 0;
279
280 for( Vector<int>::iterator iter = m_productIntids.begin( ); iter != m_productIntids.end( ); ++iter, ++i1 ) {
281 if( *iter == a_intid ) return( m_productMultiplicities[i1] );
282 }
283
284 return( 0 );
285}
286
287/* *********************************************************************************************************//**
288 * Returns the energy dependent multiplicity for outgoing particle with pops index *a_index*. The returned value may not
289 * be an integer. Energy dependent multiplicity mainly occurs for photons and fission neutrons.
290 *
291 * @param a_index [in] The PoPs index of the requested particle.
292 * @param a_projectileEnergy [in] The energy of the projectile.
293 *
294 * @return The multiplicity value for the requested particle.
295 ***********************************************************************************************************/
296
297LUPI_HOST_DEVICE double Reaction::productAverageMultiplicity( int a_index, double a_projectileEnergy ) const {
298
299 double multiplicity = 0.0;
300
301 if( m_crossSectionThreshold > a_projectileEnergy ) return( multiplicity );
302
303 std::size_t i1 = 0;
304 for( Vector<int>::iterator iter = m_productIndices.begin( ); iter != m_productIndices.end( ); ++iter, ++i1 ) {
305 if( *iter == a_index ) {
306 multiplicity = m_productMultiplicities[i1];
307 break;
308 }
309 }
310
311 if( multiplicity < 0 ) {
312#ifdef MCGIDI_USE_OUTPUT_CHANNEL
313 multiplicity = m_outputChannel->productAverageMultiplicity( a_index, a_projectileEnergy );
314#else
315 multiplicity = 0.0;
316 for( auto productIter = m_products.begin( ); productIter != m_products.end( ); ++productIter ) {
317 multiplicity += (*productIter)->productAverageMultiplicity( a_index, a_projectileEnergy );
318 }
319
320 if( ( m_totalDelayedNeutronMultiplicity != nullptr ) && ( a_index == m_neutronIndex ) ) {
321 multiplicity += m_totalDelayedNeutronMultiplicity->evaluate( a_projectileEnergy );
322 }
323#endif
324 }
325
326 return( multiplicity );
327}
328
329/* *********************************************************************************************************//**
330 * Returns the energy dependent multiplicity for outgoing particle with pops intid *a_intid*. The returned value may not
331 * be an integer. Energy dependent multiplicity mainly occurs for photons and fission neutrons.
332 *
333 * @param a_intid [in] The PoPs intid of the requested particle.
334 * @param a_projectileEnergy [in] The energy of the projectile.
335 *
336 * @return The multiplicity value for the requested particle.
337 ***********************************************************************************************************/
338
339LUPI_HOST_DEVICE double Reaction::productAverageMultiplicityViaIntid( int a_intid, double a_projectileEnergy ) const {
340
341 double multiplicity = 0.0;
342
343 if( m_crossSectionThreshold > a_projectileEnergy ) return( multiplicity );
344
345 std::size_t i1 = 0;
346 for( Vector<int>::iterator iter = m_productIntids.begin( ); iter != m_productIntids.end( ); ++iter, ++i1 ) {
347 if( *iter == a_intid ) {
348 multiplicity = m_productMultiplicities[i1];
349 break;
350 }
351 }
352
353 if( multiplicity < 0 ) {
354#ifdef MCGIDI_USE_OUTPUT_CHANNEL
355 multiplicity = m_outputChannel->productAverageMultiplicityViaIntid( a_intid, a_projectileEnergy );
356#else
357 multiplicity = 0.0;
358 for( auto productIter = m_products.begin( ); productIter != m_products.end( ); ++productIter ) {
359 multiplicity += (*productIter)->productAverageMultiplicityViaIntid( a_intid, a_projectileEnergy );
360 }
361
362 if( ( m_totalDelayedNeutronMultiplicity != nullptr ) && ( a_intid == PoPI::Intids::neutron ) ) {
363 multiplicity += m_totalDelayedNeutronMultiplicity->evaluate( a_projectileEnergy );
364 }
365#endif
366 }
367
368 return( multiplicity );
369}
370
371/* *********************************************************************************************************//**
372 * Updates the m_userParticleIndex to *a_userParticleIndex* for all particles with PoPs index *a_particleIndex*.
373 *
374 * @param a_particleIndex [in] The PoPs index of the particle whose user index is to be set.
375 * @param a_userParticleIndex [in] The particle index specified by the user.
376 ***********************************************************************************************************/
377
378LUPI_HOST void Reaction::setUserParticleIndex( int a_particleIndex, int a_userParticleIndex ) {
379
380#ifdef MCGIDI_USE_OUTPUT_CHANNEL
381 m_outputChannel->setUserParticleIndex( a_particleIndex, a_userParticleIndex );
382#else
383 for( auto productIter = m_products.begin( ); productIter != m_products.end( ); ++productIter ) {
384 (*productIter)->setUserParticleIndex( a_particleIndex, a_userParticleIndex );
385 }
386
387 for( auto iter = m_delayedNeutrons.begin( ); iter != m_delayedNeutrons.end( ); ++iter )
388 (*iter)->setUserParticleIndex( a_particleIndex, a_userParticleIndex );
389#endif
390
391 for( std::size_t i1 = 0; i1 < m_productIndices.size( ); ++i1 ) {
392 if( m_productIndices[i1] == a_particleIndex ) m_userProductIndices[i1] = a_userParticleIndex;
393 }
394
395 for( std::size_t i1 = 0; i1 < m_productIndicesTransportable.size( ); ++i1 ) {
396 if( m_productIndicesTransportable[i1] == a_particleIndex ) m_userProductIndicesTransportable[i1] = a_userParticleIndex;
397 }
398
399 if( a_particleIndex == m_fissionResiduaIndex ) m_fissionResiduaUserIndex = a_userParticleIndex;
400
401 if( m_GRIN_capture != nullptr ) m_GRIN_capture->setUserParticleIndex( a_particleIndex, a_userParticleIndex );
402 if( m_GRIN_inelastic != nullptr ) m_GRIN_inelastic->setUserParticleIndex( a_particleIndex, a_userParticleIndex );
403}
404
405/* *********************************************************************************************************//**
406 * Updates the m_userParticleIndex to *a_userParticleIndex* for all particles with PoPs index *a_particleIntid*.
407 *
408 * @param a_particleIndex [in] The PoPs intid of the particle whose user intid is to be set.
409 * @param a_userParticleIndex [in] The particle index specified by the user.
410 ***********************************************************************************************************/
411
412LUPI_HOST void Reaction::setUserParticleIndexViaIntid( int a_particleIntid, int a_userParticleIndex ) {
413
414#ifdef MCGIDI_USE_OUTPUT_CHANNEL
415 m_outputChannel->setUserParticleIndexViaIntid( a_particleIntid, a_userParticleIndex );
416#else
417 for( auto productIter = m_products.begin( ); productIter != m_products.end( ); ++productIter ) {
418 (*productIter)->setUserParticleIndexViaIntid( a_particleIntid, a_userParticleIndex );
419 }
420
421 for( auto iter = m_delayedNeutrons.begin( ); iter != m_delayedNeutrons.end( ); ++iter )
422 (*iter)->setUserParticleIndexViaIntid( a_particleIntid, a_userParticleIndex );
423#endif
424
425 for( std::size_t i1 = 0; i1 < m_productIntids.size( ); ++i1 ) {
426 if( m_productIntids[i1] == a_particleIntid ) m_userProductIndices[i1] = a_userParticleIndex;
427 }
428
429 for( std::size_t i1 = 0; i1 < m_productIntidsTransportable.size( ); ++i1 ) {
430 if( m_productIntidsTransportable[i1] == a_particleIntid ) m_userProductIndicesTransportable[i1] = a_userParticleIndex;
431 }
432
433 if( a_particleIntid == m_fissionResiduaIntid ) m_fissionResiduaUserIndex = a_userParticleIndex;
434
435 if( m_GRIN_capture != nullptr ) m_GRIN_capture->setUserParticleIndexViaIntid( a_particleIntid, a_userParticleIndex );
436 if( m_GRIN_inelastic != nullptr ) m_GRIN_inelastic->setUserParticleIndexViaIntid( a_particleIntid, a_userParticleIndex );
437}
438
439/* *********************************************************************************************************//**
440 * This method calls the **setModelDBRC_data* method on the first product of *this* with *a_modelDBRC_data*.
441 *
442 * @param a_modelDBRC_data [in] The instance storing data needed to treat the DRRC upscatter mode.
443 ***********************************************************************************************************/
444
446
447#ifdef MCGIDI_USE_OUTPUT_CHANNEL
448 m_outputChannel->setModelDBRC_data( a_modelDBRC_data );
449#else
450 m_products[0]->setModelDBRC_data( a_modelDBRC_data );
451#endif
452}
453
454/* *********************************************************************************************************//**
455 * Adds the associated orphan products of an orphan product reaction to *a_associatedOrphanProducts*.
456 *
457 * @param a_associatedOrphanProducts [in] A list where the associated orphan products are added to.
458 ***********************************************************************************************************/
459
460LUPI_HOST void Reaction::addOrphanProductToProductList( std::vector<Product *> &a_associatedOrphanProducts ) const {
461
462#ifdef MCGIDI_USE_OUTPUT_CHANNEL
463 m_outputChannel->addOrphanProductToProductList( a_associatedOrphanProducts );
464#else
465 for( auto productIter = m_products.begin( ); productIter != m_products.end( ); ++productIter ) {
466 a_associatedOrphanProducts.push_back( *productIter );
467 }
468#endif
469}
470
471/* *********************************************************************************************************//**
472 * Adds the associated orphan products of an orphan product reaction to *a_associatedOrphanProducts*.
473 *
474 * @param a_associatedOrphanProducts [in] A list where the associated orphan products are added to.
475 ***********************************************************************************************************/
476
478
479#ifdef MCGIDI_USE_OUTPUT_CHANNEL
480 m_outputChannel->addOrphanProductToProductList( a_associatedOrphanProducts );
481#else
482 for( auto productIter = m_products.begin( ); productIter != m_products.end( ); ++productIter ) {
483 a_associatedOrphanProducts.push_back( *productIter );
484 }
485#endif
486}
487
488/* *********************************************************************************************************//**
489 * Adds the associated orphan products of an orphan product to *a_associatedOrphanProducts*.
490 *
491 * @param a_associatedOrphanProducts [in] A list where the associated orphan products are added to.
492 ***********************************************************************************************************/
493
495
496 for( auto associatedOrphanProductIndex = m_associatedOrphanProductIndices.begin( );
497 associatedOrphanProductIndex != m_associatedOrphanProductIndices.end( ); ++associatedOrphanProductIndex ) {
498 Reaction *orphanProduct = a_orphanProducts[*associatedOrphanProductIndex];
499 orphanProduct->addOrphanProductToProductList( m_associatedOrphanProducts );
500 }
501}
502
503/* *********************************************************************************************************//**
504 * Adds the contents of **a_associatedOrphanProductIndcies** and **a_associatedOrphanProducts** to this instance.
505 *
506 * @param a_associatedOrphanProductIndcies [in] The list of indices of the orphanProduct reaction that make up the product in **a_associatedOrphanProducts**.
507 * @param a_associatedOrphanProducts [in] The list of pointers to the associated orphan products.
508 ***********************************************************************************************************/
509
510LUPI_HOST void Reaction::setOrphanProductData( std::vector<std::size_t> const &a_associatedOrphanProductIndcies,
511 std::vector<Product *> const &a_associatedOrphanProducts ) {
512
513 m_associatedOrphanProductIndices.reserve( a_associatedOrphanProductIndcies.size( ) );
514 for( auto iter = a_associatedOrphanProductIndcies.begin( ); iter != a_associatedOrphanProductIndcies.end( ); ++iter )
515 m_associatedOrphanProductIndices.push_back( *iter );
516
517 m_associatedOrphanProducts.reserve( a_associatedOrphanProducts.size( ) );
518 for( auto iter = a_associatedOrphanProducts.begin( ); iter != a_associatedOrphanProducts.end( ); ++iter )
519 m_associatedOrphanProducts.push_back( *iter );
520}
521
522/* *********************************************************************************************************//**
523 * This method serializes *this* for broadcasting as needed for MPI and GPUs. The method can count the number of required
524 * bytes, pack *this* or unpack *this* depending on *a_mode*.
525 *
526 * @param a_buffer [in] The buffer to read or write data to depending on *a_mode*.
527 * @param a_mode [in] Specifies the action of this method.
528 ***********************************************************************************************************/
529
531
532 DATA_MEMBER_SIZE_T( m_GIDI_reactionIndex, a_buffer, a_mode );
533 DATA_MEMBER_STRING( m_label, a_buffer, a_mode );
534 DATA_MEMBER_INT( m_ENDF_MT, a_buffer, a_mode );
535 DATA_MEMBER_INT( m_ENDL_C, a_buffer, a_mode );
536 DATA_MEMBER_INT( m_ENDL_S, a_buffer, a_mode );
537 DATA_MEMBER_INT( m_initialStateIndex, a_buffer, a_mode );
538 DATA_MEMBER_INT( m_neutronIndex, a_buffer, a_mode );
539 DATA_MEMBER_CAST( m_hasFission, a_buffer, a_mode, bool );
540 DATA_MEMBER_DOUBLE( m_projectileMass, a_buffer, a_mode );
541 DATA_MEMBER_DOUBLE( m_targetMass, a_buffer, a_mode );
542 DATA_MEMBER_DOUBLE( m_crossSectionThreshold, a_buffer, a_mode );
543 DATA_MEMBER_DOUBLE( m_twoBodyThreshold, a_buffer, a_mode );
544 DATA_MEMBER_CAST( m_hasFinalStatePhotons, a_buffer, a_mode, bool );
545 DATA_MEMBER_INT( m_fissionResiduaIntid, a_buffer, a_mode );
546 DATA_MEMBER_INT( m_fissionResiduaIndex, a_buffer, a_mode );
547 DATA_MEMBER_INT( m_fissionResiduaUserIndex, a_buffer, a_mode );
548 serializeFissionResiduals( m_fissionResiduals, a_buffer, a_mode );
549 DATA_MEMBER_DOUBLE( m_fissionResidualMass, a_buffer, a_mode );
550
551 DATA_MEMBER_VECTOR_INT( m_productIntids, a_buffer, a_mode );
552 DATA_MEMBER_VECTOR_INT( m_productIndices, a_buffer, a_mode );
553 DATA_MEMBER_VECTOR_INT( m_userProductIndices, a_buffer, a_mode );
554 DATA_MEMBER_VECTOR_INT( m_productMultiplicities, a_buffer, a_mode );
555 DATA_MEMBER_VECTOR_INT( m_productIntidsTransportable, a_buffer, a_mode );
556 DATA_MEMBER_VECTOR_INT( m_productIndicesTransportable, a_buffer, a_mode );
557 DATA_MEMBER_VECTOR_INT( m_userProductIndicesTransportable, a_buffer, a_mode );
558
559#ifdef MCGIDI_USE_OUTPUT_CHANNEL
560 bool haveChannel = m_outputChannel != nullptr;
561 DATA_MEMBER_CAST( haveChannel, a_buffer, a_mode, bool );
562 if( haveChannel ) {
563 if( a_mode == LUPI::DataBuffer::Mode::Unpack ) {
564 if (a_buffer.m_placement != nullptr) {
565 m_outputChannel = new(a_buffer.m_placement) OutputChannel();
566 a_buffer.incrementPlacement( sizeof(OutputChannel));
567 }
568 else {
569 m_outputChannel = new OutputChannel();
570 } }
571 else if( a_mode == LUPI::DataBuffer::Mode::Memory ) {
572 a_buffer.incrementPlacement( sizeof( OutputChannel ) );
573 }
574 m_outputChannel->serialize( a_buffer, a_mode );
575 }
576#else
577 serializeQs( a_buffer, a_mode, m_Qs );
578 serializeProducts( a_buffer, a_mode, m_products );
579 m_totalDelayedNeutronMultiplicity = serializeFunction1d( a_buffer, a_mode, m_totalDelayedNeutronMultiplicity );
580 serializeDelayedNeutrons( a_buffer, a_mode, m_delayedNeutrons );
581#endif
582
583 DATA_MEMBER_VECTOR_SIZE_T( m_associatedOrphanProductIndices, a_buffer, a_mode );
584
585 std::size_t vectorSize = m_associatedOrphanProducts.size( );
586 int vectorSizeInt = (int) vectorSize;
587 DATA_MEMBER_INT( vectorSizeInt, a_buffer, a_mode );
588 vectorSize = (std::size_t) vectorSizeInt;
589 if( a_mode == LUPI::DataBuffer::Mode::Unpack ) {
590 m_associatedOrphanProducts.reserve( vectorSize, &a_buffer.m_placement ); }
591 else if( a_mode == LUPI::DataBuffer::Mode::Memory ) {
592 a_buffer.m_placement += m_associatedOrphanProducts.internalSize( );
593 }
594
595 if( a_mode == LUPI::DataBuffer::Mode::Unpack ) {
596 m_protareSingle = nullptr;
597 m_reactionIndex = MCGIDI_nullReaction;
598 }
599
600 DATA_MEMBER_CAST( m_GRIN_specialSampleProducts, a_buffer, a_mode, bool );
601 DATA_MEMBER_DOUBLE( m_GRIN_inelasticThreshold, a_buffer, a_mode );
602 DATA_MEMBER_DOUBLE( m_GRIN_maximumCaptureIncidentEnergy, a_buffer, a_mode );
603
604 if( m_GRIN_specialSampleProducts ) {
605 if( a_mode == LUPI::DataBuffer::Mode::Unpack ) {
606 if( a_buffer.m_placement != nullptr ) {
607 if( m_ENDF_MT == 91 ) {
608 m_GRIN_inelastic = new(a_buffer.m_placement) GRIN_inelastic;
609 a_buffer.incrementPlacement( sizeof( GRIN_inelastic ) ); }
610 else {
611 m_GRIN_capture = new(a_buffer.m_placement) GRIN_capture;
612 a_buffer.incrementPlacement( sizeof( GRIN_capture ) );
613 } }
614 else {
615 if( m_ENDF_MT == 91 ) {
616 m_GRIN_inelastic = new GRIN_inelastic( ); }
617 else {
618 m_GRIN_capture = new GRIN_capture( );
619 }
620 }
621 }
622
623 if( a_mode == LUPI::DataBuffer::Mode::Memory ) {
624 if( m_ENDF_MT == 91 ) {
625 a_buffer.incrementPlacement( sizeof( GRIN_inelastic ) ); }
626 else {
627 a_buffer.incrementPlacement( sizeof( GRIN_capture ) );
628 }
629 }
630
631 if( m_ENDF_MT == 91 ) {
632 m_GRIN_inelastic->serialize( a_buffer, a_mode ); }
633 else {
634 m_GRIN_capture->serialize( a_buffer, a_mode );
635 }
636 }
637}
638
639}
#define DATA_MEMBER_STRING(member, buf, mode)
#define DATA_MEMBER_VECTOR_INT(member, buf, mode)
#define DATA_MEMBER_CAST(member, buf, mode, someType)
#define DATA_MEMBER_SIZE_T(member, buf, mode)
#define DATA_MEMBER_VECTOR_SIZE_T(member, buf, mode)
#define DATA_MEMBER_DOUBLE(member, buf, mode)
#define DATA_MEMBER_INT( member, buf, mode)
#define LUPI_HOST_DEVICE
#define LUPI_HOST
#define LUPI_maybeUnused
#define MCGIDI_nullReaction
Definition MCGIDI.hpp:64
#define PoPI_AMU2MeV_c2
Definition PoPI.hpp:30
Suite const & inelasticIncidentEnergies() const
Definition GIDI.hpp:3853
Suite const & captureLevelProbabilities() const
Definition GIDI.hpp:3854
PhysicalQuantity const & maximumCaptureIncidentEnergy() const
Definition GIDI.hpp:3851
Construction::FissionResiduals fissionResiduals() const
Definition GIDI.hpp:4122
double value() const
Definition GIDI.hpp:728
int productMultiplicity(std::string const &a_productID) const
Definition GIDI.hpp:4318
OutputChannel * outputChannel() const
Definition GIDI.hpp:4307
void productIDs(std::set< std::string > &a_ids, Transporting::Particles const &a_particles, bool a_transportablesOnly) const
T * get(std::size_t a_Index)
Definition GIDI.hpp:2642
std::size_t size() const
Definition GIDI.hpp:2591
LUPI_HOST_DEVICE void incrementPlacement(std::size_t a_delta)
LUPI_HOST_DEVICE void serialize(LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode)
LUPI_HOST_DEVICE double finalQ(double a_x1) const
LUPI_HOST void setUserParticleIndexViaIntid(int a_particleIntid, int a_userParticleIndex)
LUPI_HOST_DEVICE double productAverageMultiplicity(int a_index, double a_projectileEnergy) const
LUPI_HOST void setUserParticleIndex(int a_particleIndex, int a_userParticleIndex)
LUPI_HOST void moveProductsEtAlToReaction(std::vector< Product * > &a_products, Functions::Function1d **a_totalDelayedNeutronMultiplicity, std::vector< DelayedNeutron * > &a_delayedNeutrons, std::vector< Functions::Function1d_d1 * > &a_Qs)
LUPI_HOST_DEVICE double productAverageMultiplicityViaIntid(int a_intid, double a_projectileEnergy) const
LUPI_HOST void setModelDBRC_data(Sampling::Upscatter::ModelDBRC_data *a_modelDBRC_data)
LUPI_HOST void addOrphanProductToProductList(std::vector< Product * > &a_associatedOrphanProducts) const
LUPI_HOST_DEVICE double productAverageMultiplicity(int a_index, double a_projectileEnergy) const
LUPI_HOST_DEVICE int productMultiplicity(int a_index) const
LUPI_HOST_DEVICE void serialize(LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode)
LUPI_HOST void setOrphanProductData(std::vector< std::size_t > const &a_associatedOrphanProductIndcies, std::vector< Product * > const &a_associatedOrphanProducts)
LUPI_HOST void setUserParticleIndexViaIntid(int a_particleIntid, int a_userParticleIndex)
LUPI_HOST_DEVICE int productMultiplicityViaIntid(int a_intid) const
LUPI_HOST void setUserParticleIndex(int a_particleIndex, int a_userParticleIndex)
LUPI_HOST_DEVICE ~Reaction()
LUPI_HOST_DEVICE double finalQ(double a_energy) const
LUPI_HOST_DEVICE double crossSection(URR_protareInfos const &a_URR_protareInfos, std::size_t a_hashIndex, double a_temperature, double a_energy) const
LUPI_HOST_DEVICE double productAverageMultiplicityViaIntid(int a_intid, double a_projectileEnergy) const
LUPI_HOST_DEVICE Reaction()
LUPI_HOST void setModelDBRC_data(Sampling::Upscatter::ModelDBRC_data *a_modelDBRC_data)
LUPI_HOST GIDI::Functions::XYs1d crossSectionAsGIDI_XYs1d(double a_temperature) const
GIDI::GRIN::GRIN_continuumGammas const * m_GRIN_continuumGammas
Definition MCGIDI.hpp:280
bool m_hasFinalStatePhotons
Definition MCGIDI.hpp:275
PoPI::Database const & m_popsUser
Definition MCGIDI.hpp:256
PoPI::Database const & m_pops
Definition MCGIDI.hpp:257
LUPI_HOST_DEVICE void push_back(const T &dataElem)
LUPI_HOST_DEVICE void reserve(std::size_t s, char **address=nullptr, bool mem_flag=CPU_MEM)
std::vector< Styles::TemperatureInfo > TemperatureInfos
Definition GIDI.hpp:3440
Definition GIDI.hpp:32
Simple C++ string class, useful as replacement for std::string if this cannot be used,...
Definition MCGIDI.hpp:43
LUPI_HOST int MCGIDI_popsIntid(PoPI::Database const &a_pops, std::string const &a_ID)
LUPI_HOST_DEVICE void serializeFissionResiduals(GIDI::Construction::FissionResiduals &a_fissionResiduals, LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode)
LUPI_HOST_DEVICE void serializeDelayedNeutrons(LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode, Vector< DelayedNeutron * > &a_delayedNeutrons)
LUPI_HOST_DEVICE void serializeQs(LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode, Vector< Functions::Function1d_d1 * > &a_Qs)
LUPI_HOST int MCGIDI_popsIndex(PoPI::Database const &a_pops, std::string const &a_ID)
LUPI_HOST_DEVICE Functions::Function1d * serializeFunction1d(LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode, Functions::Function1d *a_function1d)
LUPI_HOST_DEVICE void serializeProducts(LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode, Vector< Product * > &a_products)
static std::string const FissionProductENDL99125
Definition PoPI.hpp:172
static std::string const FissionProductENDL99120
Definition PoPI.hpp:171
static int constexpr FissionProductENDL99120
Definition PoPI.hpp:180
static int constexpr neutron
Definition PoPI.hpp:177
static int constexpr FissionProductENDL99125
Definition PoPI.hpp:181