Geant4  10.00.p02
G4EnergyLossForExtrapolator.cc
Go to the documentation of this file.
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: G4EnergyLossForExtrapolator.cc 75168 2013-10-29 09:20:52Z gcosmo $
27 //
28 //---------------------------------------------------------------------------
29 //
30 // ClassName: G4EnergyLossForExtrapolator
31 //
32 // Description: This class provide calculation of energy loss, fluctuation,
33 // and msc angle
34 //
35 // Author: 09.12.04 V.Ivanchenko
36 //
37 // Modification:
38 // 08-04-05 Rename Propogator -> Extrapolator (V.Ivanchenko)
39 // 16-03-06 Add muon tables and fix bug in units (V.Ivanchenko)
40 // 21-03-06 Add verbosity defined in the constructor and Initialisation
41 // start only when first public method is called (V.Ivanchenko)
42 // 03-05-06 Remove unused pointer G4Material* from number of methods (VI)
43 // 12-05-06 SEt linLossLimit=0.001 (VI)
44 //
45 //----------------------------------------------------------------------------
46 //
47 
48 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
49 
51 #include "G4PhysicalConstants.hh"
52 #include "G4SystemOfUnits.hh"
53 #include "G4PhysicsLogVector.hh"
54 #include "G4ParticleDefinition.hh"
55 #include "G4Material.hh"
56 #include "G4MaterialCutsCouple.hh"
57 #include "G4Electron.hh"
58 #include "G4Positron.hh"
59 #include "G4Proton.hh"
60 #include "G4MuonPlus.hh"
61 #include "G4MuonMinus.hh"
62 #include "G4ParticleTable.hh"
63 #include "G4LossTableBuilder.hh"
64 #include "G4MollerBhabhaModel.hh"
65 #include "G4BetheBlochModel.hh"
69 #include "G4ProductionCuts.hh"
70 #include "G4LossTableManager.hh"
71 #include "G4WentzelVIModel.hh"
72 
73 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
74 
76  :maxEnergyTransfer(DBL_MAX),verbose(verb),isInitialised(false)
77 {
78  currentParticle = 0;
79  currentMaterial = 0;
80 
81  linLossLimit = 0.01;
82  emin = 1.*MeV;
83  emax = 10.*TeV;
84  nbins = 70;
85 
86  nmat = index = 0;
87  pcuts = 0;
88 
90  = kineticEnergy = tmax = 0;
91  gam = 1.0;
92 
96 
98 }
99 
100 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
101 
103 {
104  for(G4int i=0; i<nmat; i++) {delete couples[i];}
105  delete dedxElectron;
106  delete dedxPositron;
107  delete dedxProton;
108  delete dedxMuon;
109  delete rangeElectron;
110  delete rangePositron;
111  delete rangeProton;
112  delete rangeMuon;
113  delete invRangeElectron;
114  delete invRangePositron;
115  delete invRangeProton;
116  delete invRangeMuon;
117  delete mscElectron;
118  delete pcuts;
119 }
120 
121 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
122 
123 G4double
125  G4double stepLength,
126  const G4Material* mat,
127  const G4ParticleDefinition* part)
128 {
130  G4double kinEnergyFinal = kinEnergy;
131  if(SetupKinematics(part, mat, kinEnergy)) {
132  G4double step = TrueStepLength(kinEnergy,stepLength,mat,part);
133  G4double r = ComputeRange(kinEnergy,part);
134  if(r <= step) {
135  kinEnergyFinal = 0.0;
136  } else if(step < linLossLimit*r) {
137  kinEnergyFinal -= step*ComputeDEDX(kinEnergy,part);
138  } else {
139  G4double r1 = r - step;
140  kinEnergyFinal = ComputeEnergy(r1,part);
141  }
142  }
143  return kinEnergyFinal;
144 }
145 
146 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
147 
148 G4double
150  G4double stepLength,
151  const G4Material* mat,
152  const G4ParticleDefinition* part)
153 {
154  if(!isInitialised) { Initialisation(); }
155  G4double kinEnergyFinal = kinEnergy;
156 
157  if(SetupKinematics(part, mat, kinEnergy)) {
158  G4double step = TrueStepLength(kinEnergy,stepLength,mat,part);
159  G4double r = ComputeRange(kinEnergy,part);
160 
161  if(step < linLossLimit*r) {
162  kinEnergyFinal += step*ComputeDEDX(kinEnergy,part);
163  } else {
164  G4double r1 = r + step;
165  kinEnergyFinal = ComputeEnergy(r1,part);
166  }
167  }
168  return kinEnergyFinal;
169 }
170 
171 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
172 
173 G4double
175  G4double stepLength,
176  const G4Material* mat,
177  const G4ParticleDefinition* part)
178 {
179  G4double res = stepLength;
181  if(SetupKinematics(part, mat, kinEnergy)) {
182  if(part == electron || part == positron) {
183  G4double x = stepLength*ComputeValue(kinEnergy, mscElectron);
184  if(x < 0.2) { res *= (1.0 + 0.5*x + x*x/3.0); }
185  else if(x < 0.9999) { res = -G4Log(1.0 - x)*stepLength/x; }
186  else { res = ComputeRange(kinEnergy,part); }
187 
188  } else {
189  res = ComputeTrueStep(mat,part,kinEnergy,stepLength);
190  }
191  }
192  return res;
193 }
194 
195 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
196 
197 G4bool
199  const G4Material* mat,
200  G4double kinEnergy)
201 {
202  if(!part || !mat || kinEnergy < keV) return false;
204  G4bool flag = false;
205  if(part != currentParticle) {
206  flag = true;
207  currentParticle = part;
208  mass = part->GetPDGMass();
209  G4double q = part->GetPDGCharge()/eplus;
210  charge2 = q*q;
211  }
212  if(mat != currentMaterial) {
213  G4int i = mat->GetIndex();
214  if(i >= nmat) {
215  G4cout << "### G4EnergyLossForExtrapolator WARNING:index i= "
216  << i << " is out of table - NO extrapolation" << G4endl;
217  } else {
218  flag = true;
219  currentMaterial = mat;
221  radLength = mat->GetRadlen();
222  index = i;
223  }
224  }
225  if(flag || kinEnergy != kineticEnergy) {
226  kineticEnergy = kinEnergy;
227  G4double tau = kinEnergy/mass;
228 
229  gam = tau + 1.0;
230  bg2 = tau * (tau + 2.0);
231  beta2 = bg2/(gam*gam);
232  tmax = kinEnergy;
233  if(part == electron) tmax *= 0.5;
234  else if(part != positron) {
235  G4double r = electron_mass_c2/mass;
236  tmax = 2.0*bg2*electron_mass_c2/(1.0 + 2.0*gam*r + r*r);
237  }
239  }
240  return true;
241 }
242 
243 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
244 
246 {
247  isInitialised = true;
248  if(verbose>1) {
249  G4cout << "### G4EnergyLossForExtrapolator::Initialisation" << G4endl;
250  }
251  currentParticle = 0;
252  currentMaterial = 0;
253  kineticEnergy = 0.0;
254 
260 
261  currentParticleName = "";
262 
265  pcuts = new G4ProductionCuts();
266 
267  couples.resize(nmat,0);
268  cuts.resize(nmat,DBL_MAX);
269 
270  for(G4int i=0; i<nmat; i++) {
271  couples[i] = new G4MaterialCutsCouple((*mtable)[i],pcuts);
272  }
273 
287 
288  G4LossTableBuilder builder;
289 
290  if(verbose>1) {
291  G4cout << "### G4EnergyLossForExtrapolator Builds electron tables"
292  << G4endl;
293  }
297 
298  if(verbose>1) {
299  G4cout << "### G4EnergyLossForExtrapolator Builds positron tables"
300  << G4endl;
301  }
305 
306  if(verbose>1) {
307  G4cout << "### G4EnergyLossForExtrapolator Builds muon tables" << G4endl;
308  }
312 
313  if(verbose>1) {
314  G4cout << "### G4EnergyLossForExtrapolator Builds proton tables"
315  << G4endl;
316  }
320 
322 }
323 
324 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
325 
327 {
328  G4PhysicsTable* table = new G4PhysicsTable();
329 
330  for(G4int i=0; i<nmat; i++) {
331 
333  v->SetSpline(G4LossTableManager::Instance()->SplineFlag());
334  table->push_back(v);
335  }
336  return table;
337 }
338 
339 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
340 
341 const G4ParticleDefinition*
343 {
344  const G4ParticleDefinition* p = 0;
345  if(name != currentParticleName) {
347  if(!p) {
348  G4cout << "### G4EnergyLossForExtrapolator WARNING:FindParticle fails to find "
349  << name << G4endl;
350  }
351  } else {
352  p = currentParticle;
353  }
354  return p;
355 }
356 
357 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
358 
359 G4double
361  const G4ParticleDefinition* part)
362 {
363  G4double x = 0.0;
364  if(part == electron) x = ComputeValue(kinEnergy, dedxElectron);
365  else if(part == positron) x = ComputeValue(kinEnergy, dedxPositron);
366  else if(part == muonPlus || part == muonMinus) {
367  x = ComputeValue(kinEnergy, dedxMuon);
368  } else {
369  G4double e = kinEnergy*proton_mass_c2/mass;
371  }
372  return x;
373 }
374 
375 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
376 
377 G4double
379  const G4ParticleDefinition* part)
380 {
381  G4double x = 0.0;
382  if(part == electron) x = ComputeValue(kinEnergy, rangeElectron);
383  else if(part == positron) x = ComputeValue(kinEnergy, rangePositron);
384  else if(part == muonPlus || part == muonMinus)
385  x = ComputeValue(kinEnergy, rangeMuon);
386  else {
387  G4double massratio = proton_mass_c2/mass;
388  G4double e = kinEnergy*massratio;
389  x = ComputeValue(e, rangeProton)/(charge2*massratio);
390  }
391  return x;
392 }
393 
394 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
395 
396 G4double
398  const G4ParticleDefinition* part)
399 {
400  G4double x = 0.0;
401  if(part == electron) x = ComputeValue(range, invRangeElectron);
402  else if(part == positron) x = ComputeValue(range, invRangePositron);
403  else if(part == muonPlus || part == muonMinus)
404  x = ComputeValue(range, invRangeMuon);
405  else {
406  G4double massratio = proton_mass_c2/mass;
407  G4double r = range*massratio*charge2;
408  x = ComputeValue(r, invRangeProton)/massratio;
409  }
410  return x;
411 }
412 
413 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
414 
416  const G4ParticleDefinition* part,
417  G4PhysicsTable* table)
418 {
421  ioni->Initialise(part, cuts);
422  brem->Initialise(part, cuts);
423 
424  mass = electron_mass_c2;
425  charge2 = 1.0;
426  currentParticle = part;
427 
429  if(0<verbose) {
430  G4cout << "G4EnergyLossForExtrapolator::ComputeElectronDEDX for "
431  << part->GetParticleName()
432  << G4endl;
433  }
434  for(G4int i=0; i<nmat; i++) {
435 
436  const G4Material* mat = (*mtable)[i];
437  if(1<verbose)
438  G4cout << "i= " << i << " mat= " << mat->GetName() << G4endl;
439  const G4MaterialCutsCouple* couple = couples[i];
440  G4PhysicsVector* aVector = (*table)[i];
441 
442  for(G4int j=0; j<=nbins; j++) {
443 
444  G4double e = aVector->Energy(j);
445  G4double dedx = ioni->ComputeDEDX(couple,part,e,e)
446  + brem->ComputeDEDX(couple,part,e,e);
447  if(1<verbose) {
448  G4cout << "j= " << j
449  << " e(MeV)= " << e/MeV
450  << " dedx(Mev/cm)= " << dedx*cm/MeV
451  << " dedx(Mev.cm2/g)= "
452  << dedx/((MeV*mat->GetDensity())/(g/cm2))
453  << G4endl;
454  }
455  aVector->PutValue(j,dedx);
456  }
457  }
458  delete ioni;
459  delete brem;
460 }
461 
462 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
463 
464 void
466  G4PhysicsTable* table)
467 {
468  G4BetheBlochModel* ioni = new G4BetheBlochModel();
471  ioni->Initialise(part, cuts);
472  pair->Initialise(part, cuts);
473  brem->Initialise(part, cuts);
474 
475  mass = part->GetPDGMass();
476  charge2 = 1.0;
477  currentParticle = part;
478 
480 
481  if(0<verbose) {
482  G4cout << "G4EnergyLossForExtrapolator::ComputeMuonDEDX for "
483  << part->GetParticleName()
484  << G4endl;
485  }
486 
487  for(G4int i=0; i<nmat; i++) {
488 
489  const G4Material* mat = (*mtable)[i];
490  if(1<verbose) {
491  G4cout << "i= " << i << " mat= " << mat->GetName() << G4endl;
492  }
493  const G4MaterialCutsCouple* couple = couples[i];
494  G4PhysicsVector* aVector = (*table)[i];
495  for(G4int j=0; j<=nbins; j++) {
496 
497  G4double e = aVector->Energy(j);
498  G4double dedx = ioni->ComputeDEDX(couple,part,e,e) +
499  pair->ComputeDEDX(couple,part,e,e) +
500  brem->ComputeDEDX(couple,part,e,e);
501  aVector->PutValue(j,dedx);
502  if(1<verbose) {
503  G4cout << "j= " << j
504  << " e(MeV)= " << e/MeV
505  << " dedx(Mev/cm)= " << dedx*cm/MeV
506  << " dedx(Mev/(g/cm2)= " << dedx/((MeV*mat->GetDensity())/(g/cm2))
507  << G4endl;
508  }
509  }
510  }
511  delete ioni;
512 }
513 
514 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
515 
516 void
518  G4PhysicsTable* table)
519 {
520  G4BetheBlochModel* ioni = new G4BetheBlochModel();
521  ioni->Initialise(part, cuts);
522 
523  mass = part->GetPDGMass();
524  charge2 = 1.0;
525  currentParticle = part;
526 
528 
529  if(0<verbose) {
530  G4cout << "G4EnergyLossForExtrapolator::ComputeProtonDEDX for "
531  << part->GetParticleName()
532  << G4endl;
533  }
534 
535  for(G4int i=0; i<nmat; i++) {
536 
537  const G4Material* mat = (*mtable)[i];
538  if(1<verbose)
539  G4cout << "i= " << i << " mat= " << mat->GetName() << G4endl;
540  const G4MaterialCutsCouple* couple = couples[i];
541  G4PhysicsVector* aVector = (*table)[i];
542  for(G4int j=0; j<=nbins; j++) {
543 
544  G4double e = aVector->Energy(j);
545  G4double dedx = ioni->ComputeDEDX(couple,part,e,e);
546  aVector->PutValue(j,dedx);
547  if(1<verbose) {
548  G4cout << "j= " << j
549  << " e(MeV)= " << e/MeV
550  << " dedx(Mev/cm)= " << dedx*cm/MeV
551  << " dedx(Mev.cm2/g)= " << dedx/((mat->GetDensity())/(g/cm2))
552  << G4endl;
553  }
554  }
555  }
556  delete ioni;
557 }
558 
559 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
560 
561 void
563  G4PhysicsTable* table)
564 {
565  G4WentzelVIModel* msc = new G4WentzelVIModel();
567  msc->Initialise(part, cuts);
568 
569  mass = part->GetPDGMass();
570  charge2 = 1.0;
571  currentParticle = part;
572 
574 
575  if(0<verbose) {
576  G4cout << "G4EnergyLossForExtrapolator::ComputeProtonDEDX for "
577  << part->GetParticleName()
578  << G4endl;
579  }
580 
581  for(G4int i=0; i<nmat; i++) {
582 
583  const G4Material* mat = (*mtable)[i];
584  msc->SetCurrentCouple(couples[i]);
585  if(1<verbose)
586  G4cout << "i= " << i << " mat= " << mat->GetName() << G4endl;
587  G4PhysicsVector* aVector = (*table)[i];
588  for(G4int j=0; j<=nbins; j++) {
589 
590  G4double e = aVector->Energy(j);
591  G4double xs = msc->CrossSectionPerVolume(mat,part,e);
592  aVector->PutValue(j,xs);
593  if(1<verbose) {
594  G4cout << "j= " << j << " e(MeV)= " << e/MeV
595  << " xs(1/mm)= " << xs*mm << G4endl;
596  }
597  }
598  }
599  delete msc;
600 }
601 
602 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
603 
static const double cm
Definition: G4SIunits.hh:106
void BuildRangeTable(const G4PhysicsTable *dedxTable, G4PhysicsTable *rangeTable, G4bool isIonisation=false)
virtual G4double CrossSectionPerVolume(const G4Material *, const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy=0.0, G4double maxEnergy=DBL_MAX)
Definition: G4VEmModel.cc:245
static G4MuonPlus * MuonPlus()
Definition: G4MuonPlus.cc:99
static const double MeV
Definition: G4SIunits.hh:193
G4ParticleDefinition * FindParticle(G4int PDGEncoding)
const G4ParticleDefinition * muonMinus
static G4LossTableManager * Instance()
static const double cm2
Definition: G4SIunits.hh:107
void ComputeProtonDEDX(const G4ParticleDefinition *part, G4PhysicsTable *table)
G4bool SetupKinematics(const G4ParticleDefinition *, const G4Material *, G4double kinEnergy)
std::vector< const G4MaterialCutsCouple * > couples
void ComputeTrasportXS(const G4ParticleDefinition *part, G4PhysicsTable *table)
size_t GetIndex() const
Definition: G4Material.hh:260
G4String name
Definition: TRTMaterials.hh:40
const G4String & GetName() const
Definition: G4Material.hh:176
void push_back(G4PhysicsVector *)
const G4double pi
static G4MaterialTable * GetMaterialTable()
Definition: G4Material.cc:587
std::vector< G4Material * > G4MaterialTable
G4double GetDensity() const
Definition: G4Material.hh:178
G4double TrueStepLength(G4double kinEnergy, G4double step, const G4Material *, const G4ParticleDefinition *part)
virtual void Initialise(const G4ParticleDefinition *, const G4DataVector &)
int G4int
Definition: G4Types.hh:78
const G4String & GetParticleName() const
void SetSpline(G4bool)
const G4ParticleDefinition * FindParticle(const G4String &name)
G4double ComputeTrueStep(const G4Material *, const G4ParticleDefinition *part, G4double kinEnergy, G4double stepLength)
G4GLOB_DLL std::ostream G4cout
G4double GetElectronDensity() const
Definition: G4Material.hh:215
bool G4bool
Definition: G4Types.hh:79
void PutValue(size_t index, G4double theValue)
static G4Proton * Proton()
Definition: G4Proton.cc:93
const G4ParticleDefinition * proton
virtual void Initialise(const G4ParticleDefinition *, const G4DataVector &)
G4double ComputeDEDX(G4double kinEnergy, const G4ParticleDefinition *)
virtual void Initialise(const G4ParticleDefinition *, const G4DataVector &)
void BuildInverseRangeTable(const G4PhysicsTable *rangeTable, G4PhysicsTable *invRangeTable, G4bool isIonisation=false)
G4double Energy(size_t index) const
static size_t GetNumberOfMaterials()
Definition: G4Material.cc:594
G4double ComputeRange(G4double kinEnergy, const G4ParticleDefinition *)
G4double GetRadlen() const
Definition: G4Material.hh:218
G4double EnergyBeforeStep(G4double kinEnergy, G4double step, const G4Material *, const G4ParticleDefinition *)
G4double EnergyAfterStep(G4double kinEnergy, G4double step, const G4Material *, const G4ParticleDefinition *)
G4double G4Log(G4double x)
Definition: G4Log.hh:230
void ComputeMuonDEDX(const G4ParticleDefinition *part, G4PhysicsTable *table)
static G4Positron * Positron()
Definition: G4Positron.cc:94
void ComputeElectronDEDX(const G4ParticleDefinition *part, G4PhysicsTable *table)
const G4ParticleDefinition * muonPlus
G4double ComputeDEDX(const G4MaterialCutsCouple *, const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy=DBL_MAX)
Definition: G4VEmModel.hh:456
G4double GetPDGMass() const
virtual void Initialise(const G4ParticleDefinition *, const G4DataVector &)
static G4ParticleTable * GetParticleTable()
void SetCurrentCouple(const G4MaterialCutsCouple *)
Definition: G4VEmModel.hh:419
static const double g
Definition: G4SIunits.hh:162
const G4ParticleDefinition * electron
G4double ComputeEnergy(G4double range, const G4ParticleDefinition *)
static G4MuonMinus * MuonMinus()
Definition: G4MuonMinus.cc:100
static G4Electron * Electron()
Definition: G4Electron.cc:94
#define G4endl
Definition: G4ios.hh:61
static const double TeV
Definition: G4SIunits.hh:197
virtual void Initialise(const G4ParticleDefinition *, const G4DataVector &)
static const double keV
Definition: G4SIunits.hh:195
const G4ParticleDefinition * positron
double G4double
Definition: G4Types.hh:76
static const double eplus
Definition: G4SIunits.hh:178
G4double ComputeValue(G4double x, const G4PhysicsTable *table)
G4double GetPDGCharge() const
#define DBL_MAX
Definition: templates.hh:83
static const double mm
Definition: G4SIunits.hh:102
void SetPolarAngleLimit(G4double)
Definition: G4VEmModel.hh:718
const G4ParticleDefinition * currentParticle
virtual void Initialise(const G4ParticleDefinition *, const G4DataVector &)