Geant4  10.03.p01
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
G4PAIModelData Class Reference

#include <G4PAIModelData.hh>

Public Member Functions

 G4PAIModelData (G4double tmin, G4double tmax, G4int verbose)
 
 ~G4PAIModelData ()
 
void Initialise (const G4MaterialCutsCouple *, G4PAIModel *)
 
G4double DEDXPerVolume (G4int coupleIndex, G4double scaledTkin, G4double cut) const
 
G4double CrossSectionPerVolume (G4int coupleIndex, G4double scaledTkin, G4double tcut, G4double tmax) const
 
G4double SampleAlongStepTransfer (G4int coupleIndex, G4double kinEnergy, G4double scaledTkin, G4double tmax, G4double stepFactor) const
 
G4double SamplePostStepTransfer (G4int coupleIndex, G4double scaledTkin, G4double tmin, G4double tmax) const
 

Detailed Description

Definition at line 68 of file G4PAIModelData.hh.

Constructor & Destructor Documentation

G4PAIModelData::G4PAIModelData ( G4double  tmin,
G4double  tmax,
G4int  verbose 
)
explicit

Definition at line 58 of file G4PAIModelData.cc.

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(keV)= " << lowestTkin/keV
82  << " Tmin(keV)= " << fLowestKineticEnergy/keV
83  << " Tmax(GeV)= " << fHighestKineticEnergy/GeV
84  << G4endl;
85  }
86 }
int G4int
Definition: G4Types.hh:78
static constexpr double TeV
Definition: G4SIunits.hh:218
G4GLOB_DLL std::ostream G4cout
void SetVerbose(G4int v)
T max(const T t1, const T t2)
brief Return the largest of the two arguments
static constexpr double GeV
Definition: G4SIunits.hh:217
#define G4endl
Definition: G4ios.hh:61
double G4double
Definition: G4Types.hh:76
static constexpr double keV
Definition: G4SIunits.hh:216

Here is the call graph for this function:

G4PAIModelData::~G4PAIModelData ( )

Definition at line 90 of file G4PAIModelData.cc.

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  }
105  }
106  delete fParticleEnergyVector;
107 }

Member Function Documentation

G4double G4PAIModelData::CrossSectionPerVolume ( G4int  coupleIndex,
G4double  scaledTkin,
G4double  tcut,
G4double  tmax 
) const

Definition at line 245 of file G4PAIModelData.cc.

248 {
249  G4double cross, cross1, cross2;
250 
251  // iPlace is in interval from 0 to (N-1)
252  size_t iPlace = fParticleEnergyVector->FindBin(scaledTkin, 0);
253  size_t nPlace = fParticleEnergyVector->GetVectorLength() - 1;
254 
255  G4bool one = true;
256  if(scaledTkin >= fParticleEnergyVector->Energy(nPlace)) { iPlace = nPlace; }
257  else if(scaledTkin > fParticleEnergyVector->Energy(0)) {
258  one = false;
259  }
260  G4PhysicsTable* table = fPAIxscBank[coupleIndex];
261 
262  //G4cout<<"iPlace = "<<iPlace<<"; tmax = "
263  // <<tmax<<"; cutEnergy = "<<cutEnergy<<G4endl;
264  cross1 = (*table)(iPlace)->Value(tmax)/tmax;
265  //G4cout<<"cross1 = "<<cross1<<G4endl;
266  cross2 = (*table)(iPlace)->Value(tcut)/tcut;
267  //G4cout<<"cross2 = "<<cross2<<G4endl;
268  cross = (cross2-cross1);
269  //G4cout<<"cross = "<<cross<<G4endl;
270  if(!one) {
271  cross2 = (*table)(iPlace+1)->Value(tcut)/tcut
272  - (*table)(iPlace+1)->Value(tmax)/tmax;
273 
274  G4double E1 = fParticleEnergyVector->Energy(iPlace);
275  G4double E2 = fParticleEnergyVector->Energy(iPlace+1);
276  G4double W = 1.0/(E2 - E1);
277  G4double W1 = (E2 - scaledTkin)*W;
278  G4double W2 = (scaledTkin - E1)*W;
279  cross *= W1;
280  cross += W2*cross2;
281  }
282 
283  cross = std::max(cross, 0.0);
284  return cross;
285 }
size_t GetVectorLength() const
bool G4bool
Definition: G4Types.hh:79
size_t FindBin(G4double energy, size_t idx) const
G4double Energy(size_t index) const
T max(const T t1, const T t2)
brief Return the largest of the two arguments
double G4double
Definition: G4Types.hh:76

