Files
geant4/source/processes/hadronic/models/inclxx/utils/include/G4INCLParticle.hh
T
2016-06-09 16:46:55 +02:00

411 lines
12 KiB
C++

//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// INCL++ intra-nuclear cascade model
// Pekka Kaitaniemi, CEA and Helsinki Institute of Physics
// Davide Mancusi, CEA
// Alain Boudard, CEA
// Sylvie Leray, CEA
// Joseph Cugnon, University of Liege
//
// INCL++ revision: v5.0_rc3
//
#define INCLXX_IN_GEANT4_MODE 1
#include "globals.hh"
/*
* Particle.hh
*
* Created on: Jun 5, 2009
* Author: Pekka Kaitaniemi
*/
#ifndef PARTICLE_HH_
#define PARTICLE_HH_
#include "G4INCLThreeVector.hh"
#include "G4INCLParticleTable.hh"
#include "G4INCLParticleType.hh"
#include "G4INCLLogger.hh"
#include <list>
#include <sstream>
#include <string>
namespace G4INCL {
class Particle;
typedef std::list<G4INCL::Particle*> ParticleList;
typedef std::list<G4INCL::Particle*>::const_iterator ParticleIter;
class Particle {
public:
Particle();
Particle(ParticleType t, G4double energy, ThreeVector momentum, ThreeVector position);
Particle(ParticleType t, ThreeVector momentum, ThreeVector position);
virtual ~Particle();
/**
* Get the particle type.
* @see G4INCL::ParticleType
*/
G4INCL::ParticleType getType() const {
return theType;
};
void setType(ParticleType t) {
theType = t;
switch(theType)
{
case DeltaPlusPlus:
theA = 1;
theZ = 2;
break;
case Proton:
case DeltaPlus:
theA = 1;
theZ = 1;
break;
case Neutron:
case DeltaZero:
theA = 1;
theZ = 0;
break;
case DeltaMinus:
theA = 1;
theZ = -1;
break;
case PiPlus:
theA = 0;
theZ = 1;
break;
case PiZero:
theA = 0;
theZ = 0;
break;
case PiMinus:
theA = 0;
theZ = -1;
break;
case Composite:
// ERROR("Trying to set particle type to Composite! Construct a Cluster object instead" << std::endl);
break;
case UnknownParticle:
ERROR("Trying to set particle type to Unknown!" << std::endl);
break;
}
if( !isResonance() && t!=Composite )
theMass = ParticleTable::getMass(theType);
}
/**
* Is this a nucleon?
*/
G4bool isNucleon() const {
if(theType == G4INCL::Proton || theType == G4INCL::Neutron)
return true;
else
return false;
};
G4bool isParticipant() const {
return participant;
}
void makeParticipant() {
participant = true;
}
void makeSpectator() {
participant = false;
}
/** \brief Is this a pion? */
G4bool isPion() const { return (theType == PiPlus || theType == PiZero || theType == PiMinus); }
/** \brief Is it a resonance? */
inline G4bool isResonance() const { return isDelta(); }
/** \brief Is it a Delta? */
inline G4bool isDelta() const {
return (theType==DeltaPlusPlus || theType==DeltaPlus ||
theType==DeltaZero || theType==DeltaMinus);
}
/** \brief Returns the baryon number. */
G4int getA() const { return theA; }
/** \brief Returns the charge number. */
G4int getZ() const { return theZ; }
G4double getBeta() const {
const G4double P = theMomentum.mag();
return P/theEnergy;
}
/**
* Returns a three vector we can give to the boost() -method.
*
* In order to go to the particle rest frame you need to multiply
* the boost vector by -1.0.
*/
ThreeVector boostVector() const {
return theMomentum / theEnergy;
}
/**
* Boost the particle using a boost vector.
*
* Example (go to the particle rest frame):
* particle->boost(particle->boostVector());
*/
void boost(const ThreeVector &boostVector) {
const G4double beta2 = boostVector.mag2();
const G4double gamma = 1.0 / std::sqrt(1.0 - beta2);
const G4double bp = theMomentum.dot(boostVector);
const G4double alpha = (gamma*gamma)/(1.0 + gamma);
theMomentum = theMomentum + boostVector * alpha * bp - boostVector * gamma * theEnergy;
theEnergy = gamma * (theEnergy - bp);
}
/** \brief Get the cached particle mass. */
inline G4double getMass() const { return theMass; }
/** \brief Get the the particle invariant mass.
*
* Uses the relativistic invariant
* \f[ m = \sqrt{E^2 - {\vec p}^2}\f]
**/
G4double getInvariantMass() const {
const G4double mass = std::pow(theEnergy, 2) - theMomentum.dot(theMomentum);
if(mass < 0.0) {
ERROR("E*E - p*p is negative." << std::endl);
return 0.0;
} else {
return std::sqrt(mass);
}
};
/// \brief Get the particle kinetic energy.
inline G4double getKineticEnergy() const { return theEnergy - theMass; }
/// \brief Get the particle potential energy.
inline G4double getPotentialEnergy() const { return thePotentialEnergy; }
/// \brief Set the particle potential energy.
inline void setPotentialEnergy(G4double v) { thePotentialEnergy = v; }
/**
* Get the energy of the particle in MeV.
*/
G4double getEnergy() const
{
return theEnergy;
};
/**
* Set the mass of the particle in MeV/c^2.
*/
void setMass(G4double mass)
{
this->theMass = mass;
}
/**
* Set the energy of the particle in MeV.
*/
void setEnergy(G4double energy)
{
this->theEnergy = energy;
};
/**
* Get the momentum vector.
*/
const G4INCL::ThreeVector &getMomentum() const
{
return theMomentum;
};
/** Get the angular momentum w.r.t. the origin */
G4INCL::ThreeVector getAngularMomentum() const
{
return thePosition.vector(theMomentum);
};
/**
* Set the momentum vector.
*/
void setMomentum(const G4INCL::ThreeVector &momentum)
{
this->theMomentum = momentum;
};
/**
* Set the position vector.
*/
const G4INCL::ThreeVector &getPosition() const
{
return thePosition;
};
void setPosition(const G4INCL::ThreeVector &position)
{
this->thePosition = position;
};
G4double getHelicity() { return theHelicity; };
void setHelicity(G4double h) { theHelicity = h; };
void propagate(G4double step) {
thePosition += (theMomentum*(step/theEnergy));
};
/** \brief Return the number of collisions undergone by the particle. **/
G4int getNumberOfCollisions() const { return nCollisions; }
/** \brief Set the number of collisions undergone by the particle. **/
void setNumberOfCollisions(G4int n) { nCollisions = n; }
/** \brief Increment the number of collisions undergone by the particle. **/
void incrementNumberOfCollisions() { nCollisions++; }
/** \brief Return the number of decays undergone by the particle. **/
G4int getNumberOfDecays() const { return nDecays; }
/** \brief Set the number of decays undergone by the particle. **/
void setNumberOfDecays(G4int n) { nDecays = n; }
/** \brief Increment the number of decays undergone by the particle. **/
void incrementNumberOfDecays() { nDecays++; }
/** \brief Mark the particle as out of its potential well
*
* This flag is used to control pions created outside their potential well
* in delta decay. The pion potential checks it and returns zero if it is
* true (necessary in order to correctly enforce energy conservation). The
* Nucleus::applyFinalState() method uses it to determine whether new
* avatars should be generated for the particle.
*/
void setOutOfWell() { outOfWell = true; }
/// \brief Check if the particle is out of its potential well
G4bool isOutOfWell() const { return outOfWell; }
void setEmissionTime(G4double t) { emissionTime = t; }
G4double getEmissionTime() { return emissionTime; };
/** \brief Transverse component of the position w.r.t. the momentum. */
ThreeVector getTransversePosition() {
return thePosition - theMomentum *
(thePosition.dot(theMomentum)/theMomentum.mag2());
}
/** \brief Rescale the momentum to match the total energy. */
const ThreeVector &adjustMomentumFromEnergy();
/** \brief Recompute the energy to match the momentum. */
G4double adjustEnergyFromMomentum();
/** \brief Check if the particle belongs to a given list **/
G4bool isInList(ParticleList const &l) const {
for(ParticleIter i=l.begin(); i!=l.end(); ++i)
if((*i)->getID()==ID) return true;
return false;
}
G4bool isCluster() const {
if(theType == Composite) return true;
else return false;
}
std::string prG4int() const {
std::stringstream ss;
ss << "Particle (ID = " << ID << ") type = ";
ss << ParticleTable::getName(theType);
ss << std::endl
<< " energy = " << theEnergy << std::endl
<< " momentum = "
<< theMomentum.prG4int()
<< std::endl
<< " position = "
<< thePosition.prG4int()
<< std::endl;
return ss.str();
};
std::string dump() const {
std::stringstream ss;
ss << "(particle " << ID << " ";
ss << ParticleTable::getName(theType);
ss << std::endl
<< thePosition.dump()
<< std::endl
<< theMomentum.dump()
<< std::endl
<< theEnergy << ")" << std::endl;
return ss.str();
};
long getID() const { return ID; };
/**
* Return a NULL poG4inter
*/
ParticleList const *getParticles() const {
WARN("Particle::getParticles() method was called on a Particle object" << std::endl);
return 0;
}
protected:
G4int theZ, theA;
G4bool participant;
G4INCL::ParticleType theType;
G4double theEnergy;
G4INCL::ThreeVector theMomentum;
G4INCL::ThreeVector thePosition;
G4int nCollisions;
G4int nDecays;
G4double thePotentialEnergy;
long ID;
private:
G4double theHelicity;
G4double emissionTime;
G4bool outOfWell;
G4double theMass;
static long nextID;
};
}
#endif /* PARTICLE_HH_ */