Geant4  10.00.p02
G4INCLParticle.hh
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 // Pekka Kaitaniemi, CEA and Helsinki Institute of Physics
28 // Davide Mancusi, CEA
29 // Alain Boudard, CEA
30 // Sylvie Leray, CEA
31 // Joseph Cugnon, University of Liege
32 //
33 #define INCLXX_IN_GEANT4_MODE 1
34 
35 #include "globals.hh"
36 
37 /*
38  * Particle.hh
39  *
40  * \date Jun 5, 2009
41  * \author Pekka Kaitaniemi
42  */
43 
44 #ifndef PARTICLE_HH_
45 #define PARTICLE_HH_
46 
47 #include "G4INCLThreeVector.hh"
48 #include "G4INCLParticleTable.hh"
49 #include "G4INCLParticleType.hh"
50 #include "G4INCLParticleSpecies.hh"
51 #include "G4INCLLogger.hh"
52 #include <vector>
53 #include <sstream>
54 #include <string>
55 #include <algorithm>
56 
57 namespace G4INCL {
58 
59  class Particle;
60 
61  template<class T>
62  class UnorderedVector : private std::vector<T> {
63  public:
65  using std::vector<T>::push_back;
66  using std::vector<T>::pop_back;
67  using std::vector<T>::size;
68  using std::vector<T>::begin;
69  using std::vector<T>::end;
70  using std::vector<T>::rbegin;
71  using std::vector<T>::rend;
72  using std::vector<T>::front;
73  using std::vector<T>::back;
74  using std::vector<T>::clear;
75  using std::vector<T>::empty;
76  using std::vector<T>::insert;
77  using std::vector<T>::erase;
78  using typename std::vector<T>::iterator;
79  using typename std::vector<T>::reverse_iterator;
80  using typename std::vector<T>::const_iterator;
81  using typename std::vector<T>::const_reverse_iterator;
82  void remove(const T &t) {
83  const typename std::vector<T>::iterator removeMe = std::find(begin(), end(), t);
84 // assert(removeMe!=end());
85  *removeMe = back();
86  pop_back();
87  }
88  };
89 
91  typedef ParticleList::const_iterator ParticleIter;
92  typedef ParticleList::iterator ParticleMutableIter;
93 
94  class Particle {
95  public:
96  Particle();
98  Particle(ParticleType t, ThreeVector const &momentum, ThreeVector const &position);
99  virtual ~Particle() {}
100 
105  Particle(const Particle &rhs) :
106  theZ(rhs.theZ),
107  theA(rhs.theA),
109  theType(rhs.theType),
110  theEnergy(rhs.theEnergy),
116  nDecays(rhs.nDecays),
122  outOfWell(rhs.outOfWell),
123  theMass(rhs.theMass)
124  {
125  if(rhs.thePropagationEnergy == &(rhs.theFrozenEnergy))
127  else
129  if(rhs.thePropagationMomentum == &(rhs.theFrozenMomentum))
131  else
133  // ID intentionally not copied
134  ID = nextID++;
135  }
136 
137  protected:
139  void swap(Particle &rhs) {
140  std::swap(theZ, rhs.theZ);
141  std::swap(theA, rhs.theA);
142  std::swap(theParticipantType, rhs.theParticipantType);
143  std::swap(theType, rhs.theType);
144  if(rhs.thePropagationEnergy == &(rhs.theFrozenEnergy))
146  else
148  std::swap(theEnergy, rhs.theEnergy);
149  std::swap(theFrozenEnergy, rhs.theFrozenEnergy);
150  if(rhs.thePropagationMomentum == &(rhs.theFrozenMomentum))
152  else
154  std::swap(theMomentum, rhs.theMomentum);
155  std::swap(theFrozenMomentum, rhs.theFrozenMomentum);
156  std::swap(thePosition, rhs.thePosition);
157  std::swap(nCollisions, rhs.nCollisions);
158  std::swap(nDecays, rhs.nDecays);
159  std::swap(thePotentialEnergy, rhs.thePotentialEnergy);
160  // ID intentionally not swapped
161 
162  std::swap(theHelicity, rhs.theHelicity);
163  std::swap(emissionTime, rhs.emissionTime);
164  std::swap(outOfWell, rhs.outOfWell);
165 
166  std::swap(theMass, rhs.theMass);
167  std::swap(rpCorrelated, rhs.rpCorrelated);
169  }
170 
171  public:
172 
177  Particle &operator=(const Particle &rhs) {
178  Particle temporaryParticle(rhs);
179  swap(temporaryParticle);
180  return *this;
181  }
182 
188  return theType;
189  };
190 
193  return ParticleSpecies(theType);
194  };
195 
197  theType = t;
198  switch(theType)
199  {
200  case DeltaPlusPlus:
201  theA = 1;
202  theZ = 2;
203  break;
204  case Proton:
205  case DeltaPlus:
206  theA = 1;
207  theZ = 1;
208  break;
209  case Neutron:
210  case DeltaZero:
211  theA = 1;
212  theZ = 0;
213  break;
214  case DeltaMinus:
215  theA = 1;
216  theZ = -1;
217  break;
218  case PiPlus:
219  theA = 0;
220  theZ = 1;
221  break;
222  case PiZero:
223  theA = 0;
224  theZ = 0;
225  break;
226  case PiMinus:
227  theA = 0;
228  theZ = -1;
229  break;
230  case Composite:
231  // INCL_ERROR("Trying to set particle type to Composite! Construct a Cluster object instead" << std::endl);
232  theA = 0;
233  theZ = 0;
234  break;
235  case UnknownParticle:
236  theA = 0;
237  theZ = 0;
238  INCL_ERROR("Trying to set particle type to Unknown!" << std::endl);
239  break;
240  }
241 
242  if( !isResonance() && t!=Composite )
243  setINCLMass();
244  }
245 
249  G4bool isNucleon() const {
251  return true;
252  else
253  return false;
254  };
255 
257  return theParticipantType;
258  }
259 
261  theParticipantType = p;
262  }
263 
266  }
267 
270  }
271 
274  }
275 
276  virtual void makeParticipant() {
278  }
279 
280  virtual void makeTargetSpectator() {
282  }
283 
284  virtual void makeProjectileSpectator() {
286  }
287 
289  G4bool isPion() const { return (theType == PiPlus || theType == PiZero || theType == PiMinus); }
290 
292  inline G4bool isResonance() const { return isDelta(); }
293 
295  inline G4bool isDelta() const {
296  return (theType==DeltaPlusPlus || theType==DeltaPlus ||
298  }
299 
301  G4int getA() const { return theA; }
302 
304  G4int getZ() const { return theZ; }
305 
306  G4double getBeta() const {
307  const G4double P = theMomentum.mag();
308  return P/theEnergy;
309  }
310 
318  return theMomentum / theEnergy;
319  }
320 
327  void boost(const ThreeVector &aBoostVector) {
328  const G4double beta2 = aBoostVector.mag2();
329  const G4double gamma = 1.0 / std::sqrt(1.0 - beta2);
330  const G4double bp = theMomentum.dot(aBoostVector);
331  const G4double alpha = (gamma*gamma)/(1.0 + gamma);
332 
333  theMomentum = theMomentum + aBoostVector * (alpha * bp - gamma * theEnergy);
334  theEnergy = gamma * (theEnergy - bp);
335  }
336 
345  void lorentzContract(const ThreeVector &aBoostVector, const ThreeVector &refPos) {
346  const G4double beta2 = aBoostVector.mag2();
347  const G4double gamma = 1.0 / std::sqrt(1.0 - beta2);
348  const ThreeVector theRelativePosition = thePosition - refPos;
349  const ThreeVector transversePosition = theRelativePosition - aBoostVector * (theRelativePosition.dot(aBoostVector) / aBoostVector.mag2());
350  const ThreeVector longitudinalPosition = theRelativePosition - transversePosition;
351 
352  thePosition = refPos + transversePosition + longitudinalPosition / gamma;
353  }
354 
356  inline G4double getMass() const { return theMass; }
357 
359  inline G4double getINCLMass() const {
360  switch(theType) {
361  case Proton:
362  case Neutron:
363  case PiPlus:
364  case PiMinus:
365  case PiZero:
367  break;
368 
369  case DeltaPlusPlus:
370  case DeltaPlus:
371  case DeltaZero:
372  case DeltaMinus:
373  return theMass;
374  break;
375 
376  case Composite:
378  break;
379 
380  default:
381  INCL_ERROR("Particle::getINCLMass: Unknown particle type." << std::endl);
382  return 0.0;
383  break;
384  }
385  }
386 
388  inline virtual G4double getTableMass() const {
389  switch(theType) {
390  case Proton:
391  case Neutron:
392  case PiPlus:
393  case PiMinus:
394  case PiZero:
396  break;
397 
398  case DeltaPlusPlus:
399  case DeltaPlus:
400  case DeltaZero:
401  case DeltaMinus:
402  return theMass;
403  break;
404 
405  case Composite:
407  break;
408 
409  default:
410  INCL_ERROR("Particle::getTableMass: Unknown particle type." << std::endl);
411  return 0.0;
412  break;
413  }
414  }
415 
417  inline G4double getRealMass() const {
418  switch(theType) {
419  case Proton:
420  case Neutron:
421  case PiPlus:
422  case PiMinus:
423  case PiZero:
425  break;
426 
427  case DeltaPlusPlus:
428  case DeltaPlus:
429  case DeltaZero:
430  case DeltaMinus:
431  return theMass;
432  break;
433 
434  case Composite:
436  break;
437 
438  default:
439  INCL_ERROR("Particle::getRealMass: Unknown particle type." << std::endl);
440  return 0.0;
441  break;
442  }
443  }
444 
447 
450 
453 
465  G4double getEmissionQValueCorrection(const G4int AParent, const G4int ZParent) const {
466  const G4int ADaughter = AParent - theA;
467  const G4int ZDaughter = ZParent - theZ;
468 
469  // Note the minus sign here
470  G4double theQValue;
471  if(isCluster())
472  theQValue = -ParticleTable::getTableQValue(theA, theZ, ADaughter, ZDaughter);
473  else {
474  const G4double massTableParent = ParticleTable::getTableMass(AParent,ZParent);
475  const G4double massTableDaughter = ParticleTable::getTableMass(ADaughter,ZDaughter);
476  const G4double massTableParticle = getTableMass();
477  theQValue = massTableParent - massTableDaughter - massTableParticle;
478  }
479 
480  const G4double massINCLParent = ParticleTable::getINCLMass(AParent,ZParent);
481  const G4double massINCLDaughter = ParticleTable::getINCLMass(ADaughter,ZDaughter);
482  const G4double massINCLParticle = getINCLMass();
483 
484  // The rhs corresponds to the INCL Q-value
485  return theQValue - (massINCLParent-massINCLDaughter-massINCLParticle);
486  }
487 
503  G4double getTransferQValueCorrection(const G4int AFrom, const G4int ZFrom, const G4int ATo, const G4int ZTo) const {
504  const G4int AFromDaughter = AFrom - theA;
505  const G4int ZFromDaughter = ZFrom - theZ;
506  const G4int AToDaughter = ATo + theA;
507  const G4int ZToDaughter = ZTo + theZ;
508  const G4double theQValue = ParticleTable::getTableQValue(AToDaughter,ZToDaughter,AFromDaughter,ZFromDaughter,AFrom,ZFrom);
509 
510  const G4double massINCLTo = ParticleTable::getINCLMass(ATo,ZTo);
511  const G4double massINCLToDaughter = ParticleTable::getINCLMass(AToDaughter,ZToDaughter);
512  /* Note that here we have to use the table mass in the INCL Q-value. We
513  * cannot use theMass, because at this stage the particle is probably
514  * still off-shell; and we cannot use getINCLMass(), because it leads to
515  * violations of global energy conservation.
516  */
517  const G4double massINCLParticle = getTableMass();
518 
519  // The rhs corresponds to the INCL Q-value for particle absorption
520  return theQValue - (massINCLToDaughter-massINCLTo-massINCLParticle);
521  }
522 
529  const G4double mass = std::pow(theEnergy, 2) - theMomentum.dot(theMomentum);
530  if(mass < 0.0) {
531  INCL_ERROR("E*E - p*p is negative." << std::endl);
532  return 0.0;
533  } else {
534  return std::sqrt(mass);
535  }
536  };
537 
539  inline G4double getKineticEnergy() const { return theEnergy - theMass; }
540 
542  inline G4double getPotentialEnergy() const { return thePotentialEnergy; }
543 
546 
551  {
552  return theEnergy;
553  };
554 
558  void setMass(G4double mass)
559  {
560  this->theMass = mass;
561  }
562 
566  void setEnergy(G4double energy)
567  {
568  this->theEnergy = energy;
569  };
570 
575  {
576  return theMomentum;
577  };
578 
581  {
583  };
584 
588  virtual void setMomentum(const G4INCL::ThreeVector &momentum)
589  {
590  this->theMomentum = momentum;
591  };
592 
597  {
598  return thePosition;
599  };
600 
601  virtual void setPosition(const G4INCL::ThreeVector &position)
602  {
603  this->thePosition = position;
604  };
605 
607  void setHelicity(G4double h) { theHelicity = h; };
608 
609  void propagate(G4double step) {
610  thePosition += ((*thePropagationMomentum)*(step/(*thePropagationEnergy)));
611  };
612 
615 
618 
621 
623  G4int getNumberOfDecays() const { return nDecays; }
624 
627 
630 
639  void setOutOfWell() { outOfWell = true; }
640 
642  G4bool isOutOfWell() const { return outOfWell; }
643 
646 
650  }
651 
655  }
656 
659 
662 
664  G4bool isInList(ParticleList const &l) const {
665  return (std::find(l.begin(), l.end(), this)!=l.end());
666  }
667 
668  G4bool isCluster() const {
669  return (theType == Composite);
670  }
671 
673  void setFrozenMomentum(const ThreeVector &momentum) { theFrozenMomentum = momentum; }
674 
676  void setFrozenEnergy(const G4double energy) { theFrozenEnergy = energy; }
677 
680 
683 
685  ThreeVector getPropagationVelocity() const { return (*thePropagationMomentum)/(*thePropagationEnergy); }
686 
696  }
697 
707  }
708 
714  virtual void rotate(const G4double angle, const ThreeVector &axis) {
715  thePosition.rotate(angle, axis);
716  theMomentum.rotate(angle, axis);
717  theFrozenMomentum.rotate(angle, axis);
718  }
719 
720  std::string print() const {
721  std::stringstream ss;
722  ss << "Particle (ID = " << ID << ") type = ";
724  ss << std::endl
725  << " energy = " << theEnergy << std::endl
726  << " momentum = "
727  << theMomentum.print()
728  << std::endl
729  << " position = "
730  << thePosition.print()
731  << std::endl;
732  return ss.str();
733  };
734 
735  std::string dump() const {
736  std::stringstream ss;
737  ss << "(particle " << ID << " ";
739  ss << std::endl
740  << thePosition.dump()
741  << std::endl
742  << theMomentum.dump()
743  << std::endl
744  << theEnergy << ")" << std::endl;
745  return ss.str();
746  };
747 
748  long getID() const { return ID; };
749 
753  ParticleList const *getParticles() const {
754  INCL_WARN("Particle::getParticles() method was called on a Particle object" << std::endl);
755  return 0;
756  }
757 
765  if(rpCorrelated)
766  return theMomentum.mag();
767  else
768  return uncorrelatedMomentum;
769  }
770 
773 
775  void rpCorrelate() { rpCorrelated = true; }
776 
778  void rpDecorrelate() { rpCorrelated = false; }
779 
783  if(norm>0.)
784  return thePosition.dot(*thePropagationMomentum) / std::sqrt(norm);
785  else
786  return 1.;
787  }
788 
789  protected:
803  long ID;
804 
807 
808  private:
812 
814  static G4ThreadLocal long nextID;
815 
816  };
817 }
818 
819 #endif /* PARTICLE_HH_ */
G4int getA() const
Returns the baryon number.
ParticipantType theParticipantType
void setParticipantType(ParticipantType const p)
G4double getCosRPAngle() const
Get the cosine of the angle between position and momentum.
G4int getNumberOfCollisions() const
Return the number of collisions undergone by the particle.
void setMass(G4double mass)
Set the mass of the particle in MeV/c^2.
G4bool isResonance() const
Is it a resonance?
virtual void makeTargetSpectator()
G4double getReflectionMomentum() const
Return the reflection momentum.
G4double getMass() const
Get the cached particle mass.
G4bool isInList(ParticleList const &l) const
Check if the particle belongs to a given list.
G4double * thePropagationEnergy
G4double getBeta() const
G4ThreadLocal ParticleMassFn getTableParticleMass
Static pointer to the mass function for particles.
G4double dot(const ThreeVector &v) const
Dot product.
void rotate(const G4double angle, const ThreeVector &axis)
Rotate the vector by a given angle around a given axis.
G4double getEmissionTime()
ThreeVector getPropagationVelocity() const
Get the propagation velocity of the particle.
void setEmissionTime(G4double t)
G4INCL::ThreeVector theFrozenMomentum
G4double getTableQValue(const G4int A1, const G4int Z1, const G4int A2, const G4int Z2)
Get Q-value (in MeV/c^2)
#define INCL_ERROR(x)
G4bool isTargetSpectator() const
void boost(const ThreeVector &aBoostVector)
Boost the particle using a boost vector.
const G4INCL::ThreeVector & getMomentum() const
Get the momentum vector.
G4double adjustEnergyFromMomentum()
Recompute the energy to match the momentum.
G4bool isDelta() const
Is it a Delta?
std::string print() const
G4double getEnergy() const
Get the energy of the particle in MeV.
void setINCLMass()
Set the mass of the Particle to its table mass.
void thawPropagation()
Unfreeze particle propagation.
#define INCL_WARN(x)
virtual void makeProjectileSpectator()
void propagate(G4double step)
void setOutOfWell()
Mark the particle as out of its potential well.
G4double getINCLMass() const
Get the INCL particle mass.
void incrementNumberOfCollisions()
Increment the number of collisions undergone by the particle.
G4bool isParticipant() const
void setUncorrelatedMomentum(const G4double p)
Set the uncorrelated momentum.
G4double uncorrelatedMomentum
#define G4ThreadLocal
Definition: tls.hh:52
ThreeVector boostVector() const
Returns a three vector we can give to the boost() -method.
int G4int
Definition: G4Types.hh:78
ThreeVector vector(const ThreeVector &v) const
Vector product.
G4double mag2() const
Get the square of the length.
G4double getPotentialEnergy() const
Get the particle potential energy.
ParticleList const * getParticles() const
Return a NULL pointer.
void incrementNumberOfDecays()
Increment the number of decays undergone by the particle.
G4double getInvariantMass() const
Get the the particle invariant mass.
void rpCorrelate()
Make the particle follow a strict r-p correlation.
virtual void rotate(const G4double angle, const ThreeVector &axis)
Rotate the particle position and momentum.
void setEnergy(G4double energy)
Set the energy of the particle in MeV.
G4double getRealMass(const G4INCL::ParticleType t)
Get particle mass (in MeV/c^2)
UnorderedVector< Particle * > ParticleList
void rpDecorrelate()
Make the particle not follow a strict r-p correlation.
void setNumberOfDecays(G4int n)
Set the number of decays undergone by the particle.
G4double getTransferQValueCorrection(const G4int AFrom, const G4int ZFrom, const G4int ATo, const G4int ZTo) const
Computes correction on the transfer Q-value.
ParticipantType getParticipantType() const
bool G4bool
Definition: G4Types.hh:79
void lorentzContract(const ThreeVector &aBoostVector, const ThreeVector &refPos)
Lorentz-contract the particle position around some center.
virtual G4INCL::ThreeVector getAngularMomentum() const
Get the angular momentum w.r.t.
virtual void setPosition(const G4INCL::ThreeVector &position)
G4int getZ() const
Returns the charge number.
void setPotentialEnergy(G4double v)
Set the particle potential energy.
static G4ThreadLocal long nextID
std::string dump() const
const G4int n
G4bool isOutOfWell() const
Check if the particle is out of its potential well.
G4INCL::ThreeVector thePosition
ThreeVector getFrozenMomentum() const
Get the frozen particle momentum.
ThreeVector getTransversePosition() const
Transverse component of the position w.r.t.
Particle(const Particle &rhs)
Copy constructor.
G4INCL::ParticleType theType
void setFrozenMomentum(const ThreeVector &momentum)
Set the frozen particle momentum.
G4double getINCLMass(const G4int A, const G4int Z)
Get INCL nuclear mass (in MeV/c^2)
G4int getNumberOfDecays() const
Return the number of decays undergone by the particle.
G4INCL::ParticleType getType() const
Get the particle type.
G4double energy(const ThreeVector &p, const G4double m)
G4ThreadLocal NuclearMassFn getTableMass
Static pointer to the mass function for nuclei.
void setTableMass()
Set the mass of the Particle to its table mass.
int position
Definition: filter.cc:7
const G4INCL::ThreeVector & getPosition() const
Set the position vector.
void setRealMass()
Set the mass of the Particle to its real mass.
void swap(Particle &rhs)
Helper method for the assignment operator.
G4bool isProjectileSpectator() const
void setType(ParticleType t)
static const G4double bp
std::string dump() const
void setNumberOfCollisions(G4int n)
Set the number of collisions undergone by the particle.
G4double getHelicity()
Particle & operator=(const Particle &rhs)
Assignment operator.
G4bool isNucleon() const
Is this a nucleon?
G4bool isCluster() const
G4INCL::ThreeVector theMomentum
virtual G4double getTableMass() const
Get the tabulated particle mass.
std::string print() const
G4double getKineticEnergy() const
Get the particle kinetic energy.
virtual G4INCL::ParticleSpecies getSpecies() const
Get the particle species.
G4double getRealMass() const
Get the real particle mass.
virtual void makeParticipant()
G4double mag() const
Get the length of the vector.
double G4double
Definition: G4Types.hh:76
G4double theFrozenEnergy
G4double getEmissionQValueCorrection(const G4int AParent, const G4int ZParent) const
Computes correction on the emission Q-value.
G4INCL::ThreeVector * thePropagationMomentum
static const G4double alpha
G4bool isPion() const
Is this a pion?
const ThreeVector & adjustMomentumFromEnergy()
Rescale the momentum to match the total energy.
ParticleList::iterator ParticleMutableIter
G4double thePotentialEnergy
ThreeVector getLongitudinalPosition() const
Longitudinal component of the position w.r.t.
ParticleList::const_iterator ParticleIter
std::string getName(const ParticleType t)
Get the native INCL name of the particle.
long getID() const
void setHelicity(G4double h)
virtual void setMomentum(const G4INCL::ThreeVector &momentum)
Set the momentum vector.
void setFrozenEnergy(const G4double energy)
Set the frozen particle momentum.
void freezePropagation()
Freeze particle propagation.
G4double getFrozenEnergy() const
Get the frozen particle momentum.