Here is the call graph for this function:

Here is the caller graph for this function:

G4double G4PAIModelData::DEDXPerVolume ( G4int  coupleIndex,
G4double  scaledTkin,
G4double  cut 
) const

Definition at line 203 of file G4PAIModelData.cc.

205 {
206  // VI: iPlace is the low edge index of the bin
207  // iPlace is in interval from 0 to (N-1)
208  size_t iPlace = fParticleEnergyVector->FindBin(scaledTkin, 0);
209  size_t nPlace = fParticleEnergyVector->GetVectorLength() - 1;
210  /*
211  G4cout << "G4PAIModelData::DEDXPerVolume: coupleIdx= " << coupleIndex
212  << " Tscaled= " << scaledTkin << " cut= " << cut
213  << " iPlace= " << iPlace << " nPlace= " << nPlace << G4endl;
214  */
215  G4bool one = true;
216  if(scaledTkin >= fParticleEnergyVector->Energy(nPlace)) { iPlace = nPlace; }
217  else if(scaledTkin > fParticleEnergyVector->Energy(0)) {
218  one = false;
219  }
220 
221  // VI: apply interpolation of the vector
222  G4double dEdx = fdEdxTable[coupleIndex]->Value(scaledTkin);
223  G4double del = (*(fPAIdEdxBank[coupleIndex]))(iPlace)->Value(cut);
224  //G4cout << "dEdx= " << dEdx << " del= " << del << G4endl;
225  if(!one) {
226  G4double del2 = (*(fPAIdEdxBank[coupleIndex]))(iPlace+1)->Value(cut);
227  G4double E1 = fParticleEnergyVector->Energy(iPlace);
228  G4double E2 = fParticleEnergyVector->Energy(iPlace+1);
229  G4double W = 1.0/(E2 - E1);
230  G4double W1 = (E2 - scaledTkin)*W;
231  G4double W2 = (scaledTkin - E1)*W;
232  del *= W1;
233  del += W2*del2;
234  }
235  dEdx -= del;
236  //G4cout << "dEdx= " << dEdx << " del= " << del << G4endl;
237 
238  dEdx = std::max(dEdx, 0.);
239  return dEdx;
240 }
size_t GetVectorLength() const
bool G4bool
Definition: G4Types.hh:79
size_t FindBin(G4double energy, size_t idx) const
G4double Energy(size_t index) const
T max(const T t1, const T t2)
brief Return the largest of the two arguments
double G4double
Definition: G4Types.hh:76

Here is the call graph for this function:

Here is the caller graph for this function:

void G4PAIModelData::Initialise ( const G4MaterialCutsCouple couple,
G4PAIModel model 
)

Definition at line 111 of file G4PAIModelData.cc.

