Geant4  10.01.p01
G4PAIModelData.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: G4PAIModelData.cc 72008 2013-07-03 08:46:39Z vnivanch $
27 //
28 // -------------------------------------------------------------------
29 //
30 // GEANT4 Class
31 // File name: G4PAIModelData.cc
32 //
33 // Author: V. Ivanchenko based on V.Grichine code of G4PAIModel
34 //
35 // Creation date: 16.08.2013
36 //
37 // Modifications:
38 //
39 
40 #include "G4PAIModelData.hh"
41 #include "G4PAIModel.hh"
42 
43 #include "G4SystemOfUnits.hh"
44 #include "G4PhysicalConstants.hh"
45 
46 #include "G4PhysicsLogVector.hh"
47 #include "G4PhysicsFreeVector.hh"
48 #include "G4PhysicsTable.hh"
49 #include "G4MaterialCutsCouple.hh"
50 #include "G4SandiaTable.hh"
51 #include "Randomize.hh"
52 #include "G4Poisson.hh"
53 
55 
56 using namespace std;
57 
59 {
60  const G4int nPerDecade = 10;
61  const G4double lowestTkin = 50*keV;
62  const G4double highestTkin = 10*TeV;
63 
64  fPAIySection.SetVerbose(ver);
65 
66  fLowestKineticEnergy = std::max(tmin, lowestTkin);
67  fHighestKineticEnergy = tmax;
68  if(tmax < 10*fLowestKineticEnergy) {
69  fHighestKineticEnergy = 10*fLowestKineticEnergy;
70  } else if(tmax > highestTkin) {
71  fHighestKineticEnergy = std::max(highestTkin, 10*fLowestKineticEnergy);
72  }
73  fTotBin = (G4int)(nPerDecade*
74  std::log10(fHighestKineticEnergy/fLowestKineticEnergy));
75 
76  fParticleEnergyVector = new G4PhysicsLogVector(fLowestKineticEnergy,
77  fHighestKineticEnergy,
78  fTotBin);
79  if(0 < ver) {
80  G4cout << "### G4PAIModelData: Nbins= " << fTotBin
81  << " Tlowest(MeV)= " << fLowestKineticEnergy/MeV
82  << " Tmin(keV)= " << tmin/keV
83  << " Tmax(GeV)= " << fHighestKineticEnergy/GeV
84  << G4endl;
85  }
86 }
87 
89 
91 {
92  size_t n = fPAIxscBank.size();
93  if(0 < n) {
94  for(size_t i=0; i<n; ++i) {
95  if(fPAIxscBank[i]) {
96  fPAIxscBank[i]->clearAndDestroy();
97  delete fPAIxscBank[i];
98  }
99  if(fPAIdEdxBank[i]) {
100  fPAIdEdxBank[i]->clearAndDestroy();
101  delete fPAIdEdxBank[i];
102  }
103  delete fdEdxTable[i];
104  delete fdNdxCutTable[i];
105  delete fdEdxCutTable[i];
106  }
107  }
108  delete fParticleEnergyVector;
109 }
110 
112 
114  G4double cut, G4PAIModel* model)
115 {
116  const G4Material* mat = couple->GetMaterial();
117  fSandia.Initialize(const_cast<G4Material*>(mat));
118 
119  G4PhysicsTable* PAItransferTable = new G4PhysicsTable(fTotBin+1);
120  G4PhysicsTable* PAIdEdxTable = new G4PhysicsTable(fTotBin+1);
121 
122  G4PhysicsLogVector* dEdxCutVector =
123  new G4PhysicsLogVector(fLowestKineticEnergy,
124  fHighestKineticEnergy,
125  fTotBin);
126 
127  G4PhysicsLogVector* dEdxMeanVector =
128  new G4PhysicsLogVector(fLowestKineticEnergy,
129  fHighestKineticEnergy,
130  fTotBin);
131 
132  G4PhysicsLogVector* dNdxCutVector =
133  new G4PhysicsLogVector(fLowestKineticEnergy,
134  fHighestKineticEnergy,
135  fTotBin);
136 
137  // low energy Sandia interval
138  G4double Tmin = fSandia.GetSandiaMatTablePAI(0,0);
139 
140  // energy safety
141  const G4double deltaLow = 100.*eV;
142 
143  for (G4int i = 0; i <= fTotBin; ++i) {
144 
145  G4double kinEnergy = fParticleEnergyVector->Energy(i);
146  G4double Tmax = model->ComputeMaxEnergy(kinEnergy);
147  G4double tau = kinEnergy/proton_mass_c2;
148  G4double bg2 = tau*( tau + 2. );
149 
150  if (Tmax < Tmin + deltaLow ) { Tmax = Tmin + deltaLow; }
151 
152  fPAIySection.Initialize(mat, Tmax, bg2, &fSandia);
153  /*
154  G4cout << i << ". TransferMax(keV)= "<< Tmax/keV << " cut(keV)= "
155  << cut/keV << " E(MeV)= " << kinEnergy/MeV << G4endl;
156  */
157  G4int n = fPAIySection.GetSplineSize();
158  G4int kmin = 0;
159  for(G4int k = 0; k < n; ++k) {
160  if(fPAIySection.GetIntegralPAIySection(k+1) <= 0.0) {
161  kmin = k;
162  } else {
163  break;
164  }
165  }
166  n -= kmin;
167 
168  G4PhysicsFreeVector* transferVector = new G4PhysicsFreeVector(n);
169  G4PhysicsFreeVector* dEdxVector = new G4PhysicsFreeVector(n);
170 
171  //G4double tr0 = 0.0;
172  G4double tr = 0.0;
173  for(G4int k = kmin; k < n; ++k)
174  {
175  G4double t = fPAIySection.GetSplineEnergy(k+1);
176  tr = fPAIySection.GetIntegralPAIySection(k+1);
177  //if(tr >= tr0) { tr0 = tr; }
178  //else { G4cout << "G4PAIModelData::Initialise Warning: Ekin(MeV)= "
179  // << t/MeV << " IntegralTransfer= " << tr
180  // << " < " << tr0 << G4endl; }
181  transferVector->PutValue(k , t, t*tr);
182  dEdxVector->PutValue(k, t, fPAIySection.GetIntegralPAIdEdx(k+1));
183  }
184  //G4cout << *transferVector << G4endl;
185 
186  G4double ionloss = fPAIySection.GetMeanEnergyLoss();// total <dE/dx>
187 
188  if(ionloss < 0.0) ionloss = 0.0;
189 
190  dEdxMeanVector->PutValue(i,ionloss);
191 
192  G4double dNdxCut = transferVector->Value(cut)/cut;
193  G4double dEdxCut = dEdxVector->Value(cut);
194  //G4cout << "i= " << i << " x= " << dNdxCut << G4endl;
195  if(dNdxCut < 0.0) { dNdxCut = 0.0; }
196  if(dEdxCut < 0.0) { dEdxCut = 0.0; }
197  dNdxCutVector->PutValue(i, dNdxCut);
198  dEdxCutVector->PutValue(i, dEdxCut);
199 
200  PAItransferTable->insertAt(i,transferVector);
201  PAIdEdxTable->insertAt(i,dEdxVector);
202 
203  //transferVector->SetSpline(true);
204  //transferVector->FillSecondDerivatives();
205  //dEdxVector->SetSpline(true);
206  //dEdxVector->FillSecondDerivatives();
207 
208  } // end of Tkin loop`
209  fPAIxscBank.push_back(PAItransferTable);
210  fPAIdEdxBank.push_back(PAIdEdxTable);
211  /*
212  dEdxMeanVector->SetSpline(true);
213  dEdxMeanVector->FillSecondDerivatives();
214  dNdxCutVector->SetSpline(true);
215  dNdxCutVector->FillSecondDerivatives();
216  dEdxCutVector->SetSpline(true);
217  dEdxCutVector->FillSecondDerivatives();
218  */
219  fdEdxTable.push_back(dEdxMeanVector);
220  fdNdxCutTable.push_back(dNdxCutVector);
221  fdEdxCutTable.push_back(dEdxCutVector);
222 }
223 
225 
227  G4double cut) const
228 {
229  // VI: iPlace is the low edge index of the bin
230  // iPlace is in interval from 0 to (N-1)
231  size_t iPlace = fParticleEnergyVector->FindBin(scaledTkin, 0);
232  size_t nPlace = fParticleEnergyVector->GetVectorLength() - 1;
233 
234  G4bool one = true;
235  if(scaledTkin >= fParticleEnergyVector->Energy(nPlace)) { iPlace = nPlace; }
236  else if(scaledTkin > fParticleEnergyVector->Energy(0)) {
237  one = false;
238  }
239 
240  // VI: apply interpolation of the vector
241  G4double dEdx = fdEdxTable[coupleIndex]->Value(scaledTkin);
242  G4double del = (*(fPAIdEdxBank[coupleIndex]))(iPlace)->Value(cut);
243  if(!one) {
244  G4double del2 = (*(fPAIdEdxBank[coupleIndex]))(iPlace+1)->Value(cut);
245  G4double E1 = fParticleEnergyVector->Energy(iPlace);
246  G4double E2 = fParticleEnergyVector->Energy(iPlace+1);
247  G4double W = 1.0/(E2 - E1);
248  G4double W1 = (E2 - scaledTkin)*W;
249  G4double W2 = (scaledTkin - E1)*W;
250  del *= W1;
251  del += W2*del2;
252  }
253  dEdx -= del;
254 
255  if( dEdx < 0.) { dEdx = 0.; }
256  return dEdx;
257 }
258 
260 
261 G4double
263  G4double scaledTkin,
264  G4double tcut, G4double tmax) const
265 {
266  G4double cross, cross1, cross2;
267 
268  // iPlace is in interval from 0 to (N-1)
269  size_t iPlace = fParticleEnergyVector->FindBin(scaledTkin, 0);
270  size_t nPlace = fParticleEnergyVector->GetVectorLength() - 1;
271 
272  G4bool one = true;
273  if(scaledTkin >= fParticleEnergyVector->Energy(nPlace)) { iPlace = nPlace; }
274  else if(scaledTkin > fParticleEnergyVector->Energy(0)) {
275  one = false;
276  }
277  G4PhysicsTable* table = fPAIxscBank[coupleIndex];
278 
279  //G4cout<<"iPlace = "<<iPlace<<"; tmax = "
280  // <<tmax<<"; cutEnergy = "<<cutEnergy<<G4endl;
281  cross1 = (*table)(iPlace)->Value(tmax)/tmax;
282  //G4cout<<"cross1 = "<<cross1<<G4endl;
283  cross2 = (*table)(iPlace)->Value(tcut)/tcut;
284  //G4cout<<"cross2 = "<<cross2<<G4endl;
285  cross = (cross2-cross1);
286  //G4cout<<"cross = "<<cross<<G4endl;
287  if(!one) {
288  cross2 = (*table)(iPlace+1)->Value(tcut)/tcut
289  - (*table)(iPlace+1)->Value(tmax)/tmax;
290 
291  G4double E1 = fParticleEnergyVector->Energy(iPlace);
292  G4double E2 = fParticleEnergyVector->Energy(iPlace+1);
293  G4double W = 1.0/(E2 - E1);
294  G4double W1 = (E2 - scaledTkin)*W;
295  G4double W2 = (scaledTkin - E1)*W;
296  cross *= W1;
297  cross += W2*cross2;
298  }
299 
300  if( cross < 0.0) { cross = 0.0; }
301  return cross;
302 }
303 
305 
307  G4double kinEnergy,
308  G4double scaledTkin,
309  G4double stepFactor) const
310 {
311  G4double loss = 0.0;
312  G4double omega;
313  G4double position, E1, E2, W1, W2, W, dNdxCut1, dNdxCut2, meanNumber;
314 
315  size_t iPlace = fParticleEnergyVector->FindBin(scaledTkin, 0);
316  size_t nPlace = fParticleEnergyVector->GetVectorLength() - 1;
317 
318  G4bool one = true;
319  if(scaledTkin >= fParticleEnergyVector->Energy(nPlace)) { iPlace = nPlace; }
320  else if(scaledTkin > fParticleEnergyVector->Energy(0)) {
321  one = false;
322  }
323  G4PhysicsLogVector* vcut = fdNdxCutTable[coupleIndex];
324  G4PhysicsVector* v1 = (*(fPAIxscBank[coupleIndex]))(iPlace);
325  G4PhysicsVector* v2 = 0;
326 
327  dNdxCut1 = (*vcut)[iPlace];
328  G4double e1 = v1->Energy(0);
329  G4double e2 = e1;
330 
331  G4double meanN1 = ((*v1)[0]/e1 - dNdxCut1)*stepFactor;
332  meanNumber = meanN1;
333 
334  //G4cout<<"iPlace = "<<iPlace<< " meanN1= " << meanN1
335  // << " dNdxCut1= " << dNdxCut1 << G4endl;
336 
337  dNdxCut2 = dNdxCut1;
338  W1 = 1.0;
339  W2 = 0.0;
340  if(!one) {
341  v2 = (*(fPAIxscBank[coupleIndex]))(iPlace+1);
342  dNdxCut2 = (*vcut)[iPlace+1];
343  e2 = v2->Energy(0);
344  G4double meanN2 = ((*v2)[0]/e2 - dNdxCut2)*stepFactor;
345  E1 = fParticleEnergyVector->Energy(iPlace);
346  E2 = fParticleEnergyVector->Energy(iPlace+1);
347  W = 1.0/(E2 - E1);
348  W1 = (E2 - scaledTkin)*W;
349  W2 = (scaledTkin - E1)*W;
350  meanNumber = W1*meanN1 + W2*meanN2;
351  //G4cout<<"meanN= " << meanNumber << " meanN2= " << meanN2
352  // << " dNdxCut2= " << dNdxCut2 << G4endl;
353  }
354  if(meanNumber < 0.0) { return 0.0; }
355 
356  G4int numOfCollisions = G4Poisson(meanNumber);
357 
358  //G4cout << "N= " << numOfCollisions << G4endl;
359 
360  if(0 == numOfCollisions) { return 0.0; }
361 
362  for(G4int i=0; i< numOfCollisions; ++i) {
363  G4double rand = G4UniformRand();
364  position = dNdxCut1 + ((*v1)[0]/e1 - dNdxCut1)*rand;
365  omega = GetEnergyTransfer(coupleIndex, iPlace, position);
366  //G4cout << "omega(keV)= " << omega/keV << G4endl;
367  if(!one) {
368  position = dNdxCut2 + ((*v2)[0]/e2 - dNdxCut2)*rand;
369  G4double omega2 = GetEnergyTransfer(coupleIndex, iPlace+1, position);
370  omega = omega*W1 + omega2*W2;
371  }
372  //G4cout << "omega(keV)= " << omega/keV << G4endl;
373 
374  loss += omega;
375  if(loss > kinEnergy) { break; }
376  }
377 
378  // G4cout<<"PAIModelData AlongStepLoss = "<<loss/keV<<" keV, on step = "
379  //<<step/mm<<" mm"<<G4endl;
380  if(loss > kinEnergy) { loss = kinEnergy; }
381  else if(loss < 0.) { loss = 0.; }
382  return loss;
383 }
384 
386 //
387 // Returns post step PAI energy transfer > cut electron energy
388 // according to passed scaled kinetic energy of particle
389 
391  G4double scaledTkin,
392  G4double tmax) const
393 {
394  //G4cout<<"G4PAIModelData::GetPostStepTransfer idx= "<< coupleIndex
395  // << " Tkin= " << scaledTkin << " Tmax= " << tmax << G4endl;
396  G4double transfer = 0.0;
397  G4double rand = G4UniformRand();
398 
399  size_t nPlace = fParticleEnergyVector->GetVectorLength() - 1;
400  size_t iPlace = fParticleEnergyVector->FindBin(scaledTkin, 0);
401 
402  G4bool one = true;
403  if(scaledTkin >= fParticleEnergyVector->Energy(nPlace)) { iPlace = nPlace; }
404  else if(scaledTkin > fParticleEnergyVector->Energy(0)) {
405  one = false;
406  }
407  G4PhysicsTable* table = fPAIxscBank[coupleIndex];
408  G4PhysicsLogVector* vcut = fdNdxCutTable[coupleIndex];
409  G4PhysicsVector* v1 = (*table)[iPlace];
410 
412 
413  //G4cout << *v1 << G4endl;
414 
415  G4double dNdxCut1 = (*vcut)[iPlace];
416  G4double emax = std::min(tmax, v1->GetMaxEnergy());
417  G4double dNdxCutM = v1->Value(emax)/emax;
418  /*
419  G4cout << "iPlace= " << iPlace << " nPlace= " << nPlace << " emax= " << emax
420  << " dNdxCut1= " << dNdxCut1 << " dNdxCutM= " << dNdxCutM
421  << " one= " << one << G4endl;
422  */
423  if(one) {
424  position = dNdxCutM + (dNdxCut1 - dNdxCutM)*rand;
425  transfer = GetEnergyTransfer(coupleIndex, iPlace, position);
426 
427  //G4cout<<"PAImodel PostStepTransfer = "<<transfer/keV<<" keV"
428  // << " position= " << position << G4endl;
429 
430  } else {
431 
432  G4double E1, E2, W1, W2, W;
433  G4double dNdxCut2 = (*vcut)[iPlace+1];
434  G4PhysicsVector* v2 = (*table)[iPlace+1];
435  emax = std::min(tmax, v2->GetMaxEnergy());
436  G4double dNdxCutM2 = v2->Value(emax)/emax;
437 
438  //G4cout << " emax2= " << emax
439  // << " dNdxCut2= " << dNdxCut2 << " dNdxCutM2= " << dNdxCutM2 << G4endl;
440 
441  E1 = fParticleEnergyVector->Energy(iPlace);
442  E2 = fParticleEnergyVector->Energy(iPlace+1);
443  W = 1.0/(E2 - E1);
444  W1 = (E2 - scaledTkin)*W;
445  W2 = (scaledTkin - E1)*W;
446  /*
447  G4cout<< "E1= " << E1 << " E2= " << E2 <<" iPlace= " << iPlace
448  << " dNdxCut1 = "<<dNdxCut1 <<" dNdxCut2 = "<<dNdxCut2
449  << " W1= " << W1 << " W2= " << W2 <<G4endl;
450  */
451  position = dNdxCutM + (dNdxCut1 - dNdxCutM)*rand;
452  G4double tr1 = 0.0;
453  if(position > 0.0) {
454  tr1 = GetEnergyTransfer(coupleIndex, iPlace, position);
455  }
456  //G4cout<<"PAImodel PostStepTransfer1 = "<<tr1/keV<<" keV"
457  // << " position= " << position << G4endl;
458 
459  position = dNdxCutM2 + (dNdxCut2 - dNdxCutM2)*rand;
460  G4double tr2 = GetEnergyTransfer(coupleIndex, iPlace+1, position);
461  //G4cout<<"PAImodel PostStepTransfer2 = "<<tr2/keV<<" keV"
462  // << " position= " << position << G4endl;
463 
464  transfer = tr1*W1 + tr2*W2;
465  }
466  //G4cout<<"PAImodel PostStepTransfer = "<<transfer/keV<<" keV"
467  // << " position= " << position << G4endl;
468  if(transfer < 0.0 ) { transfer = 0.0; }
469  return transfer;
470 }
471 
473 //
474 // Returns PAI energy transfer according to passed
475 // indexes of particle kinetic enegry and random x-section
476 
478  size_t iPlace,
479  G4double position) const
480 {
481  G4PhysicsVector* v = (*(fPAIxscBank[coupleIndex]))(iPlace);
482  if(position*v->Energy(0) >= (*v)[0]) { return v->Energy(0); }
483 
484  size_t iTransferMax = v->GetVectorLength() - 1;
485 
486  size_t iTransfer;
487  G4double x1(0.0), x2(0.0), y1(0.0), y2(0.0), energyTransfer;
488 
489  //G4cout << "iPlace= " << iPlace << " iTransferMax= " << iTransferMax << G4endl;
490  for(iTransfer=1; iTransfer<=iTransferMax; ++iTransfer) {
491  x2 = v->Energy(iTransfer);
492  y2 = (*v)[iTransfer]/x2;
493  if(position >= y2) { break; }
494  if(iTransfer == iTransferMax) { return v->GetMaxEnergy(); }
495  }
496 
497  x1 = v->Energy(iTransfer-1);
498  y1 = (*v)[iTransfer-1]/x1;
499  /*
500  G4cout << "i= " << iTransfer << " imax= " << iTransferMax
501  << " x1= " << x1 << " x2= " << x2 << G4endl;
502  */
503  energyTransfer = x1;
504  if ( x1 != x2 ) {
505  if ( y1 == y2 ) {
506  energyTransfer += (x2 - x1)*G4UniformRand();
507  } else {
508  if(x1*1.1 < x2) {
509  const G4int nbins = 5;
510  G4double del = (x2 - x1)/G4int(nbins);
511  x2 = x1;
512  for(G4int i=1; i<=nbins; ++i) {
513  x2 += del;
514  y2 = v->Value(x2)/x2;
515  if(position >= y2) { break; }
516  x1 = x2;
517  y1 = y2;
518  }
519  }
520  //G4cout << "x1(keV)= " << x1/keV << " x2(keV)= " << x2/keV
521  // << " y1= " << y1 << " y2= " << y2 << " pos= " << position << G4endl;
522  energyTransfer = (y2 - y1)*x1*x2/(position*(x1 - x2) - y1*x1 + y2*x2);
523  }
524  }
525  // G4cout << "x1(keV)= " << x1/keV << " x2(keV)= " << x2/keV
526  // << " y1= " << y1 << " y2= " << y2 << " pos= " << position
527  // << " E(keV)= " << energyTransfer/keV << G4endl;
528  return energyTransfer;
529 }
530 
532 
static const double MeV
Definition: G4SIunits.hh:193
G4long G4Poisson(G4double mean)
Definition: G4Poisson.hh:51
G4double GetMaxEnergy() const
void PutValue(size_t binNumber, G4double binValue, G4double dataValue)
G4double GetEnergyTransfer(G4int coupleIndex, size_t iPlace, G4double position) const
static const G4double e2
size_t GetVectorLength() const
int G4int
Definition: G4Types.hh:78
G4double SampleAlongStepTransfer(G4int coupleIndex, G4double kinEnergy, G4double scaledTkin, G4double stepFactor) const
G4double SamplePostStepTransfer(G4int coupleIndex, G4double scaledTkin, G4double scaledTmax) const
G4double DEDXPerVolume(G4int coupleIndex, G4double scaledTkin, G4double cut) const
#define position
Definition: xmlparse.cc:605
#define G4UniformRand()
Definition: Randomize.hh:95
G4GLOB_DLL std::ostream G4cout
bool G4bool
Definition: G4Types.hh:79
void PutValue(size_t index, G4double theValue)
static const double GeV
Definition: G4SIunits.hh:196
const G4int n
G4double Energy(size_t index) const
G4double Value(G4double theEnergy, size_t &lastidx) const
static const G4double e1
G4double CrossSectionPerVolume(G4int coupleIndex, G4double scaledTkin, G4double tcut, G4double tmax) const
static const double eV
Definition: G4SIunits.hh:194
T max(const T t1, const T t2)
brief Return the largest of the two arguments
void Initialise(const G4MaterialCutsCouple *, G4double cut, G4PAIModel *)
T min(const T t1, const T t2)
brief Return the smallest of the two arguments
void insertAt(size_t, G4PhysicsVector *)
#define G4endl
Definition: G4ios.hh:61
static const double TeV
Definition: G4SIunits.hh:197
static const double keV
Definition: G4SIunits.hh:195
double G4double
Definition: G4Types.hh:76
G4PAIModelData(G4double tmin, G4double tmax, G4int verbose)
G4double ComputeMaxEnergy(G4double scaledEnergy)
Definition: G4PAIModel.hh:158
const G4Material * GetMaterial() const