34 #define INCLXX_IN_GEANT4_MODE 1 45 #include "G4INCLSurfaceAvatar.hh" 56 :IAvatar(time), theParticle(aParticle), theNucleus(n),
65 sinRefractionAngle(0.),
66 cosRefractionAngle(0.),
67 refractionIndexRatio(0.),
68 internalReflection(
false)
73 SurfaceAvatar::~SurfaceAvatar() {
78 if(theParticle->isTargetSpectator()) {
79 INCL_DEBUG(
"Particle " << theParticle->getID() <<
" is a spectator, reflection" <<
'\n');
80 return new ReflectionChannel(theNucleus, theParticle);
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');
91 return new ReflectionChannel(theNucleus, theParticle);
96 const G4double transmissionProbability = getTransmissionProbability(theParticle);
99 const G4double cosR = cosRefractionAngle;
101 INCL_DEBUG(
"Transmission probability for particle " << theParticle->getID() <<
" = " << transmissionProbability <<
'\n');
110 if(theParticle->isNucleon()
111 && (!theParticle->isProjectileSpectator() || !theNucleus->isNucleusNucleusCollision())
112 && transmissionProbability>1.
E-4) {
113 Cluster *candidateCluster = 0;
116 if(candidateCluster != 0 &&
119 INCL_DEBUG(
"Cluster algorithm succeded. Candidate cluster:" <<
'\n' << candidateCluster->print() <<
'\n');
122 const G4double clusterTransmissionProbability = getTransmissionProbability(candidateCluster);
125 INCL_DEBUG(
"Transmission probability for cluster " << candidateCluster->getID() <<
" = " << clusterTransmissionProbability <<
'\n');
127 if (x <= clusterTransmissionProbability) {
128 theNucleus->getStore()->getBook().incrementEmittedClusters();
129 INCL_DEBUG(
"Cluster " << candidateCluster->getID() <<
" passes the Coulomb barrier, transmitting." <<
'\n');
130 return new TransmissionChannel(theNucleus, candidateCluster);
132 INCL_DEBUG(
"Cluster " << candidateCluster->getID() <<
" does not pass the Coulomb barrier. Falling back to transmission of the leading particle." <<
'\n');
133 delete candidateCluster;
136 delete candidateCluster;
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);
153 if(x <= transmissionProbability) {
154 INCL_DEBUG(
"Particle " << theParticle->getID() <<
" passes the Coulomb barrier, transmitting." <<
'\n');
155 if(theNucleus->getStore()->getConfig()->getRefraction()) {
156 return new TransmissionChannel(theNucleus, theParticle, kOut, cosR);
158 return new TransmissionChannel(theNucleus, theParticle, TOut);
161 INCL_DEBUG(
"Particle " << theParticle->getID() <<
" does not pass the Coulomb barrier, reflection." <<
'\n');
162 return new ReflectionChannel(theNucleus, theParticle);
166 void SurfaceAvatar::fillFinalState(FinalState *fs) {
167 getChannel()->fillFinalState(fs);
170 void SurfaceAvatar::preInteraction() {}
172 void SurfaceAvatar::postInteraction(FinalState *fs) {
173 ParticleList
const &outgoing = fs->getOutgoingParticles();
174 if(!outgoing.empty()) {
176 Particle *out = outgoing.front();
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())
183 theNucleus->getStore()->getBook().decrementCascading();
185 }
else if(!theParticle->isTargetSpectator()) {
187 theNucleus->getStore()->getBook().decrementCascading();
192 std::string SurfaceAvatar::dump()
const {
193 std::stringstream ss;
194 ss <<
"(avatar " << theTime <<
" 'reflection" <<
'\n' 196 << theParticle->dump()
201 G4double SurfaceAvatar::getTransmissionProbability(Particle
const *
const particle) {
203 particleMass = particle->getMass();
204 const G4double V = particle->getPotentialEnergy();
207 const G4int theA = theNucleus->getA();
208 const G4int theZ = theNucleus->getZ();
209 const G4double correction = particle->getEmissionQValueCorrection(theA, theZ);
210 particleTOut = particle->getKineticEnergy() + correction;
212 if (particleTOut <= V)
215 TMinusV = particleTOut-V;
216 TMinusV2 = TMinusV*TMinusV;
219 const G4double particlePIn2 = particle->getMomentum().mag2();
220 const G4double particlePOut2 = 2.*particleMass*TMinusV+TMinusV2;
221 particlePIn = std::sqrt(particlePIn2);
222 particlePOut = std::sqrt(particlePOut2);
225 G4double theTransmissionProbability;
226 if(theNucleus->getStore()->getConfig()->getRefraction()) {
228 initializeRefractionVariables(particle);
230 if(internalReflection)
234 const G4double x = refractionIndexRatio*cosIncidentAngle;
235 const G4double y = (x - cosRefractionAngle) / (x + cosRefractionAngle);
237 theTransmissionProbability = 1. - y*
y;
242 const G4double y = particlePIn+particlePOut;
245 theTransmissionProbability = 4.*particlePIn*particlePOut/(y*
y);
250 const G4int particleZ = particle->getZ();
251 if (particleZ <= 0 || particleZ >= theZ)
252 return theTransmissionProbability;
255 const G4double theTransmissionBarrier = theNucleus->getTransmissionBarrier(particle);
256 if (TMinusV >= theTransmissionBarrier)
257 return theTransmissionProbability;
260 const G4double px = std::sqrt(TMinusV/theTransmissionBarrier);
261 const G4double logCoulombTransmission =
262 particleZ*(theZ-particleZ)/137.03*std::sqrt(2.*particleMass/TMinusV/(1.+TMinusV/2./particleMass))
264 INCL_DEBUG(
"Coulomb barrier, logCoulombTransmission=" << logCoulombTransmission <<
'\n');
265 if (logCoulombTransmission > 35.)
267 theTransmissionProbability *= std::exp(-2.*logCoulombTransmission);
269 return theTransmissionProbability;
272 void SurfaceAvatar::initializeRefractionVariables(Particle
const *
const particle) {
273 cosIncidentAngle = particle->getCosRPAngle();
274 if(cosIncidentAngle>1.)
276 sinIncidentAngle = std::sqrt(1. - cosIncidentAngle*cosIncidentAngle);
277 refractionIndexRatio = particlePIn/particlePOut;
278 const G4double sinCandidate = refractionIndexRatio*sinIncidentAngle;
279 internalReflection = (std::fabs(sinCandidate)>1.);
280 if(internalReflection) {
281 sinRefractionAngle = 1.;
282 cosRefractionAngle = 0.;
284 sinRefractionAngle = sinCandidate;
285 cosRefractionAngle = std::sqrt(1. - sinRefractionAngle*sinRefractionAngle);
287 INCL_DEBUG(
"Refraction parameters initialised as follows:\n" 288 <<
" cosIncidentAngle=" << cosIncidentAngle <<
'\n' 289 <<
" sinIncidentAngle=" << sinIncidentAngle <<
'\n' 290 <<
" cosRefractionAngle=" << cosRefractionAngle <<
'\n' 291 <<
" sinRefractionAngle=" << sinRefractionAngle <<
'\n' 292 <<
" refractionIndexRatio=" << refractionIndexRatio <<
'\n' 293 <<
" internalReflection=" << internalReflection <<
'\n');
G4double arcCos(const G4double x)
Calculates arccos with some tolerance on illegal arguments.
G4bool clusterCanEscape(Nucleus const *const n, Cluster const *const c)
Determine whether the cluster can escape or not.
Cluster * getCluster(Nucleus *n, Particle *p)
Call the clustering algorithm.
Static class for cluster formation.
ParticleList::const_iterator ParticleIter