Geant4  10.03.p03
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4IntraNucleiCascader Class Reference

#include <G4IntraNucleiCascader.hh>

Inheritance diagram for G4IntraNucleiCascader:
Collaboration diagram for G4IntraNucleiCascader:

Public Member Functions

 G4IntraNucleiCascader ()
 
virtual ~G4IntraNucleiCascader ()
 
void collide (G4InuclParticle *bullet, G4InuclParticle *target, G4CollisionOutput &globalOutput)
 
void rescatter (G4InuclParticle *bullet, G4KineticTrackVector *theSecondaries, G4V3DNucleus *theNucleus, G4CollisionOutput &globalOutput)
 
void setVerboseLevel (G4int verbose=0)
 
- Public Member Functions inherited from G4CascadeColliderBase
 G4CascadeColliderBase (const G4String &name, G4int verbose=0)
 
virtual ~G4CascadeColliderBase ()
 
- Public Member Functions inherited from G4VCascadeCollider
 G4VCascadeCollider (const G4String &name, G4int verbose=0)
 
virtual ~G4VCascadeCollider ()
 

Protected Member Functions

G4bool initialize (G4InuclParticle *bullet, G4InuclParticle *target)
 
void newCascade (G4int itry)
 
void setupCascade ()
 
void generateCascade ()
 
G4bool finishCascade ()
 
void finalize (G4int itry, G4InuclParticle *bullet, G4InuclParticle *target, G4CollisionOutput &globalOutput)
 
G4InuclParticlecreateTarget (G4V3DNucleus *theNucleus)
 
void preloadCascade (G4V3DNucleus *theNucleus, G4KineticTrackVector *theSecondaries)
 
void copyWoundedNucleus (G4V3DNucleus *theNucleus)
 
void copySecondaries (G4KineticTrackVector *theSecondaries)
 
void processSecondary (const G4KineticTrack *aSecondary)
 
void releaseSecondary (const G4KineticTrack *aSecondary)
 
void processTrappedParticle (const G4CascadParticle &trapped)
 
void decayTrappedParticle (const G4CascadParticle &trapped)
 
G4bool particleCanInteract (const G4CascadParticle &cpart) const
 
- Protected Member Functions inherited from G4CascadeColliderBase
virtual G4bool useEPCollider (G4InuclParticle *bullet, G4InuclParticle *target) const
 
virtual G4bool inelasticInteractionPossible (G4InuclParticle *bullet, G4InuclParticle *target, G4double ekin) const
 
virtual G4bool validateOutput (G4InuclParticle *bullet, G4InuclParticle *target, G4CollisionOutput &output)
 
virtual G4bool validateOutput (const G4Fragment &fragment, G4CollisionOutput &output)
 
virtual G4bool validateOutput (G4InuclParticle *bullet, G4InuclParticle *target, const std::vector< G4InuclElementaryParticle > &particles)
 
- Protected Member Functions inherited from G4VCascadeCollider
virtual void setName (const G4String &name)
 

Additional Inherited Members

- Protected Attributes inherited from G4CascadeColliderBase
G4InteractionCase interCase
 
G4CascadeCheckBalancebalance
 
- Protected Attributes inherited from G4VCascadeCollider
G4String theName
 
G4int verboseLevel
 

Detailed Description

Definition at line 89 of file G4IntraNucleiCascader.hh.

Constructor & Destructor Documentation

G4IntraNucleiCascader::G4IntraNucleiCascader ( )

Definition at line 167 of file G4IntraNucleiCascader.cc.

168  : G4CascadeColliderBase("G4IntraNucleiCascader"), model(new G4NucleiModel),
169  theElementaryParticleCollider(new G4ElementaryParticleCollider),
170  theRecoilMaker(new G4CascadeRecoilMaker), theClusterMaker(0),
171  theCascadeHistory(0), tnuclei(0), bnuclei(0), bparticle(0),
172  minimum_recoil_A(0.), coulombBarrier(0.),
173  nucleusTarget(new G4InuclNuclei),
174  protonTarget(new G4InuclElementaryParticle) {
176  theClusterMaker = new G4CascadeCoalescence;
177 
179  theCascadeHistory = new G4CascadeHistory;
180 }
static G4bool showHistory()
static G4bool doCoalescence()
G4CascadeColliderBase(const G4String &name, G4int verbose=0)
const XML_Char XML_Content * model
Definition: expat.h:151

Here is the call graph for this function:

G4IntraNucleiCascader::~G4IntraNucleiCascader ( )
virtual

Definition at line 182 of file G4IntraNucleiCascader.cc.

182  {
183  delete model;
184  delete theElementaryParticleCollider;
185  delete theRecoilMaker;
186  delete theClusterMaker;
187  delete theCascadeHistory;
188  delete nucleusTarget;
189  delete protonTarget;
190 }
const XML_Char XML_Content * model
Definition: expat.h:151

Member Function Documentation

void G4IntraNucleiCascader::collide ( G4InuclParticle bullet,
G4InuclParticle target,
G4CollisionOutput globalOutput 
)
virtual

Implements G4VCascadeCollider.

Definition at line 205 of file G4IntraNucleiCascader.cc.

207  {
208  if (verboseLevel) G4cout << " >>> G4IntraNucleiCascader::collide " << G4endl;
209 
210  if (!initialize(bullet, target)) return; // Load buffers and drivers
211 
212  G4int itry = 0;
213  do { /* Loop checking 08.06.2015 MHK */
214  newCascade(++itry);
215  setupCascade();
216  generateCascade();
217  } while (!finishCascade() && itry<itry_max);
218 
219  // Report full structure of final cascade if requested
220  if (theCascadeHistory) theCascadeHistory->Print(G4cout);
221 
222  finalize(itry, bullet, target, globalOutput);
223 }
void Print(std::ostream &os) const
int G4int
Definition: G4Types.hh:78
G4bool initialize(G4InuclParticle *bullet, G4InuclParticle *target)
G4GLOB_DLL std::ostream G4cout
#define G4endl
Definition: G4ios.hh:61
void finalize(G4int itry, G4InuclParticle *bullet, G4InuclParticle *target, G4CollisionOutput &globalOutput)

