#include <G4INCLClusteringModelIntercomparison.hh>
Inheritance diagram for G4INCL::ClusteringModelIntercomparison:
Public Member Functions | |
ClusteringModelIntercomparison (Config const *const theConfig) | |
virtual | ~ClusteringModelIntercomparison () |
virtual Cluster * | getCluster (Nucleus *, Particle *) |
virtual G4bool | clusterCanEscape (Nucleus const *const, Cluster const *const) |
Data Structures | |
class | SortedNucleonConfiguration |
Class for storing and comparing sorted nucleon configurations. |
Definition at line 58 of file G4INCLClusteringModelIntercomparison.hh.
G4INCL::ClusteringModelIntercomparison::ClusteringModelIntercomparison | ( | Config const *const | theConfig | ) | [inline] |
Definition at line 60 of file G4INCLClusteringModelIntercomparison.hh.
References G4INCL::ParticleTable::clusterZMax, G4INCL::ParticleTable::clusterZMin, and G4INCL::ParticleTable::maxClusterMass.
00060 : 00061 theNucleus(NULL), 00062 selectedA(0), 00063 selectedZ(0), 00064 sqtot(0.), 00065 cascadingEnergyPool(0.), 00066 protonMass(ParticleTable::getRealMass(Proton)), 00067 neutronMass(ParticleTable::getRealMass(Neutron)), 00068 runningMaxClusterAlgorithmMass(theConfig->getClusterMaxMass()), 00069 nConsideredMax(0), 00070 nConsidered(0), 00071 consideredPartners(NULL), 00072 isInRunningConfiguration(NULL), 00073 maxMassConfigurationSkipping(ParticleTable::maxClusterMass) 00074 { 00075 // Set up the maximum charge and neutron number for clusters 00076 clusterZMaxAll = 0; 00077 clusterNMaxAll = 0; 00078 for(G4int A=0; A<=runningMaxClusterAlgorithmMass; ++A) { 00079 if(ParticleTable::clusterZMax[A]>clusterZMaxAll) 00080 clusterZMaxAll = ParticleTable::clusterZMax[A]; 00081 if(A-ParticleTable::clusterZMin[A]>clusterNMaxAll) 00082 clusterNMaxAll = A-ParticleTable::clusterZMin[A]; 00083 } 00084 std::fill(candidateConfiguration, 00085 candidateConfiguration + ParticleTable::maxClusterMass, 00086 static_cast<Particle*>(NULL)); 00087 00088 std::fill(runningEnergies, 00089 runningEnergies + ParticleTable::maxClusterMass, 00090 0.0); 00091 00092 std::fill(runningPotentials, 00093 runningPotentials + ParticleTable::maxClusterMass, 00094 0.0); 00095 00096 std::fill(runningConfiguration, 00097 runningConfiguration + ParticleTable::maxClusterMass, 00098 -1); 00099 00100 }
virtual G4INCL::ClusteringModelIntercomparison::~ClusteringModelIntercomparison | ( | ) | [inline, virtual] |
G4bool G4INCL::ClusteringModelIntercomparison::clusterCanEscape | ( | Nucleus const * | const, | |
Cluster const * | const | |||
) | [virtual] |
Determine whether cluster can escape or not.
Implements G4INCL::IClusteringModel.
Definition at line 344 of file G4INCLClusteringModelIntercomparison.cc.
References G4INCL::ThreeVector::dot(), G4INCL::Particle::getA(), G4INCL::Particle::getMomentum(), G4INCL::Particle::getPosition(), G4INCL::ThreeVector::mag2(), and CLHEP::detail::n.
00344 { 00345 // Forbid emission of the whole nucleus 00346 if(c->getA()>=n->getA()) 00347 return false; 00348 00349 // Check the escape angle of the cluster 00350 const ThreeVector &pos = c->getPosition(); 00351 const ThreeVector &mom = c->getMomentum(); 00352 const G4double cosEscapeAngle = pos.dot(mom) / std::sqrt(pos.mag2()*mom.mag2()); 00353 if(cosEscapeAngle < limitCosEscapeAngle) 00354 return false; 00355 00356 return true; 00357 }
Choose a cluster candidate to be produced. At this point we don't yet decide if it can pass through the Coulomb barrier or not.
Implements G4INCL::IClusteringModel.
Definition at line 50 of file G4INCLClusteringModelIntercomparison.cc.
References G4INCL::ParticleTable::clusterPhaseSpaceCut, G4INCL::ParticleTable::clusterPosFact2, G4INCL::ThreeVector::dot(), G4INCL::Particle::getA(), G4INCL::Config::getClusterMaxMass(), G4INCL::Store::getConfig(), G4INCL::Nucleus::getDensity(), G4INCL::Particle::getEnergy(), G4INCL::Particle::getID(), G4INCL::Particle::getMomentum(), G4INCL::NuclearDensity::getNuclearRadius(), G4INCL::Store::getParticles(), G4INCL::Particle::getPosition(), G4INCL::Particle::getPotentialEnergy(), G4INCL::Nucleus::getStore(), G4INCL::Nucleus::getUniverseRadius(), G4INCL::Particle::getZ(), G4INCL::ThreeVector::mag(), and G4INCL::Particle::setPosition().
00050 { 00051 // Set the maximum clustering mass dynamically, based on the current nucleus 00052 const G4int maxClusterAlgorithmMass = nucleus->getStore()->getConfig()->getClusterMaxMass(); 00053 runningMaxClusterAlgorithmMass = std::min(maxClusterAlgorithmMass, nucleus->getA()/2); 00054 00055 // Nucleus too small? 00056 if(runningMaxClusterAlgorithmMass<=1) 00057 return NULL; 00058 00059 theNucleus = nucleus; 00060 Particle *theLeadingParticle = particle; 00061 00062 // Initialise sqtot to a large number 00063 sqtot = 50000.0; 00064 selectedA = 0; 00065 selectedZ = 0; 00066 00067 // The distance parameter, known as h in publications. 00068 // Default value is 1 fm. 00069 const G4double transp = 1.0; 00070 00071 const G4double rmaxws = theNucleus->getUniverseRadius(); 00072 00073 // Radius of the sphere where the leading particle is positioned. 00074 const G4double Rprime = theNucleus->getDensity()->getNuclearRadius() + transp; 00075 00076 // Bring the leading particle back to the coalescence sphere 00077 const G4double pk = theLeadingParticle->getMomentum().mag(); 00078 const G4double cospr = theLeadingParticle->getPosition().dot(theLeadingParticle->getMomentum())/(theNucleus->getUniverseRadius() * pk); 00079 const G4double arg = rmaxws*rmaxws - Rprime*Rprime; 00080 G4double translat; 00081 00082 if(arg > 0.0) { 00083 // coalescence sphere smaller than Rmax 00084 const G4double cosmin = std::sqrt(arg)/rmaxws; 00085 if(cospr <= cosmin) { 00086 // there is an intersection with the coalescence sphere 00087 translat = rmaxws * cospr; 00088 } else { 00089 // no intersection with the coalescence sphere 00090 translat = rmaxws * (cospr - std::sqrt(cospr*cospr - cosmin*cosmin)); 00091 } 00092 } else { 00093 // coalescence sphere larger than Rmax 00094 translat = rmaxws * cospr - std::sqrt(Rprime*Rprime - rmaxws*rmaxws*(1.0 - cospr*cospr)); 00095 } 00096 00097 const ThreeVector oldLeadingParticlePosition = theLeadingParticle->getPosition(); 00098 const ThreeVector leadingParticlePosition = oldLeadingParticlePosition - theLeadingParticle->getMomentum() * (translat/pk); 00099 const ThreeVector &leadingParticleMomentum = theLeadingParticle->getMomentum(); 00100 theLeadingParticle->setPosition(leadingParticlePosition); 00101 00102 // Initialise the array of considered nucleons 00103 const G4int theNucleusA = theNucleus->getA(); 00104 if(nConsideredMax < theNucleusA) { 00105 delete [] consideredPartners; 00106 delete [] isInRunningConfiguration; 00107 nConsideredMax = 2*theNucleusA; 00108 consideredPartners = new Particle *[nConsideredMax]; 00109 isInRunningConfiguration = new G4bool [nConsideredMax]; 00110 std::fill(isInRunningConfiguration, 00111 isInRunningConfiguration + nConsideredMax, 00112 false); 00113 } 00114 00115 // Select the subset of nucleons that will be considered in the 00116 // cluster production: 00117 cascadingEnergyPool = 0.; 00118 nConsidered = 0; 00119 const ParticleList particles = theNucleus->getStore()->getParticles(); 00120 for(ParticleIter i = particles.begin(); i != particles.end(); ++i) { 00121 if (!(*i)->isNucleon()) continue; // Only nucleons are allowed in clusters 00122 if ((*i)->getID() == theLeadingParticle->getID()) continue; // Don't count the leading particle 00123 00124 G4double space = ((*i)->getPosition() - leadingParticlePosition).mag2(); 00125 G4double momentum = ((*i)->getMomentum() - leadingParticleMomentum).mag2(); 00126 G4double size = space*momentum*ParticleTable::clusterPosFact2[runningMaxClusterAlgorithmMass]; 00127 // Nucleons are accepted only if they are "close enough" in phase space 00128 // to the leading nucleon. The selected phase-space parameter corresponds 00129 // to the running maximum cluster mass. 00130 if(size < ParticleTable::clusterPhaseSpaceCut[runningMaxClusterAlgorithmMass]) { 00131 consideredPartners[nConsidered] = *i; 00132 // Keep trace of how much energy is carried by cascading nucleons. This 00133 // is used to stop the clustering algorithm as soon as possible. 00134 if(!(*i)->isTargetSpectator()) 00135 cascadingEnergyPool += (*i)->getEnergy() - (*i)->getPotentialEnergy() - 931.3; 00136 nConsidered++; 00137 // Make sure we don't exceed the array size 00138 // assert(nConsidered<=nConsideredMax); 00139 } 00140 } 00141 // Sort the list of considered partners so that we give priority 00142 // to participants. As soon as we encounter the first spectator in 00143 // the list we know that all the remaining nucleons will be 00144 // spectators too. 00145 std::partition(consideredPartners, consideredPartners+nConsidered, cascadingFirstPredicate); 00146 00147 // Clear the sets of checked configurations 00148 // We stop caching two masses short of the max mass -- there seems to be a 00149 // performance hit above 00150 maxMassConfigurationSkipping = runningMaxClusterAlgorithmMass-2; 00151 for(G4int i=0; i<runningMaxClusterAlgorithmMass-2; ++i) // no caching for A=1,2 00152 checkedConfigurations[i].clear(); 00153 00154 // Initialise position, momentum and energy of the running cluster 00155 // configuration 00156 runningPositions[1] = leadingParticlePosition; 00157 runningMomenta[1] = leadingParticleMomentum; 00158 runningEnergies[1] = theLeadingParticle->getEnergy(); 00159 runningPotentials[1] = theLeadingParticle->getPotentialEnergy(); 00160 00161 // Make sure that all the elements of isInRunningConfiguration are false. 00162 // assert(std::count(isInRunningConfiguration, isInRunningConfiguration+nConsidered, true)==0); 00163 00164 // Start the cluster search! 00165 findClusterStartingFrom(1, theLeadingParticle->getZ()); 00166 00167 // Again, make sure that all the elements of isInRunningConfiguration have 00168 // been reset to false. This is a sanity check. 00169 // assert(std::count(isInRunningConfiguration, isInRunningConfiguration+nConsidered, true)==0); 00170 00171 Cluster *chosenCluster = 0; 00172 if(selectedA!=0) { // A cluster was found! 00173 candidateConfiguration[selectedA-1] = theLeadingParticle; 00174 chosenCluster = new Cluster(candidateConfiguration, 00175 candidateConfiguration + selectedA); 00176 } 00177 00178 // Restore the original position of the leading particle 00179 theLeadingParticle->setPosition(oldLeadingParticlePosition); 00180 00181 return chosenCluster; 00182 }