Geant4  9.6.p02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4INCLSurfaceAvatar.cc
Go to the documentation of this file.
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 // INCL++ intra-nuclear cascade model
27 // Pekka Kaitaniemi, CEA and Helsinki Institute of Physics
28 // Davide Mancusi, CEA
29 // Alain Boudard, CEA
30 // Sylvie Leray, CEA
31 // Joseph Cugnon, University of Liege
32 //
33 #define INCLXX_IN_GEANT4_MODE 1
34 
35 #include "globals.hh"
36 
37 /*
38  * G4INCLReflectionAvatar.cc
39  *
40  * \date Jun 8, 2009
41  * \author Pekka Kaitaniemi
42  */
43 
44 #include "G4INCLSurfaceAvatar.hh"
45 #include "G4INCLRandom.hh"
48 #include "G4INCLClustering.hh"
49 #include <sstream>
50 #include <string>
51 
52 namespace G4INCL {
53 
55  :IAvatar(time), theParticle(aParticle), theNucleus(n)
56  {
58  }
59 
61 
62  }
63 
65  {
66  if(theParticle->isTargetSpectator()) {
67  DEBUG("Particle " << theParticle->getID() << " is a spectator, reflection" << std::endl);
68  return new ReflectionChannel(theNucleus, theParticle);
69  }
70 
71  // We forbid transmission of resonances below the Fermi energy. Emitting a
72  // delta particle below Tf can lead to negative excitation energies, since
73  // CDPP assumes that particles stay in the Fermi sea.
74  if(theParticle->isResonance()) {
75  const G4double theFermiEnergy = theNucleus->getPotential()->getFermiEnergy(theParticle);
76  if(theParticle->getKineticEnergy()<theFermiEnergy) {
77  DEBUG("Particle " << theParticle->getID() << " is a resonance below Tf, reflection" << std::endl
78  << " Tf=" << theFermiEnergy << ", EKin=" << theParticle->getKineticEnergy() << std::endl);
79  return new ReflectionChannel(theNucleus, theParticle);
80  }
81  }
82 
83  // Don't try to make a cluster if the leading particle is too slow
84  const G4double transmissionProbability = getTransmissionProbability(theParticle);
85 
86  DEBUG("Transmission probability for particle " << theParticle->getID() << " = " << transmissionProbability << std::endl);
87  /* Don't attempt to construct clusters when a projectile spectator is
88  * trying to escape during a nucleus-nucleus collision. The idea behind
89  * this is that projectile spectators will later be collected in the
90  * projectile remnant, and trying to clusterise them somewhat feels like
91  * G4double counting. Moreover, applying the clustering algorithm on escaping
92  * projectile spectators makes the code *really* slow if the projectile is
93  * large.
94  */
95  if(theParticle->isNucleon()
96  && (!theParticle->isProjectileSpectator() || !theNucleus->isNucleusNucleusCollision())
97  && transmissionProbability>1.E-4) {
98  Cluster *candidateCluster = 0;
99 
100  candidateCluster = Clustering::getCluster(theNucleus, theParticle);
101  if(candidateCluster != 0 &&
102  Clustering::clusterCanEscape(theNucleus, candidateCluster)) {
103 
104  DEBUG("Cluster algorithm succeded. Candidate cluster:" << std::endl << candidateCluster->print() << std::endl);
105 
106  // Check if the cluster can penetrate the Coulomb barrier
107  const G4double clusterTransmissionProbability = getTransmissionProbability(candidateCluster);
108  const G4double x = Random::shoot();
109 
110  DEBUG("Transmission probability for cluster " << candidateCluster->getID() << " = " << clusterTransmissionProbability << std::endl);
111 
112  if (x <= clusterTransmissionProbability) {
113  DEBUG("Cluster " << candidateCluster->getID() << " passes the Coulomb barrier, transmitting." << std::endl);
114  return new TransmissionChannel(theNucleus, candidateCluster);
115  } else {
116  DEBUG("Cluster " << candidateCluster->getID() << " does not pass the Coulomb barrier. Falling back to transmission of the leading particle." << std::endl);
117  delete candidateCluster;
118  }
119  } else {
120  delete candidateCluster;
121  }
122  }
123 
124  // If we haven't transmitted a cluster (maybe cluster feature was
125  // disabled or maybe we just can't produce an acceptable cluster):
126 
127  // Always transmit projectile spectators if no cluster was formed and if
128  // transmission is energetically allowed
129  if(theParticle->isProjectileSpectator() && transmissionProbability>0.) {
130  DEBUG("Particle " << theParticle->getID() << " is a projectile spectator, transmission" << std::endl);
131  return new TransmissionChannel(theNucleus, theParticle);
132  }
133 
134  // Transmit or reflect depending on the transmission probability
135  const G4double x = Random::shoot();
136 
137  if(x <= transmissionProbability) { // Transmission
138  DEBUG("Particle " << theParticle->getID() << " passes the Coulomb barrier, transmitting." << std::endl);
139  return new TransmissionChannel(theNucleus, theParticle);
140  } else { // Reflection
141  DEBUG("Particle " << theParticle->getID() << " does not pass the Coulomb barrier, reflection." << std::endl);
142  return new ReflectionChannel(theNucleus, theParticle);
143  }
144  }
145 
147  {
148  return getChannel()->getFinalState();
149  }
150 
152 
154  ParticleList outgoing = fs->getOutgoingParticles();
155  if(!outgoing.empty()) { // Transmission
156 // assert(outgoing.size()==1);
157  Particle *out = outgoing.front();
158  if(out->isCluster()) {
159  Cluster *clusterOut = dynamic_cast<Cluster*>(out);
160  ParticleList const components = clusterOut->getParticles();
161  for(ParticleIter i=components.begin(); i!=components.end(); ++i) {
162  if(!(*i)->isTargetSpectator())
163  theNucleus->getStore()->getBook()->decrementCascading();
164  }
165  } else if(!theParticle->isTargetSpectator()) {
166 // assert(out==theParticle);
167  theNucleus->getStore()->getBook()->decrementCascading();
168  }
169  }
170  return fs;
171  }
172 
173  std::string SurfaceAvatar::dump() const {
174  std::stringstream ss;
175  ss << "(avatar " << theTime << " 'reflection" << std::endl
176  << "(list " << std::endl
177  << theParticle->dump()
178  << "))" << std::endl;
179  return ss.str();
180  }
181 
183 
184  G4double E = particle->getKineticEnergy();
185  const G4double V = particle->getPotentialEnergy();
186 
187  // Correction to the particle kinetic energy if using real masses
188  const G4int theA = theNucleus->getA();
189  const G4int theZ = theNucleus->getZ();
190  E += particle->getEmissionQValueCorrection(theA, theZ);
191 
192  if (E <= V) // No transmission if total energy < 0
193  return 0.0;
194 
195  const G4double m = particle->getMass();
196  const G4double EMinusV = E-V;
197  const G4double EMinusV2 = EMinusV*EMinusV;
198 
199  // Intermediate variable for calculation
200  const G4double x=std::sqrt((2.*m*E+E*E)*(2.*m*EMinusV+EMinusV2));
201 
202  // The transmission probability for a potential step
203  G4double theTransmissionProbability =
204  4.*x/(2.*m*(E+EMinusV)+E*E+(EMinusV2)+2.*x);
205 
206  // For neutral and negative particles, no Coulomb transmission
207  // Also, no Coulomb if the particle takes away all of the nuclear charge
208  const G4int theParticleZ = particle->getZ();
209  if (theParticleZ <= 0 || theParticleZ >= theZ)
210  return theTransmissionProbability;
211 
212  // Nominal Coulomb barrier
213  const G4double theTransmissionBarrier = theNucleus->getTransmissionBarrier(particle);
214  if (EMinusV >= theTransmissionBarrier) // Above the Coulomb barrier
215  return theTransmissionProbability;
216 
217  // Coulomb-penetration factor
218  const G4double px = std::sqrt(EMinusV/theTransmissionBarrier);
219  const G4double logCoulombTransmission =
220  theParticleZ*(theZ-theParticleZ)/137.03*std::sqrt(2.*m/EMinusV/(1.+EMinusV/2./m))
221  *(std::acos(px)-px*std::sqrt(1.-px*px));
222  if (logCoulombTransmission > 35.) // Transmission is forbidden by Coulomb
223  return 0.;
224  theTransmissionProbability *= std::exp(-2.*logCoulombTransmission);
225 
226  return theTransmissionProbability;
227  }
228 
229 }