Geant4 11.2.2
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4INCLStandardPropagationModel.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// 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 * StandardPropagationModel.cpp
40 *
41 * \date 4 juin 2009
42 * \author Pekka Kaitaniemi
43 */
44
49#include "G4INCLDecayAvatar.hh"
51#include "G4INCLRandom.hh"
52#include <iostream>
53#include <algorithm>
54#include "G4INCLLogger.hh"
55#include "G4INCLGlobals.hh"
62#include "G4INCLIntersection.hh"
63#include <vector>
64
65namespace G4INCL {
66
68 :theNucleus(0), maximumTime(70.0), currentTime(0.0),
69 hadronizationTime(hTime),
70 firstAvatar(true),
71 theLocalEnergyType(localEnergyType),
72 theLocalEnergyDeltaType(localEnergyDeltaType)
73 {
74 }
75
77 {
78 delete theNucleus;
79 }
80
82 {
83 return theNucleus;
84 }
85
86//D
87
88 G4double StandardPropagationModel::shoot(ParticleSpecies const &projectileSpecies, const G4double kineticEnergy, const G4double impactParameter, const G4double phi) {
89 if(projectileSpecies.theType==Composite){
90 return shootComposite(projectileSpecies, kineticEnergy, impactParameter, phi);
91 }
92 else if(projectileSpecies.theType==antiProton && theNucleus->getAnnihilationType()!=Def){
93 return shootAtrest(projectileSpecies.theType, kineticEnergy);
94 }
95 else{
96 return shootParticle(projectileSpecies.theType, kineticEnergy, impactParameter, phi);
97 }
98 }
99
100//D
101
103 theNucleus->setParticleNucleusCollision();
104 currentTime = 0.0;
105
106 // Create final state particles
107 const G4double projectileMass = ParticleTable::getTableParticleMass(t);
108 G4double energy = kineticEnergy + projectileMass;
109 G4double momentumZ = std::sqrt(energy*energy - projectileMass*projectileMass);
110 ThreeVector momentum(0.0, 0.0, momentumZ);
111 Particle *pb = new G4INCL::Particle(t, energy, momentum, ThreeVector());
112 PbarAtrestEntryChannel *obj = new PbarAtrestEntryChannel(theNucleus, pb);
113 ParticleList fslist = obj->makeMesonStar();
114 const G4bool isProton = obj->ProtonIsTheVictim();
115 delete pb;
116
117 //set Stopping time according to highest meson energy of the star
118 G4double temfin;
119 G4double TLab;
120 std::vector<G4double> energies;
121 std::vector<G4double> projections;
122 ThreeVector ab, cd;
123
124 for(ParticleIter pit = fslist.begin(), e = fslist.end(); pit!=e; ++pit){
125 energies.push_back((*pit)->getKineticEnergy());
126 ab = (*pit)->boostVector();
127 cd = (*pit)->getPosition();
128 projections.push_back(ab.dot(cd)); //projection length
129 }// make vector of energies
130
131 temfin = 30.18 * std::pow(theNucleus->getA(), 0.17);
132 TLab = *max_element(energies.begin(), energies.end()); //choose max energy
133
134 // energy-dependent stopping time above 2 AGeV
135 if(TLab>2000.)
136 temfin *= (5.8E4-TLab)/5.6E4;
137
138 maximumTime = temfin;
139
140 // If the incoming particle is slow, use a larger stopping time
141 const G4double rMax = theNucleus->getUniverseRadius();
142 const G4double distance = 2.*rMax;
143 const G4double maxMesonVelocityProjection = *max_element(energies.begin(), energies.end());
144 const G4double traversalTime = distance / maxMesonVelocityProjection;
145 if(maximumTime < traversalTime)
146 maximumTime = traversalTime;
147 INCL_DEBUG("Cascade stopping time is " << maximumTime << '\n');
148
149
150 // Fill in the relevant kinematic variables
151 theNucleus->setIncomingAngularMomentum(G4INCL::ThreeVector(0., 0., 0.));
152 theNucleus->setIncomingMomentum(G4INCL::ThreeVector(0., 0., 0.));
153 if(isProton){
154 theNucleus->setInitialEnergy(pb->getMass()
155 + ParticleTable::getTableMass(theNucleus->getA() + 1,theNucleus->getZ() + 1,theNucleus->getS()));
156 }
157 else{
158 theNucleus->setInitialEnergy(pb->getMass()
159 + ParticleTable::getTableMass(theNucleus->getA() + 1,theNucleus->getZ(),theNucleus->getS()));
160 }
161 //kinetic energy excluded from the balance
162
163 for(ParticleIter p = fslist.begin(), e = fslist.end(); p!=e; ++p){
164 (*p)->makeProjectileSpectator();
165 }
166
168 firstAvatar = false;
169
170 // Get the entry avatars for mesons
171 IAvatarList theAvatarList = obj->bringMesonStar(fslist, theNucleus);
172 delete obj;
173 theNucleus->getStore()->addParticleEntryAvatars(theAvatarList);
174 INCL_DEBUG("Avatars added" << '\n');
175
176 return 99.;
177 }
178
179//D
180
181 G4double StandardPropagationModel::shootParticle(ParticleType const type, const G4double kineticEnergy, const G4double impactParameter, const G4double phi) {
182 theNucleus->setParticleNucleusCollision();
183 currentTime = 0.0;
184
185 // Create the projectile particle
186 const G4double projectileMass = ParticleTable::getTableParticleMass(type);
187 G4double energy = kineticEnergy + projectileMass;
188 G4double momentumZ = std::sqrt(energy*energy - projectileMass*projectileMass);
189 ThreeVector momentum(0.0, 0.0, momentumZ);
190 Particle *p= new G4INCL::Particle(type, energy, momentum, ThreeVector());
191
192 G4double temfin;
193 G4double TLab;
194 if( p->isMeson()) {
195 temfin = 30.18 * std::pow(theNucleus->getA(), 0.17);
196 TLab = p->getKineticEnergy();
197 } else {
198 temfin = 29.8 * std::pow(theNucleus->getA(), 0.16);
199 TLab = p->getKineticEnergy()/p->getA();
200 }
201
202 // energy-dependent stopping time above 2 AGeV
203 if(TLab>2000.)
204 temfin *= (5.8E4-TLab)/5.6E4;
205
206 maximumTime = temfin;
207
208 // If the incoming particle is slow, use a larger stopping time
209 const G4double rMax = theNucleus->getUniverseRadius();
210 const G4double distance = 2.*rMax;
211 const G4double projectileVelocity = p->boostVector().mag();
212 const G4double traversalTime = distance / projectileVelocity;
213 if(maximumTime < traversalTime)
214 maximumTime = traversalTime;
215 INCL_DEBUG("Cascade stopping time is " << maximumTime << '\n');
216
217 // If Coulomb is activated, do not process events with impact
218 // parameter larger than the maximum impact parameter, taking into
219 // account Coulomb distortion.
220 if(impactParameter>CoulombDistortion::maxImpactParameter(p->getSpecies(), kineticEnergy, theNucleus)) {
221 INCL_DEBUG("impactParameter>CoulombDistortion::maxImpactParameter" << '\n');
222 delete p;
223 return -1.;
224 }
225
226 ThreeVector position(impactParameter * std::cos(phi),
227 impactParameter * std::sin(phi),
228 0.);
230
231 // Fill in the relevant kinematic variables
233 theNucleus->setIncomingMomentum(p->getMomentum());
234 theNucleus->setInitialEnergy(p->getEnergy()
235 + ParticleTable::getTableMass(theNucleus->getA(),theNucleus->getZ(),theNucleus->getS()));
236
237 // Reset the particle kinematics to the INCL values
238 p->setINCLMass();
239 p->setEnergy(p->getMass() + kineticEnergy);
241
244 firstAvatar = false;
245
246 // Get the entry avatars from Coulomb and put them in the Store
247 ParticleEntryAvatar *theEntryAvatar = CoulombDistortion::bringToSurface(p, theNucleus);
248 if(theEntryAvatar) {
249 theNucleus->getStore()->addParticleEntryAvatar(theEntryAvatar);
250
251 return p->getTransversePosition().mag();
252 } else {
253 delete p;
254 return -1.;
255 }
256 }
257
258 G4double StandardPropagationModel::shootComposite(ParticleSpecies const &species, const G4double kineticEnergy, const G4double impactParameter, const G4double phi) {
259 theNucleus->setNucleusNucleusCollision();
260 currentTime = 0.0;
261
262 // Create the ProjectileRemnant object
263 ProjectileRemnant *pr = new ProjectileRemnant(species, kineticEnergy);
264
265 // Same stopping time as for nucleon-nucleus
266 maximumTime = 29.8 * std::pow(theNucleus->getA(), 0.16);
267
268 // If the incoming cluster is slow, use a larger stopping time
270 const G4double rMax = theNucleus->getUniverseRadius();
271 const G4double distance = 2.*rMax + 2.725*rms;
272 const G4double projectileVelocity = pr->boostVector().mag();
273 const G4double traversalTime = distance / projectileVelocity;
274 if(maximumTime < traversalTime)
275 maximumTime = traversalTime;
276 INCL_DEBUG("Cascade stopping time is " << maximumTime << '\n');
277
278 // If Coulomb is activated, do not process events with impact
279 // parameter larger than the maximum impact parameter, taking into
280 // account Coulomb distortion.
281 if(impactParameter>CoulombDistortion::maxImpactParameter(pr,theNucleus)) {
282 INCL_DEBUG("impactParameter>CoulombDistortion::maxImpactParameter" << '\n');
283 delete pr;
284 return -1.;
285 }
286
287 // Position the cluster at the right impact parameter
288 ThreeVector position(impactParameter * std::cos(phi),
289 impactParameter * std::sin(phi),
290 0.);
292
293 // Fill in the relevant kinematic variables
295 theNucleus->setIncomingMomentum(pr->getMomentum());
296 theNucleus->setInitialEnergy(pr->getEnergy()
297 + ParticleTable::getTableMass(theNucleus->getA(),theNucleus->getZ(),theNucleus->getS()));
298
300 firstAvatar = false;
301
302 // Get the entry avatars from Coulomb
303 IAvatarList theAvatarList
304 = CoulombDistortion::bringToSurface(pr, theNucleus);
305
306 if(theAvatarList.empty()) {
307 INCL_DEBUG("No ParticleEntryAvatar found, transparent event" << '\n');
308 delete pr;
309 return -1.;
310 }
311
312 /* Store the internal kinematics of the projectile remnant.
313 *
314 * Note that this is at variance with the Fortran version, which stores
315 * the initial kinematics of the particles *after* putting the spectators
316 * on mass shell, but *before* removing the same energy from the
317 * participants. Due to the different code flow, doing so in the C++
318 * version leads to wrong excitation energies for the forced compound
319 * nucleus.
320 */
321 pr->storeComponents();
322
323 // Tell the Nucleus about the ProjectileRemnant
324 theNucleus->setProjectileRemnant(pr);
325
326 // Register the ParticleEntryAvatars
327 theNucleus->getStore()->addParticleEntryAvatars(theAvatarList);
328
329 return pr->getTransversePosition().mag();
330 }
331
333 return maximumTime;
334 }
335
337// assert(time>0.0);
338 maximumTime = time;
339 }
340
342 return currentTime;
343 }
344
346 {
347 theNucleus = nucleus;
348 }
349
351 {
352 if(anAvatar) theNucleus->getStore()->add(anAvatar);
353 }
354
356 // Is either particle a participant?
357 if(!p1->isParticipant() && !p2->isParticipant() && p1->getParticipantType()==p2->getParticipantType()) return NULL;
358
359 // Is it a pi-resonance collision (we don't treat them)?
360 if((p1->isResonance() && p2->isPion()) || (p1->isPion() && p2->isResonance()))
361 return NULL;
362
363 // Is it a photon collision (we don't treat them)?
364 if(p1->isPhoton() || p2->isPhoton())
365 return NULL;
366
367 // Will the avatar take place between now and the end of the cascade?
368 G4double minDistOfApproachSquared = 0.0;
369 G4double t = getTime(p1, p2, &minDistOfApproachSquared);
370 if(t>maximumTime || t<currentTime+hadronizationTime) return NULL;
371
372 // Local energy. Jump through some hoops to calculate the cross section
373 // at the collision point, and clean up after yourself afterwards.
374 G4bool hasLocalEnergy;
375 if(p1->isPion() || p2->isPion())
376 hasLocalEnergy = ((theLocalEnergyDeltaType == FirstCollisionLocalEnergy &&
377 theNucleus->getStore()->getBook().getAcceptedCollisions()==0) ||
378 theLocalEnergyDeltaType == AlwaysLocalEnergy);
379 else
380 hasLocalEnergy = ((theLocalEnergyType == FirstCollisionLocalEnergy &&
381 theNucleus->getStore()->getBook().getAcceptedCollisions()==0) ||
382 theLocalEnergyType == AlwaysLocalEnergy);
383 const G4bool p1HasLocalEnergy = (hasLocalEnergy && !p1->isMeson() && !p1->isAntiNucleon());
384 const G4bool p2HasLocalEnergy = (hasLocalEnergy && !p2->isMeson() && !p2->isAntiNucleon());
385
386 if(p1HasLocalEnergy) {
387 backupParticle1 = *p1;
388 p1->propagate(t - currentTime);
389 if(p1->getPosition().mag() > theNucleus->getSurfaceRadius(p1)) {
390 *p1 = backupParticle1;
391 return NULL;
392 }
394 }
395 if(p2HasLocalEnergy) {
396 backupParticle2 = *p2;
397 p2->propagate(t - currentTime);
398 if(p2->getPosition().mag() > theNucleus->getSurfaceRadius(p2)) {
399 *p2 = backupParticle2;
400 if(p1HasLocalEnergy) {
401 *p1 = backupParticle1;
402 }
403 return NULL;
404 }
406 }
407
408 // Compute the total cross section
409 const G4double totalCrossSection = CrossSections::total(p1, p2);
410 const G4double squareTotalEnergyInCM = KinematicsUtils::squareTotalEnergyInCM(p1,p2);
411
412 // Restore particles to their state before the local-energy tweak
413 if(p1HasLocalEnergy) {
414 *p1 = backupParticle1;
415 }
416 if(p2HasLocalEnergy) {
417 *p2 = backupParticle2;
418 }
419
420 // Is the CM energy > cutNN? (no cutNN on the first collision)
421 if(theNucleus->getStore()->getBook().getAcceptedCollisions()>0
422 && p1->isNucleon() && p2->isNucleon()
423 && squareTotalEnergyInCM < BinaryCollisionAvatar::getCutNNSquared()) return NULL;
424
425 // Do the particles come close enough to each other?
426 if(Math::tenPi*minDistOfApproachSquared > totalCrossSection) return NULL;
427
428 // Bomb out if the two collision partners are the same particle
429// assert(p1->getID() != p2->getID());
430
431 // Return a new avatar, then!
432 return new G4INCL::BinaryCollisionAvatar(t, totalCrossSection, theNucleus, p1, p2);
433 }
434
436 Intersection theIntersection(
438 aParticle->getPosition(),
439 aParticle->getPropagationVelocity(),
440 theNucleus->getSurfaceRadius(aParticle)));
441 G4double time;
442 if(theIntersection.exists) {
443 time = currentTime + theIntersection.time;
444 } else {
445 INCL_ERROR("Imaginary reflection time for particle: " << '\n'
446 << aParticle->print());
447 time = 10000.0;
448 }
449 return time;
450 }
451
453 G4INCL::Particle const * const particleB, G4double *minDistOfApproach) const
454 {
455 G4double time;
457 t13 -= particleB->getPropagationVelocity();
458 G4INCL::ThreeVector distance = particleA->getPosition();
459 distance -= particleB->getPosition();
460 const G4double t7 = t13.dot(distance);
461 const G4double dt = t13.mag2();
462 if(dt <= 1.0e-10) {
463 (*minDistOfApproach) = 100000.0;
464 return currentTime + 100000.0;
465 } else {
466 time = -t7/dt;
467 }
468 (*minDistOfApproach) = distance.mag2() + time * t7;
469 return currentTime + time;
470 }
471
472 void StandardPropagationModel::generateUpdatedCollisions(const ParticleList &updatedParticles, const ParticleList &particles) {
473
474 // Loop over all the updated particles
475 for(ParticleIter updated=updatedParticles.begin(), e=updatedParticles.end(); updated!=e; ++updated)
476 {
477 // Loop over all the particles
478 for(ParticleIter particle=particles.begin(), end=particles.end(); particle!=end; ++particle)
479 {
480 /* Consider the generation of a collision avatar only if (*particle)
481 * is not one of the updated particles.
482 * The criterion makes sure that you don't generate avatars between
483 * updated particles. */
484 if(updatedParticles.contains(*particle)) continue;
485
487 }
488 }
489 }
490
492 // Loop over all the particles
493 for(ParticleIter p1=particles.begin(), e=particles.end(); p1!=e; ++p1) {
494 // Loop over the rest of the particles
495 for(ParticleIter p2 = p1 + 1; p2 != particles.end(); ++p2) {
497 }
498 }
499 }
500
502
503 const G4bool haveExcept = !except.empty();
504
505 // Loop over all the particles
506 for(ParticleIter p1=particles.begin(), e=particles.end(); p1!=e; ++p1)
507 {
508 // Loop over the rest of the particles
509 ParticleIter p2 = p1;
510 for(++p2; p2 != particles.end(); ++p2)
511 {
512 // Skip the collision if both particles must be excluded
513 if(haveExcept && except.contains(*p1) && except.contains(*p2)) continue;
514
516 }
517 }
518
519 }
520
522
523 for(ParticleIter iter=particles.begin(), e=particles.end(); iter!=e; ++iter) {
524 G4double time = this->getReflectionTime(*iter);
525 if(time <= maximumTime) registerAvatar(new SurfaceAvatar(*iter, time, theNucleus));
526 }
527 ParticleList const &p = theNucleus->getStore()->getParticles();
528 generateUpdatedCollisions(particles, p); // Predict collisions with spectators and participants
529 }
530
532 ParticleList const &particles = theNucleus->getStore()->getParticles();
533// assert(!particles.empty());
534 G4double time;
535 for(ParticleIter i=particles.begin(), e=particles.end(); i!=e; ++i) {
536 time = this->getReflectionTime(*i);
537 if(time <= maximumTime) registerAvatar(new SurfaceAvatar(*i, time, theNucleus));
538 }
539 generateCollisions(particles);
540 generateDecays(particles);
541 }
542
543#ifdef INCL_REGENERATE_AVATARS
544 void StandardPropagationModel::generateAllAvatarsExceptUpdated(FinalState const * const fs) {
545 ParticleList const &particles = theNucleus->getStore()->getParticles();
546// assert(!particles.empty());
547 for(ParticleIter i=particles.begin(), e=particles.end(); i!=e; ++i) {
548 G4double time = this->getReflectionTime(*i);
549 if(time <= maximumTime) registerAvatar(new SurfaceAvatar(*i, time, theNucleus));
550 }
551 ParticleList except = fs->getModifiedParticles();
552 ParticleList const &entering = fs->getEnteringParticles();
553 except.insert(except.end(), entering.begin(), entering.end());
554 generateCollisions(particles,except);
555 generateDecays(particles);
556 }
557#endif
558
560 for(ParticleIter i=particles.begin(), e=particles.end(); i!=e; ++i) {
561 if((*i)->isDelta()) {
562 G4double decayTime = DeltaDecayChannel::computeDecayTime((*i)); // time in fm/c
563 G4double time = currentTime + decayTime;
564 if(time <= maximumTime) {
565 registerAvatar(new DecayAvatar((*i), time, theNucleus));
566 }
567 }
568 else if((*i)->getType() == SigmaZero) {
569 G4double decayTime = SigmaZeroDecayChannel::computeDecayTime((*i)); // time in fm/c
570 G4double time = currentTime + decayTime;
571 if(time <= maximumTime) {
572 registerAvatar(new DecayAvatar((*i), time, theNucleus));
573 }
574 }
575 if((*i)->isOmega()) {
577 G4double timeOmega = currentTime + decayTimeOmega;
578 if(timeOmega <= maximumTime) {
579 registerAvatar(new DecayAvatar((*i), timeOmega, theNucleus));
580 }
581 }
582 }
583 }
584
586 {
587 if(fs) {
588 // We update only the information related to particles that were updated
589 // by the previous avatar.
590#ifdef INCL_REGENERATE_AVATARS
591#warning "The INCL_REGENERATE_AVATARS code has not been tested in a while. Use it at your peril."
592 if(!fs->getModifiedParticles().empty() || !fs->getEnteringParticles().empty() || !fs->getCreatedParticles().empty()) {
593 // Regenerates the entire avatar list, skipping collisions between
594 // updated particles
595 theNucleus->getStore()->clearAvatars();
596 theNucleus->getStore()->initialiseParticleAvatarConnections();
597 generateAllAvatarsExceptUpdated(fs);
598 }
599#else
600 ParticleList const &updatedParticles = fs->getModifiedParticles();
601 if(fs->getValidity()==PauliBlockedFS) {
602 // This final state might represents the outcome of a Pauli-blocked delta
603 // decay
604// assert(updatedParticles.empty() || (updatedParticles.size()==1 && updatedParticles.front()->isResonance()));
605// assert(fs->getEnteringParticles().empty() && fs->getCreatedParticles().empty() && fs->getOutgoingParticles().empty() && fs->getDestroyedParticles().empty());
606 generateDecays(updatedParticles);
607 } else {
608 ParticleList const &entering = fs->getEnteringParticles();
609 generateDecays(updatedParticles);
610 generateDecays(entering);
611
612 ParticleList const &created = fs->getCreatedParticles();
613 if(created.empty() && entering.empty())
614 updateAvatars(updatedParticles);
615 else {
616 ParticleList updatedParticlesCopy = updatedParticles;
617 updatedParticlesCopy.insert(updatedParticlesCopy.end(), entering.begin(), entering.end());
618 updatedParticlesCopy.insert(updatedParticlesCopy.end(), created.begin(), created.end());
619 updateAvatars(updatedParticlesCopy);
620 }
621 }
622#endif
623 }
624
625 G4INCL::IAvatar *theAvatar = theNucleus->getStore()->findSmallestTime();
626 if(theAvatar == 0) return 0; // Avatar list is empty
627 // theAvatar->dispose();
628
629 if(theAvatar->getTime() < currentTime) {
630 INCL_ERROR("Avatar time = " << theAvatar->getTime() << ", currentTime = " << currentTime << '\n');
631 return 0;
632 } else if(theAvatar->getTime() > currentTime) {
633 theNucleus->getStore()->timeStep(theAvatar->getTime() - currentTime);
634
635 currentTime = theAvatar->getTime();
636 theNucleus->getStore()->getBook().setCurrentTime(currentTime);
637 }
638
639 return theAvatar;
640 }
641}
Static class for selecting Coulomb distortion.
Simple class for computing intersections between a straight line and a sphere.
#define INCL_ERROR(x)
#define INCL_DEBUG(x)
double G4double
Definition G4Types.hh:83
bool G4bool
Definition G4Types.hh:86
void setCurrentTime(G4double t)
Definition G4INCLBook.hh:97
G4int getAcceptedCollisions() const
G4INCL::ThreeVector getAngularMomentum() const
Get the total angular momentum (orbital + spin)
void setPosition(const ThreeVector &position)
Set the position of the cluster.
static G4double computeDecayTime(Particle *p)
ParticleList const & getEnteringParticles() const
ParticleList const & getModifiedParticles() const
FinalStateValidity getValidity() const
ParticleList const & getCreatedParticles() const
G4double getTime() const
Store * getStore() const
AnnihilationType getAnnihilationType() const
Getter for theAnnihilationType.
void setIncomingAngularMomentum(const ThreeVector &j)
Set the incoming angular-momentum vector.
void setInitialEnergy(const G4double e)
Set the initial energy.
G4double getSurfaceRadius(Particle const *const particle) const
Get the maximum allowed radius for a given particle.
void setIncomingMomentum(const ThreeVector &p)
Set the incoming momentum vector.
void setParticleNucleusCollision()
Set a particle-nucleus collision.
void setNucleusNucleusCollision()
Set a nucleus-nucleus collision.
void setProjectileRemnant(ProjectileRemnant *const c)
Set the projectile remnant.
G4double getUniverseRadius() const
Getter for theUniverseRadius.
ThreeVector boostVector() const
virtual G4INCL::ParticleSpecies getSpecies() const
Get the particle species.
G4bool isPhoton() const
Is this a photon?
G4int getS() const
Returns the strangeness number.
G4bool isMeson() const
Is this a Meson?
virtual G4INCL::ThreeVector getAngularMomentum() const
G4double getEnergy() const
ParticipantType getParticipantType() const
ThreeVector getPropagationVelocity() const
Get the propagation velocity of the particle.
void propagate(G4double step)
G4int getZ() const
Returns the charge number.
const G4INCL::ThreeVector & getPosition() const
G4bool isParticipant() const
G4double getKineticEnergy() const
Get the particle kinetic energy.
G4bool isAntiNucleon() const
Is this an antinucleon?
virtual void makeProjectileSpectator()
const ThreeVector & adjustMomentumFromEnergy()
Rescale the momentum to match the total energy.
G4bool isPion() const
Is this a pion?
void setINCLMass()
Set the mass of the Particle to its table mass.
const G4INCL::ThreeVector & getMomentum() const
G4bool isResonance() const
Is it a resonance?
void setEnergy(G4double energy)
std::string print() const
ThreeVector getTransversePosition() const
Transverse component of the position w.r.t. the momentum.
G4double getMass() const
Get the cached particle mass.
virtual void setPosition(const G4INCL::ThreeVector &position)
G4int getA() const
Returns the baryon number.
G4bool isNucleon() const
IAvatarList bringMesonStar(ParticleList const &pL, Nucleus *const n)
void storeComponents()
Store the projectile components.
static G4double computeDecayTime(Particle *p)
G4double getReflectionTime(G4INCL::Particle const *const aParticle)
Get the reflection time.
G4INCL::IAvatar * propagate(FinalState const *const fs)
G4double getTime(G4INCL::Particle const *const particleA, G4INCL::Particle const *const particleB, G4double *minDistOfApproach) const
void generateCollisions(const ParticleList &particles)
Generate and register collisions among particles in a list, except between those in another list.
G4double shootAtrest(ParticleType const t, const G4double kineticEnergy)
StandardPropagationModel(LocalEnergyType localEnergyType, LocalEnergyType localEnergyDeltaType, const G4double hTime=0.0)
void registerAvatar(G4INCL::IAvatar *anAvatar)
void updateAvatars(const ParticleList &particles)
void generateAllAvatars()
(Re)Generate all possible avatars.
G4double shoot(ParticleSpecies const &projectileSpecies, const G4double kineticEnergy, const G4double impactParameter, const G4double phi)
IAvatar * generateBinaryCollisionAvatar(Particle *const p1, Particle *const p2)
Generate a two-particle avatar.
void generateUpdatedCollisions(const ParticleList &updatedParticles, const ParticleList &particles)
Generate and register collisions between a list of updated particles and all the other particles.
G4double shootComposite(ParticleSpecies const &s, const G4double kineticEnergy, const G4double impactParameter, const G4double phi)
void generateDecays(const ParticleList &particles)
Generate decays for particles that can decay.
G4double shootParticle(ParticleType const t, const G4double kineticEnergy, const G4double impactParameter, const G4double phi)
void clearAvatars()
void addParticleEntryAvatars(IAvatarList const &al)
Add one ParticleEntry avatar.
void timeStep(G4double step)
IAvatar * findSmallestTime()
void add(Particle *p)
Book & getBook()
ParticleList const & getParticles() const
void addParticleEntryAvatar(IAvatar *a)
Add one ParticleEntry avatar.
G4double dot(const ThreeVector &v) const
G4double mag2() const
G4bool contains(const T &t) const
ParticleEntryAvatar * bringToSurface(Particle *p, Nucleus *const n)
Modify the momentum of an incoming particle and position it on the surface of the nucleus.
G4double maxImpactParameter(ParticleSpecies const &p, const G4double kinE, Nucleus const *const n)
Return the maximum impact parameter for Coulomb-distorted trajectories.
G4double total(Particle const *const p1, Particle const *const p2)
Intersection getLaterTrajectoryIntersection(const ThreeVector &x0, const ThreeVector &p, const G4double r)
Compute the second intersection of a straight particle trajectory with a sphere.
G4double squareTotalEnergyInCM(Particle const *const p1, Particle const *const p2)
void transformToLocalEnergyFrame(Nucleus const *const n, Particle *const p)
const G4double tenPi
G4ThreadLocal NuclearMassFn getTableMass
Static pointer to the mass function for nuclei.
G4ThreadLocal ParticleMassFn getTableParticleMass
Static pointer to the mass function for particles.
G4double getLargestNuclearRadius(const G4int A, const G4int Z)
ParticleList::const_iterator ParticleIter
@ FirstCollisionLocalEnergy
Intersection-point structure.