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;
83 runningMaxClusterAlgorithmMass = std::min(maxClusterAlgorithmMass, nucleus->
getA()/2);
86 if(runningMaxClusterAlgorithmMass<=1)
90 Particle *theLeadingParticle = particle;
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.;
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 *
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 getClusterMaxMass() const
Get the maximum mass for production of clusters.
G4double getProtonNuclearRadius() const
NuclearDensity const * getDensity() const
Getter for theDensity.
G4double getUniverseRadius() const
Getter for theUniverseRadius.
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.
ParticleList const & getParticles() const
Config const * getConfig()
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.