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