113 {
114  const G4Material* mat = couple->GetMaterial();
115  fSandia.Initialize(const_cast<G4Material*>(mat));
116 
117  G4PhysicsTable* PAItransferTable = new G4PhysicsTable(fTotBin+1);
118  G4PhysicsTable* PAIdEdxTable = new G4PhysicsTable(fTotBin+1);
119  G4PhysicsLogVector* dEdxMeanVector =
120  new G4PhysicsLogVector(fLowestKineticEnergy,
121  fHighestKineticEnergy,
122  fTotBin);
123  // low energy Sandia interval
124  G4double Tmin = fSandia.GetSandiaMatTablePAI(0,0);
125 
126  // energy safety
127  static const G4double deltaLow = 100.*eV;
128 
129  for (G4int i = 0; i <= fTotBin; ++i) {
130 
131  G4double kinEnergy = fParticleEnergyVector->Energy(i);
132  G4double Tmax = model->ComputeMaxEnergy(kinEnergy);
133  G4double tau = kinEnergy/proton_mass_c2;
134  G4double bg2 = tau*( tau + 2. );
135 
136  if (Tmax < Tmin + deltaLow ) { Tmax = Tmin + deltaLow; }
137 
138  fPAIySection.Initialize(mat, Tmax, bg2, &fSandia);
139 
140  //G4cout << i << ". TransferMax(keV)= "<< Tmax/keV
141  // << " E(MeV)= " << kinEnergy/MeV << G4endl;
142 
143  G4int n = fPAIySection.GetSplineSize();
144  G4int kmin = 0;
145  for(G4int k = 0; k < n; ++k) {
146  if(fPAIySection.GetIntegralPAIySection(k+1) <= 0.0) {
147  kmin = k;
148  } else {
149  break;
150  }
151  }
152  n -= kmin;
153 
154  G4PhysicsFreeVector* transferVector = new G4PhysicsFreeVector(n);
155  G4PhysicsFreeVector* dEdxVector = new G4PhysicsFreeVector(n);
156 
157  //G4double tr0 = 0.0;
158  G4double tr = 0.0;
159  for(G4int k = kmin; k < n; ++k)
160  {
161  G4double t = fPAIySection.GetSplineEnergy(k+1);
162  tr = fPAIySection.GetIntegralPAIySection(k+1);
163  //if(tr >= tr0) { tr0 = tr; }
164  //else { G4cout << "G4PAIModelData::Initialise Warning: Ekin(MeV)= "
165  // << t/MeV << " IntegralTransfer= " << tr
166  // << " < " << tr0 << G4endl; }
167  transferVector->PutValue(k, t, t*tr);
168  dEdxVector->PutValue(k, t, fPAIySection.GetIntegralPAIdEdx(k+1));
169  }
170  //G4cout << "TransferVector:" << G4endl;
171  //G4cout << *transferVector << G4endl;
172  //G4cout << "DEDXVector:" << G4endl;
173  //G4cout << *dEdxVector << G4endl;
174 
175  G4double ionloss = fPAIySection.GetMeanEnergyLoss();// total <dE/dx>
176 
177  if(ionloss < 0.0) ionloss = 0.0;
178 
179  dEdxMeanVector->PutValue(i,ionloss);
180 
181  PAItransferTable->insertAt(i,transferVector);
182  PAIdEdxTable->insertAt(i,dEdxVector);
183 
184  //transferVector->SetSpline(true);
185  //transferVector->FillSecondDerivatives();
186  //dEdxVector->SetSpline(true);
187  //dEdxVector->FillSecondDerivatives();
188 
189  } // end of Tkin loop`
190  fPAIxscBank.push_back(PAItransferTable);
191  fPAIdEdxBank.push_back(PAIdEdxTable);
192  //G4cout << "dEdxMeanVector: " << G4endl;
193  //G4cout << *dEdxMeanVector << G4endl;
194  /*
195  dEdxMeanVector->SetSpline(true);
196  dEdxMeanVector->FillSecondDerivatives();
197  */
198  fdEdxTable.push_back(dEdxMeanVector);
199 }
static constexpr double proton_mass_c2
G4double GetMeanEnergyLoss() const
void PutValue(size_t index, G4double energy, G4double dataValue)
G4double GetSandiaMatTablePAI(G4int, G4int) const
int G4int
Definition: G4Types.hh:78
G4double GetIntegralPAIdEdx(G4int i) const
void Initialize(const G4Material *material, G4double maxEnergyTransfer, G4double betaGammaSq, G4SandiaTable *)
G4double GetSplineEnergy(G4int i) const
void PutValue(size_t index, G4double theValue)
static constexpr double eV
Definition: G4SIunits.hh:215
G4double GetIntegralPAIySection(G4int i) const
G4double Energy(size_t index) const
void insertAt(size_t, G4PhysicsVector *)
G4int GetSplineSize() const
double G4double
Definition: G4Types.hh:76
G4double ComputeMaxEnergy(G4double scaledEnergy)
Definition: G4PAIModel.hh:166
void Initialize(G4Material *)
const G4Material * GetMaterial() const

Here is the call graph for this function:

Here is the caller graph for this function:

G4double G4PAIModelData::SampleAlongStepTransfer ( G4int  coupleIndex,
G4double  kinEnergy,
G4double  scaledTkin,
G4double  tmax,
G4double  stepFactor 
) const

Definition at line 289 of file G4PAIModelData.cc.

