34#define INCLXX_IN_GEANT4_MODE 1
46 const G4int ClusteringModelIntercomparison::clusterZMin[
ParticleTable::maxClusterMass+1] = {0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3};
47 const G4int ClusteringModelIntercomparison::clusterZMax[
ParticleTable::maxClusterMass+1] = {0, 0, 1, 2, 3, 3, 5, 5, 6, 6, 7, 7, 8};
61 0.0082645, 0.0069444};
70 const G4double ClusteringModelIntercomparison::limitCosEscapeAngle = 0.7;
72#ifdef INCL_DO_NOT_COMPILE
74 G4bool cascadingFirstPredicate(ConsideredPartner
const &aPartner) {
75 return !aPartner.isTargetSpectator;
82 const G4int maxClusterAlgorithmMass = nucleus->getStore()->getConfig()->getClusterMaxMass();
83 runningMaxClusterAlgorithmMass = std::min(maxClusterAlgorithmMass, nucleus->getA()/2);
86 if(runningMaxClusterAlgorithmMass<=1)
90 Particle *theLeadingParticle = particle;
101 const G4double rmaxws = theNucleus->getUniverseRadius();
104 const G4double Rprime = theNucleus->getDensity()->getProtonNuclearRadius() + transp;
109 const G4double arg = rmaxws*rmaxws - Rprime*Rprime;
114 const G4double cosmin = std::sqrt(arg)/rmaxws;
115 if(cospr <= cosmin) {
117 translat = rmaxws * cospr;
120 translat = rmaxws * (cospr - std::sqrt(cospr*cospr - cosmin*cosmin));
124 translat = rmaxws * cospr - std::sqrt(Rprime*Rprime - rmaxws*rmaxws*(1.0 - cospr*cospr));
128 const ThreeVector leadingParticlePosition = oldLeadingParticlePosition - theLeadingParticle->
getMomentum() * (translat/pk);
130 theLeadingParticle->
setPosition(leadingParticlePosition);
133 const G4int theNucleusA = theNucleus->getA();
134 if(nConsideredMax < theNucleusA) {
135 delete [] consideredPartners;
136 delete [] isInRunningConfiguration;
137 nConsideredMax = 2*theNucleusA;
139 isInRunningConfiguration =
new G4bool [nConsideredMax];
140 std::fill(isInRunningConfiguration,
141 isInRunningConfiguration + nConsideredMax,
147 cascadingEnergyPool = 0.;
149 ParticleList const &particles = theNucleus->getStore()->getParticles();
150 for(
ParticleIter i=particles.begin(), e=particles.end(); i!=e; ++i) {
151 if (!(*i)->isNucleonorLambda())
continue;
152 if ((*i)->getID() == theLeadingParticle->
getID())
continue;
154 G4double space = ((*i)->getPosition() - leadingParticlePosition).mag2();
155 G4double momentum = ((*i)->getMomentum() - leadingParticleMomentum).mag2();
156 G4double size = space*momentum*clusterPosFact2[runningMaxClusterAlgorithmMass];
160 if(size < clusterPhaseSpaceCut[runningMaxClusterAlgorithmMass]) {
161 consideredPartners[nConsidered] = *i;
164 if(!(*i)->isTargetSpectator())
165 cascadingEnergyPool += consideredPartners[nConsidered].energy - consideredPartners[nConsidered].potentialEnergy - 931.3;
177#ifndef INCL_CACHING_CLUSTERING_MODEL_INTERCOMPARISON_None
181 maxMassConfigurationSkipping = runningMaxClusterAlgorithmMass-2;
182 for(
G4int i=0; i<runningMaxClusterAlgorithmMass-2; ++i)
183 checkedConfigurations[i].clear();
188 runningPositions[1] = leadingParticlePosition;
189 runningMomenta[1] = leadingParticleMomentum;
190 runningEnergies[1] = theLeadingParticle->
getEnergy();
197 findClusterStartingFrom(1, theLeadingParticle->
getZ(), 0);
205 candidateConfiguration[selectedA-1] = theLeadingParticle;
206 chosenCluster =
new Cluster(candidateConfiguration,
207 candidateConfiguration + selectedA);
211 theLeadingParticle->
setPosition(oldLeadingParticlePosition);
213 return chosenCluster;
218 const G4double psMomentum = (p.
momentum*oldA - runningMomenta[oldA]).mag2();
219 return psSpace * psMomentum * clusterPosFact2[oldA + 1];
222 void ClusteringModelIntercomparison::findClusterStartingFrom(
const G4int oldA,
const G4int oldZ,
const G4int oldS) {
223 const G4int newA = oldA + 1;
224 const G4int oldAMinusOne = oldA - 1;
230 const G4double phaseSpaceCut = clusterPhaseSpaceCut[newA];
233 const G4bool cachingEnabled = (newA<=maxMassConfigurationSkipping && newA>=3);
236#if defined(INCL_CACHING_CLUSTERING_MODEL_INTERCOMPARISON_HashMask)
237 HashContainer *theHashContainer;
239 theHashContainer = &(checkedConfigurations[oldA-2]);
241 theHashContainer = NULL;
242#elif defined(INCL_CACHING_CLUSTERING_MODEL_INTERCOMPARISON_Set)
243 SortedNucleonConfigurationContainer *theConfigContainer;
245 theConfigContainer = &(checkedConfigurations[oldA-2]);
247 theConfigContainer = NULL;
248#elif !defined(INCL_CACHING_CLUSTERING_MODEL_INTERCOMPARISON_None)
249#error Unrecognized INCL_CACHING_CLUSTERING_MODEL_INTERCOMPARISON. Allowed values are: Set, HashMask, None.
253 const G4int ZMinForNewA = clusterZMin[newA];
254 const G4int ZMaxForNewA = clusterZMax[newA];
256 for(
G4int i=0; i<nConsidered; ++i) {
258 if(isInRunningConfiguration[i])
continue;
260 ConsideredPartner
const &candidateNucleon = consideredPartners[i];
263 newZ = oldZ + candidateNucleon.
Z;
264 newS = oldS + candidateNucleon.S;
268 if(newZ > clusterZMaxAll || newN > clusterNMaxAll || newS>0)
274 const G4double phaseSpace = getPhaseSpace(oldA, candidateNucleon);
275 if(phaseSpace > phaseSpaceCut)
continue;
278 runningConfiguration[oldAMinusOne] = i;
279#if defined(INCL_CACHING_CLUSTERING_MODEL_INTERCOMPARISON_HashMask)
280 Hashing::HashType configHash;
281 HashIterator aHashIter;
282#elif defined(INCL_CACHING_CLUSTERING_MODEL_INTERCOMPARISON_Set)
283 SortedNucleonConfiguration thisConfig;
284 SortedNucleonConfigurationIterator thisConfigIter;
287#if defined(INCL_CACHING_CLUSTERING_MODEL_INTERCOMPARISON_HashMask)
288 configHash = Hashing::hashConfig(runningConfiguration, oldA);
289 aHashIter = theHashContainer->lower_bound(configHash);
291 if(aHashIter!=theHashContainer->end()
292 && !(configHash < *aHashIter))
294#elif defined(INCL_CACHING_CLUSTERING_MODEL_INTERCOMPARISON_Set)
295 thisConfig.fill(runningConfiguration,oldA);
296 thisConfigIter = theConfigContainer->lower_bound(thisConfig);
298 if(thisConfigIter!=theConfigContainer->end()
299 && !(thisConfig < *thisConfigIter))
305 runningEnergies[newA] = runningEnergies[oldA] + candidateNucleon.energy;
307 runningPotentials[newA] = runningPotentials[oldA] + candidateNucleon.potentialEnergy;
310 G4double oldCascadingEnergyPool = cascadingEnergyPool;
311 if(!candidateNucleon.isTargetSpectator)
312 cascadingEnergyPool -= candidateNucleon.energy - candidateNucleon.potentialEnergy - 931.3;
317 const G4double halfB = 0.72 * newZ *
318 theNucleus->getZ()/(theNucleus->getDensity()->getProtonNuclearRadius()+1.7);
319 const G4double tout = runningEnergies[newA] - runningPotentials[newA] -
321 if(tout<=halfB && tout+cascadingEnergyPool<=halfB) {
322 cascadingEnergyPool = oldCascadingEnergyPool;
327 runningPositions[newA] = (runningPositions[oldA] * oldA + candidateNucleon.position)*clusterPosFact[newA];
328 runningMomenta[newA] = runningMomenta[oldA] + candidateNucleon.momentum;
332#if defined(INCL_CACHING_CLUSTERING_MODEL_INTERCOMPARISON_HashMask)
333 theHashContainer->insert(aHashIter, configHash);
334#elif defined(INCL_CACHING_CLUSTERING_MODEL_INTERCOMPARISON_Set)
335 theConfigContainer->insert(thisConfigIter, thisConfig);
341 isInRunningConfiguration[i] =
true;
344 if(newZ >= ZMinForNewA && newZ <= ZMaxForNewA) {
347 runningMomenta[newA]);
348 const G4double sqct = (sqc - 2.*newZ*protonMass - 2.*(newA+newS-newZ)*neutronMass + 2.*newS*lambdaMass
350 *clusterPosFact[newA];
361 for(
G4int j=0; j<oldA; ++j)
362 candidateConfiguration[j] = consideredPartners[runningConfiguration[j]].particle;
370 if(newA < runningMaxClusterAlgorithmMass && newA+1 < theNucleus->getA() && newS<=0) {
371 findClusterStartingFrom(newA, newZ, newS);
375 isInRunningConfiguration[i] =
false;
376 cascadingEnergyPool = oldCascadingEnergyPool;
382 if(c->
getA()>=n->getA() || c->
getS()>0)
388 const G4double cosEscapeAngle = pos.dot(mom) / std::sqrt(pos.mag2()*mom.
mag2());
389 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 getS() const
Returns the strangeness number.
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.
G4double dot(const ThreeVector &v) const
G4double invariantMass(const G4double E, const ThreeVector &p)
G4double getRealMass(const G4INCL::ParticleType t)
Get particle mass (in MeV/c^2).
const G4int maxClusterMass
ParticleList::const_iterator ParticleIter
Container for the relevant information.