Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
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// INCL++ revision: v5.1.8
34//
35#define INCLXX_IN_GEANT4_MODE 1
36
37#include "globals.hh"
38
39/*
40 * G4INCLReflectionAvatar.cc
41 *
42 * \date Jun 8, 2009
43 * \author Pekka Kaitaniemi
44 */
45
47#include "G4INCLRandom.hh"
50#include "G4INCLClustering.hh"
51#include <sstream>
52#include <string>
53
54namespace G4INCL {
55
57 :IAvatar(time), theParticle(aParticle), theNucleus(n)
58 {
60 }
61
63
64 }
65
67 {
68 if(theParticle->isTargetSpectator()) {
69 DEBUG("Particle " << theParticle->getID() << " is a spectator, reflection" << std::endl);
70 return new ReflectionChannel(theNucleus, theParticle);
71 }
72
73 // We forbid transmission of resonances below the Fermi energy. Emitting a
74 // delta particle below Tf can lead to negative excitation energies, since
75 // CDPP assumes that particles stay in the Fermi sea.
76 if(theParticle->isResonance()) {
77 const G4double theFermiEnergy = theNucleus->getPotential()->getFermiEnergy(theParticle);
78 if(theParticle->getKineticEnergy()<theFermiEnergy) {
79 DEBUG("Particle " << theParticle->getID() << " is a resonance below Tf, reflection" << std::endl
80 << " Tf=" << theFermiEnergy << ", EKin=" << theParticle->getKineticEnergy() << std::endl);
81 return new ReflectionChannel(theNucleus, theParticle);
82 }
83 }
84
85 // Don't try to make a cluster if the leading particle is too slow
86 const G4double transmissionProbability = getTransmissionProbability(theParticle);
87
88 DEBUG("Transmission probability for particle " << theParticle->getID() << " = " << transmissionProbability << std::endl);
89 /* Don't attempt to construct clusters when a projectile spectator is
90 * trying to escape during a nucleus-nucleus collision. The idea behind
91 * this is that projectile spectators will later be collected in the
92 * projectile remnant, and trying to clusterise them somewhat feels like
93 * G4double counting. Moreover, applying the clustering algorithm on escaping
94 * projectile spectators makes the code *really* slow if the projectile is
95 * large.
96 */
97 if(theParticle->isNucleon()
98 && (!theParticle->isProjectileSpectator() || !theNucleus->isNucleusNucleusCollision())
99 && transmissionProbability>1.E-4) {
100 Cluster *candidateCluster = 0;
101
102 candidateCluster = Clustering::getCluster(theNucleus, theParticle);
103 if(candidateCluster != 0 &&
104 Clustering::clusterCanEscape(theNucleus, candidateCluster)) {
105
106 DEBUG("Cluster algorithm succeded. Candidate cluster:" << std::endl << candidateCluster->print() << std::endl);
107
108 // Check if the cluster can penetrate the Coulomb barrier
109 const G4double clusterTransmissionProbability = getTransmissionProbability(candidateCluster);
110 const G4double x = Random::shoot();
111
112 DEBUG("Transmission probability for cluster " << candidateCluster->getID() << " = " << clusterTransmissionProbability << std::endl);
113
114 if (x <= clusterTransmissionProbability) {
115 DEBUG("Cluster " << candidateCluster->getID() << " passes the Coulomb barrier, transmitting." << std::endl);
116 return new TransmissionChannel(theNucleus, candidateCluster);
117 } else {
118 DEBUG("Cluster " << candidateCluster->getID() << " does not pass the Coulomb barrier. Falling back to transmission of the leading particle." << std::endl);
119 delete candidateCluster;
120 }
121 } else {
122 delete candidateCluster;
123 }
124 }
125
126 // If we haven't transmitted a cluster (maybe cluster feature was
127 // disabled or maybe we just can't produce an acceptable cluster):
128
129 // Always transmit projectile spectators if no cluster was formed and if
130 // transmission is energetically allowed
131 if(theParticle->isProjectileSpectator() && transmissionProbability>0.) {
132 DEBUG("Particle " << theParticle->getID() << " is a projectile spectator, transmission" << std::endl);
133 return new TransmissionChannel(theNucleus, theParticle);
134 }
135
136 // Transmit or reflect depending on the transmission probability
137 const G4double x = Random::shoot();
138
139 if(x <= transmissionProbability) { // Transmission
140 DEBUG("Particle " << theParticle->getID() << " passes the Coulomb barrier, transmitting." << std::endl);
141 return new TransmissionChannel(theNucleus, theParticle);
142 } else { // Reflection
143 DEBUG("Particle " << theParticle->getID() << " does not pass the Coulomb barrier, reflection." << std::endl);
144 return new ReflectionChannel(theNucleus, theParticle);
145 }
146 }
147
149 {
150 return getChannel()->getFinalState();
151 }
152
154
156 ParticleList outgoing = fs->getOutgoingParticles();
157 if(!outgoing.empty()) { // Transmission
158// assert(outgoing.size()==1);
159 Particle *out = outgoing.front();
160 if(out->isCluster()) {
161 Cluster *clusterOut = dynamic_cast<Cluster*>(out);
162 ParticleList const components = clusterOut->getParticles();
163 for(ParticleIter i=components.begin(); i!=components.end(); ++i) {
164 if(!(*i)->isTargetSpectator())
165 theNucleus->getStore()->getBook()->decrementCascading();
166 }
167 } else if(!theParticle->isTargetSpectator()) {
168// assert(out==theParticle);
169 theNucleus->getStore()->getBook()->decrementCascading();
170 }
171 }
172 return fs;
173 }
174
175 std::string SurfaceAvatar::dump() const {
176 std::stringstream ss;
177 ss << "(avatar " << theTime << " 'reflection" << std::endl
178 << "(list " << std::endl
179 << theParticle->dump()
180 << "))" << std::endl;
181 return ss.str();
182 }
183
185
186 G4double E = particle->getKineticEnergy();
187 const G4double V = particle->getPotentialEnergy();
188
189 // Correction to the particle kinetic energy if using real masses
190 const G4int theA = theNucleus->getA();
191 const G4int theZ = theNucleus->getZ();
192 E += particle->getEmissionQValueCorrection(theA, theZ);
193
194 if (E <= V) // No transmission if total energy < 0
195 return 0.0;
196
197 const G4double m = particle->getMass();
198 const G4double EMinusV = E-V;
199 const G4double EMinusV2 = EMinusV*EMinusV;
200
201 // Intermediate variable for calculation
202 const G4double x=std::sqrt((2.*m*E+E*E)*(2.*m*EMinusV+EMinusV2));
203
204 // The transmission probability for a potential step
205 G4double theTransmissionProbability =
206 4.*x/(2.*m*(E+EMinusV)+E*E+(EMinusV2)+2.*x);
207
208 // For neutral and negative particles, no Coulomb transmission
209 // Also, no Coulomb if the particle takes away all of the nuclear charge
210 const G4int theParticleZ = particle->getZ();
211 if (theParticleZ <= 0 || theParticleZ >= theZ)
212 return theTransmissionProbability;
213
214 // Nominal Coulomb barrier
215 const G4double theTransmissionBarrier = theNucleus->getTransmissionBarrier(particle);
216 if (EMinusV >= theTransmissionBarrier) // Above the Coulomb barrier
217 return theTransmissionProbability;
218
219 // Coulomb-penetration factor
220 const G4double px = std::sqrt(EMinusV/theTransmissionBarrier);
221 const G4double logCoulombTransmission =
222 theParticleZ*(theZ-theParticleZ)/137.03*std::sqrt(2.*m/EMinusV/(1.+EMinusV/2./m))
223 *(std::acos(px)-px*std::sqrt(1.-px*px));
224 if (logCoulombTransmission > 35.) // Transmission is forbidden by Coulomb
225 return 0.;
226 theTransmissionProbability *= std::exp(-2.*logCoulombTransmission);
227
228 return theTransmissionProbability;
229 }
230
231}
Static class for cluster formation.
#define DEBUG(x)
double G4double
Definition: G4Types.hh:64
int G4int
Definition: G4Types.hh:66
void decrementCascading()
Definition: G4INCLBook.hh:74
ParticleList const & getParticles() const
std::string print() const
static G4bool clusterCanEscape(Nucleus const *const n, Cluster const *const c)
static Cluster * getCluster(Nucleus *n, Particle *p)
ParticleList const & getOutgoingParticles() const
void setType(AvatarType t)
virtual G4INCL::FinalState * getFinalState()=0
G4double getFermiEnergy(const Particle *const p) const
Return the Fermi energy for a particle.
NuclearPotential::INuclearPotential * getPotential() const
Getter for thePotential.
Store * getStore() const
G4bool isNucleusNucleusCollision() const
Is it a nucleus-nucleus collision?
G4double getTransmissionBarrier(Particle const *const p)
Get the transmission barrier.
G4bool isCluster() const
G4double getEmissionQValueCorrection(const G4int AParent, const G4int ZParent) const
Computes correction on the emission Q-value.
G4double getPotentialEnergy() const
Get the particle potential energy.
std::string dump() const
G4int getZ() const
Returns the charge number.
G4double getKineticEnergy() const
Get the particle kinetic energy.
G4bool isTargetSpectator() const
G4bool isProjectileSpectator() const
G4bool isResonance() const
Is it a resonance?
G4double getMass() const
Get the cached particle mass.
long getID() const
G4int getA() const
Returns the baryon number.
G4bool isNucleon() const
static G4double shoot()
Definition: G4INCLRandom.hh:99
Book * getBook()
Definition: G4INCLStore.hh:243
std::string dump() const
G4double getTransmissionProbability(Particle const *const particle) const
Calculate the transmission probability for the particle.
SurfaceAvatar(G4INCL::Particle *aParticle, G4double time, G4INCL::Nucleus *aNucleus)
virtual FinalState * postInteraction(FinalState *)
G4INCL::IChannel * getChannel() const
G4INCL::FinalState * getFinalState() const
@ SurfaceAvatarType
std::list< G4INCL::Particle * > ParticleList
std::list< G4INCL::Particle * >::const_iterator ParticleIter