59#include "G4mplAtlasIonisationWithDeltaModel.hh"
61#include "Randomize.hh"
62#include "G4LossTableManager.hh"
63#include "G4ParticleChangeForLoss.hh"
64#include "G4Electron.hh"
65#include "G4DynamicParticle.hh"
66#include "G4Version.hh"
68#include "CLHEP/Units/SystemOfUnits.h"
69#include "CLHEP/Units/PhysicalConstants.h"
73G4mplAtlasIonisationWithDeltaModel::G4mplAtlasIonisationWithDeltaModel(G4double mCharge,
const G4String& nam)
74 : G4VEmModel(nam),G4VEmFluctuationModel(nam),
81 beta2lim(betalim*betalim),
82 bg2lim(beta2lim*(1.0 + beta2lim))
84 nmpl = std::abs(magCharge) * 2 * CLHEP::fine_structure_const;
87 pi_hbarc2_over_mc2 = CLHEP::pi * CLHEP::hbarc * CLHEP::hbarc / CLHEP::electron_mass_c2;
88 chargeSquare = magCharge * magCharge;
89 dedxlim = 45.*nmpl*nmpl*CLHEP::GeV*CLHEP::cm2/CLHEP::g;
91 theElectron = G4Electron::Electron();
92 BetheBlochModel =
new G4BetheBlochModel();
93 G4cout <<
"### Monopole ionisation model with d-electron production, Gmag= "
94 << magCharge/CLHEP::eplus << G4endl;
99G4mplAtlasIonisationWithDeltaModel::~G4mplAtlasIonisationWithDeltaModel()
105G4mplAtlasIonisationWithDeltaModel::Initialise(
const G4ParticleDefinition* p,
106 const G4DataVector& G4DataVec)
109 mass = monopole->GetPDGMass();
113 fParticleChange =
reinterpret_cast<G4ParticleChangeForLoss*
>(pParticleChange);
115 fParticleChange =
new G4ParticleChangeForLoss();
117 BetheBlochModel->Initialise(p, G4DataVec);
123G4mplAtlasIonisationWithDeltaModel::ComputeDEDXPerVolume(
const G4Material* material,
124 const G4ParticleDefinition* p,
125 G4double kineticEnergy,
128 const G4double tmax = MaxSecondaryEnergy(p,kineticEnergy);
129 const G4double cutEnergy = std::min(tmax, maxEnergy);
130 const G4double tau = kineticEnergy /
mass;
131 const G4double gam = tau + 1.0;
132 const G4double bg2 = tau * (tau + 2.0);
133 const G4double beta2 = bg2 / (gam * gam);
134 const G4double
beta = std::sqrt(beta2);
137 G4double dedx = dedxlim*
beta*material->GetDensity();
143 if(beta >= betalim) {
144 dedx = ComputeDEDXAhlen(material, bg2, cutEnergy);
148 const G4double dedx1 = dedxlim*betalow*material->GetDensity();
149 const G4double dedx2 = ComputeDEDXAhlen(material, bg2lim, cutEnergy);
152 const G4double kapa2 =
beta - betalow;
153 const G4double kapa1 = betalim -
beta;
154 dedx = (kapa1*dedx1 + kapa2*dedx2)/(kapa1 + kapa2);
157 if(
p->GetPDGCharge() != 0) {
158 G4double dedxBetheBloch = BetheBlochModel->ComputeDEDXPerVolume(material, p, kineticEnergy, maxEnergy);
159 dedx += dedxBetheBloch;
167G4mplAtlasIonisationWithDeltaModel::ComputeDEDXAhlen(
const G4Material* material,
171 const G4double eDensity = material->GetElectronDensity();
172 const G4double eexc = material->GetIonisation()->GetMeanExcitationEnergy();
176 0.5*(std::log(2.0 * CLHEP::electron_mass_c2 * bg2*cutEnergy / (eexc*eexc)) - 1.0);
180 if(nmpl > 1) {
k = 0.346; }
183 const G4double
B[7] = { 0.0, 0.248, 0.672, 1.022, 1.243, 1.464, 1.685};
185 if(nmpl > 6.0) { dedx += 0.5 *
k -
B[6]; }
186 else if(nmpl < 1.0) { dedx += 0.5 *
k -
B[1]; }
188 dedx += 0.5 *
k -
B[G4int(std::abs(magCharge) * 2 * CLHEP::fine_structure_const + 0.5)];
191 const G4double
x = std::log(bg2)/twoln10;
193 dedx -= material->GetIonisation()->DensityCorrection(
x);
196 dedx *= pi_hbarc2_over_mc2 * eDensity * nmpl * nmpl;
198 if (dedx < 0.0) { dedx = 0; }
205G4mplAtlasIonisationWithDeltaModel::ComputeCrossSectionPerElectron(
206 const G4ParticleDefinition* p,
207 G4double kineticEnergy,
209 G4double maxKinEnergy)
211 G4double cross = 0.0;
212 const G4double tmax = MaxSecondaryEnergy(p, kineticEnergy);
213 const G4double maxEnergy = std::min(tmax,maxKinEnergy);
214 if(cutEnergy < maxEnergy) {
215 cross = (1.0/cutEnergy - 1.0/maxEnergy)*CLHEP::twopi_mc2_rcl2*chargeSquare;
218 if(
p->GetPDGCharge() != 0) {
219 G4double crossBetheBloch = BetheBlochModel->ComputeCrossSectionPerElectron(p, kineticEnergy, cutEnergy, maxKinEnergy);
220 cross += crossBetheBloch;
229G4mplAtlasIonisationWithDeltaModel::ComputeCrossSectionPerAtom(
230 const G4ParticleDefinition* p,
231 G4double kineticEnergy,
232 G4double Z, G4double,
236 const G4double cross =
237 Z*ComputeCrossSectionPerElectron(p,kineticEnergy,cutEnergy,maxEnergy);
244G4mplAtlasIonisationWithDeltaModel::SampleSecondaries(std::vector<G4DynamicParticle*>* vdp,
245 const G4MaterialCutsCouple*,
246 const G4DynamicParticle* dp,
247 G4double minKinEnergy,
250 G4double kineticEnergy =
dp->GetKineticEnergy();
251 const G4double tmax = MaxSecondaryEnergy(
dp->GetDefinition(),kineticEnergy);
253 G4double maxKinEnergy = std::min(maxEnergy,tmax);
254 if(minKinEnergy >= maxKinEnergy) {
return; }
260 const G4double totEnergy = kineticEnergy +
mass;
261 const G4double etot2 = totEnergy*totEnergy;
262 const G4double beta2 = kineticEnergy*(kineticEnergy + 2.0*
mass)/etot2;
265 const G4double
q = G4UniformRand();
266 const G4double deltaKinEnergy = minKinEnergy*maxKinEnergy
267 /(minKinEnergy*(1.0 -
q) + maxKinEnergy*
q);
270 const G4double totMomentum = totEnergy*std::sqrt(beta2);
271 const G4double deltaMomentum =
272 std::sqrt(deltaKinEnergy * (deltaKinEnergy + 2.0*CLHEP::electron_mass_c2));
273 G4double
cost = deltaKinEnergy * (totEnergy + CLHEP::electron_mass_c2) /
274 (deltaMomentum * totMomentum);
279 const G4double sint = std::sqrt((1.0 -
cost)*(1.0 +
cost));
281 const G4double
phi = CLHEP::twopi * G4UniformRand() ;
284 const G4ThreeVector& direction =
dp->GetMomentumDirection();
285 deltaDirection.rotateUz(direction);
288 G4DynamicParticle* delta =
289 new G4DynamicParticle(theElectron,deltaDirection,deltaKinEnergy);
291 vdp->push_back(delta);
294 kineticEnergy -= deltaKinEnergy;
295 G4ThreeVector finalP = direction*totMomentum - deltaDirection*deltaMomentum;
296 finalP = finalP.unit();
298 fParticleChange->SetProposedKineticEnergy(kineticEnergy);
299 fParticleChange->SetProposedMomentumDirection(finalP);
304G4double G4mplAtlasIonisationWithDeltaModel::SampleFluctuations(
305#
if G4VERSION_NUMBER < 1100
306 const G4MaterialCutsCouple* material,
307 const G4DynamicParticle* dp,
312 const G4MaterialCutsCouple* material,
313 const G4DynamicParticle* dp,
317 const G4double meanLoss
321#if G4VERSION_NUMBER < 1100
322 G4double siga = Dispersion(material->GetMaterial(),dp,tmax,
length);
324 G4double siga = Dispersion(material->GetMaterial(),dp,tcut,tmax,
length);
326 G4double loss = meanLoss;
327 siga = std::sqrt(siga);
328 const G4double twomeanLoss = meanLoss + meanLoss;
330 if(twomeanLoss < siga) {
333 loss = twomeanLoss*G4UniformRand();
334 x = (loss - meanLoss)/siga;
335 }
while (1.0 - 0.5*
x*
x < G4UniformRand());
338 loss = G4RandGauss::shoot(meanLoss,siga);
339 }
while (0.0 > loss || loss > twomeanLoss);
347G4mplAtlasIonisationWithDeltaModel::Dispersion(
const G4Material* material,
348 const G4DynamicParticle* dp,
349#
if G4VERSION_NUMBER < 1100
360 const G4double tau =
dp->GetKineticEnergy()/
mass;
362 const G4double electronDensity = material->GetElectronDensity();
363 const G4double gam = tau + 1.0;
364 const G4double invbeta2 = (gam*gam)/(tau * (tau+2.0));
365 siga = (invbeta2 - 0.5) * CLHEP::twopi_mc2_rcl2 * tmax *
length
366 * electronDensity * chargeSquare;
374G4mplAtlasIonisationWithDeltaModel::MaxSecondaryEnergy(
const G4ParticleDefinition*,
377 const G4double tau = kinEnergy/
mass;
378 return 2.0*CLHEP::electron_mass_c2*tau*(tau + 2.);
Scalar phi() const
phi method
int cost(std::vector< std::string > &files, node &n, const std::string &directory="", bool deleteref=false, bool relocate=false)