Geant4 11.4.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
GIDI_product.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 <stdlib.h>
11#include "GIDI.hpp"
12#include <HAPI.hpp>
13
14namespace GIDI {
15
16/*! \class Product
17 * Class to store a GNDS <**product**> node.
18 */
19
20/* *********************************************************************************************************//**
21 * Constructed
22 ***********************************************************************************************************/
23
24Product::Product( PoPI::Database const &a_pops, std::string const &a_productID, std::string const &a_label ) :
26 m_particle( ParticleInfo( a_productID, a_pops, a_pops, true ) ),
27 m_GNDS_particle( ParticleInfo( a_productID, a_pops, a_pops, true ) ),
28 m_productMultiplicity( 0 ),
29 m_treatProductAsIfInfinityMass( false ),
30 m_multiplicity( GIDI_multiplicityChars, GIDI_labelChars ),
31 m_distribution( GIDI_distributionChars, GIDI_labelChars ),
32 m_averageEnergy( GIDI_averageEnergyChars, GIDI_labelChars ),
33 m_averageMomentum( GIDI_averageMomentumChars, GIDI_labelChars ),
34 m_outputChannel( nullptr ) {
35
37 setLabel( a_label );
38
39 m_multiplicity.setAncestor( this );
40 m_distribution.setAncestor( this );
41 m_averageEnergy.setAncestor( this );
42 m_averageMomentum.setAncestor( this );
43}
44
45/* *********************************************************************************************************//**
46 * Constructed from data in a <**product**> node.
47 *
48 * @param a_construction [in] Used to pass user options to the constructor.
49 * @param a_node [in] The HAPI::Node to be parsed and used to construct the Product.
50 * @param a_setupInfo [in] Information create my the Protare constructor to help in parsing.
51 * @param a_pops [in] The *external* PoPI::Database instance used to get particle indices and possibly other particle information.
52 * @param a_internalPoPs [in] The *internal* PoPI::Database instance used to get particle indices and possibly other particle information.
53 * This is the <**PoPs**> node under the <**reactionSuite**> node.
54 * @param a_parent [in] The **m_products** member of GIDI::OutputChannel this product belongs to.
55 * @param a_styles [in] The <**styles**> node under the <**reactionSuite**> node.
56 ***********************************************************************************************************/
57
58Product::Product( Construction::Settings const &a_construction, HAPI::Node const &a_node, SetupInfo &a_setupInfo, PoPI::Database const &a_pops,
59 PoPI::Database const &a_internalPoPs, Suite *a_parent, Styles::Suite const *a_styles ) :
60 Form( a_node, a_setupInfo, FormType::product, a_parent ),
61 m_particle( a_node.attribute_as_string( GIDI_pidChars ), a_pops, a_internalPoPs, false ),
62 m_GNDS_particle( a_node.attribute_as_string( GIDI_pidChars ), a_pops, a_internalPoPs, false ),
63 m_productMultiplicity( 0 ),
64 m_treatProductAsIfInfinityMass( false ),
65 m_multiplicity( a_construction, GIDI_multiplicityChars, GIDI_labelChars, a_node, a_setupInfo, a_pops, a_internalPoPs, parseMultiplicitySuite, a_styles ),
66 m_distribution( a_construction, GIDI_distributionChars, GIDI_labelChars, a_node, a_setupInfo, a_pops, a_internalPoPs, parseDistributionSuite, a_styles ),
67 m_averageEnergy( a_construction, GIDI_averageEnergyChars, GIDI_labelChars, a_node, a_setupInfo, a_pops, a_internalPoPs, parseAverageEnergySuite, a_styles ),
68 m_averageMomentum( a_construction, GIDI_averageMomentumChars, GIDI_labelChars, a_node, a_setupInfo, a_pops, a_internalPoPs, parseAverageMomentumSuite, a_styles ),
69 m_outputChannel( nullptr ) {
70
71 if( a_setupInfo.m_outputChannelLevel == 0 ) a_setupInfo.m_initialState = m_particle.ID( );
72 m_multiplicity.setAncestor( this );
73 m_distribution.setAncestor( this );
74 m_averageEnergy.setAncestor( this );
75 m_averageMomentum.setAncestor( this );
76
77 auto iter = a_setupInfo.m_particleSubstitution->find( m_GNDS_particle.ID( ) );
78 if( iter != a_setupInfo.m_particleSubstitution->end( ) ) m_particle = iter->second;
79
80 if( a_setupInfo.m_protare->projectile( ).ID( ) == PoPI::IDs::photon ) {
81 if( m_particle.ID( ) == a_setupInfo.m_protare->GNDS_target( ).ID( ) ) m_particle = a_setupInfo.m_protare->target( );
82 }
83
84 if( a_setupInfo.m_protare->isPhotoAtomic( ) || a_setupInfo.m_protare->isTNSL_ProtareSingle( ) ) {
85 m_treatProductAsIfInfinityMass = m_GNDS_particle.ID( ) == a_setupInfo.m_protare->GNDS_target( ).ID( );
86 }
87
88 HAPI::Node const _outputChannel = a_node.child( GIDI_outputChannelChars );
89 a_setupInfo.m_outputChannelLevel += 1;
90 if( ! _outputChannel.empty( ) )
91 m_outputChannel = new OutputChannel( a_construction, _outputChannel, a_setupInfo, a_pops, a_internalPoPs, a_styles, false, false );
92 a_setupInfo.m_outputChannelLevel -= 1;
93
94 if( m_outputChannel == nullptr ) {
95 if( m_multiplicity.size( ) > 0 ) {
96 GIDI::Functions::Function1dForm const *function1d = m_multiplicity.get<GIDI::Functions::Function1dForm>( 0 );
97
98 if( function1d->type( ) == FormType::constant1d ) {
99 m_productMultiplicity = static_cast<int>( function1d->evaluate( 0.0 ) ); }
100 else if( function1d->type( ) != FormType::unspecified1d ) {
101 m_productMultiplicity = -1;
102 }
103 } }
104 else {
105 m_outputChannel->setAncestor( this );
106 }
107}
108
109/* *********************************************************************************************************//**
110 ***********************************************************************************************************/
111
113
114 if( m_outputChannel != nullptr ) delete m_outputChannel;
115}
116
117/* *********************************************************************************************************//**
118 * Returns the maximum product depth for this product.
119 *
120 * @return The maximum product depth.
121 ***********************************************************************************************************/
122
123int Product::depth( ) const {
124
125 if( m_outputChannel == nullptr ) return( 0 );
126 return( m_outputChannel->depth( ) );
127}
128
129/* *********************************************************************************************************//**
130 * Only for internal use. Called by ProtareTNSL instance to zero the lower energy multi-group data covered by the ProtareSingle that
131 * contains the TNSL data covers the lower energy multi-group data.
132 *
133 * @param a_maximumTNSL_MultiGroupIndex [in] A map that contains labels for heated multi-group data and the last valid group boundary
134 * for the TNSL data for that boundary.
135 ***********************************************************************************************************/
136
137void Product::modifiedMultiGroupElasticForTNSL( std::map<std::string,std::size_t> const &a_maximumTNSL_MultiGroupIndex ) {
138
139 m_multiplicity.modifiedMultiGroupElasticForTNSL( a_maximumTNSL_MultiGroupIndex );
140 m_distribution.modifiedMultiGroupElasticForTNSL( a_maximumTNSL_MultiGroupIndex );
141 m_averageEnergy.modifiedMultiGroupElasticForTNSL( a_maximumTNSL_MultiGroupIndex );
142 m_averageMomentum.modifiedMultiGroupElasticForTNSL( a_maximumTNSL_MultiGroupIndex );
143}
144
145/* *********************************************************************************************************//**
146 * Returns true if the product has an output channel and its output channel hasFission returns true, and false otherwise.
147 *
148 * @return true if at least one output channel is a fission channel.
149 ***********************************************************************************************************/
150
151bool Product::hasFission( ) const {
152
153 if( m_outputChannel != nullptr ) return( m_outputChannel->hasFission( ) );
154 return( false );
155}
156
157/* *********************************************************************************************************//**
158 * Returns **false* if *this* has delayed fission neutrons and they are not complete; otherwise, returns **true**.
159 *
160 * @param a_isDelayedNeutron [in] **true** is called from FissionFragmentData::isDelayedFissionNeutronComplete and **false** otherwise.
161 *
162 * @return bool
163 ***********************************************************************************************************/
164
165bool Product::isDelayedFissionNeutronComplete( bool a_isDelayedNeutron ) const {
166
167 if( a_isDelayedNeutron ) {
168 return( isCompleteParticle( ) ); }
169 else {
170 if( m_outputChannel != nullptr ) return( m_outputChannel->isDelayedFissionNeutronComplete( ) );
171 }
172
173 return( true );
174}
175
176/* *********************************************************************************************************//**
177 * Returns **true** if all outgoing particles (i.e., products) are specifed in *a_particles*. That is, the user
178 * will be tracking all products of *this* reaction.
179 *
180 * @param a_particles [in] The list of particles to be transported.
181 *
182 * @return bool.
183 ***********************************************************************************************************/
184
186
187 if( m_outputChannel != nullptr ) return( m_outputChannel->areAllProductsTracked( a_particles ) );
188
189 return( a_particles.hasParticle( m_particle.ID( ) ) );
190}
191
192/* *********************************************************************************************************//**
193 * 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.
194 *
195 * @param a_item [in] The name of the class member whose pointer is to be return.
196 * @return The pointer to the class member or nullptr if class does not have a member named a_item.
197 ***********************************************************************************************************/
198
199GUPI::Ancestry *Product::findInAncestry3( std::string const &a_item ) {
200
201 if( a_item == GIDI_multiplicityChars ) return( &m_multiplicity );
202 if( a_item == GIDI_distributionChars ) return( &m_distribution );
203 if( a_item == GIDI_averageEnergyChars ) return( &m_averageEnergy );
204 if( a_item == GIDI_averageMomentumChars ) return( &m_averageMomentum );
205 if( a_item == GIDI_outputChannelChars ) return( m_outputChannel );
206
207 return( nullptr );
208}
209
210/* *********************************************************************************************************//**
211 * 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.
212 *
213 * @param a_item [in] The name of the class member whose pointer is to be return.
214 * @return The pointer to the class member or nullptr if class does not have a member named a_item.
215 ***********************************************************************************************************/
216
217GUPI::Ancestry const *Product::findInAncestry3( std::string const &a_item ) const {
218
219 if( a_item == GIDI_multiplicityChars ) return( &m_multiplicity );
220 if( a_item == GIDI_distributionChars ) return( &m_distribution );
221 if( a_item == GIDI_averageEnergyChars ) return( &m_averageEnergy );
222 if( a_item == GIDI_averageMomentumChars ) return( &m_averageMomentum );
223 if( a_item == GIDI_outputChannelChars ) return( m_outputChannel );
224
225 return( nullptr );
226}
227
228/* *********************************************************************************************************//**
229 * Insert a std::set with the products index and any product in in its output channel.
230 * If a_transportablesOnly is true, only transportable product indices are return.
231 *
232 * @param a_indices [out] The unique list of product indices.
233 * @param a_particles [in] The list of particles to be transported.
234 * @param a_transportablesOnly [in] If true, only transportable product indices are added in the list.
235 ***********************************************************************************************************/
236
237void Product::productIDs( std::set<std::string> &a_indices, Transporting::Particles const &a_particles, bool a_transportablesOnly ) const {
238
239 if( m_outputChannel == nullptr ) {
240 if( a_transportablesOnly && !a_particles.hasParticle( m_particle.ID( ) ) ) return;
241 if( m_particle.ID( ) != "" ) a_indices.insert( m_particle.ID( ) ); }
242 else {
243 m_outputChannel->productIDs( a_indices, a_particles, a_transportablesOnly );
244 }
245}
246
247/* *********************************************************************************************************//**
248 * Returns the product multiplicity (e.g., 0, 1, 2, ...) or -1 if energy dependent or not an integer for particle with id *a_productID*.
249 *
250 * @param a_productID; [in] The id of the requested particle.
251 *
252 * @return The multiplicity for the requested particle.
253 ***********************************************************************************************************/
254
255int Product::productMultiplicity( std::string const &a_productID ) const {
256
257 if( m_outputChannel != nullptr ) return( m_outputChannel->productMultiplicity( a_productID ) );
258
259 if( PoPI::compareSpecialParticleIDs( a_productID, m_particle.ID( ) ) ) return( m_productMultiplicity );
260 return( 0 );
261}
262
263/* *********************************************************************************************************//**
264 * Determines the maximum Legredre order present in the multi-group transfer matrix for a this product and any sub-products for a give label.
265 *
266 * @param a_smr [Out] If errors are not to be thrown, then the error is reported via this instance.
267 * @param a_settings [in] Specifies the requested label.
268 * @param a_temperatureInfo [in] Specifies the temperature and labels use to lookup the requested data.
269 * @param a_productID [in] Particle id for the requested product.
270 *
271 * @return The maximum Legredre order. If no transfer matrix data are present for the requested product, -1 is returned.
272 ***********************************************************************************************************/
273
275 Styles::TemperatureInfo const &a_temperatureInfo, std::string const &a_productID ) const {
276
277 int _maximumLegendreOrder = -1;
278
279 if( m_outputChannel == nullptr ) {
280 if( PoPI::compareSpecialParticleIDs( m_particle.ID( ), a_productID ) ) {
281 Distributions::MultiGroup3d const *form = dynamic_cast<Distributions::MultiGroup3d const*>( a_settings.form(
282 a_smr, m_distribution, a_temperatureInfo, "distribution for maximumLegendreOrder" ) );
283 if( form != nullptr ) {
284 Functions::Gridded3d const &gdata = form->data( );
285 Array3d const &data = gdata.data( );
286 _maximumLegendreOrder = static_cast<int>( data.size( ) ) - 1;
287 }
288 } }
289 else {
290 int __maximumLegendreOrder = m_outputChannel->maximumLegendreOrder( a_smr, a_settings, a_temperatureInfo, a_productID );
291 if( __maximumLegendreOrder > _maximumLegendreOrder ) _maximumLegendreOrder = __maximumLegendreOrder;
292 }
293
294 return( _maximumLegendreOrder );
295}
296
297/* *********************************************************************************************************//**
298 * Returns the sum of the multi-group, multiplicity for the requested label for the this product and any sub-product.
299 * This is a cross section weighted multiplicity.
300 *
301 * @param a_smr [Out] If errors are not to be thrown, then the error is reported via this instance.
302 * @param a_settings [in] Specifies the requested label.
303 * @param a_temperatureInfo [in] Specifies the temperature and labels use to lookup the requested data.
304 * @param a_productID [in] Particle id for the requested product.
305 *
306 * @return The requested multi-group multiplicity as a GIDI::Vector.
307 ***********************************************************************************************************/
308
310 Styles::TemperatureInfo const &a_temperatureInfo, std::string const &a_productID ) const {
311
312 Vector vector( 0 );
313
314 if( m_outputChannel == nullptr ) {
315 if( ( PoPI::compareSpecialParticleIDs( m_particle.ID( ), a_productID ) ) && ( !m_treatProductAsIfInfinityMass ) ) {
316 Functions::Gridded1d const *form = dynamic_cast<Functions::Gridded1d const*>( a_settings.form(
317 a_smr, m_multiplicity, a_temperatureInfo, "multiplicity" ) );
318 if( form != nullptr ) vector += form->data( );
319 } }
320 else {
321 vector += m_outputChannel->multiGroupMultiplicity( a_smr, a_settings, a_temperatureInfo, a_productID );
322 }
323
324 return( vector );
325}
326
327/* *********************************************************************************************************//**
328 * Returns the sum of the multi-group, Q for the requested label for the this product and any sub-product . This is a cross section weighted Q.
329 * If a_final is false, only the Q for the products output channel is returned, otherwise, the Q for all output channels
330 * summed, including output channels for each products.
331 *
332 * @param a_smr [Out] If errors are not to be thrown, then the error is reported via this instance.
333 * @param a_settings [in] Specifies the requested label.
334 * @param a_temperatureInfo [in] Specifies the temperature and labels use to lookup the requested data.
335 * @param a_final [in] If true, the Q is calculated for all output channels, including those for products.
336 *
337 * @return The requested multi-group Q as a GIDI::Vector.
338 ***********************************************************************************************************/
339
341 Styles::TemperatureInfo const &a_temperatureInfo, bool a_final ) const {
342
343 Vector _vector( 0 );
344
345 if( m_outputChannel != nullptr ) _vector += m_outputChannel->multiGroupQ( a_smr, a_settings, a_temperatureInfo, a_final );
346
347 return( _vector );
348}
349
350/* *********************************************************************************************************//**
351 * Returns the multi-group, product matrix for the requested label for the requested product index for the requested Legendre order.
352 * If no data are found, an empty GIDI::Matrix is returned.
353 *
354 * @param a_smr [Out] If errors are not to be thrown, then the error is reported via this instance.
355 * @param a_settings [in] Specifies the requested label and if delayed neutrons should be included.
356 * @param a_temperatureInfo [in] Specifies the temperature and labels use to lookup the requested data.
357 * @param a_particles [in] The list of particles to be transported.
358 * @param a_productID [in] Particle id for the requested product.
359 * @param a_order [in] Requested product matrix, Legendre order.
360 *
361 * @return The requested multi-group product matrix as a GIDI::Matrix.
362 ***********************************************************************************************************/
363
365 Styles::TemperatureInfo const &a_temperatureInfo, Transporting::Particles const &a_particles, std::string const &a_productID,
366 std::size_t a_order ) const {
367
368 Matrix matrix( 0, 0 );
369
370 if( m_outputChannel == nullptr ) {
371 if( ( PoPI::compareSpecialParticleIDs( m_particle.ID( ), a_productID ) ) && ( !m_treatProductAsIfInfinityMass ) ) {
372 Distributions::MultiGroup3d const *form = dynamic_cast<Distributions::MultiGroup3d const*>( a_settings.form(
373 a_smr, m_distribution, a_temperatureInfo, "distribution for product matrix" ) );
374 if( form != nullptr ) {
375 Functions::Gridded3d const &gdata = form->data( );
376 Array3d const &data = gdata.data( );
377 matrix = data.matrix( a_order );
378 }
379 } }
380 else {
381 matrix += m_outputChannel->multiGroupProductMatrix( a_smr, a_settings, a_temperatureInfo, a_particles, a_productID, a_order );
382 }
383
384 return( matrix );
385}
386
387/* *********************************************************************************************************//**
388 * Returns the sum of the multi-group, average energy for the requested label for the requested product. This is a cross section weighted average energy
389 * summed over this and all sub-products.
390 *
391 * @param a_smr [Out] If errors are not to be thrown, then the error is reported via this instance.
392 * @param a_settings [in] Specifies the requested label.
393 * @param a_temperatureInfo [in] Specifies the temperature and labels use to lookup the requested data.
394 * @param a_productID [in] Particle id for the requested product.
395 *
396 * @return The requested multi-group average energy as a GIDI::Vector.
397 ***********************************************************************************************************/
398
400 Styles::TemperatureInfo const &a_temperatureInfo, std::string const &a_productID ) const {
401
402 Vector vector( 0 );
403
404 if( m_outputChannel == nullptr ) {
405 if( ( PoPI::compareSpecialParticleIDs( m_particle.ID( ), a_productID ) ) && ( !m_treatProductAsIfInfinityMass ) ) {
406 Functions::Gridded1d const *form = dynamic_cast<Functions::Gridded1d const*>( a_settings.form(
407 a_smr, m_averageEnergy, a_temperatureInfo, "average product energy" ) );
408 if( form != nullptr ) vector += form->data( );
409 } }
410 else {
411 vector += m_outputChannel->multiGroupAverageEnergy( a_smr, a_settings, a_temperatureInfo, a_productID );
412 }
413
414 return( vector );
415}
416
417/* *********************************************************************************************************//**
418 * Returns the sum of the multi-group, average momentum for the requested label for the requested product. This is a cross section weighted average momentum
419 * summed over this and all sub-products.
420 *
421 * @param a_smr [Out] If errors are not to be thrown, then the error is reported via this instance.
422 * @param a_settings [in] Specifies the requested label.
423 * @param a_temperatureInfo [in] Specifies the temperature and labels use to lookup the requested data.
424 * @param a_productID [in] Particle id for the requested product.
425 *
426 * @return The requested multi-group average momentum as a GIDI::Vector.
427 ***********************************************************************************************************/
428
430 Styles::TemperatureInfo const &a_temperatureInfo, std::string const &a_productID ) const {
431
432 Vector vector( 0 );
433
434 if( m_outputChannel == nullptr ) {
435 if( ( PoPI::compareSpecialParticleIDs( m_particle.ID( ), a_productID ) ) && ( !m_treatProductAsIfInfinityMass ) ) {
436 Functions::Gridded1d const *form = dynamic_cast<Functions::Gridded1d const*>( a_settings.form(
437 a_smr, m_averageMomentum, a_temperatureInfo, "average product momentum" ) );
438 if( form != nullptr ) vector += form->data( );
439 } }
440 else {
441 vector += m_outputChannel->multiGroupAverageMomentum( a_smr, a_settings, a_temperatureInfo, a_productID );
442 }
443 return( vector );
444}
445
446/* *********************************************************************************************************//**
447 * Returns, via arguments, the average energy and momentum, and gain for product with particle id *a_particleID*.
448 *
449 * @param a_settings [in] Specifies the requested label.
450 * @param a_particleID [in] The particle id of the product.
451 * @param a_energy [in] The energy of the projectile.
452 * @param a_productEnergy [in] The average energy of the product.
453 * @param a_productMomentum [in] The average momentum of the product.
454 * @param a_productGain [in] The gain of the product.
455 * @param a_ignoreIncompleteParticles [in] If *true*, incomplete particles are ignore, otherwise a *throw* is executed.
456 ***********************************************************************************************************/
457
458void Product::continuousEnergyProductData( Transporting::Settings const &a_settings, std::string const &a_particleID, double a_energy,
459 double &a_productEnergy, double &a_productMomentum, double &a_productGain, bool a_ignoreIncompleteParticles ) const {
460
461 if( m_outputChannel == nullptr ) {
462 if( a_particleID == m_particle.ID( ) ) {
463 if( !isCompleteParticle( ) ) {
464 if( a_ignoreIncompleteParticles ) return;
465 throw Exception( "GIDI::Product::continuousEnergyProductData: particle is incomplete: " + toXLink( ) + "." );
466 }
467 a_productEnergy += averageEnergy( ).get<GIDI::Functions::Function1dForm>( 0 )->evaluate( a_energy );
468 a_productMomentum += averageMomentum( ).get<GIDI::Functions::Function1dForm>( 0 )->evaluate( a_energy );
469 a_productGain += multiplicity( ).get<GIDI::Functions::Function1dForm>( 0 )->evaluate( a_energy ); } }
470 else {
471 m_outputChannel->continuousEnergyProductData( a_settings, a_particleID, a_energy, a_productEnergy, a_productMomentum, a_productGain, a_ignoreIncompleteParticles );
472 }
473}
474
475/* *********************************************************************************************************//**
476 * Modifies the average product energies, momenta and gains for product with particle id *a_particleID*.
477 *
478 * @param a_settings [in] Specifies user options.
479 * @param a_particleID [in] The particle id of the product.
480 * @param a_energies [in] The vector of energies to map the data to.
481 * @param a_offset [in] The index of the first energy whose data are to be added to the vectors.
482 * @param a_productEnergies [out] The vector of average energies of the product.
483 * @param a_productMomenta [out] The vector of average momenta of the product.
484 * @param a_productGains [out] The vector of gain of the product.
485 * @param a_ignoreIncompleteParticles [in] If *true*, incomplete particles are ignore, otherwise a *throw* is executed.
486 ***********************************************************************************************************/
487
488void Product::mapContinuousEnergyProductData( Transporting::Settings const &a_settings, std::string const &a_particleID,
489 std::vector<double> const &a_energies, std::size_t a_offset, std::vector<double> &a_productEnergies, std::vector<double> &a_productMomenta,
490 std::vector<double> &a_productGains, bool a_ignoreIncompleteParticles ) const {
491
492 if( m_outputChannel == nullptr ) {
493 if( a_particleID == m_particle.ID( ) ) {
494 if( !isCompleteParticle( ) ) {
495 if( a_ignoreIncompleteParticles ) return;
496 throw Exception( "GIDI::Product::mapContinuousEnergyProductData: particle is incomplete: " + toXLink( ) + "." );
497 }
499 if( multiplicity1->type( ) == FormType::branching1d ) return;
500
501 averageEnergy( ).get<GIDI::Functions::Function1dForm>( 0 )->mapToXsAndAdd( a_offset, a_energies, a_productEnergies, -1.0 );
502 averageMomentum( ).get<GIDI::Functions::Function1dForm>( 0 )->mapToXsAndAdd( a_offset, a_energies, a_productMomenta, -1.0 );
503 multiplicity1->mapToXsAndAdd( a_offset, a_energies, a_productGains, 1.0 );
504 } }
505 else {
506 m_outputChannel->mapContinuousEnergyProductData( a_settings, a_particleID, a_energies, a_offset, a_productEnergies, a_productMomenta,
507 a_productGains, a_ignoreIncompleteParticles );
508 }
509}
510
511/* *********************************************************************************************************//**
512 * Returns *true* if the product is complete and *false* otherwise. A product is complete if its multiplicity and/or distribution
513 * are other than *unspecified*.
514 *
515 * @return *true* if the product is complete and *false* otherwise.
516 ***********************************************************************************************************/
517
519
520 if( m_multiplicity.size( ) == 0 ) return( false );
521 if( m_multiplicity.get<Form>( 0 )->type( ) == FormType::unspecified ) return( false );
522 if( m_distribution.size( ) == 0 ) return( false );
523 if( m_distribution.get<Form>( 0 )->type( ) == FormType::unspecified ) return( false );
524
525 return( true );
526}
527
528/* *********************************************************************************************************//**
529 * If the product has a distribution and its first distribution form is not **unspecified**, its PoPs id is added to *a_incompleteParticles*.
530 *
531 * @return Returns *true* if the product has distribution data and *false* otherwise.
532 ***********************************************************************************************************/
533
534void Product::incompleteParticles( Transporting::Settings const &a_settings, std::set<std::string> &a_incompleteParticles ) const {
535
536 if( m_outputChannel == nullptr ) {
537 if( !isCompleteParticle( ) ) a_incompleteParticles.insert( particle( ).ID( ) ); }
538 else {
539 m_outputChannel->incompleteParticles( a_settings, a_incompleteParticles );
540 }
541}
542
543/* *********************************************************************************************************//**
544 * This methods calculates multi-group data for all needed components and adds each component's multi-group with label *a_heatedMultiGroupLabel*.
545 *
546 * @param a_temperatureInfo [in] Specifies the temperature and labels use to lookup the requested data.
547 * @param a_heatedMultiGroupLabel [in] The label of the style for the multi-group data being added.
548 * @param a_multiGroupCalulationInformation [in] Store multi-group boundary and flux data used for multi-grouping.
549 * @param a_crossSectionXYs1d [in[ The cross section weight.
550 ***********************************************************************************************************/
551
552void Product::calculateMultiGroupData( ProtareSingle const *a_protare, Styles::TemperatureInfo const &a_temperatureInfo,
553 std::string const &a_heatedMultiGroupLabel, MultiGroupCalulationInformation const &a_multiGroupCalulationInformation,
554 Functions::XYs1d const &a_crossSectionXYs1d ) {
555
556// FIXME, need to calculateMultiGroupData for the distribution.
557
558 if( isCompleteParticle( ) ) {
559 if( m_multiplicity.find( a_heatedMultiGroupLabel ) != m_multiplicity.end( ) ) {
560 calculate1dMultiGroupDataInComponent( a_protare, a_heatedMultiGroupLabel, a_multiGroupCalulationInformation, m_multiplicity, a_crossSectionXYs1d );
561 calculate1dMultiGroupDataInComponent( a_protare, a_heatedMultiGroupLabel, a_multiGroupCalulationInformation, m_averageEnergy, a_crossSectionXYs1d );
562 calculate1dMultiGroupDataInComponent( a_protare, a_heatedMultiGroupLabel, a_multiGroupCalulationInformation, m_averageMomentum, a_crossSectionXYs1d );
563 }
564 }
565
566 if( m_outputChannel != nullptr )
567 m_outputChannel->calculateMultiGroupData( a_protare, a_temperatureInfo, a_heatedMultiGroupLabel, a_multiGroupCalulationInformation, a_crossSectionXYs1d );
568}
569
570/* *********************************************************************************************************//**
571 * Fills the argument *a_writeInfo* with the XML lines that represent *this*. Recursively enters each sub-node.
572 *
573 * @param a_writeInfo [in/out] Instance containing incremental indentation and other information and stores the appended lines.
574 * @param a_indent [in] The amount to indent *this* node.
575 ***********************************************************************************************************/
576
577void Product::toXMLList( GUPI::WriteInfo &a_writeInfo, std::string const &a_indent ) const {
578
579 std::string indent2 = a_writeInfo.incrementalIndent( a_indent );
580 std::string attributes;
581
582 attributes += a_writeInfo.addAttribute( GIDI_pidChars, m_GNDS_particle.ID( ) );
583 if( label( ) != "" ) attributes += a_writeInfo.addAttribute( GIDI_labelChars, label( ) );
584 a_writeInfo.addNodeStarter( a_indent, moniker( ), attributes );
585
586 m_multiplicity.toXMLList( a_writeInfo, indent2 );
587 m_distribution.toXMLList( a_writeInfo, indent2 );
588 m_averageEnergy.toXMLList( a_writeInfo, indent2 );
589 m_averageMomentum.toXMLList( a_writeInfo, indent2 );
590 if( m_outputChannel != nullptr ) m_outputChannel->toXMLList( a_writeInfo, indent2 );
591
592 a_writeInfo.addNodeEnder( moniker( ) );
593}
594
595}
#define GIDI_productChars
Definition GIDI.hpp:221
#define GIDI_outputChannelChars
Definition GIDI.hpp:227
#define GIDI_labelChars
Definition GIDI.hpp:438
#define GIDI_multiplicityChars
Definition GIDI.hpp:223
#define GIDI_averageEnergyChars
Definition GIDI.hpp:225
#define GIDI_pidChars
Definition GIDI.hpp:454
#define GIDI_averageMomentumChars
Definition GIDI.hpp:226
#define GIDI_distributionChars
Definition GIDI.hpp:224
std::size_t size() const
Definition GIDI.hpp:974
Matrix matrix(std::size_t a_index) const
Functions::Gridded3d const & data() const
Definition GIDI.hpp:2391
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
void setLabel(std::string const &a_label)
Definition GIDI_form.cc:114
virtual void mapToXsAndAdd(std::size_t a_offset, std::vector< double > const &a_Xs, std::vector< double > &a_results, double a_scaleFactor) const
Definition GIDI_form.cc:424
virtual double evaluate(double a_x1) const =0
Vector const & data() const
Definition GIDI.hpp:1254
Array3d const & data() const
Definition GIDI.hpp:1975
std::string const & ID() const
Definition GIDI.hpp:760
Component & averageMomentum()
Definition GIDI.hpp:3904
Vector multiGroupMultiplicity(LUPI::StatusMessageReporting &a_smr, Transporting::MG const &a_settings, Styles::TemperatureInfo const &a_temperatureInfo, std::string const &a_productID) const
Vector multiGroupQ(LUPI::StatusMessageReporting &a_smr, Transporting::MG const &a_settings, Styles::TemperatureInfo const &a_temperatureInfo, bool a_final) const
Component & averageEnergy()
Definition GIDI.hpp:3902
Component & multiplicity()
Definition GIDI.hpp:3898
bool hasFission() const
void toXMLList(GUPI::WriteInfo &a_writeInfo, std::string const &a_indent="") const
Vector multiGroupAverageEnergy(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
GUPI::Ancestry * findInAncestry3(std::string const &a_item)
Product(PoPI::Database const &a_pops, std::string const &a_productID, std::string const &a_label)
bool areAllProductsTracked(Transporting::Particles const &a_particles) const
int productMultiplicity(std::string const &a_productID) const
int maximumLegendreOrder(LUPI::StatusMessageReporting &a_smr, Transporting::MG const &a_settings, Styles::TemperatureInfo const &a_temperatureInfo, std::string const &a_productID) const
bool isDelayedFissionNeutronComplete(bool a_isDelayedNeutron) const
void productIDs(std::set< std::string > &a_ids, Transporting::Particles const &a_particles, bool a_transportablesOnly) const
bool isCompleteParticle() const
int depth() const
void calculateMultiGroupData(ProtareSingle const *a_protare, Styles::TemperatureInfo const &a_temperatureInfo, std::string const &a_heatedMultiGroupLabel, MultiGroupCalulationInformation const &a_multiGroupCalulationInformation, Functions::XYs1d const &a_crossSectionXYs1d)
void modifiedMultiGroupElasticForTNSL(std::map< std::string, std::size_t > const &a_maximumTNSL_MultiGroupIndex)
Matrix multiGroupProductMatrix(LUPI::StatusMessageReporting &a_smr, Transporting::MG const &a_settings, Styles::TemperatureInfo const &a_temperatureInfo, Transporting::Particles const &a_particles, std::string const &a_productID, std::size_t a_order) const
void incompleteParticles(Transporting::Settings const &a_settings, std::set< std::string > &a_incompleteParticles) const
ParticleInfo const & particle() const
Definition GIDI.hpp:3891
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
Vector multiGroupAverageMomentum(LUPI::StatusMessageReporting &a_smr, Transporting::MG const &a_settings, Styles::TemperatureInfo const &a_temperatureInfo, std::string const &a_productID) const
bool isPhotoAtomic() const
Definition GIDI.hpp:4746
bool isTNSL_ProtareSingle() const
Definition GIDI.hpp:4745
ParticleInfo const & projectile() const
Definition GIDI.hpp:4541
std::string m_initialState
Definition GIDI.hpp:604
ParticleSubstitution * m_particleSubstitution
Definition GIDI.hpp:598
ProtareSingle * m_protare
Definition GIDI.hpp:597
int m_outputChannelLevel
Definition GIDI.hpp:603
T * get(std::size_t a_Index)
Definition GIDI.hpp:2642
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
bool hasParticle(std::string const &a_id) const
void setMoniker(std::string const &a_moniker)
Definition GUPI.hpp:103
std::string const & moniker() const
Definition GUPI.hpp:102
std::string toXLink() const
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
Node child(const char *name) const
Definition HAPI_Node.cc:72
Definition GIDI.hpp:32
FormType
Definition GIDI.hpp:118
void calculate1dMultiGroupDataInComponent(ProtareSingle const *a_protare, std::string const &a_heatedMultiGroupLabel, MultiGroupCalulationInformation const &a_multiGroupCalulationInformation, Component &a_component, Functions::XYs1d const &a_crossSection)
Form * parseAverageEnergySuite(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)
Form * parseMultiplicitySuite(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)
Form * parseAverageMomentumSuite(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)
Form * parseDistributionSuite(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)
bool compareSpecialParticleIDs(std::string const &a_id1, std::string const &a_id2)
Definition PoPI_misc.cc:133
static std::string const photon
Definition PoPI.hpp:162