35#define INCLXX_IN_GEANT4_MODE 1
46 const G4double ClusteringModelIntercomparison::limitCosEscapeAngle = 0.7;
48 static G4bool cascadingFirstPredicate(Particle *aParticle) {
49 return !aParticle->isTargetSpectator();
55 runningMaxClusterAlgorithmMass = std::min(maxClusterAlgorithmMass, nucleus->
getA()/2);
58 if(runningMaxClusterAlgorithmMass<=1)
62 Particle *theLeadingParticle = particle;
81 const G4double arg = rmaxws*rmaxws - Rprime*Rprime;
86 const G4double cosmin = std::sqrt(arg)/rmaxws;
89 translat = rmaxws * cospr;
92 translat = rmaxws * (cospr - std::sqrt(cospr*cospr - cosmin*cosmin));
96 translat = rmaxws * cospr - std::sqrt(Rprime*Rprime - rmaxws*rmaxws*(1.0 - cospr*cospr));
100 const ThreeVector leadingParticlePosition = oldLeadingParticlePosition - theLeadingParticle->
getMomentum() * (translat/pk);
102 theLeadingParticle->
setPosition(leadingParticlePosition);
105 const G4int theNucleusA = theNucleus->
getA();
106 if(nConsideredMax < theNucleusA) {
107 delete [] consideredPartners;
108 delete [] isInRunningConfiguration;
109 nConsideredMax = 2*theNucleusA;
110 consideredPartners =
new Particle *[nConsideredMax];
111 isInRunningConfiguration =
new G4bool [nConsideredMax];
112 std::fill(isInRunningConfiguration,
113 isInRunningConfiguration + nConsideredMax,
119 cascadingEnergyPool = 0.;
122 for(
ParticleIter i = particles.begin(); i != particles.end(); ++i) {
123 if (!(*i)->isNucleon())
continue;
124 if ((*i)->getID() == theLeadingParticle->
getID())
continue;
126 G4double space = ((*i)->getPosition() - leadingParticlePosition).mag2();
127 G4double momentum = ((*i)->getMomentum() - leadingParticleMomentum).mag2();
133 consideredPartners[nConsidered] = *i;
136 if(!(*i)->isTargetSpectator())
137 cascadingEnergyPool += (*i)->getEnergy() - (*i)->getPotentialEnergy() - 931.3;
147 std::partition(consideredPartners, consideredPartners+nConsidered, cascadingFirstPredicate);
152 maxMassConfigurationSkipping = runningMaxClusterAlgorithmMass-2;
153 for(
G4int i=0; i<runningMaxClusterAlgorithmMass-2; ++i)
154 checkedConfigurations[i].clear();
158 runningPositions[1] = leadingParticlePosition;
159 runningMomenta[1] = leadingParticleMomentum;
160 runningEnergies[1] = theLeadingParticle->
getEnergy();
167 findClusterStartingFrom(1, theLeadingParticle->
getZ());
175 candidateConfiguration[selectedA-1] = theLeadingParticle;
176 chosenCluster =
new Cluster(candidateConfiguration,
177 candidateConfiguration + selectedA);
181 theLeadingParticle->
setPosition(oldLeadingParticlePosition);
183 return chosenCluster;
186 inline G4double ClusteringModelIntercomparison::getPhaseSpace(
const G4int oldA,
Particle const *
const p) {
192 void ClusteringModelIntercomparison::findClusterStartingFrom(
const G4int oldA,
const G4int oldZ) {
193 const G4int newA = oldA + 1;
194 const G4int oldAMinusOne = oldA - 1;
202 const G4bool cachingEnabled = (newA<=maxMassConfigurationSkipping && newA>=3);
205#if defined(INCL_CACHING_CLUSTERING_MODEL_INTERCOMPARISON_HashMask)
206 HashContainer *theHashContainer;
208 theHashContainer = &(checkedConfigurations[oldA-2]);
210 theHashContainer = NULL;
211#elif defined(INCL_CACHING_CLUSTERING_MODEL_INTERCOMPARISON_Set)
212 SortedNucleonConfigurationContainer *theConfigContainer;
214 theConfigContainer = &(checkedConfigurations[oldA-2]);
216 theConfigContainer = NULL;
218#error Unrecognized INCL_CACHING_CLUSTERING_MODEL_INTERCOMPARISON. Allowed values are: Set, HashMask.
225 for(
G4int i=0; i<nConsidered; ++i) {
227 if(isInRunningConfiguration[i])
continue;
229 Particle *
const candidateNucleon = consideredPartners[i];
232 newZ = oldZ + candidateNucleon->
getZ();
236 if(newZ > clusterZMaxAll || newN > clusterNMaxAll)
242 const G4double phaseSpace = getPhaseSpace(oldA, candidateNucleon);
243 if(phaseSpace > phaseSpaceCut)
continue;
246 runningConfiguration[oldAMinusOne] = i;
247#if defined(INCL_CACHING_CLUSTERING_MODEL_INTERCOMPARISON_HashMask)
248 Hashing::HashType configHash;
249 HashIterator aHashIter;
250#elif defined(INCL_CACHING_CLUSTERING_MODEL_INTERCOMPARISON_Set)
251 SortedNucleonConfiguration thisConfig;
252 SortedNucleonConfigurationIterator thisConfigIter;
255#if defined(INCL_CACHING_CLUSTERING_MODEL_INTERCOMPARISON_HashMask)
256 configHash = Hashing::hashConfig(runningConfiguration, oldA);
257 aHashIter = theHashContainer->lower_bound(configHash);
259 if(aHashIter!=theHashContainer->end()
260 && !(configHash < *aHashIter))
262#elif defined(INCL_CACHING_CLUSTERING_MODEL_INTERCOMPARISON_Set)
263 thisConfig.fill(runningConfiguration,oldA);
264 thisConfigIter = theConfigContainer->lower_bound(thisConfig);
266 if(thisConfigIter!=theConfigContainer->end()
267 && !(thisConfig < *thisConfigIter))
273 runningEnergies[newA] = runningEnergies[oldA] + candidateNucleon->getEnergy();
275 runningPotentials[newA] = runningPotentials[oldA] + candidateNucleon->getPotentialEnergy();
278 G4double oldCascadingEnergyPool = cascadingEnergyPool;
279 if(!candidateNucleon->isTargetSpectator())
280 cascadingEnergyPool -= candidateNucleon->getEnergy() - candidateNucleon->getPotentialEnergy() - 931.3;
285 const G4double halfB = 0.72 * newZ *
287 const G4double tout = runningEnergies[newA] - runningPotentials[newA] -
289 if(tout<=halfB && tout+cascadingEnergyPool<=halfB) {
290 cascadingEnergyPool = oldCascadingEnergyPool;
296 runningMomenta[newA] = runningMomenta[oldA] + candidateNucleon->getMomentum();
300#if defined(INCL_CACHING_CLUSTERING_MODEL_INTERCOMPARISON_HashMask)
301 theHashContainer->insert(aHashIter, configHash);
302#elif defined(INCL_CACHING_CLUSTERING_MODEL_INTERCOMPARISON_Set)
303 theConfigContainer->insert(thisConfigIter, thisConfig);
308 isInRunningConfiguration[i] =
true;
311 if(newZ >= ZMinForNewA && newZ <= ZMaxForNewA) {
314 runningMomenta[newA]);
315 const G4double sqct = (sqc - 2.*newZ*protonMass - 2.*(newA-newZ)*neutronMass
327 for(
G4int j=0; j<oldA; ++j)
328 candidateConfiguration[j] = consideredPartners[runningConfiguration[j]];
336 if(newA < runningMaxClusterAlgorithmMass && newA+1 < theNucleus->
getA()) {
337 findClusterStartingFrom(newA, newZ);
341 isInRunningConfiguration[i] =
false;
342 cascadingEnergyPool = oldCascadingEnergyPool;
348 if(c->
getA()>=n->getA())
355 if(cosEscapeAngle < limitCosEscapeAngle)
Functions for hashing a collection of NucleonItems.
virtual G4bool clusterCanEscape(Nucleus const *const, Cluster const *const)
virtual Cluster * getCluster(Nucleus *, Particle *)
G4int getClusterMaxMass() const
Get the maximum mass for production of clusters.
static G4double invariantMass(const G4double E, const ThreeVector &p)
G4double getNuclearRadius()
NuclearDensity * getDensity() const
Getter for theDensity.
G4double getUniverseRadius() const
Getter for theUniverseRadius.
static const G4double clusterPosFact2[maxClusterMass+1]
static const G4int clusterZMin[maxClusterMass+1]
static const G4double clusterPosFact[maxClusterMass+1]
static G4double getRealMass(const G4INCL::ParticleType t)
Get particle mass (in MeV/c^2)
static const G4double clusterPhaseSpaceCut[maxClusterMass+1]
static const G4int clusterZMax[maxClusterMass+1]
G4double getEnergy() const
G4double getPotentialEnergy() const
Get the particle potential energy.
G4int getZ() const
Returns the charge number.
const G4INCL::ThreeVector & getPosition() const
const G4INCL::ThreeVector & getMomentum() const
virtual void setPosition(const G4INCL::ThreeVector &position)
G4int getA() const
Returns the baryon number.
ParticleList const & getParticles() const
Config const * getConfig()
G4double dot(const ThreeVector &v) const
std::list< G4INCL::Particle * > ParticleList
std::list< G4INCL::Particle * >::const_iterator ParticleIter