Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/electromagnetic/highenergy/src/G4mplIonisationWithDeltaModel.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ]

  1 //
  2 // ********************************************************************
  3 // * License and Disclaimer                                           *
  4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.                             *
 10 // *                                                                  *
 11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                                                  *
 18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // ********************************************************************
 25 //
 26 // $Id: G4mplIonisationWithDeltaModel.cc 97391 2016-06-02 10:08:45Z gcosmo $
 27 //
 28 // -------------------------------------------------------------------
 29 //
 30 // GEANT4 Class header file
 31 //
 32 //
 33 // File name:     G4mplIonisationWithDeltaModel
 34 //
 35 // Author:        Vladimir Ivanchenko 
 36 //
 37 // Creation date: 06.09.2005
 38 //
 39 // Modifications:
 40 // 12.08.2007 Changing low energy approximation and extrapolation. 
 41 //            Small bug fixing and refactoring (M. Vladymyrov)
 42 // 13.11.2007 Use low-energy asymptotic from [3] (V.Ivanchenko) 
 43 //
 44 //
 45 // -------------------------------------------------------------------
 46 // References
 47 // [1] Steven P. Ahlen: Energy loss of relativistic heavy ionizing particles, 
 48 //     S.P. Ahlen, Rev. Mod. Phys 52(1980), p121
 49 // [2] K.A. Milton arXiv:hep-ex/0602040
 50 // [3] S.P. Ahlen and K. Kinoshita, Phys. Rev. D26 (1982) 2347
 51 
 52 
 53 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 54 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 55 
 56 #include "G4mplIonisationWithDeltaModel.hh"
 57 #include "Randomize.hh"
 58 #include "G4PhysicalConstants.hh"
 59 #include "G4SystemOfUnits.hh"
 60 #include "G4ParticleChangeForLoss.hh"
 61 #include "G4Electron.hh"
 62 #include "G4DynamicParticle.hh"
 63 #include "G4ProductionCutsTable.hh"
 64 #include "G4MaterialCutsCouple.hh"
 65 #include "G4Log.hh"
 66 
 67 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 68 
 69 using namespace std;
 70 
 71 std::vector<G4double>* G4mplIonisationWithDeltaModel::dedx0 = nullptr;
 72 
 73 G4mplIonisationWithDeltaModel::G4mplIonisationWithDeltaModel(G4double mCharge,
 74                    const G4String& nam)
 75   : G4VEmModel(nam),G4VEmFluctuationModel(nam),
 76   magCharge(mCharge),
 77   twoln10(log(100.0)),
 78   betalow(0.01),
 79   betalim(0.1),
 80   beta2lim(betalim*betalim),
 81   bg2lim(beta2lim*(1.0 + beta2lim))
 82 {
 83   nmpl = G4lrint(std::fabs(magCharge) * 2 * fine_structure_const);
 84   if(nmpl > 6)      { nmpl = 6; }
 85   else if(nmpl < 1) { nmpl = 1; }
 86   pi_hbarc2_over_mc2 = pi * hbarc * hbarc / electron_mass_c2;
 87   chargeSquare = magCharge * magCharge;
 88   dedxlim = 45.*nmpl*nmpl*GeV*cm2/g;
 89   fParticleChange = nullptr;
 90   theElectron = G4Electron::Electron();
 91   G4cout << "### Monopole ionisation model with d-electron production, Gmag= " 
 92    << magCharge/eplus << G4endl;
 93   monopole = nullptr;
 94   mass = 0.0;
 95 }
 96 
 97 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 98 
 99 G4mplIonisationWithDeltaModel::~G4mplIonisationWithDeltaModel()
