19#include <simulation/monopoles/G4mplIonisationWithDeltaModel.h>
21#include <Randomize.hh>
22#include <CLHEP/Units/PhysicalConstants.h>
23#include <CLHEP/Units/SystemOfUnits.h>
24#include <G4ParticleChangeForLoss.hh>
25#include <G4Electron.hh>
26#include <G4DynamicParticle.hh>
27#include <G4ProductionCutsTable.hh>
28#include <G4MaterialCutsCouple.hh>
32#include <framework/logging/Logger.h>
36using namespace Belle2::Monopoles;
43 : G4VEmModel(nam), G4VEmFluctuationModel(nam),
48 beta2lim(betalim * betalim),
49 bg2lim(beta2lim * (1.0 + beta2lim)),
50 pi_hbarc2_over_mc2(pi * hbarc * hbarc / electron_mass_c2)
59 B2INFO(
"Monopole ionisation model with d-electron production, Gmag= " <<
magCharge / eplus);
61 B2WARNING(
"Monopole charge Gmag= " <<
magCharge / eplus <<
"e not reasonable. Please choose a value smaller than 411e.");
68 if (IsMaster()) {
delete dedx0; }
79 SetLowEnergyLimit(emin);
80 SetHighEnergyLimit(emax);
90 if (!
dedx0) {
dedx0 =
new std::vector<G4double>; }
91 G4ProductionCutsTable* theCoupleTable =
92 G4ProductionCutsTable::GetProductionCutsTable();
93 G4int numOfCouples = theCoupleTable->GetTableSize();
94 G4int n =
dedx0->size();
95 if (n < numOfCouples) {
dedx0->resize(numOfCouples); }
96 G4Pow* g4calc = G4Pow::GetInstance();
99 for (G4int i = 0; i < numOfCouples; ++i) {
101 const G4Material* material =
102 theCoupleTable->GetMaterialCutsCouple(i)->GetMaterial();
103 G4double eDensity = material->GetElectronDensity();
104 G4double vF = electron_Compton_length * g4calc->A13(3.*pi * pi * eDensity);
106 (G4Log(2 * vF / fine_structure_const) - 0.5) / vF;
113 const G4MaterialCutsCouple* couple)
115 return couple->GetMaterial()->GetIonisation()->GetMeanExcitationEnergy();
120 const G4ParticleDefinition* p,
121 G4double kineticEnergy,
126 G4double cutEnergy = std::min(tmax, maxEnergy);
127 cutEnergy = std::max(LowEnergyLimit(), cutEnergy);
128 G4double tau = kineticEnergy /
mass;
129 G4double gam = tau + 1.0;
130 G4double bg2 = tau * (tau + 2.0);
131 G4double beta2 = bg2 / (gam * gam);
132 G4double beta =
sqrt(beta2);
136 G4double dedx = (*dedx0)[CurrentCouple()->GetIndex()] * beta;
148 G4double dedx1 = (*dedx0)[CurrentCouple()->GetIndex()] *
betalow;
152 G4double kapa2 = beta -
betalow;
153 G4double kapa1 =
betalim - beta;
154 dedx = (kapa1 * dedx1 + kapa2 * dedx2) / (kapa1 + kapa2);
165 G4double eDensity = material->GetElectronDensity();
166 G4double eexc = material->GetIonisation()->GetMeanExcitationEnergy();
170 0.5 * (G4Log(2.0 * electron_mass_c2 * bg2 * cutEnergy / (eexc * eexc)) - 1.0);
176 if (
nmpl >= 0.5) { k = 0.406; }
177 if (
nmpl >= 1) { k = 0.346; }
178 if (
nmpl >= 1.5) { k = 0.3; }
179 const G4double B[7] = { 0.0, 0.248, 0.672, 1.022, 1.243, 1.464, 1.685};
181 dedx += 0.5 * k - B[int(floor(
nmpl + 0.5))];
185 G4double x = G4Log(bg2) /
twoln10;
186 dedx -= material->GetIonisation()->DensityCorrection(x);
191 dedx = std::max(dedx, 0.0);
197 const G4ParticleDefinition* p,
198 G4double kineticEnergy,
200 G4double maxKinEnergy)
204 G4double maxEnergy = std::min(tmax, maxKinEnergy);
205 G4double cutEnergy = std::max(LowEnergyLimit(), cut);
206 G4double cross = (cutEnergy < maxEnergy)
207 ? (1.0 / cutEnergy - 1.0 / maxEnergy) * twopi_mc2_rcl2 *
chargeSquare : 0.0;
215 const G4ParticleDefinition* p,
216 G4double kineticEnergy,
217 G4double Z, G4double,
228 const G4MaterialCutsCouple*,
229 const G4DynamicParticle* dp,
230 G4double minKinEnergy,
233 G4double kineticEnergy = dp->GetKineticEnergy();
236 G4double maxKinEnergy = std::min(maxEnergy, tmax);
237 if (minKinEnergy >= maxKinEnergy) {
return; }
239 G4double totEnergy = kineticEnergy +
mass;
240 G4double etot2 = totEnergy * totEnergy;
241 G4double beta2 = kineticEnergy * (kineticEnergy + 2.0 *
mass) / etot2;
244 G4double q = G4UniformRand();
245 G4double deltaKinEnergy = minKinEnergy * maxKinEnergy
246 / (minKinEnergy * (1.0 - q) + maxKinEnergy * q);
249 G4double totMomentum = totEnergy *
sqrt(beta2);
250 G4double deltaMomentum =
251 sqrt(deltaKinEnergy * (deltaKinEnergy + 2.0 * electron_mass_c2));
252 G4double cost = deltaKinEnergy * (totEnergy + electron_mass_c2) /
253 (deltaMomentum * totMomentum);
254 cost = std::min(cost, 1.0);
256 G4double sint =
sqrt((1.0 - cost) * (1.0 + cost));
258 G4double phi = twopi * G4UniformRand() ;
260 G4ThreeVector deltaDirection(sint * cos(phi), sint * sin(phi), cost);
261 G4ThreeVector direction = dp->GetMomentumDirection();
262 deltaDirection.rotateUz(direction);
265 G4DynamicParticle* delta =
266 new G4DynamicParticle(
theElectron, deltaDirection, deltaKinEnergy);
268 vdp->push_back(delta);
271 kineticEnergy -= deltaKinEnergy;
272 G4ThreeVector finalP = direction * totMomentum - deltaDirection * deltaMomentum;
273 finalP = finalP.unit();
280 const G4MaterialCutsCouple* couple,
281 const G4DynamicParticle* dp,
287 G4double siga =
Dispersion(couple->GetMaterial(), dp, tcut, tmax, length);
288 G4double loss = meanLoss;
290 G4double twomeanLoss = meanLoss + meanLoss;
292 if (twomeanLoss < siga) {
295 loss = twomeanLoss * G4UniformRand();
296 x = (loss - meanLoss) / siga;
298 }
while (1.0 - 0.5 * x * x < G4UniformRand());
301 loss = G4RandGauss::shoot(meanLoss, siga);
303 }
while (0.0 > loss || loss > twomeanLoss);
310 const G4DynamicParticle* dp,
316 G4double tau = dp->GetKineticEnergy() /
mass;
318 G4double electronDensity = material->GetElectronDensity();
319 const G4double beta = dp->GetBeta();
320 siga = (tmax / (beta * beta) - 0.5 * tcut) * twopi_mc2_rcl2 * length
330 G4double tau = kinEnergy /
mass;
331 return 2.0 * electron_mass_c2 * tau * (tau + 2.);
G4double pi_hbarc2_over_mc2
Convenient constants combination with mass.
G4double betalow
Beta threshold for low asymptotic.
G4double beta2lim
Square of betalim.
virtual ~G4mplIonisationWithDeltaModel()
Destructor.
virtual G4double MinEnergyCut(const G4ParticleDefinition *, const G4MaterialCutsCouple *couple) override
Threshold for zero value.
G4double chargeSquare
Square of magnetic charge in units of Dirac charge.
virtual G4double ComputeCrossSectionPerAtom(const G4ParticleDefinition *p, G4double kineticEnergy, G4double Z, G4double A, G4double cutEnergy, G4double maxEnergy) override
Compute cross section per atom for delta electrons emission.
G4ParticleChangeForLoss * fParticleChange
Pointer to ionising particle.
G4ParticleDefinition * theElectron
Electron definition.
G4double twoln10
log(100.0)
const G4ParticleDefinition * monopole
Monopole definition.
G4double dedxlim
dedx limit in asymptotic formula, not used
G4double mass
Mass of the monopole.
virtual G4double ComputeDEDXPerVolume(const G4Material *material, const G4ParticleDefinition *p, G4double kineticEnergy, G4double maxEnergy) override
G4VEmModel::ComputeDEDXPerVolume implementation.
virtual G4double MaxSecondaryEnergy(const G4ParticleDefinition *p, G4double kinEnergy) override
Calculate maximum energy available for secondary particle emission.
G4double magCharge
Monopole magnetic charge in e+ units.
G4double ComputeDEDXAhlen(const G4Material *material, G4double bg2, G4double cut)
Calculate dedx based on extrapolated Ahlen formula.
virtual void Initialise(const G4ParticleDefinition *p, const G4DataVector &) override
G4VEmModel::Initialise implementation.
virtual void SampleSecondaries(std::vector< G4DynamicParticle * > *vdp, const G4MaterialCutsCouple *materialCutsCouple, const G4DynamicParticle *dp, G4double tmin, G4double maxEnergy) override
Create the sample of secondary delta electrons.
void SetParticle(const G4ParticleDefinition *p)
Read definition of the monopole.
virtual G4double SampleFluctuations(const G4MaterialCutsCouple *couple, const G4DynamicParticle *dp, G4double tcut, G4double tmax, G4double length, G4double meanLoss) override
Create fluctuations in the energies lost to a secondary delta electron.
virtual G4double ComputeCrossSectionPerElectron(const G4ParticleDefinition *p, G4double kineticEnergy, G4double cutEnergy, G4double maxEnergy)
Compute cross section per electron for delta electrons emission.
G4double bg2lim
(beta*gamma)^2 for betalim
virtual G4double Dispersion(const G4Material *material, const G4DynamicParticle *, G4double tcut, G4double tmax, G4double length) override
Calculate dispersion.
static std::vector< G4double > * dedx0
Base dedx for each couple in current material.
G4mplIonisationWithDeltaModel(G4double mCharge, const G4String &nam="mplIonisationWithDelta")
Constructor.
G4double betalim
Beta threshold for high energy (only Ahlen formula)
double sqrt(double a)
sqrt for double
Abstract base class for different kinds of events.