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>
36 using namespace Belle2::Monopoles;
37 using namespace CLHEP;
39 std::vector<G4double>* G4mplIonisationWithDeltaModel::dedx0 =
nullptr;
41 G4mplIonisationWithDeltaModel::G4mplIonisationWithDeltaModel(G4double mCharge,
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.
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.