277 lines
7.8 KiB
C++
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;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|