Geant4  10.01.p02
G4INCLCascade.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 
42 #include "G4INCLCascade.hh"
43 #include "G4INCLRandom.hh"
45 #include "G4INCLParticleTable.hh"
47 #include "G4INCLGlobalInfo.hh"
48 
49 #include "G4INCLPauliBlocking.hh"
50 
51 #include "G4INCLCrossSections.hh"
52 
54 
55 #include "G4INCLLogger.hh"
56 #include "G4INCLGlobals.hh"
58 
60 
62 
63 #include "G4INCLClustering.hh"
64 
65 #include "G4INCLIntersection.hh"
66 
68 
69 #include "G4INCLCascadeAction.hh"
71 
72 #include <cstring>
73 #include <cstdlib>
74 #include <numeric>
75 
76 namespace G4INCL {
77 
78  INCL::INCL(Config const * const config)
79  :propagationModel(0), theA(208), theZ(82),
80  targetInitSuccess(false),
82  maxUniverseRadius(0.),
83  maxInteractionDistance(0.),
84  fixedImpactParameter(0.),
85  theConfig(config),
86  nucleus(NULL),
87  forceTransparent(false),
88  minRemnantSize(4)
89  {
90  // Set the logger object.
91 #ifdef INCLXX_IN_GEANT4_MODE
93 #else // INCLXX_IN_GEANT4_MODE
95 #endif // INCLXX_IN_GEANT4_MODE
96 
97  // Set the random number generator algorithm. The system can support
98  // multiple different generator algorithms in a completely
99  // transparent way.
101 
102  // Select the Pauli and CDPP blocking algorithms
104 
105  // Set the cross-section set
107 
108  // Set the phase-space generator
110 
111  // Select the Coulomb-distortion algorithm:
113 
114  // Select the clustering algorithm:
116 
117  // Initialize the INCL particle table:
119 
120  // Initialize the value of cutNN in BinaryCollisionAvatar
122 
123  // Propagation model is responsible for finding avatars and
124  // transporting the particles. In principle this step is "hidden"
125  // behind an abstract interface and the rest of the system does not
126  // care how the transportation and avatar finding is done. This
127  // should allow us to "easily" experiment with different avatar
128  // finding schemes and even to support things like curved
129  // trajectories in the future.
133  else
136 
139 #ifdef INCL_ROOT_USE
140  theGlobalInfo.rootSelection = theConfig->getROOTSelectionString();
141 #endif
142 
143 #ifndef INCLXX_IN_GEANT4_MODE
144  // Fill in the global information
147  const ParticleSpecies theSpecies = theConfig->getProjectileSpecies();
148  theGlobalInfo.Ap = theSpecies.theA;
149  theGlobalInfo.Zp = theSpecies.theZ;
151 #endif
152 
154  }
155 
158 #ifndef INCLXX_IN_GEANT4_MODE
159  NuclearMassTable::deleteTable();
160 #endif
167 #ifndef INCLXX_IN_GEANT4_MODE
168  Logger::deleteLoggerSlave();
169 #endif
173  delete cascadeAction;
174  delete propagationModel;
175  delete theConfig;
176  }
177 
178  G4bool INCL::prepareReaction(const ParticleSpecies &projectileSpecies, const G4double kineticEnergy, const G4int A, const G4int Z) {
179  if(A < 0 || A > 300 || Z < 1 || Z > 200) {
180  INCL_ERROR("Unsupported target: A = " << A << " Z = " << Z << '\n'
181  << "Target configuration rejected." << '\n');
182  return false;
183  }
184  if(projectileSpecies.theType==Composite &&
185  (projectileSpecies.theZ==projectileSpecies.theA || projectileSpecies.theZ==0)) {
186  INCL_ERROR("Unsupported projectile: A = " << projectileSpecies.theA << " Z = " << projectileSpecies.theZ << '\n'
187  << "Projectile configuration rejected." << '\n');
188  return false;
189  }
190 
191  // Reset the forced-transparent flag
192  forceTransparent = false;
193 
194  // Initialise the maximum universe radius
195  initUniverseRadius(projectileSpecies, kineticEnergy, A, Z);
196 
197  // Initialise the nucleus
198  theZ = Z;
201  else
202  theA = A;
204 
205  // Set the maximum impact parameter
206  maxImpactParameter = CoulombDistortion::maxImpactParameter(projectileSpecies, kineticEnergy, nucleus);
207  INCL_DEBUG("Maximum impact parameter initialised: " << maxImpactParameter << '\n');
208 
209  // For forced CN events
210  initMaxInteractionDistance(projectileSpecies, kineticEnergy);
211 
212  // Set the geometric cross section
214  Math::tenPi*std::pow(maxImpactParameter,2);
215 
216  // Set the minimum remnant size
217  if(projectileSpecies.theA > 0)
219  else
220  minRemnantSize = std::min(theA-1, 4);
221 
222  return true;
223  }
224 
226  delete nucleus;
227 
229  nucleus->getStore()->getBook().reset();
231 
233  return true;
234  }
235 
237  ParticleSpecies const &projectileSpecies,
238  const G4double kineticEnergy,
239  const G4int targetA,
240  const G4int targetZ
241  ) {
242  // Set the target and the projectile
243  targetInitSuccess = prepareReaction(projectileSpecies, kineticEnergy, targetA, targetZ);
244 
245  if(!targetInitSuccess) {
246  INCL_WARN("Target initialisation failed for A=" << targetA << ", Z=" << targetZ << '\n');
248  return theEventInfo;
249  }
250 
252 
253  const G4bool canRunCascade = preCascade(projectileSpecies, kineticEnergy);
254  if(canRunCascade) {
255  cascade();
256  postCascade();
258  }
260  return theEventInfo;
261  }
262 
263  G4bool INCL::preCascade(ParticleSpecies const &projectileSpecies, const G4double kineticEnergy) {
264  // Reset theEventInfo
266 
268 
269  // Fill in the event information
270  theEventInfo.projectileType = projectileSpecies.theType;
271  theEventInfo.Ap = projectileSpecies.theA;
272  theEventInfo.Zp = projectileSpecies.theZ;
273  theEventInfo.Ep = kineticEnergy;
276 
277  // Do nothing below the Coulomb barrier
278  if(maxImpactParameter<=0.) {
279  // Fill in the event information
280  theEventInfo.transparent = true;
281 
282  return false;
283  }
284 
285  // Randomly draw an impact parameter or use a fixed value, depending on the
286  // Config option
287  G4double impactParameter, phi;
288  if(fixedImpactParameter<0.) {
289  impactParameter = maxImpactParameter * std::sqrt(Random::shoot0());
290  phi = Random::shoot() * Math::twoPi;
291  } else {
292  impactParameter = fixedImpactParameter;
293  phi = 0.;
294  }
295  INCL_DEBUG("Selected impact parameter: " << impactParameter << '\n');
296 
297  // Fill in the event information
298  theEventInfo.impactParameter = impactParameter;
299 
300  const G4double effectiveImpactParameter = propagationModel->shoot(projectileSpecies, kineticEnergy, impactParameter, phi);
301  if(effectiveImpactParameter < 0.) {
302  // Fill in the event information
303  theEventInfo.transparent = true;
304 
305  return false;
306  }
307 
308  // Fill in the event information
309  theEventInfo.transparent = false;
310  theEventInfo.effectiveImpactParameter = effectiveImpactParameter;
311 
312  return true;
313  }
314 
315  void INCL::cascade() {
316  FinalState *finalState = new FinalState;
317 
318  do {
319  // Run book keeping actions that should take place before propagation:
321 
322  // Get the avatar with the smallest time and propagate particles
323  // to that point in time.
324  IAvatar *avatar = propagationModel->propagate(finalState);
325 
326  finalState->reset();
327 
328  // Run book keeping actions that should take place after propagation:
330 
331  if(avatar == 0) break; // No more avatars in the avatar list.
332 
333  // Run book keeping actions that should take place before avatar:
335 
336  // Channel is responsible for calculating the outcome of the
337  // selected avatar. There are different kinds of channels. The
338  // class IChannel is, again, an abstract interface that defines
339  // the externally observable behavior of all interaction
340  // channels.
341  // The handling of the channel is transparent to the API.
342  // Final state tells what changed...
343  avatar->fillFinalState(finalState);
344 
345  // Run book keeping actions that should take place after avatar:
346  cascadeAction->afterAvatarAction(avatar, nucleus, finalState);
347 
348  // So now we must give this information to the nucleus
349  nucleus->applyFinalState(finalState);
350  // and now we are ready to process the next avatar!
351 
352  delete avatar;
353  } while(continueCascade());
354 
355  delete finalState;
356  }
357 
359  // Fill in the event information
361 
362  // Forced CN?
364  INCL_DEBUG("Trying compound nucleus" << '\n');
367  // Global checks of conservation laws
368 #ifndef INCLXX_IN_GEANT4_MODE
369  if(!theEventInfo.transparent) globalConservationChecks(true);
370 #endif
371  return;
372  }
373 
375 
377  ProjectileRemnant * const projectileRemnant = nucleus->getProjectileRemnant();
378  if(projectileRemnant) {
379  // Clear the incoming list (particles will be deleted by the ProjectileRemnant)
381  } else {
382  // Delete particles in the incoming list
384  }
385  } else {
386  // Check if the nucleus contains deltas
388 
389  // Take care of any remaining deltas
392 
393  // Apply Coulomb distortion, if appropriate
394  // Note that this will apply Coulomb distortion also on pions emitted by
395  // unphysical remnants (see decayInsideDeltas). This is at variance with
396  // what INCL4.6 does, but these events are (should be!) so rare that
397  // whatever we do doesn't (shouldn't!) make any noticeable difference.
399 
400  // If the normal cascade predicted complete fusion, use the tabulated
401  // masses to compute the excitation energy, the recoil, etc.
402  if(nucleus->getStore()->getOutgoingParticles().size()==0
404  || nucleus->getProjectileRemnant()->getParticles().size()==0)) {
405 
406  INCL_DEBUG("Cascade resulted in complete fusion, using realistic fusion kinematics" << '\n');
407 
409 
410  if(nucleus->getExcitationEnergy()<0.) {
411  // Complete fusion is energetically impossible, return a transparent
412  INCL_WARN("Complete-fusion kinematics yields negative excitation energy, returning a transparent!" << '\n');
413  theEventInfo.transparent = true;
414  return;
415  }
416 
417  } else { // Normal cascade here
418 
419  // Set the excitation energy
421 
422  // Make a projectile pre-fragment out of the geometrical and dynamical
423  // spectators
425 
426  // Compute recoil momentum, energy and spin of the nucleus
427  if(nucleus->getA()==1 && minRemnantSize>1) {
428  INCL_ERROR("Computing one-nucleon recoil kinematics. We should never be here nowadays, cascade should stop earlier than this." << '\n');
429  }
431 
432 #ifndef INCLXX_IN_GEANT4_MODE
433  // Global checks of conservation laws
434  globalConservationChecks(false);
435 #endif
436 
437  // Make room for the remnant recoil by rescaling the energies of the
438  // outgoing particles.
440 
441  }
442 
443  // Cluster decay
445 
446 #ifndef INCLXX_IN_GEANT4_MODE
447  // Global checks of conservation laws
448  globalConservationChecks(true);
449 #endif
450 
451  // Fill the EventInfo structure
453 
454  }
455  }
456 
458  // If this is not a nucleus-nucleus collision, don't attempt to make a
459  // compound nucleus.
460  //
461  // Yes, even nucleon-nucleus collisions can lead to particles entering
462  // below the Fermi level. Take e.g. 1-MeV p + He4.
464  forceTransparent = true;
465  return;
466  }
467 
468  // Reset the internal Nucleus variables
474 
475  // CN kinematical variables
476  // Note: the CN orbital angular momentum is neglected in what follows. We
477  // should actually take it into account!
478  ThreeVector theCNMomentum = nucleus->getIncomingMomentum();
481  G4int theCNA=theEventInfo.At, theCNZ=theEventInfo.Zt;
482  Cluster * const theProjectileRemnant = nucleus->getProjectileRemnant();
483  G4double theCNEnergy = theTargetMass + theProjectileRemnant->getEnergy();
484 
485  // Loop over the potential participants
486  ParticleList const &initialProjectileComponents = theProjectileRemnant->getParticles();
487  std::vector<Particle *> shuffledComponents(initialProjectileComponents.begin(), initialProjectileComponents.end());
488  // Shuffle the list of potential participants
489  std::random_shuffle(shuffledComponents.begin(), shuffledComponents.end(), Random::getAdapter());
490 
491  G4bool success = true;
492  G4bool atLeastOneNucleonEntering = false;
493  for(std::vector<Particle*>::const_iterator p=shuffledComponents.begin(), e=shuffledComponents.end(); p!=e; ++p) {
494  // Skip particles that miss the interaction distance
496  (*p)->getPosition(),
497  (*p)->getPropagationVelocity(),
499  if(!intersectionInteractionDistance.exists)
500  continue;
501 
502  // Build an entry avatar for this nucleon
503  atLeastOneNucleonEntering = true;
504  ParticleEntryAvatar *theAvatar = new ParticleEntryAvatar(0.0, nucleus, *p);
505  nucleus->getStore()->addParticleEntryAvatar(theAvatar);
506  FinalState *fs = theAvatar->getFinalState();
508  FinalStateValidity validity = fs->getValidity();
509  delete fs;
510  switch(validity) {
511  case ValidFS:
513  case ParticleBelowZeroFS:
514  // Add the particle to the CN
515  theCNA++;
516  theCNZ += (*p)->getZ();
517  break;
518  case PauliBlockedFS:
520  default:
521  success = false;
522  break;
523  }
524  }
525 
526  if(!success || !atLeastOneNucleonEntering) {
527  INCL_DEBUG("No nucleon entering in forced CN, forcing a transparent" << '\n');
528  forceTransparent = true;
529  return;
530  }
531 
532 // assert(theCNA==nucleus->getA());
533 // assert(theCNA<=theEventInfo.At+theEventInfo.Ap);
534 // assert(theCNZ<=theEventInfo.Zt+theEventInfo.Zp);
535 
536  // Update the kinematics of the CN
537  theCNEnergy -= theProjectileRemnant->getEnergy();
538  theCNMomentum -= theProjectileRemnant->getMomentum();
539 
540  // Deal with the projectile remnant
542 
543  // Subtract the angular momentum of the projectile remnant
544 // assert(nucleus->getStore()->getOutgoingParticles().empty());
545  theCNSpin -= theProjectileRemnant->getAngularMomentum();
546 
547  // Compute the excitation energy of the CN
548  const G4double theCNMass = ParticleTable::getTableMass(theCNA,theCNZ);
549  const G4double theCNInvariantMassSquared = theCNEnergy*theCNEnergy-theCNMomentum.mag2();
550  if(theCNInvariantMassSquared<0.) {
551  // Negative invariant mass squared, return a transparent
552  forceTransparent = true;
553  return;
554  }
555  const G4double theCNExcitationEnergy = std::sqrt(theCNInvariantMassSquared) - theCNMass;
556  if(theCNExcitationEnergy<0.) {
557  // Negative excitation energy, return a transparent
558  INCL_DEBUG("CN excitation energy is negative, forcing a transparent" << '\n'
559  << " theCNA = " << theCNA << '\n'
560  << " theCNZ = " << theCNZ << '\n'
561  << " theCNEnergy = " << theCNEnergy << '\n'
562  << " theCNMomentum = (" << theCNMomentum.getX() << ", "<< theCNMomentum.getY() << ", " << theCNMomentum.getZ() << ")" << '\n'
563  << " theCNExcitationEnergy = " << theCNExcitationEnergy << '\n'
564  << " theCNSpin = (" << theCNSpin.getX() << ", "<< theCNSpin.getY() << ", " << theCNSpin.getZ() << ")" << '\n'
565  );
566  forceTransparent = true;
567  return;
568  } else {
569  // Positive excitation energy, can make a CN
570  INCL_DEBUG("CN excitation energy is positive, forcing a CN" << '\n'
571  << " theCNA = " << theCNA << '\n'
572  << " theCNZ = " << theCNZ << '\n'
573  << " theCNEnergy = " << theCNEnergy << '\n'
574  << " theCNMomentum = (" << theCNMomentum.getX() << ", "<< theCNMomentum.getY() << ", " << theCNMomentum.getZ() << ")" << '\n'
575  << " theCNExcitationEnergy = " << theCNExcitationEnergy << '\n'
576  << " theCNSpin = (" << theCNSpin.getX() << ", "<< theCNSpin.getY() << ", " << theCNSpin.getZ() << ")" << '\n'
577  );
578  nucleus->setA(theCNA);
579  nucleus->setZ(theCNZ);
580  nucleus->setMomentum(theCNMomentum);
581  nucleus->setEnergy(theCNEnergy);
582  nucleus->setExcitationEnergy(theCNExcitationEnergy);
583  nucleus->setMass(theCNMass+theCNExcitationEnergy);
584  nucleus->setSpin(theCNSpin); // neglects any orbital angular momentum of the CN
585 
586  // Take care of any remaining deltas
588 
589  // Cluster decay
591 
592  // Fill the EventInfo structure
594  }
595  }
596 
598  RecoilCMFunctor theRecoilFunctor(nucleus, theEventInfo);
599 
600  // Apply the root-finding algorithm
601  const RootFinder::Solution theSolution = RootFinder::solve(&theRecoilFunctor, 1.0);
602  if(theSolution.success) {
603  theRecoilFunctor(theSolution.x); // Apply the solution
604  } else {
605  INCL_WARN("Couldn't accommodate remnant recoil while satisfying energy conservation, root-finding algorithm failed." << '\n');
606  }
607 
608  }
609 
610 #ifndef INCLXX_IN_GEANT4_MODE
611  void INCL::globalConservationChecks(G4bool afterRecoil) {
613 
614  // Global conservation checks
615  const G4double pLongBalance = theBalance.momentum.getZ();
616  const G4double pTransBalance = theBalance.momentum.perp();
617  if(theBalance.Z != 0) {
618  INCL_ERROR("Violation of charge conservation! ZBalance = " << theBalance.Z << '\n');
619  }
620  if(theBalance.A != 0) {
621  INCL_ERROR("Violation of baryon-number conservation! ABalance = " << theBalance.A << '\n');
622  }
623  G4double EThreshold, pLongThreshold, pTransThreshold;
624  if(afterRecoil) {
625  // Less stringent checks after accommodating recoil
626  EThreshold = 10.; // MeV
627  pLongThreshold = 1.; // MeV/c
628  pTransThreshold = 1.; // MeV/c
629  } else {
630  // More stringent checks before accommodating recoil
631  EThreshold = 0.1; // MeV
632  pLongThreshold = 0.1; // MeV/c
633  pTransThreshold = 0.1; // MeV/c
634  }
635  if(std::abs(theBalance.energy)>EThreshold) {
636  INCL_WARN("Violation of energy conservation > " << EThreshold << " MeV. EBalance = " << theBalance.energy << " afterRecoil = " << afterRecoil << " eventNumber=" << theEventInfo.eventNumber << '\n');
637  }
638  if(std::abs(pLongBalance)>pLongThreshold) {
639  INCL_WARN("Violation of longitudinal momentum conservation > " << pLongThreshold << " MeV/c. pLongBalance = " << pLongBalance << " afterRecoil = " << afterRecoil << " eventNumber=" << theEventInfo.eventNumber << '\n');
640  }
641  if(std::abs(pTransBalance)>pTransThreshold) {
642  INCL_WARN("Violation of transverse momentum conservation > " << pTransThreshold << " MeV/c. pTransBalance = " << pTransBalance << " afterRecoil = " << afterRecoil << " eventNumber=" << theEventInfo.eventNumber << '\n');
643  }
644 
645  // Feed the EventInfo variables
646  theEventInfo.EBalance = theBalance.energy;
647  theEventInfo.pLongBalance = pLongBalance;
648  theEventInfo.pTransBalance = pTransBalance;
649  }
650 #endif
651 
653  // Stop if we have passed the stopping time
655  INCL_DEBUG("Cascade time (" << propagationModel->getCurrentTime()
656  << ") exceeded stopping time (" << propagationModel->getStoppingTime()
657  << "), stopping cascade" << '\n');
658  return false;
659  }
660  // Stop if there are no participants and no pions inside the nucleus
661  if(nucleus->getStore()->getBook().getCascading()==0 &&
662  nucleus->getStore()->getIncomingParticles().empty()) {
663  INCL_DEBUG("No participants in the nucleus and no incoming particles left, stopping cascade" << '\n');
664  return false;
665  }
666  // Stop if the remnant is smaller than minRemnantSize
667  if(nucleus->getA() <= minRemnantSize) {
668  INCL_DEBUG("Remnant size (" << nucleus->getA()
669  << ") smaller than or equal to minimum (" << minRemnantSize
670  << "), stopping cascade" << '\n');
671  return false;
672  }
673  // Stop if we have to try and make a compound nucleus or if we have to
674  // force a transparent
676  INCL_DEBUG("Trying to make a compound nucleus, stopping cascade" << '\n');
677  return false;
678  }
679 
680  return true;
681  }
682 
683  void INCL::finalizeGlobalInfo(Random::SeedVector const &initialSeeds) {
684  const G4double normalisationFactor = theGlobalInfo.geometricCrossSection /
686  theGlobalInfo.nucleonAbsorptionCrossSection = normalisationFactor *
688  theGlobalInfo.pionAbsorptionCrossSection = normalisationFactor *
690  theGlobalInfo.reactionCrossSection = normalisationFactor *
692  theGlobalInfo.errorReactionCrossSection = normalisationFactor *
694  theGlobalInfo.forcedCNCrossSection = normalisationFactor *
696  theGlobalInfo.errorForcedCNCrossSection = normalisationFactor *
698  theGlobalInfo.completeFusionCrossSection = normalisationFactor *
700  theGlobalInfo.errorCompleteFusionCrossSection = normalisationFactor *
701  std::sqrt((G4double) (theGlobalInfo.nCompleteFusion));
704 
705  theGlobalInfo.initialRandomSeeds.assign(initialSeeds.begin(), initialSeeds.end());
706 
708  theGlobalInfo.finalRandomSeeds.assign(theSeeds.begin(), theSeeds.end());
709  }
710 
712  // Do nothing if this is not a nucleus-nucleus reaction
714  return 0;
715 
716  // Get the spectators (geometrical+dynamical) from the Store
719 
720  G4int nUnmergedSpectators = 0;
721 
722  // If there are no spectators, do nothing
723  if(dynSpectators.empty() && geomSpectators.empty()) {
724  return 0;
725  } else if(dynSpectators.size()==1 && geomSpectators.empty()) {
726  // No geometrical spectators, one dynamical spectator
727  // Just put it back in the outgoing list
728  nucleus->getStore()->addToOutgoing(dynSpectators.front());
729  } else {
730  // Make a cluster out of the geometrical spectators
731  ProjectileRemnant *theProjectileRemnant = nucleus->getProjectileRemnant();
732 
733  // Add the dynamical spectators to the bunch
734  ParticleList rejected = theProjectileRemnant->addAllDynamicalSpectators(dynSpectators);
735  // Put back the rejected spectators into the outgoing list
736  nUnmergedSpectators = rejected.size();
737  nucleus->getStore()->addToOutgoing(rejected);
738 
739  // Deal with the projectile remnant
741 
742  }
743 
744  return nUnmergedSpectators;
745  }
746 
747  void INCL::initMaxInteractionDistance(ParticleSpecies const &projectileSpecies, const G4double kineticEnergy) {
748  if(projectileSpecies.theType != Composite) {
750  return;
751  }
752 
755 
756  const G4double theNNDistance = CrossSections::interactionDistanceNN(projectileSpecies, kineticEnergy);
757  maxInteractionDistance = r0 + theNNDistance;
758  INCL_DEBUG("Initialised interaction distance: r0 = " << r0 << '\n'
759  << " theNNDistance = " << theNNDistance << '\n'
760  << " maxInteractionDistance = " << maxInteractionDistance << '\n');
761  }
762 
763  void INCL::initUniverseRadius(ParticleSpecies const &p, const G4double kineticEnergy, const G4int A, const G4int Z) {
764  G4double rMax = 0.0;
765  if(A==0) {
766  IsotopicDistribution const &anIsotopicDistribution =
768  IsotopeVector theIsotopes = anIsotopicDistribution.getIsotopes();
769  for(IsotopeIter i=theIsotopes.begin(), e=theIsotopes.end(); i!=e; ++i) {
770  const G4double pMaximumRadius = ParticleTable::getMaximumNuclearRadius(Proton, i->theA, Z);
771  const G4double nMaximumRadius = ParticleTable::getMaximumNuclearRadius(Neutron, i->theA, Z);
772  const G4double maximumRadius = std::min(pMaximumRadius, nMaximumRadius);
773  rMax = std::max(maximumRadius, rMax);
774  }
775  } else {
776  const G4double pMaximumRadius = ParticleTable::getMaximumNuclearRadius(Proton, A, Z);
777  const G4double nMaximumRadius = ParticleTable::getMaximumNuclearRadius(Neutron, A, Z);
778  rMax = std::min(pMaximumRadius, nMaximumRadius);
779  }
780  if(p.theType==Composite || p.theType==Proton || p.theType==Neutron) {
783  } else if(p.theType==PiPlus
784  || p.theType==PiZero
785  || p.theType==PiMinus) {
788  }
789  INCL_DEBUG("Initialised universe radius: " << maxUniverseRadius << '\n');
790  }
791 
793  // Increment the global counter for the number of shots
795 
797  // Increment the global counter for the number of transparents
799  // Increment the global counter for the number of forced transparents
800  if(forceTransparent)
802  return;
803  }
804 
805  // Check if we have an absorption:
808 
809  // Count complete-fusion events
811 
814 
815  // Counters for the number of violations of energy conservation in
816  // collisions
818  }
819 
820 }
Short_t Ap
Projectile mass number given as input.
Short_t Zp
Charge number of the projectile nucleus.
G4int getA() const
Returns the baryon number.
Float_t effectiveImpactParameter
Effective (Coulomb-distorted) impact parameter [fm].
G4double maxUniverseRadius
void fillFinalState(FinalState *fs)
G4bool targetInitSuccess
CascadeActionType getCascadeActionType() const
Get the cascade-action type.
ConservationBalance getConservationBalance(EventInfo const &theEventInfo, const G4bool afterRecoil) const
Compute charge, mass, energy and momentum balance.
void initializeParticles()
Call the Cluster method to generate the initial distribution of particles.
Float_t nucleonAbsorptionCrossSection
Nucleon absorption cross section.
G4int minRemnantSize
Remnant size below which cascade stops.
Bool_t nucleonAbsorption
True if the event is a nucleon absorption.
G4bool containsDeltas()
Returns true if the nucleus contains any deltas.
IsotopeVector::iterator IsotopeIter
The INCL configuration object.
Definition: G4INCLConfig.hh:60
void setMass(G4double mass)
Set the mass of the particle in MeV/c^2.
static void setCutNN(const G4double c)
FinalStateValidity getValidity() const
void deleteGenerator()
Delete the generator.
G4bool prepareReaction(const ParticleSpecies &projectileSpecies, const G4double kineticEnergy, const G4int A, const G4int Z)
G4bool continueCascade()
Stopping criterion for the cascade.
void cascade()
The actual cascade loop.
Float_t pLongBalance
Longitudinal momentum-conservation balance [MeV/c].
G4double maxInteractionDistance
Int_t nEnergyViolationInteraction
Number of attempted collisions/decays for which the energy-conservation algorithm failed to find a so...
void postCascade()
Finalise the cascade and clean up.
G4int getTargetZ() const
Get the target charge number.
Definition: G4INCLConfig.hh:97
G4bool preCascade(ParticleSpecies const &projectileSpecies, const G4double kineticEnergy)
Initialise the cascade.
Int_t nForcedCompoundNucleus
Number of forced compound-nucleus events.
const ThreeVector & getIncomingMomentum() const
Get the incoming momentum vector.
std::string cascadeModel
Name of the cascade model.
ParticleList const & getParticles() const
Get the list of particles in the cluster.
void beforeRunAction(Config const *config)
G4bool decayOutgoingClusters()
Force the decay of unstable outgoing clusters.
G4bool isNucleusNucleusCollision() const
Is it a nucleus-nucleus collision?
Abstract interface to the nuclear potential.
virtual G4INCL::IAvatar * propagate(FinalState const *const fs)=0
Propagate the particles and get the next avatar.
Float_t errorReactionCrossSection
Error on the calculated reaction cross section.
void beforeCascadeAction(IPropagationModel *)
const G4double tenPi
Config const *const theConfig
void applyFinalState(FinalState *)
Apply reaction final state information to the nucleus.
#define INCL_ERROR(x)
void updateGlobalInfo()
Update global counters and other members of theGlobalInfo object.
void setZ(const G4int Z)
Set the charge number of the cluster.
const G4INCL::ThreeVector & getMomentum() const
Get the momentum vector.
void initialize(Config const *const)
Initialize generator according to a Config object.
const ThreeVector & getIncomingAngularMomentum() const
Get the incoming angular-momentum vector.
Store * getStore() const
G4double interactionDistanceNN(const ParticleSpecies &aSpecies, const G4double kineticEnergy)
Compute the "interaction distance".
Float_t forcedCNCrossSection
Calculated forced-compound-nucleus cross section.
Float_t pionAbsorptionCrossSection
Pion absorption cross section.
std::vector< Int_t > finalRandomSeeds
Final seeds for the pseudo-random-number generator.
Bool_t forcedDeltasOutside
Event involved forced delta decays outside the nucleus.
G4double getEnergy() const
Get the energy of the particle in MeV.
Struct for conservation laws.
#define INCL_WARN(x)
Bool_t pionAbsorption
True if the event is a pion absorption.
G4double maxImpactParameter(ParticleSpecies const &p, const G4double kinE, Nucleus const *const n)
Return the maximum impact parameter for Coulomb-distorted trajectories.
G4bool isNaturalTarget() const
Natural targets.
Definition: G4INCLConfig.hh:87
Bool_t clusterDecay
Event involved cluster decay.
G4bool hasRemnant() const
Does the nucleus give a cascade remnant?
void deleteIncoming()
Clear the incoming list and delete the particles.
Definition: G4INCLStore.hh:150
ParticleList const & getIncomingParticles() const
Return the list of incoming particles (i.e.
Definition: G4INCLStore.hh:217
Float_t Ep
Projectile kinetic energy given as input.
Short_t At
Target mass number given as input.
Cluster is a particle (inherits from the Particle class) that is actually a collection of elementary ...
Int_t nTransparents
Number of transparent shots.
G4double shoot0()
Return a random number in the ]0,1] interval.
void reset()
Reset the projectile remnant to the state at the beginning of the cascade.
std::vector< Int_t > initialRandomSeeds
Initial seeds for the pseudo-random-number generator.
CascadeAction * cascadeAction
int G4int
Definition: G4Types.hh:78
Float_t stoppingTime
Cascade stopping time [fm/c].
G4double mag2() const
Get the square of the length.
Class containing default actions to be performed at intermediate cascade steps.
Float_t Ep
Projectile kinetic energy given as input.
IPropagationModel * propagationModel
Short_t At
Mass number of the target nucleus.
G4double getNuclearRadius(const ParticleType t, const G4int A, const G4int Z)
void setEnergy(G4double energy)
Set the energy of the particle in MeV.
G4INCL::ThreeVector getAngularMomentum() const
Get the total angular momentum (orbital + spin)
static G4ThreadLocal Int_t eventNumber
Number of the event.
SeedVector getSeeds()
Get the seeds of the current generator.
Definition: G4INCLRandom.cc:89
void clearCache()
Clear the INuclearPotential cache.
void beforeAvatarAction(IAvatar *a, Nucleus *n)
G4double getImpactParameter() const
void finalizeGlobalInfo(Random::SeedVector const &initialSeeds)
Short_t Zt
Charge number of the target nucleus.
Float_t impactParameter
Impact parameter [fm].
G4double fixedImpactParameter
void rescaleOutgoingForRecoil()
Rescale the energies of the outgoing particles.
void useFusionKinematics()
Adjust the kinematics for complete-fusion events.
void deleteCoulomb()
Delete the Coulomb-distortion object.
Static class for selecting Coulomb distortion.
INCL(Config const *const config)
void initMaxInteractionDistance(ParticleSpecies const &p, const G4double kineticEnergy)
Initialise the maximum interaction distance.
static std::string const getVersionString()
Get the INCL version string.
Final state of an interaction.
Simple container for output of calculation-wide results.
Float_t pTransBalance
Transverse momentum-conservation balance [MeV/c].
void deleteBlockers()
Delete blockers.
Float_t EBalance
Energy-conservation balance [MeV].
G4bool decayOutgoingDeltas()
Force the decay of outgoing deltas.
ParticleList const & getOutgoingParticles() const
Return the list of outgoing particles (i.e.
Definition: G4INCLStore.hh:223
static void deleteBackupParticles()
Release the memory allocated for the backup particles.
G4int getCascading() const
Definition: G4INCLBook.hh:105
virtual G4double shoot(ParticleSpecies const &projectileSpecies, const G4double kineticEnergy, const G4double impactParameter, const G4double phi)=0
Book & getBook()
Return the pointer to the Book object which keeps track of various counters.
Definition: G4INCLStore.hh:259
Bool_t deltasInside
Event involved deltas in the nucleus at the end of the cascade.
ParticleList extractDynamicalSpectators()
Returns a list of dynamical spectators.
Definition: G4INCLStore.hh:232
GlobalInfo theGlobalInfo
Int_t nForcedTransparents
Number of forced transparents.
Class that stores isotopic abundances for a given element.
std::string deexcitationModel
Name of the de-excitation model.
void beforePropagationAction(IPropagationModel *pm)
bool G4bool
Definition: G4Types.hh:79
void initUniverseRadius(ParticleSpecies const &p, const G4double kineticEnergy, const G4int A, const G4int Z)
Initialize the universe radius.
void initialize(Config const *const theConfig)
G4int getTargetA() const
Get the target mass number.
Definition: G4INCLConfig.hh:94
Intersection getEarlierTrajectoryIntersection(const ThreeVector &x0, const ThreeVector &p, const G4double r)
Compute the first intersection of a straight particle trajectory with a sphere.
const EventInfo & processEvent()
G4int getZ() const
Returns the charge number.
Alternative CascadeAction for dumping avatars.
G4double getExcitationEnergy() const
Get the excitation energy of the nucleus.
Class to adjust remnant recoil in the reaction CM system.
G4double computeExcitationEnergy() const
Compute the current excitation energy.
Float_t completeFusionCrossSection
Calculated complete-fusion cross section (nParticles==0)
Int_t nShots
Number of shots.
Int_t nUnmergedSpectators
Number of dynamical spectators that were merged back into the projectile remnant. ...
void afterCascadeAction(Nucleus *)
static const G4double A[nN]
G4bool decayMe()
Force the phase-space decay of the Nucleus.
void initialize(Config const *const theConfig)
Initialize the clustering model based on the Config object.
void clearOutgoing()
Clear all outgoing particles from the store.
Definition: G4INCLStore.cc:223
std::vector< Isotope > IsotopeVector
IsotopeVector const & getIsotopes() const
Get the isotope vector.
Functions that encapsulate a mass table.
Float_t reactionCrossSection
Calculated reaction cross section.
Standard INCL4 particle propagation and avatar prediction.
G4bool getTryCompoundNucleus()
Float_t geometricCrossSection
Geometric cross section.
G4bool initializeTarget(const G4int A, const G4int Z)
Short_t Zp
Projectile charge number given as input.
Adapter const & getAdapter()
void initVerbosityLevelFromEnvvar()
void addParticleEntryAvatar(IAvatar *a)
Add one ParticleEntry avatar.
Definition: G4INCLStore.cc:66
Float_t errorCompleteFusionCrossSection
Error on the calculated complete-fusion cross section (nParticles==0)
void reset()
Definition: G4INCLBook.hh:52
void setA(const G4int A)
Set the mass number of the cluster.
ParticleList addAllDynamicalSpectators(ParticleList const &pL)
Add back all dynamical spectators to the projectile remnant.
G4double maxImpactParameter
G4bool decayInsideDeltas()
Force the decay of deltas inside the nucleus.
void finalizeProjectileRemnant(const G4double emissionTime)
Finalise the projectile remnant.
G4double getMaximumNuclearRadius(const ParticleType t, const G4int A, const G4int Z)
Static class for cluster formation.
void deleteClusteringModel()
Delete the clustering model.
std::string getDeExcitationString() const
Get the de-excitation string.
ParticleSpecies getProjectileSpecies() const
Get the projectile species.
T max(const T t1, const T t2)
brief Return the largest of the two arguments
virtual void setNucleus(G4INCL::Nucleus *nucleus)=0
Set the nucleus for the propagation model.
Int_t nPionAbsorptions
Number of nucleon absorptions (no outcoming pions)
G4double interactionDistancePiN(const G4double projectileKineticEnergy)
Compute the "interaction distance".
LocalEnergyType getLocalEnergyPiType() const
Get the type of local energy for pi-N and decay avatars.
G4ThreadLocal NuclearMassFn getTableMass
Static pointer to the mass function for nuclei.
LocalEnergyType getLocalEnergyBBType() const
Get the type of local energy for N-N avatars.
void initialize(Config const *const theConfig)
void reset()
Reset the EventInfo members.
G4double perp() const
void makeCompoundNucleus()
Make a compound nucleus.
virtual G4double getStoppingTime()=0
Get the current stopping time.
T min(const T t1, const T t2)
brief Return the smallest of the two arguments
G4bool isEventTransparent() const
Is the event transparent?
FinalState * getFinalState()
const G4double twoPi
Int_t nEnergyViolationInteraction
Number of attempted collisions/decays for which the energy-conservation algorithm failed to find a so...
Solution solve(RootFunctor const *const f, const G4double x0)
Numerically solve a one-dimensional equation.
void fillEventInfo(EventInfo *eventInfo)
Fill the event info which contains INCL output data.
G4int drawRandomNaturalIsotope(const G4int Z)
ProjectileRemnant * getProjectileRemnant() const
Get the projectile remnant.
G4double getX() const
G4bool forceTransparent
G4double shoot()
Generate flat distribution of random numbers.
Definition: G4INCLRandom.cc:93
void initialize(Config const *const aConfig)
Initialise blockers according to a Config object.
Short_t Zt
Target charge number given as input.
Intersection-point structure.
Bool_t transparent
True if the event is transparent.
IsotopicDistribution const & getNaturalIsotopicDistribution(const G4int Z)
double G4double
Definition: G4Types.hh:76
void afterPropagationAction(IPropagationModel *pm, IAvatar *avatar)
#define INCL_DEBUG(x)
void computeRecoilKinematics()
Compute the recoil momentum and spin of the nucleus.
virtual G4double getCurrentTime()=0
Returns the current global time of the system.
Nucleus * nucleus
void afterAvatarAction(IAvatar *a, Nucleus *n, FinalState *fs)
G4double getProjectileKineticEnergy() const
Get the projectile kinetic energy.
G4int makeProjectileRemnant()
Make a projectile pre-fragment out of geometrical spectators.
Int_t nNucleonAbsorptions
Number of nucleon absorptions (no outcoming particles)
Float_t energyViolationInteractionCrossSection
Cross section for attempted collisions/decays for which the energy-conservation algorithm failed to f...
void addToOutgoing(Particle *p)
add the particle to the outgoing particle list.
Definition: G4INCLStore.hh:190
Bool_t forcedDeltasInside
Event involved forced delta decays inside the nucleus.
EventInfo theEventInfo
Short_t Ap
Mass number of the projectile nucleus.
Short_t nCascadeParticles
Number of cascade particles.
void setExcitationEnergy(const G4double e)
Set the excitation energy of the cluster.
void initialize(Config const *const theConfig=0)
Initialize the particle table.
void setSpin(const ThreeVector &j)
Set the spin of the nucleus.
Float_t errorForcedCNCrossSection
Error on the calculated forced-compound-nucleus cross section.
G4double getCutNN() const
G4double getZ() const
const G4double r0
void distortOut(ParticleList const &pL, Nucleus const *const n)
Modify the momentum of an outgoing particle.
Simple class for computing intersections between a straight line and a sphere.
void initialize(Config const *const theConfig)
Initialize the Coulomb-distortion algorithm.
void clearIncoming()
Clear the incoming list.
Definition: G4INCLStore.hh:145
Int_t nCompleteFusion
Number of complete-fusion events (nParticles==0)
Int_t projectileType
Projectile particle type.
virtual void setMomentum(const G4INCL::ThreeVector &momentum)
Set the momentum vector.
G4double getY() const