294 {
295  //G4cout << "=== G4PAIModelData::SampleAlongStepTransfer" << G4endl;
296  G4double loss = 0.0;
297 
298  size_t iPlace = fParticleEnergyVector->FindBin(scaledTkin, 0);
299  size_t nPlace = fParticleEnergyVector->GetVectorLength() - 1;
300 
301  G4bool one = true;
302  if(scaledTkin >= fParticleEnergyVector->Energy(nPlace)) { iPlace = nPlace; }
303  else if(scaledTkin > fParticleEnergyVector->Energy(0)) {
304  one = false;
305  }
306 
307  G4double meanNumber = 0.0;
308  G4double meanN11 = 0.0;
309  G4double meanN12 = 0.0;
310  G4double meanN21 = 0.0;
311  G4double meanN22 = 0.0;
312 
313  G4PhysicsVector* v1 = (*(fPAIxscBank[coupleIndex]))(iPlace);
314  G4PhysicsVector* v2 = 0;
315 
316  G4double e1 = v1->Energy(0);
317  G4double e2 = std::min(tmax, v1->GetMaxEnergy());
318 
319  if(e2 >= e1) {
320  meanN11 = (*v1)[0]/e1;
321  meanN12 = v1->Value(e2)/e2;
322  meanNumber = (meanN11 - meanN12)*stepFactor;
323  }
324  //G4cout<<"iPlace = "<<iPlace<< " meanN11= " << meanN11
325  // << " meanN12= " << meanN12 << G4endl;
326 
327  G4double W1 = 1.0;
328  G4double W2 = 0.0;
329  if(!one) {
330  v2 = (*(fPAIxscBank[coupleIndex]))(iPlace+1);
331 
332  e1 = v2->Energy(0);
333  e2 = std::min(tmax, v2->GetMaxEnergy());
334  if(e2 >= e1) {
335  meanN21 = (*v2)[0]/e1;
336  meanN22 = v2->Value(e2)/e2;
337  G4double E1 = fParticleEnergyVector->Energy(iPlace);
338  G4double E2 = fParticleEnergyVector->Energy(iPlace+1);
339  G4double W = 1.0/(E2 - E1);
340  W1 = (E2 - scaledTkin)*W;
341  W2 = (scaledTkin - E1)*W;
342  meanNumber *= W1;
343  meanNumber += (meanN21 - meanN22)*stepFactor*W2;
344  }
345  }
346 
347  if(meanNumber < 0.0) { return loss; }
348  G4int numOfCollisions = G4Poisson(meanNumber);
349 
350  //G4cout << "meanNumber= " << meanNumber << " N= " << numOfCollisions << G4endl;
351 
352  if(0 == numOfCollisions) { return loss; }
353 
354  G4double position, omega, omega2;
355  for(G4int i=0; i< numOfCollisions; ++i) {
356  G4double rand = G4UniformRand();
357  position = meanN12 + (meanN11 - meanN12)*rand;
358  omega = GetEnergyTransfer(coupleIndex, iPlace, position);
359  //G4cout << "omega(keV)= " << omega/keV << G4endl;
360  if(!one) {
361  position = meanN22 + (meanN21 - meanN22)*rand;
362  omega2 = GetEnergyTransfer(coupleIndex, iPlace+1, position);
363  omega *= W1;
364  omega += omega2*W2;
365  }
366  //G4cout << "omega(keV)= " << omega/keV << G4endl;
367 
368  loss += omega;
369  if(loss > kinEnergy) { break; }
370  }
371 
372  //G4cout<<"PAIModelData AlongStepLoss = "<<loss/keV<<" keV"<<G4endl;
373  if(loss > kinEnergy) { loss = kinEnergy; }
374  else if(loss < 0.) { loss = 0.; }
375  return loss;
376 }
G4long G4Poisson(G4double mean)
Definition: G4Poisson.hh:51
G4double GetMaxEnergy() const
size_t GetVectorLength() const
int G4int
Definition: G4Types.hh:78
#define position
Definition: xmlparse.cc:622
#define G4UniformRand()
Definition: Randomize.hh:97
bool G4bool
Definition: G4Types.hh:79
size_t FindBin(G4double energy, size_t idx) const
G4double Energy(size_t index) const
G4double Value(G4double theEnergy, size_t &lastidx) const
T min(const T t1, const T t2)
brief Return the smallest of the two arguments
double G4double
Definition: G4Types.hh:76

Here is the call graph for this function:

Here is the caller graph for this function:

G4double G4PAIModelData::SamplePostStepTransfer ( G4int  coupleIndex,
G4double  scaledTkin,
G4double  tmin,
G4double  tmax 
) const

