Files
geant4/source/processes/hadronic/stopping/src/G4MuMinusCaptureCascade.cc
T
2016-06-08 15:42:07 +02:00

277 lines
7.8 KiB
C++

// 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 --- Copyright CERN 1998
// CERN Geneva Switzerland
//
// For information related to this code contact:
// CERN, CN Division, ASD group
// History: first implementation, based on object model of
// 2nd December 1995, G.Cosmo
// ------------ G4MuonMinusCaptureAtRest physics process --------
// by Vladimir Ivanchenko
// E-mail: Vladimir.Ivantchenko@cern.ch
// April 2000
// **************************************************************
//-----------------------------------------------------------------------------
#include "G4MuMinusCaptureCascade.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
// constructor
G4MuMinusCaptureCascade::G4MuMinusCaptureCascade()
{
theElectron = G4Electron::Electron();
theGamma = G4Gamma::Gamma();
Emass = theElectron->GetPDGMass();
MuMass = G4MuonMinus::MuonMinus()->GetPDGMass();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
// destructor
G4MuMinusCaptureCascade::~G4MuMinusCaptureCascade()
{ }
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4MuMinusCaptureCascade::GetKShellEnergy(G4double Z)
{
// Calculate the Energy of K Mesoatom Level for this Element using
// the Energy of Hydrogen Atom taken into account finite size of the
// nucleus (V.Ivanchenko)
const size_t ListK = 27;
static G4double ListZK[ListK] = {
2., 4., 6., 8., 11., 14., 17., 18., 21., 24.,
26., 29., 32., 38., 40., 41., 44., 49., 53., 55.,
60., 65., 70., 75., 81., 85., 92.};
static G4double ListKEnergy[ListK] = {
0.011, 0.043, 0.098, 0.173, 0.326,
0.524, 0.765, 0.853, 1.146, 1.472,
1.708, 2.081, 2.475, 3.323, 3.627,
3.779, 4.237, 5.016, 5.647, 5.966,
6.793, 7.602, 8.421, 9.249, 10.222,
10.923,11.984};
// Energy with finit size corrections
G4double KEnergy = GetLinApprox(ListK,ListZK,ListKEnergy,Z);
return KEnergy;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4MuMinusCaptureCascade::GetLinApprox(const size_t N,
const G4double X[],
const G4double Y[],
G4double Xuser)
{
G4double Yuser = 0.0;
G4int i;
if(N < 1) return Yuser;
else if(Xuser < X[0]) Yuser = Y[0];
else if(Xuser > X[N-1]) Yuser = Y[N-1];
else {
for (i = 1; i < N - 1; i++){
if(Xuser < X[i]) {break;}
}
Yuser = X[i] - X[i-1];
if(Yuser != 0.0){
Yuser = Y[i-1] + (Y[i] - Y[i-1]) * (Xuser - X[i-1]) / Yuser;
}
}
return Yuser;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4ThreeVector G4MuMinusCaptureCascade::GetRandomVec()
{
//
// generate uniform vector
//
G4double Theta = (2.0 * G4UniformRand() - 1.0) * pi ;
G4double Phi = twopi * G4UniformRand() ;
G4double sinTheta = sin(Theta);
G4double dirx = sinTheta * cos(Phi);
G4double diry = sinTheta * sin(Phi);
G4double dirz = cos(Theta);
return G4ThreeVector(dirx, diry, dirz);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4MuMinusCaptureCascade::AddNewParticle(G4ParticleDefinition* aParticle,
G4ThreeVector Momentum,
G4double mass,
G4int* nParticle,
G4GHEKinematicsVector* Cascade)
{
// Store particle in the HEK vector and increment counter
Cascade[*nParticle].SetZero();
Cascade[*nParticle].SetMass( mass );
Cascade[*nParticle].SetMomentumAndUpdate(Momentum.x(), Momentum.y(), Momentum.z());
Cascade[*nParticle].SetParticleDef( aParticle );
(*nParticle)++;
return;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4int G4MuMinusCaptureCascade::DoCascade(const G4double Z, const G4double massA,
G4GHEKinematicsVector* Cascade)
{
// Inicialization - cascade start from 14th level
// N.C.Mukhopadhyay Phy. Rep. 30 (1977) 1.
G4int nPart = 0;
G4double EnergyLevel[14];
G4double mass = MuMass * massA / (MuMass + massA) ;
const G4double KEnergy = 13.6 * eV * Z * Z * mass/ electron_mass_c2;
EnergyLevel[0] = GetKShellEnergy(Z);
for( G4int i = 2; i < 15; i++ ) {
EnergyLevel[i-1] = KEnergy / (i*i) ;
}
G4int nElec = G4int(Z);
G4int nAuger = 1;
G4int nLevel = 13;
G4double DeltaE;
G4double pGamma = Z*Z*Z*Z;
// Capture on 14-th level
G4double ptot = sqrt(EnergyLevel[13]*(EnergyLevel[13] + 2.0*Emass));
G4ThreeVector moment = ptot * GetRandomVec();
AddNewParticle(theElectron,moment,Emass,&nPart,Cascade);
// Emit new photon or electron
// Simplified model for probabilities
// N.C.Mukhopadhyay Phy. Rep. 30 (1977) 1.
do {
// case of Auger electrons
if((nAuger < nElec) && ((pGamma + 10000.0) * G4UniformRand() < 10000.0) ) {
nAuger++;
DeltaE = EnergyLevel[nLevel-1] - EnergyLevel[nLevel];
nLevel--;
ptot = sqrt(DeltaE * (DeltaE + 2.0*Emass));
moment = ptot * GetRandomVec();
AddNewParticle(theElectron, moment, Emass, &nPart, Cascade);
} else {
// Case of photon cascade, probabilities from
// C.S.Wu and L.Wilets, Ann. Rev. Nuclear Sci. 19 (1969) 527.
G4double var = (10.0 + G4double(nLevel - 1) ) * G4UniformRand();
G4int iLevel = nLevel - 1 ;
if(var > 10.0) iLevel -= G4int(var-10.0) + 1;
if( iLevel < 0 ) iLevel = 0;
DeltaE = EnergyLevel[iLevel] - EnergyLevel[nLevel];
nLevel = iLevel;
moment = DeltaE * GetRandomVec();
AddNewParticle(theGamma, moment, 0.0, &nPart, Cascade);
}
} while( nLevel > 0 );
return nPart;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4MuMinusCaptureCascade::DoBoundMuonMinusDecay(G4double Z, G4double massA,
G4int* nCascade,
G4GHEKinematicsVector* Cascade)
{
// Simulation on Decay of mu- on a K-shell of the muonic atom
G4double Energy, r, x;
G4double xmax = ( 1.0 + Emass*Emass/ (MuMass*MuMass) );
G4double KEnergy = GetKShellEnergy(Z);
// Calculate electron energy
do {
do {
x = xmax*G4UniformRand();
} while (G4UniformRand() < (3.0 - 2.0*x)*x*x );
Energy = x*MuMass*0.5 - Emass - KEnergy;
} while (Energy < 0.0);
//
// generate uniform vector
//
G4double ptot = sqrt(Energy * (Energy + 2.0*Emass));
G4ThreeVector moment = ptot * GetRandomVec();
AddNewParticle(theElectron, moment, Emass, nCascade, Cascade);
// Calculate rest frame parameters of 2 neutrinos
G4double E = MuMass*( 1.0 - x*0.5 );
G4double P = sqrt( MuMass*MuMass*x*x*0.25 - Emass*Emass );
if(P >= E) {P = E;}
G4double ecm = 0.5 * sqrt( E*E - P*P );
//
// generate uniform vector
//
moment *= -P / (ptot * E);
G4ThreeVector p1 = ecm * GetRandomVec();
// Create Neutrinos
G4LorentzVector N1 = G4LorentzVector(p1,ecm);
N1.boost(moment);
AddNewParticle(G4AntiNeutrinoE::AntiNeutrinoE(),G4ThreeVector(N1),0.0,nCascade,Cascade);
G4LorentzVector N2 = G4LorentzVector(-p1,ecm);
N2.boost(moment);
AddNewParticle(G4NeutrinoMu::NeutrinoMu(),G4ThreeVector(N2),0.0,nCascade,Cascade);
return;
}