Here is the call graph for this function:

Here is the caller graph for this function:

void G4IntraNucleiCascader::copySecondaries ( G4KineticTrackVector theSecondaries)
protected

Definition at line 739 of file G4IntraNucleiCascader.cc.

739  {
740  if (verboseLevel > 1)
741  G4cout << " >>> G4IntraNucleiCascader::copySecondaries" << G4endl;
742 
743  for (size_t i=0; i<secondaries->size(); i++) {
744  if (verboseLevel > 3) G4cout << " processing secondary " << i << G4endl;
745 
746  processSecondary((*secondaries)[i]); // Copy to cascade or to output
747  }
748 
749  // Sort list of secondaries to put leading particle first
750  std::sort(cascad_particles.begin(), cascad_particles.end(),
752 
753  if (verboseLevel > 2) {
754  G4cout << " Original list of " << secondaries->size() << " secondaries"
755  << " produced " << cascad_particles.size() << " cascade, "
756  << output.numberOfOutgoingParticles() << " released particles, "
757  << output.numberOfOutgoingNuclei() << " fragments" << G4endl;
758  }
759 }
G4GLOB_DLL std::ostream G4cout
G4int numberOfOutgoingParticles() const
void processSecondary(const G4KineticTrack *aSecondary)
G4int numberOfOutgoingNuclei() const
#define G4endl
Definition: G4ios.hh:61

Here is the call graph for this function:

Here is the caller graph for this function:

void G4IntraNucleiCascader::copyWoundedNucleus ( G4V3DNucleus theNucleus)
protected

Definition at line 708 of file G4IntraNucleiCascader.cc.

708  {
709  if (verboseLevel > 1)
710  G4cout << " >>> G4IntraNucleiCascader::copyWoundedNucleus" << G4endl;
711 
712  // Loop over nucleons and count hits as exciton holes
713  theExitonConfiguration.clear();
714  hitNucleons.clear();
715  if (theNucleus->StartLoop()) {
716  G4Nucleon* nucl = 0;
717  G4int nuclType = 0;
718  /* Loop checking 08.06.2015 MHK */
719  while ((nucl = theNucleus->GetNextNucleon())) {
720  if (nucl->AreYouHit()) { // Found previously interacted nucleon
722  theExitonConfiguration.incrementHoles(nuclType);
723  hitNucleons.push_back(nucl->GetPosition());
724  }
725  }
726  }
727 
728  if (verboseLevel > 3)
729  G4cout << " nucleus has " << theExitonConfiguration.neutronHoles
730  << " neutrons hit, " << theExitonConfiguration.protonHoles
731  << " protons hit" << G4endl;
732 
733  // Preload nuclear model with confirmed hits, including locations
734  model->reset(theExitonConfiguration.neutronHoles,
735  theExitonConfiguration.protonHoles, &hitNucleons);
736 }
const G4ParticleDefinition * GetParticleType() const
Definition: G4Nucleon.hh:84
virtual G4bool StartLoop()=0
virtual const G4ThreeVector & GetPosition() const
Definition: G4Nucleon.hh:68
int G4int
Definition: G4Types.hh:78
G4GLOB_DLL std::ostream G4cout
G4bool AreYouHit() const
Definition: G4Nucleon.hh:97
#define G4endl
Definition: G4ios.hh:61
virtual G4Nucleon * GetNextNucleon()=0
const XML_Char XML_Content * model
Definition: expat.h:151

Here is the call graph for this function:

Here is the caller graph for this function:

G4InuclParticle * G4IntraNucleiCascader::createTarget ( G4V3DNucleus theNucleus)
protected

Definition at line 679 of file G4IntraNucleiCascader.cc.

679  {
680  G4int theNucleusA = theNucleus->GetMassNumber();
681  G4int theNucleusZ = theNucleus->GetCharge();
682 
683  if (theNucleusA > 1) {
684  if (!nucleusTarget) nucleusTarget = new G4InuclNuclei; // Just in case
685  nucleusTarget->fill(0., theNucleusA, theNucleusZ, 0.);
686  return nucleusTarget;
687  } else {
688  if (!protonTarget) protonTarget = new G4InuclElementaryParticle;
689  protonTarget->fill(0., (theNucleusZ==1)?proton:neutron);
690  return protonTarget;
691  }
692 
693  return 0; // Can never actually get here
694 }
void fill(G4int a, G4int z, G4double exc=0., Model model=DefaultModel)
virtual G4int GetCharge()=0
virtual G4int GetMassNumber()=0
int G4int
Definition: G4Types.hh:78
void fill(G4int ityp, Model model=DefaultModel)

Here is the call graph for this function:

Here is the caller graph for this function:

void G4IntraNucleiCascader::decayTrappedParticle ( const G4CascadParticle trapped)
protected

Definition at line 871 of file G4IntraNucleiCascader.cc.

871  {
872  if (verboseLevel > 3)
873  G4cout << " unstable must be decayed in flight" << G4endl;
874 
875  const G4InuclElementaryParticle& trappedP = trapped.getParticle();
876 
877  G4DecayTable* unstable = trappedP.getDefinition()->GetDecayTable();
878  if (!unstable) { // No decay table; cannot decay!
879  if (verboseLevel > 3)
880  G4cerr << " no decay table! Releasing trapped particle" << G4endl;
881 
882  output.addOutgoingParticle(trappedP);
883  return;
884  }
885 
886  // Get secondaries from decay in particle's rest frame
887  G4DecayProducts* daughters = unstable->SelectADecayChannel()->DecayIt( trappedP.getDefinition()->GetPDGMass() );
888  if (!daughters) { // No final state; cannot decay!
889  if (verboseLevel > 3)
890  G4cerr << " no daughters! Releasing trapped particle" << G4endl;
891 
892  output.addOutgoingParticle(trappedP);
893  return;
894  }
895 
896  if (verboseLevel > 3)
897  G4cout << " " << daughters->entries() << " decay daughters" << G4endl;
898 
899  // Convert secondaries to lab frame
900  G4double decayEnergy = trappedP.getEnergy();
901  G4ThreeVector decayDir = trappedP.getMomentum().vect().unit();
902  daughters->Boost(decayEnergy, decayDir);
903 
904  // Put all the secondaries onto the list for propagation
905  const G4ThreeVector& decayPos = trapped.getPosition();
906  G4int zone = trapped.getCurrentZone();
907  G4int gen = trapped.getGeneration()+1;
908 
909  for (G4int i=0; i<daughters->entries(); i++) {
910  G4DynamicParticle* idaug = (*daughters)[i];
911 
913 
914  // Propagate hadronic secondaries with known interactions (tables)
915  if (G4CascadeChannelTables::GetTable(idaugEP.type())) {
916  if (verboseLevel > 3) G4cout << " propagating " << idaugEP << G4endl;
917  cascad_particles.push_back(G4CascadParticle(idaugEP,decayPos,zone,0.,gen));
918  } else {
919  if (verboseLevel > 3) G4cout << " releasing " << idaugEP << G4endl;
920  output.addOutgoingParticle(idaugEP);
921  }
922  }
923 
924  delete daughters; // Clean up memory created by DecayIt()
925 }
static const G4CascadeChannel * GetTable(G4int initialState)
G4LorentzVector getMomentum() const
G4int getGeneration() const
const G4ParticleDefinition * getDefinition() const
void addOutgoingParticle(const G4InuclElementaryParticle &particle)
G4double getEnergy() const
void Boost(G4double totalEnergy, const G4ThreeVector &momentumDirection)
int G4int
Definition: G4Types.hh:78
const G4InuclElementaryParticle & getParticle() const
G4DecayTable * GetDecayTable() const
Hep3Vector vect() const
G4GLOB_DLL std::ostream G4cout
G4VDecayChannel * SelectADecayChannel(G4double parentMass=-1.)
Definition: G4DecayTable.cc:81
G4double GetPDGMass() const
Hep3Vector unit() const
G4int getCurrentZone() const
#define G4endl
Definition: G4ios.hh:61
G4int entries() const
const G4ThreeVector & getPosition() const
virtual G4DecayProducts * DecayIt(G4double parentMass=-1.0)=0
double G4double
Definition: G4Types.hh:76
G4GLOB_DLL std::ostream G4cerr

Here is the call graph for this function:

Here is the caller graph for this function:

void G4IntraNucleiCascader::finalize ( G4int  itry,
G4InuclParticle bullet,
G4InuclParticle target,
G4CollisionOutput globalOutput 
)
protected

Definition at line 657 of file G4IntraNucleiCascader.cc.

659  {
660  if (itry >= itry_max) {
661  if (verboseLevel) {
662  G4cout << " IntraNucleiCascader-> no inelastic interaction after "
663  << itry << " attempts " << G4endl;
664  }
665 
666  output.trivialise(bullet, target);
667  } else if (verboseLevel) {
668  G4cout << " IntraNucleiCascader output after trials " << itry << G4endl;
669  }
670 
671  // Copy final generated cascade to output buffer for return
672  globalOutput.add(output);
673 }
void trivialise(G4InuclParticle *bullet, G4InuclParticle *target)
void add(const G4CollisionOutput &right)
G4GLOB_DLL std::ostream G4cout
#define G4endl
Definition: G4ios.hh:61

Here is the call graph for this function:

Here is the caller graph for this function:

G4bool G4IntraNucleiCascader::finishCascade ( )
protected

Definition at line 508 of file G4IntraNucleiCascader.cc.

508  {
509  if (verboseLevel > 1)
510  G4cout << " >>> G4IntraNucleiCascader::finishCascade ?" << G4endl;
511 
512  // Add left-over cascade particles to output
513  output.addOutgoingParticles(cascad_particles);
514  cascad_particles.clear();
515 
516  // Cascade is finished. Check if it's OK.
517  if (verboseLevel>3) {
518  G4cout << " G4IntraNucleiCascader finished" << G4endl;
519  output.printCollisionOutput();
520  }
521 
522  // Apply cluster coalesence model to produce light ions
523  if (theClusterMaker) {
524  theClusterMaker->setVerboseLevel(verboseLevel);
525  theClusterMaker->FindClusters(output);
526 
527  // Update recoil fragment after generating light ions
528  if (verboseLevel>3) G4cout << " Recomputing recoil fragment" << G4endl;
529  theRecoilMaker->collide(interCase.getBullet(), interCase.getTarget(),
530  output);
531  if (verboseLevel>3) {
532  G4cout << " After cluster coalescence" << G4endl;
533  output.printCollisionOutput();
534  }
535  }
536 
537  // Use last created recoil fragment instead of re-constructing
538  G4int afin = theRecoilMaker->getRecoilA();
539  G4int zfin = theRecoilMaker->getRecoilZ();
540 
541  // FIXME: Should we deal with unbalanced (0,0) case before rejecting?
542 
543  // Sanity check before proceeding
544  if (!theRecoilMaker->goodFragment() && !theRecoilMaker->wholeEvent()) {
545  if (verboseLevel > 1)
546  G4cerr << " Recoil nucleus is not physical: A=" << afin << " Z="
547  << zfin << G4endl;
548  return false; // Discard event and try again
549  }
550 
551  const G4LorentzVector& presid = theRecoilMaker->getRecoilMomentum();
552 
553  if (verboseLevel > 1) {
554  G4cout << " afin " << afin << " zfin " << zfin << G4endl;
555  }
556 
557  if (afin == 0) return true; // Whole event fragmented, exit
558 
559  if (afin == 1) { // Add bare nucleon to particle list
560  G4int last_type = (zfin==1) ? 1 : 2; // proton=1, neutron=2
561 
563  G4double mres = presid.m();
564 
565  // Check for sensible kinematics
566  if (mres-mass < -small_ekin) { // Insufficient recoil energy
567  if (verboseLevel > 2) G4cerr << " unphysical recoil nucleon" << G4endl;
568  return false;
569  }
570 
571  if (mres-mass > small_ekin) { // Too much extra energy
572  if (verboseLevel > 2)
573  G4cerr << " extra energy with recoil nucleon" << G4endl;
574 
575  // FIXME: For now, we add the nucleon as unbalanced, and let
576  // "SetOnShell" fudge things. This should be abandoned.
577  }
578 
579  G4InuclElementaryParticle last_particle(presid, last_type,
581 
582  if (verboseLevel > 3) {
583  G4cout << " adding recoiling nucleon to output list\n"
584  << last_particle << G4endl;
585  }
586 
587  output.addOutgoingParticle(last_particle);
588 
589  // Update recoil to include residual nucleon
590  theRecoilMaker->collide(interCase.getBullet(), interCase.getTarget(),
591  output);
592  }
593 
594  // Process recoil fragment for consistency, exit or reject
595  if (output.numberOfOutgoingParticles() == 1) {
596  G4double Eex = theRecoilMaker->getRecoilExcitation();
597  if (std::abs(Eex) < quasielast_cut) {
598  if (verboseLevel > 3) {
599  G4cout << " quasi-elastic scatter with " << Eex << " MeV recoil"
600  << G4endl;
601  }
602 
603  theRecoilMaker->setRecoilExcitation(Eex=0.);
604  if (verboseLevel > 3) {
605  G4cout << " Eex reset to " << theRecoilMaker->getRecoilExcitation()
606  << G4endl;
607  }
608  }
609  }
610 
611  if (theRecoilMaker->goodNucleus()) {
612  theRecoilMaker->addExcitonConfiguration(theExitonConfiguration);
613 
614  G4Fragment* recoilFrag = theRecoilMaker->makeRecoilFragment();
615  if (!recoilFrag) {
616  G4cerr << "Got null pointer for recoil fragment!" << G4endl;
617  return false;
618  }
619 
620  if (verboseLevel > 2)
621  G4cout << " adding recoil fragment to output list" << G4endl;
622 
623  output.addRecoilFragment(*recoilFrag);
624  }
625 
626  // Put final-state particles in "leading order" for return
627  std::vector<G4InuclElementaryParticle>& opart = output.getOutgoingParticles();
628  std::sort(opart.begin(), opart.end(), G4ParticleLargerEkin());
629 
630  // Adjust final state to balance momentum and energy if necessary
631  if (theRecoilMaker->wholeEvent() || theRecoilMaker->goodNucleus()) {
634  output.setVerboseLevel(0);
635 
636  if (output.acceptable()) return true;
637  else if (verboseLevel>2) G4cerr << " Cascade setOnShell failed." << G4endl;
638  }
639 
640  // Cascade not physically reasonable
641  if (afin <= minimum_recoil_A && minimum_recoil_A < tnuclei->getA()) {
642  ++minimum_recoil_A;
643  if (verboseLevel > 3) {
644  G4cout << " minimum recoil fragment increased to A " << minimum_recoil_A
645  << G4endl;
646  }
647  }
648 
649  if (verboseLevel>2) G4cerr << " Cascade failed. Retrying..." << G4endl;
650  return false;
651 }
void setVerboseLevel(G4int verbose)
void setVerboseLevel(G4int verbose)
void printCollisionOutput(std::ostream &os=G4cout) const
void addOutgoingParticle(const G4InuclElementaryParticle &particle)
const G4LorentzVector & getRecoilMomentum() const
static G4double getParticleMass(G4int type)
int G4int
Definition: G4Types.hh:78
G4double getRecoilExcitation() const
G4bool acceptable() const
void collide(G4InuclParticle *bullet, G4InuclParticle *target, G4CollisionOutput &output)
G4GLOB_DLL std::ostream G4cout
G4int numberOfOutgoingParticles() const
void addOutgoingParticles(const std::vector< G4InuclElementaryParticle > &particles)
const std::vector< G4InuclElementaryParticle > & getOutgoingParticles() const
G4InuclParticle * getBullet() const
#define G4endl
Definition: G4ios.hh:61
void addRecoilFragment(const G4Fragment *aFragment)
void FindClusters(G4CollisionOutput &finalState)
void setRecoilExcitation(G4double Eexc)
double G4double
Definition: G4Types.hh:76
G4InuclParticle * getTarget() const
void addExcitonConfiguration(const G4ExitonConfiguration exciton)
G4Fragment * makeRecoilFragment()
void setOnShell(G4InuclParticle *bullet, G4InuclParticle *target)
G4GLOB_DLL std::ostream G4cerr

Here is the call graph for this function:

Here is the caller graph for this function:

void G4IntraNucleiCascader::generateCascade ( )
protected

Definition at line 362 of file G4IntraNucleiCascader.cc.

362  {
363  if (verboseLevel>1) G4cout << " generateCascade " << G4endl;
364 
365  /* Loop checking 08.06.2015 MHK */
366  G4int iloop = 0;
367  while (!cascad_particles.empty() && !model->empty()) {
368  iloop++;
369 
370  if (verboseLevel > 2) {
371  G4cout << " Iteration " << iloop << ": Number of cparticles "
372  << cascad_particles.size() << " last one: \n"
373  << cascad_particles.back() << G4endl;
374  }
375 
376  // Record incident particle first, to get history ID
377  if (theCascadeHistory) {
378  theCascadeHistory->AddEntry(cascad_particles.back());
379  if (verboseLevel > 2) {
380  G4cout << " active cparticle got history ID "
381  << cascad_particles.back().getHistoryId() << G4endl;
382  }
383  }
384 
385  // If non-interacting particle, move directly to output
386  if (!particleCanInteract(cascad_particles.back())) {
387  if (verboseLevel > 2)
388  G4cout << " particle is non-interacting; moving to output" << G4endl;
389 
390  output.addOutgoingParticle(cascad_particles.back().getParticle());
391  cascad_particles.pop_back();
392  continue;
393  }
394 
395  // Generate interaction with nucleon
396  model->generateParticleFate(cascad_particles.back(),
397  theElementaryParticleCollider,
398  new_cascad_particles);
399 
400  // Record interaction for later reporting (if desired)
401  if (theCascadeHistory && new_cascad_particles.size()>1)
402  theCascadeHistory->AddVertex(cascad_particles.back(), new_cascad_particles);
403 
404  if (verboseLevel > 2) {
405  G4cout << " After generate fate: New particles "
406  << new_cascad_particles.size() << G4endl
407  << " Discarding last cparticle from list " << G4endl;
408  }
409 
410  cascad_particles.pop_back();
411 
412  // handle the result of a new step
413 
414  if (new_cascad_particles.size() == 1) { // last particle goes without interaction
415  const G4CascadParticle& currentCParticle = new_cascad_particles[0];
416 
417  if (model->stillInside(currentCParticle)) {
418  if (verboseLevel > 3)
419  G4cout << " particle still inside nucleus " << G4endl;
420 
421  if (currentCParticle.getNumberOfReflections() < reflection_cut &&
422  model->worthToPropagate(currentCParticle)) {
423  if (verboseLevel > 3) G4cout << " continue reflections " << G4endl;
424  cascad_particles.push_back(currentCParticle);
425  } else {
426  processTrappedParticle(currentCParticle);
427  } // reflection or exciton
428 
429  } else { // particle about to leave nucleus - check for Coulomb barrier
430  if (verboseLevel > 3) G4cout << " possible escape " << G4endl;
431 
432  const G4InuclElementaryParticle& currentParticle =
433  currentCParticle.getParticle();
434 
435  G4double KE = currentParticle.getKineticEnergy();
436  G4double mass = currentParticle.getMass();
437  G4double Q = currentParticle.getCharge();
438 
439  if (verboseLevel > 3)
440  G4cout << " KE " << KE << " barrier " << Q*coulombBarrier << G4endl;
441 
442  if (KE < Q*coulombBarrier) {
443  // Calculate barrier penetration
444  G4double CBP = 0.0;
445 
446  // if (KE > 0.0001) CBP = std::exp(-0.00126*tnuclei->getZ()*0.25*
447  // (1./KE - 1./coulombBarrier));
448  if (KE > 0.0001) CBP = G4Exp(-0.0181*0.5*tnuclei->getZ()*
449  (1./KE - 1./coulombBarrier)*
450  std::sqrt(mass*(coulombBarrier-KE)) );
451 
452  if (G4UniformRand() < CBP) {
453  if (verboseLevel > 3)
454  G4cout << " tunneled\n" << currentParticle << G4endl;
455 
456  // Tunnelling through barrier leaves KE unchanged
457  output.addOutgoingParticle(currentParticle);
458  } else {
459  processTrappedParticle(currentCParticle);
460  }
461  } else {
462  output.addOutgoingParticle(currentParticle);
463 
464  if (verboseLevel > 3)
465  G4cout << " Goes out\n" << output.getOutgoingParticles().back()
466  << G4endl;
467  }
468  }
469  } else { // interaction
470  if (verboseLevel > 3)
471  G4cout << " interacted, adding new to list " << G4endl;
472 
473  cascad_particles.insert(cascad_particles.end(),
474  new_cascad_particles.begin(),
475  new_cascad_particles.end());
476 
477  std::pair<G4int, G4int> holes = model->getTypesOfNucleonsInvolved();
478  if (verboseLevel > 3)
479  G4cout << " adding new exciton holes " << holes.first << ","
480  << holes.second << G4endl;
481 
482  theExitonConfiguration.incrementHoles(holes.first);
483 
484  if (holes.second > 0)
485  theExitonConfiguration.incrementHoles(holes.second);
486  } // if (new_cascad_particles ...
487 
488  // Evaluate nuclear residue
489  theRecoilMaker->collide(interCase.getBullet(), interCase.getTarget(),
490  output, cascad_particles);
491 
492  G4double aresid = theRecoilMaker->getRecoilA();
493  if (verboseLevel > 2) {
494  G4cout << " cparticles remaining " << cascad_particles.size()
495  << " nucleus (model) has "
496  << model->getNumberOfNeutrons() << " n, "
497  << model->getNumberOfProtons() << " p "
498  << " residual fragment A " << aresid << G4endl;
499  }
500 
501  if (aresid <= minimum_recoil_A) return; // Must have minimum fragment
502  } // while cascade-list and model
503 }
void processTrappedParticle(const G4CascadParticle &trapped)
G4int getZ() const
static double Q[]
void addOutgoingParticle(const G4InuclElementaryParticle &particle)
G4bool particleCanInteract(const G4CascadParticle &cpart) const
int G4int
Definition: G4Types.hh:78
const G4InuclElementaryParticle & getParticle() const
G4double getKineticEnergy() const
void collide(G4InuclParticle *bullet, G4InuclParticle *target, G4CollisionOutput &output)
#define G4UniformRand()
Definition: Randomize.hh:97
G4GLOB_DLL std::ostream G4cout
G4int AddEntry(G4CascadParticle &cpart)
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
Definition: G4Exp.hh:183
const std::vector< G4InuclElementaryParticle > & getOutgoingParticles() const
G4double getCharge() const
G4InuclParticle * getBullet() const
#define G4endl
Definition: G4ios.hh:61
double G4double
Definition: G4Types.hh:76
G4InuclParticle * getTarget() const
const XML_Char XML_Content * model
Definition: expat.h:151
G4int getNumberOfReflections() const
G4int AddVertex(G4CascadParticle &cpart, std::vector< G4CascadParticle > &daug)
G4double getMass() const

Here is the call graph for this function:

Here is the caller graph for this function:

G4bool G4IntraNucleiCascader::initialize ( G4InuclParticle bullet,
G4InuclParticle target 
)
protected

Definition at line 252 of file G4IntraNucleiCascader.cc.

253  {
254  if (verboseLevel>1)
255  G4cout << " >>> G4IntraNucleiCascader::initialize " << G4endl;
256 
257  // Configure processing modules
258  theRecoilMaker->setTolerance(small_ekin);
259 
260  interCase.set(bullet,target); // Classify collision type
261 
262  if (verboseLevel > 3) {
263  G4cout << *interCase.getBullet() << G4endl
264  << *interCase.getTarget() << G4endl;
265  }
266 
267  // Bullet may be nucleus or simple particle
268  bnuclei = dynamic_cast<G4InuclNuclei*>(interCase.getBullet());
269  bparticle = dynamic_cast<G4InuclElementaryParticle*>(interCase.getBullet());
270 
271  if (!bnuclei && !bparticle) {
272  G4cerr << " G4IntraNucleiCascader: projectile is not a valid particle."
273  << G4endl;
274  return false;
275  }
276 
277  // Target _must_ be nucleus
278  tnuclei = dynamic_cast<G4InuclNuclei*>(interCase.getTarget());
279  if (!tnuclei) {
280  if (verboseLevel)
281  G4cerr << " Target is not a nucleus. Abandoning." << G4endl;
282  return false;
283  }
284 
285  model->generateModel(tnuclei);
286  coulombBarrier = 0.00126*tnuclei->getZ() / (1.+G4cbrt(tnuclei->getA()));
287 
288  // Energy/momentum conservation usually requires a recoiling nuclear fragment
289  // This cut will be increased on each "itry" if momentum could not balance.
290  minimum_recoil_A = 0.;
291 
292  if (verboseLevel > 3) {
293  G4LorentzVector momentum_in = bullet->getMomentum() + target->getMomentum();
294  G4cout << " intitial momentum E " << momentum_in.e() << " Px "
295  << momentum_in.x() << " Py " << momentum_in.y() << " Pz "
296  << momentum_in.z() << G4endl;
297  }
298 
299  return true;
300 }
G4int getZ() const
G4LorentzVector getMomentum() const
G4GLOB_DLL std::ostream G4cout
G4int getA() const
void set(G4InuclParticle *part1, G4InuclParticle *part2)
void setTolerance(G4double tolerance)
G4InuclParticle * getBullet() const
#define G4endl
Definition: G4ios.hh:61
G4InuclParticle * getTarget() const
const XML_Char XML_Content * model
Definition: expat.h:151
G4GLOB_DLL std::ostream G4cerr

Here is the call graph for this function:

Here is the caller graph for this function:

void G4IntraNucleiCascader::newCascade ( G4int  itry)
protected

Definition at line 304 of file G4IntraNucleiCascader.cc.

304  {
305  if (verboseLevel > 1) {
306  G4cout << " IntraNucleiCascader itry " << itry << " inter_case "
307  << interCase.code() << G4endl;
308  }
309 
310  model->reset(); // Start new cascade process
311  output.reset();
312  new_cascad_particles.clear();
313  theExitonConfiguration.clear();
314  cascad_particles.clear(); // List of initial secondaries
315 
316  if (theCascadeHistory) theCascadeHistory->Clear();
317 }
G4int code() const
G4GLOB_DLL std::ostream G4cout
#define G4endl
Definition: G4ios.hh:61
const XML_Char XML_Content * model
Definition: expat.h:151

Here is the call graph for this function:

Here is the caller graph for this function:

G4bool G4IntraNucleiCascader::particleCanInteract ( const G4CascadParticle cpart) const
protected

Definition at line 931 of file G4IntraNucleiCascader.cc.

931  {
932  // If we have a lookup table for particle type on proton, it interacts
933  return (0 != G4CascadeChannelTables::GetTable(cpart.getParticle().type()));
934 }
static const G4CascadeChannel * GetTable(G4int initialState)
const G4InuclElementaryParticle & getParticle() const

Here is the call graph for this function:

Here is the caller graph for this function:

void G4IntraNucleiCascader::preloadCascade ( G4V3DNucleus theNucleus,
G4KineticTrackVector theSecondaries 
)
protected

Definition at line 699 of file G4IntraNucleiCascader.cc.

700  {
701  if (verboseLevel > 1)
702  G4cout << " >>> G4IntraNucleiCascader::preloadCascade" << G4endl;
703 
704  copyWoundedNucleus(theNucleus); // Update interacted nucleon counts
705  copySecondaries(theSecondaries); // Copy original to internal list
706 }
G4GLOB_DLL std::ostream G4cout
void copyWoundedNucleus(G4V3DNucleus *theNucleus)
void copySecondaries(G4KineticTrackVector *theSecondaries)
#define G4endl
Definition: G4ios.hh:61

Here is the call graph for this function:

Here is the caller graph for this function:

void G4IntraNucleiCascader::processSecondary ( const G4KineticTrack aSecondary)
protected

Definition at line 764 of file G4IntraNucleiCascader.cc.

764  {
765  if (!ktrack) return; // Sanity check
766 
767  // Get particle type to determine whether to keep or release
768  const G4ParticleDefinition* kpd = ktrack->GetDefinition();
769  if (!kpd) return;
770 
772  if (!ktype) {
773  releaseSecondary(ktrack);
774  return;
775  }
776 
777  if (verboseLevel > 1) {
778  G4cout << " >>> G4IntraNucleiCascader::processSecondary "
779  << kpd->GetParticleName() << G4endl;
780  }
781 
782  // Allocate next local particle in buffer and fill
783  cascad_particles.resize(cascad_particles.size()+1); // Like push_back();
784  G4CascadParticle& cpart = cascad_particles.back();
785 
786  // Convert momentum to Bertini internal units
787  cpart.getParticle().fill(ktrack->Get4Momentum()/GeV, ktype);
788  cpart.setGeneration(1);
789  cpart.setMovingInsideNuclei();
790  cpart.initializePath(0);
791 
792  // Convert position units to Bertini's internal scale
793  G4ThreeVector cpos = ktrack->GetPosition()/model->getRadiusUnits();
794 
795  cpart.updatePosition(cpos);
796  cpart.updateZone(model->getZone(cpos.mag()));
797 
798  if (verboseLevel > 2)
799  G4cout << " Created cascade particle \n" << cpart << G4endl;
800 }
void initializePath(G4double npath)
void updatePosition(const G4ThreeVector &pos)
void setGeneration(G4int gen)
int G4int
Definition: G4Types.hh:78
const G4InuclElementaryParticle & getParticle() const
const G4String & GetParticleName() const
void updateZone(G4int izone)
G4GLOB_DLL std::ostream G4cout
void setMovingInsideNuclei(G4bool isMovingIn=true)
static constexpr double GeV
Definition: G4SIunits.hh:217
void fill(G4int ityp, Model model=DefaultModel)
#define G4endl
Definition: G4ios.hh:61
double mag() const
const XML_Char XML_Content * model
Definition: expat.h:151
void releaseSecondary(const G4KineticTrack *aSecondary)

Here is the call graph for this function:

Here is the caller graph for this function:

void G4IntraNucleiCascader::processTrappedParticle ( const G4CascadParticle trapped)
protected

Definition at line 839 of file G4IntraNucleiCascader.cc.

839  {
840  const G4InuclElementaryParticle& trappedP = trapped.getParticle();
841 
842  G4int xtype = trappedP.type();
843  if (verboseLevel > 3) G4cout << " exciton of type " << xtype << G4endl;
844 
845  if (trappedP.nucleon()) { // normal exciton (proton or neutron)
846  theExitonConfiguration.incrementQP(xtype);
847  if (theCascadeHistory) theCascadeHistory->DropEntry(trapped);
848  return;
849  }
850 
851  if (trappedP.hyperon()) { // Not nucleon, so must be hyperon
852  decayTrappedParticle(trapped);
853  if (theCascadeHistory) theCascadeHistory->DropEntry(trapped);
854  return;
855  }
856 
857  // non-standard exciton; release it
858  // FIXME: this is a meson, so need to absorb it
859  if (verboseLevel > 3) {
860  G4cout << " non-standard should be absorbed, now released\n"
861  << trapped << G4endl;
862  }
863 
864  output.addOutgoingParticle(trappedP);
865 }
void addOutgoingParticle(const G4InuclElementaryParticle &particle)
int G4int
Definition: G4Types.hh:78
const G4InuclElementaryParticle & getParticle() const
G4GLOB_DLL std::ostream G4cout
void decayTrappedParticle(const G4CascadParticle &trapped)
void DropEntry(const G4CascadParticle &cpart)
#define G4endl
Definition: G4ios.hh:61

Here is the call graph for this function:

Here is the caller graph for this function:

void G4IntraNucleiCascader::releaseSecondary ( const G4KineticTrack aSecondary)
protected

Definition at line 805 of file G4IntraNucleiCascader.cc.

805  {
806  const G4ParticleDefinition* kpd = ktrack->GetDefinition();
807 
808  if (verboseLevel > 1) {
809  G4cout << " >>> G4IntraNucleiCascader::releaseSecondary "
810  << kpd->GetParticleName() << G4endl;
811  }
812 
813  // Convert light ion into nucleus on fragment list
814  if (dynamic_cast<const G4Ions*>(kpd)) {
815  // Use resize() and fill() to avoid memory churn
816  output.getOutgoingNuclei().resize(output.numberOfOutgoingNuclei()+1);
817  G4InuclNuclei& inucl = output.getOutgoingNuclei().back();
818 
819  inucl.fill(ktrack->Get4Momentum()/GeV,
820  kpd->GetAtomicMass(), kpd->GetAtomicNumber());
821  if (verboseLevel > 2)
822  G4cout << " Created pre-cascade fragment\n" << inucl << G4endl;
823  } else {
824  // Use resize() and fill() to avoid memory churn
825  output.getOutgoingParticles().resize(output.numberOfOutgoingParticles()+1);
826  G4InuclElementaryParticle& ipart = output.getOutgoingParticles().back();
827 
828  // SPECIAL: Use G4PartDef directly, allowing unknown type code
829  ipart.fill(ktrack->Get4Momentum()/GeV, ktrack->GetDefinition());
830  if (verboseLevel > 2)
831  G4cout << " Created invalid pre-cascade particle\n" << ipart << G4endl;
832  }
833 }
void fill(G4int a, G4int z, G4double exc=0., Model model=DefaultModel)
const G4String & GetParticleName() const
G4int GetAtomicNumber() const
G4GLOB_DLL std::ostream G4cout
G4int numberOfOutgoingParticles() const
G4int GetAtomicMass() const
G4int numberOfOutgoingNuclei() const
const std::vector< G4InuclNuclei > & getOutgoingNuclei() const
const std::vector< G4InuclElementaryParticle > & getOutgoingParticles() const
static constexpr double GeV
Definition: G4SIunits.hh:217
void fill(G4int ityp, Model model=DefaultModel)
#define G4endl
Definition: G4ios.hh:61

Here is the call graph for this function:

Here is the caller graph for this function:

void G4IntraNucleiCascader::rescatter ( G4InuclParticle bullet,
G4KineticTrackVector theSecondaries,
G4V3DNucleus theNucleus,
G4CollisionOutput globalOutput 
)
virtual

Reimplemented from G4CascadeColliderBase.

Definition at line 228 of file G4IntraNucleiCascader.cc.

231  {
232  if (verboseLevel)
233  G4cout << " >>> G4IntraNucleiCascader::rescatter " << G4endl;
234 
235  G4InuclParticle* target = createTarget(theNucleus);
236  if (!initialize(bullet, target)) return; // Load buffers and drivers
237 
238  G4int itry = 0;
239  do { /* Loop checking 08.06.2015 MHK */
240  newCascade(++itry);
241  preloadCascade(theNucleus, theSecondaries);
242  generateCascade();
243  } while (!finishCascade() && itry<itry_max);
244 
245  // Report full structure of final cascade if requested
246  if (theCascadeHistory) theCascadeHistory->Print(G4cout);
247 
248  finalize(itry, bullet, target, globalOutput);
249 }
const XML_Char * target
Definition: expat.h:268
void Print(std::ostream &os) const
int G4int
Definition: G4Types.hh:78
G4InuclParticle * createTarget(G4V3DNucleus *theNucleus)
G4bool initialize(G4InuclParticle *bullet, G4InuclParticle *target)
G4GLOB_DLL std::ostream G4cout
#define G4endl
Definition: G4ios.hh:61
void finalize(G4int itry, G4InuclParticle *bullet, G4InuclParticle *target, G4CollisionOutput &globalOutput)
void preloadCascade(G4V3DNucleus *theNucleus, G4KineticTrackVector *theSecondaries)

Here is the call graph for this function:

Here is the caller graph for this function:

void G4IntraNucleiCascader::setupCascade ( )
protected

Definition at line 322 of file G4IntraNucleiCascader.cc.

322  {
323  if (verboseLevel > 1)
324  G4cout << " >>> G4IntraNucleiCascader::setupCascade" << G4endl;
325 
326  if (interCase.hadNucleus()) { // particle with nuclei
327  if (verboseLevel > 3)
328  G4cout << " bparticle charge " << bparticle->getCharge()
329  << " baryon number " << bparticle->baryon() << G4endl;
330 
331  cascad_particles.push_back(model->initializeCascad(bparticle));
332  } else { // nuclei with nuclei
333  G4int ab = bnuclei->getA();
334  G4int zb = bnuclei->getZ();
335 
336  G4NucleiModel::modelLists all_particles; // Buffer to receive lists
337  model->initializeCascad(bnuclei, tnuclei, all_particles);
338 
339  cascad_particles = all_particles.first;
340  output.addOutgoingParticles(all_particles.second);
341 
342  if (cascad_particles.size() == 0) { // compound nuclei
343  G4int i;
344 
345  for (i = 0; i < ab; i++) {
346  G4int knd = i < zb ? 1 : 2;
347  theExitonConfiguration.incrementQP(knd);
348  };
349 
350  G4int ihn = G4int(2 * (ab-zb) * inuclRndm() + 0.5);
351  G4int ihz = G4int(2 * zb * inuclRndm() + 0.5);
352 
353  for (i = 0; i < ihn; i++) theExitonConfiguration.incrementHoles(2);
354  for (i = 0; i < ihz; i++) theExitonConfiguration.incrementHoles(1);
355  }
356  } // if (interCase ...
357 }
G4bool hadNucleus() const
std::pair< std::vector< G4CascadParticle >, std::vector< G4InuclElementaryParticle > > modelLists
G4int getZ() const
int G4int
Definition: G4Types.hh:78
G4GLOB_DLL std::ostream G4cout
G4int getA() const
void addOutgoingParticles(const std::vector< G4InuclElementaryParticle > &particles)
static const G4double ab
G4double getCharge() const
#define G4endl
Definition: G4ios.hh:61
const XML_Char XML_Content * model
Definition: expat.h:151

Here is the call graph for this function:

Here is the caller graph for this function:

void G4IntraNucleiCascader::setVerboseLevel ( G4int  verbose = 0)
virtual

Reimplemented from G4CascadeColliderBase.

Definition at line 192 of file G4IntraNucleiCascader.cc.

192  {
194  model->setVerboseLevel(verbose);
195  theElementaryParticleCollider->setVerboseLevel(verbose);
196  theRecoilMaker->setVerboseLevel(verbose);
197 
198  // Optional functionality
199  if (theClusterMaker) theClusterMaker->setVerboseLevel(verbose);
200  if (theCascadeHistory) theCascadeHistory->setVerboseLevel(verbose);
201 }
void setVerboseLevel(G4int verbose)
virtual void setVerboseLevel(G4int verbose=0)
virtual void setVerboseLevel(G4int verbose=0)
void setVerboseLevel(G4int verbose=0)
const XML_Char XML_Content * model
Definition: expat.h:151

Here is the call graph for this function:

Here is the caller graph for this function:


The documentation for this class was generated from the following files: