Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer 3 // * License and Disclaimer * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/ 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. 9 // * include a list of copyright holders. * 10 // * 10 // * * 11 // * Neither the authors of this software syst 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitatio 16 // * for the full disclaimer and the limitation of liability. * 17 // * 17 // * * 18 // * This code implementation is the result 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboratio 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distri 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you ag 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publicati 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Sof 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************* 24 // ******************************************************************** 25 // 25 // 26 // INCL++ intra-nuclear cascade model 26 // INCL++ intra-nuclear cascade model 27 // Alain Boudard, CEA-Saclay, France << 27 // Pekka Kaitaniemi, CEA and Helsinki Institute of Physics 28 // Joseph Cugnon, University of Liege, Belgium << 28 // Davide Mancusi, CEA 29 // Jean-Christophe David, CEA-Saclay, France << 29 // Alain Boudard, CEA 30 // Pekka Kaitaniemi, CEA-Saclay, France, and H << 30 // Sylvie Leray, CEA 31 // Sylvie Leray, CEA-Saclay, France << 31 // Joseph Cugnon, University of Liege 32 // Davide Mancusi, CEA-Saclay, France << 33 // 32 // 34 #define INCLXX_IN_GEANT4_MODE 1 33 #define INCLXX_IN_GEANT4_MODE 1 35 34 36 #include "globals.hh" 35 #include "globals.hh" 37 36 38 #ifndef G4INCLClusteringModelIntercomparison_h 37 #ifndef G4INCLClusteringModelIntercomparison_hh 39 #define G4INCLClusteringModelIntercomparison_h 38 #define G4INCLClusteringModelIntercomparison_hh 1 40 39 41 #ifdef INCLXX_IN_GEANT4_MODE 40 #ifdef INCLXX_IN_GEANT4_MODE 42 #define INCL_CACHING_CLUSTERING_MODEL_INTERCOM 41 #define INCL_CACHING_CLUSTERING_MODEL_INTERCOMPARISON_Set 1 43 #endif // INCLXX_IN_GEANT4_MODE 42 #endif // INCLXX_IN_GEANT4_MODE 44 43 45 #include "G4INCLIClusteringModel.hh" 44 #include "G4INCLIClusteringModel.hh" 46 #include "G4INCLParticle.hh" 45 #include "G4INCLParticle.hh" 47 #include "G4INCLParticleTable.hh" 46 #include "G4INCLParticleTable.hh" 48 #include "G4INCLCluster.hh" 47 #include "G4INCLCluster.hh" 49 #include "G4INCLNucleus.hh" 48 #include "G4INCLNucleus.hh" 50 #include "G4INCLKinematicsUtils.hh" 49 #include "G4INCLKinematicsUtils.hh" 51 #include "G4INCLHashing.hh" 50 #include "G4INCLHashing.hh" 52 51 53 #include <set> 52 #include <set> 54 #include <algorithm> 53 #include <algorithm> 55 54 56 namespace G4INCL { 55 namespace G4INCL { 57 56 58 /** \brief Container for the relevant inform 57 /** \brief Container for the relevant information 59 * 58 * 60 * This struct contains all the information 59 * This struct contains all the information that is relevant for the 61 * clustering algorithm. It is probably more 60 * clustering algorithm. It is probably more compact than the Particles it 62 * feeds on, hopefully improving cache perfo 61 * feeds on, hopefully improving cache performance. 63 */ 62 */ 64 struct ConsideredPartner { 63 struct ConsideredPartner { 65 Particle *particle; 64 Particle *particle; 66 G4bool isTargetSpectator; 65 G4bool isTargetSpectator; 67 G4int Z; 66 G4int Z; 68 G4int S; << 69 ThreeVector position; 67 ThreeVector position; 70 ThreeVector momentum; 68 ThreeVector momentum; 71 G4double energy; 69 G4double energy; 72 G4double potentialEnergy; 70 G4double potentialEnergy; 73 71 74 ConsideredPartner() : 72 ConsideredPartner() : 75 particle(NULL), 73 particle(NULL), 76 isTargetSpectator(false), 74 isTargetSpectator(false), 77 Z(0), 75 Z(0), 78 S(0), << 79 energy(0.), 76 energy(0.), 80 potentialEnergy(0.) 77 potentialEnergy(0.) 81 {} 78 {} 82 79 83 ConsideredPartner(Particle * const p) : 80 ConsideredPartner(Particle * const p) : 84 particle(p), 81 particle(p), 85 isTargetSpectator(particle->isTargetSpec 82 isTargetSpectator(particle->isTargetSpectator()), 86 Z(particle->getZ()), 83 Z(particle->getZ()), 87 S(particle->getS()), << 88 position(particle->getPosition()), 84 position(particle->getPosition()), 89 momentum(particle->getMomentum()), 85 momentum(particle->getMomentum()), 90 energy(particle->getEnergy()), 86 energy(particle->getEnergy()), 91 potentialEnergy(particle->getPotentialEn 87 potentialEnergy(particle->getPotentialEnergy()) 92 {} 88 {} 93 }; 89 }; 94 90 95 /// \brief Cluster coalescence algorithm use 91 /// \brief Cluster coalescence algorithm used in the IAEA intercomparison 96 class ClusteringModelIntercomparison : publi 92 class ClusteringModelIntercomparison : public IClusteringModel { 97 public: 93 public: 98 ClusteringModelIntercomparison(Config cons 94 ClusteringModelIntercomparison(Config const * const theConfig) : 99 theNucleus(NULL), 95 theNucleus(NULL), 100 selectedA(0), 96 selectedA(0), 101 selectedZ(0), 97 selectedZ(0), 102 selectedS(0), << 103 sqtot(0.), 98 sqtot(0.), 104 cascadingEnergyPool(0.), 99 cascadingEnergyPool(0.), 105 protonMass(ParticleTable::getRealMass(Pr 100 protonMass(ParticleTable::getRealMass(Proton)), 106 neutronMass(ParticleTable::getRealMass(N 101 neutronMass(ParticleTable::getRealMass(Neutron)), 107 lambdaMass(ParticleTable::getRealMass(La << 108 runningMaxClusterAlgorithmMass(theConfig 102 runningMaxClusterAlgorithmMass(theConfig->getClusterMaxMass()), 109 nConsideredMax(0), 103 nConsideredMax(0), 110 nConsidered(0), 104 nConsidered(0), 111 consideredPartners(NULL), 105 consideredPartners(NULL), 112 isInRunningConfiguration(NULL), 106 isInRunningConfiguration(NULL), 113 maxMassConfigurationSkipping(ParticleTab 107 maxMassConfigurationSkipping(ParticleTable::maxClusterMass) 114 { 108 { 115 // Set up the maximum charge and neutron 109 // Set up the maximum charge and neutron number for clusters 116 clusterZMaxAll = 0; 110 clusterZMaxAll = 0; 117 clusterNMaxAll = 0; 111 clusterNMaxAll = 0; 118 for(G4int A=0; A<=runningMaxClusterAlgor 112 for(G4int A=0; A<=runningMaxClusterAlgorithmMass; ++A) { 119 if(clusterZMax[A]>clusterZMaxAll) 113 if(clusterZMax[A]>clusterZMaxAll) 120 clusterZMaxAll = clusterZMax[A]; 114 clusterZMaxAll = clusterZMax[A]; 121 if(A-clusterZMin[A]>clusterNMaxAll) 115 if(A-clusterZMin[A]>clusterNMaxAll) 122 clusterNMaxAll = A-clusterZMin[A]; 116 clusterNMaxAll = A-clusterZMin[A]; 123 } 117 } 124 std::fill(candidateConfiguration, 118 std::fill(candidateConfiguration, 125 candidateConfiguration + Parti 119 candidateConfiguration + ParticleTable::maxClusterMass, 126 static_cast<Particle*>(NULL)); 120 static_cast<Particle*>(NULL)); 127 121 128 std::fill(runningEnergies, 122 std::fill(runningEnergies, 129 runningEnergies + ParticleTabl 123 runningEnergies + ParticleTable::maxClusterMass, 130 0.0); 124 0.0); 131 125 132 std::fill(runningPotentials, 126 std::fill(runningPotentials, 133 runningPotentials + ParticleTa 127 runningPotentials + ParticleTable::maxClusterMass, 134 0.0); 128 0.0); 135 129 136 std::fill(runningConfiguration, 130 std::fill(runningConfiguration, 137 runningConfiguration + Particl 131 runningConfiguration + ParticleTable::maxClusterMass, 138 -1); 132 -1); 139 133 140 } 134 } 141 135 142 virtual ~ClusteringModelIntercomparison() 136 virtual ~ClusteringModelIntercomparison() { 143 delete [] consideredPartners; 137 delete [] consideredPartners; 144 delete [] isInRunningConfiguration; 138 delete [] isInRunningConfiguration; 145 } 139 } 146 140 147 virtual Cluster* getCluster(Nucleus*, Part 141 virtual Cluster* getCluster(Nucleus*, Particle*); 148 virtual G4bool clusterCanEscape(Nucleus co 142 virtual G4bool clusterCanEscape(Nucleus const * const, Cluster const * const); 149 143 150 private: 144 private: 151 void findClusterStartingFrom(const G4int o << 145 void findClusterStartingFrom(const G4int oldA, const G4int oldZ); 152 G4double getPhaseSpace(const G4int oldA, C 146 G4double getPhaseSpace(const G4int oldA, ConsideredPartner const &p); 153 147 154 Nucleus *theNucleus; 148 Nucleus *theNucleus; 155 149 156 G4double runningEnergies[ParticleTable::ma 150 G4double runningEnergies[ParticleTable::maxClusterMass+1]; 157 ThreeVector runningMomenta[ParticleTable:: 151 ThreeVector runningMomenta[ParticleTable::maxClusterMass+1]; 158 ThreeVector runningPositions[ParticleTable 152 ThreeVector runningPositions[ParticleTable::maxClusterMass+1]; 159 G4double runningPotentials[ParticleTable:: 153 G4double runningPotentials[ParticleTable::maxClusterMass+1]; 160 #if defined(INCL_CACHING_CLUSTERING_MODEL_INTE 154 #if defined(INCL_CACHING_CLUSTERING_MODEL_INTERCOMPARISON_HashMask) 161 Hashing::NucleonItem runningConfiguration[ 155 Hashing::NucleonItem runningConfiguration[ParticleTable::maxClusterMass]; 162 #elif defined(INCL_CACHING_CLUSTERING_MODEL_IN << 156 #elif defined(INCL_CACHING_CLUSTERING_MODEL_INTERCOMPARISON_Set) 163 G4int runningConfiguration[ParticleTable:: 157 G4int runningConfiguration[ParticleTable::maxClusterMass]; 164 #else 158 #else 165 #error Unrecognized INCL_CACHING_CLUSTERING_MO << 159 #error Unrecognized INCL_CACHING_CLUSTERING_MODEL_INTERCOMPARISON. Allowed values are: Set, HashMask. 166 #endif 160 #endif 167 161 168 G4int selectedA, selectedZ, selectedS; << 162 G4int selectedA, selectedZ; 169 G4double sqtot; 163 G4double sqtot; 170 164 171 G4int clusterZMaxAll, clusterNMaxAll; 165 G4int clusterZMaxAll, clusterNMaxAll; 172 166 173 G4double cascadingEnergyPool; 167 G4double cascadingEnergyPool; 174 168 175 /// \brief Lower limit of Z for cluster of 169 /// \brief Lower limit of Z for cluster of mass A 176 static const G4int clusterZMin[ParticleTab 170 static const G4int clusterZMin[ParticleTable::maxClusterMass+1]; 177 /// \brief Upper limit of Z for cluster of 171 /// \brief Upper limit of Z for cluster of mass A 178 static const G4int clusterZMax[ParticleTab 172 static const G4int clusterZMax[ParticleTable::maxClusterMass+1]; 179 173 180 /// \brief Precomputed factor 1.0/A 174 /// \brief Precomputed factor 1.0/A 181 static const G4double clusterPosFact[Parti 175 static const G4double clusterPosFact[ParticleTable::maxClusterMass+1]; 182 176 183 /// \brief Precomputed factor (1.0/A)^2 177 /// \brief Precomputed factor (1.0/A)^2 184 static const G4double clusterPosFact2[Part 178 static const G4double clusterPosFact2[ParticleTable::maxClusterMass+1]; 185 179 186 /// \brief Phase-space parameters for clus 180 /// \brief Phase-space parameters for cluster formation 187 static const G4double clusterPhaseSpaceCut 181 static const G4double clusterPhaseSpaceCut[ParticleTable::maxClusterMass+1]; 188 182 189 static const G4double limitCosEscapeAngle; 183 static const G4double limitCosEscapeAngle; 190 184 191 const G4double protonMass; 185 const G4double protonMass; 192 const G4double neutronMass; 186 const G4double neutronMass; 193 const G4double lambdaMass; << 194 187 195 G4int runningMaxClusterAlgorithmMass; 188 G4int runningMaxClusterAlgorithmMass; 196 189 197 G4int nConsideredMax; 190 G4int nConsideredMax; 198 G4int nConsidered; 191 G4int nConsidered; 199 192 200 /** \brief Array of considered cluster par 193 /** \brief Array of considered cluster partners 201 * 194 * 202 * A dynamical array of ConsideredPartner 195 * A dynamical array of ConsideredPartner objects is allocated on this 203 * variable and filled with pointers to nu 196 * variable and filled with pointers to nucleons which are eligible for 204 * clustering. We used to use a ParticleLi 197 * clustering. We used to use a ParticleList for this purpose, but this 205 * made it very cumbersome to check whethe 198 * made it very cumbersome to check whether nucleons had already been 206 * included in the running configuration. 199 * included in the running configuration. Using an array of Particle* 207 * coupled with a boolean mask (\see{isInR 200 * coupled with a boolean mask (\see{isInRunningConfiguration}) reduces the 208 * overhead by a large amount. Running ti 201 * overhead by a large amount. Running times for 1-GeV p+Pb208 went down 209 * by almost 30% (!). 202 * by almost 30% (!). 210 * 203 * 211 * Lesson learnt: when you need speed, not 204 * Lesson learnt: when you need speed, nothing beats a good ol' array. 212 */ 205 */ 213 ConsideredPartner *consideredPartners; 206 ConsideredPartner *consideredPartners; 214 207 215 /** \brief Array of flags for nucleons in 208 /** \brief Array of flags for nucleons in the running configuration 216 * 209 * 217 * Clustering partners that are already us 210 * Clustering partners that are already used in the running cluster 218 * configuration are flagged as "true" in 211 * configuration are flagged as "true" in this array. 219 */ 212 */ 220 G4bool *isInRunningConfiguration; 213 G4bool *isInRunningConfiguration; 221 214 222 /** \brief Best cluster configuration 215 /** \brief Best cluster configuration 223 * 216 * 224 * This array contains pointers to the nuc 217 * This array contains pointers to the nucleons which make up the best 225 * cluster configuration that has been fou 218 * cluster configuration that has been found so far. 226 */ 219 */ 227 Particle *candidateConfiguration[ParticleT 220 Particle *candidateConfiguration[ParticleTable::maxClusterMass]; 228 221 229 #if defined(INCL_CACHING_CLUSTERING_MODEL_INTE 222 #if defined(INCL_CACHING_CLUSTERING_MODEL_INTERCOMPARISON_HashMask) 230 typedef std::set<Hashing::HashType> HashCo 223 typedef std::set<Hashing::HashType> HashContainer; 231 typedef HashContainer::iterator HashIterat 224 typedef HashContainer::iterator HashIterator; 232 225 233 /// \brief Array of containers for configu 226 /// \brief Array of containers for configurations that have already been checked 234 HashContainer checkedConfigurations[Partic 227 HashContainer checkedConfigurations[ParticleTable::maxClusterMass-2]; 235 #elif defined(INCL_CACHING_CLUSTERING_MODEL_IN 228 #elif defined(INCL_CACHING_CLUSTERING_MODEL_INTERCOMPARISON_Set) 236 /** \brief Class for storing and comparing 229 /** \brief Class for storing and comparing sorted nucleon configurations 237 * 230 * 238 * This class is actually just a wrapper a 231 * This class is actually just a wrapper around an array of Particle* 239 * pointers. It provides a lexicographical 232 * pointers. It provides a lexicographical comparison operator 240 * (SortedNucleonConfiguration::operator<) 233 * (SortedNucleonConfiguration::operator<) for inclusion in std::set 241 * containers. 234 * containers. 242 */ 235 */ 243 class SortedNucleonConfiguration { 236 class SortedNucleonConfiguration { 244 public: 237 public: 245 // Use Particle* as nucleon identifier 238 // Use Particle* as nucleon identifiers 246 typedef G4int NucleonItem; 239 typedef G4int NucleonItem; 247 240 248 /// \brief Constructor 241 /// \brief Constructor 249 SortedNucleonConfiguration() : theSize 242 SortedNucleonConfiguration() : theSize(0), nucleons(NULL) {} 250 243 251 /// \brief Copy constructor 244 /// \brief Copy constructor 252 SortedNucleonConfiguration(const Sorte 245 SortedNucleonConfiguration(const SortedNucleonConfiguration &rhs) : 253 theSize(rhs.theSize), 246 theSize(rhs.theSize), 254 nucleons(new NucleonItem[theSize]) 247 nucleons(new NucleonItem[theSize]) 255 { 248 { 256 std::copy(rhs.nucleons, rhs.nucleons+t 249 std::copy(rhs.nucleons, rhs.nucleons+theSize, nucleons); 257 } 250 } 258 251 259 /// \brief Destructor 252 /// \brief Destructor 260 ~SortedNucleonConfiguration() { 253 ~SortedNucleonConfiguration() { 261 delete [] nucleons; 254 delete [] nucleons; 262 } 255 } 263 256 264 /// \brief Helper method for the assig 257 /// \brief Helper method for the assignment operator 265 void swap(SortedNucleonConfiguration & 258 void swap(SortedNucleonConfiguration &rhs) { 266 std::swap(theSize, rhs.theSize); 259 std::swap(theSize, rhs.theSize); 267 std::swap(nucleons, rhs.nucleons); 260 std::swap(nucleons, rhs.nucleons); 268 } 261 } 269 262 270 /// \brief Assignment operator 263 /// \brief Assignment operator 271 SortedNucleonConfiguration &operator=( 264 SortedNucleonConfiguration &operator=(const SortedNucleonConfiguration &rhs) { 272 SortedNucleonConfiguration tempConfi 265 SortedNucleonConfiguration tempConfig(rhs); 273 swap(tempConfig); 266 swap(tempConfig); 274 return *this; 267 return *this; 275 } 268 } 276 269 277 /** \brief Order operator for SortedNu 270 /** \brief Order operator for SortedNucleonConfiguration 278 * 271 * 279 * The comparison is done lexicographi 272 * The comparison is done lexicographically (i.e. from the first 280 * element to the last). 273 * element to the last). 281 */ 274 */ 282 G4bool operator<(const SortedNucleonCo 275 G4bool operator<(const SortedNucleonConfiguration &rhs) const { 283 // assert(theSize==rhs.theSize); 276 // assert(theSize==rhs.theSize); 284 return std::lexicographical_compare( 277 return std::lexicographical_compare(nucleons, nucleons+theSize, rhs.nucleons, rhs.nucleons+theSize); 285 } 278 } 286 279 287 /// \brief Fill configuration with arr 280 /// \brief Fill configuration with array of NucleonItem 288 void fill(NucleonItem *config, size_t 281 void fill(NucleonItem *config, size_t n) { 289 theSize = n; 282 theSize = n; 290 nucleons = new NucleonItem[theSize]; 283 nucleons = new NucleonItem[theSize]; 291 std::copy(config, config+theSize, nu 284 std::copy(config, config+theSize, nucleons); 292 std::sort(nucleons, nucleons+theSize 285 std::sort(nucleons, nucleons+theSize); 293 } 286 } 294 287 295 private: 288 private: 296 /// \brief Size of the array 289 /// \brief Size of the array 297 size_t theSize; 290 size_t theSize; 298 291 299 /// \brief The real array 292 /// \brief The real array 300 NucleonItem *nucleons; 293 NucleonItem *nucleons; 301 }; 294 }; 302 295 303 typedef std::set<SortedNucleonConfiguratio 296 typedef std::set<SortedNucleonConfiguration> SortedNucleonConfigurationContainer; 304 typedef SortedNucleonConfigurationContaine 297 typedef SortedNucleonConfigurationContainer::iterator SortedNucleonConfigurationIterator; 305 298 306 /// \brief Array of containers for configu 299 /// \brief Array of containers for configurations that have already been checked 307 SortedNucleonConfigurationContainer checke 300 SortedNucleonConfigurationContainer checkedConfigurations[ParticleTable::maxClusterMass-2]; 308 #elif !defined(INCL_CACHING_CLUSTERING_MODEL_I << 301 #else 309 #error Unrecognized INCL_CACHING_CLUSTERING_MO << 302 #error Unrecognized INCL_CACHING_CLUSTERING_MODEL_INTERCOMPARISON. Allowed values are: Set, HashMask. 310 #endif 303 #endif 311 304 312 /** \brief Maximum mass for configuration 305 /** \brief Maximum mass for configuration storage 313 * 306 * 314 * Skipping configurations becomes ineffic 307 * Skipping configurations becomes inefficient above this mass. 315 */ 308 */ 316 G4int maxMassConfigurationSkipping; 309 G4int maxMassConfigurationSkipping; 317 }; 310 }; 318 311 319 } 312 } 320 313 321 #endif 314 #endif 322 315