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"
73 G4mplAtlasIonisationWithDeltaModel::G4mplAtlasIonisationWithDeltaModel(G4double mCharge,
const G4String& nam)
74 : G4VEmModel(nam),G4VEmFluctuationModel(nam),
78 twoln10(std::
log(100.0)),
81 beta2lim(betalim*betalim),
82 bg2lim(beta2lim*(1.0 + beta2lim))
88 chargeSquare = magCharge * magCharge;
92 G4cout <<
"### Monopole ionisation model with d-electron production, Gmag= "
98 G4mplAtlasIonisationWithDeltaModel::~G4mplAtlasIonisationWithDeltaModel()
104 G4mplAtlasIonisationWithDeltaModel::Initialise(
const G4ParticleDefinition*
p,
108 mass = monopole->GetPDGMass();
112 fParticleChange =
reinterpret_cast<G4ParticleChangeForLoss*
>(pParticleChange);
114 fParticleChange =
new G4ParticleChangeForLoss();
121 G4mplAtlasIonisationWithDeltaModel::ComputeDEDXPerVolume(
const G4Material* material,
122 const G4ParticleDefinition*
p,
123 G4double kineticEnergy,
126 const G4double tmax = MaxSecondaryEnergy(
p,kineticEnergy);
127 const G4double cutEnergy =
std::min(tmax, maxEnergy);
128 const G4double tau = kineticEnergy /
mass;
129 const G4double gam = tau + 1.0;
130 const G4double bg2 = tau * (tau + 2.0);
131 const G4double beta2 = bg2 / (gam * gam);
132 const G4double
beta = std::sqrt(beta2);
135 G4double dedx = dedxlim*
beta*material->GetDensity();
141 if(
beta >= betalim) {
142 dedx = ComputeDEDXAhlen(material, bg2, cutEnergy);
146 const G4double dedx1 = dedxlim*betalow*material->GetDensity();
147 const G4double dedx2 = ComputeDEDXAhlen(material, bg2lim, cutEnergy);
150 const G4double kapa2 =
beta - betalow;
151 const G4double kapa1 = betalim -
beta;
152 dedx = (kapa1*dedx1 + kapa2*dedx2)/(kapa1 + kapa2);
161 G4mplAtlasIonisationWithDeltaModel::ComputeDEDXAhlen(
const G4Material* material,
165 const G4double eDensity = material->GetElectronDensity();
166 const G4double eexc = material->GetIonisation()->GetMeanExcitationEnergy();
174 if(nmpl > 1) {
k = 0.346; }
177 const G4double
B[7] = { 0.0, 0.248, 0.672, 1.022, 1.243, 1.464, 1.685};
179 if(nmpl > 6.0) { dedx += 0.5 *
k -
B[6]; }
180 else if(nmpl < 1.0) { dedx += 0.5 *
k -
B[1]; }
185 const G4double
x =
std::log(bg2)/twoln10;
187 dedx -= material->GetIonisation()->DensityCorrection(
x);
190 dedx *= pi_hbarc2_over_mc2 * eDensity * nmpl * nmpl;
192 if (dedx < 0.0) { dedx = 0; }
199 G4mplAtlasIonisationWithDeltaModel::ComputeCrossSectionPerElectron(
200 const G4ParticleDefinition*
p,
201 G4double kineticEnergy,
203 G4double maxKinEnergy)
205 G4double cross = 0.0;
206 const G4double tmax = MaxSecondaryEnergy(
p, kineticEnergy);
207 const G4double maxEnergy =
std::min(tmax,maxKinEnergy);
208 if(cutEnergy < maxEnergy) {
217 G4mplAtlasIonisationWithDeltaModel::ComputeCrossSectionPerAtom(
218 const G4ParticleDefinition*
p,
219 G4double kineticEnergy,
220 G4double
Z, G4double,
224 const G4double cross =
225 Z*ComputeCrossSectionPerElectron(
p,kineticEnergy,cutEnergy,maxEnergy);
232 G4mplAtlasIonisationWithDeltaModel::SampleSecondaries(std::vector<G4DynamicParticle*>* vdp,
233 const G4MaterialCutsCouple*,
234 const G4DynamicParticle*
dp,
235 G4double minKinEnergy,
238 G4double kineticEnergy =
dp->GetKineticEnergy();
239 const G4double tmax = MaxSecondaryEnergy(
dp->GetDefinition(),kineticEnergy);
241 G4double maxKinEnergy =
std::min(maxEnergy,tmax);
242 if(minKinEnergy >= maxKinEnergy) {
return; }
248 const G4double totEnergy = kineticEnergy +
mass;
249 const G4double etot2 = totEnergy*totEnergy;
250 const G4double beta2 = kineticEnergy*(kineticEnergy + 2.0*
mass)/etot2;
253 const G4double
q = G4UniformRand();
254 const G4double deltaKinEnergy = minKinEnergy*maxKinEnergy
255 /(minKinEnergy*(1.0 -
q) + maxKinEnergy*
q);
258 const G4double totMomentum = totEnergy*std::sqrt(beta2);
259 const G4double deltaMomentum =
262 (deltaMomentum * totMomentum);
267 const G4double sint = std::sqrt((1.0 -
cost)*(1.0 +
cost));
272 const G4ThreeVector& direction =
dp->GetMomentumDirection();
273 deltaDirection.rotateUz(direction);
276 G4DynamicParticle* delta =
277 new G4DynamicParticle(theElectron,deltaDirection,deltaKinEnergy);
279 vdp->push_back(delta);
282 kineticEnergy -= deltaKinEnergy;
283 G4ThreeVector finalP = direction*totMomentum - deltaDirection*deltaMomentum;
284 finalP = finalP.unit();
286 fParticleChange->SetProposedKineticEnergy(kineticEnergy);
287 fParticleChange->SetProposedMomentumDirection(finalP);
292 G4double G4mplAtlasIonisationWithDeltaModel::SampleFluctuations(
293 #
if G4VERSION_NUMBER < 1100
294 const G4MaterialCutsCouple* material,
295 const G4DynamicParticle*
dp,
300 const G4MaterialCutsCouple* material,
301 const G4DynamicParticle*
dp,
305 const G4double meanLoss
309 #if G4VERSION_NUMBER < 1100
310 G4double siga = Dispersion(material->GetMaterial(),
dp,tmax,
length);
312 G4double siga = Dispersion(material->GetMaterial(),
dp,tcut,tmax,
length);
314 G4double loss = meanLoss;
315 siga = std::sqrt(siga);
316 const G4double twomeanLoss = meanLoss + meanLoss;
318 if(twomeanLoss < siga) {
321 loss = twomeanLoss*G4UniformRand();
322 x = (loss - meanLoss)/siga;
323 }
while (1.0 - 0.5*
x*
x < G4UniformRand());
326 loss = G4RandGauss::shoot(meanLoss,siga);
327 }
while (0.0 > loss || loss > twomeanLoss);
335 G4mplAtlasIonisationWithDeltaModel::Dispersion(
const G4Material* material,
336 const G4DynamicParticle*
dp,
337 #
if G4VERSION_NUMBER < 1100
348 const G4double tau =
dp->GetKineticEnergy()/
mass;
350 const G4double electronDensity = material->GetElectronDensity();
351 const G4double gam = tau + 1.0;
352 const G4double invbeta2 = (gam*gam)/(tau * (tau+2.0));
354 * electronDensity * chargeSquare;
362 G4mplAtlasIonisationWithDeltaModel::MaxSecondaryEnergy(
const G4ParticleDefinition*,
365 const G4double tau = kinEnergy/
mass;