Geant4  10.02
G4INCLBinaryCollisionAvatar.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  * G4INCLBinaryCollisionAvatar.cc
40  *
41  * \date Jun 5, 2009
42  * \author Pekka Kaitaniemi
43  */
44 
46 #include "G4INCLElasticChannel.hh"
50 #include "G4INCLCrossSections.hh"
51 #include "G4INCLKinematicsUtils.hh"
52 #include "G4INCLRandom.hh"
53 #include "G4INCLParticleTable.hh"
54 #include "G4INCLPauliBlocking.hh"
58 #include "G4INCLStore.hh"
59 #include "G4INCLBook.hh"
60 #include "G4INCLLogger.hh"
61 #include <string>
62 #include <sstream>
63 // #include <cassert>
64 
65 namespace G4INCL {
66 
67  // WARNING: if you update the default cutNN value, make sure you update the
68  // cutNNSquared variable, too.
70  G4ThreadLocal G4double BinaryCollisionAvatar::cutNNSquared = 3648100.0; // 1910.0 * 1910.0
71 
74  : InteractionAvatar(time, n, p1, p2), theCrossSection(crossSection),
75  isParticle1Spectator(false),
76  isParticle2Spectator(false),
77  isElastic(false)
78  {
80  }
81 
83  }
84 
86  // We already check cutNN at avatar creation time, but we have to check it
87  // again here. For composite projectiles, we might have created independent
88  // avatars with no cutNN before any collision took place.
89  if(particle1->isNucleon()
90  && particle2->isNucleon()
93  // Below a certain cut value we don't do anything:
94  if(energyCM2 < cutNNSquared) {
95  INCL_DEBUG("CM energy = sqrt(" << energyCM2 << ") MeV < std::sqrt(" << cutNNSquared
96  << ") MeV = cutNN" << "; returning a NULL channel" << '\n');
98  return NULL;
99  }
100  }
101 
121  ThreeVector minimumDistance = particle1->getPosition();
122  minimumDistance -= particle2->getPosition();
123  const G4double betaDotX = boostVector.dot(minimumDistance);
124  const G4double minDist = Math::tenPi*(minimumDistance.mag2() + betaDotX*betaDotX / (1.-boostVector.mag2()));
125  if(minDist > theCrossSection) {
126  INCL_DEBUG("CM distance of approach is too small: " << minDist << ">" <<
127  theCrossSection <<"; returning a NULL channel" << '\n');
129  return NULL;
130  }
131 
133  if(particle1->isNucleon() && particle2->isNucleon()) {
135  const G4double deltaProductionCX = CrossSections::NNToNDelta(particle1, particle2);
136  const G4double onePiProductionCX = CrossSections::NNToxPiNN(1,particle1, particle2);
137  const G4double twoPiProductionCX = CrossSections::NNToxPiNN(2,particle1, particle2);
138  const G4double threePiProductionCX = CrossSections::NNToxPiNN(3,particle1, particle2);
139  const G4double fourPiProductionCX = CrossSections::NNToxPiNN(4,particle1, particle2);
141 
142  const G4double rChannel=Random::shoot() * totCX;
143 
144  if(elasticCX > rChannel) {
145  // Elastic NN channel
146  isElastic = true;
147  INCL_DEBUG("NN interaction: elastic channel chosen" << '\n');
148  return new ElasticChannel(particle1, particle2);
149  } else if((elasticCX + deltaProductionCX) > rChannel) {
150  isElastic = false;
151  // NN -> N Delta channel is chosen
152  INCL_DEBUG("NN interaction: Delta channel chosen" << '\n');
154  } else if(elasticCX + deltaProductionCX + onePiProductionCX > rChannel) {
155  isElastic = false;
156  // NN -> PiNN channel is chosen
157  INCL_DEBUG("NN interaction: one Pion channel chosen" << '\n');
159  } else if(elasticCX + deltaProductionCX + onePiProductionCX + twoPiProductionCX > rChannel) {
160  isElastic = false;
161  // NN -> 2PiNN channel is chosen
162  INCL_DEBUG("NN interaction: two Pions channel chosen" << '\n');
164  } else if(elasticCX + deltaProductionCX + onePiProductionCX + twoPiProductionCX + threePiProductionCX > rChannel) {
165  isElastic = false;
166  // NN -> 3PiNN channel is chosen
167  INCL_DEBUG("NN interaction: three Pions channel chosen" << '\n');
169  } else if (elasticCX + deltaProductionCX + onePiProductionCX + twoPiProductionCX + threePiProductionCX + fourPiProductionCX > rChannel) {
170  isElastic = false;
171  // NN -> 4PiNN channel is chosen
172  INCL_DEBUG("NN interaction: four Pions channel chosen" << '\n');
174  } else {
175  INCL_WARN("inconsistency within the NN Cross Sections (sum!=inelastic)" << '\n');
176  if(fourPiProductionCX>0.) {
177  INCL_WARN("Returning a 4pi channel" << '\n');
178  isElastic = false;
180  } else if(threePiProductionCX>0.) {
181  INCL_WARN("Returning a 3pi channel" << '\n');
182  isElastic = false;
184  } else if(twoPiProductionCX>0.) {
185  INCL_WARN("Returning a 2pi channel" << '\n');
186  isElastic = false;
188  } else if(onePiProductionCX>0.) {
189  INCL_WARN("Returning a 1pi channel" << '\n');
190  isElastic = false;
192  } else if(deltaProductionCX>0.) {
193  INCL_WARN("Returning a delta-production channel" << '\n');
194  isElastic = false;
196  } else {
197  INCL_WARN("Returning an elastic channel" << '\n');
198  isElastic = true;
199  return new ElasticChannel(particle1, particle2);
200  }
201  }
202 
204  } else if((particle1->isNucleon() && particle2->isDelta()) ||
205  (particle1->isDelta() && particle2->isNucleon())) {
208 
209  if(elasticCX/(elasticCX + recombinationCX) < Random::shoot()) {
210  isElastic = false;
211  } else
212  isElastic = true;
213 
214  if(isElastic) {
215 // Elastic N Delta channel
216  INCL_DEBUG("NDelta interaction: elastic channel chosen" << '\n');
217  return new ElasticChannel(particle1, particle2);
218  } else { // Recombination
219 // N Delta -> NN channel is chosen
220  INCL_DEBUG("NDelta interaction: recombination channel chosen" << '\n');
222  }
223 
225  } else if(particle1->isDelta() && particle2->isDelta()) {
226  isElastic = true;
227  INCL_DEBUG("DeltaDelta interaction: elastic channel chosen" << '\n');
228  return new ElasticChannel(particle1, particle2);
229 
231  } else if(isPiN) {
233  const G4double deltaProductionCX = CrossSections::piNToDelta(particle1, particle2);
234  const G4double onePiProductionCX = CrossSections::piNToxPiN(2,particle1, particle2);
235  const G4double twoPiProductionCX = CrossSections::piNToxPiN(3,particle1, particle2);
236  const G4double threePiProductionCX = CrossSections::piNToxPiN(4,particle1, particle2);
238 // assert(std::fabs(totCX-elasticCX-deltaProductionCX-onePiProductionCX-twoPiProductionCX-threePiProductionCX)<1.);
239 
240  const G4double rChannel=Random::shoot() * totCX;
241 
242  if(elasticCX > rChannel) {
243  // Elastic PiN channel
244  isElastic = true;
245  INCL_DEBUG("PiN interaction: elastic channel chosen" << '\n');
247  } else if(elasticCX + deltaProductionCX > rChannel) {
248  isElastic = false;
249  // PiN -> Delta channel is chosen
250  INCL_DEBUG("PiN interaction: Delta channel chosen" << '\n');
252  } else if(elasticCX + deltaProductionCX + onePiProductionCX > rChannel) {
253  isElastic = false;
254  // PiN -> PiNPi channel is chosen
255  INCL_DEBUG("PiN interaction: one Pion channel chosen" << '\n');
257  } else if(elasticCX + deltaProductionCX + onePiProductionCX + twoPiProductionCX > rChannel) {
258  isElastic = false;
259  // PiN -> PiN2Pi channel is chosen
260  INCL_DEBUG("PiN interaction: two Pions channel chosen" << '\n');
262  } else if(elasticCX + deltaProductionCX + onePiProductionCX + twoPiProductionCX + threePiProductionCX > rChannel) {
263  isElastic = false;
264  // PiN -> PiN3Pi channel is chosen
265  INCL_DEBUG("PiN interaction: three Pions channel chosen" << '\n');
267  } else {
268  INCL_WARN("inconsistency within the PiN Cross Sections (sum!=inelastic)" << '\n');
269  if(threePiProductionCX>0.) {
270  INCL_WARN("Returning a 3pi channel" << '\n');
271  isElastic = false;
273  } else if(twoPiProductionCX>0.) {
274  INCL_WARN("Returning a 2pi channel" << '\n');
275  isElastic = false;
277  } else if(onePiProductionCX>0.) {
278  INCL_WARN("Returning a 1pi channel" << '\n');
279  isElastic = false;
281  } else if(deltaProductionCX>0.) {
282  INCL_WARN("Returning a delta-production channel" << '\n');
283  isElastic = false;
285  } else {
286  INCL_WARN("Returning an elastic channel" << '\n');
287  isElastic = true;
289  }
290  }
291  } else {
292  INCL_DEBUG("BinaryCollisionAvatar can only handle nucleons (for the moment)."
293  << '\n'
294  << particle1->print()
295  << '\n'
296  << particle2->print()
297  << '\n');
299  return NULL;
300  }
301  }
302 
307  }
308 
310  // Call the postInteraction method of the parent class
311  // (provides Pauli blocking and enforces energy conservation)
313 
314  switch(fs->getValidity()) {
315  case PauliBlockedFS:
317  break;
320  case ParticleBelowZeroFS:
321  break;
322  case ValidFS:
323  Book &theBook = theNucleus->getStore()->getBook();
324  theBook.incrementAcceptedCollisions();
325  if(theBook.getAcceptedCollisions() == 1) {
326  // Store time and cross section of the first collision
327  G4double t = theBook.getCurrentTime();
328  theBook.setFirstCollisionTime(t);
330 
331  // Store position and momentum of the spectator on the first
332  // collision
334  INCL_ERROR("First collision must be within a target spectator and a non-target spectator");
335  }
339  } else {
342  }
343 
344  // Store the elasticity of the first collision
346  }
347  }
348  return;
349  }
350 
351  std::string BinaryCollisionAvatar::dump() const {
352  std::stringstream ss;
353  ss << "(avatar " << theTime <<" 'nn-collision" << '\n'
354  << "(list " << '\n'
355  << particle1->dump()
356  << particle2->dump()
357  << "))" << '\n';
358  return ss.str();
359  }
360 
361 }
FinalStateValidity getValidity() const
void incrementBlockedCollisions()
Definition: G4INCLBook.hh:73
G4double dot(const ThreeVector &v) const
Dot product.
Channel generates a final state of an avatar.
G4int getAcceptedCollisions() const
Definition: G4INCLBook.hh:100
G4double squareTotalEnergyInCM(Particle const *const p1, Particle const *const p2)
const G4double tenPi
#define INCL_ERROR(x)
G4bool isTargetSpectator() const
const G4INCL::ThreeVector & getMomentum() const
Get the momentum vector.
Store * getStore() const
G4bool isDelta() const
Is it a Delta?
std::string print() const
G4double NDeltaToNN(Particle const *const p1, Particle const *const p2)
#define INCL_WARN(x)
#define G4ThreadLocal
Definition: tls.hh:89
virtual void postInteraction(FinalState *)
G4double mag2() const
Get the square of the length.
static G4ThreadLocal Particle * backupParticle2
void incrementAcceptedCollisions()
Definition: G4INCLBook.hh:72
Final state of an interaction.
void setType(AvatarType t)
Book & getBook()
Return the pointer to the Book object which keeps track of various counters.
Definition: G4INCLStore.hh:259
void setFirstCollisionXSec(const G4double x)
Definition: G4INCLBook.hh:85
static G4ThreadLocal Particle * backupParticle1
G4double NNToNDelta(Particle const *const p1, Particle const *const p2)
const G4int n
void setFirstCollisionTime(const G4double t)
Definition: G4INCLBook.hh:82
static G4ThreadLocal G4double cutNNSquared
static G4ThreadLocal G4double cutNN
Delta-nucleon recombination channel.
G4double total(Particle const *const p1, Particle const *const p2)
const G4INCL::ThreeVector & getPosition() const
Set the position vector.
std::string dump() const
G4double piNToDelta(Particle const *const p1, Particle const *const p2)
G4bool isNucleon() const
Is this a nucleon?
G4double shoot()
Generate flat distribution of random numbers.
Definition: G4INCLRandom.cc:93
G4double piNToxPiN(const G4int xpi, Particle const *const p1, Particle const *const p2)
void restoreParticles() const
Restore the state of both particles.
G4double mag() const
Get the length of the vector.
BinaryCollisionAvatar(G4double, G4double, G4INCL::Nucleus *, G4INCL::Particle *, G4INCL::Particle *)
double G4double
Definition: G4Types.hh:76
G4double getCurrentTime() const
Definition: G4INCLBook.hh:98
#define INCL_DEBUG(x)
void setFirstCollisionIsElastic(const G4bool e)
Definition: G4INCLBook.hh:94
G4double NNToxPiNN(const G4int xpi, Particle const *const p1, Particle const *const p2)
void setFirstCollisionSpectatorMomentum(const G4double x)
Definition: G4INCLBook.hh:91
G4double elastic(Particle const *const p1, Particle const *const p2)
void setFirstCollisionSpectatorPosition(const G4double x)
Definition: G4INCLBook.hh:88