100 {
101   if(IsMaster()) { delete dedx0; }
102 }
103 
104 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
105 
106 void G4mplIonisationWithDeltaModel::SetParticle(const G4ParticleDefinition* p)
107 {
108   monopole = p;
109   mass     = monopole->GetPDGMass();
110   G4double emin = 
111     std::min(LowEnergyLimit(),0.1*mass*(1./sqrt(1. - betalow*betalow) - 1.)); 
112   G4double emax = 
113     std::max(HighEnergyLimit(),10*mass*(1./sqrt(1. - beta2lim) - 1.)); 
114   SetLowEnergyLimit(emin);
115   SetHighEnergyLimit(emax);
116 }
117 
118 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
119 
120 void 
121 G4mplIonisationWithDeltaModel::Initialise(const G4ParticleDefinition* p,
122             const G4DataVector&)
123 {
124   if(!monopole) { SetParticle(p); }
125   if(!fParticleChange) { fParticleChange = GetParticleChangeForLoss(); }
126   if(IsMaster()) {
127     if(!dedx0) { dedx0 = new std::vector<G4double>; }
128     G4ProductionCutsTable* theCoupleTable=
129       G4ProductionCutsTable::GetProductionCutsTable();
130     G4int numOfCouples = theCoupleTable->GetTableSize();
131     G4int n = dedx0->size();
132     if(n < numOfCouples) { dedx0->resize(numOfCouples); }
133 
134     // initialise vector
135     for(G4int i=0; i<numOfCouples; ++i) {
136 
137       const G4Material* material = 
138   theCoupleTable->GetMaterialCutsCouple(i)->GetMaterial();
139       G4double eDensity = material->GetElectronDensity();
140       G4double vF = electron_Compton_length*pow(3.*pi*pi*eDensity,0.3333333333);
141       (*dedx0)[i] = pi_hbarc2_over_mc2*eDensity*nmpl*nmpl*
142   (G4Log(2*vF/fine_structure_const) - 0.5)/vF;
143     }
144   }
145 }
146 
147 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
148 
149 G4double 
150 G4mplIonisationWithDeltaModel::ComputeDEDXPerVolume(const G4Material* material,
151                 const G4ParticleDefinition* p,
152                 G4double kineticEnergy,
153                 G4double maxEnergy)
154 {
155   if(!monopole) { SetParticle(p); }
156   G4double tmax = MaxSecondaryEnergy(p,kineticEnergy);
157   G4double cutEnergy = std::min(tmax, maxEnergy);
158   cutEnergy = std::max(LowEnergyLimit(), cutEnergy);
159   G4double tau   = kineticEnergy / mass;
160   G4double gam   = tau + 1.0;
161   G4double bg2   = tau * (tau + 2.0);
162   G4double beta2 = bg2 / (gam * gam);
163   G4double beta  = sqrt(beta2);
164 
165   // low-energy asymptotic formula
166   //G4double dedx  = dedxlim*beta*material->GetDensity();
167   G4double dedx = (*dedx0)[CurrentCouple()->GetIndex()]*beta;
168 
169   // above asymptotic
170   if(beta > betalow) {
171 
172     // high energy
173     if(beta >= betalim) {
174       dedx = ComputeDEDXAhlen(material, bg2, cutEnergy);
175 
176     } else {
177 
178       //G4double dedx1 = dedxlim*betalow*material->GetDensity();
179       G4double dedx1 = (*dedx0)[CurrentCouple()->GetIndex()]*betalow;
180       G4double dedx2 = ComputeDEDXAhlen(material, bg2lim, cutEnergy);
181 
182       // extrapolation between two formula 
183       G4double kapa2 = beta - betalow;
184       G4double kapa1 = betalim - beta;
185       dedx = (kapa1*dedx1 + kapa2*dedx2)/(kapa1 + kapa2);
186     }
187   }
188   return dedx;
189 }
190 
191 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
192 
193 G4double 
194 G4mplIonisationWithDeltaModel::ComputeDEDXAhlen(const G4Material* material, 
195             G4double bg2, 
196             G4double cutEnergy)
197 {
198   G4double eDensity = material->GetElectronDensity();
199   G4double eexc  = material->GetIonisation()->GetMeanExcitationEnergy();
200 
201   // Ahlen's formula for nonconductors, [1]p157, f(5.7)
202   G4double dedx = 
203     0.5*(log(2.0 * electron_mass_c2 * bg2*cutEnergy / (eexc*eexc)) - 1.0);
204 
205   // Kazama et al. cross-section correction
206   G4double  k = 0.406;
207   if(nmpl > 1) { k = 0.346; }
208 
209   // Bloch correction
210   const G4double B[7] = { 0.0, 0.248, 0.672, 1.022, 1.243, 1.464, 1.685}; 
211 
212   dedx += 0.5 * k - B[nmpl];
213 
214   // density effect correction
215   G4double x = G4Log(bg2)/twoln10;
216   dedx -= material->GetIonisation()->DensityCorrection(x);
217 
218   // now compute the total ionization loss
219   dedx *=  pi_hbarc2_over_mc2 * eDensity * nmpl * nmpl;
220 
221   if (dedx < 0.0) { dedx = 0.; }
222   return dedx;
223 }
224 
225 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
226 
227 G4double
228 G4mplIonisationWithDeltaModel::ComputeCrossSectionPerElectron(
229                                            const G4ParticleDefinition* p,
230              G4double kineticEnergy,
231              G4double cut,
232              G4double maxKinEnergy)
233 {
234   if(!monopole) { SetParticle(p); }
235   G4double cross = 0.0;
236   G4double tmax = MaxSecondaryEnergy(p, kineticEnergy);
237   G4double maxEnergy = std::min(tmax,maxKinEnergy);
238   G4double cutEnergy = std::max(LowEnergyLimit(), cut);
239   if(cutEnergy < maxEnergy) {
240     cross = (0.5/cutEnergy - 0.5/maxEnergy)*pi_hbarc2_over_mc2 * nmpl * nmpl;
241   }
242   return cross;
243 }
244 
245 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
246 
247 G4double 
248 G4mplIonisationWithDeltaModel::ComputeCrossSectionPerAtom(
249             const G4ParticleDefinition* p,
250             G4double kineticEnergy,
251             G4double Z, G4double,
252             G4double cutEnergy,
253             G4double maxEnergy)
254 {
255   G4double cross = 
256     Z*ComputeCrossSectionPerElectron(p,kineticEnergy,cutEnergy,maxEnergy);
257   return cross;
258 }
259 
260 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
261 
262 void 
263 G4mplIonisationWithDeltaModel::SampleSecondaries(vector<G4DynamicParticle*>* vdp,
264              const G4MaterialCutsCouple*,
265              const G4DynamicParticle* dp,
266              G4double minKinEnergy,
267              G4double maxEnergy)
268 {
269   G4double kineticEnergy = dp->GetKineticEnergy();
270   G4double tmax = MaxSecondaryEnergy(dp->GetDefinition(),kineticEnergy);
271 
272   G4double maxKinEnergy = std::min(maxEnergy,tmax);
273   if(minKinEnergy >= maxKinEnergy) { return; }
274 
275   //G4cout << "G4mplIonisationWithDeltaModel::SampleSecondaries: E(GeV)= "
276   //   << kineticEnergy/GeV << " M(GeV)= " << mass/GeV
277   //   << " tmin(MeV)= " << minKinEnergy/MeV << G4endl;
278 
279   G4double totEnergy     = kineticEnergy + mass;
280   G4double etot2         = totEnergy*totEnergy;
281   G4double beta2         = kineticEnergy*(kineticEnergy + 2.0*mass)/etot2;
282   
283   // sampling without nuclear size effect
284   G4double q = G4UniformRand();
285   G4double deltaKinEnergy = minKinEnergy*maxKinEnergy
286     /(minKinEnergy*(1.0 - q) + maxKinEnergy*q);
287 
288   // delta-electron is produced
289   G4double totMomentum = totEnergy*sqrt(beta2);
290   G4double deltaMomentum =
291            sqrt(deltaKinEnergy * (deltaKinEnergy + 2.0*electron_mass_c2));
292   G4double cost = deltaKinEnergy * (totEnergy + electron_mass_c2) /
293                                    (deltaMomentum * totMomentum);
294   if(cost > 1.0) { cost = 1.0; }
295 
296   G4double sint = sqrt((1.0 - cost)*(1.0 + cost));
297 
298   G4double phi = twopi * G4UniformRand() ;
299 
300   G4ThreeVector deltaDirection(sint*cos(phi),sint*sin(phi), cost);
301   G4ThreeVector direction = dp->GetMomentumDirection();
302   deltaDirection.rotateUz(direction);
303 
304   // create G4DynamicParticle object for delta ray
305   G4DynamicParticle* delta = 
306     new G4DynamicParticle(theElectron,deltaDirection,deltaKinEnergy);
307 
308   vdp->push_back(delta);
309 
310   // Change kinematics of primary particle
311   kineticEnergy       -= deltaKinEnergy;
312   G4ThreeVector finalP = direction*totMomentum - deltaDirection*deltaMomentum;
313   finalP               = finalP.unit();
314 
315   fParticleChange->SetProposedKineticEnergy(kineticEnergy);
316   fParticleChange->SetProposedMomentumDirection(finalP);
317 }
318 
319 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
320 
321 G4double G4mplIonisationWithDeltaModel::SampleFluctuations(
322                const G4MaterialCutsCouple* couple,
323                const G4DynamicParticle* dp,
324                G4double tmax,
325                G4double length,
326                G4double meanLoss)
327 {
328   G4double siga = Dispersion(couple->GetMaterial(),dp,tmax,length);
329   G4double loss = meanLoss;
330   siga = sqrt(siga);
331   G4double twomeanLoss = meanLoss + meanLoss;
332 
333   if(twomeanLoss < siga) {
334     G4double x;
335     do {
336       loss = twomeanLoss*G4UniformRand();
337       x = (loss - meanLoss)/siga;
338       // Loop checking, 07-Aug-2015, Vladimir Ivanchenko
339     } while (1.0 - 0.5*x*x < G4UniformRand());
340   } else {
341     do {
342       loss = G4RandGauss::shoot(meanLoss,siga);
343       // Loop checking, 07-Aug-2015, Vladimir Ivanchenko
344     } while (0.0 > loss || loss > twomeanLoss);
345   }
346   return loss;
347 }
348 
349 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
350 
351 G4double 
352 G4mplIonisationWithDeltaModel::Dispersion(const G4Material* material,
353             const G4DynamicParticle* dp,
354             G4double tmax,
355             G4double length)
356 {
357   G4double siga = 0.0;
358   G4double tau   = dp->GetKineticEnergy()/mass;
359   if(tau > 0.0) { 
360     G4double electronDensity = material->GetElectronDensity();
361     G4double gam   = tau + 1.0;
362     G4double invbeta2 = (gam*gam)/(tau * (tau+2.0));
363     siga  = (invbeta2 - 0.5) * twopi_mc2_rcl2 * tmax * length
364       * electronDensity * chargeSquare;
365   }
366   return siga;
367 }
368 
369 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
370 
371 G4double 
372 G4mplIonisationWithDeltaModel::MaxSecondaryEnergy(const G4ParticleDefinition*,
373               G4double kinEnergy)
374 {
375   G4double tau = kinEnergy/mass;
376   return 2.0*electron_mass_c2*tau*(tau + 2.);
377 }
378 
379 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
380