// // ******************************************************************** // * 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. * // ******************************************************************** // // // $Id: G4DynamicParticle.cc,v 1.29 2010/05/20 01:01:07 kurasige Exp $ // GEANT4 tag $Name: geant4-09-04-beta-cand-01 $ // // // -------------------------------------------------------------- // GEANT 4 class implementation file // // History: first implementation, based on object model of // 2nd December 1995, G.Cosmo // ---------------- G4DynamicParticle ---------------- // first implementation by Makoto Asai, 29 January 1996 // revised by G.Cosmo, 29 February 1996 // revised by H.Kurashige 06 May 1996 // revised by Hisaya Kurashige, 27 July 1996 // modify thePreAssignedDecayProducts // add void SetMomentum(G4ThreeVector &momentum) // add void Set4Momentum(G4LorentzVector &momentum) // add G4DynamicParticle(G4ParticleDefinition * aParticleDefinition, // G4LorentzVector &p4vector) // revised by Hisaya Kurashige, 19 Oct 1996 // add theKillProcess // add ProperTime // revised by Hisaya Kurashige, 26 Mar 1997 // modify destructor // revised by Hisaya Kurashige, 05 June 1997 // modify DumpInfo() // revised by Hisaya Kurashige, 5 June 1998 // remove theKillProcess // revised by Hisaya Kurashige, 5 Mar 2001 // fixed SetDefinition() // revised by V.Ivanchenko, 12 June 2003 // fixed problem of massless particles // revised by V.Ivanchenko, 18 June 2003 // take into account the case of virtual photons // revised by M.Kelsey 12 May 2010 // ensure that all constructors initialize all data members //-------------------------------------------------------------- #include "G4DynamicParticle.hh" #include "G4DecayProducts.hh" #include "G4LorentzVector.hh" #include "G4ParticleDefinition.hh" #include "G4ParticleTable.hh" #include "G4IonTable.hh" G4Allocator aDynamicParticleAllocator; static const G4double EnergyMomentumRelationAllowance = keV; //////////////////// G4DynamicParticle::G4DynamicParticle(): theMomentumDirection(0.0,0.0,1.0), theParticleDefinition(0), theKineticEnergy(0.0), theProperTime(0.0), theDynamicalMass(0.0), theDynamicalCharge(0.0), theDynamicalSpin(0.0), theDynamicalMagneticMoment(0.0), theElectronOccupancy(0), thePreAssignedDecayProducts(0), thePreAssignedDecayTime(-1.0), verboseLevel(1), primaryParticle(0), thePDGcode(0) {} //////////////////// // -- constructors ---- //////////////////// G4DynamicParticle::G4DynamicParticle(G4ParticleDefinition * aParticleDefinition, const G4ThreeVector& aMomentumDirection, G4double aKineticEnergy): theMomentumDirection(aMomentumDirection), theParticleDefinition(aParticleDefinition), theKineticEnergy(aKineticEnergy), theProperTime(0.0), theDynamicalMass(aParticleDefinition->GetPDGMass()), theDynamicalCharge(aParticleDefinition->GetPDGCharge()), theDynamicalSpin(aParticleDefinition->GetPDGSpin()), theDynamicalMagneticMoment(aParticleDefinition->GetPDGMagneticMoment()), theElectronOccupancy(0), thePreAssignedDecayProducts(0), thePreAssignedDecayTime(-1.0), verboseLevel(1), primaryParticle(0), thePDGcode(0) {} //////////////////// G4DynamicParticle::G4DynamicParticle(G4ParticleDefinition * aParticleDefinition, const G4ThreeVector& aParticleMomentum): theParticleDefinition(aParticleDefinition), theKineticEnergy(0.0), theProperTime(0.0), theDynamicalMass(aParticleDefinition->GetPDGMass()), theDynamicalCharge(aParticleDefinition->GetPDGCharge()), theDynamicalSpin(aParticleDefinition->GetPDGSpin()), theDynamicalMagneticMoment(aParticleDefinition->GetPDGMagneticMoment()), theElectronOccupancy(0), thePreAssignedDecayProducts(0), thePreAssignedDecayTime(-1.0), verboseLevel(1), primaryParticle(0), thePDGcode(0) { // 3-dim momentum is given SetMomentum(aParticleMomentum); } //////////////////// G4DynamicParticle::G4DynamicParticle(G4ParticleDefinition * aParticleDefinition, const G4LorentzVector &aParticleMomentum): theParticleDefinition(aParticleDefinition), theKineticEnergy(0.0), theProperTime(0.0), theDynamicalMass(aParticleDefinition->GetPDGMass()), theDynamicalCharge(aParticleDefinition->GetPDGCharge()), theDynamicalSpin(aParticleDefinition->GetPDGSpin()), theDynamicalMagneticMoment(aParticleDefinition->GetPDGMagneticMoment()), theElectronOccupancy(0), thePreAssignedDecayProducts(0), thePreAssignedDecayTime(-1.0), verboseLevel(1), primaryParticle(0), thePDGcode(0) { // 4-momentum vector (Lorentz vecotr) is given Set4Momentum(aParticleMomentum); } G4DynamicParticle::G4DynamicParticle(G4ParticleDefinition * aParticleDefinition, G4double totalEnergy, const G4ThreeVector &aParticleMomentum): theParticleDefinition(aParticleDefinition), theKineticEnergy(0.0), theProperTime(0.0), theDynamicalMass(aParticleDefinition->GetPDGMass()), theDynamicalCharge(aParticleDefinition->GetPDGCharge()), theDynamicalSpin(aParticleDefinition->GetPDGSpin()), theDynamicalMagneticMoment(aParticleDefinition->GetPDGMagneticMoment()), theElectronOccupancy(0), thePreAssignedDecayProducts(0), thePreAssignedDecayTime(-1.0), verboseLevel(1), primaryParticle(0), thePDGcode(0) { // total energy and 3-dim momentum are given G4double pModule2 = aParticleMomentum.mag2(); if (pModule2>0.0) { G4double mass2 = totalEnergy*totalEnergy - pModule2; if(mass2 < EnergyMomentumRelationAllowance*EnergyMomentumRelationAllowance) { theDynamicalMass = 0.; SetMomentumDirection(aParticleMomentum.unit()); SetKineticEnergy(totalEnergy); } else { theDynamicalMass = std::sqrt(mass2); SetMomentum(aParticleMomentum); } } else { SetMomentumDirection(1.0,0.0,0.0); SetKineticEnergy(0.0); } } //////////////////// G4DynamicParticle::G4DynamicParticle(const G4DynamicParticle &right): theMomentumDirection(right.theMomentumDirection), theParticleDefinition(right.theParticleDefinition), thePolarization(right.thePolarization), theKineticEnergy(right.theKineticEnergy), theProperTime(0.0), theDynamicalMass(right.theDynamicalMass), theDynamicalCharge(right.theDynamicalCharge), theDynamicalSpin(right.theDynamicalSpin), theDynamicalMagneticMoment(right.theDynamicalMagneticMoment), theElectronOccupancy(0), thePreAssignedDecayProducts(0), // Do not copy preassignedDecayProducts thePreAssignedDecayTime(-1.0), verboseLevel(right.verboseLevel), primaryParticle(right.primaryParticle), thePDGcode(right.thePDGcode) { if (right.theElectronOccupancy != 0) { theElectronOccupancy = new G4ElectronOccupancy(*right.theElectronOccupancy); } } //////////////////// // -- destructor ---- //////////////////// G4DynamicParticle::~G4DynamicParticle() { // delete thePreAssignedDecayProducts if (thePreAssignedDecayProducts != 0) delete thePreAssignedDecayProducts; thePreAssignedDecayProducts = 0; if (theElectronOccupancy != 0) delete theElectronOccupancy; theElectronOccupancy =0; } //////////////////// // -- operators ---- //////////////////// G4DynamicParticle & G4DynamicParticle::operator=(const G4DynamicParticle &right) { if (this != &right) { theMomentumDirection = right.theMomentumDirection; theParticleDefinition = right.theParticleDefinition; thePolarization = right.thePolarization; theKineticEnergy = right.theKineticEnergy; theProperTime = right.theProperTime; theDynamicalMass = right.theDynamicalMass; theDynamicalCharge = right.theDynamicalCharge; theDynamicalSpin = right.theDynamicalSpin; theDynamicalMagneticMoment = right.theDynamicalMagneticMoment; if (theElectronOccupancy != 0) delete theElectronOccupancy; if (right.theElectronOccupancy != 0){ theElectronOccupancy = new G4ElectronOccupancy(*right.theElectronOccupancy); } else { theElectronOccupancy = 0; } // thePreAssignedDecayProducts must not be copied. thePreAssignedDecayProducts = 0; thePreAssignedDecayTime = -1.0; verboseLevel = right.verboseLevel; // Primary particle information must be preserved //*** primaryParticle = right.primaryParticle; thePDGcode = right.thePDGcode; } return *this; } //////////////////// void G4DynamicParticle::SetDefinition(G4ParticleDefinition * aParticleDefinition) { // remove preassigned decay if (thePreAssignedDecayProducts != 0) { #ifdef G4VERBOSE if (verboseLevel>0) { G4cerr << " G4DynamicParticle::SetDefinition()::" << "!!! Pre-assigned decay products is attached !!!! " << G4endl; G4cerr << "!!! New Definition is " << aParticleDefinition->GetParticleName() << " !!! " << G4endl; G4cerr << "!!! Pre-assigned decay products will be deleted !!!! " << G4endl; } #endif delete thePreAssignedDecayProducts; } thePreAssignedDecayProducts = 0; theParticleDefinition = aParticleDefinition; // set Dynamic mass/chrge theDynamicalMass = theParticleDefinition->GetPDGMass(); theDynamicalCharge = theParticleDefinition->GetPDGCharge(); theDynamicalSpin = theParticleDefinition->GetPDGSpin(); theDynamicalMagneticMoment = theParticleDefinition->GetPDGMagneticMoment(); // Set electron orbits if (theElectronOccupancy != 0) delete theElectronOccupancy; theElectronOccupancy =0; //AllocateElectronOccupancy(); } //////////////////// G4int G4DynamicParticle::operator==(const G4DynamicParticle &right) const { return (this == (G4DynamicParticle *) &right); } //////////////////// G4int G4DynamicParticle::operator!=(const G4DynamicParticle &right) const { return (this != (G4DynamicParticle *) &right); } //////////////////// // -- AllocateElectronOccupancy -- //////////////////// void G4DynamicParticle::AllocateElectronOccupancy() { G4ParticleDefinition* particle = GetDefinition(); if (G4IonTable::IsIon(particle)) { // Only ions can have ElectronOccupancy theElectronOccupancy = new G4ElectronOccupancy(); } else { theElectronOccupancy = 0; } } //////////////////// // -- methods for setting Energy/Momentum -- //////////////////// void G4DynamicParticle::SetMomentum(const G4ThreeVector &momentum) { G4double pModule2 = momentum.mag2(); if (pModule2>0.0) { G4double mass = theDynamicalMass; SetMomentumDirection(momentum.unit()); SetKineticEnergy(std::sqrt(pModule2 + mass*mass)-mass); } else { SetMomentumDirection(1.0,0.0,0.0); SetKineticEnergy(0.0); } } //////////////////// void G4DynamicParticle::Set4Momentum(const G4LorentzVector &momentum ) { G4double pModule2 = momentum.vect().mag2(); if (pModule2>0.0) { SetMomentumDirection(momentum.vect().unit()); G4double totalenergy = momentum.t(); G4double mass2 = totalenergy*totalenergy - pModule2; if(mass2 < EnergyMomentumRelationAllowance*EnergyMomentumRelationAllowance) { theDynamicalMass = 0.; SetKineticEnergy(totalenergy); } else { theDynamicalMass = std::sqrt(mass2); SetKineticEnergy(totalenergy-theDynamicalMass); } } else { SetMomentumDirection(1.0,0.0,0.0); SetKineticEnergy(0.0); } } //////////////////// // --- Dump Information -- //////////////////// void G4DynamicParticle::DumpInfo(G4int mode) const { #ifdef G4VERBOSE if (theParticleDefinition == 0) { G4cout << " G4DynamicParticle::DumpInfo():: !!!Particle type not defined !!!! " << G4endl; } else { G4cout << " Particle type - " << theParticleDefinition->GetParticleName() << G4endl << " mass: " << GetMass()/GeV << "[GeV]" <0) { if( theElectronOccupancy != 0) { theElectronOccupancy->DumpInfo(); } } } #endif } //////////////////////// G4double G4DynamicParticle::GetElectronMass() const { static G4double electronMass = 0.0; // check if electron exits and get the mass if (electronMass<=0.0) { G4ParticleDefinition* electron = G4ParticleTable::GetParticleTable()->FindParticle("e-"); if (electron == 0) { G4Exception("G4DynamicParticle: G4Electron is not defined !!"); } electronMass = electron->GetPDGMass(); } return electronMass; }