Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
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