Definition at line 383 of file G4PAIModelData.cc.

387 {
388  //G4cout<<"=== G4PAIModelData::SamplePostStepTransfer idx= "<< coupleIndex
389  // << " Tkin= " << scaledTkin << " Tmax= " << tmax << G4endl;
390  G4double transfer = 0.0;
391  G4double rand = G4UniformRand();
392 
393  size_t nPlace = fParticleEnergyVector->GetVectorLength() - 1;
394  size_t iPlace = fParticleEnergyVector->FindBin(scaledTkin, 0);
395 
396  G4bool one = true;
397  if(scaledTkin >= fParticleEnergyVector->Energy(nPlace)) { iPlace = nPlace; }
398  else if(scaledTkin > fParticleEnergyVector->Energy(0)) {
399  one = false;
400  }
401  G4PhysicsTable* table = fPAIxscBank[coupleIndex];
402  G4PhysicsVector* v1 = (*table)[iPlace];
403 
404  G4double emin = std::max(tmin, v1->Energy(0));
405  G4double emax = std::min(tmax, v1->GetMaxEnergy());
406  if(emax < emin) { return transfer; }
407 
408  G4double dNdx1 = v1->Value(emin)/emin;
409  G4double dNdx2 = v1->Value(emax)/emax;
410  /*
411  G4cout << "iPlace= " << iPlace << " nPlace= " << nPlace
412  << " emin= " << emin << " emax= " << emax
413  << " dNdx1= " << dNdx1 << " dNdx2= " << dNdx2
414  << " one: " << one << G4endl;
415  */
416  G4double position = dNdx2 + (dNdx1 - dNdx2)*rand;
417  transfer = GetEnergyTransfer(coupleIndex, iPlace, position);
418 
419  //G4cout<<"PAImodel PostStepTransfer = "<<transfer/keV<<" keV"
420  // << " position= " << position << G4endl;
421 
422  if(!one) {
423 
424  G4PhysicsVector* v2 = (*table)[iPlace+1];
425  emin = std::max(tmin, v2->Energy(0));
426  emax = std::min(tmax, v2->GetMaxEnergy());
427  if(emin <= emax) {
428  dNdx1 = v2->Value(emin)/emin;
429  dNdx2 = v2->Value(emax)/emax;
430 
431  //G4cout << " emax2= " << emax
432  // << " dNdx2= " << dNdx2 << " dNdx1= " << dNdx1 << G4endl;
433 
434  G4double E1 = fParticleEnergyVector->Energy(iPlace);
435  G4double E2 = fParticleEnergyVector->Energy(iPlace+1);
436  G4double W = 1.0/(E2 - E1);
437  G4double W1 = (E2 - scaledTkin)*W;
438  G4double W2 = (scaledTkin - E1)*W;
439 
440  //G4cout<< "E1= " << E1 << " E2= " << E2 <<" iPlace= " << iPlace
441  // << " W1= " << W1 << " W2= " << W2 <<G4endl;
442 
443  position = dNdx2 + (dNdx1 - dNdx2)*rand;
444  G4double tr2 = GetEnergyTransfer(coupleIndex, iPlace+1, position);
445 
446  //G4cout<<"PAImodel PostStepTransfer1 = "<<tr2/keV<<" keV"
447  // << " position= " << position << G4endl;
448  transfer *= W1;
449  transfer += tr2*W2;
450  }
451  }
452  //G4cout<<"PAImodel PostStepTransfer = "<<transfer/keV<<" keV"
453  // << " position= " << position << G4endl;
454  transfer = std::max(transfer, 0.0);
455  return transfer;
456 }
G4double GetMaxEnergy() const
size_t GetVectorLength() const
#define G4UniformRand()
Definition: Randomize.hh:97
bool G4bool
Definition: G4Types.hh:79
size_t FindBin(G4double energy, size_t idx) const
G4double Energy(size_t index) const
G4double Value(G4double theEnergy, size_t &lastidx) const
static const G4double emax
T max(const T t1, const T t2)
brief Return the largest of the two arguments
T min(const T t1, const T t2)
brief Return the smallest of the two arguments
double G4double
Definition: G4Types.hh:76

Here is the call graph for this function:

Here is the caller graph for this function:


The documentation for this class was generated from the following files: