Geant4  v4-10.4-release
 모두 클래스 네임스페이스들 파일들 함수 변수 타입정의 열거형 타입 열거형 멤버 Friends 매크로 그룹들 페이지들
G4INCLSurfaceAvatar.cc
이 파일의 문서화 페이지로 가기
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 // Alain Boudard, CEA-Saclay, France
28 // Joseph Cugnon, University of Liege, Belgium
29 // Jean-Christophe David, CEA-Saclay, France
30 // Pekka Kaitaniemi, CEA-Saclay, France, and Helsinki Institute of Physics, Finland
31 // Sylvie Leray, CEA-Saclay, France
32 // Davide Mancusi, CEA-Saclay, France
33 //
34 #define INCLXX_IN_GEANT4_MODE 1
35 
36 #include "globals.hh"
37 
38 /*
39  * G4INCLReflectionAvatar.cc
40  *
41  * \date Jun 8, 2009
42  * \author Pekka Kaitaniemi
43  */
44 
45 #include "G4INCLSurfaceAvatar.hh"
46 #include "G4INCLRandom.hh"
49 #include "G4INCLClustering.hh"
50 #include <sstream>
51 #include <string>
52 
53 namespace G4INCL {
54 
56  :IAvatar(time), theParticle(aParticle), theNucleus(n),
57  particlePIn(0.),
58  particlePOut(0.),
59  particleTOut(0.),
60  TMinusV(0.),
61  TMinusV2(0.),
62  particleMass(0.),
63  sinIncidentAngle(0.),
64  cosIncidentAngle(0.),
65  sinRefractionAngle(0.),
66  cosRefractionAngle(0.),
67  refractionIndexRatio(0.),
68  internalReflection(false)
69  {
71  }
72 
74  {
75  }
76 
79  INCL_DEBUG("Particle " << theParticle->getID() << " is a spectator, reflection" << '\n');
81  }
82 
83  // We forbid transmission of resonances below the Fermi energy. Emitting a
84  // delta particle below Tf can lead to negative excitation energies, since
85  // CDPP assumes that particles stay in the Fermi sea.
86  if(theParticle->isResonance()) {
87  const G4double theFermiEnergy = theNucleus->getPotential()->getFermiEnergy(theParticle);
88  if(theParticle->getKineticEnergy()<theFermiEnergy) {
89  INCL_DEBUG("Particle " << theParticle->getID() << " is a resonance below Tf, reflection" << '\n'
90  << " Tf=" << theFermiEnergy << ", EKin=" << theParticle->getKineticEnergy() << '\n');
92  }
93  }
94 
95  // Don't try to make a cluster if the leading particle is too slow
96  const G4double transmissionProbability = getTransmissionProbability(theParticle);
97  const G4double TOut = TMinusV;
98  const G4double kOut = particlePOut;
99  const G4double cosR = cosRefractionAngle;
100 
101  INCL_DEBUG("Transmission probability for particle " << theParticle->getID() << " = " << transmissionProbability << '\n');
102  /* Don't attempt to construct clusters when a projectile spectator is
103  * trying to escape during a nucleus-nucleus collision. The idea behind
104  * this is that projectile spectators will later be collected in the
105  * projectile remnant, and trying to clusterise them somewhat feels like
106  * G4double counting. Moreover, applying the clustering algorithm on escaping
107  * projectile spectators makes the code *really* slow if the projectile is
108  * large.
109  */
112  && transmissionProbability>1.E-4) {
113  Cluster *candidateCluster = 0;
114 
115  candidateCluster = Clustering::getCluster(theNucleus, theParticle);
116  if(candidateCluster != 0 &&
117  Clustering::clusterCanEscape(theNucleus, candidateCluster)) {
118 
119  INCL_DEBUG("Cluster algorithm succeded. Candidate cluster:" << '\n' << candidateCluster->print() << '\n');
120 
121  // Check if the cluster can penetrate the Coulomb barrier
122  const G4double clusterTransmissionProbability = getTransmissionProbability(candidateCluster);
123  const G4double x = Random::shoot();
124 
125  INCL_DEBUG("Transmission probability for cluster " << candidateCluster->getID() << " = " << clusterTransmissionProbability << '\n');
126 
127  if (x <= clusterTransmissionProbability) {
129  INCL_DEBUG("Cluster " << candidateCluster->getID() << " passes the Coulomb barrier, transmitting." << '\n');
130  return new TransmissionChannel(theNucleus, candidateCluster);
131  } else {
132  INCL_DEBUG("Cluster " << candidateCluster->getID() << " does not pass the Coulomb barrier. Falling back to transmission of the leading particle." << '\n');
133  delete candidateCluster;
134  }
135  } else {
136  delete candidateCluster;
137  }
138  }
139 
140  // If we haven't transmitted a cluster (maybe cluster feature was
141  // disabled or maybe we just can't produce an acceptable cluster):
142 
143  // Always transmit projectile spectators if no cluster was formed and if
144  // transmission is energetically allowed
145  if(theParticle->isProjectileSpectator() && transmissionProbability>0.) {
146  INCL_DEBUG("Particle " << theParticle->getID() << " is a projectile spectator, transmission" << '\n');
147  return new TransmissionChannel(theNucleus, theParticle, TOut);
148  }
149 
150  // Transmit or reflect depending on the transmission probability
151  const G4double x = Random::shoot();
152 
153  if(x <= transmissionProbability) { // Transmission
154  INCL_DEBUG("Particle " << theParticle->getID() << " passes the Coulomb barrier, transmitting." << '\n');
156  return new TransmissionChannel(theNucleus, theParticle, kOut, cosR);
157  } else {
158  return new TransmissionChannel(theNucleus, theParticle, TOut);
159  }
160  } else { // Reflection
161  INCL_DEBUG("Particle " << theParticle->getID() << " does not pass the Coulomb barrier, reflection." << '\n');
163  }
164  }
165 
167  getChannel()->fillFinalState(fs);
168  }
169 
171 
173  ParticleList const &outgoing = fs->getOutgoingParticles();
174  if(!outgoing.empty()) { // Transmission
175 // assert(outgoing.size()==1);
176  Particle *out = outgoing.front();
177  out->rpCorrelate();
178  if(out->isCluster()) {
179  Cluster *clusterOut = dynamic_cast<Cluster*>(out);
180  ParticleList const &components = clusterOut->getParticles();
181  for(ParticleIter i=components.begin(), e=components.end(); i!=e; ++i) {
182  if(!(*i)->isTargetSpectator())
184  }
186  } else if(!theParticle->isTargetSpectator()) {
187 // assert(out==theParticle);
189  }
190  }
191  }
192 
193  std::string SurfaceAvatar::dump() const {
194  std::stringstream ss;
195  ss << "(avatar " << theTime << " 'reflection" << '\n'
196  << "(list " << '\n'
197  << theParticle->dump()
198  << "))" << '\n';
199  return ss.str();
200  }
201 
203 
204  particleMass = particle->getMass();
205  const G4double V = particle->getPotentialEnergy();
206 
207  // Correction to the particle kinetic energy if using real masses
208  const G4int theA = theNucleus->getA();
209  const G4int theZ = theNucleus->getZ();
210  const G4double correction = particle->getEmissionQValueCorrection(theA, theZ);
211  particleTOut = particle->getKineticEnergy() + correction;
212 
213  if (particleTOut <= V) // No transmission if total energy < 0
214  return 0.0;
215 
216  TMinusV = particleTOut-V;
218 
219  // Momenta in and out
220  const G4double particlePIn2 = particle->getMomentum().mag2();
221  const G4double particlePOut2 = 2.*particleMass*TMinusV+TMinusV2;
222  particlePIn = std::sqrt(particlePIn2);
223  particlePOut = std::sqrt(particlePOut2);
224 
225  if (0. > V) // Automatic transmission for repulsive potential
226  return 1.0;
227 
228  // Compute the transmission probability
229  G4double theTransmissionProbability;
231  // Use the formula with refraction
233 
235  return 0.; // total internal reflection
236 
237  // Intermediate variables for calculation
239  const G4double y = (x - cosRefractionAngle) / (x + cosRefractionAngle);
240 
241  theTransmissionProbability = 1. - y*y;
242  } else {
243  // Use the formula without refraction
244  // Intermediate variable for calculation
246 
247  // The transmission probability for a potential step
248  theTransmissionProbability = 4.*particlePIn*particlePOut/(y*y);
249  }
250 
251  // For neutral and negative particles, no Coulomb transmission
252  // Also, no Coulomb if the particle takes away all of the nuclear charge
253  const G4int particleZ = particle->getZ();
254  if (particleZ <= 0 || particleZ >= theZ)
255  return theTransmissionProbability;
256 
257  // Nominal Coulomb barrier
258  const G4double theTransmissionBarrier = theNucleus->getTransmissionBarrier(particle);
259  if (TMinusV >= theTransmissionBarrier) // Above the Coulomb barrier
260  return theTransmissionProbability;
261 
262  // Coulomb-penetration factor
263  const G4double px = std::sqrt(TMinusV/theTransmissionBarrier);
264  const G4double logCoulombTransmission =
265  particleZ*(theZ-particleZ)/137.03*std::sqrt(2.*particleMass/TMinusV/(1.+TMinusV/2./particleMass))
266  *(Math::arcCos(px)-px*std::sqrt(1.-px*px));
267  INCL_DEBUG("Coulomb barrier, logCoulombTransmission=" << logCoulombTransmission << '\n');
268  if (logCoulombTransmission > 35.) // Transmission is forbidden by Coulomb
269  return 0.;
270  theTransmissionProbability *= std::exp(-2.*logCoulombTransmission);
271 
272  return theTransmissionProbability;
273  }
274 
276  cosIncidentAngle = particle->getCosRPAngle();
277  if(cosIncidentAngle>1.)
278  cosIncidentAngle=1.;
281  const G4double sinCandidate = refractionIndexRatio*sinIncidentAngle;
282  internalReflection = (std::fabs(sinCandidate)>1.);
283  if(internalReflection) {
284  sinRefractionAngle = 1.;
285  cosRefractionAngle = 0.;
286  } else {
287  sinRefractionAngle = sinCandidate;
289  }
290  INCL_DEBUG("Refraction parameters initialised as follows:\n"
291  << " cosIncidentAngle=" << cosIncidentAngle << '\n'
292  << " sinIncidentAngle=" << sinIncidentAngle << '\n'
293  << " cosRefractionAngle=" << cosRefractionAngle << '\n'
294  << " sinRefractionAngle=" << sinRefractionAngle << '\n'
295  << " refractionIndexRatio=" << refractionIndexRatio << '\n'
296  << " internalReflection=" << internalReflection << '\n');
297  }
298 }
Float_t x
Definition: compare.C:6
ParticleList::const_iterator ParticleIter
NuclearPotential::INuclearPotential const * getPotential() const
Getter for thePotential.
G4bool isNucleonorLambda() const
Is this a Nucleon or a Lambda?
void incrementEmittedClusters()
Definition: G4INCLBook.hh:79
std::string dump() const
G4double getCosRPAngle() const
Get the cosine of the angle between position and momentum.
void setType(AvatarType t)
G4bool clusterCanEscape(Nucleus const *const n, Cluster const *const c)
Determine whether the cluster can escape or not.
G4double getKineticEnergy() const
Get the particle kinetic energy.
const G4INCL::ThreeVector & getMomentum() const
Float_t y
Definition: compare.C:6
long getID() const
Static class for cluster formation.
Book & getBook()
Definition: G4INCLStore.hh:259
G4INCL::Particle * theParticle
virtual void fillFinalState(FinalState *fs)=0
G4double getMass() const
Get the cached particle mass.
std::string print() const
void setBiasCollisionVector(std::vector< G4int > BiasCollisionVector)
Set the vector list of biased vertices on the particle path.
G4bool isResonance() const
Is it a resonance?
Cluster * getCluster(Nucleus *n, Particle *p)
Call the clustering algorithm.
#define INCL_DEBUG(x)
ParticleList const & getParticles() const
double G4double
Definition: G4Types.hh:76
G4double shoot()
Definition: G4INCLRandom.cc:93
G4double getPotentialEnergy() const
Get the particle potential energy.
G4bool getRefraction() const
True if we should use refraction.
G4double arcCos(const G4double x)
Calculates arccos with some tolerance on illegal arguments.
G4int getZ() const
Returns the charge number.
G4int getA() const
Returns the baryon number.
SurfaceAvatar(G4INCL::Particle *aParticle, G4double time, G4INCL::Nucleus *aNucleus)
std::string dump() const
void rpCorrelate()
Make the particle follow a strict r-p correlation.
G4double getTransmissionProbability(Particle const *const particle)
Calculate the transmission probability for the particle.
G4bool isTargetSpectator() const
virtual void postInteraction(FinalState *)
ParticleList const & getOutgoingParticles() const
int G4int
Definition: G4Types.hh:78
Config const * getConfig()
Definition: G4INCLStore.hh:273
G4double mag2() const
G4double getEmissionQValueCorrection(const G4int AParent, const G4int ZParent) const
Computes correction on the emission Q-value.
void decrementCascading()
Definition: G4INCLBook.hh:78
G4bool isCluster() const
G4INCL::Nucleus * theNucleus
G4double getFermiEnergy(const Particle *const p) const
Return the Fermi energy for a particle.
G4double getTransmissionBarrier(Particle const *const p)
Get the transmission barrier.
Char_t n[5]
void initializeRefractionVariables(Particle const *const particle)
G4bool isProjectileSpectator() const
Store * getStore() const
G4bool isNucleusNucleusCollision() const
Is it a nucleus-nucleus collision?
std::vector< G4int > getParticleListBiasVector() const
void fillFinalState(FinalState *fs)