Geant4 11.4.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4GIDI_target.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26
27#include <G4GIDI.hh>
28
29/*! \class G4GIDI_target
30 * A class to store map files for a particular projectile.
31 */
32
33/* *********************************************************************************************************//**
34 * @param a_MCProtare [in] The MCGIDI protare.
35 ***********************************************************************************************************/
36
37G4GIDI_target::G4GIDI_target( PoPI::Database const &a_pops, MCGIDI::DomainHash const &a_domainHash, GIDI::Protare const &a_GIDI_protare,
38 MCGIDI::Protare *a_MCGIDI_protare ) :
39 m_MCGIDI_protare( a_MCGIDI_protare ),
40 m_target( a_GIDI_protare.target( ).ID( ) ),
41 m_fileName( a_GIDI_protare.fileName( ) ),
42 m_evaluation( a_GIDI_protare.evaluation( ) ),
43 m_targetZ( 0 ),
44 m_targetA( 0 ),
45 m_targetM( 0 ),
46 m_targetMass( 0.0 ),
47 m_domainHash( a_domainHash ),
48 m_elasticAngular( nullptr ) {
49
50 PoPI::Base const *targetAsBase = &a_pops.get<PoPI::Base const>( m_target );
51 PoPI::Base const *targetAsBase2 = targetAsBase;
52 if( targetAsBase->isAlias( ) ) {
53 targetAsBase2 = &a_pops.get<PoPI::Base const>( a_pops.final( m_target ) );
54 }
55 m_targetZ = PoPI::particleZ( *targetAsBase2, true );
56 m_targetA = PoPI::particleA( *targetAsBase2, true );
57 m_targetM = PoPI::particleMetaStableIndex( *targetAsBase );
58 if( targetAsBase2->isParticle( ) ) {
59 PoPI::Particle const *targetAsParticle = static_cast<PoPI::Particle const *>( targetAsBase2 );
60 m_targetMass = targetAsParticle->massValue( "amu" );
61 }
62
63 for( std::size_t reactionIndex = 0; reactionIndex < a_MCGIDI_protare->numberOfReactions( ); ++reactionIndex ) {
64 MCGIDI::Reaction const *reaction = a_MCGIDI_protare->reaction( reactionIndex );
65
66 if( reaction->ENDF_MT( ) == 2 ) {
67 m_elasticIndices.push_back( static_cast<int>( reactionIndex ) ); }
68 else if( reaction->ENDF_MT( ) == 18 ) {
69 m_fissionIndices.push_back( static_cast<int>( reactionIndex ) ); }
70 else if( reaction->ENDF_MT( ) == 102 ) {
71 m_captureIndices.push_back( static_cast<int>( reactionIndex ) ); }
72 else {
73 m_othersIndices.push_back( static_cast<int>( reactionIndex ) );
74 }
75 }
76
77 if( m_elasticIndices.size( ) > 0 ) {
78 MCGIDI::Reaction const *elastic = a_MCGIDI_protare->reaction( m_elasticIndices[0] );
79 MCGIDI::Product const *firstProduct = elastic->product( 0 );
80 MCGIDI::Distributions::AngularTwoBody const *angularTwoBody = static_cast<MCGIDI::Distributions::AngularTwoBody const *>( firstProduct->distribution( ) );
81 m_elasticAngular = angularTwoBody->angular( );
82 }
83}
84
85/* *********************************************************************************************************//**
86 ***********************************************************************************************************/
87
89
90 delete m_MCGIDI_protare;
91}
92
93/* *********************************************************************************************************//**
94 ***********************************************************************************************************/
95
97
98 return( static_cast<int>( m_MCGIDI_protare->numberOfReactions( ) ) );
99}
100/* *********************************************************************************************************//**
101 ***********************************************************************************************************/
102
104
105 return( static_cast<int>( m_MCGIDI_protare->numberOfOrphanProducts( ) ) );
106}
107
108/* *********************************************************************************************************//**
109 ***********************************************************************************************************/
110
111channelID G4GIDI_target::getChannelsID( int channelIndex ) const {
112
113 return( channelID( m_MCGIDI_protare->reaction( channelIndex )->label( ).c_str( ) ) );
114}
115
116/* *********************************************************************************************************//**
117 ***********************************************************************************************************/
118
119std::vector<channelID> *G4GIDI_target::getChannelIDs( ) const {
120
121 std::vector<channelID> *channelIDs = new std::vector<channelID>( 0 );
122
123 for( std::size_t reactionIndex = 0; reactionIndex < m_MCGIDI_protare->numberOfReactions( ); ++reactionIndex ) {
124 MCGIDI::Reaction const *reaction = m_MCGIDI_protare->reaction( reactionIndex );
125 channelIDs->push_back( reaction->label( ).c_str( ) );
126 }
127
128 return( channelIDs );
129}
130
131/* *********************************************************************************************************//**
132 ***********************************************************************************************************/
133
134std::vector<channelID> *G4GIDI_target::getProductionChannelIDs( ) const {
135
136 std::vector<channelID> *channelIDs = new std::vector<channelID>( 0 );
137
138 for( std::size_t reactionIndex = 0; reactionIndex < m_MCGIDI_protare->numberOfOrphanProducts( ); ++reactionIndex ) {
139 MCGIDI::Reaction const *reaction = m_MCGIDI_protare->orphanProduct( reactionIndex );
140 channelIDs->push_back( reaction->label( ).c_str( ) );
141 }
142
143 return( channelIDs );
144}
145
146/* *********************************************************************************************************//**
147 ***********************************************************************************************************/
148
149double G4GIDI_target::getTotalCrossSectionAtE( double a_energy, double a_temperature ) const {
150
151 std::size_t hashIndex = m_domainHash.index( a_energy );
152
153 return( m_MCGIDI_protare->crossSection( m_URR_protareInfos, hashIndex, a_temperature, a_energy ) );
154}
155
156/* *********************************************************************************************************//**
157 ***********************************************************************************************************/
158
159double G4GIDI_target::getElasticCrossSectionAtE( double a_energy, double a_temperature ) const {
160
161 return( sumChannelCrossSectionAtE( m_elasticIndices, a_energy, a_temperature ) );
162}
163
164/* *********************************************************************************************************//**
165 ***********************************************************************************************************/
166
167double G4GIDI_target::getCaptureCrossSectionAtE( double a_energy, double a_temperature ) const {
168
169 return( sumChannelCrossSectionAtE( m_captureIndices, a_energy, a_temperature ) );
170}
171
172/* *********************************************************************************************************//**
173 ***********************************************************************************************************/
174
175double G4GIDI_target::getFissionCrossSectionAtE( double a_energy, double a_temperature ) const {
176
177 return( sumChannelCrossSectionAtE( m_fissionIndices, a_energy, a_temperature ) );
178}
179
180/* *********************************************************************************************************//**
181 ***********************************************************************************************************/
182
183double G4GIDI_target::getOthersCrossSectionAtE( double a_energy, double a_temperature ) const {
184
185 return( sumChannelCrossSectionAtE( m_othersIndices, a_energy, a_temperature ) );
186}
187
188/* *********************************************************************************************************//**
189 ***********************************************************************************************************/
190
191double G4GIDI_target::sumChannelCrossSectionAtE( std::vector<int> const &a_indices, double a_energy, double a_temperature ) const {
192
193 std::size_t hashIndex = m_domainHash.index( a_energy );
194 double crossSection = 0.0;
195
196 for( auto indexIter = a_indices.begin( ); indexIter != a_indices.end( ); ++indexIter ) {
197 crossSection += m_MCGIDI_protare->reactionCrossSection( *indexIter, m_URR_protareInfos, hashIndex, a_temperature, a_energy );
198 }
199
200 return( crossSection );
201}
202
203/* *********************************************************************************************************//**
204 ***********************************************************************************************************/
205
206double G4GIDI_target::sumChannelCrossSectionAtE( int a_nIndices, int const *a_indices, double a_energy, double a_temperature ) const {
207
208 std::vector<int> indices( a_nIndices );
209 for( int index = 0; index < a_nIndices; ++index ) indices[index] = a_indices[index];
210
211 return( sumChannelCrossSectionAtE( indices, a_energy, a_temperature ) );
212}
213
214/* *********************************************************************************************************//**
215 ***********************************************************************************************************/
216
217int G4GIDI_target::sampleChannelCrossSectionAtE( std::vector<int> const &a_indices, double a_energy, double a_temperature,
218 double (*a_rng)( void * ), void *a_rngState ) const {
219
220 int index = 0;
221 int nIndices = static_cast<int>( a_indices.size( ) );
222 double crossSectionSample = sumChannelCrossSectionAtE( a_indices, a_energy, a_temperature );
223 double crossSectionSum = 0.0;
224
225 crossSectionSample *= a_rng( a_rngState );
226 for( ; index < nIndices; ++index ) {
227 crossSectionSum += sumChannelCrossSectionAtE( 1, &a_indices[index], a_energy, a_temperature );
228 if( crossSectionSum >= crossSectionSample ) break;
229 }
230 if( index == nIndices ) --index; // This should really be an error.
231
232 return( a_indices[index] );
233}
234/* *********************************************************************************************************//**
235 ***********************************************************************************************************/
236
237int G4GIDI_target::sampleChannelCrossSectionAtE( int a_nIndices, int const *a_indices, double a_energy, double a_temperature,
238 double (*a_rng)( void * ), void *a_rngState ) const {
239
240 std::vector<int> indices( a_nIndices );
241 for( int index = 0; index < a_nIndices; ++index ) indices[index] = a_indices[index];
242
243 return( sampleChannelCrossSectionAtE( indices, a_energy, a_temperature, a_rng, a_rngState ) );
244}
245
246/* *********************************************************************************************************//**
247 ***********************************************************************************************************/
248
249double G4GIDI_target::getElasticFinalState( double a_energy, LUPI_maybeUnused double a_temperature, double (*a_rng)( void * ), void *a_rngState ) const {
250
251 return( m_elasticAngular->sample( a_energy, a_rng( a_rngState ), [&]() -> double { return a_rng( a_rngState ); } ) );
252}
253
254/* *********************************************************************************************************//**
255 ***********************************************************************************************************/
256
257std::vector<G4GIDI_Product> *G4GIDI_target::getCaptureFinalState( double a_energy, double a_temperature, double (*a_rng)( void * ), void *a_rngState ) const {
258
259 return( getFinalState( m_captureIndices, a_energy, a_temperature, a_rng, a_rngState ) );
260}
261
262/* *********************************************************************************************************//**
263 ***********************************************************************************************************/
264
265std::vector<G4GIDI_Product> *G4GIDI_target::getFissionFinalState( double a_energy, double a_temperature, double (*a_rng)( void * ), void *a_rngState ) const {
266
267 return( getFinalState( m_fissionIndices, a_energy, a_temperature, a_rng, a_rngState ) );
268}
269
270/* *********************************************************************************************************//**
271 ***********************************************************************************************************/
272
273std::vector<G4GIDI_Product> *G4GIDI_target::getOthersFinalState( double a_energy, double a_temperature, double (*a_rng)( void * ), void *a_rngState ) const {
274
275 return( getFinalState( m_othersIndices, a_energy, a_temperature, a_rng, a_rngState ) );
276}
277
278/* *********************************************************************************************************//**
279 ***********************************************************************************************************/
280
281std::vector<G4GIDI_Product> *G4GIDI_target::getFinalState( std::vector<int> const &a_indices, double a_energy, double a_temperature,
282 double (*a_rng)( void * ), void *a_rngState ) const {
283
284 int reactionIndex;
285
286 if( a_indices.size( ) == 0 ) return( NULL );
287 if( a_indices.size( ) == 1 ) {
288 reactionIndex = a_indices[0]; }
289 else {
290 reactionIndex = sampleChannelCrossSectionAtE( a_indices, a_energy, a_temperature, a_rng, a_rngState );
291 }
292
295 input.setTemperatureAndEnergy( a_temperature, a_energy );
296
297 MCGIDI::Reaction const *reaction = m_MCGIDI_protare->reaction( reactionIndex );
298 reaction->sampleProducts( m_MCGIDI_protare, input, [&]() -> double { return a_rng( a_rngState ); },
299 [&] (MCGIDI::Sampling::Product &a_product) -> void { productHandler.push_back( a_product ); }, productHandler );
300
301 std::vector<G4GIDI_Product> *products = new std::vector<G4GIDI_Product>( productHandler.size( ) );
302
303 for( std::size_t index = 0; index < productHandler.size( ); ++index ) {
304 MCGIDI::Sampling::Product &productIn = productHandler[index];
305 G4GIDI_Product &productOut = (*products)[index];
306
307 if( productIn.m_productIntid == 1020000000 ) { // Neutron.
308 productOut.A = 1;
309 productOut.Z = 0;
310 productOut.m = 0; }
311 else if( productIn.m_productIntid == 1000000000 ) { // Photon.
312 productOut.A = 0;
313 productOut.Z = 0;
314 productOut.m = 0; }
315 else {
316 PoPI::ParseIntidInfo parseIntidInfo( productIn.m_productIntid );
317 productOut.A = parseIntidInfo.AAA( );
318 productOut.Z = parseIntidInfo.ZZZ( );
319 productOut.m = parseIntidInfo.metaStableIndex( );
320 }
321
322 productOut.kineticEnergy = productIn.m_kineticEnergy;
323 productOut.px = productIn.m_px_vx;
324 productOut.py = productIn.m_py_vy;
325 productOut.pz = productIn.m_pz_vz;
326 }
327
328 return( products );
329}
330
331/* *********************************************************************************************************//**
332 ***********************************************************************************************************/
333
334std::vector<G4GIDI_Product> *G4GIDI_target::getFinalState( int a_nIndices, int const *a_indices, double a_energy, double a_temperature,
335 double (*a_rng)( void * ), void *a_rngState ) const {
336
337 std::vector<int> indices( a_nIndices );
338 for( int index = 0; index < a_nIndices; ++index ) indices[index] = a_indices[index];
339
340 return( getFinalState( indices, a_energy, a_temperature, a_rng, a_rngState ) );
341}
#define channelID
Definition G4GIDI.hh:36
#define LUPI_maybeUnused
double px
Definition G4GIDI.hh:44
double pz
Definition G4GIDI.hh:44
double kineticEnergy
Definition G4GIDI.hh:44
double py
Definition G4GIDI.hh:44
double sumChannelCrossSectionAtE(std::vector< int > const &a_indices, double a_energy, double a_temperature) const
G4GIDI_target(PoPI::Database const &a_pops, MCGIDI::DomainHash const &a_domainHash, GIDI::Protare const &a_GIDI_protare, MCGIDI::Protare *a_MCGIDI_protare)
channelID getChannelsID(int channelIndex) const
double getElasticFinalState(double a_energy, double a_temperature, double(*a_rng)(void *), void *a_rngState) const
int getNumberOfProductionChannels() const
double getFissionCrossSectionAtE(double a_energy, double a_temperature) const
double getTotalCrossSectionAtE(double a_energy, double a_temperature) const
std::vector< G4GIDI_Product > * getFinalState(std::vector< int > const &a_indices, double a_energy, double a_temperature, double(*a_rng)(void *), void *a_rngState) const
double getElasticCrossSectionAtE(double a_energy, double a_temperature) const
std::vector< G4GIDI_Product > * getCaptureFinalState(double a_energy, double a_temperature, double(*a_rng)(void *), void *a_rngState) const
std::vector< G4GIDI_Product > * getOthersFinalState(double a_energy, double a_temperature, double(*a_rng)(void *), void *a_rngState) const
double getOthersCrossSectionAtE(double a_energy, double a_temperature) const
int sampleChannelCrossSectionAtE(std::vector< int > const &a_indices, double a_energy, double a_temperature, double(*a_rng)(void *), void *a_rngState) const
int getNumberOfChannels() const
std::vector< G4GIDI_Product > * getFissionFinalState(double a_energy, double a_temperature, double(*a_rng)(void *), void *a_rngState) const
std::vector< channelID > * getProductionChannelIDs() const
std::vector< channelID > * getChannelIDs() const
double getCaptureCrossSectionAtE(double a_energy, double a_temperature) const
MCGIDI_VIRTUAL_FUNCTION LUPI_HOST_DEVICE Reaction const * reaction(std::size_t a_index) const MCGIDI_TRUE_VIRTUAL
LUPI_HOST_DEVICE void setTemperatureAndEnergy(double a_temperature, double a_energy)
LUPI_HOST_DEVICE void push_back(Product &a_product)
bool isAlias(void) const
Definition PoPI.hpp:658
virtual bool isParticle() const
Definition PoPI.hpp:657
T const & get(std::string const &a_id) const
int particleA(Base const &a_particle, bool a_isNeutronProtonANucleon=false)
Definition PoPI_misc.cc:227
int particleMetaStableIndex(Base const &a_particle)
Definition PoPI_misc.cc:349
int particleZ(Base const &a_particle, bool a_isNeutronProtonANucleon=false)
Definition PoPI_misc.cc:150