Geant4 11.4.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
GIDI_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 <cmath>
11
12#include "GIDI.hpp"
13#include <HAPI.hpp>
14
15namespace GIDI {
16
17/* *********************************************************************************************************//**
18 * Parses a <**reaction**> node.
19 ***********************************************************************************************************/
20
21Reaction::Reaction( int a_ENDF_MT, std::string const &a_fissionGenre ) :
23 m_reactionIndex( 0 ),
24 m_active( true ),
25 m_ENDF_MT( a_ENDF_MT ),
26 m_fissionGenre( a_fissionGenre ),
27 m_QThreshold( 0.0 ),
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 ),
36 m_doubleDifferentialCrossSection( GIDI_doubleDifferentialCrossSectionChars, GIDI_labelChars ),
37 m_crossSection( GIDI_crossSectionChars, GIDI_labelChars ),
38 m_availableEnergy( GIDI_availableEnergyChars, GIDI_labelChars ),
39 m_availableMomentum( GIDI_availableMomentumChars, GIDI_labelChars ),
40 m_outputChannel( ) {
41
43
44 ENDL_CFromENDF_MT( m_ENDF_MT, &m_ENDL_C, &m_ENDL_S );
45}
46
47/* *********************************************************************************************************//**
48 * Parses a <**reaction**> node.
49 *
50 * @param a_construction [in] Used to pass user options to the constructor.
51 * @param a_node [in] The reaction HAPI::Node to be parsed and used to construct the reaction.
52 * @param a_setupInfo [in] Information create my the Protare constructor to help in parsing.
53 * @param a_pops [in] The *external* PoPI::Database instance used to get particle indices and possibly other particle information.
54 * @param a_internalPoPs [in] The *internal* PoPI::Database instance used to get particle indices and possibly other particle information.
55 * This is the <**PoPs**> node under the <**reactionSuite**> node.
56 * @param a_protare [in] The GIDI::Protare this reaction belongs to.
57 * @param a_styles [in] The <**styles**> node under the <**reactionSuite**> node.
58 ***********************************************************************************************************/
59
60Reaction::Reaction( Construction::Settings const &a_construction, HAPI::Node const &a_node, SetupInfo &a_setupInfo, PoPI::Database const &a_pops,
61 PoPI::Database const &a_internalPoPs, Protare const &a_protare, Styles::Suite const *a_styles ) :
62 Form( a_node, a_setupInfo, FormType::reaction ),
63 m_active( true ),
64 m_ENDF_MT( a_node.attribute_as_int( GIDI_ENDF_MT_Chars ) ),
65 m_ENDL_C( 0 ),
66 m_ENDL_S( 0 ),
67 m_fissionGenre( a_node.attribute_as_string( GIDI_fissionGenreChars ) ),
68 m_QThreshold( 0.0 ),
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 ),
77 m_doubleDifferentialCrossSection( a_construction, GIDI_doubleDifferentialCrossSectionChars, GIDI_labelChars, a_node, a_setupInfo, a_pops,
78 a_internalPoPs, parseDoubleDifferentialCrossSectionSuite, a_styles ),
79 m_crossSection( a_construction, GIDI_crossSectionChars, GIDI_labelChars, a_node, a_setupInfo, a_pops, a_internalPoPs, parseCrossSectionSuite, a_styles ),
80 m_availableEnergy( a_construction, GIDI_availableEnergyChars, GIDI_labelChars, a_node, a_setupInfo, a_pops, a_internalPoPs, parseAvailableSuite, a_styles ),
81 m_availableMomentum( a_construction, GIDI_availableMomentumChars, GIDI_labelChars, a_node, a_setupInfo, a_pops, a_internalPoPs, parseAvailableSuite, a_styles ),
82 m_outputChannel( nullptr ) {
83
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 )
88 m_isPhotoAtomicIncoherentScattering = m_doubleDifferentialCrossSection.get<Form>( 0 )->type( ) == FormType::incoherentPhotonScattering;
89
90 m_doubleDifferentialCrossSection.setAncestor( this );
91 m_crossSection.setAncestor( this );
92 m_availableEnergy.setAncestor( this );
93 m_availableMomentum.setAncestor( this );
94
95 a_setupInfo.m_outputChannelLevel = 0;
96 m_outputChannel = new OutputChannel( a_construction, a_node.child( GIDI_outputChannelChars ), a_setupInfo, a_pops,
97 a_internalPoPs, a_styles, hasFission( ), true );
98 m_outputChannel->setAncestor( this );
99
100 HAPI::Node const CoulombPlusNuclearElastic = a_node.child( GIDI_doubleDifferentialCrossSectionChars ).first_child( );
101 if( CoulombPlusNuclearElastic.name( ) == GIDI_CoulombPlusNuclearElasticChars ) { // Check RutherfordScattering.
102 m_RutherfordScatteringPresent = true;
103 m_onlyRutherfordScatteringPresent = true;
104 for( HAPI::Node child = CoulombPlusNuclearElastic.first_child( ); !child.empty( ); child.to_next_sibling( ) ) {
105 if( child.name( ) != GIDI_RutherfordScatteringChars ) m_onlyRutherfordScatteringPresent = false;
106 if( child.name( ) == GIDI_nuclearPlusInterferenceChars ) m_nuclearPlusInterferencePresent = true;
107 }
108 }
109
110 ENDL_CFromENDF_MT( m_ENDF_MT, &m_ENDL_C, &m_ENDL_S );
111 if( a_setupInfo.m_isENDL_C_9 ) m_ENDL_C = 9;
112 if( m_ENDL_C == 20 ) {
113 Product *product = m_outputChannel->products( ).get<Product>( 0 );
114 if( product->particle( ).ID( ) == "H1" ) m_ENDL_C = 21;
115 }
116 else if( m_ENDL_C == 22 ) {
117 Product *product = m_outputChannel->products( ).get<Product>( 0 );
118 if( product->particle( ).ID( ) == "H2" ) m_ENDL_C = 35;
119 }
120
121 if( ( a_construction.parseMode( ) != Construction::ParseMode::outline ) && ( a_construction.parseMode( ) != Construction::ParseMode::readOnly ) ) {
122 double _Q = 0.0;
123 Form const &QForm = *(m_outputChannel->Q( ).get<Form>( 0 ));
124 switch( QForm.type( ) ) {
125 case FormType::constant1d : {
126 Functions::Constant1d const &constant1d = static_cast<Functions::Constant1d const &>( QForm );
127 _Q = constant1d.value( );
128 break; }
129 case FormType::XYs1d : {
130 Functions::XYs1d const &xys1d = static_cast<Functions::XYs1d const &>( QForm );
131 _Q = xys1d.evaluate( 0.0 );
132 break; }
133 case FormType::gridded1d : { // Should be a special reaction (e.g., summed multi-group data) and can be ignored.
134 _Q = 0.0;
135 break; }
136 default :
137 throw Exception( "Reaction::Reaction: unsupported Q form " + QForm.label( ) );
138 }
139 m_twoBodyThreshold = -_Q * a_protare.thresholdFactor( );
140 _Q *= -1;
141 if( _Q <= 0.0 ) _Q = 0.0;
142 m_QThreshold = a_protare.thresholdFactor( ) * _Q;
143
144 if( _Q > 0.0 ) { // Try to do a better job determining m_crossSectionThreshold.
145 std::vector<Suite::const_iterator> monikers = a_protare.styles( ).findAllOfMoniker( GIDI_griddedCrossSectionStyleChars );
146 if( ( a_construction.parseMode( ) != Construction::ParseMode::multiGroupOnly ) && ( monikers.size( ) > 0 ) ) {
147 Styles::GriddedCrossSection const &griddedCrossSection = static_cast<Styles::GriddedCrossSection const &>( **monikers[0] );
148 Grid grid = griddedCrossSection.grid( );
149
150 if( m_crossSection.has( griddedCrossSection.label( ) ) ) {
151 Functions::Ys1d const &ys1d = static_cast<Functions::Ys1d const &>( *m_crossSection.get<Functions::Ys1d>( griddedCrossSection.label( ) ) );
152 m_crossSectionThreshold = grid[ys1d.start( )];
153 }
154 }
155 if( m_crossSectionThreshold == 0.0 ) { // Should also check 'evaluate' style before using m_QThreshold as a default.
156 m_crossSectionThreshold = m_QThreshold;
157 }
158 }
159 if( m_twoBodyThreshold > 0.0 ) m_twoBodyThreshold = m_crossSectionThreshold;
160 }
161}
162
163/* *********************************************************************************************************//**
164 ***********************************************************************************************************/
165
167
168 if( m_outputChannel != nullptr ) delete m_outputChannel;
169}
170
171/* *********************************************************************************************************//**
172 * Fills in a std::set with a unique list of all product indices produced by this reaction.
173 * If a_transportablesOnly is true, only transportable product indices are return.
174 *
175 * @param a_ids [out] The unique list of product indices.
176 * @param a_particles [in] The list of particles to be transported.
177 * @param a_transportablesOnly [in] If true, only transportable product indices are added in the list.
178 ***********************************************************************************************************/
179
180void Reaction::productIDs( std::set<std::string> &a_ids, Transporting::Particles const &a_particles, bool a_transportablesOnly ) const {
181
182 if( m_decayPositronium ) {
183 std::string electronAnti( PoPI::IDs::electron + PoPI::IDs::anti );
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 ) {
187 if( ( *iterId == PoPI::IDs::electron ) || ( *iterId == electronAnti ) ) continue;
188 a_ids.insert( *iterId );
189 }
190 a_ids.insert( PoPI::IDs::photon ); }
191 else {
192 m_outputChannel->productIDs( a_ids, a_particles, a_transportablesOnly );
193 }
194}
195
196/* *********************************************************************************************************//**
197 * Determines the maximum Legredre order present in the multi-group transfer matrix for a give product for a give label. Inspects all
198 * products produced by this reaction.
199 *
200 * @param a_smr [Out] If errors are not to be thrown, then the error is reported via this instance.
201 * @param a_settings [in] Specifies the requested label.
202 * @param a_temperatureInfo [in] Specifies the temperature and labels use to lookup the requested data.
203 * @param a_productID [in] Particle id of the requested product.
204 *
205 * @return The maximum Legredre order. If no transfer matrix data are present for the requested product, -1 is returned.
206 ***********************************************************************************************************/
207
209 Styles::TemperatureInfo const &a_temperatureInfo, std::string const &a_productID ) const {
210
211 if( m_isPairProduction && ( a_productID == PoPI::IDs::photon ) ) return( 0 );
212 return( m_outputChannel->maximumLegendreOrder( a_smr, a_settings, a_temperatureInfo, a_productID ) );
213}
214
215/* *********************************************************************************************************//**
216 * Returns the multi-group, total multiplicity for the requested label for the requested product. This is a cross section weighted multiplicity.
217 *
218 * @param a_smr [Out] If errors are not to be thrown, then the error is reported via this instance.
219 * @param a_settings [in] Specifies the requested label.
220 * @param a_temperatureInfo [in] Specifies the temperature and labels use to lookup the requested data.
221 * @param a_productID [in] Particle id for the requested product.
222 *
223 * @return The requested multi-group multiplicity as a GIDI::Vector.
224 ***********************************************************************************************************/
225
227 Styles::TemperatureInfo const &a_temperatureInfo, std::string const &a_productID ) const {
228
229 Vector vector( 0 );
230
231 if( m_decayPositronium ) {
232 if( a_productID == PoPI::IDs::photon ) vector += multiGroupCrossSection( a_smr, a_settings, a_temperatureInfo ) * 2; }
233 else {
234 vector += m_outputChannel->multiGroupMultiplicity( a_smr, a_settings, a_temperatureInfo, a_productID );
235 }
236
237 return( vector );
238}
239
240/* *********************************************************************************************************//**
241 * Returns true if at least one output channel contains a fission channel.
242 *
243 * @return true if at least one output channel is a fission channel.
244 ***********************************************************************************************************/
245
246bool Reaction::hasFission( ) const {
247
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 );
253
254 return( false );
255}
256
257/* *********************************************************************************************************//**
258 * Sets *this* reaction's output channel to **a_outputChannel**.
259 *
260 * @param a_outputChannel [in] The output channel to make *this* reaction output channel.
261 ***********************************************************************************************************/
262
264
265 m_outputChannel = a_outputChannel;
266 m_outputChannel->setAncestor( this );
267}
268
269/* *********************************************************************************************************//**
270 * Only for internal use. Called by ProtareTNSL instance to zero the lower energy multi-group data covered by the TNSL ProtareSingle.
271 *
272 * @param a_maximumTNSL_MultiGroupIndex [in] A map that contains labels for heated multi-group data and the last valid group boundary
273 * for the TNSL data for that boundary.
274 ***********************************************************************************************************/
275
276void Reaction::modifiedMultiGroupElasticForTNSL( std::map<std::string,std::size_t> const &a_maximumTNSL_MultiGroupIndex ) {
277
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 );
282}
283
284/* *********************************************************************************************************//**
285 * Used by GUPI::Ancestry to tranverse GNDS nodes. This method returns a pointer to a derived class' a_item member or nullptr if none exists.
286 *
287 * @param a_item [in] The name of the class member whose pointer is to be return.
288 *
289 * @return The pointer to the class member or nullptr if class does not have a member named a_item.
290 ***********************************************************************************************************/
291
292GUPI::Ancestry *Reaction::findInAncestry3( std::string const &a_item ) {
293
294 if( a_item == GIDI_doubleDifferentialCrossSectionChars ) return( &m_doubleDifferentialCrossSection );
295 if( a_item == GIDI_crossSectionChars ) return( &m_crossSection );
296 if( a_item == GIDI_availableEnergyChars ) return( &m_availableEnergy );
297 if( a_item == GIDI_availableMomentumChars ) return( &m_availableMomentum );
298 if( a_item == GIDI_outputChannelChars ) return( m_outputChannel );
299
300 return( nullptr );
301}
302
303/* *********************************************************************************************************//**
304 * Used by GUPI::Ancestry to tranverse GNDS nodes. This method returns a pointer to a derived class' a_item member or nullptr if none exists.
305 *
306 * @param a_item [in] The name of the class member whose pointer is to be return.
307 *
308 * @return The pointer to the class member or nullptr if class does not have a member named a_item.
309 ***********************************************************************************************************/
310
311GUPI::Ancestry const *Reaction::findInAncestry3( std::string const &a_item ) const {
312
313 if( a_item == GIDI_doubleDifferentialCrossSectionChars ) return( &m_doubleDifferentialCrossSection );
314 if( a_item == GIDI_crossSectionChars ) return( &m_crossSection );
315 if( a_item == GIDI_availableEnergyChars ) return( &m_availableEnergy );
316 if( a_item == GIDI_availableMomentumChars ) return( &m_availableMomentum );
317 if( a_item == GIDI_outputChannelChars ) return( m_outputChannel );
318
319 return( nullptr );
320}
321
322/* *********************************************************************************************************//**
323 * Returns **true** if all outgoing particles (i.e., products) are specifed in *a_particles*. That is, the user
324 * will be tracking all products of *this* reaction.
325 *
326 * @param a_particles [in] The list of particles to be transported.
327 *
328 * @return bool.
329 ***********************************************************************************************************/
330
332
333 if( hasFission( ) || m_isPhotoAtomicIncoherentScattering ) return( false );
334
335 return( m_outputChannel->areAllProductsTracked( a_particles ) );
336}
337
338/* *********************************************************************************************************//**
339 * Returns the multi-group, cross section for the requested label the reaction.
340 *
341 * @param a_smr [Out] If errors are not to be thrown, then the error is reported via this instance.
342 * @param a_settings [in] Specifies the requested label.
343 * @param a_temperatureInfo [in] Specifies the temperature and labels use to lookup the requested data.
344 * @param a_label [in] If not an empty string, this is used as the label for the form to return and the *a_temperatureInfo* labels are ignored.
345 *
346 * @return The requested multi-group cross section as a GIDI::Vector.
347 ***********************************************************************************************************/
348
350 Styles::TemperatureInfo const &a_temperatureInfo, std::string const &a_label ) const {
351
352 Vector vector( 0 );
353
354 Functions::Gridded1d const *form = dynamic_cast<Functions::Gridded1d const*>(
355 a_settings.form( a_smr, m_crossSection, a_temperatureInfo, "cross section", a_label ) );
356 if( form != nullptr ) vector = form->data( );
357
358 return( vector );
359}
360
361/* *********************************************************************************************************//**
362 * Returns the multi-group, total Q for the requested label. This is a cross section weighted Q.
363 *
364 * @param a_smr [Out] If errors are not to be thrown, then the error is reported via this instance.
365 * @param a_settings [in] Specifies the requested label.
366 * @param a_temperatureInfo [in] Specifies the temperature and labels use to lookup the requested data.
367 * @param a_final [in] If false, only the Q for the primary reactions are return, otherwise, the Q for the final reactions.
368 * @param a_reactionsToExclude [in] A list of reaction indices that are to be ignored when calculating the Q.
369 *
370 * @return The requested multi-group Q as a GIDI::Vector.
371 ***********************************************************************************************************/
372
374 Styles::TemperatureInfo const &a_temperatureInfo, bool a_final ) const {
375
376 if( m_decayPositronium ) return( Vector { 0 } ); // Special case, returns Q with all 0.0s.
377
378 return( m_outputChannel->multiGroupQ( a_smr, a_settings, a_temperatureInfo, a_final ) );
379}
380
381/* *********************************************************************************************************//**
382 * Returns the multi-group, product matrix for the requested label for the requested product index for the requested Legendre order.
383 * If no data are found, an empty GIDI::Matrix is returned.
384 *
385 * @param a_smr [Out] If errors are not to be thrown, then the error is reported via this instance.
386 * @param a_settings [in] Specifies the requested label and if delayed neutrons should be included.
387 * @param a_temperatureInfo [in] Specifies the temperature and labels use to lookup the requested data.
388 * @param a_particles [in] The list of particles to be transported.
389 * @param a_productID [in] Particle id for the requested product.
390 * @param a_order [in] Requested product matrix, Legendre order.
391 *
392 * @return The requested multi-group product matrix as a GIDI::Matrix.
393 ***********************************************************************************************************/
394
396 Styles::TemperatureInfo const &a_temperatureInfo, Transporting::Particles const &a_particles, std::string const &a_productID,
397 std::size_t a_order ) const {
398
399 Matrix matrix( 0, 0 );
400
401 if( m_decayPositronium ) {
402 if( a_productID == PoPI::IDs::photon ) {
403 if( a_order == 0 ) {
404 Vector productionCrossSection = multiGroupCrossSection( a_smr, a_settings, a_temperatureInfo ) * 2;
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 );
407 GIDI::Transporting::MultiGroup const &multiGroup = particle->second.fineMultiGroup( );
408 int multiGroupIndexFromEnergy = multiGroup.multiGroupIndexFromEnergy( PoPI_electronMass_MeV_c2, true );
409 Matrix matrix2( productionCrossSection.size( ), productionCrossSection.size( ) );
410
411 for( std::size_t i1 = 0; i1 < productionCrossSection.size( ); ++i1 ) {
412 matrix2.set( i1, static_cast<std::size_t>( multiGroupIndexFromEnergy ), productionCrossSection[i1] );
413 }
414 matrix += matrix2;
415 }
416 } }
417 else {
418 matrix += m_outputChannel->multiGroupProductMatrix( a_smr, a_settings, a_temperatureInfo, a_particles, a_productID, a_order );
419 }
420
421 return( matrix );
422}
423
424/* *********************************************************************************************************//**
425 * Like Reaction::multiGroupProductMatrix, but only returns the fission neutron, transfer matrix.
426 *
427 * @param a_smr [Out] If errors are not to be thrown, then the error is reported via this instance.
428 * @param a_settings [in] Specifies the requested label and if delayed neutrons should be included.
429 * @param a_temperatureInfo [in] Specifies the temperature and labels use to lookup the requested data.
430 * @param a_particles [in] The list of particles to be transported.
431 * @param a_order [in] Requested product matrix, Legendre order.
432 *
433 * @return The requested multi-group neutron fission matrix as a GIDI::Matrix.
434 ***********************************************************************************************************/
435
437 Styles::TemperatureInfo const &a_temperatureInfo, Transporting::Particles const &a_particles, std::size_t a_order ) const {
438
439 Matrix matrix( 0, 0 );
440
441 if( hasFission( ) ) matrix += multiGroupProductMatrix( a_smr, a_settings, a_temperatureInfo, a_particles, PoPI::IDs::neutron, a_order );
442 return( matrix );
443}
444
445/* *********************************************************************************************************//**
446 * Returns the multi-group, total available energy for the requested label. This is a cross section weighted available energy.
447 *
448 * @param a_smr [Out] If errors are not to be thrown, then the error is reported via this instance.
449 * @param a_settings [in] Specifies the requested label.
450 * @param a_temperatureInfo [in] Specifies the temperature and labels use to lookup the requested data.
451 *
452 * @return The requested multi-group available energy as a GIDI::Vector.
453 ***********************************************************************************************************/
454
456 Styles::TemperatureInfo const &a_temperatureInfo ) const {
457
458 Vector vector( 0 );
459
460 Functions::Gridded1d const *form = dynamic_cast<Functions::Gridded1d const*>( a_settings.form( a_smr, m_availableEnergy, a_temperatureInfo, "available energy" ) );
461 if( form != nullptr ) vector = form->data( );
462
463 if( m_decayPositronium )
464 vector -= m_outputChannel->multiGroupQ( a_smr, a_settings, a_temperatureInfo, false );
465
466 return( vector );
467}
468
469/* *********************************************************************************************************//**
470 * Returns the multi-group, total average energy for the requested label for the requested product. This is a cross section weighted average energy
471 * summed over all products for this reaction.
472 *
473 * @param a_smr [Out] If errors are not to be thrown, then the error is reported via this instance.
474 * @param a_settings [in] Specifies the requested label.
475 * @param a_temperatureInfo [in] Specifies the temperature and labels use to lookup the requested data.
476 * @param a_productID [in] Particle id for the requested product.
477 *
478 * @return The requested multi-group average energy as a GIDI::Vector.
479 ***********************************************************************************************************/
480
482 Styles::TemperatureInfo const &a_temperatureInfo, std::string const &a_productID ) const {
483
484 Vector vector( 0 );
485
486 if( m_decayPositronium ) {
487 if( a_productID == PoPI::IDs::photon ) vector += multiGroupCrossSection( a_smr, a_settings, a_temperatureInfo ) * 2.0 * PoPI_electronMass_MeV_c2; }
488 else {
489 vector += m_outputChannel->multiGroupAverageEnergy( a_smr, a_settings, a_temperatureInfo, a_productID );
490 }
491
492 return( vector );
493}
494
495/* *********************************************************************************************************//**
496 * Returns the multi-group, total deposition energy for the requested label for *this* reaction. This is a cross section weighted
497 * deposition energy. The deposition energy is calculated by subtracting the average energy from each transportable particle
498 * from the available energy. The list of transportable particles is specified via the list of particle specified in the *a_settings* argument.
499 * This method does not include any photon deposition energy for *this* reaction that is in the **GNDS** orphanProducts node.
500 *
501 * @param a_smr [Out] If errors are not to be thrown, then the error is reported via this instance.
502 * @param a_settings [in] Specifies the requested label and the products that are transported.
503 * @param a_temperatureInfo [in] Specifies the temperature and labels use to lookup the requested data.
504 * @param a_particles [in] The list of particles to be transported.
505 *
506 * @return The requested multi-group deposition energy as a GIDI::Vector.
507 ***********************************************************************************************************/
508
510 Styles::TemperatureInfo const &a_temperatureInfo, Transporting::Particles const &a_particles ) const {
511
512 std::map<std::string, Transporting::Particle> const &products = a_particles.particles( );
513 Vector vector;
514
515 if( moniker( ) != GIDI_orphanProductChars ) {
516 if( ( a_settings.zeroDepositionIfAllProductsTracked( ) ) && areAllProductsTracked( a_particles ) && !m_isPairProduction ) return( vector );
517
518 vector = multiGroupAvailableEnergy( a_smr, a_settings, a_temperatureInfo );
519 }
520
521 Vector availableEnergy( vector );
522
523 for( std::map<std::string, Transporting::Particle>::const_iterator iter = products.begin( ); iter != products.end( ); ++iter ) {
524 vector -= multiGroupAverageEnergy( a_smr, a_settings, a_temperatureInfo, iter->first );
525 }
526
527 for( std::size_t index = 0; index < availableEnergy.size( ); ++index ) { // Check for values that should probably be 0.0.
528 if( std::fabs( vector[index] ) < std::fabs( 1e-14 * availableEnergy[index] ) ) vector[index] = 0.0;
529 }
530
531 return( vector );
532}
533
534/* *********************************************************************************************************//**
535 * Returns the multi-group, total available momentum for the requested label. This is a cross section weighted available momentum.
536 *
537 * @param a_smr [Out] If errors are not to be thrown, then the error is reported via this instance.
538 * @param a_settings [in] Specifies the requested label.
539 * @param a_temperatureInfo [in] Specifies the temperature and labels use to lookup the requested data.
540 *
541 * @return The requested multi-group available momentum as a GIDI::Vector.
542 ***********************************************************************************************************/
543
545 Styles::TemperatureInfo const &a_temperatureInfo ) const {
546
547 Vector vector( 0 );
548
549 Functions::Gridded1d const *form = dynamic_cast<Functions::Gridded1d const*>( a_settings.form( a_smr, m_availableMomentum, a_temperatureInfo, "available momentum" ) );
550 if( form != nullptr ) vector = form->data( );
551
552 return( vector );
553}
554/* *********************************************************************************************************//**
555 * Returns the multi-group, total average momentum for the requested label for the requested product. This is a cross section weighted average momentum.
556 *
557 * @param a_smr [Out] If errors are not to be thrown, then the error is reported via this instance.
558 * @param a_settings [in] Specifies the requested label.
559 * @param a_temperatureInfo [in] Specifies the temperature and labels use to lookup the requested data.
560 * @param a_productID [in] Particle id for the requested product.
561 *
562 * @return The requested multi-group average momentum as a GIDI::Vector.
563 ***********************************************************************************************************/
564
566 Styles::TemperatureInfo const &a_temperatureInfo, std::string const &a_productID ) const {
567
568 Vector vector( 0 );
569
570 if( !m_isPairProduction ) vector += m_outputChannel->multiGroupAverageMomentum( a_smr, a_settings, a_temperatureInfo, a_productID );
571
572 return( vector );
573}
574
575/* *********************************************************************************************************//**
576 * Returns the multi-group, total deposition momentum for the requested label for *this* reaction. This is a cross section
577 * weighted deposition momentum. The deposition momentum is calculated by subtracting the average momentum from each transportable particle
578 * from the available momentum. The list of transportable particles is specified via the list of particle specified in the *a_settings* argument.
579 * This method does not include any photon deposition momentum for *this* reaction that is in the **GNDS** orphanProducts node.
580 *
581 * @param a_smr [Out] If errors are not to be thrown, then the error is reported via this instance.
582 * @param a_settings [in] Specifies the requested label.
583 * @param a_temperatureInfo [in] Specifies the temperature and labels use to lookup the requested data.
584 * @param a_particles [in] The list of particles to be transported.
585 *
586 * @return The requested multi-group deposition momentum as a GIDI::Vector.
587 ***********************************************************************************************************/
588
590 Styles::TemperatureInfo const &a_temperatureInfo, Transporting::Particles const &a_particles ) const {
591
592 std::map<std::string, Transporting::Particle> const &products = a_particles.particles( );
593 Vector vector;
594
595 if( moniker( ) != GIDI_orphanProductChars ) {
596 vector = multiGroupAvailableMomentum( a_smr, a_settings, a_temperatureInfo );
597 }
598
599 for( std::map<std::string, Transporting::Particle>::const_iterator iter = products.begin( ); iter != products.end( ); ++iter ) {
600 vector -= multiGroupAverageMomentum( a_smr, a_settings, a_temperatureInfo, iter->first );
601 }
602
603 return( vector );
604}
605
606/* *********************************************************************************************************//**
607 * Returns the multi-group, gain for the requested particle and label. This is a cross section weighted gain summed over all reactions.
608 * If *a_productID* and *a_projectileID* are the same, then the multi-group cross section is subtracted for the returned value to indicate
609 * that the *a_projectileID* as been absorted.
610 *
611 * @param a_smr [Out] If errors are not to be thrown, then the error is reported via this instance.
612 * @param a_settings [in] Specifies the requested label.
613 * @param a_temperatureInfo [in] Specifies the temperature and labels use to lookup the requested data.
614 * @param a_productID [in] The particle PoPs' id for the whose gain is to be calculated.
615 * @param a_projectileID [in] The particle PoPs' id for the projectile.
616 *
617 * @return The requested multi-group gain as a **GIDI::Vector**.
618 ***********************************************************************************************************/
619
621 Styles::TemperatureInfo const &a_temperatureInfo, std::string const &a_productID, std::string const &a_projectileID ) const {
622
623 Vector vector( multiGroupMultiplicity( a_smr, a_settings, a_temperatureInfo, a_productID ) );
624
625 if( PoPI::compareSpecialParticleIDs( a_productID, a_projectileID ) ) vector -= multiGroupCrossSection( a_smr, a_settings, a_temperatureInfo );
626
627 return( vector );
628}
629
630/* *********************************************************************************************************//**
631 * Appends a DelayedNeutronProduct instance for each delayed neutron in *m_delayedNeutrons*.
632 *
633 * @param a_delayedNeutronProducts [in/out] The list to append the delayed neutrons to.
634 ***********************************************************************************************************/
635
636void Reaction::delayedNeutronProducts( DelayedNeutronProducts &a_delayedNeutronProducts ) const {
637
638 if( m_outputChannel != nullptr ) m_outputChannel->delayedNeutronProducts( a_delayedNeutronProducts );
639}
640
641/* *********************************************************************************************************//**
642 * If *this* has an output channel, this output channel's **incompleteParticles* is called.
643 *
644 * @param a_settings [in] Specifies the requested label.
645 * @param a_incompleteParticles [out] The list of particles whose **completeParticle** method returns *false*.
646 ***********************************************************************************************************/
647
648void Reaction::incompleteParticles( Transporting::Settings const &a_settings, std::set<std::string> &a_incompleteParticles ) const {
649
650 if( m_outputChannel != nullptr ) m_outputChannel->incompleteParticles( a_settings, a_incompleteParticles );
651 if( m_isPairProduction ) a_incompleteParticles.erase( PoPI::IDs::photon ); // Kludge for old processed files.
652}
653
654/* *********************************************************************************************************//**
655 * Returns, via arguments, the average energy and momentum, and gain for product with particle id *a_particleID*.
656 *
657 * @param a_settings [in] Specifies the requested label.
658 * @param a_particleID [in] The particle id of the product.
659 * @param a_energy [in] The energy of the projectile.
660 * @param a_productEnergy [in] The average energy of the product.
661 * @param a_productMomentum [in] The average momentum of the product.
662 * @param a_productGain [in] The gain of the product.
663 * @param a_ignoreIncompleteParticles [in] If *true*, incomplete particles are ignore, otherwise a *throw* is executed.
664 ***********************************************************************************************************/
665
666void Reaction::continuousEnergyProductData( Transporting::Settings const &a_settings, std::string const &a_particleID, double a_energy, double &a_productEnergy, double &a_productMomentum,
667 double &a_productGain, bool a_ignoreIncompleteParticles ) const {
668
669 a_productEnergy = 0.0;
670 a_productMomentum = 0.0;
671 a_productGain = 0.0;
672
673// if( ENDF_MT( ) == 516 ) return; // FIXME, may be something wrong with the way FUDGE converts ENDF to GNDS.
674
675 if( m_outputChannel != nullptr )
676 m_outputChannel->continuousEnergyProductData( a_settings, a_particleID, a_energy, a_productEnergy, a_productMomentum, a_productGain,
677 a_ignoreIncompleteParticles );
678}
679
680/* *********************************************************************************************************//**
681 * Modifies the average product energies, momenta and gains for product with particle id *a_particleID*.
682 *
683 * @param a_settings [in] Specifies user options.
684 * @param a_particleID [in] The particle id of the product.
685 * @param a_energies [in] The vector of energies to map the data to.
686 * @param a_offset [in] The index of the first energy whose data are to be added to the vectors.
687 * @param a_productEnergies [out] The vector of average energies of the product.
688 * @param a_productMomenta [out] The vector of average momenta of the product.
689 * @param a_productGains [out] The vector of gain of the product.
690 * @param a_ignoreIncompleteParticles [in] If *true*, incomplete particles are ignore, otherwise a *throw* is executed.
691 ***********************************************************************************************************/
692
693void Reaction::mapContinuousEnergyProductData( Transporting::Settings const &a_settings, std::string const &a_particleID,
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 {
696
697// if( ENDF_MT( ) == 516 ) return; // FIXME, may be something wrong with the way FUDGE converts ENDF to GNDS.
698
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 );
702}
703
704/* *********************************************************************************************************//**
705 * This method modifies the cross section for *this* reaction as
706 *
707 * crossSection = a_offset + a_slope * crossSection
708 *
709 * Either or both of *a_offset* and *a_slope* can be an empty Functions::XYs1d instance or a nullptr.
710 * If both *a_offset* and *a_slope* are non-empty Functions::XYs1d instances, the domains of both must be the same.
711 * If the returned value is false, no data are changed.
712 *
713 * @param a_offset [in] A pointer to a XYs1d function for the offset.
714 * @param a_slope [in] A pointer to a XYs1d function for the slope.
715 * @param a_updateMultiGroup [in] If true, the multi-group data are also modified.
716 *
717 * @return true if data can be modified and false otherwise.
718 ***********************************************************************************************************/
719
720bool Reaction::modifyCrossSection( Functions::XYs1d const *a_offset, Functions::XYs1d const *a_slope, bool a_updateMultiGroup ) {
721/*
722 -) FIXME, this does not modify the total cross section for the protare! Does it needed to be?
723*/
724
725 ProtareSingle &protare( dynamic_cast<ProtareSingle &>( *root( ) ) );
726 Styles::Suite const &styles = protare.styles( );
727 Functions::XYs1d const *offset1 = a_offset, *slope1 = a_slope;
728
729 if( a_offset == nullptr ) offset1 = new Functions::XYs1d( ); // Handle nullptr cases.
730 if( a_slope == nullptr ) slope1 = new Functions::XYs1d( );
731
732 if( offset1->size( ) == 0 ) { // Handle empty functions.
733 if( slope1->size( ) == 0 ) {
734 if( a_offset == nullptr ) delete offset1;
735 if( a_slope == nullptr ) delete slope1;
736 return( false );
737 }
738 Functions::XYs1d const *offset2 = Functions::XYs1d::makeConstantXYs1d( offset1->axes( ), slope1->domainMin( ), slope1->domainMax( ), 0.0 );
739 if( a_offset == nullptr ) delete offset1;
740 offset1 = offset2; }
741 else if( slope1->size( ) == 0 ) {
742 Functions::XYs1d const *slope2 = Functions::XYs1d::makeConstantXYs1d( slope1->axes( ), offset1->domainMin( ), offset1->domainMax( ), 1.0 );
743 if( a_slope == nullptr ) delete slope1;
744 slope1 = slope2;
745 }
746
747 double domainMin = offset1->domainMin( ), domainMax = offset1->domainMax( );
748
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." );
751
752 Styles::TemperatureInfos temperatureInfos = protare.temperatures( );
753
754 Functions::XYs1d *xys1d = static_cast<Functions::XYs1d *>(
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." );
757
758 if( ( xys1d->domainMin( ) >= domainMax ) || ( xys1d->domainMax( ) <= domainMin ) ) {
759 if( a_offset == nullptr ) delete offset1;
760 if( a_slope == nullptr ) delete slope1;
761 return( false );
762 }
763
764 double crossSectionDomainMax = xys1d->domainMax( );
765 if( xys1d->domainMin( ) > domainMin ) domainMin = xys1d->domainMin( );
766 if( crossSectionDomainMax < domainMax ) domainMax = crossSectionDomainMax;
767
768 Functions::XYs1d offset = offset1->domainSlice( domainMin, domainMax, true );
769 Functions::XYs1d slope = slope1->domainSlice( domainMin, domainMax, true );
770 if( a_offset == nullptr ) delete offset1;
771 if( a_slope == nullptr ) delete slope1;
772
773 for( auto temperatureInfo = temperatureInfos.begin( ); temperatureInfo != temperatureInfos.end( ); ++temperatureInfo ) {
774 xys1d = static_cast<Functions::XYs1d *>(
775 m_crossSection.findInstanceOfTypeInLineage( styles, temperatureInfo->heatedCrossSection( ), GIDI_XYs1dChars ) );
776 Functions::XYs1d xys1dSliced = xys1d->domainSlice( domainMin, domainMax, true );
777 if( xys1dSliced.interpolation( ) != ptwXY_interpolationLinLin ) {
778 Functions::XYs1d *temp = xys1dSliced.asXYs1d( true, 1e-3, 1e-6, 1e-6 );
779 xys1dSliced = (*temp);
780 delete temp;
781 }
782 Functions::XYs1d modified = offset + slope * xys1dSliced;
783
784 int64_t index1;
785 ptwXYPoint *p1;
786 ptwXYPoints *ptwXY = xys1d->ptwXY( );
787 int64_t length = ptwXY_length( nullptr, ptwXY );
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;
792 }
793 p1->y = modified.evaluate( p1->x );
794 }
795
796 Functions::Ys1d *ys1d = m_crossSection.get<Functions::Ys1d>( temperatureInfo->griddedCrossSection( ) );
797 std::vector<double> &Ys = ys1d->Ys( );
798 Styles::GriddedCrossSection const griddedCrossSection = *styles.get<Styles::GriddedCrossSection>( temperatureInfo->griddedCrossSection( ) );
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];
803
804 if( xValue < domainMin ) continue;
805 if( xValue >= domainMax ) {
806 if( ( xValue != domainMax ) || ( xValue != crossSectionDomainMax ) ) break;
807 }
808 Ys[index2] = modified.evaluate( xValue );
809 }
810 if( a_updateMultiGroup ) recalculateMultiGroupData( &protare, *temperatureInfo );
811 }
812
813 return( true );
814}
815
816/* *********************************************************************************************************//**
817 * Thid methid is deprecated, use modifyCrossSection instead. See modifyCrossSection for useage.
818 ***********************************************************************************************************/
819
820bool Reaction::modifiedCrossSection( Functions::XYs1d const *a_offset, Functions::XYs1d const *a_slope ) {
821
822 return modifyCrossSection( a_offset, a_slope, false );
823}
824
825/* *********************************************************************************************************//**
826 * This function recalculates the multi-group data for data labelled with a_temperatureInfo.heatedMultiGroup().
827 *
828 * @param a_temperatureInfo [in] The temperature for which multi-group data are to be recalculated.
829 ***********************************************************************************************************/
830
831void Reaction::recalculateMultiGroupData( ProtareSingle const *a_protare, Styles::TemperatureInfo const &a_temperatureInfo ) {
832
833 std::string heatedMultiGroupLabel = a_temperatureInfo.heatedMultiGroup( );
834
835 GUPI::Ancestry const *ancestorRoot = root( );
836 if( ancestorRoot->moniker( ) != GIDI_topLevelChars ) throw Exception( "Reaction::recalculateMultiGroupData: could not find parent protare." );
837
838 Styles::Suite const &styles = a_protare->styles( );
839 if( styles.find( heatedMultiGroupLabel ) == styles.end( ) ) return;
840
841 Styles::HeatedMultiGroup const &heatedMultiGroupStyle = *styles.get<Styles::HeatedMultiGroup const>( heatedMultiGroupLabel );
842
843 std::vector<double> groupBoundaries = heatedMultiGroupStyle.groupBoundaries( a_protare->projectile( ).ID( ) );
844 Transporting::MultiGroup multiGroup = Transporting::MultiGroup( "recal", groupBoundaries );
845
846 Transporting::Flux flux( "recal", a_temperatureInfo.temperature( ).value( ) );
847 double energies[2] = { groupBoundaries[0], groupBoundaries.back( ) };
848 double fluxValues[2] = { 1.0, 1.0 };
849 Transporting::Flux_order flux_order( 0, 2, energies, fluxValues );
850 flux.addFluxOrder( flux_order );
851
852 MultiGroupCalulationInformation multiGroupCalulationInformation( multiGroup, flux );
853 calculateMultiGroupData( a_protare, a_temperatureInfo, heatedMultiGroupLabel, multiGroupCalulationInformation );
854}
855
856/* *********************************************************************************************************//**
857 * This methods calculates multi-group data for all needed components and adds each component's multi-group with label *a_heatedMultiGroupLabel*.
858 *
859 * @param a_temperatureInfo [in] Specifies the temperature and labels use to lookup the requested data.
860 * @param a_heatedMultiGroupLabel [in] The label of the style for the multi-group data being added.
861 * @param a_multiGroupCalulationInformation [in] Store multi-group boundary and flux data used for multi-grouping.
862 * @param a_crossSectionXYs1d [in[ The cross section weight.
863 ***********************************************************************************************************/
864
865// FIXME maybe, as upscatter is currently not handled.
866
867void Reaction::calculateMultiGroupData( ProtareSingle const *a_protare, Styles::TemperatureInfo const &a_temperatureInfo,
868 std::string const &a_heatedMultiGroupLabel, MultiGroupCalulationInformation const &a_multiGroupCalulationInformation ) {
869
870 Styles::Suite const &styles = a_protare->styles( );
871 Transporting::MultiGroup multiGroup = a_multiGroupCalulationInformation.m_multiGroup;
872
873 std::vector<double> flatValues { multiGroup[0], 1.0, multiGroup[multiGroup.size( ) - 1], 1.0 };
874 Functions::XYs1d flatFunction( Axes( ), ptwXY_interpolationLinLin, flatValues );
875
876 Functions::XYs1d const *crossSectionXYs1d = static_cast<Functions::XYs1d *>(
877 m_crossSection.findInstanceOfTypeInLineage( styles, a_temperatureInfo.heatedCrossSection( ), GIDI_XYs1dChars ) );
878
879 calculate1dMultiGroupDataInComponent( a_protare, a_heatedMultiGroupLabel, a_multiGroupCalulationInformation, m_crossSection, flatFunction );
880 calculate1dMultiGroupDataInComponent( a_protare, a_heatedMultiGroupLabel, a_multiGroupCalulationInformation, m_availableEnergy, *crossSectionXYs1d );
881 calculate1dMultiGroupDataInComponent( a_protare, a_heatedMultiGroupLabel, a_multiGroupCalulationInformation, m_availableMomentum, *crossSectionXYs1d );
882
883 if( m_outputChannel != nullptr )
884 m_outputChannel->calculateMultiGroupData( a_protare, a_temperatureInfo, a_heatedMultiGroupLabel, a_multiGroupCalulationInformation, *crossSectionXYs1d );
885}
886
887/* *********************************************************************************************************//**
888 * Fills the argument *a_writeInfo* with the XML lines that represent *this*. Recursively enters each sub-node.
889 *
890 * @param a_writeInfo [in/out] Instance containing incremental indentation and other information and stores the appended lines.
891 * @param a_indent [in] The amount to indent *this* node.
892 ***********************************************************************************************************/
893
894void Reaction::toXMLList( GUPI::WriteInfo &a_writeInfo, std::string const &a_indent ) const {
895
896 std::string indent2 = a_writeInfo.incrementalIndent( a_indent );
897 std::string attributes;
898
899 attributes += a_writeInfo.addAttribute( GIDI_labelChars, label( ) );
900 attributes += a_writeInfo.addAttribute( GIDI_ENDF_MT_Chars, intToString( ENDF_MT( ) ) );
901 if( m_fissionGenre != "" ) attributes += a_writeInfo.addAttribute( GIDI_fissionGenreChars, m_fissionGenre );
902 a_writeInfo.addNodeStarter( a_indent, moniker( ), attributes );
903
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 );
909
910 a_writeInfo.addNodeEnder( moniker( ) );
911}
912
913/* *********************************************************************************************************//**
914 * Calculates the ENDL C and S values for a ENDF MT value.
915 *
916 * @param ENDF_MT [in] The ENDF MT value.
917 * @param ENDL_C [out] The ENDL C value for the ENDF MT value.
918 * @param ENDL_S [out] The ENDL S value for the ENDF MT value.
919 *
920 * @return Returns 0 if the ENDF MT value is valid and 1 otherwise.
921 ***********************************************************************************************************/
922
923int ENDL_CFromENDF_MT( int ENDF_MT, int *ENDL_C, int *ENDL_S ) {
924
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 };
940 *ENDL_C = 0;
941 *ENDL_S = 0;
942 if( ENDF_MT <= 0 ) {
943 *ENDL_C = -ENDF_MT;
944 return( 1 );
945 }
946 if( ENDF_MT > 1572 ) return( 1 );
947 if( ENDF_MT < 50 ) {
948 *ENDL_C = MT1_50ToC[ENDF_MT - 1]; }
949 else if( ENDF_MT <= 91 ) {
950 *ENDL_C = 11;
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 ) ) {
955 *ENDL_C = 15;
956 if( ENDF_MT == 455 ) *ENDL_S = 7; }
957 else if( ( ENDF_MT >= 502 ) && ( ENDF_MT <= 572 ) ) {
958 if( ENDF_MT == 502 ) {
959 *ENDL_C = 71; }
960 else if( ENDF_MT == 504 ) {
961 *ENDL_C = 72; }
962 else if( ( ENDF_MT >= 515 ) && ( ENDF_MT <= 517 ) ) {
963 *ENDL_C = 74; }
964 else if( ENDF_MT == 522 ) {
965 *ENDL_C = 73; }
966 else if( ( ENDF_MT >= 534 ) && ( ENDF_MT <= 572 ) ) {
967 *ENDL_C = 73; } }
968 else if( ENDF_MT >= 600 ) {
969 if( ENDF_MT < 650 ) {
970 *ENDL_C = 40;
971 if( ENDF_MT != 649 ) *ENDL_S = 1; }
972 else if( ENDF_MT < 700 ) {
973 *ENDL_C = 41;
974 if( ENDF_MT != 699 ) *ENDL_S = 1; }
975 else if( ENDF_MT < 750 ) {
976 *ENDL_C = 42;
977 if( ENDF_MT != 749 ) *ENDL_S = 1; }
978 else if( ENDF_MT < 800 ) {
979 *ENDL_C = 44;
980 if( ENDF_MT != 799 ) *ENDL_S = 1; }
981 else if( ENDF_MT < 850 ) {
982 *ENDL_C = 45;
983 if( ENDF_MT != 849 ) *ENDL_S = 1; }
984 else if( ( ENDF_MT >= 875 ) && ( ENDF_MT <= 891 ) ) {
985 *ENDL_C = 12;
986 if( ENDF_MT != 891 ) *ENDL_S = 1; }
987 else if( ( ENDF_MT >= 1534 ) && (ENDF_MT <= 1572 ) ) {
988 *ENDL_C = 72;
989 }
990 }
991
992 return( 0 );
993}
994
995}
G4ThreadLocal T * G4GeomSplitter< T >::offset
#define GIDI_crossSectionChars
Definition GIDI.hpp:215
#define GIDI_nuclearPlusInterferenceChars
Definition GIDI.hpp:377
#define GIDI_ENDF_MT_Chars
Definition GIDI.hpp:420
#define GIDI_griddedCrossSectionStyleChars
Definition GIDI.hpp:251
#define GIDI_availableMomentumChars
Definition GIDI.hpp:217
#define GIDI_XYs1dChars
Definition GIDI.hpp:288
#define GIDI_outputChannelChars
Definition GIDI.hpp:227
#define GIDI_orphanProductChars
Definition GIDI.hpp:182
#define GIDI_RutherfordScatteringChars
Definition GIDI.hpp:376
#define GIDI_reactionChars
Definition GIDI.hpp:180
#define GIDI_fissionGenreChars
Definition GIDI.hpp:410
#define GIDI_availableEnergyChars
Definition GIDI.hpp:216
#define GIDI_labelChars
Definition GIDI.hpp:438
#define GIDI_doubleDifferentialCrossSectionChars
Definition GIDI.hpp:214
#define GIDI_topLevelChars
Definition GIDI.hpp:169
#define GIDI_CoulombPlusNuclearElasticChars
Definition GIDI.hpp:375
#define PoPI_electronMass_MeV_c2
Definition PoPI.hpp:31
ParseMode parseMode() const
Definition GIDI.hpp:557
bool decayPositronium() const
Definition GIDI.hpp:567
std::string const & label() const
Definition GIDI.hpp:658
FormType type() const
Definition GIDI.hpp:667
Form(FormType a_type)
Definition GIDI_form.cc:25
Axes const & axes() const
Definition GIDI.hpp:1012
ptwXY_interpolation interpolation() const
Definition GIDI.hpp:1015
Vector const & data() const
Definition GIDI.hpp:1254
std::size_t size() const
Definition GIDI.hpp:1100
double evaluate(double a_x1) const
ptwXYPoints const * ptwXY() const
Definition GIDI.hpp:1101
double domainMax() const
Definition GIDI.hpp:1115
double domainMin() const
Definition GIDI.hpp:1114
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::size_t size() const
Definition GIDI.hpp:1154
std::vector< double > const & Ys() const
Definition GIDI.hpp:1166
std::size_t start() const
Definition GIDI.hpp:1163
nf_Buffer< double > const & values() const
Definition GIDI.hpp:849
void set(std::size_t a_row, std::size_t a_column, double a_value)
Transporting::MultiGroup const & m_multiGroup
Definition GIDI.hpp:5495
std::string const & ID() const
Definition GIDI.hpp:760
double value() const
Definition GIDI.hpp:728
Styles::Suite & styles()
Definition GIDI.hpp:4802
virtual Styles::Suite & styles()=0
virtual double thresholdFactor() const =0
ParticleInfo const & projectile() const
Definition GIDI.hpp:4541
bool areAllProductsTracked(Transporting::Particles const &a_particles) const
friend class ProtareSingle
Definition GIDI.hpp:4247
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
bool hasFission() 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
int ENDF_MT() const
Definition GIDI.hpp:4284
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()
Definition GIDI.hpp:4302
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
bool m_isENDL_C_9
Definition GIDI.hpp:602
int m_outputChannelLevel
Definition GIDI.hpp:603
std::string const & label() const
Definition GIDI.hpp:3130
Grid const & grid() const
Definition GIDI.hpp:3368
std::vector< double > groupBoundaries(std::string const &a_ID) const
PhysicalQuantity const & temperature() const
Definition GIDI.hpp:3430
std::string const & heatedMultiGroup() const
Definition GIDI.hpp:3434
std::string const & heatedCrossSection() const
Definition GIDI.hpp:3431
std::vector< iterator > findAllOfMoniker(std::string const &a_moniker)
T * get(std::size_t a_Index)
Definition GIDI.hpp:2642
iterator find(std::string const &a_label, bool a_convertLazyParsingHelperForm=false)
iterator end()
Definition GIDI.hpp:2596
Styles::Suite const * styles()
Definition GIDI.hpp:2608
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()
Definition GIDI.hpp:3692
bool zeroDepositionIfAllProductsTracked() const
Definition GIDI.hpp:3734
std::size_t size() const
Definition GIDI_data.hpp:79
void setMoniker(std::string const &a_moniker)
Definition GUPI.hpp:103
void setAncestor(Ancestry *a_ancestor)
Definition GUPI.hpp:106
std::string const & moniker() const
Definition GUPI.hpp:102
Ancestry * root()
void addNodeEnder(std::string const &a_moniker)
Definition GUPI.hpp:59
std::string incrementalIndent(std::string const &indent)
Definition GUPI.hpp:52
void addNodeStarter(std::string const &indent, std::string const &a_moniker, std::string const &a_attributes="")
Definition GUPI.hpp:55
std::string addAttribute(std::string const &a_name, std::string const &a_value) const
Definition GUPI.hpp:60
std::string name() const
Definition HAPI_Node.cc:136
bool empty() const
Definition HAPI_Node.cc:150
Node first_child() const
Definition HAPI_Node.cc:82
Node child(const char *name) const
Definition HAPI_Node.cc:72
std::vector< Styles::TemperatureInfo > TemperatureInfos
Definition GIDI.hpp:3440
Definition GIDI.hpp:32
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)
FormType
Definition GIDI.hpp:118
@ incoherentPhotonScattering
Definition GIDI.hpp:135
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)
Definition GIDI_misc.cc:415
std::vector< DelayedNeutronProduct > DelayedNeutronProducts
Definition GIDI.hpp:4031
bool compareSpecialParticleIDs(std::string const &a_id1, std::string const &a_id2)
Definition PoPI_misc.cc:133
@ ptwXY_interpolationLinLin
Definition ptwXY.h:37
struct ptwXYPoints_s ptwXYPoints
int64_t ptwXY_length(statusMessageReporting *smr, ptwXYPoints *ptwXY)
Definition ptwXY_core.c:793
struct ptwXYPoint_s ptwXYPoint
static std::string const anti
Definition PoPI.hpp:173
static std::string const photon
Definition PoPI.hpp:162
static std::string const neutron
Definition PoPI.hpp:164
static std::string const electron
Definition PoPI.hpp:163
double y
Definition ptwXY.h:64
double x
Definition ptwXY.h:64
ptwXYPoint * points
Definition ptwXY.h:93