G4INCL::ClusteringModelIntercomparison Class Reference

Cluster coalescence algorithm used in the IAEA intercomparison. More...

#include <G4INCLClusteringModelIntercomparison.hh>

Inheritance diagram for G4INCL::ClusteringModelIntercomparison:

G4INCL::IClusteringModel

Public Member Functions

 ClusteringModelIntercomparison (Config const *const theConfig)
virtual ~ClusteringModelIntercomparison ()
virtual ClustergetCluster (Nucleus *, Particle *)
virtual G4bool clusterCanEscape (Nucleus const *const, Cluster const *const)

Data Structures

class  SortedNucleonConfiguration
 Class for storing and comparing sorted nucleon configurations.

Detailed Description

Cluster coalescence algorithm used in the IAEA intercomparison.

Definition at line 58 of file G4INCLClusteringModelIntercomparison.hh.


Constructor & Destructor Documentation

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]

Definition at line 102 of file G4INCLClusteringModelIntercomparison.hh.

00102                                               {
00103       delete [] consideredPartners;
00104       delete [] isInRunningConfiguration;
00105     }


Member Function Documentation

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   }

Cluster * G4INCL::ClusteringModelIntercomparison::getCluster ( Nucleus ,
Particle  
) [virtual]

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   }


The documentation for this class was generated from the following files:
Generated on Mon May 27 17:54:06 2013 for Geant4 by  doxygen 1.4.7