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 BetheBlochModel =
new G4BetheBlochModel();
93 G4cout <<
"### Monopole ionisation model with d-electron production, Gmag= "
99 G4mplAtlasIonisationWithDeltaModel::~G4mplAtlasIonisationWithDeltaModel()
105 G4mplAtlasIonisationWithDeltaModel::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);
123 G4mplAtlasIonisationWithDeltaModel::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;
167 G4mplAtlasIonisationWithDeltaModel::ComputeDEDXAhlen(
const G4Material* material,
171 const G4double eDensity = material->GetElectronDensity();
172 const G4double eexc = material->GetIonisation()->GetMeanExcitationEnergy();
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]; }
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; }
205 G4mplAtlasIonisationWithDeltaModel::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) {
218 if(
p->GetPDGCharge() != 0) {
219 G4double crossBetheBloch = BetheBlochModel->ComputeCrossSectionPerElectron(
p, kineticEnergy, cutEnergy, maxKinEnergy);
220 cross += crossBetheBloch;
229 G4mplAtlasIonisationWithDeltaModel::ComputeCrossSectionPerAtom(
230 const G4ParticleDefinition*
p,
231 G4double kineticEnergy,
232 G4double
Z, G4double,
236 const G4double cross =
237 Z*ComputeCrossSectionPerElectron(
p,kineticEnergy,cutEnergy,maxEnergy);
244 G4mplAtlasIonisationWithDeltaModel::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 =
274 (deltaMomentum * totMomentum);
279 const G4double sint = std::sqrt((1.0 -
cost)*(1.0 +
cost));
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);
304 G4double 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);
347 G4mplAtlasIonisationWithDeltaModel::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));
366 * electronDensity * chargeSquare;
374 G4mplAtlasIonisationWithDeltaModel::MaxSecondaryEnergy(
const G4ParticleDefinition*,
377 const G4double tau = kinEnergy/
mass;