Import Geant4 6.0.0 source tree

This commit is contained in:
Gabriele Cosmo
2016-06-09 10:41:53 +02:00
parent 4aea781e80
commit 96686e0c8f
6560 changed files with 153347 additions and 238155 deletions
@@ -0,0 +1,37 @@
# $Id: GNUmakefile,v 1.2 2003/10/17 17:23:43 lara Exp $
# ----------------------------------------------------------------
# GNUmakefile for hadronic management library. G.Folger 10-Dec-97
# ----------------------------------------------------------------
name := G4had_mod_util
ifndef G4INSTALL
G4INSTALL = ../../../../..
endif
include $(G4INSTALL)/config/architecture.gmk
ifdef PRECOMPOUND_TEST
CPPFLAGS += -DPRECOMPOUND_TEST
endif
CPPFLAGS += -I$(G4BASE)/global/management/include \
-I$(G4BASE)/global/HEPRandom/include \
-I$(G4BASE)/global/HEPGeometry/include \
-I$(G4BASE)/global/HEPNumerics/include \
-I$(G4BASE)/track/include \
-I$(G4BASE)/geometry/volumes/include \
-I$(G4BASE)/geometry/management/include \
-I$(G4BASE)/geometry/navigation/include \
-I$(G4BASE)/processes/hadronic/util/include \
-I$(G4BASE)/processes/hadronic/models/management/include \
-I$(G4BASE)/particles/management/include \
-I$(G4BASE)/particles/leptons/include \
-I$(G4BASE)/particles/bosons/include \
-I$(G4BASE)/particles/hadrons/mesons/include \
-I$(G4BASE)/particles/hadrons/barions/include \
-I$(G4BASE)/particles/hadrons/ions/include \
-I$(G4BASE)/processes/management/include \
-I$(G4BASE)/materials/include
include $(G4INSTALL)/config/common.gmk
@@ -0,0 +1,108 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
#ifndef G4DecayStrongResonances_h
#define G4DecayStrongResonances_h 1
#include "G4Fancy3DNucleus.hh"
#include "G4Nucleon.hh"
#include "G4Nucleus.hh"
#include "G4KineticTrackVector.hh"
#include "G4FragmentVector.hh"
#include "G4HadFinalState.hh"
#include "G4DynamicParticleVector.hh"
#include <algorithm>
class G4DecayStrongResonances
{
public:
G4DecayStrongResonances(){}
~G4DecayStrongResonances(){}
private:
G4int operator==(G4DecayStrongResonances& right) {return (this == &right);}
G4int operator!=(G4DecayStrongResonances& right) {return (this != &right);}
G4double theEnergy;
public:
G4ReactionProductVector* Propagate(G4KineticTrackVector* theSecondaries, G4V3DNucleus* )
{
// decay the strong resonances
G4ReactionProductVector * theResult = new G4ReactionProductVector;
G4KineticTrackVector *result1, *secondaries, *result;
result1=theSecondaries;
result=new G4KineticTrackVector();
size_t aResult=0;
for (aResult=0; aResult < result1->size(); aResult++)
{
G4ParticleDefinition * pdef;
pdef=result1->operator[](aResult)->GetDefinition();
secondaries=NULL;
if ( pdef->GetPDGWidth() > 0 && pdef->GetPDGLifeTime() < 5E-17*s )
{
secondaries = result1->operator[](aResult)->Decay();
}
if ( secondaries == NULL )
{
result->push_back(result1->operator[](aResult));
result1->operator[](aResult)=NULL; //protect for clearAndDestroy
}
else
{
for (size_t aSecondary=0; aSecondary<secondaries->size(); aSecondary++)
{
result1->push_back(secondaries->operator[](aSecondary));
}
delete secondaries;
}
}
std::for_each(result1->begin(), result1->end(), DeleteKineticTrack());
delete result1;
// translate to ReactionProducts
G4ReactionProduct * it = NULL;
for(aResult=0; aResult < result->size(); aResult++)
{
it = new G4ReactionProduct();
it->SetDefinition((*result)[aResult]->GetDefinition());
it->SetMass((*result)[aResult]->GetDefinition()->GetPDGMass());
it->SetTotalEnergy((*result)[aResult]->Get4Momentum().t());
it->SetMomentum((*result)[aResult]->Get4Momentum().vect());
theResult->push_back(it);
}
std::for_each(result->begin(), result->end(), DeleteKineticTrack());
delete result;
return theResult;
}
private:
};
#endif // G4DecayStrongResonances_h
@@ -0,0 +1,229 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
//
//
#ifndef G4ExcitedString_h
#define G4ExcitedString_h 1
// ------------------------------------------------------------
// GEANT 4 class header file
//
// ---------------- G4ExcitedString ----------------
// by Gunter Folger, June 1998.
// class for an excited string used by Parton String Models
// ------------------------------------------------------------
#include "G4ios.hh"
#include "globals.hh"
#include "G4ThreeVector.hh"
#include "G4LorentzVector.hh"
#include "G4LorentzRotation.hh"
#include "G4Parton.hh"
#include "G4PartonVector.hh"
#include "G4KineticTrack.hh"
#include "G4HadronicException.hh"
#include <algorithm>
class G4ExcitedString
{
public:
enum {
PROJECTILE = 1,
TARGET = -1
};
G4ExcitedString(G4Parton* Color, G4Parton* Gluon, G4Parton* AntiColor, G4int Direction=PROJECTILE);
G4ExcitedString(G4Parton* Color, G4Parton* AntiColor, G4int Direction=PROJECTILE);
G4ExcitedString(G4KineticTrack * atrack);
G4ExcitedString(const G4ExcitedString &right);
~G4ExcitedString();
int operator==(const G4ExcitedString &right) const;
int operator!=(const G4ExcitedString &right) const;
const G4ThreeVector & GetPosition() const;
void SetPosition(const G4ThreeVector &aPosition);
const G4PartonVector * GetPartonList() const;
G4LorentzVector Get4Momentum() const;
void LorentzRotate(const G4LorentzRotation & rotation);
void InsertParton(G4Parton * aParton, const G4Parton * addafter = NULL);
G4LorentzRotation TransformToCenterOfMass();
G4LorentzRotation TransformToAlignedCms();
void Boost(G4ThreeVector& Velocity);
G4Parton* GetColorParton(void) const;
G4Parton* GetGluon(void) const;
G4Parton* GetAntiColorParton(void) const;
G4Parton* GetGluon(G4int GluonPos) const;
G4KineticTrack * GetKineticTrack() const;
G4Parton* GetLeftParton(void) const;
G4Parton* GetRightParton(void) const;
G4bool IsItKinkyString(void) const;
G4int GetDirection(void) const;
G4bool IsExcited() const;
private:
G4int theDirection; // must be 1 or -1 (PROJECTILE or TARGET)
G4ThreeVector thePosition;
G4PartonVector thePartons; // would like initial capacity for 3 Partons.
G4KineticTrack* theTrack;
};
inline
int G4ExcitedString::operator==(const G4ExcitedString &right) const
{
return this == &right;
}
inline
int G4ExcitedString::operator!=(const G4ExcitedString &right) const
{
return this != &right;
}
inline
const G4ThreeVector & G4ExcitedString::GetPosition() const
{
return thePosition;
}
inline
void G4ExcitedString::SetPosition(const G4ThreeVector &aPosition)
{
thePosition= aPosition;
}
inline
G4LorentzVector G4ExcitedString::Get4Momentum() const
{
G4LorentzVector momentum;
for ( unsigned int index=0; index < thePartons.size() ; index++ )
{
momentum += thePartons[index]->Get4Momentum();
}
return momentum;
}
inline
void G4ExcitedString::LorentzRotate(const G4LorentzRotation & rotation)
{
for ( unsigned int index=0; index < thePartons.size() ; index++ )
{
thePartons[index]->Set4Momentum(rotation*thePartons[index]->Get4Momentum());
}
}
inline
void G4ExcitedString::InsertParton(G4Parton *aParton, const G4Parton * addafter)
{
G4PartonVector::iterator insert_index;
if ( addafter != NULL )
{
insert_index=std::find(thePartons.begin(), thePartons.end(), addafter);
if (insert_index == thePartons.end()) // No object addafter in thePartons
{
G4String text = "G4ExcitedString::InsertParton called with invalid second argument";
throw G4HadronicException(__FILE__, __LINE__, text);
}
}
thePartons.insert(insert_index+1, aParton);
}
inline
G4LorentzRotation G4ExcitedString::TransformToCenterOfMass()
{
G4LorentzVector momentum=Get4Momentum();
G4LorentzRotation toCms(-1*momentum.boostVector());
for ( unsigned int index=0; index < thePartons.size() ; index++ )
{
momentum=toCms * thePartons[index]->Get4Momentum();
thePartons[index]->Set4Momentum(momentum);
}
return toCms;
}
inline
G4LorentzRotation G4ExcitedString::TransformToAlignedCms()
{
G4LorentzVector momentum=Get4Momentum();
G4LorentzRotation toAlignedCms(-1*momentum.boostVector());
momentum= toAlignedCms* thePartons[0]->Get4Momentum();
toAlignedCms.rotateZ(-1*momentum.phi());
toAlignedCms.rotateY(-1*momentum.theta());
for ( unsigned int index=0; index < thePartons.size() ; index++ )
{
momentum=toAlignedCms * thePartons[index]->Get4Momentum();
thePartons[index]->Set4Momentum(momentum);
}
return toAlignedCms;
}
inline
const G4PartonVector * G4ExcitedString::GetPartonList() const
{
return &thePartons;
}
inline
G4KineticTrack * G4ExcitedString::GetKineticTrack() const
{
return theTrack;
}
inline
G4bool G4ExcitedString::IsExcited() const
{
return theTrack == 0;
}
#endif
@@ -0,0 +1,41 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
//
//
#ifndef G4ExcitedStringVector_h
#define G4ExcitedStringVector_h 1
// ------------------------------------------------------------
// GEANT 4 class header file
//
// ---------------- G4ExcitedStringVector ----------------
// by Gunter Folger, June 1998.
// ------------------------------------------------------------
#include "G4ExcitedString.hh"
#include <vector>
typedef std::vector<G4ExcitedString *> G4ExcitedStringVector;
struct DeleteString { void operator()(G4ExcitedString* aS){delete aS;} };
#endif
@@ -0,0 +1,109 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
//
//
#ifndef G4Fancy3DNucleus_h
#define G4Fancy3DNucleus_h 1
// ------------------------------------------------------------
// GEANT 4 class header file
//
// ---------------- G4Fancy3DNucleus ----------------
// by Gunter Folger, May 1998.
// class for a 3D nucleus, arranging nucleons in space and momentum.
// ------------------------------------------------------------
#include "globals.hh"
#include "G4DynamicParticle.hh"
#include "G4V3DNucleus.hh"
#include "G4Nucleon.hh"
#include "G4VNuclearDensity.hh"
#include "G4FermiMomentum.hh"
#include <vector>
class G4Fancy3DNucleus : public G4V3DNucleus
{
public:
G4Fancy3DNucleus();
~G4Fancy3DNucleus();
private:
G4Fancy3DNucleus(const G4Fancy3DNucleus &right);
const G4Fancy3DNucleus & operator=(const G4Fancy3DNucleus &right);
int operator==(const G4Fancy3DNucleus &right) const;
int operator!=(const G4Fancy3DNucleus &right) const;
// Implementation
void ChooseNucleons();
void ChoosePositions();
void ChooseFermiMomenta();
G4double BindingEnergy();
G4bool ReduceSum(G4ThreeVector * momentum, G4double *);
public:
void Init(G4double theA, G4double theZ);
G4bool StartLoop();
G4Nucleon * GetNextNucleon();
const std::vector<G4Nucleon *> & GetNucleons();
G4int GetMassNumber();
G4double GetMass();
G4int GetCharge();
G4double GetNuclearRadius();
G4double GetNuclearRadius(const G4double maxRelativeDensity);
G4double GetOuterRadius();
G4double CoulombBarrier();
void DoLorentzBoost(const G4LorentzVector & theBoost);
void DoLorentzBoost(const G4ThreeVector & theBeta);
void DoLorentzContraction(const G4LorentzVector & theBoost);
void DoLorentzContraction(const G4ThreeVector & theBeta);
void CenterNucleons();
void DoTranslation(const G4ThreeVector & theShift);
const G4VNuclearDensity * GetNuclearDensity() const;
private:
G4int myA;
G4int myZ;
G4Nucleon * theNucleons;
std::vector<G4Nucleon *> theRWNucleons; // should not have two...
struct DeleteNucleon{ void operator()(G4Nucleon *aN){delete aN;} };
G4int currentNucleon;
G4VNuclearDensity * theDensity;
G4FermiMomentum theFermi;
const G4double nucleondistance;
};
inline G4int G4Fancy3DNucleus::GetCharge()
{
return myZ;
}
inline G4int G4Fancy3DNucleus::GetMassNumber()
{
return myA;
}
#endif
@@ -0,0 +1,76 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
//
//
#ifndef G4FermiMomentum_h
#define G4FermiMomentum_h 1
#include "globals.hh"
#include "G4ThreeVector.hh"
#include "Randomize.hh"
class G4FermiMomentum
{
public:
G4FermiMomentum();
~G4FermiMomentum();
inline void Init(G4double anA, G4double aZ) {theA = anA; theZ = aZ;}
inline G4double GetFermiMomentum(G4double density)
{
return constofpmax * cbrt(density * theA);
}
inline G4ThreeVector GetMomentum(G4double density,
G4double maxMomentum=-1.)
{
if (maxMomentum < 0 ) maxMomentum=GetFermiMomentum(density);
G4ThreeVector p;
do {
p=G4ThreeVector(2.*G4UniformRand()-1.,
2.*G4UniformRand()-1.,
2.*G4UniformRand()-1.);
} while ( p.mag() > 1. );
return p*maxMomentum;
}
private:
G4double cbrt(G4double x) { return pow(x,1./3.); }
private:
G4double theA;
G4double theZ;
// pmax= hbar * c * ( 3* pi**2 * rho )**(1/3) =
// hbar * c * ( 3* pi**2 )**(1/3) * rho**(1/3)=
// constofpmax * rho**(1/3)
G4double constofpmax;
};
#endif
@@ -0,0 +1,308 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
//
//
// Hadronic Process: Nuclear De-excitations
// by V. Lara (May 1998)
#ifndef G4Fragment_h
#define G4Fragment_h 1
#include "G4ios.hh"
#include <iomanip>
#include <vector>
#include "globals.hh"
#include "G4LorentzVector.hh"
#include "G4ParticleMomentum.hh"
#include "G4ThreeVector.hh"
#include "G4NucleiProperties.hh"
#include "G4ParticleTable.hh"
#include "G4IonTable.hh"
#include "Randomize.hh"
#include "G4Proton.hh"
#include "G4Neutron.hh"
#include "G4HadronicException.hh"
#include "G4HadTmpUtil.hh"
class G4ParticleDefinition;
class G4Fragment; // Forward deckaration
typedef std::vector<G4Fragment*> G4FragmentVector;
class G4Fragment
{
public:
// ============= CONSTRUCTORS ==================
// Default constructor
G4Fragment();
// Destructor
~G4Fragment();
// Copy constructor
G4Fragment(const G4Fragment &right);
// Several constructors
// A,Z and 4-momentum
G4Fragment(const G4int A, const G4int Z, const G4LorentzVector aMomentum);
// 4-momentum and pointer to G4particleDefinition (for gammas)
G4Fragment(const G4LorentzVector aMomentum, G4ParticleDefinition * aParticleDefinition);
// ============= OPERATORS ==================
const G4Fragment & operator=(const G4Fragment &right);
G4bool operator==(const G4Fragment &right) const;
G4bool operator!=(const G4Fragment &right) const;
friend std::ostream& operator<<(std::ostream&, const G4Fragment*);
friend std::ostream& operator<<(std::ostream&, const G4Fragment&);
// ============= METHODS ==================
inline G4double GetA(void) const;
void SetA(const G4double value);
G4double GetZ(void) const;
void SetZ(const G4double value);
G4double GetExcitationEnergy(void) const;
void SetExcitationEnergy(const G4double value);
const G4LorentzVector GetMomentum(void) const;
void SetMomentum(const G4LorentzVector value);
const G4ThreeVector GetAngularMomentum(void) const;
void SetAngularMomentum(const G4ThreeVector value);
G4int GetNumberOfExcitons(void) const;
// void SetNumberOfExcitons(const G4int value);
G4int GetNumberOfHoles(void) const;
void SetNumberOfHoles(const G4int value);
G4int GetNumberOfCharged(void) const;
void SetNumberOfCharged(const G4int value);
G4int GetNumberOfParticles(void) const;
void SetNumberOfParticles(const G4int value);
inline G4ParticleDefinition * GetParticleDefinition(void) const;
void SetParticleDefinition(G4ParticleDefinition * aParticleDefinition);
G4double GetCreationTime(void) const;
void SetCreationTime(const G4double time);
// Some utility methods
inline G4double GetGroundStateMass(void) const;
inline G4double GetBindingEnergy(void) const;
#ifdef PRECOMPOUND_TEST
G4String GetCreatorModel() const { return theCreatorModel; }
void SetCreatorModel(const G4String & aModel)
{ theCreatorModel = aModel; }
#endif
private:
G4double CalculateExcitationEnergy(const G4LorentzVector value) const;
G4ThreeVector IsotropicRandom3Vector(const G4double Magnitude = 1.0) const;
// ============= DATA MEMBERS ==================
G4double theA;
G4double theZ;
G4double theExcitationEnergy;
G4LorentzVector theMomentum;
G4ThreeVector theAngularMomentum;
G4int numberOfParticles;
G4int numberOfHoles;
G4int numberOfCharged;
// Gamma evaporation requeriments
G4ParticleDefinition * theParticleDefinition;
G4double theCreationTime;
#ifdef PRECOMPOUND_TEST
G4String theCreatorModel;
#endif
};
// Class G4Fragment
inline G4double G4Fragment::GetA() const
{
return theA;
}
inline void G4Fragment::SetA(const G4double value)
{
theA = value;
}
inline G4double G4Fragment::GetZ() const
{
return theZ;
}
inline void G4Fragment::SetZ(const G4double value)
{
theZ = value;
}
inline G4double G4Fragment::GetExcitationEnergy() const
{
// temporary fix for what seems to be
// a problem with rounding errors for on-shell lorentz-vectors in CLHEP.
// HPW Apr 1999 @@@@@@@
if(abs(theExcitationEnergy)<10*eV) return 0;
return theExcitationEnergy;
}
inline void G4Fragment::SetExcitationEnergy(const G4double )
{
// theExcitationEnergy = value;
G4cout << "Warning: G4Fragment::SetExcitationEnergy() is a dummy method. Please, avoid to use it." << G4endl;
}
inline const G4LorentzVector G4Fragment::GetMomentum() const
{
return theMomentum;
}
inline void G4Fragment::SetMomentum(const G4LorentzVector value)
{
theMomentum = value;
theExcitationEnergy = CalculateExcitationEnergy(value);
}
inline const G4ThreeVector G4Fragment::GetAngularMomentum() const
{
return theAngularMomentum;
}
inline void G4Fragment::SetAngularMomentum(const G4ThreeVector value)
{
theAngularMomentum = value;
}
inline G4int G4Fragment::GetNumberOfExcitons() const
{
return numberOfParticles + numberOfHoles;
}
inline void G4Fragment::SetNumberOfParticles(const G4int value)
{
numberOfParticles = value;
}
inline G4int G4Fragment::GetNumberOfHoles() const
{
return numberOfHoles;
}
inline void G4Fragment::SetNumberOfHoles(const G4int value)
{
numberOfHoles = value;
}
inline G4int G4Fragment::GetNumberOfCharged() const
{
return numberOfCharged;
}
inline void G4Fragment::SetNumberOfCharged(const G4int value)
{
if (value <= numberOfParticles) numberOfCharged = value;
else
{
G4String text = "G4Fragment::SetNumberOfCharged: Number of charged particles can't be greater than number of particles";
throw G4HadronicException(__FILE__, __LINE__, text);
}
}
inline G4int G4Fragment::GetNumberOfParticles() const
{
return numberOfParticles;
}
inline G4ParticleDefinition * G4Fragment::GetParticleDefinition(void) const
{
return theParticleDefinition;
}
inline void G4Fragment::SetParticleDefinition(G4ParticleDefinition * aParticleDefinition)
{
theParticleDefinition = aParticleDefinition;
}
inline G4double G4Fragment::GetCreationTime(void) const
{
return theCreationTime;
}
inline void G4Fragment::SetCreationTime(const G4double time)
{
theCreationTime = time;
}
inline G4double G4Fragment::GetGroundStateMass(void) const
{
if (theA == 0) return 0.0; // photon
else return G4ParticleTable::GetParticleTable()->
GetIonTable()->GetIonMass(G4lrint(theZ),G4lrint(theA));
}
inline G4double G4Fragment::GetBindingEnergy(void) const
{
return -GetGroundStateMass()+(theA-theZ)*G4Neutron::Neutron()->GetPDGMass()
+ theZ*G4Proton::Proton()->GetPDGMass();
}
#endif
@@ -0,0 +1,33 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
//
//
// Hadronic Process: Nuclear De-excitations
// by V. Lara (May 1998)
#ifndef G4FragmentVector_h
#define G4FragmentVector_h 1
#include "G4Fragment.hh"
#endif
@@ -0,0 +1,105 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
//
//
//$Id: G4GeneralPhaseSpaceDecay.hh,v 1.1 1997/05/21
// ----------------------------------------------------------------
// GEANT 4 class header file
//
// History: first implementation, A. Feliciello, 20th May 1998
//
// Note: this class is a generalization of the
// G4PhaseSpaceDecayChannel one
// ----------------------------------------------------------------
#ifndef G4GeneralPhaseSpaceDecay_h
#define G4GeneralPhaseSpaceDecay_h 1
#include "G4ios.hh"
#include "globals.hh"
#include "G4VDecayChannel.hh"
class G4GeneralPhaseSpaceDecay : public G4VDecayChannel
{
public:
//Constructors
G4GeneralPhaseSpaceDecay(G4int Verbose = 1);
G4GeneralPhaseSpaceDecay(const G4String& theParentName,
G4double theBR,
G4int theNumberOfDaughters,
const G4String& theDaughterName1,
const G4String& theDaughterName2 = "",
const G4String& theDaughterName3 = "");
G4GeneralPhaseSpaceDecay(const G4String& theParentName,
G4double theParentMass,
G4double theBR,
G4int theNumberOfDaughters,
const G4String& theDaughterName1,
const G4String& theDaughterName2 = "",
const G4String& theDaughterName3 = "");
// Destructor
virtual ~G4GeneralPhaseSpaceDecay();
public:
G4double GetParentMass() const;
void SetParentMass(const G4double aParentMass);
virtual G4DecayProducts* DecayIt(G4double mass=0.0);
static G4double Pmx(G4double e, G4double p1, G4double p2);
protected:
G4DecayProducts* OneBodyDecayIt();
G4DecayProducts* TwoBodyDecayIt();
G4DecayProducts* ThreeBodyDecayIt();
G4DecayProducts* ManyBodyDecayIt();
private:
G4double parentmass;
};
inline G4double G4GeneralPhaseSpaceDecay::GetParentMass() const
{
return parentmass;
}
inline void G4GeneralPhaseSpaceDecay::SetParentMass(const G4double aParentMass)
{
parentmass = aParentMass;
}
inline
G4double G4GeneralPhaseSpaceDecay::Pmx(G4double e, G4double p1, G4double p2)
{
// calculate momentum of daughter particles in two-body decay
G4double ppp = (e+p1+p2)*(e+p1-p2)*(e-p1+p2)*(e-p1-p2)/(4.0*e*e);
if (ppp>0) return sqrt(ppp);
else return -1.;
}
#endif
@@ -0,0 +1,451 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
//
//
// $Id: G4KineticTrack.hh,v 1.0 1998/05/20
// -----------------------------------------------------------------------------
// GEANT 4 class header file
//
// History: first implementation, A. Feliciello, 20th May 1998
// -----------------------------------------------------------------------------
#ifndef G4KineticTrack_h
#define G4KineticTrack_h 1
#include "globals.hh"
#include "G4ios.hh"
#include "Randomize.hh"
#include "G4ThreeVector.hh"
#include "G4LorentzVector.hh"
#include "G4VKineticNucleon.hh"
#include "G4Nucleon.hh"
#include "G4ParticleDefinition.hh"
#include "G4VDecayChannel.hh"
// #include "G4Allocator.hh"
class G4KineticTrackVector;
class G4KineticTrack : public G4VKineticNucleon
{
public:
G4KineticTrack();
G4KineticTrack(const G4KineticTrack& right);
G4KineticTrack(G4ParticleDefinition* aDefinition,
G4double aFormationTime,
G4ThreeVector aPosition,
G4LorentzVector& a4Momentum);
G4KineticTrack(G4Nucleon * nucleon,
G4ThreeVector aPosition,
G4LorentzVector& a4Momentum);
~G4KineticTrack();
const G4KineticTrack& operator=(const G4KineticTrack& right);
G4int operator==(const G4KineticTrack& right) const;
G4int operator!=(const G4KineticTrack& right) const;
/*
inline void *operator new(size_t);
inline void operator delete(void *aTrack);
*/
G4ParticleDefinition* GetDefinition() const;
void SetDefinition(G4ParticleDefinition* aDefinition);
G4double GetFormationTime() const;
void SetFormationTime(G4double aFormationTime);
const G4ThreeVector& GetPosition() const;
void SetPosition(const G4ThreeVector aPosition);
const G4LorentzVector& Get4Momentum() const;
void Set4Momentum(const G4LorentzVector& a4Momentum);
void Update4Momentum(G4double aEnergy); // update E and p, not changing mass
void Update4Momentum(const G4ThreeVector & aMomentum); // idem
void SetTrackingMomentum(const G4LorentzVector& a4Momentum);
void UpdateTrackingMomentum(G4double aEnergy); // update E and p, not changing mass
void UpdateTrackingMomentum(const G4ThreeVector & aMomentum); // idem
const G4LorentzVector& GetTrackingMomentum() const;
G4double SampleResidualLifetime();
void Hit();
void SetNucleon(G4Nucleon * aN) {theNucleon = aN;}
G4bool IsParticipant() const;
G4KineticTrackVector* Decay();
// LB move to public (before was private) LB
G4double* GetActualWidth() const;
G4double GetActualMass() const;
G4int GetnChannels() const;
// position relativ to nucleus "state"
enum CascadeState {undefined, outside, going_in, inside,
going_out, gone_out, captured, miss_nucleus };
CascadeState SetState(const CascadeState new_state);
CascadeState GetState() const;
void SetProjectilePotential(const G4double aPotential);
G4double GetProjectilePotential() const;
private:
void SetnChannels(const G4int aChannel);
void SetActualWidth(G4double* anActualWidth);
G4double EvaluateTotalActualWidth();
G4double EvaluateCMMomentum (const G4double mass,
const G4double* m_ij) const;
G4double IntegrateCMMomentum(const G4double lowerLimit) const;
G4double IntegrateCMMomentum(const G4double lowerLimit ,const G4double polemass) const;
G4double IntegrateCMMomentum2() const;
public:
G4double BrWig(const G4double Gamma,
const G4double rmass,
const G4double mass) const;
private:
G4double IntegrandFunction1 (G4double xmass) const;
G4double IntegrandFunction2 (G4double xmass) const;
G4double IntegrandFunction3 (G4double xmass) const;
G4double IntegrandFunction4 (G4double xmass) const;
public:
// friend G4double IntegrandFunction3 (G4double xmass);
// friend G4double IntegrandFunction4 (G4double xmass);
// LB new variable created LB
G4int chosench;
private:
G4ParticleDefinition* theDefinition;
G4double theFormationTime;
G4ThreeVector thePosition;
G4LorentzVector the4Momentum;
G4LorentzVector theFermi3Momentum;
G4LorentzVector theTotal4Momentum;
G4Nucleon * theNucleon;
G4int nChannels;
G4double theActualMass;
G4double* theActualWidth;
// Temporary storage for daughter masses and widths
// (needed because Integrand Function cannot take > 1 argument)
G4double* theDaughterMass;
G4double* theDaughterWidth;
CascadeState theStateToNucleus;
G4double theProjectilePotential;
};
// extern G4Allocator<G4KineticTrack> theKTAllocator;
// Class G4KineticTrack
/*
inline void * G4KineticTrack::operator new(size_t)
{
void * aT;
aT = (void *) theKTAllocator.MallocSingle();
return aT;
}
inline void G4KineticTrack::operator delete(void * aT)
{
theKTAllocator.FreeSingle((G4KineticTrack *) aT);
}
*/
inline G4ParticleDefinition* G4KineticTrack::GetDefinition() const
{
return theDefinition;
}
inline void G4KineticTrack::SetDefinition(G4ParticleDefinition* aDefinition)
{
theDefinition = aDefinition;
}
inline G4double G4KineticTrack::GetFormationTime() const
{
return theFormationTime;
}
inline void G4KineticTrack::SetFormationTime(G4double aFormationTime)
{
theFormationTime = aFormationTime;
}
inline const G4ThreeVector& G4KineticTrack::GetPosition() const
{
return thePosition;
}
inline void G4KineticTrack::SetPosition(const G4ThreeVector aPosition)
{
thePosition = aPosition;
}
inline const G4LorentzVector& G4KineticTrack::Get4Momentum() const
{
return theTotal4Momentum;
}
inline const G4LorentzVector& G4KineticTrack::GetTrackingMomentum() const
{
return the4Momentum;
}
inline void G4KineticTrack::Set4Momentum(const G4LorentzVector& a4Momentum)
{
// set the4Momentum and update theTotal4Momentum
theTotal4Momentum=a4Momentum;
the4Momentum = theTotal4Momentum;
theFermi3Momentum=G4LorentzVector(0);
}
inline void G4KineticTrack::Update4Momentum(G4double aEnergy)
{
// update the4Momentum with aEnergy at constant mass (the4Momentum.mag()
// updates theTotal4Momentum as well.
G4double newP(0);
G4double mass2=theTotal4Momentum.mag2();
if ( sqr(aEnergy) > mass2 )
{
newP = sqrt(sqr(aEnergy) - mass2 );
} else
{
aEnergy=sqrt(mass2);
}
Set4Momentum(G4LorentzVector(newP*the4Momentum.vect().unit(), aEnergy));
}
inline void G4KineticTrack::Update4Momentum(const G4ThreeVector & aMomentum)
{
// update the4Momentum with aMomentum at constant mass (the4Momentum.mag()
// updates theTotal4Momentum as well.
G4double newE=sqrt(theTotal4Momentum.mag2() + aMomentum.mag2());
Set4Momentum(G4LorentzVector(aMomentum, newE));
}
inline void G4KineticTrack::SetTrackingMomentum(const G4LorentzVector& aMomentum)
{
// set the4Momentum and update theTotal4Momentum, keep the mass of aMomentum
the4Momentum = aMomentum;
theTotal4Momentum=the4Momentum+theFermi3Momentum;
// keep mass of aMomentum for the total momentum
G4double m2 = aMomentum.mag2();
G4double p2=theTotal4Momentum.vect().mag2();
theTotal4Momentum.setE(sqrt(m2+p2));
}
inline void G4KineticTrack::UpdateTrackingMomentum(G4double aEnergy)
{
// update the4Momentum with aEnergy at constant mass (the4Momentum.mag()
// updates theTotal4Momentum as well.
G4double newP(0);
G4double mass2=theTotal4Momentum.mag2();
if ( sqr(aEnergy) > mass2 )
{
newP = sqrt(sqr(aEnergy) - mass2 );
} else
{
aEnergy=sqrt(mass2);
}
SetTrackingMomentum(G4LorentzVector(newP*the4Momentum.vect().unit(), aEnergy));
}
inline void G4KineticTrack::UpdateTrackingMomentum(const G4ThreeVector & aMomentum)
{
// update the4Momentum with aMomentum at constant mass (the4Momentum.mag()
// updates theTotal4Momentum as well.
G4double newE=sqrt(theTotal4Momentum.mag2() + aMomentum.mag2());
SetTrackingMomentum(G4LorentzVector(aMomentum, newE));
}
inline G4double G4KineticTrack::GetActualMass() const
{
G4ThreeVector theMomentum = the4Momentum.vect();
G4double theMomentum2 = theMomentum.mag2();
G4double theTotalEnergy = the4Momentum.e();
G4double theMass = sqrt(abs(theTotalEnergy * theTotalEnergy - theMomentum2));
return theMass;
}
inline G4int G4KineticTrack::GetnChannels() const
{
return nChannels;
}
inline void G4KineticTrack::SetnChannels(const G4int numberOfChannels)
{
nChannels = numberOfChannels;
}
inline G4double* G4KineticTrack::GetActualWidth() const
{
return theActualWidth;
}
inline void G4KineticTrack::SetActualWidth(G4double* anActualWidth)
{
theActualWidth = anActualWidth;
}
inline G4double G4KineticTrack::EvaluateTotalActualWidth()
{
G4int index;
G4double theTotalActualWidth = 0.0;
for (index = nChannels - 1; index >= 0; index--)
{
theTotalActualWidth += theActualWidth[index];
}
return theTotalActualWidth;
}
inline G4double G4KineticTrack::SampleResidualLifetime()
{
G4double theTotalActualWidth = this->EvaluateTotalActualWidth();
G4double tau = hbar_Planck * (-1.0 / theTotalActualWidth);
G4double theResidualLifetime = tau * log(G4UniformRand());
return theResidualLifetime*the4Momentum.gamma();
}
inline G4double G4KineticTrack::EvaluateCMMomentum(const G4double m,
const G4double* m_ij) const
{
G4double theCMMomentum;
if((m_ij[0]+m_ij[1])<m)
theCMMomentum = 1 / (2 * m) *
sqrt (((m * m) - (m_ij[0] + m_ij[1]) * (m_ij[0] + m_ij[1])) *
((m * m) - (m_ij[0] - m_ij[1]) * (m_ij[0] - m_ij[1])));
else
theCMMomentum=0.;
return theCMMomentum;
}
inline G4double G4KineticTrack::BrWig(const G4double Gamma, const G4double rmass, const G4double mass) const
{
G4double Norm = twopi;
return (Gamma/((mass-rmass)*(mass-rmass)+Gamma*Gamma/4.))/Norm;
}
inline
void G4KineticTrack::Hit()
{
if(theNucleon)
{
theNucleon->Hit(1);
}
}
inline
G4bool G4KineticTrack::IsParticipant() const
{
if(!theNucleon) return true;
return theNucleon->AreYouHit();
}
inline
G4KineticTrack::CascadeState G4KineticTrack::GetState() const
{
return theStateToNucleus;
}
inline
G4KineticTrack::CascadeState G4KineticTrack::SetState(const CascadeState new_state)
{
CascadeState old_state=theStateToNucleus;
theStateToNucleus=new_state;
return old_state;
}
inline
void G4KineticTrack::SetProjectilePotential(G4double aPotential)
{
theProjectilePotential = aPotential;
}
inline
G4double G4KineticTrack::GetProjectilePotential() const
{
return theProjectilePotential;
}
#endif
@@ -0,0 +1,49 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
//
// Modified at 8-Oct-1998 by Maxim Komogorov. Methods BoostBeam,Boost,Shift
// were added.
#ifndef G4KineticTrackVector_h
#define G4KineticTrackVector_h 1
#include "globals.hh"
#include "G4KineticTrack.hh"
#include <vector>
class G4KineticTrackVector : public std::vector<G4KineticTrack *>
{
public:
G4KineticTrackVector();
public:
void BoostBeam(G4ThreeVector& BeamMom);
void Boost(G4ThreeVector& Velocity);
void Shift(G4ThreeVector& Pos);
};
struct DeleteKineticTrack{void operator()(G4KineticTrack * aT){delete aT;}};
#endif
@@ -0,0 +1,68 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
//
//
#ifndef G4NuclearFermiDensity_h
#define G4NuclearFermiDensity_h 1
#include "globals.hh"
#include "G4ThreeVector.hh"
#include "G4VNuclearDensity.hh"
#include <CLHEP/Units/PhysicalConstants.h> // pi, fermi,..
#include <math.h> // pow
class G4NuclearFermiDensity : public G4VNuclearDensity
{
public:
G4NuclearFermiDensity(G4double anA, G4double aZ);
~G4NuclearFermiDensity();
G4double GetRelativeDensity(const G4ThreeVector & aPosition) const
{
return 1./(1.+exp((aPosition.mag()-theR)/a));
}
G4double GetRadius(const G4double maxRelativeDenisty) const
{
return (maxRelativeDenisty>0 && maxRelativeDenisty <= 1 ) ?
(theR + a*log((1-maxRelativeDenisty+exp(-1*theR/a))/maxRelativeDenisty)) : DBL_MAX;
}
G4double GetDeriv(const G4ThreeVector & aPosition) const
{
return -exp((aPosition.mag()-theR)/a) * sqr(GetDensity(aPosition)) / (a*Getrho0());
}
private:
G4int theA;
G4int theZ;
G4double theR; // Nuclear Radius
const G4double a; // Determines the nuclear surface thickness
};
#endif
@@ -0,0 +1,54 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
//
//
#ifndef G4NuclearShellModelDensity_h
#define G4NuclearShellModelDensity_h 1
#include "globals.hh"
#include "G4ThreeVector.hh"
#include "G4VNuclearDensity.hh"
#include <CLHEP/Units/PhysicalConstants.h> // pi, fermi,..
#include <math.h> // pow,..
class G4NuclearShellModelDensity : public G4VNuclearDensity
{
public:
G4NuclearShellModelDensity(G4double anA, G4double aZ);
~G4NuclearShellModelDensity();
G4double GetRelativeDensity(const G4ThreeVector & aPosition) const;
G4double GetRadius(const G4double maxRelativeDenisty) const;
G4double GetDeriv(const G4ThreeVector & aPosition) const;
private:
G4int theA;
G4int theZ;
G4double theRsquare;
};
#endif
@@ -0,0 +1,129 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
//
//
#ifndef G4Nucleon_h
#define G4Nucleon_h 1
// ------------------------------------------------------------
// GEANT 4 class header file
//
// ---------------- G4Nucleon ----------------
// by Gunter Folger, May 1998.
// class for a nucleon (inside a 3D Nucleus)
// ------------------------------------------------------------
#include "G4ThreeVector.hh"
#include "G4LorentzVector.hh"
#include "globals.hh"
#include "G4ParticleDefinition.hh"
#include "G4Proton.hh"
#include "G4Neutron.hh"
#include "G4VKineticNucleon.hh"
//#include "G4VSplitableHadron.hh"
class G4VSplitableHadron;
class G4Nucleon : public G4VKineticNucleon
{
public:
G4Nucleon();
~G4Nucleon();
inline int operator==(const G4Nucleon &right) const;
inline int operator!=(const G4Nucleon &right) const;
const G4Nucleon& operator=(const G4Nucleon& right);
public:
inline void SetPosition(G4ThreeVector & aPosition) {thePosition = aPosition;}
virtual inline const G4ThreeVector & GetPosition() const {return thePosition;}
inline void SetMomentum(G4LorentzVector & aMomentum) {theMomentum = aMomentum;}
inline const G4LorentzVector& GetMomentum() const {return theMomentum;}
virtual inline const G4LorentzVector & Get4Momentum() const {return theMomentum;}
inline void SetBindingEnergy(G4double anEnergy) {theBindingE = anEnergy;}
inline G4double GetBindingEnergy() const {return theBindingE;}
inline void SetParticleType(G4Proton * aProton) {theParticleType = aProton;}
inline void SetParticleType(G4Neutron *aNeutron){theParticleType = aNeutron;}
inline G4ParticleDefinition * GetParticleType() const {return theParticleType;}
virtual G4ParticleDefinition* GetDefinition() const {return theParticleType;}
inline void Boost(const G4ThreeVector & beta){ theMomentum.boost(beta); }
void Boost(const G4LorentzVector & aMomentum);
inline void Hit(G4VSplitableHadron * aHit) { theSplitableHadron=aHit;}
inline void Hit(G4int )
{
theSplitableHadron=reinterpret_cast<G4VSplitableHadron *>(1111);
// G4cout << "$%$#%@%$#@%@%%% "<<theSplitableHadron<<G4endl;
}
inline G4VSplitableHadron * GetSplitableHadron() const { return theSplitableHadron;}
inline G4bool AreYouHit() const
{
G4bool result = true;
if (theSplitableHadron==NULL) result = false;
return result;
}
private:
G4ThreeVector thePosition;
G4LorentzVector theMomentum;
G4double theBindingE;
G4ParticleDefinition * theParticleType;
G4VSplitableHadron * theSplitableHadron;
};
std::ostream & operator << (std::ostream &, const G4Nucleon&);
inline int G4Nucleon::operator==(const G4Nucleon &right) const
{
return this==&right;
}
inline int G4Nucleon::operator!=(const G4Nucleon &right) const
{
return this!=&right;
}
inline const G4Nucleon& G4Nucleon::operator=(const G4Nucleon& right)
{
thePosition=right.GetPosition();
theMomentum=right.Get4Momentum();
theBindingE=right.GetBindingEnergy();
theParticleType=right.GetDefinition();
theSplitableHadron=right.GetSplitableHadron();
return *this;
}
#endif
@@ -0,0 +1,160 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
//
//
#ifndef G4Parton_h
#define G4Parton_h 1
// ------------------------------------------------------------
// GEANT 4 class header file
//
// ---------------- G4Parton ----------------
// by Gunter Folger, June 1998.
// class for Parton (inside a string) used by Parton String Models
// ------------------------------------------------------------
#include "globals.hh"
#include "G4ThreeVector.hh"
#include "G4LorentzVector.hh"
#include <iostream>
#include "G4ParticleTable.hh"
#include "Randomize.hh"
class G4Parton
{
public:
G4Parton()
{
// CAUTION:
// this is a preliminary definition yielding u and d quarks only!
//
PDGencoding=(G4int)(2.*G4UniformRand());
theColour = (G4int)(3.*G4UniformRand())+1;
theIsoSpinZ = ((G4int)(G4UniformRand()))-0.5;
theSpinZ = ((G4int)(G4UniformRand()))-0.5;
}
G4Parton(G4int PDGencoding);
G4Parton(const G4Parton &right);
~G4Parton();
const G4Parton & operator=(const G4Parton &right);
int operator==(const G4Parton &right) const;
int operator!=(const G4Parton &right) const;
G4int GetPDGcode() const;
G4ParticleDefinition * GetDefinition();
void DefineMomentumInZ(G4double aLightConeMomentum, G4bool aDirection);
const G4ThreeVector & GetPosition()const;
void SetPosition(const G4ThreeVector &aPosition);
const G4LorentzVector & Get4Momentum() const;
void Set4Momentum(const G4LorentzVector & aMomentum);
void SetX(G4double anX) { theX = anX; }
G4double GetX() {return theX;}
void SetColour(G4int aColour) {theColour = aColour;}
G4int GetColour() {return theColour;}
void SetIsoSpinZ(G4double anIsoSpinZ) {theIsoSpinZ = anIsoSpinZ;}
G4double GetIsoSpinZ() {return theIsoSpinZ;}
void SetSpinZ(G4double aSpinZ) {theSpinZ = aSpinZ;}
G4double GetSpinZ() {return theSpinZ;}
private:
G4double GetMass();
private:
G4int PDGencoding;
G4ParticleDefinition * theDefinition;
G4LorentzVector theMomentum;
G4ThreeVector thePosition;
G4int theColour;
G4double theIsoSpinZ;
G4double theSpinZ;
G4double theX;
};
inline int G4Parton::operator==(const G4Parton &right) const
{
return this==&right;
}
inline int G4Parton::operator!=(const G4Parton &right) const
{
return this!=&right;
}
inline G4int G4Parton::GetPDGcode() const
{
return PDGencoding;
}
inline const G4ThreeVector & G4Parton::GetPosition() const
{
return thePosition;
}
inline void G4Parton::SetPosition(const G4ThreeVector &aPosition)
{
thePosition=aPosition;
}
inline const G4LorentzVector & G4Parton::Get4Momentum() const
{
return theMomentum;
}
inline void G4Parton::Set4Momentum(const G4LorentzVector & aMomentum)
{
theMomentum=aMomentum;
}
inline
G4double G4Parton::GetMass()
{
return theDefinition->GetPDGMass();
}
inline
G4ParticleDefinition * G4Parton::GetDefinition()
{
return theDefinition;
}
#endif
@@ -0,0 +1,41 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
//
//
#ifndef G4PartonVector_h
#define G4PartonVector_h 1
// ------------------------------------------------------------
// GEANT 4 class header file
//
// ---------------- G4PartonVector ----------------
// by Gunter Folger, May 1998.
// ------------------------------------------------------------
#include "G4Parton.hh"
#include <vector>
typedef std::vector<G4Parton *> G4PartonVector;
struct DeleteParton{ void operator()(G4Parton*aP){delete aP;} };
#endif
@@ -0,0 +1,82 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
//
//
#ifndef G4SampleResonance_h
#define G4SampleResonance_h 1
// ------------------------------------------------------------
// GEANT 4 class header file
//
// ---------------- G4SampleResonance ----------------
// by Henning Weber, March 2001.
// helper class for sampling resonance masses
// ------------------------------------------------------------
#include "globals.hh"
#include <map>
#include "G4ParticleDefinition.hh"
class G4SampleResonance
{
public:
G4double GetMinimumMass(const G4ParticleDefinition* p) const;
G4double SampleMass(const G4double poleMass,
const G4double gamma,
const G4double minMass,
const G4double maxMass) const;
G4double SampleMass(const G4ParticleDefinition* p, const G4double maxMass) const;
private:
G4double BrWigInt0(const G4double x, const G4double gamma, const G4double m0) const
{ return 2.0*gamma*atan( 2.0 * (x-m0)/ gamma ); }
G4double BrWigInt1(const G4double x, const G4double gamma, const G4double m0) const
{ return 0.5*gamma*gamma*log( (x-m0)*(x-m0)+gamma*gamma/4.0 ) + m0*BrWigInt0(x,gamma,m0); }
G4double BrWigInv(const G4double x, const G4double gamma, const G4double m0) const
{ return 0.5*gamma*tan( 0.5*x/gamma )+m0; }
public:
typedef std::map<const G4ParticleDefinition*, G4double, std::less<const G4ParticleDefinition*> >::const_iterator minMassMapIterator;
typedef std::map<const G4ParticleDefinition*, G4double, std::less<const G4ParticleDefinition*> > minMassMapType;
private:
static minMassMapType minMassCache;
};
#endif
@@ -0,0 +1,165 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
//
//
// ------------------------------------------------------------
// GEANT 4 class implementation file
//
// ---------------- G4ExcitedString ----------------
// by Gunter Folger, June 1998.
// class for an excited string used by Parton String Models
// ------------------------------------------------------------
// G4ExcitedString
#include "G4ExcitedString.hh"
#include <algorithm>
//G4ExcitedString::G4ExcitedString(const G4ExcitedString &right)
//{}
G4ExcitedString::G4ExcitedString(G4Parton* Color, G4Parton* AntiColor, G4int Direction)
{
thePartons.push_back(Color);
thePartons.push_back(AntiColor);
thePosition = Color->GetPosition();
theDirection = Direction;
theTrack=0;
}
G4ExcitedString::G4ExcitedString(G4Parton* Color, G4Parton* Gluon, G4Parton* AntiColor, G4int Direction)
{
thePartons.push_back(Color);
thePartons.push_back(Gluon);
thePartons.push_back(AntiColor);
thePosition = Color->GetPosition();
theDirection = Direction;
theTrack=0;
}
G4ExcitedString::G4ExcitedString(G4KineticTrack * track)
{
thePosition = track->GetPosition();
theTrack= track;
theDirection=0;
}
G4ExcitedString::~G4ExcitedString()
{
std::for_each(thePartons.begin(), thePartons.end(), DeleteParton());
}
//const G4ExcitedString & G4ExcitedString::operator=(const G4ExcitedString &right)
//{}
//int G4ExcitedString::operator==(const G4ExcitedString &right) const
//{}
//int G4ExcitedString::operator!=(const G4ExcitedString &right) const
//{}
// Additional Declarations
void G4ExcitedString::Boost(G4ThreeVector& Velocity)
{
for(unsigned int cParton = 0; cParton < thePartons.size() ; cParton++ )
{
G4LorentzVector Mom = thePartons[cParton]->Get4Momentum();
Mom.boost(Velocity);
thePartons[cParton]->Set4Momentum(Mom);
}
}
//---------------------------------------------------------------------------------
G4Parton* G4ExcitedString::GetColorParton(void) const
{
G4Parton * start = *(thePartons.begin());
G4Parton * end = *(thePartons.end()-1);
G4int Encoding = start->GetPDGcode();
if (Encoding < -1000 || ((Encoding < 1000) && (Encoding > 0)))
return start;
return end;
}
//---------------------------------------------------------------------------------
G4Parton* G4ExcitedString::GetGluon(void) const
{
return thePartons[1];
}
//---------------------------------------------------------------------------------
G4Parton* G4ExcitedString::GetGluon(G4int GluonPos) const
{
return thePartons[1 + GluonPos];
}
//---------------------------------------------------------------------------------
G4Parton* G4ExcitedString::GetAntiColorParton(void) const
{
G4Parton * start = *(thePartons.begin());
G4Parton * end = *(thePartons.end()-1);
G4int Encoding = start->GetPDGcode();
if (Encoding < -1000 || ((Encoding < 1000) && (Encoding > 0)))
return end;
return start;
}
//---------------------------------------------------------------------------------
G4bool G4ExcitedString::IsItKinkyString(void) const
{
return (thePartons.size() > 2);
}
//---------------------------------------------------------------------------------
G4int G4ExcitedString::GetDirection(void) const
{
return theDirection;
}
//*********************************************************************************
G4Parton* G4ExcitedString::GetLeftParton(void) const
{
return *thePartons.begin();
}
//---------------------------------------------------------------------------------
G4Parton* G4ExcitedString::GetRightParton(void) const
{
return *(thePartons.end()-1);
}
//*********************************************************************************
@@ -0,0 +1,516 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
//
//
// ------------------------------------------------------------
// GEANT 4 class implementation file
//
// ---------------- G4Fancy3DNucleus ----------------
// by Gunter Folger, May 1998.
// class for a 3D nucleus, arranging nucleons in space and momentum.
// ------------------------------------------------------------
#include "G4Fancy3DNucleus.hh"
#include "G4NuclearFermiDensity.hh"
#include "G4NuclearShellModelDensity.hh"
#include "G4NucleiPropertiesTable.hh"
#include "Randomize.hh"
#include "G4ios.hh"
#include <algorithm>
#include "G4HadronicException.hh"
G4Fancy3DNucleus::G4Fancy3DNucleus()
: nucleondistance(0.8*fermi)
{
theDensity=NULL;
theNucleons=NULL;
currentNucleon=-1;
myA=0;
myZ=0;
//G4cout <<"G4Fancy3DNucleus::G4Fancy3DNucleus()"<<G4endl;
}
/* No use for these
*
*G4Fancy3DNucleus::G4Fancy3DNucleus(const G4Fancy3DNucleus &right)
* : nucleondistance(0.8*fermi) {}
*const G4Fancy3DNucleus & G4Fancy3DNucleus::operator=(const G4Fancy3DNucleus &right)
*{
*}
*
*
*int G4Fancy3DNucleus::operator==(const G4Fancy3DNucleus &right) const
*{
*}
*
*int G4Fancy3DNucleus::operator!=(const G4Fancy3DNucleus &right) const
*{
*}
*
*/
G4Fancy3DNucleus::~G4Fancy3DNucleus()
{
if(theNucleons!=NULL) delete [] theNucleons;
if(theDensity!=NULL) delete theDensity;
}
void G4Fancy3DNucleus::Init(G4double theA, G4double theZ)
{
// G4cout << "G4Fancy3DNucleus::Init(theA, theZ) called"<<G4endl;
currentNucleon=-1;
if(theNucleons!=NULL) delete [] theNucleons;
// this was delected already:
// std::for_each(theRWNucleons.begin(), theRWNucleons.end(), DeleteNucleon());
theRWNucleons.clear();
myZ = G4int(theZ);
myA= ( G4UniformRand()>theA-G4int(theA) ) ? G4int(theA) : G4int(theA)+1;
theNucleons = new G4Nucleon[myA];
// G4cout << "myA, myZ" << myA << ", " << myZ << G4endl;
if(theDensity!=NULL) delete theDensity;
if ( myA < 17 ) {
theDensity = new G4NuclearShellModelDensity(myA, myZ);
} else {
theDensity = new G4NuclearFermiDensity(myA, myZ);
}
theFermi.Init(myA, myZ);
ChooseNucleons();
ChoosePositions();
// CenterNucleons(); // This would introduce a bias
ChooseFermiMomenta();
G4double Ebinding= BindingEnergy()/myA;
for (G4int aNucleon=0; aNucleon < myA; aNucleon++)
{
theNucleons[aNucleon].SetBindingEnergy(Ebinding);
}
return;
}
G4bool G4Fancy3DNucleus::StartLoop()
{
currentNucleon=0;
return theNucleons != NULL;
}
G4Nucleon * G4Fancy3DNucleus::GetNextNucleon()
{
return ( currentNucleon>=0 && currentNucleon<myA ) ?
theNucleons+currentNucleon++ : NULL;
}
const std::vector<G4Nucleon *> & G4Fancy3DNucleus::GetNucleons()
{
if ( theRWNucleons.size()==0 )
{
for (G4int i=0; i< myA; i++)
{
theRWNucleons.push_back(theNucleons+i);
}
}
return theRWNucleons;
}
G4double G4Fancy3DNucleus::BindingEnergy()
{
return G4NucleiPropertiesTable::GetBindingEnergy(myZ,myA);
}
G4double G4Fancy3DNucleus::GetNuclearRadius()
{
return GetNuclearRadius(0.5);
}
G4double G4Fancy3DNucleus::GetNuclearRadius(const G4double maxRelativeDensity)
{
return theDensity->GetRadius(maxRelativeDensity);
}
G4double G4Fancy3DNucleus::GetOuterRadius()
{
G4double maxradius2=0;
for (int i=0; i<myA; i++)
{
if ( theNucleons[i].GetPosition().mag2() > maxradius2 )
{
maxradius2=theNucleons[i].GetPosition().mag2();
}
}
return sqrt(maxradius2)+nucleondistance;
}
G4double G4Fancy3DNucleus::GetMass()
{
return myZ*G4Proton::Proton()->GetPDGMass() +
(myA-myZ)*G4Neutron::Neutron()->GetPDGMass() -
BindingEnergy();
}
void G4Fancy3DNucleus::DoLorentzBoost(const G4LorentzVector & theBoost)
{
for (G4int i=0; i<myA; i++){
theNucleons[i].Boost(theBoost);
}
}
void G4Fancy3DNucleus::DoLorentzBoost(const G4ThreeVector & theBeta)
{
for (G4int i=0; i<myA; i++){
theNucleons[i].Boost(theBeta);
}
}
void G4Fancy3DNucleus::DoLorentzContraction(const G4ThreeVector & theBeta)
{
G4double factor=(1-sqrt(1-theBeta.mag2()))/theBeta.mag2(); // (gamma-1)/gamma/beta**2
for (G4int i=0; i< myA; i++)
{
G4ThreeVector rprime=theNucleons[i].GetPosition() -
factor * (theBeta*theNucleons[i].GetPosition()) *
// theNucleons[i].GetPosition();
theBeta;
theNucleons[i].SetPosition(rprime);
}
}
void G4Fancy3DNucleus::DoLorentzContraction(const G4LorentzVector & theBoost)
{
G4ThreeVector beta= 1/theBoost.e() * theBoost.vect();
// DoLorentzBoost(beta);
DoLorentzContraction(beta);
}
void G4Fancy3DNucleus::CenterNucleons()
{
G4ThreeVector center;
for (G4int i=0; i<myA; i++ )
{
center+=theNucleons[i].GetPosition();
}
center *= -1./myA;
DoTranslation(center);
}
void G4Fancy3DNucleus::DoTranslation(const G4ThreeVector & theShift)
{
for (G4int i=0; i<myA; i++ )
{
G4ThreeVector tempV = theNucleons[i].GetPosition() + theShift;
theNucleons[i].SetPosition(tempV);
}
}
const G4VNuclearDensity * G4Fancy3DNucleus::GetNuclearDensity() const
{
return theDensity;
}
//----------------------- private Implementation Methods-------------
void G4Fancy3DNucleus::ChooseNucleons()
{
G4int protons=0,nucleons=0;
while (nucleons < myA )
{
if ( protons < myZ && G4UniformRand() < (G4double)(myZ-protons)/(G4double)(myA-nucleons) )
{
protons++;
theNucleons[nucleons++].SetParticleType(G4Proton::Proton());
}
else if ( (nucleons-protons) < (myA-myZ) )
{
theNucleons[nucleons++].SetParticleType(G4Neutron::Neutron());
}
else G4cout << "G4Fancy3DNucleus::ChooseNucleons not efficient" << G4endl;
}
return;
}
void G4Fancy3DNucleus::ChoosePositions()
{
G4int i=0;
G4ThreeVector aPos,center;
G4bool freeplace;
G4double maxR=GetNuclearRadius(0.01); // there are no nucleons at a
// relative Density of 0.01
while ( i < myA )
{
do
{ aPos=G4ThreeVector( (2*G4UniformRand()-1.),
(2*G4UniformRand()-1.),
(2*G4UniformRand()-1.));
} while (aPos.mag2() > 1. );
aPos *=maxR;
G4double density=theDensity->GetRelativeDensity(aPos);
if (G4UniformRand() < density)
{
freeplace= true;
G4double pFermi=theFermi.GetFermiMomentum(theDensity->GetDensity(aPos));
// protons must at least have binding energy of CoulombBarrier, so
// assuming the Fermi energy corresponds to a potential, we must place these such
// that the Fermi Energy > CoulombBarrier
if (theNucleons[i].GetDefinition() == G4Proton::Proton())
{
G4double eFermi= sqrt( sqr(pFermi) + sqr(theNucleons[i].GetDefinition()->GetPDGMass()) )
- theNucleons[i].GetDefinition()->GetPDGMass();
if (eFermi <= CoulombBarrier() ) freeplace=false;
}
for( int j=0; j<i && freeplace; j++)
{
freeplace= freeplace &&
(theNucleons[j].GetPosition()-aPos).mag() > nucleondistance;
}
if ( freeplace )
{
theNucleons[i].SetPosition(aPos);
++i;
}
}
}
}
void G4Fancy3DNucleus::ChooseFermiMomenta()
{
G4int i;
G4double density;
G4ThreeVector * momentum=new G4ThreeVector[myA];
G4double * fermiM=new G4double[myA];
for (G4int ntry=0; ntry<1 ; ntry ++ )
{
for (i=0; i < myA; i++ ) // momenta for all, including last, in case we swap nucleons
{
density = theDensity->GetDensity(theNucleons[i].GetPosition());
fermiM[i] = theFermi.GetFermiMomentum(density);
G4ThreeVector mom=theFermi.GetMomentum(density);
if (theNucleons[i].GetDefinition() == G4Proton::Proton())
{
G4double eMax = sqrt(sqr(fermiM[i]) +sqr(theNucleons[i].GetDefinition()->GetPDGMass()) )
- CoulombBarrier();
if ( eMax > theNucleons[i].GetDefinition()->GetPDGMass() )
{
G4double pmax2= sqr(eMax) - sqr(theNucleons[i].GetDefinition()->GetPDGMass());
fermiM[i] = sqrt(pmax2);
while ( mom.mag2() > pmax2 )
{
mom=theFermi.GetMomentum(density, fermiM[i]);
}
} else
{
G4cerr << "G4Fancy3DNucleus: difficulty finding proton momentum" << G4endl;
mom=0;
}
}
momentum[i]= mom;
}
if (ReduceSum(momentum,fermiM) )
break;
// G4cout <<" G4FancyNucleus: iterating to find momenta: "<< ntry<< G4endl;
}
// G4ThreeVector sum;
// for (G4int index=0; index<myA;sum+=momentum[index++])
// ;
// G4cout << "final sum / mag() " << sum << " / " << sum.mag() << G4endl;
G4double energy;
for ( i=0; i< myA ; i++ )
{
energy = theNucleons[i].GetParticleType()->GetPDGMass()
- BindingEnergy()/myA;
G4LorentzVector tempV(momentum[i],energy);
theNucleons[i].SetMomentum(tempV);
}
delete [] momentum;
delete [] fermiM;
}
class G4Fancy3DNucleusHelper // Helper class
{
public:
G4Fancy3DNucleusHelper(const G4ThreeVector &vec,const G4double size,const G4int index)
: Vector(vec), Size(size), anInt(index) {}
int operator ==(const G4Fancy3DNucleusHelper &right) const
{
return this==&right;
}
int operator < (const G4Fancy3DNucleusHelper &right) const
{
return size()<right.size();
}
const G4ThreeVector& vector() const
{
return Vector;
}
const G4double size() const
{
return Size;
}
const G4int index() const
{
return anInt;
}
G4Fancy3DNucleusHelper operator =(const G4Fancy3DNucleusHelper &right)
{
Vector = right.Vector;
Size = right.Size;
anInt = right.anInt;
return *this;
}
private:
G4Fancy3DNucleusHelper(): Vector(0), Size(0), anInt(0) {G4cout << "def ctor for MixMasch" << G4endl;}
G4ThreeVector Vector;
G4double Size;
G4int anInt;
};
G4bool G4Fancy3DNucleus::ReduceSum(G4ThreeVector * momentum, G4double *pFermiM)
{
G4ThreeVector sum;
G4double PFermi=pFermiM[myA-1];
for (G4int i=0; i < myA-1 ; i++ )
{ sum+=momentum[i]; }
// check if have to do anything at all..
if ( sum.mag() <= PFermi )
{
momentum[myA-1]=-sum;
return true;
}
// find all possible changes in momentum, changing only the component parallel to sum
G4ThreeVector testDir=sum.unit();
std::vector<G4Fancy3DNucleusHelper> testSums; // Sorted on delta.mag()
for ( G4int aNucleon=0; aNucleon < myA-1; aNucleon++){
G4ThreeVector delta=2*((momentum[aNucleon]*testDir)* testDir);
testSums.push_back(G4Fancy3DNucleusHelper(delta,delta.mag(),aNucleon));
}
std::sort(testSums.begin(), testSums.end());
// reduce Momentum Sum until the next would be allowed.
G4int index=testSums.size();
while ( (sum-testSums[--index].vector()).mag()>PFermi && index>0)
{
// Only take one which improve, ie. don't change sign and overshoot...
if ( sum.mag() > (sum-testSums[index].vector()).mag() ) {
momentum[testSums[index].index()]-=testSums[index].vector();
sum-=testSums[index].vector();
}
}
if ( (sum-testSums[index].vector()).mag() <= PFermi )
{
G4int best=-1;
G4double pBest=2*PFermi; // anything larger than PFermi
for ( G4int aNucleon=0; aNucleon<=index; aNucleon++)
{
// find the momentum closest to choosen momentum for last Nucleon.
G4double pTry=(testSums[aNucleon].vector()-sum).mag();
if ( pTry < PFermi
&& abs(momentum[myA-1].mag() - pTry ) < pBest )
{
pBest=abs(momentum[myA-1].mag() - pTry );
best=aNucleon;
}
}
if ( best < 0 )
{
G4String text = "G4Fancy3DNucleus.cc: Logic error in ReduceSum()";
throw G4HadronicException(__FILE__, __LINE__, text);
}
momentum[testSums[best].index()]-=testSums[best].vector();
momentum[myA-1]=testSums[best].vector()-sum;
testSums.clear();
return true;
}
testSums.clear();
// try to compensate momentum using another Nucleon....
G4int swapit=-1;
while (swapit<myA-1)
{
if ( pFermiM[++swapit] > PFermi ) break;
}
if (swapit == myA-1 ) return false;
// Now we have a nucleon with a bigger Fermi Momentum.
// Exchange with last nucleon.. and iterate.
// G4cout << " Nucleon to swap with : " << swapit << G4endl;
// G4cout << " Fermi momentum test, and better.. " << PFermi << " / "
// << theFermi.GetFermiMomentum(density) << G4endl;
// cout << theNucleons[swapit]<< G4endl << theNucleons[myA-1] << G4endl;
// cout << momentum[swapit] << G4endl << momentum[myA-1] << G4endl;
G4Nucleon swap= theNucleons[swapit];
G4ThreeVector mom_swap=momentum[swapit];
G4double pf=pFermiM[swapit];
theNucleons[swapit]=theNucleons[myA-1];
momentum[swapit]=momentum[myA-1];
pFermiM[swapit]=pFermiM[myA-1];
theNucleons[myA-1]=swap;
momentum[myA-1]=mom_swap;
pFermiM[myA-1]=pf;
// cout << "after swap" <<G4endl<< theNucleons[swapit] << G4endl << theNucleons[myA-1] << G4endl;
// cout << momentum[swapit] << G4endl << momentum[myA-1] << G4endl;
return ReduceSum(momentum,pFermiM);
}
G4double G4Fancy3DNucleus::CoulombBarrier()
{
G4double coulombBarrier = (1.44/1.14) * MeV * myZ / (1.0 + pow(G4double(myA),1./3.));
return coulombBarrier;
}
@@ -0,0 +1,28 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
//
//
#include "G4FermiMomentum.hh"
G4FermiMomentum::G4FermiMomentum() : constofpmax(hbarc*cbrt(3.*pi2)) {}
G4FermiMomentum::~G4FermiMomentum(){}
@@ -0,0 +1,229 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
//
//
// Hadronic Process: Nuclear De-excitations
// by V. Lara (May 1998)
#include "G4Fragment.hh"
#include "G4HadronicException.hh"
#include "G4HadTmpUtil.hh"
// Default constructor
G4Fragment::G4Fragment() :
theA(0),
theZ(0),
theExcitationEnergy(0.0),
theMomentum(0),
theAngularMomentum(0),
numberOfParticles(0),
numberOfHoles(0),
numberOfCharged(0),
theParticleDefinition(0),
theCreationTime(0.0)
#ifdef PRECOMPOUND_TEST
,theCreatorModel("No name")
#endif
{
theAngularMomentum = IsotropicRandom3Vector();
}
// Copy Constructor
G4Fragment::G4Fragment(const G4Fragment &right)
{
theA = right.theA;
theZ = right.theZ;
theExcitationEnergy = right.theExcitationEnergy;
theMomentum = right.theMomentum;
theAngularMomentum = right.theAngularMomentum;
numberOfParticles = right.numberOfParticles;
numberOfHoles = right.numberOfHoles;
numberOfCharged = right.numberOfCharged;
theParticleDefinition = right.theParticleDefinition;
theCreationTime = right.theCreationTime;
#ifdef PRECOMPOUND_TEST
theCreatorModel = right.theCreatorModel;
#endif
}
G4Fragment::~G4Fragment()
{
}
G4Fragment::G4Fragment(const G4int A, const G4int Z, const G4LorentzVector aMomentum) :
theA(A),
theZ(Z),
theMomentum(aMomentum),
numberOfParticles(0),
numberOfHoles(0),
numberOfCharged(0),
theParticleDefinition(0),
theCreationTime(0.0)
#ifdef PRECOMPOUND_TEST
,theCreatorModel("No name")
#endif
{
theExcitationEnergy = theMomentum.mag() -
G4ParticleTable::GetParticleTable()->GetIonTable()
->GetIonMass( G4lrint(theZ), G4lrint(theA) );
if( theExcitationEnergy < 0.0 )
if( theExcitationEnergy > -10.0 * eV || 0==G4lrint(theA))
theExcitationEnergy = 0.0;
else
{
G4cout << "A, Z, momentum, theExcitationEnergy"<<
A<<" "<<Z<<" "<<aMomentum<<" "<<theExcitationEnergy<<G4endl;
G4String text = "G4Fragment::G4Fragment Excitation Energy < 0.0!";
throw G4HadronicException(__FILE__, __LINE__, text);
}
}
// This constructor is for initialize photons
G4Fragment::G4Fragment(const G4LorentzVector aMomentum, G4ParticleDefinition * aParticleDefinition) :
theA(0),
theZ(0),
theMomentum(aMomentum),
numberOfParticles(0),
numberOfHoles(0),
numberOfCharged(0),
theParticleDefinition(aParticleDefinition),
theCreationTime(0.0)
#ifdef PRECOMPOUND_TEST
,theCreatorModel("No name")
#endif
{
theExcitationEnergy = CalculateExcitationEnergy(aMomentum);
theAngularMomentum = IsotropicRandom3Vector();
}
const G4Fragment & G4Fragment::operator=(const G4Fragment &right)
{
if (this != &right) {
theA = right.theA;
theZ = right.theZ;
theExcitationEnergy = right.theExcitationEnergy;
theMomentum = right.theMomentum;
theAngularMomentum = right.theAngularMomentum;
numberOfParticles = right.numberOfParticles;
numberOfHoles = right.numberOfHoles;
numberOfCharged = right.numberOfCharged;
theParticleDefinition = right.theParticleDefinition;
theCreationTime = right.theCreationTime;
#ifdef PRECOMPOUND_TEST
theCreatorModel = right.theCreatorModel;
#endif
}
return *this;
}
G4bool G4Fragment::operator==(const G4Fragment &right) const
{
return (this == (G4Fragment *) &right);
}
G4bool G4Fragment::operator!=(const G4Fragment &right) const
{
return (this != (G4Fragment *) &right);
}
std::ostream& operator << (std::ostream &out, const G4Fragment *theFragment)
{
std::ios::fmtflags old_floatfield = out.flags();
out.setf(std::ios::floatfield);
out
<< "Fragment: A = " << std::setprecision(3) << theFragment->theA
<< ", Z = " << std::setprecision(3) << theFragment->theZ ;
out.setf(std::ios::scientific,std::ios::floatfield);
out
<< ", U = " << theFragment->GetExcitationEnergy()/MeV
<< " MeV" << G4endl
<< " P = ("
<< theFragment->theMomentum.x()/MeV << ","
<< theFragment->theMomentum.y()/MeV << ","
<< theFragment->theMomentum.z()/MeV
<< ") MeV E = "
<< theFragment->theMomentum.t()/MeV << " MeV";
// What about Angular momentum???
if (theFragment->GetNumberOfExcitons() != 0) {
out << G4endl;
out << " "
<< "#Particles = " << theFragment->numberOfParticles
<< ", #Holes = " << theFragment->numberOfHoles
<< ", #Charged = " << theFragment->numberOfCharged;
}
out.setf(old_floatfield,std::ios::floatfield);
return out;
}
std::ostream& operator << (std::ostream &out, const G4Fragment &theFragment)
{
out << &theFragment;
return out;
}
G4double G4Fragment::CalculateExcitationEnergy(const G4LorentzVector value) const
{
G4double theMaxGroundStateMass = theZ*G4Proton::Proton()->GetPDGMass()+
(theA-theZ)*G4Neutron::Neutron()->GetPDGMass();
G4double U = value.m() - std::min(theMaxGroundStateMass, GetGroundStateMass());
if( U < 0.0 )
if( U > -10.0 * eV || 0==G4lrint(theA))
U = 0.0;
else
{
G4cerr << "G4Fragment::G4Fragment Excitation Energy ="
<<U << " for A = "<<theA<<" and Z= "<<theZ<<G4endl;
U=0.0;
}
return U;
}
G4ThreeVector G4Fragment::IsotropicRandom3Vector(const G4double Magnitude) const
// Create a unit vector with a random direction isotropically distributed
{
G4double CosTheta = 1.0 - 2.0*G4UniformRand();
G4double SinTheta = sqrt(1.0 - CosTheta*CosTheta);
G4double Phi = twopi*G4UniformRand();
G4ThreeVector Vector(Magnitude*cos(Phi)*SinTheta,
Magnitude*sin(Phi)*SinTheta,
Magnitude*CosTheta);
return Vector;
}
@@ -0,0 +1,496 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
//
//
// $Id: G4GeneralSpaceDecay.cc,v 1.0 1998/05/21
// ----------------------------------------------------------------
// GEANT 4 class header file
//
// History: first implementation, A. Feliciello, 21st May 1998
//
// Note: this class is a generalization of the
// G4PhaseSpaceDecayChannel one
// ----------------------------------------------------------------
#include "G4ParticleDefinition.hh"
#include "G4DecayProducts.hh"
#include "G4VDecayChannel.hh"
#include "G4GeneralPhaseSpaceDecay.hh"
#include "Randomize.hh"
#include "G4LorentzVector.hh"
#include "G4LorentzRotation.hh"
#include "G4ios.hh"
G4GeneralPhaseSpaceDecay::G4GeneralPhaseSpaceDecay(G4int Verbose) :
G4VDecayChannel("Phase Space", Verbose)
{
if (GetVerboseLevel()>1) G4cout << "G4GeneralPhaseSpaceDecay:: constructor " << G4endl;
}
G4GeneralPhaseSpaceDecay::G4GeneralPhaseSpaceDecay(const G4String& theParentName,
G4double theBR,
G4int theNumberOfDaughters,
const G4String& theDaughterName1,
const G4String& theDaughterName2,
const G4String& theDaughterName3) :
G4VDecayChannel("Phase Space",
theParentName,theBR,
theNumberOfDaughters,
theDaughterName1,
theDaughterName2,
theDaughterName3)
{
if (GetVerboseLevel()>1) G4cout << "G4GeneralPhaseSpaceDecay:: constructor " << G4endl;
// Set the parent particle (resonance) mass to the (default) PDG vale
if (parent != NULL)
{
parentmass = parent->GetPDGMass();
}
}
G4GeneralPhaseSpaceDecay::G4GeneralPhaseSpaceDecay(const G4String& theParentName,
G4double theParentMass,
G4double theBR,
G4int theNumberOfDaughters,
const G4String& theDaughterName1,
const G4String& theDaughterName2,
const G4String& theDaughterName3) :
G4VDecayChannel("Phase Space",
theParentName,theBR,
theNumberOfDaughters,
theDaughterName1,
theDaughterName2,
theDaughterName3),
parentmass(theParentMass)
{
if (GetVerboseLevel()>1) G4cout << "G4GeneralPhaseSpaceDecay:: constructor " << G4endl;
}
G4GeneralPhaseSpaceDecay::~G4GeneralPhaseSpaceDecay()
{
}
G4DecayProducts *G4GeneralPhaseSpaceDecay::DecayIt(G4double)
{
if (GetVerboseLevel()>1) G4cout << "G4GeneralPhaseSpaceDecay::DecayIt ";
G4DecayProducts * products = NULL;
if (parent == NULL) FillParent();
if (daughters == NULL) FillDaughters();
switch (numberOfDaughters){
case 0:
if (GetVerboseLevel()>0) {
G4cout << "G4GeneralPhaseSpaceDecay::DecayIt ";
G4cout << " daughters not defined " <<G4endl;
}
break;
case 1:
products = OneBodyDecayIt();
break;
case 2:
products = TwoBodyDecayIt();
break;
case 3:
products = ThreeBodyDecayIt();
break;
default:
products = ManyBodyDecayIt();
break;
}
if ((products == NULL) && (GetVerboseLevel()>0)) {
G4cout << "G4GeneralPhaseSpaceDecay::DecayIt ";
G4cout << *parent_name << " can not decay " << G4endl;
DumpInfo();
}
return products;
}
G4DecayProducts *G4GeneralPhaseSpaceDecay::OneBodyDecayIt()
{
if (GetVerboseLevel()>1) G4cout << "G4GeneralPhaseSpaceDecay::OneBodyDecayIt()"<<G4endl;
// G4double daughtermass = daughters[0]->GetPDGMass();
//create parent G4DynamicParticle at rest
G4ParticleMomentum dummy;
G4DynamicParticle * parentparticle = new G4DynamicParticle(parent, dummy, 0.0);
//create G4Decayproducts
G4DecayProducts *products = new G4DecayProducts(*parentparticle);
delete parentparticle;
//create daughter G4DynamicParticle at rest
G4DynamicParticle * daughterparticle = new G4DynamicParticle(daughters[0], dummy, 0.0);
products->PushProducts(daughterparticle);
if (GetVerboseLevel()>1)
{
G4cout << "G4GeneralPhaseSpaceDecay::OneBodyDecayIt ";
G4cout << " create decay products in rest frame " <<G4endl;
products->DumpInfo();
}
return products;
}
G4DecayProducts *G4GeneralPhaseSpaceDecay::TwoBodyDecayIt()
{
if (GetVerboseLevel()>1) G4cout << "G4GeneralPhaseSpaceDecay::TwoBodyDecayIt()"<<G4endl;
//daughters'mass
G4double daughtermass[2];
G4double daughtermomentum;
daughtermass[0] = daughters[0]->GetPDGMass();
daughtermass[1] = daughters[1]->GetPDGMass();
// G4double sumofdaughtermass = daughtermass[0] + daughtermass[1];
//create parent G4DynamicParticle at rest
G4ParticleMomentum dummy;
G4DynamicParticle * parentparticle = new G4DynamicParticle( parent, dummy, 0.0);
//create G4Decayproducts
G4DecayProducts *products = new G4DecayProducts(*parentparticle);
delete parentparticle;
//calculate daughter momentum
daughtermomentum = Pmx(parentmass,daughtermass[0],daughtermass[1]);
G4double costheta = 2.*G4UniformRand()-1.0;
G4double sintheta = sqrt((1.0 - costheta)*(1.0 + costheta));
G4double phi = 2.0*M_PI*G4UniformRand()*rad;
G4ParticleMomentum direction(sintheta*cos(phi),sintheta*sin(phi),costheta);
//create daughter G4DynamicParticle
G4DynamicParticle * daughterparticle = new G4DynamicParticle( daughters[0], direction*daughtermomentum);
products->PushProducts(daughterparticle);
daughterparticle = new G4DynamicParticle( daughters[1], direction*(-1.0*daughtermomentum));
products->PushProducts(daughterparticle);
if (GetVerboseLevel()>1)
{
G4cout << "G4GeneralPhaseSpaceDecay::TwoBodyDecayIt ";
G4cout << " create decay products in rest frame " <<G4endl;
products->DumpInfo();
}
return products;
}
G4DecayProducts *G4GeneralPhaseSpaceDecay::ThreeBodyDecayIt()
// algorism of this code is originally written in GDECA3 of GEANT3
{
if (GetVerboseLevel()>1) G4cout << "G4GeneralPhaseSpaceDecay::ThreeBodyDecayIt()"<<G4endl;
//daughters'mass
G4double daughtermass[3];
G4double sumofdaughtermass = 0.0;
for (G4int index=0; index<3; index++)
{
daughtermass[index] = daughters[index]->GetPDGMass();
sumofdaughtermass += daughtermass[index];
}
//create parent G4DynamicParticle at rest
G4ParticleMomentum dummy;
G4DynamicParticle * parentparticle = new G4DynamicParticle( parent, dummy, 0.0);
//create G4Decayproducts
G4DecayProducts *products = new G4DecayProducts(*parentparticle);
delete parentparticle;
//calculate daughter momentum
// Generate two
G4double rd1, rd2, rd;
G4double daughtermomentum[3];
G4double momentummax=0.0, momentumsum = 0.0;
G4double energy;
do
{
rd1 = G4UniformRand();
rd2 = G4UniformRand();
if (rd2 > rd1)
{
rd = rd1;
rd1 = rd2;
rd2 = rd;
}
momentummax = 0.0;
momentumsum = 0.0;
// daughter 0
energy = rd2*(parentmass - sumofdaughtermass);
daughtermomentum[0] = sqrt(energy*energy + 2.0*energy* daughtermass[0]);
if ( daughtermomentum[0] >momentummax )momentummax = daughtermomentum[0];
momentumsum += daughtermomentum[0];
// daughter 1
energy = (1.-rd1)*(parentmass - sumofdaughtermass);
daughtermomentum[1] = sqrt(energy*energy + 2.0*energy* daughtermass[1]);
if ( daughtermomentum[1] >momentummax )momentummax = daughtermomentum[1];
momentumsum += daughtermomentum[1];
// daughter 2
energy = (rd1-rd2)*(parentmass - sumofdaughtermass);
daughtermomentum[2] = sqrt(energy*energy + 2.0*energy* daughtermass[2]);
if ( daughtermomentum[2] >momentummax )momentummax = daughtermomentum[2];
momentumsum += daughtermomentum[2];
} while (momentummax > momentumsum - momentummax );
// output message
if (GetVerboseLevel()>1) {
G4cout << " daughter 0:" << daughtermomentum[0]/GeV << "[GeV/c]" <<G4endl;
G4cout << " daughter 1:" << daughtermomentum[1]/GeV << "[GeV/c]" <<G4endl;
G4cout << " daughter 2:" << daughtermomentum[2]/GeV << "[GeV/c]" <<G4endl;
G4cout << " momentum sum:" << momentumsum/GeV << "[GeV/c]" <<G4endl;
}
//create daughter G4DynamicParticle
G4double costheta, sintheta, phi, sinphi, cosphi;
G4double costhetan, sinthetan, phin, sinphin, cosphin;
costheta = 2.*G4UniformRand()-1.0;
sintheta = sqrt((1.0-costheta)*(1.0+costheta));
phi = 2.0*M_PI*G4UniformRand()*rad;
sinphi = sin(phi);
cosphi = cos(phi);
G4ParticleMomentum direction0(sintheta*cosphi,sintheta*sinphi,costheta);
G4DynamicParticle * daughterparticle
= new G4DynamicParticle( daughters[0], direction0*daughtermomentum[0]);
products->PushProducts(daughterparticle);
costhetan = (daughtermomentum[1]*daughtermomentum[1]-daughtermomentum[2]*daughtermomentum[2]-daughtermomentum[0]*daughtermomentum[0])/(2.0*daughtermomentum[2]*daughtermomentum[0]);
sinthetan = sqrt((1.0-costhetan)*(1.0+costhetan));
phin = 2.0*M_PI*G4UniformRand()*rad;
sinphin = sin(phin);
cosphin = cos(phin);
G4ParticleMomentum direction2;
direction2.setX( sinthetan*cosphin*costheta*cosphi - sinthetan*sinphin*sinphi + costhetan*sintheta*cosphi);
direction2.setY( sinthetan*cosphin*costheta*sinphi + sinthetan*sinphin*cosphi + costhetan*sintheta*sinphi);
direction2.setZ( -sinthetan*cosphin*sintheta + costhetan*costheta);
daughterparticle = new G4DynamicParticle( daughters[2], direction2*(daughtermomentum[2]/direction2.mag()));
products->PushProducts(daughterparticle);
daughterparticle =
new G4DynamicParticle(
daughters[1],
(direction0*daughtermomentum[0] + direction2*(daughtermomentum[2]/direction2.mag()))*(-1.0)
);
products->PushProducts(daughterparticle);
if (GetVerboseLevel()>1) {
G4cout << "G4GeneralPhaseSpaceDecay::ThreeBodyDecayIt ";
G4cout << " create decay products in rest frame " <<G4endl;
products->DumpInfo();
}
return products;
}
G4DecayProducts *G4GeneralPhaseSpaceDecay::ManyBodyDecayIt()
// algorism of this code is originally written in FORTRAN by M.Asai
//*****************************************************************
// NBODY
// N-body phase space Monte-Carlo generator
// Makoto Asai
// Hiroshima Institute of Technology
// (asai@kekvax.kek.jp)
// Revised release : 19/Apr/1995
//
{
//return value
G4DecayProducts *products;
if (GetVerboseLevel()>1) G4cout << "G4GeneralPhaseSpaceDecay::ManyBodyDecayIt()"<<G4endl;
//daughters'mass
G4double *daughtermass = new G4double[numberOfDaughters];
G4double sumofdaughtermass = 0.0;
for (G4int index=0; index<numberOfDaughters; index++){
daughtermass[index] = daughters[index]->GetPDGMass();
sumofdaughtermass += daughtermass[index];
}
//Calculate daughter momentum
G4double *daughtermomentum = new G4double[numberOfDaughters];
G4ParticleMomentum direction;
G4DynamicParticle **daughterparticle;
G4double *sm = new G4double[numberOfDaughters];
G4double tmas;
G4double weight = 1.0;
G4int numberOfTry = 0;
G4int index1, index2;
do {
//Generate rundom number in descending order
G4double temp;
G4double *rd = new G4double[numberOfDaughters];
rd[0] = 1.0;
for(index1 =1; index1 < numberOfDaughters -1; index1++)
rd[index1] = G4UniformRand();
rd[ numberOfDaughters -1] = 0.0;
for(index1 =1; index1 < numberOfDaughters -1; index1++) {
for(index2 = index1+1; index2 < numberOfDaughters; index2++) {
if (rd[index1] < rd[index2]){
temp = rd[index1];
rd[index1] = rd[index2];
rd[index2] = temp;
}
}
}
//calcurate virtual mass
tmas = parentmass - sumofdaughtermass;
temp = sumofdaughtermass;
for(index1 =0; index1 < numberOfDaughters; index1++) {
sm[index1] = rd[index1]*tmas + temp;
temp -= daughtermass[index1];
if (GetVerboseLevel()>1) {
G4cout << index1 << " rundom number:" << rd[index1];
G4cout << " virtual mass:" << sm[index1]/GeV << "[GeV/c/c]" <<G4endl;
}
}
delete [] rd;
//Calculate daughter momentum
weight = 1.0;
index1 =numberOfDaughters-1;
daughtermomentum[index1]= Pmx( sm[index1-1],daughtermass[index1-1],sm[index1]);
if (GetVerboseLevel()>1) {
G4cout << " daughter " << index1 << ":" << *daughters_name[index1];
G4cout << " momentum:" << daughtermomentum[index1]/GeV << "[GeV/c]" <<G4endl;
}
for(index1 =numberOfDaughters-2; index1>=0; index1--) {
// calculate
daughtermomentum[index1]= Pmx( sm[index1],daughtermass[index1], sm[index1 +1]);
if(daughtermomentum[index1] < 0.0) {
// !!! illegal momentum !!!
if (GetVerboseLevel()>0) {
G4cout << "G4GeneralPhaseSpaceDecay::ManyBodyDecayIt ";
G4cout << " can not calculate daughter momentum " <<G4endl;
G4cout << " parent:" << *parent_name;
G4cout << " mass:" << parentmass/GeV << "[GeV/c/c]" <<G4endl;
G4cout << " daughter " << index1 << ":" << *daughters_name[index1];
G4cout << " mass:" << daughtermass[index1]/GeV << "[GeV/c/c]" ;
G4cout << " mass:" << daughtermomentum[index1]/GeV << "[GeV/c]" <<G4endl;
}
delete [] sm;
delete [] daughtermass;
delete [] daughtermomentum;
return NULL; // Error detection
} else {
// calculate weight of this events
weight *= daughtermomentum[index1]/sm[index1];
if (GetVerboseLevel()>1) {
G4cout << " daughter " << index1 << ":" << *daughters_name[index1];
G4cout << " momentum:" << daughtermomentum[index1]/GeV << "[GeV/c]" <<G4endl;
}
}
}
if (GetVerboseLevel()>1) {
G4cout << " weight: " << weight <<G4endl;
}
// exit if number of Try exceeds 100
if (numberOfTry++ >100) {
if (GetVerboseLevel()>0) {
G4cout << "G4GeneralPhaseSpaceDecay::ManyBodyDecayIt: ";
G4cout << " can not determine Decay Kinematics " << G4endl;
}
delete [] sm;
delete [] daughtermass;
delete [] daughtermomentum;
return NULL; // Error detection
}
} while ( weight > G4UniformRand());
if (GetVerboseLevel()>1) {
G4cout << "Start calulation of daughters momentum vector "<<G4endl;
}
G4double costheta, sintheta, phi;
G4double beta;
daughterparticle = new G4DynamicParticle*[numberOfDaughters];
index1 = numberOfDaughters -2;
costheta = 2.*G4UniformRand()-1.0;
sintheta = sqrt((1.0-costheta)*(1.0+costheta));
phi = 2.0*M_PI*G4UniformRand()*rad;
direction.setZ(costheta);
direction.setY(sintheta*sin(phi));
direction.setX(sintheta*cos(phi));
daughterparticle[index1] = new G4DynamicParticle( daughters[index1], direction*daughtermomentum[index1] );
daughterparticle[index1+1] = new G4DynamicParticle( daughters[index1+1], direction*(-1.0*daughtermomentum[index1]) );
for (index1 = numberOfDaughters -3; index1 >= 0; index1--) {
//calculate momentum direction
costheta = 2.*G4UniformRand()-1.0;
sintheta = sqrt((1.0-costheta)*(1.0+costheta));
phi = 2.0*M_PI*G4UniformRand()*rad;
direction.setZ(costheta);
direction.setY(sintheta*sin(phi));
direction.setX(sintheta*cos(phi));
// boost already created particles
beta = daughtermomentum[index1];
beta /= sqrt( daughtermomentum[index1]*daughtermomentum[index1] + sm[index1+1]*sm[index1+1] );
for (G4int index2 = index1+1; index2<numberOfDaughters; index2++) {
G4LorentzVector p4;
// make G4LorentzVector for secondaries
p4 = daughterparticle[index2]->Get4Momentum();
// boost secondaries to new frame
p4.boost( direction.x()*beta, direction.y()*beta, direction.z()*beta);
// change energy/momentum
daughterparticle[index2]->Set4Momentum(p4);
}
//create daughter G4DynamicParticle
daughterparticle[index1]= new G4DynamicParticle( daughters[index1], direction*(-1.0*daughtermomentum[index1]));
}
//create G4Decayproducts
G4DynamicParticle *parentparticle;
direction.setX(1.0); direction.setY(0.0); direction.setZ(0.0);
parentparticle = new G4DynamicParticle( parent, direction, 0.0);
products = new G4DecayProducts(*parentparticle);
delete parentparticle;
for (index1 = 0; index1<numberOfDaughters; index1++) {
products->PushProducts(daughterparticle[index1]);
}
if (GetVerboseLevel()>1) {
G4cout << "G4GeneralPhaseSpaceDecay::ManyBodyDecayIt ";
G4cout << " create decay products in rest frame " << G4endl;
products->DumpInfo();
}
delete [] daughterparticle;
delete [] daughtermomentum;
delete [] daughtermass;
delete [] sm;
return products;
}
@@ -0,0 +1,713 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
//
// -----------------------------------------------------------------------------
// GEANT 4 class implementation file
//
// History: first implementation, A. Feliciello, 20th May 1998
// -----------------------------------------------------------------------------
#include "globals.hh"
#include "G4ios.hh"
#include <math.h>
#include "Randomize.hh"
#include "G4SimpleIntegration.hh"
#include "G4ThreeVector.hh"
#include "G4LorentzVector.hh"
#include "G4KineticTrack.hh"
#include "G4KineticTrackVector.hh"
#include "G4ParticleDefinition.hh"
#include "G4DecayTable.hh"
#include "G4GeneralPhaseSpaceDecay.hh"
#include "G4DecayProducts.hh"
#include "G4LorentzRotation.hh"
#include "G4SampleResonance.hh"
#include "G4Integrator.hh"
#include "G4KaonZero.hh"
#include "G4KaonZeroShort.hh"
#include "G4KaonZeroLong.hh"
#include "G4AntiKaonZero.hh"
#include "G4HadTmpUtil.hh"
//
// Some static clobal for integration
//
static G4double G4KineticTrack_Gmass, G4KineticTrack_xmass1;
//
// Default constructor
//
G4KineticTrack::G4KineticTrack() :
theDefinition(0),
theFormationTime(0),
thePosition(0),
the4Momentum(0),
theFermi3Momentum(0),
theTotal4Momentum(0),
theNucleon(0),
nChannels(0),
theActualMass(0),
theActualWidth(0),
theDaughterMass(0),
theDaughterWidth(0),
theStateToNucleus(undefined),
theProjectilePotential(0)
{
////////////////
// DEBUG //
////////////////
/*
G4cerr << G4endl << G4endl << G4endl;
G4cerr << " G4KineticTrack default constructor invoked! \n";
G4cerr << " =========================================== \n" << G4endl;
*/
}
//
// Copy constructor
//
G4KineticTrack::G4KineticTrack(const G4KineticTrack &right) : G4VKineticNucleon()
{
G4int i;
theDefinition = right.GetDefinition();
theFormationTime = right.GetFormationTime();
thePosition = right.GetPosition();
the4Momentum = right.GetTrackingMomentum();
theFermi3Momentum = right.theFermi3Momentum;
theTotal4Momentum = right.theTotal4Momentum;
theNucleon=right.theNucleon;
nChannels = right.GetnChannels();
theActualMass = right.GetActualMass();
theActualWidth = new G4double[nChannels];
for (i = 0; i < nChannels; i++)
{
theActualWidth[i] = right.theActualWidth[i];
}
theDaughterMass = 0;
theDaughterWidth = 0;
theStateToNucleus=right.theStateToNucleus;
theProjectilePotential=right.theProjectilePotential;
////////////////
// DEBUG //
////////////////
/*
G4cerr << G4endl << G4endl << G4endl;
G4cerr << " G4KineticTrack copy constructor invoked! \n";
G4cerr << " ======================================== \n" <<G4endl;
*/
}
//
// By argument constructor
//
G4KineticTrack::G4KineticTrack(G4ParticleDefinition* aDefinition,
G4double aFormationTime,
G4ThreeVector aPosition,
G4LorentzVector& a4Momentum) :
theDefinition(aDefinition),
theFormationTime(aFormationTime),
thePosition(aPosition),
the4Momentum(a4Momentum),
theFermi3Momentum(0),
theTotal4Momentum(a4Momentum),
theNucleon(0),
theStateToNucleus(undefined),
theProjectilePotential(0)
{
if(G4KaonZero::KaonZero() == theDefinition ||
G4AntiKaonZero::AntiKaonZero() == theDefinition)
{
if(G4UniformRand()<0.5)
{
theDefinition = G4KaonZeroShort::KaonZeroShort();
}
else
{
theDefinition = G4KaonZeroLong::KaonZeroLong();
}
}
//
// Get the number of decay channels
//
G4DecayTable* theDecayTable = theDefinition->GetDecayTable();
if (theDecayTable != 0)
{
nChannels = theDecayTable->entries();
}
else
{
nChannels = 0;
}
//
// Get the actual mass value
//
theActualMass = GetActualMass();
//
// Create an array to Store the actual partial widths
// of the decay channels
//
theDaughterMass = 0;
theDaughterWidth = 0;
theActualWidth = 0;
G4bool * theDaughterIsShortLived = 0;
if(nChannels!=0) theActualWidth = new G4double[nChannels];
// cout << " ****CONSTR*** ActualMass ******* " << theActualMass << G4endl;
G4int index;
for (index = nChannels - 1; index >= 0; index--)
{
G4VDecayChannel* theChannel = theDecayTable->GetDecayChannel(index);
G4int nDaughters = theChannel->GetNumberOfDaughters();
G4double theMotherWidth;
if (nDaughters == 2 || nDaughters == 3)
{
G4double thePoleMass = theDefinition->GetPDGMass();
theMotherWidth = theDefinition->GetPDGWidth();
G4double thePoleWidth = theChannel->GetBR()*theMotherWidth;
G4ParticleDefinition* aDaughter;
theDaughterMass = new G4double[nDaughters];
theDaughterWidth = new G4double[nDaughters];
theDaughterIsShortLived = new G4bool[nDaughters];
G4int n;
for (n = 0; n < nDaughters; n++)
{
aDaughter = theChannel->GetDaughter(n);
theDaughterMass[n] = aDaughter->GetPDGMass();
theDaughterWidth[n] = aDaughter->GetPDGWidth();
theDaughterIsShortLived[n] = aDaughter->IsShortLived();
}
//
// Check whether both the decay products are stable
//
G4double theActualMom = 0.0;
G4double thePoleMom = 0.0;
G4SampleResonance aSampler;
if (nDaughters==2)
{
if ( !theDaughterIsShortLived[0] && !theDaughterIsShortLived[1] )
{
// G4cout << G4endl << "Both the " << nDaughters <<
// " decay products are stable!";
// cout << " LB: Both decay products STABLE !" << G4endl;
// cout << " parent: " << theChannel->GetParentName() << G4endl;
// cout << " particle1: " << theChannel->GetDaughterName(0) << G4endl;
// cout << " particle2: " << theChannel->GetDaughterName(1) << G4endl;
theActualMom = EvaluateCMMomentum(theActualMass,
theDaughterMass);
thePoleMom = EvaluateCMMomentum(thePoleMass,
theDaughterMass);
// cout << G4endl;
// cout << " LB: ActualMass/DaughterMass " << theActualMass << " " << theDaughterMass << G4endl;
// cout << " LB: ActualMom " << theActualMom << G4endl;
// cout << " LB: PoleMom " << thePoleMom << G4endl;
// cout << G4endl;
}
else if ( !theDaughterIsShortLived[0] && theDaughterIsShortLived[1] )
{
// G4cout << G4endl << "Only the first of the " << nDaughters <<" decay products is stable!";
// cout << " LB: only the first decay product is STABLE !" << G4endl;
// cout << " parent: " << theChannel->GetParentName() << G4endl;
// cout << " particle1: " << theChannel->GetDaughterName(0) << G4endl;
// cout << " particle2: " << theChannel->GetDaughterName(1) << G4endl;
// global variable definition
G4double lowerLimit = aSampler.GetMinimumMass(theChannel->GetDaughter(1));
theActualMom = IntegrateCMMomentum(lowerLimit);
thePoleMom = IntegrateCMMomentum(lowerLimit, thePoleMass);
// cout << " LB Parent Mass = " << G4KineticTrack_Gmass << G4endl;
// cout << " LB Actual Mass = " << theActualMass << G4endl;
// cout << " LB Daughter1 Mass = " << G4KineticTrack_Gmass1 << G4endl;
// cout << " LB Daughter2 Mass = " << G4KineticTrack_Gmass2 << G4endl;
// cout << " The Actual Momentum = " << theActualMom << G4endl;
// cout << " The Pole Momentum = " << thePoleMom << G4endl;
// cout << G4endl;
}
else if ( theDaughterIsShortLived[0] && !theDaughterIsShortLived[1] )
{
// G4cout << G4endl << "Only the second of the " << nDaughters <<
// " decay products is stable!";
// cout << " LB: only the second decay product is STABLE !" << G4endl;
// cout << " parent: " << theChannel->GetParentName() << G4endl;
// cout << " particle1: " << theChannel->GetDaughterName(0) << G4endl;
// cout << " particle2: " << theChannel->GetDaughterName(1) << G4endl;
//
// Swap the content of the theDaughterMass and theDaughterWidth arrays!!!
//
G4SwapObj(theDaughterMass, theDaughterMass + 1);
G4SwapObj(theDaughterWidth, theDaughterWidth + 1);
// global variable definition
G4double lowerLimit = aSampler.GetMinimumMass(theChannel->GetDaughter(0));
theActualMom = IntegrateCMMomentum(lowerLimit);
thePoleMom = IntegrateCMMomentum(lowerLimit, thePoleMass);
// cout << " LB Parent Mass = " << G4KineticTrack_Gmass << G4endl;
// cout << " LB Actual Mass = " << theActualMass << G4endl;
// cout << " LB Daughter1 Mass = " << G4KineticTrack_Gmass1 << G4endl;
// cout << " LB Daughter2 Mass = " << G4KineticTrack_Gmass2 << G4endl;
// cout << " The Actual Momentum = " << theActualMom << G4endl;
// cout << " The Pole Momentum = " << thePoleMom << G4endl;
// cout << G4endl;
}
else if ( theDaughterIsShortLived[0] && theDaughterIsShortLived[1] )
{
// G4cout << G4endl << "Both the " << nDaughters <<
// " decay products are resonances!";
// cout << " LB: both decay products are RESONANCES !" << G4endl;
// cout << " parent: " << theChannel->GetParentName() << G4endl;
// cout << " particle1: " << theChannel->GetDaughterName(0) << G4endl;
// cout << " particle2: " << theChannel->GetDaughterName(1) << G4endl;
// global variable definition
G4KineticTrack_Gmass = theActualMass;
theActualMom = IntegrateCMMomentum2();
G4KineticTrack_Gmass = thePoleMass;
thePoleMom = IntegrateCMMomentum2();
// cout << " LB Parent Mass = " << G4KineticTrack_Gmass << G4endl;
// cout << " LB Daughter1 Mass = " << G4KineticTrack_Gmass1 << G4endl;
// cout << " LB Daughter2 Mass = " << G4KineticTrack_Gmass2 << G4endl;
// cout << " The Actual Momentum = " << theActualMom << G4endl;
// cout << " The Pole Momentum = " << thePoleMom << G4endl;
// cout << G4endl;
}
}
else // (nDaughter==3)
{
int nShortLived = 0;
if ( theDaughterIsShortLived[0] )
{
nShortLived++;
}
if ( theDaughterIsShortLived[1] )
{
nShortLived++;
G4SwapObj(theDaughterMass, theDaughterMass + 1);
G4SwapObj(theDaughterWidth, theDaughterWidth + 1);
}
if ( theDaughterIsShortLived[2] )
{
nShortLived++;
G4SwapObj(theDaughterMass, theDaughterMass + 2);
G4SwapObj(theDaughterWidth, theDaughterWidth + 2);
}
if ( nShortLived == 0 )
{
theDaughterMass[1]+=theDaughterMass[2];
theActualMom = EvaluateCMMomentum(theActualMass,
theDaughterMass);
thePoleMom = EvaluateCMMomentum(thePoleMass,
theDaughterMass);
}
// else if ( nShortLived == 1 )
else if ( nShortLived >= 1 )
{
// need the shortlived particle in slot 1! (very bad style...)
G4SwapObj(theDaughterMass, theDaughterMass + 1);
G4SwapObj(theDaughterWidth, theDaughterWidth + 1);
theDaughterMass[0] += theDaughterMass[2];
theActualMom = IntegrateCMMomentum(0.0);
thePoleMom = IntegrateCMMomentum(0.0, thePoleMass);
}
// else
// {
// throw G4HadronicException(__FILE__, __LINE__, ("can't handle more than one shortlived in 3 particle output channel");
// }
}
G4double l=0;
//if(nDaughters<3) theChannel->GetAngularMomentum();
G4double theMassRatio = thePoleMass / theActualMass;
G4double theMomRatio = theActualMom / thePoleMom;
theActualWidth[index] = thePoleWidth * theMassRatio *
pow(theMomRatio, (2 * l + 1)) *
(1.2 / (1+ 0.2*pow(theMomRatio, (2 * l))));
delete [] theDaughterMass;
theDaughterMass = 0;
delete [] theDaughterWidth;
theDaughterWidth = 0;
delete [] theDaughterIsShortLived;
theDaughterIsShortLived = 0;
}
else // nDaughter = 1 ( e.g. K0 decays 50% to Kshort, 50% Klong
{
theMotherWidth = theDefinition->GetPDGWidth();
theActualWidth[index] = theChannel->GetBR()*theMotherWidth;
}
}
////////////////
// DEBUG //
////////////////
// for (G4int y = nChannels - 1; y >= 0; y--)
// {
// G4cout << G4endl << theActualWidth[y];
// }
// G4cout << G4endl << G4endl << G4endl;
/*
G4cerr << G4endl << G4endl << G4endl;
G4cerr << " G4KineticTrack by argument constructor invoked! \n";
G4cerr << " =============================================== \n" << G4endl;
*/
}
G4KineticTrack::G4KineticTrack(G4Nucleon * nucleon,
G4ThreeVector aPosition,
G4LorentzVector& a4Momentum)
: theDefinition(nucleon->GetDefinition()),
theFormationTime(0),
thePosition(aPosition),
the4Momentum(a4Momentum),
theFermi3Momentum(nucleon->GetMomentum()),
theNucleon(nucleon),
nChannels(0),
theActualMass(nucleon->GetDefinition()->GetPDGMass()),
theActualWidth(0),
theDaughterMass(0),
theDaughterWidth(0),
theStateToNucleus(undefined),
theProjectilePotential(0)
{
theFermi3Momentum.setE(0);
Set4Momentum(a4Momentum);
}
G4KineticTrack::~G4KineticTrack()
{
if (theActualWidth != 0) delete [] theActualWidth;
if (theDaughterMass != 0) delete [] theDaughterMass;
if (theDaughterWidth != 0) delete [] theDaughterWidth;
}
const G4KineticTrack& G4KineticTrack::operator=(const G4KineticTrack& right)
{
G4int i;
if (this != &right)
{
theDefinition = right.GetDefinition();
theFormationTime = right.GetFormationTime();
// thePosition = right.GetPosition();
the4Momentum = right.the4Momentum;
the4Momentum = right.GetTrackingMomentum();
theFermi3Momentum = right.theFermi3Momentum;
theTotal4Momentum = right.theTotal4Momentum;
theNucleon=right.theNucleon;
theStateToNucleus=right.theStateToNucleus;
if (theActualWidth != 0) delete [] theActualWidth;
nChannels = right.GetnChannels();
theActualWidth = new G4double[nChannels];
for (i = 0; i < nChannels; i++)
{
theActualWidth[i] = right.theActualWidth[i];
}
}
return *this;
}
G4int G4KineticTrack::operator==(const G4KineticTrack& right) const
{
return (this == & right);
}
G4int G4KineticTrack::operator!=(const G4KineticTrack& right) const
{
return (this != & right);
}
G4KineticTrackVector* G4KineticTrack::Decay()
{
//
// Select a possible decay channel
//
// G4int index1;
// for (index1 = nChannels - 1; index1 >= 0; index1--)
// cout << "DECAY Actual Width IND/ActualW " << index1 << " " << theActualWidth[index1] << G4endl;
// cout << "DECAY Actual Mass " << theActualMass << G4endl;
G4int chargeBalance = G4lrint(theDefinition->GetPDGCharge() );
G4int baryonBalance = G4lrint(theDefinition->GetBaryonNumber() );
G4double theTotalActualWidth = this->EvaluateTotalActualWidth();
if (theTotalActualWidth !=0)
{
G4int index;
G4double theSumActualWidth = 0.0;
G4double* theCumActualWidth = new G4double[nChannels];
for (index = nChannels - 1; index >= 0; index--)
{
theSumActualWidth += theActualWidth[index];
theCumActualWidth[index] = theSumActualWidth;
// cout << "DECAY Cum. Width " << index << " " << theCumActualWidth[index] << G4endl;
}
// cout << "DECAY Total Width " << theSumActualWidth << G4endl;
// cout << "DECAY Total Width " << theTotalActualWidth << G4endl;
G4double r = theTotalActualWidth * G4UniformRand();
G4ParticleDefinition* theDefinition = this->GetDefinition();
G4DecayTable* theDecayTable = theDefinition->GetDecayTable();
G4VDecayChannel* theDecayChannel=NULL;
for (index = nChannels - 1; index >= 0; index--)
{
if (r < theCumActualWidth[index])
{
theDecayChannel = theDecayTable->GetDecayChannel(index);
// cout << "DECAY SELECTED CHANNEL" << index << G4endl;
chosench=index;
break;
}
}
G4String theParentName = theDecayChannel->GetParentName();
G4double theParentMass = this->GetActualMass();
G4double theBR = theActualWidth[index];
// cout << "**BR*** DECAYNEW " << theBR << G4endl;
// cout << "**PMass*** DECAYNEW " << theParentMass << G4endl;
G4int theNumberOfDaughters = theDecayChannel->GetNumberOfDaughters();
G4String theDaughtersName1 = "";
G4String theDaughtersName2 = "";
G4String theDaughtersName3 = "";
switch (theNumberOfDaughters)
{
case 0:
break;
case 1:
theDaughtersName1 = theDecayChannel->GetDaughterName(0);
theDaughtersName2 = "";
theDaughtersName3 = "";
break;
case 2:
theDaughtersName1 = theDecayChannel->GetDaughterName(0);
theDaughtersName2 = theDecayChannel->GetDaughterName(1);
theDaughtersName3 = "";
break;
default:
theDaughtersName1 = theDecayChannel->GetDaughterName(0);
theDaughtersName2 = theDecayChannel->GetDaughterName(1);
theDaughtersName3 = theDecayChannel->GetDaughterName(2);
break;
}
//
// Get the decay products List
//
G4GeneralPhaseSpaceDecay thePhaseSpaceDecayChannel(theParentName,
theParentMass,
theBR,
theNumberOfDaughters,
theDaughtersName1,
theDaughtersName2,
theDaughtersName3);
G4DecayProducts* theDecayProducts = thePhaseSpaceDecayChannel.DecayIt();
//
// Create the kinetic track List associated to the decay products
//
G4LorentzRotation toMoving(Get4Momentum().boostVector());
G4DynamicParticle* theDynamicParticle;
G4double theFormationTime = 0.0;
G4ThreeVector thePosition = this->GetPosition();
G4LorentzVector momentum;
G4KineticTrackVector* theDecayProductList = new G4KineticTrackVector;
G4int dEntries = theDecayProducts->entries();
G4ParticleDefinition * aProduct = 0;
for (G4int i=dEntries; i > 0; i--)
{
theDynamicParticle = theDecayProducts->PopProducts();
aProduct = theDynamicParticle->GetDefinition();
chargeBalance -= G4lrint(aProduct->GetPDGCharge() );
baryonBalance -= G4lrint(aProduct->GetBaryonNumber() );
momentum = toMoving*theDynamicParticle->Get4Momentum();
theDecayProductList->push_back(new G4KineticTrack (aProduct,
theFormationTime,
thePosition,
momentum));
delete theDynamicParticle;
}
delete theDecayProducts;
delete [] theCumActualWidth;
if(getenv("DecayEnergyBalanceCheck"))
std::cout << "DEBUGGING energy balance D: "
<<chargeBalance<<" "
<<baryonBalance<<" "
<<G4endl;
return theDecayProductList;
}
else
{
return 0;
}
}
G4double G4KineticTrack::IntegrandFunction1(G4double xmass) const
{
G4double mass = theActualMass; /* the actual mass value */
G4double mass1 = theDaughterMass[0];
G4double mass2 = theDaughterMass[1];
G4double gamma2 = theDaughterWidth[1];
G4double result = (1. / (2 * mass)) *
sqrt(std::max((((mass * mass) - (mass1 + xmass) * (mass1 + xmass)) *
((mass * mass) - (mass1 - xmass) * (mass1 - xmass))),0.0)) *
BrWig(gamma2, mass2, xmass);
return result;
}
G4double G4KineticTrack::IntegrandFunction2(G4double xmass) const
{
G4double mass = theDefinition->GetPDGMass(); /* the pole mass value */
G4double mass1 = theDaughterMass[0];
G4double mass2 = theDaughterMass[1];
G4double gamma2 = theDaughterWidth[1];
G4double result = (1. / (2 * mass)) *
sqrt(std::max((((mass * mass) - (mass1 + xmass) * (mass1 + xmass)) *
((mass * mass) - (mass1 - xmass) * (mass1 - xmass))),0.0)) *
BrWig(gamma2, mass2, xmass);
return result;
}
G4double G4KineticTrack::IntegrandFunction3(G4double xmass) const
{
const G4double mass = G4KineticTrack_Gmass; /* the actual mass value */
// const G4double mass1 = theDaughterMass[0];
const G4double mass2 = theDaughterMass[1];
const G4double gamma2 = theDaughterWidth[1];
const G4double result = (1. / (2 * mass)) *
sqrt(((mass * mass) - (G4KineticTrack_xmass1 + xmass) * (G4KineticTrack_xmass1 + xmass)) *
((mass * mass) - (G4KineticTrack_xmass1 - xmass) * (G4KineticTrack_xmass1 - xmass))) *
BrWig(gamma2, mass2, xmass);
return result;
}
G4double G4KineticTrack::IntegrandFunction4(G4double xmass) const
{
const G4double mass = G4KineticTrack_Gmass;
const G4double mass1 = theDaughterMass[0];
const G4double gamma1 = theDaughterWidth[0];
// const G4double mass2 = theDaughterMass[1];
G4KineticTrack_xmass1 = xmass;
const G4double theLowerLimit = 0.0;
const G4double theUpperLimit = mass - xmass;
const G4int nIterations = 100;
G4Integrator<const G4KineticTrack, G4double(G4KineticTrack::*)(G4double) const> integral;
G4double result = BrWig(gamma1, mass1, xmass)*
integral.Simpson(this, &G4KineticTrack::IntegrandFunction3, theLowerLimit, theUpperLimit, nIterations);
return result;
}
G4double G4KineticTrack::IntegrateCMMomentum(const G4double theLowerLimit) const
{
const G4double theUpperLimit = theActualMass - theDaughterMass[0];
const G4int nIterations = 100;
if (theLowerLimit>=theUpperLimit) return 0.0;
G4Integrator<const G4KineticTrack, G4double(G4KineticTrack::*)(G4double) const> integral;
G4double theIntegralOverMass2 = integral.Simpson(this, &G4KineticTrack::IntegrandFunction1,
theLowerLimit, theUpperLimit, nIterations);
return theIntegralOverMass2;
}
G4double G4KineticTrack::IntegrateCMMomentum(const G4double theLowerLimit, const G4double poleMass) const
{
const G4double theUpperLimit = poleMass - theDaughterMass[0];
const G4int nIterations = 100;
if (theLowerLimit>=theUpperLimit) return 0.0;
G4Integrator<const G4KineticTrack, G4double(G4KineticTrack::*)(G4double) const> integral;
const G4double theIntegralOverMass2 = integral.Simpson(this, &G4KineticTrack::IntegrandFunction2,
theLowerLimit, theUpperLimit, nIterations);
return theIntegralOverMass2;
}
G4double G4KineticTrack::IntegrateCMMomentum2() const
{
const G4double theLowerLimit = 0.0;
const G4double theUpperLimit = theActualMass;
const G4int nIterations = 100;
if (theLowerLimit>=theUpperLimit) return 0.0;
G4Integrator<const G4KineticTrack, G4double(G4KineticTrack::*)(G4double) const> integral;
G4double theIntegralOverMass2 = integral.Simpson(this, &G4KineticTrack::IntegrandFunction4,
theLowerLimit, theUpperLimit, nIterations);
return theIntegralOverMass2;
}
@@ -0,0 +1,70 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
#include "G4KineticTrackVector.hh"
G4KineticTrackVector::G4KineticTrackVector()
{
}
//****************************************************************************************************************
// These methods were implemented by Maxim Komogorov
// Maxim.Komogorov@cern.ch
void G4KineticTrackVector::BoostBeam(G4ThreeVector& BeamMom)
{
for(unsigned int c1 = 0; c1 < size(); c1++)
{
G4KineticTrack& KT =**(begin()+c1);
G4LorentzVector Mom = KT.Get4Momentum();
G4ThreeVector Velocity = (1/sqrt(BeamMom.mag2() + sqr(KT.GetDefinition()->GetPDGMass())))*BeamMom;
Mom.boost(Velocity);
KT.Set4Momentum(Mom);
}
}
//--------------------------------------------------------------------------------------------------------------
void G4KineticTrackVector::Boost(G4ThreeVector& Velocity)
{
for(unsigned int c1 = 0; c1 < size(); c1++)
{
G4KineticTrack& KT =**(begin()+c1);
G4LorentzVector Mom = KT.Get4Momentum();
Mom.boost(Velocity);
KT.Set4Momentum(Mom);
}
}
//--------------------------------------------------------------------------------------------------------------
void G4KineticTrackVector::Shift(G4ThreeVector& Pos)
{
for(unsigned int c1 = 0; c1 < size(); c1++)
{
G4KineticTrack& KT =**(begin()+c1);
KT.SetPosition(KT.GetPosition() + Pos);
}
}
//****************************************************************************************************************
@@ -0,0 +1,41 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
//
//
#include "G4NuclearFermiDensity.hh"
G4NuclearFermiDensity::G4NuclearFermiDensity(G4double anA, G4double aZ)
: a(0.545 * fermi)
{
// const G4double r0=1.14*fermi;
const G4double r0=1.16 * ( 1. - 1.16 * pow(anA, -2./3.)) * fermi;
theA = G4int(anA);
theZ = G4int(aZ);
theR= r0 * pow(anA, 1./3. );
Setrho0(3./ (4. * pi * pow(r0,3.) * theA * ( 1. + sqr(a/theR)*pi2 )));
}
G4NuclearFermiDensity::~G4NuclearFermiDensity() {}
@@ -0,0 +1,54 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
//
//
#include "G4NuclearShellModelDensity.hh"
G4NuclearShellModelDensity::G4NuclearShellModelDensity(G4double anA, G4double aZ)
{
const G4double r0sq=0.8133*fermi*fermi;
theA = G4int(anA);
theZ = G4int(aZ);
theRsquare= r0sq * pow(G4double(theA), 2./3. );
Setrho0(pow(1./(pi*theRsquare),3./2.));
}
G4NuclearShellModelDensity::~G4NuclearShellModelDensity() {}
G4double G4NuclearShellModelDensity::GetRelativeDensity(const G4ThreeVector & aPosition) const
{
return exp(-1*aPosition.mag2()/theRsquare);
}
G4double G4NuclearShellModelDensity::GetRadius(const G4double maxRelativeDensity) const
{
return (maxRelativeDensity>0 && maxRelativeDensity <= 1 ) ?
sqrt(theRsquare * log(1/maxRelativeDensity) ) : DBL_MAX;
}
G4double G4NuclearShellModelDensity::GetDeriv(const G4ThreeVector & aPosition) const
{
return -2* aPosition.mag() / theRsquare * GetDensity(aPosition);
}
@@ -0,0 +1,63 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
//
//
#include "G4Nucleon.hh"
// ------------------------------------------------------------
// GEANT 4 class implementation file
//
// ---------------- G4Nucleon ----------------
// by Gunter Folger, May 1998.
// class for a nucleon (inside a 3D Nucleus)
// ------------------------------------------------------------
G4Nucleon::G4Nucleon()
: theBindingE(0.) , theParticleType(NULL), theSplitableHadron(NULL)
{}
G4Nucleon::~G4Nucleon()
{
}
void G4Nucleon::Boost(const G4LorentzVector & aMomentum)
{
// see e.g. CERNLIB short writeup U101 for the algorithm
G4double mass=aMomentum.mag();
G4double factor=
( theMomentum.vect()*aMomentum.vect()/(aMomentum.e()+mass) - theMomentum.e() ) / mass;
theMomentum.setE(1/mass*theMomentum.dot(aMomentum));
theMomentum.setVect(factor*aMomentum.vect() + theMomentum.vect());
}
#include <iostream>
std::ostream & operator << (std::ostream &s, const G4Nucleon& nucleon)
{
// s<< nucleon.GetDefinition()->GetParticleName()
// << " is " << nucleon.AreYouHit() ? " " : "not"
// << " hit. Momentum/position:" << G4endl;
s<< " momentum : " << nucleon.Get4Momentum() << G4endl;
s<< " position : " << nucleon.GetPosition() ;
return s;
}
@@ -0,0 +1,145 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
//
//
// ------------------------------------------------------------
// GEANT 4 class implementation file
//
// ---------------- G4Parton ----------------
// by Gunter Folger, June 1998.
// class for Parton (inside a string) used by Parton String Models
// ------------------------------------------------------------
#include "G4Parton.hh"
#include "G4HadronicException.hh"
G4Parton::G4Parton(G4int PDGcode)
{
PDGencoding=PDGcode;
theX = 0;
theDefinition=G4ParticleTable::GetParticleTable()->FindParticle(PDGencoding);
if (theDefinition == NULL)
{
G4cout << "Encoding = "<<PDGencoding<<G4endl;
G4String text = "G4Parton::GetDefinition(): Encoding not in particle table";
throw G4HadronicException(__FILE__, __LINE__, text);
}
//
// colour by random in (1,2,3)=(R,G,B) for quarks and
// in (-1,-2,-3)=(Rbar,Gbar,Bbar) for anti-quarks:
//
if (theDefinition->GetParticleType() == "quarks") {
theColour = ((G4int)(3.*G4UniformRand())+1)*(abs(PDGencoding)/PDGencoding) ;
}
//
// colour by random in (-1,-2,-3)=(Rbar,Gbar,Bbar)=(GB,RB,RG) for di-quarks and
// in (1,2,3)=(R,G,B)=(GB,RB,RG) for anti-di-quarks:
//
else if (theDefinition->GetParticleType() == "diquarks") {
theColour = -((G4int)(3.*G4UniformRand())+1)*(abs(PDGencoding)/PDGencoding);
}
//
// colour by random in (-11,-12,...,-33)=(RRbar,RGbar,RBbar,...,BBbar) for gluons:
//
else if (theDefinition->GetParticleType() == "gluons") {
theColour = -(((G4int)(3.*G4UniformRand())+1)*10 + ((G4int)(3.*G4UniformRand())+1));
}
else {
G4cout << "Encoding = "<<PDGencoding<<G4endl;
G4String text = "G4Parton::GetDefinition(): Particle is not a parton";
throw G4HadronicException(__FILE__, __LINE__, text);
}
//
// isospin-z from PDG-encoded isospin-z for
// quarks, anti-quarks, di-quarks, and anti-di-quarks:
//
if ((theDefinition->GetParticleType() == "quarks") || (theDefinition->GetParticleType() == "diquarks")){
theIsoSpinZ = theDefinition->GetPDGIsospin3();
}
//
// isospin-z choosen at random from PDG-encoded isospin for gluons (should be zero):
//
else {
G4int thisPDGiIsospin=theDefinition->GetPDGiIsospin();
if (thisPDGiIsospin == 0) {
theIsoSpinZ = 0;
}
else {
theIsoSpinZ = ((G4int)((thisPDGiIsospin+1)*G4UniformRand()))-thisPDGiIsospin*0.5;
}
}
//
// spin-z choosen at random from PDG-encoded spin:
//
G4int thisPDGiSpin=theDefinition->GetPDGiSpin();
if (thisPDGiSpin == 0) {
theSpinZ = 0;
}
else {
G4int rand=((G4int)((thisPDGiSpin+1)*G4UniformRand()));
theSpinZ = rand-thisPDGiSpin*0.5;;
}
}
G4Parton::G4Parton(const G4Parton &right)
{
PDGencoding = right.PDGencoding;
theMomentum = right.theMomentum;
thePosition = right.thePosition;
theX = right.theX;
theDefinition = right.theDefinition;
theColour = right.theColour;
theIsoSpinZ = right.theIsoSpinZ;
theSpinZ = right.theSpinZ;
}
const G4Parton & G4Parton::operator=(const G4Parton &right)
{
PDGencoding=right.GetPDGcode();
theMomentum=right.Get4Momentum();
thePosition=right.GetPosition();
theX = right.theX;
theDefinition = right.theDefinition;
theColour = right.theColour;
theIsoSpinZ = right.theIsoSpinZ;
theSpinZ = right.theSpinZ;
return *this;
}
G4Parton::~G4Parton()
{
// cout << "G4Parton::~G4Parton(): this = "<<this <<endl;
// cout << "break here"<<this <<endl;
}
void G4Parton::DefineMomentumInZ(G4double aLightConeMomentum, G4bool aDirection)
{
G4double Mass = GetMass();
G4LorentzVector a4Momentum = Get4Momentum();
aLightConeMomentum*=theX;
G4double TransverseMass2 = sqr(a4Momentum.px()) + sqr(a4Momentum.py()) + sqr(Mass);
a4Momentum.setPz(0.5*(aLightConeMomentum - TransverseMass2/aLightConeMomentum)*(aDirection? 1: -1));
a4Momentum.setE( 0.5*(aLightConeMomentum + TransverseMass2/aLightConeMomentum));
Set4Momentum(a4Momentum);
}
@@ -0,0 +1,139 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
//
//
// ------------------------------------------------------------
// GEANT 4 class header file
//
// ---------------- G4SampleResonance ----------------
// by Henning Weber, March 2001.
// helper class for sampling resonance masses
// ------------------------------------------------------------
#include "globals.hh"
#include <iostream>
#include "G4SampleResonance.hh"
#include "G4DecayTable.hh"
#include "Randomize.hh"
#include "G4HadronicException.hh"
G4SampleResonance::minMassMapType G4SampleResonance::minMassCache;
G4double G4SampleResonance::GetMinimumMass(const G4ParticleDefinition* p) const
{
G4double minResonanceMass = DBL_MAX;
if ( p->IsShortLived() )
{
minMassMapIterator i = minMassCache.find(p);
if ( i!=minMassCache.end() )
{
minResonanceMass = (*i).second;
}
else
{
// G4cout << "--> request for " << p->GetParticleName() << G4endl;
const G4DecayTable* theDecays = const_cast<G4ParticleDefinition*>(p)->GetDecayTable();
const G4int nDecays = theDecays->entries();
for (G4int i=0; i<nDecays; i++)
{
const G4VDecayChannel* aDecay = theDecays->GetDecayChannel(i);
const G4int nDaughters = aDecay->GetNumberOfDaughters();
G4double minChannelMass = 0;
for (G4int j=0; j<nDaughters; j++)
{
const G4ParticleDefinition* aDaughter = const_cast<G4VDecayChannel*>(aDecay)->GetDaughter(j);
G4double minMass = GetMinimumMass(aDaughter);
if (!minMass) minMass = DBL_MAX; // exclude gamma channel;
minChannelMass+=minMass;
}
// G4cout << "channel mass for the above is " << minChannelMass/MeV << G4endl;
if (minChannelMass < minResonanceMass) minResonanceMass = minChannelMass;
}
// replace this as soon as the compiler supports mutable!!
G4SampleResonance* self = const_cast<G4SampleResonance*>(this);
(self->minMassCache)[p] = minResonanceMass;
}
}
else
{
minResonanceMass = p->GetPDGMass();
}
// G4cout << "minimal mass for " << p->GetParticleName() << " is " << minResonanceMass/MeV << G4endl;
return minResonanceMass;
}
G4double G4SampleResonance::SampleMass(const G4ParticleDefinition* p, const G4double maxMass) const
{
return SampleMass(p->GetPDGMass(), p->GetPDGWidth(), GetMinimumMass(p), maxMass);
}
G4double G4SampleResonance::SampleMass(const G4double poleMass,
const G4double gamma,
const G4double minMass,
const G4double maxMass) const
{
// Chooses a mass randomly between minMass and maxMass
// according to a Breit-Wigner function with constant
// width gamma and pole poleMass
if ( minMass > maxMass )
{
throw G4HadronicException(__FILE__, __LINE__,
"SampleResonanceMass: mass range negative (minMass>maxMass)");
}
G4double returnMass;
if ( gamma < DBL_EPSILON )
{
returnMass = std::max(minMass, std::min(maxMass, poleMass));
}
else
{
double fmin = BrWigInt0(minMass, gamma, poleMass);
double fmax = BrWigInt0(maxMass, gamma, poleMass);
double f = fmin + (fmax-fmin)*G4UniformRand();
returnMass = BrWigInv(f, gamma, poleMass);
}
return returnMass;
}