Import Geant4 10.5.0 source tree
This commit is contained in:
@@ -23,7 +23,6 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4eplusTo3GammaOKVIModel.cc 101193 2016-11-08 18:02:50Z vnivanch $
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
@@ -32,7 +31,7 @@
|
||||
//
|
||||
// File name: G4eplusTo3GammaOKVIModel
|
||||
//
|
||||
// Author: Vladimir Ivanchenko and Omrame Kadri
|
||||
// Authors: Andrei Alkin, Vladimir Ivanchenko, Omrame Kadri
|
||||
//
|
||||
// Creation date: 29.03.2018
|
||||
//
|
||||
@@ -60,9 +59,7 @@ using namespace std;
|
||||
|
||||
G4eplusTo3GammaOKVIModel::G4eplusTo3GammaOKVIModel(const G4ParticleDefinition*,
|
||||
const G4String& nam)
|
||||
: G4VEmModel(nam),
|
||||
pi_rcl2(pi*classic_electr_radius*classic_electr_radius),
|
||||
energyTh(10*MeV)
|
||||
: G4VEmModel(nam), fDelta(0.001)
|
||||
{
|
||||
theGamma = G4Gamma::Gamma();
|
||||
fParticleChange = nullptr;
|
||||
@@ -78,27 +75,126 @@ G4eplusTo3GammaOKVIModel::~G4eplusTo3GammaOKVIModel()
|
||||
void G4eplusTo3GammaOKVIModel::Initialise(const G4ParticleDefinition*,
|
||||
const G4DataVector&)
|
||||
{
|
||||
energyTh = G4EmParameters::Instance()->LowestTripletEnergy();
|
||||
// here particle change is set for the triplet model
|
||||
if(fParticleChange) { return; }
|
||||
fParticleChange = GetParticleChangeForGamma();
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
// (A.A.) F_{ijk} calculation method
|
||||
G4double G4eplusTo3GammaOKVIModel::ComputeF(G4double fr1, G4double fr2,
|
||||
G4double fr3, G4double kinEnergy)
|
||||
{
|
||||
G4double ekin = std::max(eV,kinEnergy);
|
||||
G4double tau = ekin/electron_mass_c2;
|
||||
G4double gam = tau + 1.0;
|
||||
G4double gamma2 = gam*gam;
|
||||
G4double bg2 = tau * (tau+2.0);
|
||||
G4double bg = sqrt(bg2);
|
||||
|
||||
G4double rho = (gamma2+4.*gam+1.)*G4Log(gam+bg)/(gamma2-1.)
|
||||
- (gam+3.)/(sqrt(gam*gam - 1.)) + 1.;
|
||||
G4double border;
|
||||
|
||||
if(ekin < 500*MeV) {
|
||||
border = 1. - (electron_mass_c2)/(2*(ekin + electron_mass_c2));
|
||||
} else {
|
||||
border = 1. - (100*electron_mass_c2)/(2*(ekin + electron_mass_c2));
|
||||
}
|
||||
|
||||
border = std::min(border, 0.9999);
|
||||
|
||||
if (fr1>border) { fr1 = border; }
|
||||
if (fr2>border) { fr2 = border; }
|
||||
if (fr3>border) { fr3 = border; }
|
||||
|
||||
G4double fr1s = fr1*fr1; // "s" for "squared"
|
||||
G4double fr2s = fr2*fr2;
|
||||
G4double fr3s = fr3*fr3;
|
||||
|
||||
G4double aa = (1.-fr1)*(1.-fr2);
|
||||
G4double ab = fr3s + (fr1-fr2)*(fr1-fr2);
|
||||
G4double add= ((1.-fr1)*(1.-fr1) + (1.-fr2)*(1.-fr2))/(fr3s*aa);
|
||||
|
||||
G4double fres = -rho*(1./fr1s + 1./fr2s)
|
||||
+ (ab/(2.*(fr1*fr2*aa)))*(G4Log(2.*gam*aa/(fr1*fr2)))
|
||||
+ (ab/(2.*fr1*fr2*(1-fr3)))*G4Log(2.*gam*(1.-fr3)/(fr1*fr2)) - add;
|
||||
|
||||
return fres;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
// (A.A.) F_{ijk} calculation method
|
||||
G4double G4eplusTo3GammaOKVIModel::ComputeF0(G4double fr1, G4double fr2,
|
||||
G4double fr3)
|
||||
{
|
||||
G4double tau = 0.0;
|
||||
G4double gam = tau + 1.0;
|
||||
G4double gamma2 = gam*gam;
|
||||
G4double bg2 = tau * (tau+2.0);
|
||||
G4double bg = sqrt(bg2);
|
||||
|
||||
G4double rho = (gamma2+4.*gam+1.)*G4Log(gam+bg)/(gamma2-1.)
|
||||
- (gam+3.)/(sqrt(gam*gam - 1.)) + 1.;
|
||||
G4double border = 0.5;
|
||||
|
||||
if (fr1>border) { fr1 = border; }
|
||||
if (fr2>border) { fr2 = border; }
|
||||
if (fr3>border) { fr3 = border; }
|
||||
|
||||
G4double fr1s = fr1*fr1; // "s" for "squared"
|
||||
G4double fr2s = fr2*fr2;
|
||||
G4double fr3s = fr3*fr3;
|
||||
|
||||
G4double aa = (1.-fr1)*(1.-fr2);
|
||||
G4double ab = fr3s + (fr1-fr2)*(fr1-fr2);
|
||||
G4double add= ((1.-fr1)*(1.-fr1) + (1.-fr2)*(1.-fr2))/(fr3s*aa);
|
||||
|
||||
G4double fres = -rho*(1./fr1s + 1./fr2s)
|
||||
+ (ab/(2.*(fr1*fr2*aa)))*(G4Log(2.*gam*aa/(fr1*fr2)))
|
||||
+ (ab/(2.*fr1*fr2*(1-fr3)))*G4Log(2.*gam*(1.-fr3)/(fr1*fr2)) - add;
|
||||
|
||||
return fres;
|
||||
}
|
||||
|
||||
//(A.A.) diff x-sections for maximum search and rejection
|
||||
G4double G4eplusTo3GammaOKVIModel::ComputeFS(G4double fr1,
|
||||
G4double fr2, G4double fr3, G4double kinEnergy)
|
||||
{
|
||||
G4double ekin = std::max(eV,kinEnergy);
|
||||
G4double tau = ekin/electron_mass_c2;
|
||||
G4double gam = tau + 1.0;
|
||||
|
||||
G4double fsum = fr1*fr1*(ComputeF(fr1,fr2,fr3,ekin) +
|
||||
ComputeF(fr3,fr1,fr2,ekin) +
|
||||
ComputeF(fr2,fr3,fr1,ekin));
|
||||
|
||||
G4double dcross = fsum/((3*fr1*fr1*(gam+1.)));
|
||||
|
||||
return dcross;
|
||||
}
|
||||
|
||||
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
|
||||
|
||||
G4double
|
||||
G4eplusTo3GammaOKVIModel::ComputeCrossSectionPerElectron(G4double kineticEnergy)
|
||||
G4eplusTo3GammaOKVIModel::ComputeCrossSectionPerElectron(G4double kinEnergy)
|
||||
{
|
||||
// Calculates the cross section per electron of annihilation into two photons
|
||||
// Calculates the cross section per electron of annihilation into 3 photons
|
||||
// from the Heilter formula.
|
||||
|
||||
G4double ekin = std::max(eV,kineticEnergy);
|
||||
G4double ekin = std::max(eV,kinEnergy);
|
||||
G4double tau = ekin/electron_mass_c2;
|
||||
G4double gam = tau + 1.0;
|
||||
G4double gamma2 = gam*gam;
|
||||
G4double bg2 = tau * (tau+2.0);
|
||||
G4double bg = sqrt(bg2);
|
||||
|
||||
G4double rho = (gamma2+4*gam+1.)*G4Log(gam+bg)/(gamma2-1.)
|
||||
- (gam+3.)/(sqrt(gam*gam - 1.));
|
||||
|
||||
G4double tau = ekin/electron_mass_c2;
|
||||
G4double gam = tau + 1.0;
|
||||
G4double gamma2= gam*gam;
|
||||
G4double bg2 = tau * (tau+2.0);
|
||||
G4double bg = sqrt(bg2);
|
||||
|
||||
G4double cross = pi_rcl2*((gamma2+4*gam+1.)*G4Log(gam+bg) - (gam+3.)*bg)
|
||||
/ (bg2*(gam+1.));
|
||||
G4double cross = alpha_rcl2*(4.2 - (2.*G4Log(fDelta)+1.)*rho*rho)/(gam+1.);
|
||||
return cross;
|
||||
}
|
||||
|
||||
@@ -110,7 +206,9 @@ G4double G4eplusTo3GammaOKVIModel::ComputeCrossSectionPerAtom(
|
||||
G4double, G4double, G4double)
|
||||
{
|
||||
// Calculates the cross section per atom of annihilation into two photons
|
||||
|
||||
|
||||
|
||||
G4double cross = Z*ComputeCrossSectionPerElectron(kineticEnergy);
|
||||
return cross;
|
||||
}
|
||||
@@ -141,8 +239,17 @@ G4eplusTo3GammaOKVIModel::SampleSecondaries(vector<G4DynamicParticle*>* vdp,
|
||||
const G4DynamicParticle* dp,
|
||||
G4double, G4double)
|
||||
{
|
||||
|
||||
G4double posiKinEnergy = dp->GetKineticEnergy();
|
||||
G4DynamicParticle *aGamma1, *aGamma2, *aGamma3;
|
||||
G4double border;
|
||||
|
||||
if(posiKinEnergy < 500*MeV) {
|
||||
border = 1. - (electron_mass_c2)/(2*(posiKinEnergy + electron_mass_c2));
|
||||
} else {
|
||||
border = 1. - (100*electron_mass_c2)/(2*(posiKinEnergy + electron_mass_c2));
|
||||
}
|
||||
border = std::min(border, 0.9999);
|
||||
|
||||
CLHEP::HepRandomEngine* rndmEngine = G4Random::getTheEngine();
|
||||
|
||||
@@ -168,54 +275,70 @@ G4eplusTo3GammaOKVIModel::SampleSecondaries(vector<G4DynamicParticle*>* vdp,
|
||||
|
||||
G4ThreeVector posiDirection = dp->GetMomentumDirection();
|
||||
|
||||
G4double tau = posiKinEnergy/electron_mass_c2;
|
||||
G4double gam = tau + 1.0;
|
||||
G4double tau2 = tau + 2.0;
|
||||
G4double sqgrate = sqrt(tau/tau2)*0.5;
|
||||
G4double sqg2m1 = sqrt(tau*tau2);
|
||||
|
||||
// limits of the energy sampling
|
||||
G4double epsilmin = 0.5 - sqgrate;
|
||||
G4double epsilmax = 0.5 + sqgrate;
|
||||
G4double epsilqot = epsilmax/epsilmin;
|
||||
|
||||
//
|
||||
// sample the energy rate of the created gammas
|
||||
//
|
||||
G4double epsil, greject;
|
||||
// (A.A.) LIMITS FOR 1st GAMMA
|
||||
G4double xmin = 0.01;
|
||||
G4double xmax = 0.667; // CHANGE to 3/2
|
||||
|
||||
G4double d1, d0, x1, x2, dmax, x2min;
|
||||
|
||||
// (A.A.) sampling of x1 x2 x3 (whole cycle of rejection)
|
||||
do {
|
||||
epsil = epsilmin*G4Exp(G4Log(epsilqot)*rndmEngine->flat());
|
||||
greject = 1. - epsil + (2.*gam*epsil-1.)/(epsil*tau2*tau2);
|
||||
// Loop checking, 03-Aug-2015, Vladimir Ivanchenko
|
||||
} while( greject < rndmEngine->flat());
|
||||
x1 = 1/((1/xmin) - ((1/xmin)-(1/xmax))*rndmEngine->flat());
|
||||
dmax = ComputeFS(posiKinEnergy, x1,1.-x1,border);
|
||||
x2min = 1.-x1;
|
||||
x2 = 1 - rndmEngine->flat()*(1-x2min);
|
||||
d1 = dmax*rndmEngine->flat();
|
||||
d0 = ComputeFS(posiKinEnergy,x1,x2,2-x1-x2);
|
||||
}
|
||||
while(d0 < d1);
|
||||
|
||||
G4double x3 = 2 - x1 - x2;
|
||||
|
||||
//
|
||||
// scattered Gamma angles. ( Z - axis along the parent positron)
|
||||
// angles between Gammas
|
||||
//
|
||||
|
||||
G4double cost = (epsil*tau2-1.)/(epsil*sqg2m1);
|
||||
if(std::abs(cost) > 1.0) {
|
||||
G4cout << "### G4eplusTo3GammaOKVIModel WARNING cost= " << cost
|
||||
<< " positron Ekin(MeV)= " << posiKinEnergy
|
||||
<< " gamma epsil= " << epsil
|
||||
<< G4endl;
|
||||
if(cost > 1.0) cost = 1.0;
|
||||
else cost = -1.0;
|
||||
}
|
||||
G4double sint = sqrt((1.+cost)*(1.-cost));
|
||||
G4double phi = twopi * rndmEngine->flat();
|
||||
G4double psi13 = 2*asin(sqrt(std::abs((x1+x3-1)/(x1*x3))));
|
||||
G4double psi12 = 2*asin(sqrt(std::abs((x1+x2-1)/(x1*x2))));
|
||||
|
||||
// sin^t
|
||||
|
||||
//G4double phi = twopi * rndmEngine->flat();
|
||||
//G4double psi = acos(x3); // Angle of the plane
|
||||
|
||||
//
|
||||
// kinematic of the created pair
|
||||
//
|
||||
|
||||
G4double TotalAvailableEnergy = posiKinEnergy + 2.0*electron_mass_c2;
|
||||
G4double phot1Energy = epsil*TotalAvailableEnergy;
|
||||
|
||||
G4ThreeVector phot1Direction(sint*cos(phi), sint*sin(phi), cost);
|
||||
phot1Direction.rotateUz(posiDirection);
|
||||
G4double phot1Energy = 0.5*x1*TotalAvailableEnergy;
|
||||
G4double phot2Energy = 0.5*x2*TotalAvailableEnergy;
|
||||
G4double phot3Energy = 0.5*x3*TotalAvailableEnergy;
|
||||
|
||||
|
||||
// DIRECTIONS
|
||||
|
||||
// The azimuthal angles of ql and q3 with respect to some plane
|
||||
// through the beam axis are generated at random.
|
||||
|
||||
G4ThreeVector phot1Direction(0, 0, 1);
|
||||
G4ThreeVector phot2Direction(0, sin(psi12), cos(psi12));
|
||||
G4ThreeVector phot3Direction(0, sin(psi13), cos(psi13));
|
||||
|
||||
phot1Direction.rotateUz(posiDirection);
|
||||
phot2Direction.rotateUz(posiDirection);
|
||||
phot3Direction.rotateUz(posiDirection);
|
||||
|
||||
aGamma1 = new G4DynamicParticle (theGamma,phot1Direction, phot1Energy);
|
||||
aGamma2 = new G4DynamicParticle (theGamma,phot2Direction, phot2Energy);
|
||||
aGamma3 = new G4DynamicParticle (theGamma,phot3Direction, phot3Energy);
|
||||
|
||||
|
||||
//POLARIZATION - ???
|
||||
/*
|
||||
|
||||
|
||||
phi = twopi * rndmEngine->flat();
|
||||
G4double cosphi = cos(phi);
|
||||
G4double sinphi = sin(phi);
|
||||
@@ -238,6 +361,9 @@ G4eplusTo3GammaOKVIModel::SampleSecondaries(vector<G4DynamicParticle*>* vdp,
|
||||
pol -= cost*phot2Direction;
|
||||
pol = pol.unit();
|
||||
aGamma2->SetPolarization(pol.x(),pol.y(),pol.z());
|
||||
|
||||
*/
|
||||
|
||||
}
|
||||
/*
|
||||
G4cout << "Annihilation in fly: e0= " << posiKinEnergy
|
||||
|
||||
Reference in New Issue
Block a user