Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/Geant4/MCGIDI.hpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002 # <<BEGIN-copyright>>
0003 # Copyright 2019, Lawrence Livermore National Security, LLC.
0004 # This file is part of the gidiplus package (https://github.com/LLNL/gidiplus).
0005 # gidiplus is licensed under the MIT license (see https://opensource.org/licenses/MIT).
0006 # SPDX-License-Identifier: MIT
0007 # <<END-copyright>>
0008 */
0009 
0010 #ifndef MCGIDI_hpp_included
0011 #define MCGIDI_hpp_included 1
0012 
0013 #define MCGIDI_USE_DOUBLES 1
0014 #ifndef MCGIDI_USE_DOUBLES
0015     #define MCGIDI_FLOAT float
0016     #define DATA_MEMBER_VECTOR_FLOAT_OR_DOUBLE DATA_MEMBER_VECTOR_FLOAT
0017 #else
0018     #define MCGIDI_FLOAT double
0019     #define DATA_MEMBER_VECTOR_FLOAT_OR_DOUBLE DATA_MEMBER_VECTOR_DOUBLE
0020 #endif
0021 
0022 #define _USE_MATH_DEFINES
0023 #include "math.h"
0024 
0025 #include <LUPI.hpp>
0026 #include <PoPI.hpp>
0027 #include <GIDI.hpp>
0028 
0029 #ifdef MCGIDI_USE_VIRTUAL_FUNCTIONS
0030     #define MCGIDI_VIRTUAL_FUNCTION virtual
0031     #define MCGIDI_TRUE_VIRTUAL = 0
0032 #else
0033     #define MCGIDI_VIRTUAL_FUNCTION
0034     #define MCGIDI_TRUE_VIRTUAL
0035 #endif
0036 
0037 #if defined(HAVE_HIP) && defined(__HIP_DEVICE_COMPILE__)
0038     #define MCGIDI_PRINTF(...)
0039 #else
0040     #define MCGIDI_PRINTF printf
0041 #endif
0042 
0043 namespace MCGIDI {
0044 
0045 class Protare;
0046 class ProtareSingle;
0047 class ProtareComposite;
0048 class ProtareTNSL;
0049 class Reaction;
0050 class OutputChannel;
0051 class ACE_URR_probabilityTables;
0052 class GRIN_capture;
0053 class GRIN_inelastic;
0054 
0055 }           // End of namespace MCGIDI.
0056 
0057 #include <LUPI_dataBuffer.hpp>
0058 #include <MCGIDI_sampling.hpp>
0059 #include <MCGIDI_vector.hpp>
0060 #include <MCGIDI_string.hpp>
0061 
0062 namespace MCGIDI {
0063 
0064 #define MCGIDI_nullReaction 999999999
0065 
0066 // FIXME, this should not be used once physicalQuantity can handle changing units.
0067 #define MCGIDI_speedOfLight_cm_sh 299.792458
0068 #define MCGIDI_speedOfLight_cm_sec ( MCGIDI_speedOfLight_cm_sh * 1e8 )
0069 #define MCGIDI_classicalElectronRadius 0.2817940322010228 // Classical electron radius in unit of sqrt( b ).
0070 
0071 #define MCGIDI_particleBeta( a_mass_unitOfEnergy, a_kineticEnergy ) \
0072     ( (a_mass_unitOfEnergy) == 0.0 ? 1 : sqrt( (a_kineticEnergy) * ( (a_kineticEnergy) + 2.0 * (a_mass_unitOfEnergy) ) ) / ( (a_kineticEnergy) + (a_mass_unitOfEnergy) ) )
0073 
0074 LUPI_HOST_DEVICE double particleKineticEnergy( double a_mass_unitOfEnergy, double a_particleBeta );
0075 LUPI_HOST_DEVICE double particleKineticEnergyFromBeta2( double a_mass_unitOfEnergy, double a_particleBeta2 );    // a_particleBeta2 = a_particleBeta^2.
0076 LUPI_HOST_DEVICE double boostSpeed( double a_massProjectile, double a_kineticEnergyProjectile, double a_massTarget );
0077 LUPI_HOST_DEVICE int muCOM_From_muLab( double a_muLab, double a_boostBeta, double a_productBeta, double &a_muPlus, double &a_JacobianPlus, double &a_muMinus, double &a_JacobianMinus );
0078 
0079 enum class ProtareType { single, composite, TNSL };
0080 
0081 namespace Transporting {
0082 
0083 enum class URR_mode { none, pdfs, ACE_URR_probabilityTables };
0084 
0085 namespace LookupMode {
0086 
0087     enum class Data1d { continuousEnergy, multiGroup };
0088     enum class Distribution { pdf_cdf, epbs };
0089 
0090 }           // End of namespace LookupMode.
0091 
0092 namespace Reaction {
0093 
0094     enum class Type { Reactions, OrphanProducts };
0095 
0096 }           // End of namespace Reaction.
0097 
0098 /*
0099 ============================================================
0100 ============================ MC ============================
0101 ============================================================
0102 */
0103 class MC : public GIDI::Transporting::Settings {
0104 
0105     private:
0106         GIDI::Styles::Suite const *m_styles;                        /**< FIXME. */
0107         std::string m_label;                                        /**< FIXME. */
0108         double m_energyDomainMax;                                   /**< All reactions with a threshold greater than or equal to this value are ignored. */
0109         bool m_ignoreENDF_MT5;                                      /**< If true, the ENDF MT 5 reaction is ignored. */
0110         bool m_sampleNonTransportingParticles;                      /**< If true, all products are sampled, otherwise only transporting particles are sampled. */
0111         bool m_useSlowerContinuousEnergyConversion;                 /**< If true, the old slower conversion of GIDI::ProtareSingle to MCGIDI::HeatedCrossSectionContinuousEnergy is used. */
0112         bool m_addExpectedValueData;                                /**< If true, exected value data are included in the construction of a HeatedCrossSectionContinuousEnergy class. */
0113         LookupMode::Data1d m_crossSectionLookupMode;                /**< Determines how cross sections are evaluated. */
0114         LookupMode::Data1d m_other1dDataLookupMode;                 /**< Determines how 1d data other than cross sections are evaluated. */
0115         LookupMode::Distribution m_distributionLookupMode;          /**< Determines how distributions are evaluated and sampled. Currently, only pdf_cdf is allowed. */
0116         Sampling::Upscatter::Model m_upscatterModel;                /**< This enum specified the upscatter model to use when sampling products. */
0117         std::vector<double> m_upscatterModelAGroupBoundaries;       /**< If specified (i.e., non-zero length) then these values are used as the group boundaries for the upscatter model A multi-group cross section. */
0118         URR_mode m_URR_mode;                                        /**< Selects if URR data are to be used, and it so, which type. */
0119         bool m_wantTerrellPromptNeutronDistribution;                /**< If true, prompt fission neutron distributions are sampled from the Terrell mode. */
0120         bool m_wantRawTNSL_distributionSampling;                    /**< If true, the TNSL neutron distributions for coherent and incoherent elastic scattering are sampled from the double differential data. Otherwise, they are sampled from the distribution data. */
0121         std::vector<double> m_fixedGridPoints;                      /**< FIXME. */
0122         bool m_makePhotonEmissionProbabilitiesOne;                  /**< If true, all photon emission probabilities are set to 1.0 (i.e., all ICCs are set to 0.0). Default is false. */
0123         bool m_zeroNuclearLevelEnergyWidth;                         /**< If true, all NuclideGammaBranchStateInfo.m_nuclearLevelEnergyWidth members are set to 0.0. Default is false. */
0124 
0125     public:
0126         LUPI_HOST MC( PoPI::Database const &a_pops, std::string const &a_projectileID, GIDI::Styles::Suite const *a_styles, std::string const &a_label, 
0127                 GIDI::Transporting::DelayedNeutrons a_delayedNeutrons, double energyDomainMax );
0128         LUPI_HOST MC( PoPI::Database const &a_pops, GIDI::Protare const &a_protare, std::string const &a_label,
0129                 GIDI::Transporting::DelayedNeutrons a_delayedNeutrons, double energyDomainMax );
0130 
0131         LUPI_HOST GIDI::Styles::Suite const *styles( ) const { return( m_styles ); }               /**< Returns the value of the **m_styles**. */
0132         LUPI_HOST void styles( GIDI::Styles::Suite const *a_styles ) { m_styles = a_styles; }      /**< This is needed for ProtareTNSL, but should be avoided otherwise. FIXME, need to have a better way. */
0133 
0134         LUPI_HOST std::string label( ) const { return( m_label ); }
0135 
0136 // FIXME (1) should this not be something like
0137 // GIDI::Styles::Suite const &suite( ) const { return( *m_styles ); }                   /**< Returns a reference to **m_styles**. */
0138         LUPI_HOST double energyDomainMax( ) const { return( m_energyDomainMax ); }                /**< Returns the value of the **m_energyDomainMax**. */
0139 
0140         LUPI_HOST bool ignoreENDF_MT5( ) const { return( m_ignoreENDF_MT5 ); }                    /**< Returns the value of the **m_ignoreENDF_MT5**. */
0141         LUPI_HOST void set_ignoreENDF_MT5( bool a_ignoreENDF_MT5 ) { m_ignoreENDF_MT5 = a_ignoreENDF_MT5; }
0142         LUPI_HOST void setIgnoreENDF_MT5( bool a_ignoreENDF_MT5 ) { set_ignoreENDF_MT5( a_ignoreENDF_MT5 ); }
0143                             /**< This function is deprecated. Use **set_ignoreENDF_MT5** instead. */
0144 
0145         LUPI_HOST bool sampleNonTransportingParticles( ) const { return( m_sampleNonTransportingParticles); }
0146         LUPI_HOST void sampleNonTransportingParticles( bool a_sampleNonTransportingParticles ) {
0147                 LUPI::deprecatedFunction( "MCGIDI::Transporting::MC::sampleNonTransportingParticles", "MCGIDI::Transporting::MC::setSampleNonTransportingParticles", "" );
0148                 setSampleNonTransportingParticles( a_sampleNonTransportingParticles ); }
0149         LUPI_HOST void setSampleNonTransportingParticles( bool a_sampleNonTransportingParticles ) { m_sampleNonTransportingParticles = a_sampleNonTransportingParticles; }
0150 
0151         LUPI_HOST bool useSlowerContinuousEnergyConversion( ) const { return( m_useSlowerContinuousEnergyConversion ); }
0152         LUPI_HOST void setUseSlowerContinuousEnergyConversion( bool a_useSlowerContinuousEnergyConversion ) {
0153                 m_useSlowerContinuousEnergyConversion = a_useSlowerContinuousEnergyConversion; }
0154 
0155         LUPI_HOST bool addExpectedValueData( ) const { return( m_addExpectedValueData ); }      /**< Returns the value of the *m_addExpectedValueData* member. */
0156         LUPI_HOST void setAddExpectedValueData( bool a_addExpectedValueData ) { m_addExpectedValueData = a_addExpectedValueData; }  /**< Set the *m_addExpectedValueData* member to *a_addExpectedValueData*. */
0157 
0158         LUPI_HOST LookupMode::Data1d crossSectionLookupMode( ) const { return( m_crossSectionLookupMode ); }      /**< Returns the value of the **m_crossSectionLookupMode**. */
0159         LUPI_HOST void setCrossSectionLookupMode( LookupMode::Data1d a_crossSectionLookupMode );
0160         LUPI_HOST void crossSectionLookupMode( LookupMode::Data1d a_crossSectionLookupMode ) {
0161                 LUPI::deprecatedFunction( "MCGIDI::Transporting::MC::crossSectionLookupMode", "MCGIDI::Transporting::MC::setCrossSectionLookupMode", "" );
0162                 setCrossSectionLookupMode( a_crossSectionLookupMode ); }                                            /**< See method **setCrossSectionLookupMode**. This method is deprecated. */
0163 
0164         LUPI_HOST LookupMode::Data1d other1dDataLookupMode( ) const { return( m_other1dDataLookupMode ); }        /**< Returns the value of the **m_other1dDataLookupMode**. */
0165         LUPI_HOST void setOther1dDataLookupMode( LookupMode::Data1d a_other1dDataLookupMode );
0166         LUPI_HOST void other1dDataLookupMode( LookupMode::Data1d a_other1dDataLookupMode ) {
0167                 LUPI::deprecatedFunction( "MCGIDI::Transporting::MC::other1dDataLookupMode", "MCGIDI::Transporting::MC::setOther1dDataLookupMode", "" );
0168                 setOther1dDataLookupMode( a_other1dDataLookupMode ); }                                              /**< See method **setOther1dDataLookupMode**. This method is deprecated. */
0169 
0170         LUPI_HOST LookupMode::Distribution distributionLookupMode( ) const { return( m_distributionLookupMode ); }  /**< Returns the value of the **m_distributionLookupMode**. */
0171         LUPI_HOST void setDistributionLookupMode( LookupMode::Distribution a_distributionLookupMode );
0172         LUPI_HOST void distributionLookupMode( LookupMode::Distribution a_distributionLookupMode ) { 
0173                 LUPI::deprecatedFunction( "MCGIDI::Transporting::MC::distributionLookupMode", "MCGIDI::Transporting::MC::setDistributionLookupMode", "" );
0174                 setDistributionLookupMode( a_distributionLookupMode ); }                                            /**< See method **setDistributionLookupMode**. This method is deprecated. */
0175 
0176         LUPI_HOST Sampling::Upscatter::Model upscatterModel( ) const { return( m_upscatterModel ); }                /**< Returns the value of the **m_upscatterModel**. */
0177         LUPI_HOST void setUpscatterModelA( ) { m_upscatterModel = Sampling::Upscatter::Model::A; }                  /**< See member *m_upscatterModel* to Sampling::Upscatter::Model::A. */
0178         LUPI_HOST void setUpscatterModelB( ) { m_upscatterModel = Sampling::Upscatter::Model::B; }                  /**< Set member *m_upscatterModel* to Sampling::Upscatter::Model::B. */
0179         LUPI_HOST void setUpscatterModelBSnLimits( ) { m_upscatterModel = Sampling::Upscatter::Model::BSnLimits; }  /**< Set member *m_upscatterModel* to Sampling::Upscatter::Model::BSnLimits. */
0180         LUPI_HOST void setUpscatterModelDBRC( ) { m_upscatterModel = Sampling::Upscatter::Model::DBRC; }            /**< Set member *m_upscatterModel* to Sampling::Upscatter::Model::DBRC. */
0181         LUPI_HOST std::vector<double> const &upscatterModelAGroupBoundaries( ) { return( m_upscatterModelAGroupBoundaries ); }
0182                                                                                                                     /**< Returns a const reference to the *m_upscatterModelAGroupBoundaries* member. */
0183         LUPI_HOST void setUpscatterModelAGroupBoundaries( std::vector<double> const &a_groupBoundaries );
0184 
0185         LUPI_HOST bool want_URR_probabilityTables( ) const {
0186                 LUPI::deprecatedFunction( "MCGIDI::Transporting::MC::want_URR_probabilityTables", "MCGIDI::Transporting::MC::_URR_mode", "" );
0187                 return( m_URR_mode != URR_mode::none ); }            /**< Returns *false* if *m_URR_mode* is **URR_mode::none** and *true* otherwise. This method is deprecated. Please use **_URR_mode** instead. */
0188         LUPI_HOST void want_URR_probabilityTables( bool a_want_URR_probabilityTables ) {
0189                 LUPI::deprecatedFunction( "MCGIDI::Transporting::MC::want_URR_probabilityTables", "MCGIDI::Transporting::MC::setURR_mode", "" );
0190                 m_URR_mode = URR_mode::none;
0191                 if( a_want_URR_probabilityTables ) m_URR_mode = URR_mode::pdfs;
0192         }           /**< If *a_want_URR_probabilityTables* is *true* sets *m_URR_mode* to **URR_mode::pdfs**, otherwise set it to **URR_mode::none**. This method is deprecated. Please use **setURR_mode** instead. */
0193 
0194         LUPI_HOST URR_mode _URR_mode( ) const { return( m_URR_mode ); }                                           /**< Returns the value of the **m_URR_mode** member. */
0195         LUPI_HOST void setURR_mode( URR_mode a_URR_mode ) { m_URR_mode = a_URR_mode; }                            /**< This methods sets member *m_URR_mode* to *a_URR_mode*. */
0196 
0197         LUPI_HOST bool wantTerrellPromptNeutronDistribution( ) const { return( m_wantTerrellPromptNeutronDistribution ); }
0198                                     /**< Returns the value of the **m_wantTerrellPromptNeutronDistribution** member. */
0199         LUPI_HOST void setWantTerrellPromptNeutronDistribution( bool a_wantTerrellPromptNeutronDistribution ) {
0200                 m_wantTerrellPromptNeutronDistribution = a_wantTerrellPromptNeutronDistribution;
0201         }       /**< Set the *m_wantTerrellPromptNeutronDistribution* member to *a_wantTerrellPromptNeutronDistribution*. */
0202         LUPI_HOST void wantTerrellPromptNeutronDistribution( bool a_wantTerrellPromptNeutronDistribution ) {
0203                 LUPI::deprecatedFunction( "MCGIDI::Transporting::MC::wantTerrellPromptNeutronDistribution", "MCGIDI::Transporting::MC::setWantTerrellPromptNeutronDistribution", "" );
0204                 setWantTerrellPromptNeutronDistribution( a_wantTerrellPromptNeutronDistribution );
0205         }       /**< See method *setWantTerrellPromptNeutronDistribution*. This method is deprecated. */
0206 
0207         LUPI_HOST bool wantRawTNSL_distributionSampling( ) const { return( m_wantRawTNSL_distributionSampling ); }
0208         LUPI_HOST bool wantRawTNSL_distributionSampling( ) { return( m_wantRawTNSL_distributionSampling ); }
0209         LUPI_HOST void set_wantRawTNSL_distributionSampling( bool a_wantRawTNSL_distributionSampling ) { 
0210                 m_wantRawTNSL_distributionSampling = a_wantRawTNSL_distributionSampling; }
0211 
0212         LUPI_HOST std::vector<double> fixedGridPoints( ) const { return( m_fixedGridPoints ); }
0213         LUPI_HOST void fixedGridPoints( std::vector<double> a_fixedGridPoints ) { m_fixedGridPoints = a_fixedGridPoints; }
0214 
0215         LUPI_HOST bool makePhotonEmissionProbabilitiesOne( ) const { return( m_makePhotonEmissionProbabilitiesOne ); }
0216                                             /**< Returns the value of the **m_makePhotonEmissionProbabilitiesOne** member. */
0217         LUPI_HOST void setMakePhotonEmissionProbabilitiesOne( bool a_makePhotonEmissionProbabilitiesOne ) { m_makePhotonEmissionProbabilitiesOne = a_makePhotonEmissionProbabilitiesOne; }
0218                                             /**< Sets member *m_makePhotonEmissionProbabilitiesOne* to *a_makePhotonEmissionProbabilitiesOne*. */
0219         LUPI_HOST bool zeroNuclearLevelEnergyWidth( ) const { return( m_zeroNuclearLevelEnergyWidth ); }
0220                                             /**< Returns the value of the **m_zeroNuclearLevelEnergyWidth** member. */
0221         LUPI_HOST void setZeroNuclearLevelEnergyWidth( bool a_zeroNuclearLevelEnergyWidth ) { m_zeroNuclearLevelEnergyWidth = a_zeroNuclearLevelEnergyWidth ; }
0222                                             /**< Sets member *m_zeroNuclearLevelEnergyWidth* to *a_zeroNuclearLevelEnergyWidth*. */
0223 
0224         LUPI_HOST void process( GIDI::Protare const &a_protare );
0225 };
0226 
0227 }           // End of namespace Transporting.
0228 
0229 enum class TwoBodyOrder { notApplicable, firstParticle, secondParticle };
0230 
0231 /*
0232 ============================================================
0233 ============= ACE_URR_probabilityTablesFromGIDI ============
0234 ============================================================
0235 */
0236 
0237 class ACE_URR_probabilityTablesFromGIDI {
0238 
0239     public:
0240         LUPI_HOST ACE_URR_probabilityTablesFromGIDI( );
0241         LUPI_HOST ~ACE_URR_probabilityTablesFromGIDI( );
0242 
0243         std::map<std::string, ACE_URR_probabilityTables *> m_ACE_URR_probabilityTables;     // The string is the reaction's label.
0244 };
0245 
0246 /*
0247 ============================================================
0248 ========================= SetupInfo ========================
0249 ============================================================
0250 */
0251 class SetupInfo {
0252 
0253     public:
0254         ProtareSingle &m_protare;                               /**< The protare the data are loaded into. */
0255         GIDI::ProtareSingle const &m_GIDI_protare;              /**< The GIDI protare the data are loaded from. */
0256         PoPI::Database const &m_popsUser;                       /**< The PoPs from the user. */
0257         PoPI::Database const &m_pops;                           /**< The PoPs from the GNDS protare. */
0258         int m_neutronIndex;
0259         int m_photonIndex;
0260         LUPI::FormatVersion m_formatVersion;
0261         double m_Q;
0262         double m_product1Mass;
0263         double m_product2Mass;
0264         double m_domainMin;
0265         double m_domainMax;
0266         TwoBodyOrder m_twoBodyOrder;
0267         bool m_isPairProduction;
0268         bool m_isPhotoAtomicIncoherentScattering;
0269         std::string m_distributionLabel;                        /**< Set by the ProtareSingle constructor to the distribution label to use for all products. */
0270         std::map<std::string, int> m_particleIntids;            /**< A list of the particle intids for the transportable particles. */
0271         std::map<std::string, int> m_particleIndices;           /**< A list of the particle indices for the transportable particles. */
0272         GIDI::Reaction const *m_reaction;                       /**< A pointer to the current reaction whose data are being filled from the GIDI::ProtareSingle reaction. */
0273         Transporting::Reaction::Type m_reactionType;
0274         int m_initialStateIndex;                                /**< If not -1, then reaction contains a branching gamma data with this index for the data in m_nuclideGammaBranchStateInfos member of its **ProtareSingle** instance. */
0275         bool m_hasFinalStatePhotons;                            /**< If **true**, the reaction has a photon with finalState attribute. */
0276         std::map<std::string, int> m_initialStateIndices;       /**< If not -1, then reaction contains a branching gamma data with this index for the data in m_nuclideGammaBranchStateInfos member of its **ProtareSingle** instance. */
0277         std::map<std::string, int> m_stateNamesToIndices;       /**< A map of nuclide PoPs ids to their index in the ProtareSingle::m_nuclideGammaBranchStateInfos member. */
0278         std::map<std::string, double> m_nuclearLevelEnergies;   /**< A map of nuclide PoPs id to their nuclear level energy. */
0279         std::map<std::string, ACE_URR_probabilityTablesFromGIDI *> m_ACE_URR_probabilityTablesFromGIDI;
0280         GIDI::GRIN::GRIN_continuumGammas const *m_GRIN_continuumGammas;
0281 
0282         LUPI_HOST SetupInfo( ProtareSingle &a_protare, GIDI::ProtareSingle const &a_GIDI_protare, PoPI::Database const &a_popsUser, 
0283                 PoPI::Database const &a_pops );
0284         LUPI_HOST ~SetupInfo( );
0285 };
0286 
0287 /*
0288 ============================================================
0289 =========================== Others =========================
0290 ============================================================
0291 */
0292 LUPI_HOST int MCGIDI_popsIntid( PoPI::Database const &a_pops, std::string const &a_ID );
0293 LUPI_HOST int MCGIDI_popsIndex( PoPI::Database const &a_pops, std::string const &a_ID );
0294 
0295 #if 0
0296 /* *********************************************************************************************************//**
0297  * This function does a binary search of *a_Xs* for the *index* for which *a_Xs*[*index*] <= *a_x* < *a_Xs*[*index*+1].
0298  * The values of *a_Xs* must be ascending (i.e., *a_Xs*[i] < *a_Xs*[i+1]).
0299  *
0300  *
0301  *   Returns -2 if a_x < a_Xs[0] or return 0 if a_boundIndex is true,
0302  *           -1 if a_x > last point of a_Xs or returns a_Xs.size( ) - 1 if a_boundIndex is true, or
0303  *           the lower index of a_Xs which bound a_x otherwise.
0304              -3 if a_Xs has not data (i.e, its size is 0).
0305  *
0306  * Note, when *a_boundIndex* is false the returned *index* can be negative and when it is true the return 
0307  * value will be a valid index of *a_Xs*, including its last point unless a_Xs has not data *. The index of 
0308  * the last point is only returned when *a_boundIndex* is true and *a_x* is great than the last point of *a_Xs*.
0309  *
0310  * @param a_x               [in]    The values whose bounding index within *a_Xs* is to be determined.
0311  * @param a_Xs              [in]    The list of ascending values.
0312  * @param a_boundIndex      [in]    If true, out-of-bounds values a treated as end points.
0313  *
0314  * @return                          The *index*.
0315  ***********************************************************************************************************/
0316 #endif
0317 
0318 LUPI_HOST_DEVICE inline int binarySearchVector( double a_x, Vector<double> const &a_Xs, bool a_boundIndex = false ) {
0319 
0320     std::size_t lower = 0, middle, upper = a_Xs.size( ) - 1;
0321 
0322     if( a_Xs.size( ) == 0 ) {
0323         return( -3 ); }
0324     else if( a_x < a_Xs[0] ) {
0325         if( a_boundIndex ) return( 0 );
0326         return( -2 ); }
0327     else if( a_x > a_Xs.back( ) ) {
0328         if( a_boundIndex ) return( static_cast<int>( upper ) );
0329         return( -1 );
0330     }
0331 
0332     while( 1 ) {
0333         middle = ( lower + upper ) >> 1;
0334         if( middle == lower ) break;
0335         if( a_x < a_Xs[middle] ) {
0336             upper = middle; }
0337         else {
0338             lower = middle;
0339         }
0340     }
0341     return( static_cast<int>( lower ) );
0342 }
0343 
0344 /* *********************************************************************************************************//**
0345  ***********************************************************************************************************/
0346 
0347 LUPI_HOST_DEVICE inline int binarySearchVectorBounded( double a_x, Vector<double> const &a_Xs, std::size_t a_lower, 
0348                 std::size_t a_upper, bool a_boundIndex ) {
0349 
0350     std::size_t middle;
0351 
0352     if( a_Xs.size( ) == 0 ) {
0353         return( -3 ); }
0354     else if( a_x < a_Xs[a_lower] ) {
0355         if( a_boundIndex ) return( static_cast<int>( a_lower ) );
0356         return( -2 ); }
0357     else if( a_x > a_Xs[a_upper] ) {
0358         if( a_boundIndex ) return( static_cast<int>( a_upper ) );
0359         return( -1 );
0360     }
0361 
0362     while( 1 ) {
0363         middle = ( a_lower + a_upper ) >> 1;
0364         if( middle == a_lower ) break;
0365         if( a_x < a_Xs[middle] ) {
0366             a_upper = middle; }
0367         else {
0368             a_lower = middle;
0369         }
0370     }
0371     return( static_cast<int>( a_lower ) );
0372 }
0373 
0374 }           // End of namespace MCGIDI.
0375 
0376 #include "MCGIDI_functions.hpp"
0377 #include "MCGIDI_distributions.hpp"
0378 
0379 namespace MCGIDI {
0380 
0381 enum class ChannelType { none, twoBody, uncorrelatedBodies };
0382 
0383 /*
0384 ============================================================
0385 ===================== MultiGroupHash =======================
0386 ============================================================
0387 */
0388 class MultiGroupHash {
0389 
0390     private:
0391         Vector<double> m_boundaries;                                    /**< The list of multi-group boundaries. */
0392 
0393         LUPI_HOST void initialize( GIDI::Protare const &a_protare, GIDI::Styles::TemperatureInfo const &a_temperatureInfo, std::string a_particleID );
0394 
0395     public:
0396         LUPI_HOST_DEVICE MultiGroupHash( );
0397         LUPI_HOST MultiGroupHash( std::vector<double> a_boundaries );
0398         LUPI_HOST_DEVICE MultiGroupHash( Vector<double> a_boundaries );
0399         LUPI_HOST MultiGroupHash( GIDI::Protare const &a_protare, GIDI::Styles::TemperatureInfo const &a_temperatureInfo, std::string const &a_particleID = "" );
0400         LUPI_HOST MultiGroupHash( GIDI::Protare const &a_protare, GIDI::Transporting::Particles const &a_particles );
0401         LUPI_HOST MultiGroupHash( MultiGroupHash const &a_multiGroupHash );
0402         LUPI_HOST MultiGroupHash &operator=( MultiGroupHash const &a_rhs ) = default;
0403 
0404         LUPI_HOST_DEVICE Vector<double> const &boundaries( ) const { return( m_boundaries ); }   /**< Returns a reference to **m_styles**. */
0405         LUPI_HOST_DEVICE std::size_t index( double a_domain ) const {
0406             int _index = binarySearchVector( a_domain, m_boundaries );
0407 
0408             if( _index == -2 ) return( 0 );
0409             if( _index == -1 ) return( m_boundaries.size( ) - 2 );
0410             return( static_cast<std::size_t>( _index ) );
0411         }
0412         LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
0413 };
0414 
0415 /*
0416 ============================================================
0417 ====================== URR_protareInfo =====================
0418 ============================================================
0419 */
0420 class URR_protareInfo {
0421 
0422     public:
0423         bool m_inURR;
0424         double m_rng_Value;
0425 
0426         LUPI_HOST_DEVICE URR_protareInfo( ) : m_inURR( false ), m_rng_Value( 0.0 ) { }
0427         LUPI_HOST_DEVICE URR_protareInfo( URR_protareInfo const &a_URR_protareInfo ) {
0428             m_inURR = a_URR_protareInfo.m_inURR;
0429             m_rng_Value = a_URR_protareInfo.m_rng_Value;
0430         }
0431         LUPI_HOST_DEVICE URR_protareInfo &operator=( URR_protareInfo const &a_rhs ) {
0432 
0433             if( this != &a_rhs ) {
0434                 m_inURR = a_rhs.inURR( );
0435                 m_rng_Value = a_rhs.rng_Value( );
0436             }
0437 
0438             return( *this );
0439         }
0440 
0441         LUPI_HOST_DEVICE bool inURR( ) const { return( m_inURR ); }
0442         LUPI_HOST_DEVICE double rng_Value( ) const { return( m_rng_Value ); }
0443         LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
0444 };
0445 
0446 /*
0447 ============================================================
0448 ===================== URR_protareInfos =====================
0449 ============================================================
0450 */
0451 class URR_protareInfos {
0452 
0453     private:
0454         Vector<URR_protareInfo> m_URR_protareInfos;
0455 
0456     public:
0457         LUPI_HOST_DEVICE URR_protareInfos( ) : m_URR_protareInfos( ) { }
0458         LUPI_HOST URR_protareInfos( Vector<Protare *> &a_protares );
0459 
0460         LUPI_HOST void setup( Vector<Protare *> &a_protares );
0461 
0462         LUPI_HOST_DEVICE std::size_t size( ) const { return( m_URR_protareInfos.size( ) ); }
0463         LUPI_HOST_DEVICE URR_protareInfo const &operator[]( std::size_t a_index ) const { return( m_URR_protareInfos[a_index] ); }  /**< Returns the instance of *m_URR_protareInfos* at index *a_index*. */
0464 template <typename RNG>
0465         inline LUPI_HOST_DEVICE void updateProtare( MCGIDI::Protare const *a_protare, double a_energy, RNG && a_rng );
0466 
0467         LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
0468         LUPI_HOST_DEVICE std::size_t internalSize( ) const { return m_URR_protareInfos.internalSize( ); }
0469 };
0470 
0471 /*
0472 ============================================================
0473 ================= ACE_URR_probabilityTable =================
0474 ============================================================
0475 */
0476 
0477 class ACE_URR_probabilityTable {
0478 
0479     public:
0480         double m_energy;                                                /**< The projectile energy where the data are specified. */
0481         Vector<double> m_propabilities;                                 /**< The probability for each cross section. */
0482         Vector<double> m_crossSections;                                 /**< The cross section for each probability. */
0483 
0484         LUPI_HOST_DEVICE ACE_URR_probabilityTable( );
0485         LUPI_HOST ACE_URR_probabilityTable( double a_energy, std::vector<double> const &a_propabilities, std::vector<double> const &a_crossSection );
0486         LUPI_HOST_DEVICE ~ACE_URR_probabilityTable( );
0487 
0488         LUPI_HOST_DEVICE double energy( ) const { return( m_energy ); }
0489         LUPI_HOST_DEVICE double sample( double a_rng_Value );
0490         LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
0491 };
0492 
0493 /*
0494 ============================================================
0495 ================= ACE_URR_probabilityTables ================
0496 ============================================================
0497 */
0498 
0499 class ACE_URR_probabilityTables {
0500 
0501     public:
0502         Vector<double> m_energies;                                          /**< List of energies where probabilities tables are given. */
0503         Vector<ACE_URR_probabilityTable *> m_ACE_URR_probabilityTables;     /**< List of probabilities tables. One for each energy in *m_energies*. */
0504 
0505         LUPI_HOST_DEVICE ACE_URR_probabilityTables( );
0506         LUPI_HOST_DEVICE ACE_URR_probabilityTables( std::size_t a_capacity );
0507         LUPI_HOST_DEVICE ~ACE_URR_probabilityTables( );
0508 
0509         LUPI_HOST_DEVICE std::size_t capacity( ) const { return( m_energies.capacity( ) ); }
0510                                                                             /**< Returns the number of energies allocated to store probability tables. */
0511         LUPI_HOST_DEVICE std::size_t size( ) const { return( m_energies.size( ) ); }
0512                                                                             /**< Returns the number of energies that have URR probability tables. */
0513         LUPI_HOST_DEVICE void reserve( std::size_t a_capacity );
0514         LUPI_HOST_DEVICE void push_back( ACE_URR_probabilityTable *a_ACE_URR_probabilityTable );
0515 
0516         LUPI_HOST_DEVICE double domainMin( ) const { return( m_energies[0] ); }         /**< Returns the minimum energy where URR data are specified. */
0517         LUPI_HOST_DEVICE double domainMax( ) const { return( m_energies.back( ) ); }    /**< Returns the maximum energy where URR data are specified. */
0518         LUPI_HOST_DEVICE double sample( double a_energy, double a_rng_Value );
0519 
0520         LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
0521 };
0522 
0523 /*
0524 ============================================================
0525 ======== HeatedReactionCrossSectionContinuousEnergy ========
0526 ============================================================
0527 */
0528 
0529 class HeatedReactionCrossSectionContinuousEnergy {
0530 
0531     private:
0532         std::size_t m_offset;                                       /**< The offset relative to the cross section grid of the first cross section value in *m_crossSections*. */
0533         double m_threshold;                                         /**< The threshold for the reaction. */
0534         Vector<MCGIDI_FLOAT> m_crossSections;                       /**< The reaction's cross section. */
0535         Transporting::URR_mode m_URR_mode;                          /**< The URR data (i.e., mode) *this* has. */
0536         Probabilities::ProbabilityBase2d *m_URR_probabilityTables;  /**< Pointer to pdf URR probabilities if they were loaded. */
0537         ACE_URR_probabilityTables *m_ACE_URR_probabilityTables;     /**< The ACE URR probability tables for the reaction's cross section, if they were loaded. */
0538 
0539     public:
0540         LUPI_HOST_DEVICE HeatedReactionCrossSectionContinuousEnergy( );
0541         LUPI_HOST HeatedReactionCrossSectionContinuousEnergy( std::size_t a_offset, double a_threshold, Vector<double> &a_crossSection );
0542         LUPI_HOST HeatedReactionCrossSectionContinuousEnergy( double a_threshold, GIDI::Functions::Ys1d const &a_crossSection, 
0543                         Probabilities::ProbabilityBase2d *a_URR_probabilityTables, ACE_URR_probabilityTables *a_ACE_URR_probabilityTables );
0544         LUPI_HOST_DEVICE ~HeatedReactionCrossSectionContinuousEnergy( );
0545 
0546         LUPI_HOST_DEVICE double threshold( ) const { return( m_threshold ); }                           /**< Returns the value of the **m_threshold**. */
0547         LUPI_HOST_DEVICE std::size_t offset( ) const { return( m_offset ); }                            /**< Returns the value of the **m_offset**. */
0548         LUPI_HOST Vector<MCGIDI_FLOAT> const &crossSections( ) const { return( m_crossSections ); }     /**< Returns a reference to the member **m_crossSections**. */
0549         LUPI_HOST_DEVICE bool hasURR_probabilityTables( ) const {
0550             return( ( m_URR_probabilityTables != nullptr ) || ( m_ACE_URR_probabilityTables != nullptr ) );
0551         }                                                           /**< Returns true if URR probability tables data present and false otherwise. */
0552         LUPI_HOST_DEVICE Transporting::URR_mode URR_mode( ) const { return( m_URR_mode ); }             /**< Returns the value of **m_URR_mode**. */
0553         LUPI_HOST_DEVICE double URR_domainMin( ) const ;
0554         LUPI_HOST_DEVICE double URR_domainMax( ) const ;
0555         LUPI_HOST_DEVICE Probabilities::ProbabilityBase2d *URR_probabilityTables( ) const { return( m_URR_probabilityTables ); }      /**< Returns the value of the *m_URR_probabilityTables*. */
0556         LUPI_HOST_DEVICE ACE_URR_probabilityTables *_ACE_URR_probabilityTables( ) const { return( m_ACE_URR_probabilityTables ); }    /**< Returns the value of the *m_ACE_URR_probabilityTables*. */
0557         LUPI_HOST_DEVICE double crossSection( std::size_t a_index ) const {
0558             if( a_index < m_offset ) return( 0.0 );
0559             a_index -= m_offset;
0560             if( a_index >= m_crossSections.size( ) ) return( 0.0 );
0561 
0562             return( m_crossSections[a_index] );
0563         }
0564         LUPI_HOST GIDI::Functions::XYs1d crossSectionAsGIDI_XYs1d( double a_temperature, Vector<double> const &a_energies ) const ;
0565 
0566         LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
0567 
0568         LUPI_HOST void print( ProtareSingle const *a_protareSingle, std::string const &a_indent, std::string const &a_iFormat, 
0569                 std::string const &a_energyFormat, std::string const &a_dFormat ) const ;
0570 };
0571 
0572 /*
0573 ============================================================
0574 =================== ContinuousEnergyGain ===================
0575 ============================================================
0576 */
0577 class ContinuousEnergyGain {
0578 
0579     private:
0580         int m_particleIntid;
0581         int m_particleIndex;
0582         int m_userParticleIndex;
0583         Vector<MCGIDI_FLOAT> m_gain;
0584 
0585     public:
0586         LUPI_HOST_DEVICE ContinuousEnergyGain( );
0587         LUPI_HOST ContinuousEnergyGain( int a_particleIntid, int a_particleIndex, std::size_t a_size );
0588 
0589         LUPI_HOST ContinuousEnergyGain &operator=( ContinuousEnergyGain const &a_continuousEnergyGain );
0590 
0591         LUPI_HOST_DEVICE int particleIntid( ) const { return( m_particleIntid); }               /**< Returns the value of the *m_particleIntid* member of *this*. */
0592         LUPI_HOST_DEVICE int particleIndex( ) const { return( m_particleIndex ); }              /**< Returns the value of the *m_particleIndex* member of *this*. */
0593         LUPI_HOST_DEVICE int userParticleIndex( ) const { return( m_userParticleIndex ); }      /**< Returns the value of the *m_userParticleIndex* member of *this*. */
0594         LUPI_HOST void setUserParticleIndex( int a_particleIndex, int a_userParticleIndex ) {
0595                 if( a_particleIndex == m_particleIndex ) m_userParticleIndex = a_userParticleIndex; }
0596                                                         /**< Sets member *m_userParticleIndex* to *a_userParticleIndex* if particle's index matchs *m_particleIndex*. */
0597         LUPI_HOST void setUserParticleIndexViaIntid( int a_particleIntid, int a_userParticleIndex ) {
0598                 if( a_particleIntid == m_particleIntid ) m_userParticleIndex = a_userParticleIndex; }
0599                                                         /**< Sets member *m_userParticleIntid* to *a_userParticleIndex* if particle's intid matchs *m_particleIntid*. */
0600         LUPI_HOST_DEVICE Vector<MCGIDI_FLOAT> const &gain( ) const { return( m_gain ); }
0601         LUPI_HOST void adjustGain( std::size_t a_energy_index, double a_gain ) { m_gain[a_energy_index] += a_gain; }
0602         LUPI_HOST_DEVICE double gain( std::size_t a_energy_index, double a_energy_fraction ) const ;
0603 
0604         LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
0605         LUPI_HOST void print( ProtareSingle const *a_protareSingle, std::string const &a_indent, std::string const &a_iFormat, 
0606                 std::string const &a_energyFormat, std::string const &a_dFormat ) const ;
0607 };
0608 
0609 /*
0610 ============================================================
0611 =========== HeatedCrossSectionContinuousEnergy =============
0612 ============================================================
0613 */
0614 class HeatedCrossSectionContinuousEnergy {
0615 
0616     private:
0617         double m_temperature;                                   /**< The target temperature of the data. */
0618         Vector<std::size_t> m_hashIndices;                      /**< The indicies for the energy hash function. */
0619         Vector<double> m_energies;                              /**< Energy grid for cross sections. */
0620         Vector<MCGIDI_FLOAT> m_totalCrossSection;               /**< The total cross section. */
0621         Vector<MCGIDI_FLOAT> m_depositionEnergy;                /**< The total continuous energy, deposition-energy cross section (related to the kinetic energy of the untracked outgoing particles). */
0622         Vector<MCGIDI_FLOAT> m_depositionMomentum;              /**< The total continuous energy, deposition-momentum cross section. */
0623         Vector<MCGIDI_FLOAT> m_productionEnergy;                /**< The total continuous energy, Q-value cross section. */
0624         Vector<ContinuousEnergyGain *> m_gains;                 /**< The total continuous energy, gain cross section for each tracked particle. */
0625         Transporting::URR_mode m_URR_mode;                      /**< The URR data (i.e., mode) *this* has. */
0626         Vector<std::size_t> m_reactionsInURR_region;            /**< A list of reactions within or below the upper URR regions. This is empty unless URR probability tables present and used. */
0627         Vector<HeatedReactionCrossSectionContinuousEnergy *> m_reactionCrossSections;
0628                                                                 /**< Reaction cross section data for each reaction. */
0629         ACE_URR_probabilityTables *m_ACE_URR_probabilityTables; /**< The ACE URR probability tables for the summed URR cross section, if they were loaded. */
0630 
0631     public:
0632         LUPI_HOST_DEVICE HeatedCrossSectionContinuousEnergy( );
0633         LUPI_HOST HeatedCrossSectionContinuousEnergy( SetupInfo &a_setupInfo, Transporting::MC const &a_settings, GIDI::Transporting::Particles const &a_particles,
0634                 DomainHash const &a_domainHash, GIDI::Styles::TemperatureInfo const &a_temperatureInfo, std::vector<GIDI::Reaction const *> const &a_reactions,
0635                 std::vector<GIDI::Reaction const *> const &a_orphanProducts, bool a_fixedGrid, bool a_zeroReactions );
0636         LUPI_HOST_DEVICE ~HeatedCrossSectionContinuousEnergy( );
0637 
0638         LUPI_HOST_DEVICE std::size_t evaluationInfo( std::size_t a_hashIndex, double a_energy, double *a_energyFraction ) const ;
0639 
0640         LUPI_HOST HeatedReactionCrossSectionContinuousEnergy const *reactionCrossSection( std::size_t a_index ) const 
0641                 { return( m_reactionCrossSections[a_index] ); } /**< Returns the reaction cross section at index *a_index*. */
0642 
0643         LUPI_HOST_DEVICE double temperature( ) const { return( m_temperature ); }           /**< Returns the value of the **m_temperature** member. */
0644         LUPI_HOST_DEVICE double minimumEnergy( ) const { return( m_energies[0] ); }         /**< Returns the minimum cross section domain. */
0645         LUPI_HOST_DEVICE double maximumEnergy( ) const { return( m_energies.back( ) ); }    /**< Returns the maximum cross section domain. */
0646         LUPI_HOST_DEVICE std::size_t numberOfReactions( ) const { return( m_reactionCrossSections.size( ) ); } 
0647                                                                 /**< Returns the number of reaction cross section. */
0648 
0649         LUPI_HOST_DEVICE std::size_t thresholdOffset( std::size_t a_reactionIndex ) const { return( m_reactionCrossSections[a_reactionIndex]->offset( ) ); }
0650                                                                 /**< Returns the offset for the cross section for the reaction with index *a_reactionIndex*. */
0651         LUPI_HOST_DEVICE double threshold( std::size_t a_reactionIndex ) const { return( m_reactionCrossSections[a_reactionIndex]->threshold( ) ); }
0652                                                                 /**< Returns the threshold for the reaction with index *a_reactionIndex*. */
0653         LUPI_HOST_DEVICE bool hasURR_probabilityTables( ) const ;
0654         LUPI_HOST_DEVICE double URR_domainMin( ) const ;
0655         LUPI_HOST_DEVICE double URR_domainMax( ) const ;
0656         LUPI_HOST_DEVICE bool reactionHasURR_probabilityTables( std::size_t a_index ) const { return( m_reactionCrossSections[a_index]->hasURR_probabilityTables( ) ); }
0657 
0658         LUPI_HOST_DEVICE Vector<MCGIDI_FLOAT> &totalCrossSection( ) { return( m_totalCrossSection ); }     /**< Returns a reference to member *m_totalCrossSection*. */
0659         LUPI_HOST_DEVICE double crossSection(                               URR_protareInfos const &a_URR_protareInfos, int a_URR_index, std::size_t a_hashIndex, double a_energy, bool a_sampling = false ) const ;
0660         LUPI_HOST GIDI::Functions::XYs1d crossSectionAsGIDI_XYs1d( ) const ;
0661 
0662         LUPI_HOST_DEVICE double reactionCrossSection(  std::size_t a_reactionIndex, URR_protareInfos const &a_URR_protareInfos, int a_URR_index, std::size_t a_hashIndex, double a_energy, bool a_sampling = false ) const ;
0663         LUPI_HOST_DEVICE double reactionCrossSection2( std::size_t a_reactionIndex, URR_protareInfos const &a_URR_protareInfos, int a_URR_index, double a_energy, 
0664                 std::size_t a_energyIndex, double a_energyFraction, bool a_sampling = false ) const ;
0665         LUPI_HOST_DEVICE double reactionCrossSection(  std::size_t a_reactionIndex, URR_protareInfos const &a_URR_protareInfos, int a_URR_index, double a_energy ) const ;
0666         LUPI_HOST GIDI::Functions::XYs1d reactionCrossSectionAsGIDI_XYs1d( std::size_t a_reactionIndex ) const ;
0667 
0668         LUPI_HOST_DEVICE double depositionEnergy(   std::size_t a_hashIndex, double a_energy ) const ;
0669         LUPI_HOST_DEVICE double depositionMomentum( std::size_t a_hashIndex, double a_energy ) const ;
0670         LUPI_HOST_DEVICE double productionEnergy(   std::size_t a_hashIndex, double a_energy ) const ;
0671         LUPI_HOST_DEVICE double gain(               std::size_t a_hashIndex, double a_energy, int a_particleIndex ) const ;
0672         LUPI_HOST_DEVICE double gainViaIntid(       std::size_t a_hashIndex, double a_energy, int a_particleIntid ) const ;
0673 
0674         LUPI_HOST void setUserParticleIndex( int a_particleIndex, int a_userParticleIndex );
0675         LUPI_HOST void setUserParticleIndexViaIntid( int a_particleIntid, int a_userParticleIndex );
0676         LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
0677 
0678         LUPI_HOST_DEVICE Vector<double> const &energies( ) const { return( m_energies ); }       /**< Returns a reference to **m_styles**. */
0679 
0680         LUPI_HOST void print( ProtareSingle const *a_protareSingle, std::string const &a_indent, std::string const &a_iFormat, 
0681                 std::string const &a_energyFormat, std::string const &a_dFormat ) const ;
0682 };
0683 
0684 /*
0685 ============================================================
0686 ============ HeatedCrossSectionsContinuousEnergy ===========
0687 ============================================================
0688 */
0689 class HeatedCrossSectionsContinuousEnergy {
0690 
0691     private:
0692         Vector<double> m_temperatures;                                      /**< The list of temperatures that have **HeatedCrossSectionContinuousEnergy** data. */
0693         Vector<double> m_thresholds;                                        /**< The threshold for each reaction. */
0694         Vector<HeatedCrossSectionContinuousEnergy *> m_heatedCrossSections; /**< One **HeatedCrossSectionContinuousEnergy** instance for each temperature in *m_temperature*. */
0695 
0696     public:
0697         LUPI_HOST_DEVICE HeatedCrossSectionsContinuousEnergy( );
0698         LUPI_HOST_DEVICE ~HeatedCrossSectionsContinuousEnergy( );
0699 
0700         LUPI_HOST_DEVICE void clear( );
0701 
0702         LUPI_HOST void update( LUPI::StatusMessageReporting &a_smr, SetupInfo &a_setupInfo, Transporting::MC const &a_settings, GIDI::Transporting::Particles const &a_particles, DomainHash const &a_domainHash, 
0703                 GIDI::Styles::TemperatureInfos const &a_temperatureInfos, std::vector<GIDI::Reaction const *> const &a_reactions, 
0704                 std::vector<GIDI::Reaction const *> const &a_orphanProducts, bool a_fixedGrid, bool a_zeroReactions );
0705 
0706         LUPI_HOST_DEVICE double minimumEnergy( ) const { return( m_heatedCrossSections[0]->minimumEnergy( ) ); }
0707                                                                     /**< Returns the minimum cross section domain. */
0708         LUPI_HOST_DEVICE double maximumEnergy( ) const { return( m_heatedCrossSections[0]->maximumEnergy( ) ); }
0709                                                                     /**< Returns the maximum cross section domain. */
0710         LUPI_HOST_DEVICE Vector<double> const &temperatures( ) const { return( m_temperatures ); }   /**< Returns the value of the **m_temperatures**. */
0711         Vector<HeatedCrossSectionContinuousEnergy *> &heatedCrossSections( ) { return( m_heatedCrossSections ); }
0712 
0713         LUPI_HOST_DEVICE double threshold( std::size_t a_index ) const { return( m_thresholds[a_index] ); }     /**< Returns the threshold for the reaction at index *a_index*. */
0714         LUPI_HOST_DEVICE bool hasURR_probabilityTables( ) const { return( m_heatedCrossSections[0]->hasURR_probabilityTables( ) ); }
0715         LUPI_HOST_DEVICE double URR_domainMin( ) const { return( m_heatedCrossSections[0]->URR_domainMin( ) ); }
0716         LUPI_HOST_DEVICE double URR_domainMax( ) const { return( m_heatedCrossSections[0]->URR_domainMax( ) ); }
0717         LUPI_HOST_DEVICE bool reactionHasURR_probabilityTables( std::size_t a_index ) const { return( m_heatedCrossSections[0]->reactionHasURR_probabilityTables( a_index ) ); }
0718 
0719         LUPI_HOST_DEVICE double crossSection(                              URR_protareInfos const &a_URR_protareInfos, int a_URR_index, std::size_t a_hashIndex, 
0720                 double a_temperature, double a_energy, bool a_sampling = false ) const ;
0721         LUPI_HOST_DEVICE void crossSectionVector( double a_temperature, double a_userFactor, std::size_t a_numberAllocated, 
0722                 double *a_crossSectionVector ) const ;
0723         LUPI_HOST GIDI::Functions::XYs1d crossSectionAsGIDI_XYs1d( double a_temperature ) const ;
0724 
0725         LUPI_HOST_DEVICE double reactionCrossSection( std::size_t a_reactionIndex, URR_protareInfos const &a_URR_protareInfos, int a_URR_index, std::size_t a_hashIndex, 
0726                 double a_temperature, double a_energy, bool a_sampling = false ) const ;
0727         LUPI_HOST_DEVICE double reactionCrossSection( std::size_t a_reactionIndex, URR_protareInfos const &a_URR_protareInfos, int a_URR_index, double a_temperature, double a_energy_in ) const ;
0728         LUPI_HOST GIDI::Functions::XYs1d reactionCrossSectionAsGIDI_XYs1d( std::size_t a_reactionIndex, double a_temperature ) const ;
0729 
0730         template <typename RNG>
0731         inline LUPI_HOST_DEVICE std::size_t sampleReaction(                        URR_protareInfos const &a_URR_protareInfos, int a_URR_index, 
0732                 std::size_t a_hashIndex, double a_temperature, double a_energy, double a_crossSection, RNG && a_rng) const ;
0733 
0734         LUPI_HOST_DEVICE double depositionEnergy(   std::size_t a_hashIndex, double a_temperature, double a_energy ) const ;
0735         LUPI_HOST_DEVICE double depositionMomentum( std::size_t a_hashIndex, double a_temperature, double a_energy ) const ;
0736         LUPI_HOST_DEVICE double productionEnergy(   std::size_t a_hashIndex, double a_temperature, double a_energy ) const ;
0737         LUPI_HOST_DEVICE double gain(               std::size_t a_hashIndex, double a_temperature, double a_energy, int a_particleIndex ) const ;
0738         LUPI_HOST_DEVICE double gainViaIntid(       std::size_t a_hashIndex, double a_temperature, double a_energy, int a_particleIntid ) const ;
0739 
0740         LUPI_HOST void setUserParticleIndex( int a_particleIndex, int a_userParticleIndex );
0741         LUPI_HOST void setUserParticleIndexViaIntid( int a_particleIntid, int a_userParticleIndex );
0742         LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
0743 
0744         LUPI_HOST void print( ProtareSingle const *a_protareSingle, std::string const &a_indent, std::string const &a_iFormat, 
0745                 std::string const &a_energyFormat, std::string const &a_dFormat ) const ;
0746 };
0747 
0748 /*
0749 ============================================================
0750 ====================== MultiGroupGain ======================
0751 ============================================================
0752 */
0753 class MultiGroupGain {
0754 
0755     private:
0756         int m_particleIntid;
0757         int m_particleIndex;
0758         int m_userParticleIndex;
0759         Vector<double> m_gain;
0760 
0761     public:
0762         LUPI_HOST_DEVICE MultiGroupGain( );
0763         LUPI_HOST MultiGroupGain( int a_particleIntid, int a_particleIndex, GIDI::Vector const &a_gain );
0764 
0765         LUPI_HOST MultiGroupGain &operator=( MultiGroupGain const &a_multiGroupGain );
0766 
0767         LUPI_HOST_DEVICE int particleIntid( ) const { return( m_particleIntid ); }              /**< Returns the value of the *m_particleIntid* member of *this*. */
0768         LUPI_HOST_DEVICE int particleIndex( ) const { return( m_particleIndex ); }              /**< Returns the value of the *m_particleIndex* member of *this*. */
0769         LUPI_HOST_DEVICE int userParticleIndex( ) const { return( m_userParticleIndex ); }      /**< Returns the value of the *m_userParticleIndex* member of *this*. */
0770         LUPI_HOST void setUserParticleIndex( int a_particleIndex, int a_userParticleIndex ) {
0771                 if( a_particleIndex == m_particleIndex ) m_userParticleIndex = a_userParticleIndex; }
0772                                                         /**< Sets member *m_userParticleIndex* to *a_userParticleIndex* if particle's index matchs *m_particleIndex*. */
0773         LUPI_HOST void setUserParticleIndexViaIntid( int a_particleIntid, int a_userParticleIndex ) {
0774                 if( a_particleIntid == m_particleIntid ) m_userParticleIndex = a_userParticleIndex; }
0775                                                         /**< Sets member *m_userParticleIntid* to *a_userParticleIndex* if particle's intid matchs *m_particleIntid*. */
0776         LUPI_HOST_DEVICE Vector<double> const &gain( ) const { return( m_gain ); }
0777         LUPI_HOST_DEVICE double gain( std::size_t a_hashIndex ) const { return( m_gain[a_hashIndex] ); }
0778 
0779         LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
0780         LUPI_HOST void write( FILE *a_file ) const ;
0781 };
0782 
0783 /*
0784 ============================================================
0785 =========== HeatedReactionCrossSectionMultiGroup ===========
0786 ============================================================
0787 */
0788 class HeatedReactionCrossSectionMultiGroup {
0789 
0790     private:
0791         double m_threshold;
0792         std::size_t m_offset;
0793         Vector<double> m_crossSections;             // Multi-group reaction cross section
0794         double m_augmentedThresholdCrossSection;    // Augmented cross section at m_offset for rejecting when projectile energy is below m_threshold.
0795                                                     // This value is added to m_crossSections[m_offset] when sampling an isotope or reaction.
0796 
0797     public:
0798         LUPI_HOST_DEVICE HeatedReactionCrossSectionMultiGroup( );
0799         LUPI_HOST HeatedReactionCrossSectionMultiGroup( SetupInfo &a_setupInfo, Transporting::MC const &a_settings, 
0800                 std::size_t a_offset, std::vector<double> const &a_crossSection, double a_threshold );
0801 
0802         LUPI_HOST_DEVICE double operator[]( std::size_t a_index ) const { return( m_crossSections[a_index] ); }  /**< Returns the value of the cross section at multi-group index *a_index*. */
0803         LUPI_HOST_DEVICE double threshold( ) const { return( m_threshold ); }        /**< Returns the value of the **m_threshold**. */
0804         LUPI_HOST_DEVICE std::size_t offset( ) const { return( m_offset ); }                 /**< Returns the value of the **m_offset**. */
0805         LUPI_HOST_DEVICE double crossSection( std::size_t a_index, bool a_sampling = false ) const {
0806             if( a_index < m_offset ) return( 0.0 );
0807             std::size_t index = a_index - m_offset;
0808             if( index >= m_crossSections.size( ) ) return( 0.0 );
0809 
0810             double _crossSection( m_crossSections[index] );
0811             if( a_sampling && ( index == 0 ) ) {
0812                 _crossSection += m_augmentedThresholdCrossSection;
0813             }
0814             return( _crossSection );
0815         }
0816         LUPI_HOST_DEVICE double augmentedThresholdCrossSection( ) const { return( m_augmentedThresholdCrossSection ); }  /**< Returns the value of the **m_augmentedThresholdCrossSection**. */
0817         LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
0818         LUPI_HOST void write( FILE *a_file, std::size_t a_reactionIndex ) const ;
0819 };
0820 
0821 /*
0822 ============================================================
0823 ============== HeatedCrossSectionMultiGroup  ==============
0824 ============================================================
0825 */
0826 class HeatedCrossSectionMultiGroup {
0827 
0828     private:
0829         Vector<double> m_totalCrossSection;                 /**< The total multi-group cross section. */
0830         Vector<double> m_augmentedCrossSection;             /**< The total multi-group cross section used for sampling with rejection (i.e., null-reactions). */
0831         Vector<double> m_depositionEnergy;                  /**< The total multi-group, deposition-energy cross section (related to the kinetic energy of the untracked outgoing particles). */
0832         Vector<double> m_depositionMomentum;                /**< The total multi-group, deposition-momentum cross section. */
0833         Vector<double> m_productionEnergy;                  /**< The total multi-group, Q-value cross section. */
0834         Vector<MultiGroupGain *> m_gains;                   /**< The total multi-group, gain cross section for each tracked particle. */
0835         Vector<HeatedReactionCrossSectionMultiGroup *> m_reactionCrossSections;
0836 
0837     public:
0838         LUPI_HOST_DEVICE HeatedCrossSectionMultiGroup( );
0839         LUPI_HOST HeatedCrossSectionMultiGroup( LUPI::StatusMessageReporting &a_smr, GIDI::ProtareSingle const &a_protare, SetupInfo &a_setupInfo, 
0840                 Transporting::MC const &a_settings, GIDI::Styles::TemperatureInfo const &a_temperatureInfo,
0841                 GIDI::Transporting::Particles const &a_particles, std::vector<GIDI::Reaction const *> const &a_reactions, std::string const &a_label,
0842                 bool a_zeroReactions, GIDI::ExcludeReactionsSet const &a_reactionsToExclude );
0843         LUPI_HOST_DEVICE ~HeatedCrossSectionMultiGroup( );
0844 
0845         LUPI_HOST_DEVICE HeatedReactionCrossSectionMultiGroup *operator[]( std::size_t a_index ) const { return( m_reactionCrossSections[a_index] ); }
0846                                                                                 /**< Returns the HeatedReactionCrossSectionMultiGroup for the reaction at index *a_index *a_index*. */
0847         LUPI_HOST_DEVICE std::size_t numberOfReactions( ) const { return( m_reactionCrossSections.size( ) ); }
0848                                                                                 /**< Returns the number of reactions stored in *this*. */
0849 
0850         LUPI_HOST_DEVICE std::size_t thresholdOffset(                      std::size_t a_index ) const { return( m_reactionCrossSections[a_index]->offset( ) ); }
0851                                                                                 /**< Returns the offset for the cross section for the reaction with index *a_index*. */
0852         LUPI_HOST_DEVICE double threshold(                                 std::size_t a_index ) const { return( m_reactionCrossSections[a_index]->threshold( ) ); }
0853 
0854         LUPI_HOST_DEVICE Vector<double> &totalCrossSection( ) { return( m_totalCrossSection ); }    /**< Returns a reference to member *m_totalCrossSection*. */
0855         LUPI_HOST_DEVICE double crossSection(                              std::size_t a_hashIndex, bool a_sampling = false ) const ;
0856         LUPI_HOST_DEVICE double augmentedCrossSection(                     std::size_t a_hashIndex ) const { return( m_augmentedCrossSection[a_hashIndex] ); }
0857                                                                                 /**< Returns the value of the of the augmented cross section the reaction at index *a_index*. */
0858         LUPI_HOST_DEVICE double reactionCrossSection( std::size_t a_reactionIndex, std::size_t a_hashIndex, 
0859                 bool a_sampling = false ) const {
0860                 return( m_reactionCrossSections[a_reactionIndex]->crossSection( a_hashIndex, a_sampling ) ); }
0861                 /**< Returns the reaction's cross section for the reaction at index *a_reactionIndex* and multi-group index *a_hashIndex*. */
0862 
0863         LUPI_HOST_DEVICE double depositionEnergy(   std::size_t a_hashIndex ) const { return( m_depositionEnergy[a_hashIndex] ); }
0864         LUPI_HOST_DEVICE double depositionMomentum( std::size_t a_hashIndex ) const { return( m_depositionMomentum[a_hashIndex] ); }
0865         LUPI_HOST_DEVICE double productionEnergy(   std::size_t a_hashIndex ) const { return( m_productionEnergy[a_hashIndex] ); }
0866         LUPI_HOST_DEVICE double gain(               std::size_t a_hashIndex, int a_particleIndex ) const ;
0867         LUPI_HOST_DEVICE double gainViaIntid(       std::size_t a_hashIndex, int a_particleIntid ) const ;
0868 
0869         LUPI_HOST void setUserParticleIndex( int a_particleIndex, int a_userParticleIndex );
0870         LUPI_HOST void setUserParticleIndexViaIntid( int a_particleIntid, int a_userParticleIndex );
0871 
0872         LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
0873         LUPI_HOST void write( FILE *a_file ) const ;
0874 };
0875 
0876 /*
0877 ============================================================
0878 ============== HeatedCrossSectionsMultiGroup ==============
0879 ============================================================
0880 */
0881 class HeatedCrossSectionsMultiGroup {
0882 
0883     private:
0884         Vector<double> m_temperatures;
0885         Vector<double> m_thresholds;
0886         Vector<int> m_multiGroupThresholdIndex;                             /**< This is the group where threshold starts, -1 otherwise. */
0887         Vector<double> m_projectileMultiGroupBoundariesCollapsed;
0888         Vector<HeatedCrossSectionMultiGroup *> m_heatedCrossSections;
0889 
0890     public:
0891         LUPI_HOST_DEVICE HeatedCrossSectionsMultiGroup( );
0892         LUPI_HOST_DEVICE ~HeatedCrossSectionsMultiGroup( );
0893 
0894         LUPI_HOST_DEVICE double minimumEnergy( ) const { return( m_projectileMultiGroupBoundariesCollapsed[0] ); }
0895         LUPI_HOST_DEVICE double maximumEnergy( ) const { return( m_projectileMultiGroupBoundariesCollapsed.back( ) ); }
0896         LUPI_HOST_DEVICE Vector<double> const &temperatures( ) const { return( m_temperatures ); }   /**< Returns the value of the **m_temperatures**. */
0897 
0898         LUPI_HOST void update( LUPI::StatusMessageReporting &a_smr, GIDI::ProtareSingle const &a_protare, SetupInfo &a_setupInfo, Transporting::MC const &a_settings, GIDI::Transporting::Particles const &a_particles, 
0899                 GIDI::Styles::TemperatureInfos const &a_temperatureInfos, std::vector<GIDI::Reaction const *> const &a_reactions, 
0900                 std::vector<GIDI::Reaction const *> const &a_orphanProducts, bool a_zeroReactions, GIDI::ExcludeReactionsSet const &a_reactionsToExclude );
0901 
0902         LUPI_HOST_DEVICE int multiGroupThresholdIndex( std::size_t a_index ) const { return( m_multiGroupThresholdIndex[a_index] ); }
0903                                                                                                     /**< Returns the threshold for the reaction at index *a_index*. */
0904         LUPI_HOST_DEVICE Vector<double> const &projectileMultiGroupBoundariesCollapsed( ) const { return( m_projectileMultiGroupBoundariesCollapsed ); }
0905                                                                                                     /**< Returns the value of the **m_projectileMultiGroupBoundariesCollapsed**. */
0906         LUPI_HOST_DEVICE Vector<HeatedCrossSectionMultiGroup *> const &heatedCrossSections( ) const { return( m_heatedCrossSections ); }
0907 
0908         LUPI_HOST_DEVICE double threshold( std::size_t a_index ) const { return( m_thresholds[a_index] ); }     /**< Returns the threshold for the reaction at index *a_index*. */
0909 
0910         LUPI_HOST_DEVICE double crossSection(                              std::size_t a_hashIndex, double a_temperature, bool a_sampling = false ) const ;
0911         LUPI_HOST_DEVICE void crossSectionVector( double a_temperature, double a_userFactor, std::size_t a_numberAllocated, 
0912                 double *a_crossSectionVector ) const ;
0913         LUPI_HOST_DEVICE double reactionCrossSection( std::size_t a_reactionIndex, std::size_t a_hashIndex, double a_temperature, bool a_sampling = false ) const ;
0914         LUPI_HOST_DEVICE double reactionCrossSection( std::size_t a_reactionIndex, double a_temperature, double a_energy_in ) const ;
0915         template <typename RNG>
0916         inline LUPI_HOST_DEVICE std::size_t sampleReaction(                std::size_t a_hashIndex, double a_temperature, double a_energy_in, 
0917                 double a_crossSection, RNG &&rng) const;
0918 
0919         LUPI_HOST_DEVICE double depositionEnergy(   std::size_t a_hashIndex, double a_temperature ) const ;
0920         LUPI_HOST_DEVICE double depositionMomentum( std::size_t a_hashIndex, double a_temperature ) const ;
0921         LUPI_HOST_DEVICE double productionEnergy(   std::size_t a_hashIndex, double a_temperature ) const ;
0922         LUPI_HOST_DEVICE double gain(               std::size_t a_hashIndex, double a_temperature, int a_particleIndex ) const ;
0923         LUPI_HOST_DEVICE double gainViaIntid(       std::size_t a_hashIndex, double a_temperature, int a_particleIntid ) const ;
0924 
0925         LUPI_HOST void setUserParticleIndex( int a_particleIndex, int a_userParticleIndex );
0926         LUPI_HOST void setUserParticleIndexViaIntid( int a_particleIntid, int a_userParticleIndex );
0927 
0928         LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
0929         LUPI_HOST void write( FILE *a_file, int a_temperatureIndex ) const ;
0930         LUPI_HOST void print( ) const ;
0931 };
0932 
0933 /*
0934 ============================================================
0935 ================== NuclideGammaBranchInfo ==================
0936 ============================================================
0937 */
0938 class NuclideGammaBranchInfo {
0939 
0940     private:
0941         double m_probability;                               /**< The probability that the level decays to state *m_residualStateIndex*. */
0942         double m_photonEmissionProbability;                 /**< The conditional probability the the decay emitted a photon. */
0943         double m_gammaEnergy;                               /**< The energy of the emitted photon. */
0944         int m_residualStateIndex;                           /**< The state the residual is left in after photon decay. */
0945         bool m_residualStateKindIsContinuum;                /**< True if the kind of the residual state (i.e., nuclide) is 'continuum' and false otherwise. */
0946 
0947     public:
0948         LUPI_HOST_DEVICE NuclideGammaBranchInfo( );
0949         LUPI_HOST NuclideGammaBranchInfo( PoPI::NuclideGammaBranchInfo const &a_nuclideGammaBranchInfo, 
0950                 std::map<std::string, int> &a_stateNamesToIndices, bool a_makePhotonEmissionProbabilitiesOne );
0951 
0952         LUPI_HOST_DEVICE double probability( ) const { return( m_probability ); }                                  /**< Returns the value of the **m_probability**. */
0953         LUPI_HOST_DEVICE double photonEmissionProbability( ) const { return( m_photonEmissionProbability ); }      /**< Returns the value of the **m_photonEmissionProbability**. */
0954         LUPI_HOST_DEVICE double gammaEnergy( ) const { return( m_gammaEnergy ); }                                  /**< Returns the value of the **m_gammaEnergy**. */
0955         LUPI_HOST_DEVICE int residualStateIndex( ) const { return( m_residualStateIndex ); }                       /**< Returns the value of the **m_residualStateIndex**. */
0956         LUPI_HOST_DEVICE bool residualStateKindIsContinuum( ) const { return( m_residualStateKindIsContinuum ); }  /**< Returns the value of the **m_residualStateKindIsContinuum. **. */
0957 
0958         LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
0959         LUPI_HOST void print( ProtareSingle const *a_protareSingle, std::string const &a_indent, std::string const &a_iFormat,
0960                 std::string const &a_energyFormat, std::string const &a_dFormat ) const ;
0961 };
0962 
0963 /*
0964 ============================================================
0965 ============== NuclideGammaBranchStateInfo =================
0966 ============================================================
0967 */
0968 class NuclideGammaBranchStateInfo {
0969 
0970     private:
0971         char m_state[16];                                   /**< The GNDS PoPs id for the nuclide. */
0972         int m_intid;                                        /**< The GNDS PoPs intid for the nuclide. */
0973         double m_nuclearLevelEnergy;                        /**< The nuclear level excitation energy of the level (state). */
0974         double m_nuclearLevelEnergyWidth;                   /**< This is 0.0 except for GRIN realized continuum levels where this is the energy width from this level to the next higher level. */
0975         double m_multiplicity;                              /**< The average multiplicity of photons emitted including the emission from sub-levels. */
0976         double m_averageGammaEnergy;                        /**< The average energy of photons emitted including the emission from sub-levels. */
0977         Vector<std::size_t> m_branchIndices;                /**< The list of indices into the ProtareSingle.m_branches member that this level decays to. */
0978 
0979     public:
0980         LUPI_HOST_DEVICE NuclideGammaBranchStateInfo( );
0981         LUPI_HOST NuclideGammaBranchStateInfo( PoPI::NuclideGammaBranchStateInfo const &a_nuclideGammaBranchingInfo, 
0982                 std::vector<NuclideGammaBranchInfo *> &a_nuclideGammaBranchInfos, 
0983                 std::map<std::string, int> &a_stateNamesToIndices, bool a_makePhotonEmissionProbabilitiesOne,
0984                 bool a_ignoreNuclearLevelEnergy );
0985 
0986         LUPI_HOST_DEVICE char const *state( ) const { return( m_state ); }                                    /**< Returns a pointer to the **m_state** member. */
0987         LUPI_HOST_DEVICE int intid( ) const { return( m_intid ); }                                            /**< Returns a pointer to the **m_intid** member. */
0988         LUPI_HOST_DEVICE double nuclearLevelEnergy( ) const { return( m_nuclearLevelEnergy ); }               /**< Returns the value of the **m_nuclearLevelEnergy** member. */
0989         LUPI_HOST_DEVICE double nuclearLevelEnergyWidth( ) const { return( m_nuclearLevelEnergyWidth ); }
0990                                                                                 /**< Returns the value of the *m_nuclearLevelEnergyWidth* member. */
0991         LUPI_HOST_DEVICE double multiplicity( ) const { return( m_multiplicity ); }                           /**< Returns the value of the **m_multiplicity** member. */
0992         LUPI_HOST_DEVICE double averageGammaEnergy( ) const { return( m_averageGammaEnergy ); }               /**< Returns the value of the **m_averageGammaEnergy** member. */
0993         LUPI_HOST_DEVICE Vector<std::size_t> const &branchIndices( ) const { return( m_branchIndices ); }     /**< Returns the value of the **m_branchIndices** member. */
0994 
0995         LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
0996         LUPI_HOST void print( ProtareSingle const *a_protareSingle, std::string const &a_indent, std::string const &a_iFormat,
0997                 std::string const &a_energyFormat, std::string const &a_dFormat ) const ;
0998 };
0999 
1000 /*
1001 ============================================================
1002 =============== GRIN_levelsAndProbabilities ================
1003 ============================================================
1004 */
1005 
1006 class GRIN_levelsAndProbabilities {
1007 
1008     public:
1009         Vector<int> m_levels;                       /**< The list of nuclide indices for the nuclides in *m_state* as stored in member ProtareSingle::m_nuclideGammaBranchStateInfos. */
1010         Vector<double> m_summedProbabilities;       /**< The running sum of the probability for choosing a state from m_states. */
1011         Vector<bool> m_isModelledLevel;             /**< The entry for each item in *m_levels* which is true if the level is a modelled level and false otherwise. */
1012 
1013     public:
1014         LUPI_HOST_DEVICE  GRIN_levelsAndProbabilities( );
1015         LUPI_HOST         GRIN_levelsAndProbabilities( SetupInfo &a_setupInfo, PoPI::Database const &a_pops, 
1016                                 GIDI::Table::Table const &a_table, bool a_normalize );
1017         LUPI_HOST_DEVICE ~GRIN_levelsAndProbabilities( );
1018 
1019         LUPI_HOST void set( std::vector<int> const &a_levels, std::vector<double> const &a_probabilities );
1020 
1021         template <typename RNG>
1022         inline LUPI_HOST_DEVICE int sampleInelasticLevel( double a_energy, RNG && a_rng );
1023         LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
1024 };
1025 
1026 /*
1027 ============================================================
1028 ================= GRIN_inelasticForEnergy ==================
1029 ============================================================
1030 */
1031 
1032 class GRIN_inelasticForEnergy {
1033 
1034     private:
1035         Vector<std::size_t> m_indices;
1036         Vector<double> m_thresholds;
1037         GRIN_levelsAndProbabilities m_levelsAndProbabilities;
1038 
1039     public:
1040         LUPI_HOST_DEVICE GRIN_inelasticForEnergy( );
1041         LUPI_HOST GRIN_inelasticForEnergy( SetupInfo &a_setupInfo, double a_projectileMass, double a_targetMass,
1042                 PoPI::Database const &a_pops, GIDI::GRIN::InelasticIncidentEnergy const *inelasticIncidentEnergy );
1043         LUPI_HOST_DEVICE ~GRIN_inelasticForEnergy( );
1044 
1045         LUPI_HOST_DEVICE int sampleLevelIndex( double a_projectileEnergy, double a_random ) const ;
1046         LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
1047 };
1048 
1049 /*
1050 ============================================================
1051 ====================== GRIN_inelastic ======================
1052 ============================================================
1053 */
1054 
1055 class GRIN_inelastic {
1056 
1057     private:
1058         int m_neutronIndex;
1059         int m_neutronUserParticleIndex;
1060         double m_neutronMass;
1061 
1062         int m_targetIntid;
1063         int m_targetIndex;
1064         int m_targetUserParticleIndex;
1065         double m_targetMass;
1066 
1067         Vector<double> m_energies;
1068         Vector<GRIN_inelasticForEnergy *> m_inelasticForEnergy;
1069 
1070     public:
1071         LUPI_HOST_DEVICE  GRIN_inelastic( );
1072         LUPI_HOST         GRIN_inelastic( SetupInfo &a_setupInfo, GIDI::GRIN::GRIN_continuumGammas const &GRIN_continuumGammas );
1073         LUPI_HOST_DEVICE ~GRIN_inelastic( );
1074 
1075         LUPI_HOST void setUserParticleIndex( int a_particleIndex, int a_userParticleIndex );
1076         LUPI_HOST void setUserParticleIndexViaIntid( int a_particleIntid, int a_userParticleIndex );
1077 
1078         template <typename RNG, typename PUSHBACK>
1079         inline LUPI_HOST_DEVICE bool sampleProducts( ProtareSingle const *a_protare, double a_projectileEnergy, Sampling::Input &a_input, 
1080                 RNG && a_rng, PUSHBACK && a_push_back, Sampling::ProductHandler &a_products ) const ;
1081         LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
1082 };
1083 
1084 /*
1085 ============================================================
1086 ================= GRIN_captureToCompound ================
1087 ============================================================
1088 */
1089 
1090 class GRIN_captureToCompound {
1091 
1092     private:
1093         std::size_t m_index;                                /**< This is the index into ProtareSingle.m_nuclideGammaBranchStateInfos of the compound level forms by the capture. */
1094         GRIN_levelsAndProbabilities m_continuumIndices;     /**< This is the list of the levels the compound can decay to minus the known levels. */
1095 
1096     public:
1097         LUPI_HOST_DEVICE GRIN_captureToCompound( );
1098         LUPI_HOST GRIN_captureToCompound( SetupInfo &a_setupInfo, PoPI::Database const &a_pops, std::string a_compoundId );
1099         LUPI_HOST_DEVICE ~GRIN_captureToCompound( );
1100 
1101         LUPI_HOST_DEVICE std::size_t index( ) const { return( m_index ); }
1102         template <typename RNG>
1103         inline LUPI_HOST_DEVICE int sampleCaptureLevel( ProtareSingle const *a_protare, double a_energy, RNG && a_rng, bool a_checkEnergy ) const ;
1104         LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
1105 };
1106 
1107 /*
1108 ============================================================
1109 =============== GRIN_captureLevelProbability ===============
1110 ============================================================
1111 */
1112 
1113 /* 
1114 * The m_capturePrimaryToContinua are the modelled primary capture nuclides needed when one of the nuclide in 
1115 * *m_levelsAndProbabilities* is not selected. The nuclide in *m_capturePrimaryToContinua* whose nuclear level 
1116 * energy as found in *m_nuclearLevelEnergies* is closest but below the * neutron separation energy plus the 
1117 * kinetic energy in the com frame is to be used when a nuclide in *m_levelsAndProbabilities* is not selected.
1118 * the ints in *m_capturePrimaryToContinua* are indicies into ProtareSingle.m_nuclideGammaBranchStateInfos.
1119 */
1120 
1121 class GRIN_captureLevelProbability {
1122 
1123     private:
1124         GRIN_levelsAndProbabilities m_knownLevelsAndProbabilities;      /**< These are the known primary capture nuclide as probabilites. The probabilites do not sum to one since not all are know. */
1125         Vector<GRIN_captureToCompound *> m_captureToCompounds;          /**< This is a list of nuclides that have the same spin/parity as the input channel and the needed nuclear excitation level. */
1126 
1127     public:
1128         LUPI_HOST_DEVICE  GRIN_captureLevelProbability( );
1129         LUPI_HOST         GRIN_captureLevelProbability( SetupInfo &a_setupInfo, PoPI::Database const &a_pops, 
1130                 GIDI::GRIN::CaptureLevelProbability const *a_captureLevelProbability );
1131         LUPI_HOST_DEVICE ~GRIN_captureLevelProbability( );
1132 
1133         template <typename RNG>
1134         inline LUPI_HOST_DEVICE int sampleCaptureLevel( ProtareSingle const *a_protare, double a_energy, RNG && a_rng );
1135         LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
1136 };
1137 
1138 /*
1139 ============================================================
1140 ====================== GRIN_capture ========================
1141 ============================================================
1142 */
1143 
1144 class GRIN_capture {
1145 
1146     private:
1147         double m_captureNeutronSeparationEnergy;                                /**< For capture, the neutron separation energy as needed to emit primary gammas.  */
1148         Vector<double> m_summedProbabilities;                                   /**< The running sum of the probabilites for the *m_captureLevelProbabilities* member data. */
1149         Vector<GRIN_captureLevelProbability *> m_captureLevelProbabilities;     /**< The list of capture levels with probabilites. */
1150         int m_residualIntid;                                                    /**< The intid of the heavy residual particle. */
1151         int m_residualIndex;                                                    /**< The PoPI index of the heavy residual particle. */
1152         int m_residualUserIndex;                                                /**< The user index of the heavy residual particle. */
1153         double m_residualMass;                                                  /**< The mass if the heavy residual particle. */
1154 
1155     public:
1156         LUPI_HOST_DEVICE  GRIN_capture( );
1157         LUPI_HOST         GRIN_capture( SetupInfo &a_setupInfo, GIDI::GRIN::GRIN_continuumGammas const &GRIN_continuumGammas );
1158         LUPI_HOST_DEVICE ~GRIN_capture( );
1159 
1160         LUPI_HOST void setUserParticleIndex( int a_particleIndex, int a_userParticleIndex );
1161         LUPI_HOST void setUserParticleIndexViaIntid( int a_particleIntid, int a_userParticleIndex );
1162         template <typename RNG, typename PUSHBACK>
1163         inline LUPI_HOST_DEVICE bool sampleProducts( ProtareSingle const *a_protare, double a_projectileEnergy, Sampling::Input &a_input, 
1164                 RNG && a_rng, PUSHBACK && a_push_back, Sampling::ProductHandler &a_products ) const ;
1165         LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
1166 };
1167 
1168 /*
1169 ============================================================
1170 ========================= Product ==========================
1171 ============================================================
1172 */
1173 class Product {
1174 
1175     private:
1176         String m_ID;
1177         int m_intid;
1178         int m_index;
1179         int m_userParticleIndex;
1180         String m_label;
1181         bool m_isCompleteParticle;
1182         double m_mass;
1183         double m_excitationEnergy;
1184         TwoBodyOrder m_twoBodyOrder;
1185         int m_initialStateIndex;                                /**< If the product has branching photons, then this is the state index to start the branching. */
1186         Functions::Function1d *m_multiplicity;
1187         Distributions::Distribution *m_distribution;
1188 // still need *m_averageEnergy *m_averageMomentum;
1189 
1190         OutputChannel *m_outputChannel;
1191 
1192     public:
1193         LUPI_HOST_DEVICE Product( );
1194         LUPI_HOST Product( GIDI::Product const *a_product, SetupInfo &a_setupInfo, Transporting::MC const &a_settings, GIDI::Transporting::Particles const &a_particles,
1195                 bool a_isFission );
1196         LUPI_HOST Product( PoPI::Database const &a_pop, std::string const &a_ID, std::string const &a_label );
1197         LUPI_HOST_DEVICE ~Product( );
1198 
1199         LUPI_HOST String const &ID( ) const { return( m_ID ); }                                 /**< Returns a const reference to the *m_ID* member. */
1200         LUPI_HOST_DEVICE int intid( ) const { return( m_intid); }                               /**< Returns the value of the *m_intid* member. */
1201         LUPI_HOST_DEVICE int index( ) const { return( m_index); }                               /**< Returns the value of the *m_index* member. */
1202         LUPI_HOST_DEVICE int userParticleIndex( ) const { return( m_userParticleIndex ); }      /**< Returns the value of the **m_userParticleIndex**. */
1203         LUPI_HOST void setUserParticleIndex( int a_particleIndex, int a_userParticleIndex );
1204         LUPI_HOST void setUserParticleIndexViaIntid( int a_particleIntid, int a_userParticleIndex );
1205         LUPI_HOST void setModelDBRC_data( Sampling::Upscatter::ModelDBRC_data *a_modelDBRC_data );
1206         LUPI_HOST_DEVICE String label( ) const { return( m_label ); }                           /**< Returns the value of the **m_label**. */
1207         LUPI_HOST_DEVICE bool isCompleteParticle( ) const { return( m_isCompleteParticle ); }   /**< Returns the value of the **m_isCompleteParticle**. */
1208         LUPI_HOST_DEVICE double mass( ) const { return( m_mass ); }                             /**< Returns the value of the **m_mass**. */
1209         LUPI_HOST_DEVICE double excitationEnergy( ) const { return( m_excitationEnergy ); }     /**< Returns the value of the **m_excitationEnergy**. */
1210         LUPI_HOST_DEVICE TwoBodyOrder twoBodyOrder( ) const { return( m_twoBodyOrder ); }       /**< Returns the value of the **m_twoBodyOrder**. */
1211         LUPI_HOST_DEVICE double finalQ( double a_x1 ) const ;
1212         LUPI_HOST_DEVICE bool hasFission( ) const ;
1213 
1214 // FIXME (1) see FIXME (1) in MC class.
1215         LUPI_HOST_DEVICE Functions::Function1d const *multiplicity( ) const { return( m_multiplicity ); }      /**< Returns the value of the **m_multiplicity**. */
1216         LUPI_HOST void setMultiplicity( Functions::Function1d *a_multiplicity ) { m_multiplicity = a_multiplicity; }
1217         LUPI_HOST_DEVICE double productAverageMultiplicity(         int a_index, double a_projectileEnergy ) const ;
1218         LUPI_HOST_DEVICE double productAverageMultiplicityViaIntid( int a_intid, double a_projectileEnergy ) const ;
1219 // FIXME (1) see FIXME (1) in MC class.
1220         LUPI_HOST_DEVICE Distributions::Distribution const *distribution( ) const { return( m_distribution ); }     /**< Returns the value of the **m_distribution**. */
1221         LUPI_HOST_DEVICE Distributions::Distribution *distribution( ) { return( m_distribution ); }                 /**< Returns the value of the **m_distribution**. */
1222         LUPI_HOST void distribution( Distributions::Distribution *a_distribution ) { m_distribution = a_distribution; }
1223 // FIXME (1) see FIXME (1) in MC class.
1224         LUPI_HOST_DEVICE OutputChannel *outputChannel( ) { return( m_outputChannel ); }                  /**< Returns the value of the **m_outputChannel**. */
1225 
1226         template <typename RNG, typename PUSHBACK>
1227         inline LUPI_HOST_DEVICE void sampleProducts( ProtareSingle const *a_protare, double a_projectileEnergy, Sampling::Input &a_input,
1228                 RNG && a_rng, PUSHBACK && a_push_back, Sampling::ProductHandler &a_products ) const ;
1229         template <typename RNG, typename PUSHBACK>
1230         inline LUPI_HOST_DEVICE void sampleFinalState( ProtareSingle const *a_protare, double a_projectileEnergy, Sampling::Input &a_input,
1231                 RNG && a_rng, PUSHBACK && a_push_back, Sampling::ProductHandler &a_products ) const ;
1232         template <typename RNG>
1233         inline LUPI_HOST_DEVICE void angleBiasing( Reaction const *a_reaction, int a_pid, double a_temperature, double a_energy_in, double a_mu_lab, 
1234               double &a_probability, double &a_energy_out, RNG && a_rng, double &a_cumulative_weight ) const ;
1235         template <typename RNG>
1236         inline LUPI_HOST_DEVICE void angleBiasingViaIntid( Reaction const *a_reaction, int a_intid, double a_temperature, double a_energy_in, double a_mu_lab, 
1237                 double &a_probability, double &a_energy_out, RNG && a_rng, double &a_cumulative_weight ) const ;
1238         LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
1239 };
1240 
1241 /*
1242 ============================================================
1243 ====================== DelayedNeutron ======================
1244 ============================================================
1245 */
1246 class DelayedNeutron {
1247 
1248     private:
1249         int m_delayedNeutronIndex;                  /**< If this is a delayed fission neutron, this is its index. */
1250         double m_rate;                              /**< The GNDS rate for the delayed neutron. */
1251         Product m_product;                          /**< The GNDS <**product**> node. */
1252 
1253     public:
1254         LUPI_HOST_DEVICE DelayedNeutron( );
1255         LUPI_HOST DelayedNeutron( int a_index, GIDI::DelayedNeutron const *a_delayedNeutron, SetupInfo &a_setupInfo, Transporting::MC const &a_settings, GIDI::Transporting::Particles const &a_particles );
1256         LUPI_HOST_DEVICE ~DelayedNeutron( );
1257 
1258         LUPI_HOST_DEVICE int delayedNeutronIndex( ) const { return( m_delayedNeutronIndex ); }
1259         LUPI_HOST_DEVICE double rate( ) const { return( m_rate ); }
1260         LUPI_HOST_DEVICE Product const &product( ) const { return( m_product ); }
1261         LUPI_HOST void setUserParticleIndex( int a_particleIndex, int a_userParticleIndex );
1262         LUPI_HOST void setUserParticleIndexViaIntid( int a_particleIntid, int a_userParticleIndex );
1263 
1264         LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
1265 };
1266 
1267 /*
1268 ============================================================
1269 ======================= OutputChannel ======================
1270 ============================================================
1271 */
1272 class OutputChannel {
1273 
1274     private:
1275         ChannelType m_channelType;
1276         int m_neutronIndex;                         /**< The index of the neutron in the use PoPs database. */
1277         bool m_isFission;
1278         bool m_hasFinalStatePhotons;                /**< If **true**, *this* channel has a photon with finalState attribute. */
1279 
1280         Functions::Function1d_d1 *m_Q;              /**< The Q-function for the output channel. Note, this is currently always the *evaluated* form even when running with multi-group data. */
1281         Vector<Product *> m_products;
1282         Functions::Function1d *m_totalDelayedNeutronMultiplicity;
1283         Vector<DelayedNeutron *> m_delayedNeutrons;
1284 
1285     public:
1286         LUPI_HOST_DEVICE OutputChannel( );
1287         LUPI_HOST OutputChannel( GIDI::OutputChannel const *a_outputChannel, SetupInfo &a_setupInfo, Transporting::MC const &a_settings, GIDI::Transporting::Particles const &a_particles );
1288         LUPI_HOST_DEVICE ~OutputChannel( );
1289 
1290         LUPI_HOST_DEVICE Product *operator[]( std::size_t a_index ) { return( m_products[a_index] ); }  /**< Returns a pointer to the product at index *a_index*. */
1291 
1292         LUPI_HOST_DEVICE bool isTwoBody( ) const { return( m_channelType == ChannelType::twoBody ); }         /**< Returns true if output channel is two-body and false otherwise. */
1293         LUPI_HOST_DEVICE double finalQ( double a_x1 ) const ;
1294         LUPI_HOST_DEVICE bool isFission( ) const { return( m_isFission ); }                      /**< Returns the value of the **m_isFission**. */
1295         LUPI_HOST_DEVICE bool hasFission( ) const ;
1296 // FIXME (1) see FIXME (1) in MC class.
1297         LUPI_HOST_DEVICE Functions::Function1d_d1 *Q( ) { return( m_Q ); }                       /**< Returns the pointer of the **m_Q** member. */
1298 
1299         LUPI_HOST void setUserParticleIndex( int a_particleIndex, int a_userParticleIndex );
1300         LUPI_HOST void setUserParticleIndexViaIntid( int a_particleIntid, int a_userParticleIndex );
1301         LUPI_HOST void setModelDBRC_data( Sampling::Upscatter::ModelDBRC_data *a_modelDBRC_data );
1302 // FIXME (1) see FIXME (1) in MC class.
1303         LUPI_HOST_DEVICE Vector<Product *> const &products( ) const { return( m_products ); }    /**< Returns the value of the **m_products**. */
1304 
1305         Vector<DelayedNeutron *> delayedNeutrons( ) const { return( m_delayedNeutrons ); }
1306         LUPI_HOST_DEVICE DelayedNeutron const *delayedNeutron( std::size_t a_index ) const { return( m_delayedNeutrons[a_index] ); }
1307 
1308         LUPI_HOST void moveProductsEtAlToReaction( std::vector<Product *> &a_products, Functions::Function1d **a_totalDelayedNeutronMultiplicity, 
1309                 std::vector<DelayedNeutron *> &a_delayedNeutrons, std::vector<Functions::Function1d_d1 *> &a_Qs );
1310 #ifdef MCGIDI_USE_OUTPUT_CHANNEL
1311         LUPI_HOST void addOrphanProductToProductList( std::vector<Product *> &a_associatedOrphanProducts ) const ;
1312         LUPI_HOST_DEVICE void addOrphanProductToProductList( Vector<Product *> &a_associatedOrphanProducts ) const ;
1313 #endif
1314 
1315         LUPI_HOST_DEVICE double productAverageMultiplicity(         int a_index, double a_projectileEnergy ) const ;
1316         LUPI_HOST_DEVICE double productAverageMultiplicityViaIntid( int a_intid, double a_projectileEnergy ) const ;
1317 
1318 template <typename RNG, typename PUSHBACK>
1319         inline LUPI_HOST_DEVICE void sampleProducts( ProtareSingle const *a_protare, double a_projectileEnergy, Sampling::Input &a_input,
1320                 RNG && a_rng, PUSHBACK && a_push_back, Sampling::ProductHandler &a_products ) const;
1321         template <typename RNG>
1322         inline LUPI_HOST_DEVICE void angleBiasing( Reaction const *a_reaction, int a_pid, double a_temperature, double a_energy_in, double a_mu_lab, 
1323               double &a_probability, double &a_energy_out, RNG && a_rng, double &a_cumulative_weight ) const ;
1324         template <typename RNG>
1325         inline LUPI_HOST_DEVICE void angleBiasingViaIntid( Reaction const *a_reaction, int a_intid, double a_temperature, double a_energy_in, double a_mu_lab, 
1326                 double &a_probability, double &a_energy_out, RNG && a_rng, double &a_cumulative_weight ) const ;
1327         LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
1328 };
1329 
1330 /*
1331 ============================================================
1332 ========================= Reaction =========================
1333 ============================================================
1334 */
1335 class Reaction {
1336 
1337     private:
1338         ProtareSingle *m_protareSingle;                     /**< The ProtareSingle this reaction resides in. */
1339         std::size_t m_reactionIndex;                        /**< The index of the reaction in the ProtareSingle. */
1340         std::size_t m_GIDI_reactionIndex;                   /**< The index of the reaction in the GIDI::ProtareSingle. */
1341         String m_label;                                     /**< The **GNDS** label for the reaction. */
1342         int m_ENDF_MT;                                      /**< The ENDF MT value for the reaction. */
1343         int m_ENDL_C;                                       /**< The ENDL C value for the reaction. */
1344         int m_ENDL_S;                                       /**< The ENDL S value for the reaction. */
1345         int m_initialStateIndex;                            /**< If not -1, then reaction contains a branching gamma data with this index for the data in m_nuclideGammaBranchStateInfos member of its **ProtareSingle** instance. */
1346         int m_neutronIndex;                                 /**< The index of the neutron in the use PoPs database. */
1347         bool m_hasFission;                                  /**< Is *true* if the reaction is a fission reaction and *false* otherwise. */
1348         double m_projectileMass;                            /**< The mass of the projectile. */
1349         double m_targetMass;                                /**< The mass of the target. */
1350         double m_crossSectionThreshold;                     /**< The threshold for the reaction. */
1351         double m_twoBodyThreshold;                          /**< This is the T_1 value needed to do two-body kinematics. */
1352         bool m_hasFinalStatePhotons;                        /**< If **true**, *this* reaction has a photon with finalState attribute. */
1353         int m_fissionResiduaIntid;                          /**< The intid of the special ENDL 99120 or 99125 fission residual. */
1354         int m_fissionResiduaIndex;                          /**< The index of the special ENDL 99120 or 99125 fission residual. */
1355         int m_fissionResiduaUserIndex;                      /**< The user index of the special ENDL 99120 or 99125 fission residual. */
1356         GIDI::Construction::FissionResiduals m_fissionResiduals;  /**< This member specifies what fission redisual products will be added to the list of products produced in a fission reaction. */
1357         double m_fissionResidualMass;                       /**< The mass of the special ENDL 99120 or 99125 fission residual. */
1358 
1359         Vector<int> m_productIntids;                        /**< The list of all products *this* reaction can product by their intid. */
1360         Vector<int> m_productIndices;                       /**< The list of all products *this* reaction can product by their index. */
1361         Vector<int> m_userProductIndices;                   /**< The list of all products *this* reaction can product as user indices. */
1362         Vector<int> m_productMultiplicities;                /**< The list of all multiplicities for each product in *m_productIntids* . */
1363         Vector<int> m_productIntidsTransportable;           /**< The list of all transportabls products *this* reaction can product by their intid. */
1364         Vector<int> m_productIndicesTransportable;          /**< The list of all transportabls products *this* reaction can product by their index. */
1365         Vector<int> m_userProductIndicesTransportable;      /**< The list of all transportabls products *this* reaction can product as user indices. */
1366 
1367         Vector<Functions::Function1d_d1 *> m_Qs;            /**< A list of Q-functions that is used when the C macro MCGIDI_USE_OUTPUT is defined. */
1368         Vector<Product *> m_products;                       /**< A list of all transporting products directly or nested in **m_outputChannel** that is used instead of having **m_outputChannel** loop of all transporting products if the C macro MCGIDI_USE_OUTPUT_CHANNEL is not defined. */
1369         Functions::Function1d *m_totalDelayedNeutronMultiplicity;
1370         Vector<DelayedNeutron *> m_delayedNeutrons;         /**< A list of all delayedNeutrons that can be used instead of having m_outputChannel loop of all transporting products. For *m_products* for more details. */
1371                                                             /**< The total delayed neutron multiplicity used when the C macro MCGIDI_USE_OUTPUT is defined. */
1372 #ifdef MCGIDI_USE_OUTPUT_CHANNEL
1373         OutputChannel *m_outputChannel;                     /**< The output channel for this reaction. Only used if the C macro MCGIDI_USE_OUTPUT is defined. */
1374 #endif
1375         Vector<std::size_t> m_associatedOrphanProductIndices;   /**< The indices in the Protare's m_orphanProducts member for the orphanProducts associated with this reaction. */
1376         Vector<Product *> m_associatedOrphanProducts;       /**< The list of products from the orphanProduct reaction. */ /* Do not delete entries as owned by orphanProduct reaction. */
1377 // Still need m_availableEnergy and m_availableMomentum.
1378 
1379 // GRIN specials: new non-GNDS GRIN stuff.
1380         bool m_GRIN_specialSampleProducts;                  /**< This will be true if sampling products with GRIN special inelastic or capture data. */
1381         double m_GRIN_inelasticThreshold;                   /**< For inelastic, the a_projectileEnergy must be greater than this value 
1382                                                                 or use standard product sampling.  This is needed, for example, as the Fe56 MT 91 cross section 
1383                                                                 starts below the MT 89 cross section. Ergo, below the threshold for the nuclear level energy 
1384                                                                 for the first simulated Fe56 nuclear level. */
1385         double m_GRIN_maximumCaptureIncidentEnergy;         /**< For capture, the projectile energy must be less thans this value or use standard product sampling. */
1386         GRIN_inelastic *m_GRIN_inelastic;                   /**< A nullptr or a pointer to an instance of GIND_continuumInelatic (see below). */
1387         GRIN_capture *m_GRIN_capture;                       /**< A nullptr or a pointer to an instance of GIND_capture (see below).  */
1388 
1389     public:
1390         LUPI_HOST_DEVICE Reaction( );
1391         LUPI_HOST Reaction( GIDI::Reaction const &a_reaction, SetupInfo &a_setupInfo, Transporting::MC const &a_settings, GIDI::Transporting::Particles const &a_particles,
1392                 GIDI::Styles::TemperatureInfos const &a_temperatureInfos );
1393         LUPI_HOST_DEVICE ~Reaction( );
1394 
1395         inline LUPI_HOST_DEVICE void updateProtareSingleInfo( ProtareSingle *a_protareSingle, std::size_t a_reactionIndex ) {
1396                 m_protareSingle = a_protareSingle;
1397                 m_reactionIndex = a_reactionIndex;
1398         }
1399         LUPI_HOST_DEVICE ProtareSingle const *protareSingle( ) const { return( m_protareSingle ); }     /**< Returns the value of the **m_protareSingle**. */
1400         LUPI_HOST_DEVICE std::size_t reactionIndex( ) const { return( m_reactionIndex ); }              /**< Returns the value of the **m_reactionIndex**. */
1401         LUPI_HOST_DEVICE std::size_t GIDI_reactionIndex( ) const { return( m_GIDI_reactionIndex ); }    /**< Returns the value of the **m_GIDI_reactionIndex** member. */
1402         LUPI_HOST_DEVICE String const &label( ) const { return( m_label ); }             /**< Returns the value of the **m_label**. */
1403         LUPI_HOST_DEVICE int ENDF_MT( ) const { return( m_ENDF_MT ); }                   /**< Returns the value of the **m_ENDF_MT**. */
1404         LUPI_HOST_DEVICE int ENDL_C( ) const { return( m_ENDL_C ); }                     /**< Returns the value of the **m_ENDL_C**. */
1405         LUPI_HOST_DEVICE int ENDL_S( ) const { return( m_ENDL_S ); }                     /**< Returns the value of the **m_ENDL_S**. */
1406         LUPI_HOST_DEVICE int initialStateIndex( ) const { return( m_initialStateIndex ); }    /**< Returns the value of the **m_initialStateIndex** member. */
1407         LUPI_HOST_DEVICE double finalQ( double a_energy ) const ;
1408         LUPI_HOST_DEVICE bool hasFission( ) const { return( m_hasFission ); }            /**< Returns the value of the **m_hasFission**. */
1409         LUPI_HOST_DEVICE double projectileMass( ) const { return( m_projectileMass ); }  /**< Returns the value of the **m_projectileMass**. */
1410         LUPI_HOST_DEVICE double targetMass( ) const { return( m_targetMass ); }          /**< Returns the value of the **m_targetMass**. */
1411         LUPI_HOST_DEVICE double crossSectionThreshold( ) const { return( m_crossSectionThreshold ); }    /**< Returns the value of the **m_crossSectionThreshold**. */
1412         LUPI_HOST_DEVICE double twoBodyThreshold( ) const { return( m_twoBodyThreshold ); }              /**< Returns the value of the *m_twoBodyThreshold* member. */
1413         LUPI_HOST_DEVICE double crossSection( URR_protareInfos const &a_URR_protareInfos, std::size_t a_hashIndex, 
1414                 double a_temperature, double a_energy ) const ;
1415         LUPI_HOST_DEVICE double crossSection( URR_protareInfos const &a_URR_protareInfos, double a_temperature, double a_energy ) const ;
1416         LUPI_HOST GIDI::Functions::XYs1d crossSectionAsGIDI_XYs1d( double a_temperature ) const ;
1417 
1418         LUPI_HOST_DEVICE Vector<int> const &productIntids( ) const { return( m_productIntids ); }
1419         LUPI_HOST_DEVICE Vector<int> const &productIndices( ) const { return( m_productIndices ); }            /**< Returns a const reference to the *m_productIntids* member. */
1420         LUPI_HOST_DEVICE Vector<int> const &userProductIndices( ) const { return( m_userProductIndices ); }    /**< Returns a const reference to the *m_productIndices* member. */
1421         LUPI_HOST_DEVICE std::size_t numberOfProducts( ) const { return( m_products.size( ) ); }     /**< Returns the number of products in the **m_products** member. */
1422         LUPI_HOST_DEVICE Product const *product( std::size_t a_index ) const { return( m_products[a_index] ); }
1423         LUPI_HOST_DEVICE int productMultiplicity(         int a_index ) const ;
1424         LUPI_HOST_DEVICE int productMultiplicityViaIntid( int a_intid ) const ;
1425         LUPI_HOST_DEVICE int productMultiplicities( int a_index ) const {
1426                 LUPI::deprecatedFunction( "MCGIDI::Reaction::productMultiplicities", "MCGIDI::Reaction::productMultiplicity", "" );
1427                 return( productMultiplicity( a_index ) ); }                                 /**< This method is deprecated. Please use **productMultiplicity** instead. */
1428         LUPI_HOST_DEVICE double productAverageMultiplicity(         int a_index, double a_projectileEnergy ) const ;
1429         LUPI_HOST_DEVICE double productAverageMultiplicityViaIntid( int a_intid, double a_projectileEnergy ) const ;
1430         LUPI_HOST_DEVICE Vector<int> const &productIntidsTransportable( ) const { return( m_productIntidsTransportable ); }
1431                                                                                             /**< Returns a const reference to the *m_productIntidsTransportable* member. */
1432         LUPI_HOST_DEVICE Vector<int> const &productIndicesTransportable( ) const { return( m_productIndicesTransportable ); }
1433                                                                                             /**< Returns a const reference to the *m_productIndicesTransportable* member. */
1434         LUPI_HOST_DEVICE Vector<int> const &userProductIndicesTransportable( ) const { return( m_userProductIndicesTransportable ); }
1435 
1436 #ifdef MCGIDI_USE_OUTPUT_CHANNEL
1437         LUPI_HOST_DEVICE OutputChannel const *outputChannel( ) const { return( m_outputChannel ); }              /**< Returns the value of the **m_outputChannel**. */
1438 #endif
1439         LUPI_HOST_DEVICE Vector<std::size_t> associatedOrphanProductIndices( ) const { return( m_associatedOrphanProductIndices ); } /**< Returns the value of the **m_associatedOrphanProductIndicex** member. */
1440         LUPI_HOST void addOrphanProductToProductList( std::vector<Product *> &a_associatedOrphanProducts ) const ;
1441         LUPI_HOST_DEVICE void addOrphanProductToProductList( Vector<Product *> &a_associatedOrphanProducts ) const ;
1442         LUPI_HOST_DEVICE void addOrphanProductToProductList( Vector<Reaction *> &a_orphanProducts ) ;
1443         LUPI_HOST void setOrphanProductData( std::vector<std::size_t> const &a_associatedOrphanProductIndcies,
1444                 std::vector<Product *> const &a_associatedOrphanProducts );
1445 
1446         LUPI_HOST void setUserParticleIndex( int a_particleIndex, int a_userParticleIndex );
1447         LUPI_HOST void setUserParticleIndexViaIntid( int a_particleIntid, int a_userParticleIndex );
1448         LUPI_HOST void setModelDBRC_data( Sampling::Upscatter::ModelDBRC_data *a_modelDBRC_data );
1449 
1450         template <typename RNG, typename PUSHBACK>
1451         inline LUPI_HOST_DEVICE void sampleProducts( Protare const *a_protare, Sampling::Input &a_input, 
1452                 RNG && a_rng, PUSHBACK && a_push_back, Sampling::ProductHandler &a_products, bool a_checkOrphanProducts = true ) const ;
1453         template <typename RNG, typename PUSHBACK>
1454         inline LUPI_HOST_DEVICE static void sampleNullProducts( Protare const &a_protare, double a_projectileEnergy, Sampling::Input &a_input, 
1455                 RNG && a_rng, PUSHBACK && a_push_back, Sampling::ProductHandler &a_products );
1456         template <typename RNG>
1457         inline LUPI_HOST_DEVICE double angleBiasing( int a_pid, double a_temperature, double a_energy_in, double a_mu_lab, double &a_energy_out, 
1458                 RNG && a_rng, double *a_cumulative_weight = nullptr, bool a_checkOrphanProducts = true ) const ;
1459         template <typename RNG>
1460         inline LUPI_HOST_DEVICE double angleBiasingViaIntid( int a_intid, double a_temperature, double a_energy_in, double a_mu_lab, double &a_energy_out, 
1461                 RNG && a_rng, double *a_cumulative_weight = nullptr, bool a_checkOrphanProducts = true ) const ;
1462         LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
1463 };
1464 
1465 /*
1466 ============================================================
1467 ========================== Protare =========================
1468 ============================================================
1469 */
1470 class Protare {
1471 
1472     private:
1473         ProtareType m_protareType;                          /**< The type of protare *this* is. */
1474 
1475         String m_projectileID;                              /**< The PoPs id of the projectile. */
1476         int m_projectileIntid;                              /**< The PoPs intid of the projectile. */
1477         int m_projectileIndex;                              /**< The PoPs database index of the projectile. */
1478         int m_projectileUserIndex;                          /**< The projectile's index as specified by the user. */
1479         double m_projectileMass;                            /**< The mass of the projectile. */
1480         double m_projectileExcitationEnergy;                /**< The nuclear excitation of the projectile. */
1481 
1482         String m_targetID;                                  /**< The PoPs intid of the target. */
1483         int m_targetIntid;                                  /**< The PoPs index of the target. */
1484         int m_targetIndex;                                  /**< The PoPs database index of the target. */
1485         int m_targetUserIndex;                              /**< The target's index as specified by the user. */
1486         double m_targetMass;                                /**< The mass of the target. */
1487         double m_targetExcitationEnergy;                    /**< The nuclear excitation of the target. */
1488 
1489         int m_neutronIndex;                                 /**< The neutron particle index from the user's pops database. */
1490         int m_userNeutronIndex;                             /**< The neutron particle index defined by the user. */
1491         int m_photonIndex;                                  /**< The photon particle index from the user's pops database. */
1492         int m_userPhotonIndex;                              /**< The photon particle index defined by the user. */
1493 
1494         String m_evaluation;                                /**< The evaluation string for the Protare. */
1495         GIDI::Frame m_projectileFrame;                      /**< The frame the projectile data are given in. */
1496 
1497         Vector<int> m_productIntids;                        /**< The list of all products *this* protare can product by their intid. */
1498         Vector<int> m_productIndices;                       /**< The list of all products *this* reaction can product by their index. */
1499         Vector<int> m_userProductIndices;                   /**< The list of all products *this* reaction can product as user indices. */
1500         Vector<int> m_productIntidsTransportable;           /**< The list of all transportabls products *this* protare can product by their intid. */
1501         Vector<int> m_productIndicesTransportable;          /**< The list of all transportabls products *this* reaction can product by their index. */
1502         Vector<int> m_userProductIndicesTransportable;      /**< The list of all transportabls products *this* reaction can product as user indices. */
1503 
1504         bool m_isTNSL_ProtareSingle;                        /**< If *this* is a ProtareSingle instance with TNSL data *true* and otherwise *false*. */
1505 
1506         LUPI_HOST void productIntidsAndIndices( std::set<int> const &a_intids, std::set<int> const &a_transportableIntids,
1507                 std::set<int> const &a_indices, std::set<int> const &a_transportableIndices );
1508 
1509     public:
1510         LUPI_HOST_DEVICE Protare( ProtareType a_protareType );
1511         LUPI_HOST Protare( ProtareType a_protareType, GIDI::Protare const &a_protare, Transporting::MC const &a_settings, PoPI::Database const &a_pops );
1512         virtual LUPI_HOST_DEVICE ~Protare( );
1513 
1514         LUPI_HOST_DEVICE ProtareType protareType( ) const { return( m_protareType ); }                               /**< Returns the value of the **m_protareType** member. */    
1515 
1516         LUPI_HOST_DEVICE String const &projectileID( ) const { return( m_projectileID ); }                       /**< Returns the value of the **m_projectileID** member. */
1517         LUPI_HOST_DEVICE int projectileIntid( ) const { return( m_projectileIntid ); }                           /**< Returns the value of the **m_projectileIntid** member. */
1518         LUPI_HOST_DEVICE int projectileIndex( ) const { return( m_projectileIndex ); }                           /**< Returns the value of the **m_projectileIndex** member. */
1519         LUPI_HOST_DEVICE int projectileUserIndex( ) const { return( m_projectileUserIndex ); }                   /**< Returns the value of the **m_projectileUserIndex** member. */
1520         LUPI_HOST_DEVICE double projectileMass( ) const { return( m_projectileMass ); }                          /**< Returns the value of the **m_projectileMass** member. */
1521         LUPI_HOST_DEVICE double projectileExcitationEnergy( ) const { return( m_projectileExcitationEnergy ); }  /**< Returns the value of the **m_projectileExcitationEnergy** member. */
1522 
1523         LUPI_HOST_DEVICE String const &targetID( ) const { return( m_targetID ); }                               /**< Returns the value of the **m_targetID** member. */
1524         LUPI_HOST_DEVICE int targetIntid( ) const { return( m_targetIntid ); }                                   /**< Returns the value of the **m_targetIntid** member. */
1525         LUPI_HOST_DEVICE int targetIndex( ) const { return( m_targetIndex ); }                                   /**< Returns the value of the **m_targetIndex** member. */
1526         LUPI_HOST_DEVICE int targetUserIndex( ) const { return( m_targetUserIndex ); }                           /**< Returns the value of the **m_targetUserIndex** member. */
1527         LUPI_HOST_DEVICE double targetMass( ) const { return( m_targetMass ); }                                  /**< Returns the value of the **m_targetMass** member. */
1528         LUPI_HOST_DEVICE double targetExcitationEnergy( ) const { return( m_targetExcitationEnergy ); }          /**< Returns the value of the **m_targetExcitationEnergy** member. */
1529 
1530         LUPI_HOST_DEVICE int photonIndex( ) const { return( m_photonIndex ); }                                   /**< Returns the value of the **m_photonIndex** member. */
1531         LUPI_HOST_DEVICE int userPhotonIndex( ) const { return( m_userPhotonIndex ); }                           /**< Returns the value of the **m_userPhotonIndex** member. */
1532         LUPI_HOST_DEVICE String evaluation( ) const { return( m_evaluation ); }                                  /**< Returns the value of the **m_evaluation** member. */
1533         LUPI_HOST GIDI::Frame projectileFrame( ) const { return( m_projectileFrame ); }                          /**< Returns the value of the **m_projectileFrame** member. */
1534 
1535         LUPI_HOST Vector<int> const &productIntids( bool a_transportablesOnly ) const ;
1536         LUPI_HOST Vector<int> const &productIndices( bool a_transportablesOnly ) const ;
1537         LUPI_HOST Vector<int> const &userProductIndices( bool a_transportablesOnly ) const ;
1538         LUPI_HOST void setUserParticleIndex( int a_particleIndex, int a_userParticleIndex );
1539         LUPI_HOST void setUserParticleIndexViaIntid( int a_particleIntid, int a_userParticleIndex );
1540 
1541         LUPI_HOST_DEVICE bool isTNSL_ProtareSingle( ) const { return( m_isTNSL_ProtareSingle ); }                /**< Returns the value of the **m_isTNSL_ProtareSingle** member. */
1542         MCGIDI_VIRTUAL_FUNCTION LUPI_HOST_DEVICE std::size_t numberOfProtares( ) const MCGIDI_TRUE_VIRTUAL;                            /**< Returns the number of protares contained in *this*. */
1543         MCGIDI_VIRTUAL_FUNCTION LUPI_HOST_DEVICE ProtareSingle const *protare( std::size_t a_index ) const MCGIDI_TRUE_VIRTUAL;        /**< Returns the **a_index** - 1 Protare contained in *this*. */
1544         MCGIDI_VIRTUAL_FUNCTION LUPI_HOST_DEVICE ProtareSingle       *protare( std::size_t a_index )       MCGIDI_TRUE_VIRTUAL;        /**< Returns the **a_index** - 1 Protare contained in *this*. */
1545         MCGIDI_VIRTUAL_FUNCTION LUPI_HOST_DEVICE ProtareSingle const *protareWithReaction( std::size_t a_index ) const MCGIDI_TRUE_VIRTUAL;              /**< Returns the *ProtareSingle* that contains the (*a_index* - 1) reaction. */
1546 
1547         MCGIDI_VIRTUAL_FUNCTION LUPI_HOST_DEVICE double minimumEnergy( ) const MCGIDI_TRUE_VIRTUAL;                                              /**< Returns the minimum cross section domain. */
1548         MCGIDI_VIRTUAL_FUNCTION LUPI_HOST_DEVICE double maximumEnergy( ) const MCGIDI_TRUE_VIRTUAL ;                                             /**< Returns the maximum cross section domain. */
1549         MCGIDI_VIRTUAL_FUNCTION LUPI_HOST_DEVICE Vector<double> temperatures( std::size_t a_index = 0 ) const MCGIDI_TRUE_VIRTUAL ;    /**< Returns the list of temperatures for the requested ProtareSingle. */
1550 
1551         MCGIDI_VIRTUAL_FUNCTION LUPI_HOST Vector<double> const &projectileMultiGroupBoundaries( ) const MCGIDI_TRUE_VIRTUAL;
1552         MCGIDI_VIRTUAL_FUNCTION LUPI_HOST Vector<double> const &projectileMultiGroupBoundariesCollapsed( ) const MCGIDI_TRUE_VIRTUAL;
1553 
1554         MCGIDI_VIRTUAL_FUNCTION LUPI_HOST_DEVICE std::size_t numberOfReactions( ) const MCGIDI_TRUE_VIRTUAL;
1555         MCGIDI_VIRTUAL_FUNCTION LUPI_HOST_DEVICE Reaction const *reaction( std::size_t a_index ) const MCGIDI_TRUE_VIRTUAL;
1556         MCGIDI_VIRTUAL_FUNCTION LUPI_HOST_DEVICE std::size_t numberOfOrphanProducts( ) const MCGIDI_TRUE_VIRTUAL;
1557         MCGIDI_VIRTUAL_FUNCTION LUPI_HOST_DEVICE Reaction const *orphanProduct( std::size_t a_index ) const MCGIDI_TRUE_VIRTUAL;
1558 
1559         MCGIDI_VIRTUAL_FUNCTION LUPI_HOST_DEVICE bool hasFission( ) const MCGIDI_TRUE_VIRTUAL;
1560 
1561         MCGIDI_VIRTUAL_FUNCTION LUPI_HOST_DEVICE bool hasIncoherentDoppler( ) const MCGIDI_TRUE_VIRTUAL;
1562 
1563         MCGIDI_VIRTUAL_FUNCTION LUPI_HOST_DEVICE int URR_index( ) const MCGIDI_TRUE_VIRTUAL;
1564         MCGIDI_VIRTUAL_FUNCTION LUPI_HOST_DEVICE bool hasURR_probabilityTables( ) const MCGIDI_TRUE_VIRTUAL;
1565         MCGIDI_VIRTUAL_FUNCTION LUPI_HOST_DEVICE double URR_domainMin( ) const MCGIDI_TRUE_VIRTUAL;
1566         MCGIDI_VIRTUAL_FUNCTION LUPI_HOST_DEVICE double URR_domainMax( ) const MCGIDI_TRUE_VIRTUAL;
1567         MCGIDI_VIRTUAL_FUNCTION LUPI_HOST_DEVICE bool reactionHasURR_probabilityTables( std::size_t a_index ) const MCGIDI_TRUE_VIRTUAL ;
1568 
1569         MCGIDI_VIRTUAL_FUNCTION LUPI_HOST_DEVICE double threshold( std::size_t a_index ) const MCGIDI_TRUE_VIRTUAL;
1570 
1571         MCGIDI_VIRTUAL_FUNCTION LUPI_HOST_DEVICE double crossSection(                              URR_protareInfos const &a_URR_protareInfos,
1572                 std::size_t a_hashIndex, double a_temperature, double a_energy, bool a_sampling = false ) const MCGIDI_TRUE_VIRTUAL;
1573         MCGIDI_VIRTUAL_FUNCTION LUPI_HOST_DEVICE void crossSectionVector( double a_temperature, double a_userFactor, 
1574                 std::size_t a_numberAllocated, double *a_crossSectionVector ) const MCGIDI_TRUE_VIRTUAL;
1575         MCGIDI_VIRTUAL_FUNCTION LUPI_HOST_DEVICE double reactionCrossSection( std::size_t a_reactionIndex, 
1576                 URR_protareInfos const &a_URR_protareInfos, std::size_t a_hashIndex,
1577                 double a_temperature, double a_energy, bool a_sampling = false ) const MCGIDI_TRUE_VIRTUAL;
1578         MCGIDI_VIRTUAL_FUNCTION LUPI_HOST_DEVICE double reactionCrossSection( std::size_t a_reactionIndex, URR_protareInfos const &a_URR_protareInfos,
1579                 double a_temperature, double a_energy ) const MCGIDI_TRUE_VIRTUAL;
1580         template <typename RNG>
1581         inline MCGIDI_VIRTUAL_FUNCTION LUPI_HOST_DEVICE std::size_t sampleReaction( Sampling::Input &a_input, 
1582                 URR_protareInfos const &a_URR_protareInfos, std::size_t a_hashIndex, double a_crossSection, RNG && a_rng) const MCGIDI_TRUE_VIRTUAL;
1583 
1584         MCGIDI_VIRTUAL_FUNCTION LUPI_HOST_DEVICE double depositionEnergy(   std::size_t a_hashIndex, double a_temperature, double a_energy ) const MCGIDI_TRUE_VIRTUAL;
1585         MCGIDI_VIRTUAL_FUNCTION LUPI_HOST_DEVICE double depositionMomentum( std::size_t a_hashIndex, double a_temperature, double a_energy ) const MCGIDI_TRUE_VIRTUAL;
1586         MCGIDI_VIRTUAL_FUNCTION LUPI_HOST_DEVICE double productionEnergy(   std::size_t a_hashIndex, double a_temperature, double a_energy ) const MCGIDI_TRUE_VIRTUAL;
1587         MCGIDI_VIRTUAL_FUNCTION LUPI_HOST_DEVICE double gain(               std::size_t a_hashIndex, double a_temperature, double a_energy, int a_particleIndex ) const MCGIDI_TRUE_VIRTUAL;
1588         MCGIDI_VIRTUAL_FUNCTION LUPI_HOST_DEVICE double gainViaIntid(       std::size_t a_hashIndex, double a_temperature, double a_energy, int a_particleIntid ) const MCGIDI_TRUE_VIRTUAL;
1589 
1590         MCGIDI_VIRTUAL_FUNCTION LUPI_HOST_DEVICE Vector<double> const &upscatterModelAGroupVelocities( ) const MCGIDI_TRUE_VIRTUAL;
1591 
1592         LUPI_HOST_DEVICE void serialize( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
1593         LUPI_HOST_DEVICE void serialize2( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
1594         LUPI_HOST_DEVICE void serializeCommon( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
1595         LUPI_HOST_DEVICE long sizeOf( ) const ;
1596         LUPI_HOST_DEVICE long memorySize( );
1597         LUPI_HOST_DEVICE void incrementMemorySize( long &a_totalMemory, long &a_sharedMemory );
1598 
1599         friend ProtareSingle;
1600         friend ProtareComposite;
1601         friend ProtareTNSL;
1602 };
1603 
1604 /*
1605 ============================================================
1606 ====================== ProtareSingle =======================
1607 ============================================================
1608 */
1609 class ProtareSingle : public Protare {
1610 
1611     friend ProtareTNSL;
1612 
1613     private:
1614         String m_interaction;                                                       /**< The protare's interaction string. */
1615         int m_URR_index;                                                            /**< The index of the protare in the URR_protareInfos list. If negative, not in list. */
1616         bool m_hasURR_probabilityTables;                                            /**< *true* if URR probability tables present and *false* otherwise. */
1617         double m_URR_domainMin;                                                     /**< If URR probability tables present this is the minimum of the projectile energy domain for the tables. */
1618         double m_URR_domainMax;                                                     /**< If URR probability tables present this is the maximum of the projectile energy domain for the tables. */
1619         DomainHash m_domainHash;                                                    /**< A copy of the domain hash supplied by the user. */
1620         bool m_upscatterModelASupported;                                            /**< If **true**, upscatter model A plus can be used for this protare. */
1621         Vector<double> m_projectileMultiGroupBoundaries;                            /**< The multi-group boundaries for the projectile. Only used if m_crossSectionLookupMode and/or m_other1dDataLookupMode is multiGroup. */
1622         Vector<double> m_projectileMultiGroupBoundariesCollapsed;                   /**< The collased, multi-group boundaries for the projectile. Only used if m_crossSectionLookupMode and/or m_other1dDataLookupMode is multiGroup. */ 
1623         Vector<double> m_upscatterModelAGroupEnergies;                              /**< The speed of the projectile at each multi-group boundary. Need by upscatter model A. */
1624         Vector<double> m_upscatterModelAGroupVelocities;                            /**< The speed of the projectile at each multi-group boundary. Need by upscatter model A. */
1625         Vector<double> m_upscatterModelACrossSection;                               /**< The multi-group cross section to use for upscatter model A plus. */
1626         MultiGroupHash m_multiGroupHash;                                            /**< For upscatter model A with multi-group cross section data, this is the multi-group hash needed to lookup to cross section for the adjusted projectile energy. */
1627 
1628         Vector<Reaction *> m_reactions;                                             /**< The list of reactions. */
1629         Vector<Reaction *> m_orphanProducts;                                        /**< The list of orphan products. */
1630         bool m_isPhotoAtomic;                                                       /**< *true* if photo-atomic protare and false otherwise. */
1631         bool m_continuousEnergy;                                                    /**< If *true*, protare has continuous energy cross sections; otherwise, multi-group cross sections. */
1632         bool m_fixedGrid;                                                           /**< If *true*, continuous energy cross sections are fixed grid. */
1633         HeatedCrossSectionsContinuousEnergy m_heatedCrossSections;                  /**< Stores all cross section data for total and all reactions for all requested temperatures. */
1634         HeatedCrossSectionsMultiGroup m_heatedMultigroupCrossSections;              /**< Stores all multi-group cross section data for total and all reactions for all requested temperatures. */
1635 
1636         Vector<NuclideGammaBranchStateInfo *> m_nuclideGammaBranchStateInfos;       /**< List of all gamma branches for a nuclide. */
1637         Vector<NuclideGammaBranchInfo *> m_branches;                                /**< Condensed data on a nuclide's gamma branch including the gamma's energy, probability and the nuclide's residual state. */
1638 
1639         LUPI_HOST void setupNuclideGammaBranchStateInfos( SetupInfo &a_setupInfo, GIDI::ProtareSingle const &a_protare,
1640                 bool a_makePhotonEmissionProbabilitiesOne, bool a_zeroNuclearLevelEnergyWidth );
1641         LUPI_HOST_DEVICE void setUpscatterModelASupported( bool a_upscatterModelASupported ) { m_upscatterModelASupported = a_upscatterModelASupported; }   /**< Sets the value of *m_upscatterModelASupported* to *a_upscatterModelASupported*. */
1642 
1643     public:
1644         LUPI_HOST_DEVICE ProtareSingle( );
1645         LUPI_HOST ProtareSingle( LUPI::StatusMessageReporting &a_smr, GIDI::ProtareSingle const &a_protare, PoPI::Database const &a_pops, Transporting::MC &a_settings, 
1646                 GIDI::Transporting::Particles const &a_particles, DomainHash const &a_domainHash, GIDI::Styles::TemperatureInfos const &a_temperatureInfos,
1647                 GIDI::ExcludeReactionsSet const &a_reactionsToExclude, std::size_t a_reactionsToExcludeOffset = 0, bool a_allowFixedGrid = true );
1648         LUPI_HOST_DEVICE ~ProtareSingle( );
1649 
1650         LUPI_HOST_DEVICE bool isPhotoAtomic( ) const { return( m_isPhotoAtomic ); }
1651         LUPI_HOST_DEVICE bool continuousEnergy( ) const { return( m_continuousEnergy ); }
1652         LUPI_HOST_DEVICE bool fixedGrid( ) const { return( m_fixedGrid ); }
1653         LUPI_HOST_DEVICE HeatedCrossSectionsContinuousEnergy const &heatedCrossSections( ) const { return( m_heatedCrossSections ); }  /**< Returns a reference to the **m_heatedCrossSections** member. */
1654         LUPI_HOST_DEVICE HeatedCrossSectionsContinuousEnergy &heatedCrossSections( ) { return( m_heatedCrossSections ); }              /**< Returns a reference to the **m_heatedCrossSections** member. */
1655         LUPI_HOST_DEVICE HeatedCrossSectionsMultiGroup const &heatedMultigroupCrossSections( ) const { return( m_heatedMultigroupCrossSections ); } /**< Returns a reference to the **m_heatedMultigroupCrossSections** member. */
1656         LUPI_HOST_DEVICE HeatedCrossSectionsMultiGroup &heatedMultigroupCrossSections( ) { return( m_heatedMultigroupCrossSections ); } /**< Returns a reference to the **m_heatedMultigroupCrossSections** member. */
1657 
1658         LUPI_HOST_DEVICE const Vector<NuclideGammaBranchStateInfo *> &nuclideGammaBranchStateInfos( ) const { return( m_nuclideGammaBranchStateInfos ); }
1659                                                                                     /**< Returns a reference to the **m_nuclideGammaBranchStateInfos** member. */
1660         LUPI_HOST_DEVICE const Vector<NuclideGammaBranchInfo *> &branches( ) const { return( m_branches ); }
1661                                                                                     /**< Returns a reference to the **m_branches** member. */
1662 
1663 // FIXME (1) see FIXME (1) in MC class.
1664         LUPI_HOST_DEVICE Vector<Reaction *> const &reactions( ) const { return( m_reactions ); }                 /**< Returns the value of the **m_reactions** member. */
1665 // FIXME (1) see FIXME (1) in MC class.
1666         LUPI_HOST_DEVICE Vector<Reaction *> const &orphanProducts( ) const { return( m_orphanProducts ); }       /**< Returns the value of the **m_orphanProducts** member. */
1667 
1668         template <typename RNG, typename PUSHBACK>
1669         inline LUPI_HOST_DEVICE void sampleBranchingGammas( Sampling::Input &a_input, double a_projectileEnergy, int a_initialStateIndex, 
1670                 RNG && a_rng, PUSHBACK && push_back, Sampling::ProductHandler &a_products ) const ;
1671         LUPI_HOST void setUserParticleIndex2( int a_particleIndex, int a_userParticleIndex );
1672         LUPI_HOST void setUserParticleIndexViaIntid2( int a_particleIntid, int a_userParticleIndex );
1673 
1674 // The rest are virtual methods defined in the Protare class.
1675 
1676         LUPI_HOST_DEVICE std::size_t numberOfProtares( ) const { return( 1 ); }                        /**< Returns the number of protares contained in *this*. */
1677         LUPI_HOST_DEVICE ProtareSingle const *protare( std::size_t a_index ) const ;
1678         LUPI_HOST_DEVICE ProtareSingle       *protare( std::size_t a_index );
1679         LUPI_HOST_DEVICE ProtareSingle const *protareWithReaction( std::size_t a_index ) const ;
1680 
1681         LUPI_HOST_DEVICE double minimumEnergy( ) const { 
1682             if( m_continuousEnergy ) return( m_heatedCrossSections.minimumEnergy( ) );
1683             return( m_heatedMultigroupCrossSections.minimumEnergy( ) ); }                                   /**< Returns the minimum cross section domain. */
1684         LUPI_HOST_DEVICE double maximumEnergy( ) const { 
1685             if( m_continuousEnergy ) return( m_heatedCrossSections.maximumEnergy( ) );
1686             return( m_heatedMultigroupCrossSections.maximumEnergy( ) ); }                                   /**< Returns the maximum cross section domain. */
1687         LUPI_HOST_DEVICE Vector<double> temperatures( std::size_t a_index = 0 ) const ;
1688 
1689         LUPI_HOST Vector<double> const &projectileMultiGroupBoundaries( ) const { return( m_projectileMultiGroupBoundaries ); }
1690                                                                                                             /**< Returns the value of the **m_projectileMultiGroupBoundaries** member. */
1691         LUPI_HOST Vector<double> const &projectileMultiGroupBoundariesCollapsed( ) const { return( m_projectileMultiGroupBoundariesCollapsed ); }
1692                                                                                                             /**< Returns the value of the **m_projectileMultiGroupBoundariesCollapsed** member. */
1693 
1694         LUPI_HOST_DEVICE std::size_t numberOfReactions( ) const { return( m_reactions.size( ) ); }                       /**< Returns the number of reactions of *this*. */
1695         LUPI_HOST_DEVICE Reaction const *reaction( std::size_t a_index ) const { return( m_reactions[a_index] ); }               /**< Returns the (a_index-1)^th reaction of *this*. */
1696         LUPI_HOST_DEVICE std::size_t numberOfOrphanProducts( ) const { return( m_orphanProducts.size( ) ); }             /**< Returns the number of orphan products of *this*. */
1697         LUPI_HOST_DEVICE Reaction const *orphanProduct( std::size_t a_index ) const { return( m_orphanProducts[a_index] ); }     /**< Returns the (a_index-1)^th orphan product of *this*. */
1698 
1699         LUPI_HOST_DEVICE bool hasFission( ) const ;
1700         LUPI_HOST_DEVICE String interaction( ) const { return( m_interaction ); }
1701         LUPI_HOST_DEVICE bool hasIncoherentDoppler( ) const ;
1702 
1703         LUPI_HOST_DEVICE int URR_index( ) const { return( m_URR_index ); }
1704         LUPI_HOST_DEVICE void setURR_index( int a_URR_index ) { m_URR_index = a_URR_index; }
1705         LUPI_HOST_DEVICE bool inURR( double a_energy ) const ;
1706         LUPI_HOST_DEVICE bool hasURR_probabilityTables( ) const { return( m_hasURR_probabilityTables ); }
1707         LUPI_HOST_DEVICE double URR_domainMin( ) const { return( m_URR_domainMin ); }
1708         LUPI_HOST_DEVICE double URR_domainMax( ) const { return( m_URR_domainMax ); }
1709         LUPI_HOST_DEVICE bool reactionHasURR_probabilityTables( std::size_t a_index ) const { return( m_heatedCrossSections.reactionHasURR_probabilityTables( a_index ) ); }
1710 
1711         LUPI_HOST_DEVICE double threshold( std::size_t a_index ) const {
1712             if( m_continuousEnergy ) return( m_heatedCrossSections.threshold( a_index ) );
1713             return( m_heatedMultigroupCrossSections.threshold( a_index ) ); }                                       /**< Returns the threshold for the reaction at index *a_index*. */
1714 
1715         LUPI_HOST_DEVICE double crossSection(                              URR_protareInfos const &a_URR_protareInfos, 
1716                 std::size_t a_hashIndex, double a_temperature, double a_energy, bool a_sampling = false ) const ;
1717         LUPI_HOST_DEVICE void crossSectionVector( double a_temperature, double a_userFactor, std::size_t a_numberAllocated, 
1718                 double *a_crossSectionVector ) const ;
1719         LUPI_HOST_DEVICE double reactionCrossSection( std::size_t a_reactionIndex, URR_protareInfos const &a_URR_protareInfos, 
1720                 std::size_t a_hashIndex, double a_temperature, double a_energy, bool a_sampling = false ) const ;
1721         LUPI_HOST_DEVICE double reactionCrossSection( std::size_t a_reactionIndex, URR_protareInfos const &a_URR_protareInfos,                  double a_temperature, double a_energy ) const ;
1722 
1723         template <typename RNG>
1724         inline LUPI_HOST_DEVICE bool sampleTargetBetaForUpscatterModelA( Sampling::Input &a_input, RNG && a_rng ) const ;
1725         template <typename RNG>
1726         inline LUPI_HOST_DEVICE std::size_t sampleReaction( Sampling::Input &a_input, URR_protareInfos const &a_URR_protareInfos, 
1727                 std::size_t a_hashIndex, double a_crossSection, RNG && a_rng  ) const ;
1728 
1729         LUPI_HOST_DEVICE double depositionEnergy(   std::size_t a_hashIndex, double a_temperature, double a_energy ) const ;
1730         LUPI_HOST_DEVICE double depositionMomentum( std::size_t a_hashIndex, double a_temperature, double a_energy ) const ;
1731         LUPI_HOST_DEVICE double productionEnergy(   std::size_t a_hashIndex, double a_temperature, double a_energy ) const ;
1732         LUPI_HOST_DEVICE double gain(               std::size_t a_hashIndex, double a_temperature, double a_energy, int a_particleIndex ) const ;
1733         LUPI_HOST_DEVICE double gainViaIntid(       std::size_t a_hashIndex, double a_temperature, double a_energy, int a_particleIntid ) const ;
1734 
1735         LUPI_HOST_DEVICE bool upscatterModelASupported( ) const { return( m_upscatterModelASupported ); } /**< Returns the value of the **m_upscatterModelASupported** member. */
1736         LUPI_HOST_DEVICE Vector<double> const &upscatterModelAGroupEnergies( ) const { return( m_upscatterModelAGroupEnergies ); }   /**< Returns a reference to the **m_upscatterModelAGroupEnergies** member. */
1737         LUPI_HOST_DEVICE Vector<double> const &upscatterModelAGroupVelocities( ) const { return( m_upscatterModelAGroupVelocities ); }   /**< Returns a reference to the **m_upscatterModelAGroupVelocities** member. */
1738         LUPI_HOST_DEVICE Vector<double> const &upscatterModelACrossSection( ) const { return( m_upscatterModelACrossSection ); } 
1739                                                                                                             /**< Returns the value of the **m_upscatterModelACrossSection**. */
1740 
1741         LUPI_HOST_DEVICE void serialize2( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
1742         LUPI_HOST_DEVICE long sizeOf2( ) const { return sizeof(*this); }
1743 };
1744 
1745 /*
1746 ============================================================
1747 ===================== ProtareComposite =====================
1748 ============================================================
1749 */
1750 class ProtareComposite : public Protare {
1751 
1752     private:
1753         Vector<ProtareSingle *> m_protares;                              /**< List of protares added to *this* instance. */
1754         std::size_t m_numberOfReactions;                                    /**< The sum of the number of reaction for all stored protares. */
1755         std::size_t m_numberOfOrphanProducts;                               /**< The sum of the number of reaction for all stored protares. */
1756         double m_minimumEnergy;                                             /**< The maximum of the minimum cross section domains. */
1757         double m_maximumEnergy;                                             /**< The minimum of the maximum cross section domains. */
1758 
1759     public:
1760         LUPI_HOST_DEVICE ProtareComposite( );
1761         LUPI_HOST ProtareComposite( LUPI::StatusMessageReporting &a_smr, GIDI::ProtareComposite const &a_protare, PoPI::Database const &a_pops, Transporting::MC &a_settings, 
1762                 GIDI::Transporting::Particles const &a_particles, DomainHash const &a_domainHash, GIDI::Styles::TemperatureInfos const &a_temperatureInfos,
1763                 GIDI::ExcludeReactionsSet const &a_reactionsToExclude, std::size_t a_reactionsToExcludeOffset = 0, bool a_allowFixedGrid = true );
1764         LUPI_HOST_DEVICE ~ProtareComposite( );
1765 
1766         Vector<ProtareSingle *> protares( ) const { return( m_protares ); }       /**< Returns the value of the **m_protares** member. */
1767         LUPI_HOST void setUserParticleIndex2( int a_particleIndex, int a_userParticleIndex );
1768         LUPI_HOST void setUserParticleIndexViaIntid2( int a_particleIntid, int a_userParticleIndex );
1769 
1770 // The rest are virtual methods defined in the Protare class.
1771 
1772         LUPI_HOST_DEVICE std::size_t numberOfProtares( ) const { return( m_protares.size( ) ); }     /**< Returns the number of protares contained in *this*. */
1773         LUPI_HOST_DEVICE ProtareSingle const *protare( std::size_t a_index ) const ;
1774         LUPI_HOST_DEVICE ProtareSingle       *protare( std::size_t a_index );
1775         LUPI_HOST_DEVICE ProtareSingle const *protareWithReaction( std::size_t a_index ) const ;
1776 
1777         LUPI_HOST_DEVICE double minimumEnergy( ) const { return( m_minimumEnergy ); }     /**< Returns the value of the **m_minimumEnergy** member. */
1778         LUPI_HOST_DEVICE double maximumEnergy( ) const { return( m_maximumEnergy ); }     /**< Returns the value of the **m_maximumEnergy** member. */
1779         LUPI_HOST_DEVICE Vector<double> temperatures( std::size_t a_index = 0 ) const ;
1780 
1781         LUPI_HOST Vector<double> const &projectileMultiGroupBoundaries( ) const { return( m_protares[0]->projectileMultiGroupBoundaries( ) ); }    
1782                                                                             /**< Returns the value of the **m_projectileMultiGroupBoundaries** member. */
1783         LUPI_HOST Vector<double> const &projectileMultiGroupBoundariesCollapsed( ) const { return( m_protares[0]->projectileMultiGroupBoundariesCollapsed( ) ); }
1784                                                                             /**< Returns the value of the **m_projectileMultiGroupBoundariesCollapsed** member. */
1785 
1786         LUPI_HOST_DEVICE std::size_t numberOfReactions( ) const { return( m_numberOfReactions ); }
1787                                                                             /**< Returns the value of the **m_numberOfReactions** member. */
1788         LUPI_HOST_DEVICE Reaction const *reaction( std::size_t a_index ) const ;
1789         LUPI_HOST_DEVICE std::size_t numberOfOrphanProducts( ) const { return( m_numberOfOrphanProducts ); }
1790                                                                             /**< Returns the value of the **m_numberOfOrphanProducts** member. */
1791         LUPI_HOST_DEVICE Reaction const *orphanProduct( std::size_t a_index ) const ;
1792 
1793         LUPI_HOST_DEVICE bool hasFission( ) const ;
1794         LUPI_HOST_DEVICE bool hasIncoherentDoppler( ) const ;
1795 
1796         LUPI_HOST_DEVICE int URR_index( ) const { return( -1 ); }
1797         LUPI_HOST_DEVICE bool hasURR_probabilityTables( ) const ;
1798         LUPI_HOST_DEVICE double URR_domainMin( ) const ;
1799         LUPI_HOST_DEVICE double URR_domainMax( ) const ;
1800         LUPI_HOST_DEVICE bool reactionHasURR_probabilityTables( std::size_t a_index ) const ;
1801 
1802         LUPI_HOST_DEVICE double threshold( std::size_t a_index ) const ;
1803 
1804         LUPI_HOST_DEVICE double crossSection(                              URR_protareInfos const &a_URR_protareInfos, 
1805                 std::size_t a_hashIndex, double a_temperature, double a_energy, bool a_sampling = false ) const ;
1806         LUPI_HOST_DEVICE void crossSectionVector( double a_temperature, double a_userFactor, std::size_t a_numberAllocated, 
1807                 double *a_crossSectionVector ) const ;
1808         LUPI_HOST_DEVICE double reactionCrossSection( std::size_t a_reactionIndex, URR_protareInfos const &a_URR_protareInfos, 
1809                 std::size_t a_hashIndex, double a_temperature, double a_energy, bool a_sampling = false ) const ;
1810         LUPI_HOST_DEVICE double reactionCrossSection( std::size_t a_reactionIndex, URR_protareInfos const &a_URR_protareInfos,                  double a_temperature, double a_energy ) const ;
1811         template <typename RNG>
1812         inline LUPI_HOST_DEVICE std::size_t sampleReaction( Sampling::Input &a_input, URR_protareInfos const &a_URR_protareInfos, 
1813                 std::size_t a_hashIndex, double a_crossSection, RNG && a_rng ) const ;
1814 
1815         LUPI_HOST_DEVICE double depositionEnergy(   std::size_t a_hashIndex, double a_temperature, double a_energy ) const ;
1816         LUPI_HOST_DEVICE double depositionMomentum( std::size_t a_hashIndex, double a_temperature, double a_energy ) const ;
1817         LUPI_HOST_DEVICE double productionEnergy(   std::size_t a_hashIndex, double a_temperature, double a_energy ) const ;
1818         LUPI_HOST_DEVICE double gain(               std::size_t a_hashIndex, double a_temperature, double a_energy, int a_particleIndex ) const ;
1819         LUPI_HOST_DEVICE double gainViaIntid(       std::size_t a_hashIndex, double a_temperature, double a_energy, int a_particleIntid ) const ;
1820 
1821         LUPI_HOST_DEVICE Vector<double> const &upscatterModelAGroupVelocities( ) const { return( m_protares[0]->upscatterModelAGroupVelocities( ) ); }
1822                                                                             /**< Returns a reference to the **m_upscatterModelAGroupVelocities** member. */
1823 
1824         LUPI_HOST_DEVICE void serialize2( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
1825         LUPI_HOST_DEVICE long sizeOf2( ) const { return sizeof(*this); }
1826 };
1827 
1828 /*
1829 ============================================================
1830 ======================== ProtareTNSL =======================
1831 ============================================================
1832 */
1833 class ProtareTNSL : public Protare {
1834 
1835     private:
1836         std::size_t m_numberOfTNSLReactions;                                /**< The number of reactions of the TNSL protare. */
1837         double m_TNSL_maximumEnergy;                                        /**< The maximum energy of the cross section domain for the TNSL protare. */
1838         double m_TNSL_maximumTemperature;                                   /**< The highest temperature for processed data for the TNSL protare. */
1839         ProtareSingle *m_protareWithElastic;                                /**< Protare with non thermal neutron scattering law data. */
1840         ProtareSingle *m_TNSL;                                              /**< Protare with thermal neutron scattering law data. */
1841         ProtareSingle *m_protareWithoutElastic;                             /**< Same as *m_protare* but without elastic. */
1842 
1843     public:
1844         LUPI_HOST_DEVICE ProtareTNSL( );
1845         LUPI_HOST ProtareTNSL( LUPI::StatusMessageReporting &a_smr, GIDI::ProtareTNSL const &a_protare, PoPI::Database const &a_pops, Transporting::MC &a_settings, 
1846                 GIDI::Transporting::Particles const &a_particles, DomainHash const &a_domainHash, GIDI::Styles::TemperatureInfos const &a_temperatureInfos,
1847                 GIDI::ExcludeReactionsSet const &a_reactionsToExclude, std::size_t a_reactionsToExcludeOffset = 0, bool a_allowFixedGrid = true );
1848         LUPI_HOST_DEVICE ~ProtareTNSL( );
1849 
1850         LUPI_HOST_DEVICE ProtareSingle const *protareWithElastic( ) const { return( m_protareWithElastic ); }        /**< Returns the **m_protareWithElastic** member. */
1851         LUPI_HOST_DEVICE ProtareSingle const *TNSL( ) const { return( m_TNSL ); }                                    /**< Returns the **m_TNSL** member. */
1852         LUPI_HOST_DEVICE ProtareSingle const *protareWithoutElastic( ) const { return( m_protareWithoutElastic ); }  /**< Returns the **m_protareWithoutElastic** member. */
1853 
1854         LUPI_HOST_DEVICE double TNSL_maximumEnergy( ) const { return( m_TNSL_maximumEnergy ); }
1855         LUPI_HOST_DEVICE double TNSL_maximumTemperature( ) const { return( m_TNSL_maximumTemperature ); }
1856         LUPI_HOST void setUserParticleIndex2( int a_particleIndex, int a_userParticleIndex );
1857         LUPI_HOST void setUserParticleIndexViaIntid2( int a_particleIntid, int a_userParticleIndex );
1858 
1859 // The rest are virtual methods defined in the Protare class.
1860 
1861         LUPI_HOST_DEVICE std::size_t numberOfProtares( ) const { return( 2 ); }  /**< Always Returns 2. */
1862         LUPI_HOST_DEVICE ProtareSingle const *protare( std::size_t a_index ) const ;
1863         LUPI_HOST_DEVICE ProtareSingle       *protare( std::size_t a_index );
1864         LUPI_HOST_DEVICE ProtareSingle const *protareWithReaction( std::size_t a_index ) const ;
1865 
1866         LUPI_HOST_DEVICE double minimumEnergy( ) const { return( m_protareWithElastic->minimumEnergy( ) ); }   /**< Returns the minimum cross section domain. */
1867         LUPI_HOST_DEVICE double maximumEnergy( ) const { return( m_protareWithElastic->maximumEnergy( ) ); }   /**< Returns the maximum cross section domain. */
1868         LUPI_HOST_DEVICE Vector<double> temperatures( std::size_t a_index = 0 ) const ;
1869 
1870         LUPI_HOST Vector<double> const &projectileMultiGroupBoundaries( ) const { return( m_protareWithElastic->projectileMultiGroupBoundaries( ) ); }
1871                                                                             /**< Returns the value of the **m_projectileMultiGroupBoundaries** member. */
1872         LUPI_HOST Vector<double> const &projectileMultiGroupBoundariesCollapsed( ) const { return( m_protareWithElastic->projectileMultiGroupBoundariesCollapsed( ) ); }
1873                                                                             /**< Returns the value of the **m_projectileMultiGroupBoundariesCollapsed** member. */
1874 
1875         LUPI_HOST_DEVICE std::size_t numberOfReactions( ) const { return( m_TNSL->numberOfReactions( ) + m_protareWithElastic->numberOfReactions( ) ); }
1876         LUPI_HOST_DEVICE Reaction const *reaction( std::size_t a_index ) const ;
1877         LUPI_HOST_DEVICE std::size_t numberOfOrphanProducts( ) const { return( m_protareWithElastic->numberOfOrphanProducts( ) ); }
1878                                                                             /**< Returns the number of orphan products in the normal ProtareSingle. */
1879         LUPI_HOST_DEVICE Reaction const *orphanProduct( std::size_t a_index ) const { return( m_protareWithElastic->orphanProduct( a_index ) ); }
1880                                                                             /**< Returns the (a_index - 1 )^th orphan product in the normal ProtareSingle. */
1881 
1882         LUPI_HOST_DEVICE bool hasFission( ) const { return( m_protareWithElastic->hasFission( ) ); }    /* Returns the normal ProtareSingle's hasFission value. */
1883         LUPI_HOST_DEVICE bool hasIncoherentDoppler( ) const { return( false ); }                        /* Always returns false as this is a neutron as projectile and not a photon. */
1884 
1885         LUPI_HOST_DEVICE int URR_index( ) const { return( -1 ); }
1886         LUPI_HOST_DEVICE bool hasURR_probabilityTables( ) const { return( m_protareWithElastic->hasURR_probabilityTables( ) ); }
1887         LUPI_HOST_DEVICE double URR_domainMin( ) const { return( m_protareWithElastic->URR_domainMin( ) ); }
1888         LUPI_HOST_DEVICE double URR_domainMax( ) const { return( m_protareWithElastic->URR_domainMax( ) ); }
1889         LUPI_HOST_DEVICE bool reactionHasURR_probabilityTables( std::size_t a_index ) const ;
1890 
1891         LUPI_HOST_DEVICE double threshold( std::size_t a_index ) const ;
1892 
1893         LUPI_HOST_DEVICE double crossSection(                              URR_protareInfos const &a_URR_protareInfos, 
1894                 std::size_t a_hashIndex, double a_temperature, double a_energy, bool a_sampling = false ) const ;
1895         LUPI_HOST_DEVICE void crossSectionVector( double a_temperature, double a_userFactor, std::size_t a_numberAllocated, 
1896                 double *a_crossSectionVector ) const ;
1897         LUPI_HOST_DEVICE double reactionCrossSection( std::size_t a_reactionIndex, URR_protareInfos const &a_URR_protareInfos, 
1898                 std::size_t a_hashIndex, double a_temperature, double a_energy, bool a_sampling = false ) const ;
1899         LUPI_HOST_DEVICE double reactionCrossSection( std::size_t a_reactionIndex, URR_protareInfos const &a_URR_protareInfos,                  double a_temperature, double a_energy ) const ;
1900         template <typename RNG>
1901         inline LUPI_HOST_DEVICE std::size_t sampleReaction( Sampling::Input &a_input, URR_protareInfos const &a_URR_protareInfos, 
1902                 std::size_t a_hashIndex, double a_crossSection, RNG && a_rng ) const ;
1903 
1904         LUPI_HOST_DEVICE double depositionEnergy(   std::size_t a_hashIndex, double a_temperature, double a_energy ) const ;
1905         LUPI_HOST_DEVICE double depositionMomentum( std::size_t a_hashIndex, double a_temperature, double a_energy ) const ;
1906         LUPI_HOST_DEVICE double productionEnergy(   std::size_t a_hashIndex, double a_temperature, double a_energy ) const ;
1907         LUPI_HOST_DEVICE double gain(               std::size_t a_hashIndex, double a_temperature, double a_energy, int a_particleIndex ) const ;
1908         LUPI_HOST_DEVICE double gainViaIntid(       std::size_t a_hashIndex, double a_temperature, double a_energy, int a_particleIntid ) const ;
1909 
1910         LUPI_HOST_DEVICE Vector<double> const &upscatterModelAGroupVelocities( ) const { return( m_protareWithElastic->upscatterModelAGroupVelocities( ) ); }
1911                                                                             /**< Returns a reference to the **m_upscatterModelAGroupVelocities** member. */
1912 
1913         LUPI_HOST_DEVICE void serialize2( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
1914         LUPI_HOST_DEVICE long sizeOf2( ) const { return sizeof(*this); }
1915 };
1916 
1917 /*
1918 ============================================================
1919 =========================== Others =========================
1920 ============================================================
1921 */
1922 LUPI_HOST Protare *protareFromGIDIProtare( LUPI::StatusMessageReporting &a_smr, GIDI::Protare const &a_protare, PoPI::Database const &a_pops, Transporting::MC &a_settings, GIDI::Transporting::Particles const &a_particles,
1923                 DomainHash const &a_domainHash, GIDI::Styles::TemperatureInfos const &a_temperatureInfos, GIDI::ExcludeReactionsSet const &a_reactionsToExclude,
1924                 std::size_t a_reactionsToExcludeOffset = 0, bool a_allowFixedGrid = true );
1925 LUPI_HOST Vector<double> GIDI_VectorDoublesToMCGIDI_VectorDoubles( GIDI::Vector a_vector );
1926 LUPI_HOST void addVectorItemsToSet( Vector<int> const &a_from, std::set<int> &a_to );
1927 
1928 LUPI_HOST_DEVICE int distributionTypeToInt( Distributions::Type a_type );
1929 LUPI_HOST_DEVICE Distributions::Type intToDistributionType( int a_type );
1930 LUPI_HOST_DEVICE void serializeProducts( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode, Vector<Product *> &a_products );
1931 LUPI_HOST_DEVICE void serializeDelayedNeutrons( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode, Vector<DelayedNeutron *> &a_delayedNeutrons );
1932 LUPI_HOST_DEVICE void serializeQs( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode, Vector<Functions::Function1d_d1 *> &a_Qs );
1933 LUPI_HOST_DEVICE void serializeFissionResiduals( GIDI::Construction::FissionResiduals &a_fissionResiduals, 
1934                 LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
1935 
1936 LUPI_HOST void convertACE_URR_probabilityTablesFromGIDI( GIDI::ProtareSingle const &a_protare, Transporting::MC &a_settings, SetupInfo &a_setupInfo );
1937 LUPI_HOST_DEVICE Transporting::URR_mode serializeURR_mode( Transporting::URR_mode a_URR_mode, LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
1938 LUPI_HOST_DEVICE ACE_URR_probabilityTables *serializeACE_URR_probabilityTables( ACE_URR_probabilityTables *a_ACE_URR_probabilityTables,
1939                 LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode );
1940 
1941 LUPI_HOST_DEVICE Distributions::Distribution *serializeDistribution( LUPI::DataBuffer &a_buffer, LUPI::DataBuffer::Mode a_mode, 
1942                 Distributions::Distribution *a_distribution );
1943 
1944 LUPI_HOST std::vector<double> vectorToSTD_vector( Vector<double> a_input );
1945 LUPI_HOST std::vector<double> vectorToSTD_vector( Vector<float> a_input );
1946 
1947 }           // End of namespace MCGIDI.
1948 
1949 #include "MCGIDI_headerSource.hpp"
1950 
1951 #endif      // End of MCGIDI_hpp_included