G4INCLSurfaceAvatar.cc

Go to the documentation of this file.
00001 //
00002 // ********************************************************************
00003 // * License and Disclaimer                                           *
00004 // *                                                                  *
00005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
00006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
00007 // * conditions of the Geant4 Software License,  included in the file *
00008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
00009 // * include a list of copyright holders.                             *
00010 // *                                                                  *
00011 // * Neither the authors of this software system, nor their employing *
00012 // * institutes,nor the agencies providing financial support for this *
00013 // * work  make  any representation or  warranty, express or implied, *
00014 // * regarding  this  software system or assume any liability for its *
00015 // * use.  Please see the license in the file  LICENSE  and URL above *
00016 // * for the full disclaimer and the limitation of liability.         *
00017 // *                                                                  *
00018 // * This  code  implementation is the result of  the  scientific and *
00019 // * technical work of the GEANT4 collaboration.                      *
00020 // * By using,  copying,  modifying or  distributing the software (or *
00021 // * any work based  on the software)  you  agree  to acknowledge its *
00022 // * use  in  resulting  scientific  publications,  and indicate your *
00023 // * acceptance of all terms of the Geant4 Software license.          *
00024 // ********************************************************************
00025 //
00026 // INCL++ intra-nuclear cascade model
00027 // Pekka Kaitaniemi, CEA and Helsinki Institute of Physics
00028 // Davide Mancusi, CEA
00029 // Alain Boudard, CEA
00030 // Sylvie Leray, CEA
00031 // Joseph Cugnon, University of Liege
00032 //
00033 #define INCLXX_IN_GEANT4_MODE 1
00034 
00035 #include "globals.hh"
00036 
00037 /*
00038  * G4INCLReflectionAvatar.cc
00039  *
00040  *  \date Jun 8, 2009
00041  * \author Pekka Kaitaniemi
00042  */
00043 
00044 #include "G4INCLSurfaceAvatar.hh"
00045 #include "G4INCLRandom.hh"
00046 #include "G4INCLReflectionChannel.hh"
00047 #include "G4INCLTransmissionChannel.hh"
00048 #include "G4INCLClustering.hh"
00049 #include <sstream>
00050 #include <string>
00051 
00052 namespace G4INCL {
00053 
00054   SurfaceAvatar::SurfaceAvatar(G4INCL::Particle *aParticle, G4double time, G4INCL::Nucleus *n)
00055     :IAvatar(time), theParticle(aParticle), theNucleus(n)
00056   {
00057     setType(SurfaceAvatarType);
00058   }
00059 
00060   SurfaceAvatar::~SurfaceAvatar() {
00061 
00062   }
00063 
00064   G4INCL::IChannel* SurfaceAvatar::getChannel() const
00065   {
00066     if(theParticle->isTargetSpectator()) {
00067       DEBUG("Particle " << theParticle->getID() << " is a spectator, reflection" << std::endl);
00068       return new ReflectionChannel(theNucleus, theParticle);
00069     }
00070 
00071     // We forbid transmission of resonances below the Fermi energy. Emitting a
00072     // delta particle below Tf can lead to negative excitation energies, since
00073     // CDPP assumes that particles stay in the Fermi sea.
00074     if(theParticle->isResonance()) {
00075       const G4double theFermiEnergy = theNucleus->getPotential()->getFermiEnergy(theParticle);
00076       if(theParticle->getKineticEnergy()<theFermiEnergy) {
00077         DEBUG("Particle " << theParticle->getID() << " is a resonance below Tf, reflection" << std::endl
00078             << "  Tf=" << theFermiEnergy << ", EKin=" << theParticle->getKineticEnergy() << std::endl);
00079         return new ReflectionChannel(theNucleus, theParticle);
00080       }
00081     }
00082 
00083     // Don't try to make a cluster if the leading particle is too slow
00084     const G4double transmissionProbability = getTransmissionProbability(theParticle);
00085 
00086     DEBUG("Transmission probability for particle " << theParticle->getID() << " = " << transmissionProbability << std::endl);
00087     /* Don't attempt to construct clusters when a projectile spectator is
00088      * trying to escape during a nucleus-nucleus collision. The idea behind
00089      * this is that projectile spectators will later be collected in the
00090      * projectile remnant, and trying to clusterise them somewhat feels like
00091      * G4double counting. Moreover, applying the clustering algorithm on escaping
00092      * projectile spectators makes the code *really* slow if the projectile is
00093      * large.
00094      */
00095     if(theParticle->isNucleon()
00096         && (!theParticle->isProjectileSpectator() || !theNucleus->isNucleusNucleusCollision())
00097         && transmissionProbability>1.E-4) {
00098       Cluster *candidateCluster = 0;
00099 
00100       candidateCluster = Clustering::getCluster(theNucleus, theParticle);
00101       if(candidateCluster != 0 &&
00102           Clustering::clusterCanEscape(theNucleus, candidateCluster)) {
00103 
00104         DEBUG("Cluster algorithm succeded. Candidate cluster:" << std::endl << candidateCluster->print() << std::endl);
00105 
00106         // Check if the cluster can penetrate the Coulomb barrier
00107         const G4double clusterTransmissionProbability = getTransmissionProbability(candidateCluster);
00108         const G4double x = Random::shoot();
00109 
00110         DEBUG("Transmission probability for cluster " << candidateCluster->getID() << " = " << clusterTransmissionProbability << std::endl);
00111 
00112         if (x <= clusterTransmissionProbability) {
00113           DEBUG("Cluster " << candidateCluster->getID() << " passes the Coulomb barrier, transmitting." << std::endl);
00114           return new TransmissionChannel(theNucleus, candidateCluster);
00115         } else {
00116           DEBUG("Cluster " << candidateCluster->getID() << " does not pass the Coulomb barrier. Falling back to transmission of the leading particle." << std::endl);
00117           delete candidateCluster;
00118         }
00119       } else {
00120         delete candidateCluster;
00121       }
00122     }
00123 
00124     // If we haven't transmitted a cluster (maybe cluster feature was
00125     // disabled or maybe we just can't produce an acceptable cluster):
00126 
00127     // Always transmit projectile spectators if no cluster was formed and if
00128     // transmission is energetically allowed
00129     if(theParticle->isProjectileSpectator() && transmissionProbability>0.) {
00130       DEBUG("Particle " << theParticle->getID() << " is a projectile spectator, transmission" << std::endl);
00131       return new TransmissionChannel(theNucleus, theParticle);
00132     }
00133 
00134     // Transmit or reflect depending on the transmission probability
00135     const G4double x = Random::shoot();
00136 
00137     if(x <= transmissionProbability) { // Transmission
00138       DEBUG("Particle " << theParticle->getID() << " passes the Coulomb barrier, transmitting." << std::endl);
00139       return new TransmissionChannel(theNucleus, theParticle);
00140     } else { // Reflection
00141       DEBUG("Particle " << theParticle->getID() << " does not pass the Coulomb barrier, reflection." << std::endl);
00142       return new ReflectionChannel(theNucleus, theParticle);
00143     }
00144   }
00145 
00146   G4INCL::FinalState* SurfaceAvatar::getFinalState() const
00147   {
00148     return getChannel()->getFinalState();
00149   }
00150 
00151   void SurfaceAvatar::preInteraction() {}
00152 
00153   FinalState *SurfaceAvatar::postInteraction(FinalState *fs) {
00154     ParticleList outgoing = fs->getOutgoingParticles();
00155     if(!outgoing.empty()) { // Transmission
00156 // assert(outgoing.size()==1);
00157       Particle *out = outgoing.front();
00158       if(out->isCluster()) {
00159         Cluster *clusterOut = dynamic_cast<Cluster*>(out);
00160         ParticleList const components = clusterOut->getParticles();
00161         for(ParticleIter i=components.begin(); i!=components.end(); ++i) {
00162           if(!(*i)->isTargetSpectator())
00163             theNucleus->getStore()->getBook()->decrementCascading();
00164         }
00165       } else if(!theParticle->isTargetSpectator()) {
00166 // assert(out==theParticle);
00167         theNucleus->getStore()->getBook()->decrementCascading();
00168       }
00169     }
00170     return fs;
00171   }
00172 
00173   std::string SurfaceAvatar::dump() const {
00174     std::stringstream ss;
00175     ss << "(avatar " << theTime << " 'reflection" << std::endl
00176       << "(list " << std::endl 
00177       << theParticle->dump()
00178       << "))" << std::endl;
00179     return ss.str();
00180   }
00181 
00182   G4double SurfaceAvatar::getTransmissionProbability(Particle const * const particle) const {
00183 
00184     G4double E = particle->getKineticEnergy();
00185     const G4double V = particle->getPotentialEnergy();
00186 
00187     // Correction to the particle kinetic energy if using real masses
00188     const G4int theA = theNucleus->getA();
00189     const G4int theZ = theNucleus->getZ();
00190     E += particle->getEmissionQValueCorrection(theA, theZ);
00191 
00192     if (E <= V) // No transmission if total energy < 0
00193       return 0.0;
00194 
00195     const G4double m = particle->getMass();
00196     const G4double EMinusV = E-V;
00197     const G4double EMinusV2 = EMinusV*EMinusV;
00198 
00199     // Intermediate variable for calculation
00200     const G4double x=std::sqrt((2.*m*E+E*E)*(2.*m*EMinusV+EMinusV2));
00201 
00202     // The transmission probability for a potential step
00203     G4double theTransmissionProbability =
00204       4.*x/(2.*m*(E+EMinusV)+E*E+(EMinusV2)+2.*x);
00205 
00206     // For neutral and negative particles, no Coulomb transmission
00207     // Also, no Coulomb if the particle takes away all of the nuclear charge
00208     const G4int theParticleZ = particle->getZ();
00209     if (theParticleZ <= 0 || theParticleZ >= theZ)
00210       return theTransmissionProbability;
00211 
00212     // Nominal Coulomb barrier
00213     const G4double theTransmissionBarrier = theNucleus->getTransmissionBarrier(particle);
00214     if (EMinusV >= theTransmissionBarrier) // Above the Coulomb barrier
00215       return theTransmissionProbability;
00216 
00217     // Coulomb-penetration factor
00218     const G4double px = std::sqrt(EMinusV/theTransmissionBarrier);
00219     const G4double logCoulombTransmission =
00220       theParticleZ*(theZ-theParticleZ)/137.03*std::sqrt(2.*m/EMinusV/(1.+EMinusV/2./m))
00221       *(std::acos(px)-px*std::sqrt(1.-px*px));
00222     if (logCoulombTransmission > 35.) // Transmission is forbidden by Coulomb
00223       return 0.;
00224     theTransmissionProbability *= std::exp(-2.*logCoulombTransmission);
00225 
00226     return theTransmissionProbability;
00227   }
00228 
00229 }

Generated on Mon May 27 17:48:37 2013 for Geant4 by  doxygen 1.4.7