Geant4  10.00.p02
G4INCLCluster.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 #ifndef G4INCLCluster_hh
38 #define G4INCLCluster_hh 1
39 
40 #include "G4INCLParticle.hh"
42 #include "G4INCLParticleSampler.hh"
43 
44 namespace G4INCL {
45 
50  class Cluster : public Particle {
51  public:
52 
58  Cluster(const G4int Z, const G4int A, const G4bool createParticleSampler=true) :
59  Particle(),
61  theSpin(0.,0.,0.),
62  theParticleSampler(NULL)
63  {
65  theZ = Z;
66  theA = A;
67  setINCLMass();
68  if(createParticleSampler)
70  }
71 
75  template<class Iterator>
76  Cluster(Iterator begin, Iterator end) :
77  Particle(),
79  theSpin(0.,0.,0.),
80  theParticleSampler(NULL)
81  {
83  for(Iterator i = begin; i != end; ++i) {
84  addParticle(*i);
85  }
86  thePosition /= theA;
87  setINCLMass();
89  }
90 
91  virtual ~Cluster() {
92  delete theParticleSampler;
93  }
94 
96  Cluster(const Cluster &rhs) :
97  Particle(rhs),
99  theSpin(rhs.theSpin)
100  {
101  for(ParticleIter p=rhs.particles.begin(), e=rhs.particles.end(); p!=e; ++p) {
102  particles.push_back(new Particle(**p));
103  }
104  if(rhs.theParticleSampler)
106  else
107  theParticleSampler = NULL;
108  }
109 
111  Cluster &operator=(const Cluster &rhs) {
112  Cluster temporaryCluster(rhs);
113  Particle::operator=(temporaryCluster);
114  swap(temporaryCluster);
115  return *this;
116  }
117 
119  void swap(Cluster &rhs) {
120  Particle::swap(rhs);
122  std::swap(theSpin, rhs.theSpin);
123  // std::swap is overloaded by std::list and guaranteed to operate in
124  // constant time
125  std::swap(particles, rhs.particles);
126  std::swap(theParticleSampler, rhs.theParticleSampler);
127  }
128 
130  return ParticleSpecies(theA, theZ);
131  }
132 
134  for(ParticleIter p=particles.begin(), e=particles.end(); p!=e; ++p) {
135  delete (*p);
136  }
137  clearParticles();
138  }
139 
140  void clearParticles() { particles.clear(); }
141 
143  void setZ(const G4int Z) { theZ = Z; }
144 
146  void setA(const G4int A) { theA = A; }
147 
150 
153 
158  inline virtual G4double getTableMass() const { return getRealMass(); }
159 
163  ParticleList const &getParticles() const { return particles; }
164 
166  void removeParticle(Particle * const p) { particles.remove(p); }
167 
172  void addParticle(Particle * const p) {
173 // assert(p->isNucleon());
174  particles.push_back(p);
175  theEnergy += p->getEnergy();
177  theMomentum += p->getMomentum();
178  thePosition += p->getPosition();
179  theA += p->getA();
180  theZ += p->getZ();
182  }
183 
185  void addParticles(ParticleList const &pL) {
186  for(ParticleIter p=pL.begin(), e=pL.end(); p!=e; ++p)
187  addParticle(*p);
188  }
189 
192 
193  std::string print() const {
194  std::stringstream ss;
195  ss << "Cluster (ID = " << ID << ") type = ";
197  ss << std::endl
198  << " A = " << theA << std::endl
199  << " Z = " << theZ << std::endl
200  << " mass = " << getMass() << std::endl
201  << " energy = " << theEnergy << std::endl
202  << " momentum = "
203  << theMomentum.print()
204  << std::endl
205  << " position = "
206  << thePosition.print()
207  << std::endl
208  << "Contains the following particles:"
209  << std::endl;
210  for(ParticleIter i=particles.begin(), e=particles.end(); i!=e; ++i)
211  ss << (*i)->print();
212  ss << std::endl;
213  return ss.str();
214  }
215 
217  virtual void initializeParticles();
218 
226 
227  // First compute the current CM position and total momentum
228  ThreeVector theCMPosition, theTotalMomentum;
229  G4double theTotalEnergy = 0.0;
230  for(ParticleIter p=particles.begin(), e=particles.end(); p!=e; ++p) {
231  theCMPosition += (*p)->getPosition();
232  theTotalMomentum += (*p)->getMomentum();
233  theTotalEnergy += (*p)->getEnergy();
234  }
235  theCMPosition /= theA;
236 // assert((unsigned int)theA==particles.size());
237 
238  // Now determine the CM velocity of the particles
239  // commented out because currently unused, see below
240  // ThreeVector betaCM = theTotalMomentum / theTotalEnergy;
241 
242  // The new particle positions and momenta are scaled by a factor of
243  // \f$\sqrt{A/(A-1)}\f$, so that the resulting density distributions in
244  // the CM have the same variance as the one we started with.
245  const G4double rescaling = std::sqrt(((G4double)theA)/((G4double)(theA-1)));
246 
247  // Loop again to boost and reposition
248  for(ParticleIter p=particles.begin(), e=particles.end(); p!=e; ++p) {
249  // \bug{We should do the following, but the Fortran version actually
250  // does not!
251  // (*p)->boost(betaCM);
252  // Here is what the Fortran version does:}
253  (*p)->setMomentum(((*p)->getMomentum()-theTotalMomentum/theA)*rescaling);
254 
255  // Set the CM position of the particles
256  (*p)->setPosition(((*p)->getPosition()-theCMPosition)*rescaling);
257  }
258 
259  // Set the global cluster kinematic variables
260  thePosition.setX(0.0);
261  thePosition.setY(0.0);
262  thePosition.setZ(0.0);
263  theMomentum.setX(0.0);
264  theMomentum.setY(0.0);
265  theMomentum.setZ(0.0);
266  theEnergy = getMass();
267 
268  INCL_DEBUG("Cluster boosted to internal CM:" << std::endl << print());
269 
270  }
271 
278  // Compute the dynamical potential
279  const G4double theDynamicalPotential = computeDynamicalPotential();
280  INCL_DEBUG("The dynamical potential is " << theDynamicalPotential << " MeV" << std::endl);
281 
282  for(ParticleIter p=particles.begin(), e=particles.end(); p!=e; ++p) {
283  const G4double energy = (*p)->getEnergy() - theDynamicalPotential;
284  const ThreeVector &momentum = (*p)->getMomentum();
285  // Here particles are put off-shell so that we can satisfy the energy-
286  // and momentum-conservation laws
287  (*p)->setEnergy(energy);
288  (*p)->setMass(std::sqrt(energy*energy - momentum.mag2()));
289  }
290  INCL_DEBUG("Cluster components are now off shell:" << std::endl
291  << print());
292  }
293 
300  ThreeVector shift(position-thePosition);
301  Particle::setPosition(position);
302  for(ParticleIter p=particles.begin(), e=particles.end(); p!=e; ++p) {
303  (*p)->setPosition((*p)->getPosition()+shift);
304  }
305  }
306 
315  void boost(const ThreeVector &aBoostVector) {
316  Particle::boost(aBoostVector);
317  for(ParticleIter p=particles.begin(), e=particles.end(); p!=e; ++p) {
318  (*p)->boost(aBoostVector);
319  // Apply Lorentz contraction to the particle position
320  (*p)->lorentzContract(aBoostVector,thePosition);
321  (*p)->rpCorrelate();
322  }
323 
324  INCL_DEBUG("Cluster was boosted with (bx,by,bz)=("
325  << aBoostVector.getX() << ", " << aBoostVector.getY() << ", " << aBoostVector.getZ() << "):"
326  << std::endl << print());
327 
328  }
329 
339  const ThreeVector &normMomentum = theMomentum / getMass();
340  for(ParticleIter p=particles.begin(), e=particles.end(); p!=e; ++p) {
341  const G4double pMass = (*p)->getMass();
342  const ThreeVector frozenMomentum = normMomentum * pMass;
343  const G4double frozenEnergy = std::sqrt(frozenMomentum.mag2()+pMass*pMass);
344  (*p)->setFrozenMomentum(frozenMomentum);
345  (*p)->setFrozenEnergy(frozenEnergy);
346  (*p)->freezePropagation();
347  }
348  }
349 
357  virtual void rotate(const G4double angle, const ThreeVector &axis) {
358  Particle::rotate(angle, axis);
359  for(ParticleIter p=particles.begin(), e=particles.end(); p!=e; ++p) {
360  (*p)->rotate(angle, axis);
361  }
362  }
363 
365  virtual void makeProjectileSpectator() {
367  for(ParticleIter p=particles.begin(), e=particles.end(); p!=e; ++p) {
368  (*p)->makeProjectileSpectator();
369  }
370  }
371 
373  virtual void makeTargetSpectator() {
375  for(ParticleIter p=particles.begin(), e=particles.end(); p!=e; ++p) {
376  (*p)->makeTargetSpectator();
377  }
378  }
379 
381  virtual void makeParticipant() {
383  for(ParticleIter p=particles.begin(), e=particles.end(); p!=e; ++p) {
384  (*p)->makeParticipant();
385  }
386  }
387 
389  ThreeVector const &getSpin() const { return theSpin; }
390 
392  void setSpin(const ThreeVector &j) { theSpin = j; }
393 
397  }
398 
399  private:
407  G4double theDynamicalPotential = 0.0;
408  for(ParticleIter p=particles.begin(), e=particles.end(); p!=e; ++p) {
409  theDynamicalPotential += (*p)->getEnergy();
410  }
411  theDynamicalPotential -= getTableMass();
412  theDynamicalPotential /= theA;
413 
414  return theDynamicalPotential;
415  }
416 
417  protected:
422 
423  };
424 
425 }
426 
427 #endif
G4int getA() const
Returns the baryon number.
G4int getNumberOfCollisions() const
Return the number of collisions undergone by the particle.
virtual void makeTargetSpectator()
virtual G4double getTableMass() const
Get the real particle mass.
G4double getMass() const
Get the cached particle mass.
void putParticlesOffShell()
Put the cluster components off shell.
ParticleList const & getParticles() const
Get the list of particles in the cluster.
virtual void makeTargetSpectator()
Make all the components target spectators, too.
virtual void rotate(const G4double angle, const ThreeVector &axis)
Rotate position and momentum of all the particles.
void setZ(const G4int Z)
Set the charge number of the cluster.
void boost(const ThreeVector &aBoostVector)
Boost the particle using a boost vector.
const G4INCL::ThreeVector & getMomentum() const
Get the momentum vector.
G4double getEnergy() const
Get the energy of the particle in MeV.
void setINCLMass()
Set the mass of the Particle to its table mass.
virtual void makeProjectileSpectator()
void remove(const T &t)
void boost(const ThreeVector &aBoostVector)
Boost the cluster with the indicated velocity.
Cluster is a particle (inherits from the Particle class) that is actually a collection of elementary ...
virtual ~Cluster()
int G4int
Definition: G4Types.hh:78
G4double mag2() const
Get the square of the length.
G4double getPotentialEnergy() const
Get the particle potential energy.
void setY(G4double ay)
Set the y coordinate.
virtual void rotate(const G4double angle, const ThreeVector &axis)
Rotate the particle position and momentum.
G4INCL::ThreeVector getAngularMomentum() const
Get the total angular momentum (orbital + spin)
Class for sampling particles in a nucleus.
ThreeVector theSpin
std::string print() const
void swap(Cluster &rhs)
Helper method for the assignment operator.
bool G4bool
Definition: G4Types.hh:79
virtual void initializeParticles()
Initialise the NuclearDensity pointer and sample the particles.
virtual G4INCL::ThreeVector getAngularMomentum() const
Get the angular momentum w.r.t.
Cluster(const Cluster &rhs)
Copy constructor.
ParticleList particles
virtual void setPosition(const G4INCL::ThreeVector &position)
G4int getZ() const
Returns the charge number.
void freezeInternalMotion()
Freeze the internal motion of the particles.
G4INCL::ThreeVector thePosition
static const G4double A[nN]
virtual void makeParticipant()
Make all the components participants, too.
ParticleSampler * theParticleSampler
void removeParticle(Particle *const p)
Remove a particle from the cluster components.
G4double theExcitationEnergy
void setA(const G4int A)
Set the mass number of the cluster.
ParticleList getParticleList() const
Returns the list of particles that make up the cluster.
G4INCL::ParticleType theType
Cluster & operator=(const Cluster &rhs)
Assignment operator.
G4double energy(const ThreeVector &p, const G4double m)
void addParticles(ParticleList const &pL)
Add a list of particles to the cluster.
int position
Definition: filter.cc:7
const G4INCL::ThreeVector & getPosition() const
Set the position vector.
void swap(Particle &rhs)
Helper method for the assignment operator.
void setType(ParticleType t)
void internalBoostToCM()
Boost to the CM of the component particles.
ParticleSpecies getSpecies() const
Get the particle species.
Cluster(Iterator begin, Iterator end)
A cluster can be directly built from a list of particles.
Particle & operator=(const Particle &rhs)
Assignment operator.
void addParticle(Particle *const p)
Add one particle to the cluster.
G4INCL::ThreeVector theMomentum
ThreeVector const & getSpin() const
Get the spin of the nucleus.
G4double getX() const
std::string print() const
void setX(G4double ax)
Set the x coordinate.
G4double getExcitationEnergy() const
Get the excitation energy of the cluster.
G4double getRealMass() const
Get the real particle mass.
virtual void makeProjectileSpectator()
Make all the components projectile spectators, too.
virtual void makeParticipant()
G4double computeDynamicalPotential()
Compute the dynamical cluster potential.
double G4double
Definition: G4Types.hh:76
void setZ(G4double az)
Set the z coordinate.
#define INCL_DEBUG(x)
const ThreeVector & adjustMomentumFromEnergy()
Rescale the momentum to match the total energy.
void setExcitationEnergy(const G4double e)
Set the excitation energy of the cluster.
void setSpin(const ThreeVector &j)
Set the spin of the nucleus.
G4double thePotentialEnergy
void setPosition(const ThreeVector &position)
Set the position of the cluster.
ParticleList::const_iterator ParticleIter
G4double getZ() const
std::string getName(const ParticleType t)
Get the native INCL name of the particle.
G4double getY() const
Cluster(const G4int Z, const G4int A, const G4bool createParticleSampler=true)
Standard Cluster constructor.