source: trunk/source/processes/electromagnetic/standard/src/G4PAIxSection.cc @ 846

Last change on this file since 846 was 819, checked in by garnier, 16 years ago

import all except CVS

File size: 47.6 KB
Line 
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//
27// $Id: G4PAIxSection.cc,v 1.21 2006/06/29 19:53:20 gunter Exp $
28// GEANT4 tag $Name:  $
29//
30//
31// G4PAIxSection.cc -- class implementation file
32//
33// GEANT 4 class implementation file
34//
35// For information related to this code, please, contact
36// the Geant4 Collaboration.
37//
38// R&D: Vladimir.Grichine@cern.ch
39//
40// History:
41//
42// 13.05.03 V. Grichine, bug fixed for maxEnergyTransfer > max interval energy
43// 28.05.01 V.Ivanchenko minor changes to provide ANSI -wall compilation
44// 17.05.01 V. Grichine, low energy extension down to 10*keV of proton
45// 20.11.98 adapted to a new Material/SandiaTable interface, mma
46// 11.06.97 V. Grichine, 1st version
47//
48
49
50
51#include "G4PAIxSection.hh"
52
53#include "globals.hh"
54#include "G4ios.hh"
55#include "G4Poisson.hh"
56#include "G4Material.hh"
57#include "G4MaterialCutsCouple.hh"
58#include "G4SandiaTable.hh"
59
60using namespace std;
61
62/* ******************************************************************
63
64// Init  array of Lorentz factors
65
66const G4double G4PAIxSection::fLorentzFactor[22] =
67{
68          0.0 ,     1.1 ,   1.2 ,   1.3 ,    1.5 ,    1.8 ,  2.0 ,
69          2.5 ,     3.0 ,   4.0 ,   7.0 ,   10.0 ,   20.0 , 40.0 ,
70         70.0 ,   100.0 , 300.0 , 600.0 , 1000.0 , 3000.0 ,
71      10000.0 , 50000.0
72} ;
73
74const G4int G4PAIxSection::
75fRefGammaNumber = 29 ;         // The number of gamma for creation of
76                               // spline (9)
77
78***************************************************************** */ 
79
80// Local class constants
81
82const G4double G4PAIxSection::fDelta = 0.005 ; // energy shift from interval border
83const G4double G4PAIxSection::fError = 0.005 ; // error in lin-log approximation
84
85const G4int G4PAIxSection::fMaxSplineSize = 500 ;  // Max size of output spline
86                                                    // arrays
87
88//////////////////////////////////////////////////////////////////
89//
90// Constructor
91//
92
93G4PAIxSection::G4PAIxSection(G4MaterialCutsCouple* matCC)
94{
95  fDensity       = matCC->GetMaterial()->GetDensity();
96  G4int matIndex = matCC->GetMaterial()->GetIndex();
97  fSandia        = new G4SandiaTable(matIndex);
98
99  G4int i, j; 
100  fMatSandiaMatrix = new G4OrderedTable();
101 
102  for (i = 0; i < fSandia->GetMaxInterval()-1; i++)
103  {
104     fMatSandiaMatrix->push_back(new G4DataVector(5,0.));
105  }                     
106  for (i = 0; i < fSandia->GetMaxInterval()-1; i++)
107  {
108    (*(*fMatSandiaMatrix)[i])[0] = fSandia->GetSandiaMatTable(i,0);
109
110    for(j = 1; j < 5 ; j++)
111    {
112      (*(*fMatSandiaMatrix)[i])[j] = fSandia->GetSandiaMatTable(i,j)*fDensity;
113    }     
114  }                     
115
116
117
118}
119
120G4PAIxSection::G4PAIxSection(G4int materialIndex,
121                             G4double maxEnergyTransfer)
122{
123   const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable() ;
124   G4int i, j ;   
125
126      fDensity                = (*theMaterialTable)[materialIndex]->GetDensity() ;
127      fElectronDensity        = (*theMaterialTable)[materialIndex]->
128                             GetElectronDensity() ;
129      fIntervalNumber         = (*theMaterialTable)[materialIndex]->
130                             GetSandiaTable()->GetMatNbOfIntervals() ;
131      fIntervalNumber--;     
132      // G4cout<<fDensity<<"\t"<<fElectronDensity<<"\t"<<fIntervalNumber<<G4endl ;
133
134      fEnergyInterval = new G4double[fIntervalNumber+2] ;
135      fA1             = new G4double[fIntervalNumber+2] ;
136      fA2             = new G4double[fIntervalNumber+2] ;
137      fA3             = new G4double[fIntervalNumber+2] ;
138      fA4             = new G4double[fIntervalNumber+2] ;
139
140      for(i = 1 ; i <= fIntervalNumber ; i++ )
141      {
142         if(((*theMaterialTable)[materialIndex]->
143    GetSandiaTable()->GetSandiaCofForMaterial(i-1,0) >= maxEnergyTransfer) ||
144              i > fIntervalNumber               )
145         {
146            fEnergyInterval[i] = maxEnergyTransfer ;
147            fIntervalNumber = i ;
148            break;
149         }
150         fEnergyInterval[i] = (*theMaterialTable)[materialIndex]->
151                              GetSandiaTable()->GetSandiaCofForMaterial(i-1,0);
152         fA1[i]             = (*theMaterialTable)[materialIndex]->
153                              GetSandiaTable()->GetSandiaCofForMaterial(i-1,1);
154         fA2[i]             = (*theMaterialTable)[materialIndex]->
155                              GetSandiaTable()->GetSandiaCofForMaterial(i-1,2);
156         fA3[i]             = (*theMaterialTable)[materialIndex]->
157                              GetSandiaTable()->GetSandiaCofForMaterial(i-1,3);
158         fA4[i]             = (*theMaterialTable)[materialIndex]->
159                              GetSandiaTable()->GetSandiaCofForMaterial(i-1,4);
160         // G4cout<<i<<"\t"<<fEnergyInterval[i]<<"\t"<<fA1[i]<<"\t"<<fA2[i]<<"\t"
161         //                               <<fA3[i]<<"\t"<<fA4[i]<<"\t"<<G4endl ;
162      }   
163      if(fEnergyInterval[fIntervalNumber] != maxEnergyTransfer)
164      {
165         fIntervalNumber++;
166         fEnergyInterval[fIntervalNumber] = maxEnergyTransfer ;
167      }
168
169      // Now checking, if two borders are too close together
170
171      for(i=1;i<fIntervalNumber;i++)
172      {
173        if(fEnergyInterval[i+1]-fEnergyInterval[i] >
174           1.5*fDelta*(fEnergyInterval[i+1]+fEnergyInterval[i]))
175        {
176          continue ;
177        }
178        else
179        {
180          for(j=i;j<fIntervalNumber;j++)
181          {
182            fEnergyInterval[j] = fEnergyInterval[j+1] ;
183                        fA1[j] = fA1[j+1] ;
184                        fA2[j] = fA2[j+1] ;
185                        fA3[j] = fA3[j+1] ;
186                        fA4[j] = fA4[j+1] ;
187          }
188          fIntervalNumber-- ;
189          i-- ;
190        }
191      }
192
193
194      /* *********************************
195
196      fSplineEnergy          = new G4double[fMaxSplineSize] ;   
197      fRePartDielectricConst = new G4double[fMaxSplineSize] ;   
198      fImPartDielectricConst = new G4double[fMaxSplineSize] ;   
199      fIntegralTerm          = new G4double[fMaxSplineSize] ;   
200      fDifPAIxSection        = new G4double[fMaxSplineSize] ;   
201      fIntegralPAIxSection   = new G4double[fMaxSplineSize] ;   
202     
203      for(i=0;i<fMaxSplineSize;i++)
204      {
205         fSplineEnergy[i]          = 0.0 ;   
206         fRePartDielectricConst[i] = 0.0 ;   
207         fImPartDielectricConst[i] = 0.0 ;   
208         fIntegralTerm[i]          = 0.0 ;   
209         fDifPAIxSection[i]        = 0.0 ;   
210         fIntegralPAIxSection[i]   = 0.0 ;   
211      }
212      **************************************************  */   
213
214      InitPAI() ;  // create arrays allocated above
215     
216      delete[] fEnergyInterval ;
217      delete[] fA1 ;
218      delete[] fA2 ;
219      delete[] fA3 ;
220      delete[] fA4 ;   
221}
222
223////////////////////////////////////////////////////////////////////////
224//
225// Constructor with beta*gamma square value
226
227G4PAIxSection::G4PAIxSection( G4int materialIndex,
228                              G4double maxEnergyTransfer,
229                              G4double betaGammaSq,
230                              G4double** photoAbsCof, 
231                              G4int intNumber                   )
232{
233   const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
234   G4int i, j ;   
235   
236      fDensity                = (*theMaterialTable)[materialIndex]->GetDensity();
237      fElectronDensity        = (*theMaterialTable)[materialIndex]->
238                             GetElectronDensity() ;
239
240      fIntervalNumber         = intNumber ;
241      fIntervalNumber--;
242      //   G4cout<<fDensity<<"\t"<<fElectronDensity<<"\t"<<fIntervalNumber<<G4endl ;
243 
244      fEnergyInterval = new G4double[fIntervalNumber+2] ;
245      fA1             = new G4double[fIntervalNumber+2] ;
246      fA2             = new G4double[fIntervalNumber+2] ;
247      fA3             = new G4double[fIntervalNumber+2] ;
248      fA4             = new G4double[fIntervalNumber+2] ;
249
250      for( i = 1 ; i <= fIntervalNumber ; i++ )
251      {
252         if( ( photoAbsCof[i-1][0] >= maxEnergyTransfer ) ||
253             i > fIntervalNumber )
254         {
255            fEnergyInterval[i] = maxEnergyTransfer ;
256            fIntervalNumber = i ;
257            break;
258         }
259         fEnergyInterval[i] = photoAbsCof[i-1][0] ;
260         fA1[i]             = photoAbsCof[i-1][1] ;
261         fA2[i]             = photoAbsCof[i-1][2] ;
262         fA3[i]             = photoAbsCof[i-1][3] ;
263         fA4[i]             = photoAbsCof[i-1][4] ;
264         // G4cout<<i<<"\t"<<fEnergyInterval[i]<<"\t"<<fA1[i]<<"\t"<<fA2[i]<<"\t"
265         //        <<fA3[i]<<"\t"<<fA4[i]<<"\t"<<G4endl ;
266      }
267  // G4cout<<"i last = "<<i<<"; "<<"fIntervalNumber = "<<fIntervalNumber<<G4endl;   
268      if(fEnergyInterval[fIntervalNumber] != maxEnergyTransfer)
269      {
270         fIntervalNumber++;
271         fEnergyInterval[fIntervalNumber] = maxEnergyTransfer ;
272      }
273      for(i=1;i<=fIntervalNumber;i++)
274      {
275        //  G4cout<<i<<"\t"<<fEnergyInterval[i]<<"\t"<<fA1[i]<<"\t"<<fA2[i]<<"\t"
276        //    <<fA3[i]<<"\t"<<fA4[i]<<"\t"<<G4endl ;
277      }
278      // Now checking, if two borders are too close together
279
280      for( i = 1 ; i < fIntervalNumber ; i++ )
281      {
282        if(fEnergyInterval[i+1]-fEnergyInterval[i] >
283           1.5*fDelta*(fEnergyInterval[i+1]+fEnergyInterval[i]))
284        {
285          continue ;
286        }
287        else
288        {
289          for(j=i;j<fIntervalNumber;j++)
290          {
291            fEnergyInterval[j] = fEnergyInterval[j+1] ;
292                        fA1[j] = fA1[j+1] ;
293                        fA2[j] = fA2[j+1] ;
294                        fA3[j] = fA3[j+1] ;
295                        fA4[j] = fA4[j+1] ;
296          }
297          fIntervalNumber-- ;
298          i-- ;
299        }
300      }
301
302      // Preparation of fSplineEnergy array corresponding to min ionisation, G~4
303     
304      G4double   betaGammaSqRef = 
305      fLorentzFactor[fRefGammaNumber]*fLorentzFactor[fRefGammaNumber] - 1;
306
307      NormShift(betaGammaSqRef) ;             
308      SplainPAI(betaGammaSqRef) ;
309     
310      // Preparation of integral PAI cross section for input betaGammaSq
311   
312      for(i = 1 ; i <= fSplineNumber ; i++)
313      {
314         fdNdxCerenkov[i]   = PAIdNdxCerenkov(i,betaGammaSq);
315         fdNdxPlasmon[i]    = PAIdNdxPlasmon(i,betaGammaSq);
316         fDifPAIxSection[i] = DifPAIxSection(i,betaGammaSq);
317         // G4cout<<i<<"; dNdxC = "<<fdNdxCerenkov[i]<<"; dNdxP = "<<fdNdxPlasmon[i]
318         //    <<"; dNdxPAI = "<<fDifPAIxSection[i]<<G4endl;
319      }
320      IntegralCerenkov() ;
321      IntegralPlasmon() ;
322      IntegralPAIxSection() ;
323     
324      delete[] fEnergyInterval ;
325      delete[] fA1 ;
326      delete[] fA2 ;
327      delete[] fA3 ;
328      delete[] fA4 ;   
329}
330
331////////////////////////////////////////////////////////////////////////
332//
333// Test Constructor with beta*gamma square value
334
335G4PAIxSection::G4PAIxSection( G4int materialIndex,
336                              G4double maxEnergyTransfer,
337                              G4double betaGammaSq          )
338{
339   const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
340
341   G4int i, j, numberOfElements ;   
342   
343   fDensity         = (*theMaterialTable)[materialIndex]->GetDensity();
344   fElectronDensity = (*theMaterialTable)[materialIndex]->GetElectronDensity() ;
345   numberOfElements = (*theMaterialTable)[materialIndex]->GetNumberOfElements() ;
346
347   G4int* thisMaterialZ = new G4int[numberOfElements] ;
348   
349   for( i = 0 ; i < numberOfElements ; i++ )
350   {
351         thisMaterialZ[i] = (G4int)(*theMaterialTable)[materialIndex]->
352                                      GetElement(i)->GetZ() ;
353   }
354   G4SandiaTable     thisMaterialSandiaTable(materialIndex) ;
355   fIntervalNumber = thisMaterialSandiaTable.SandiaIntervals
356                           (thisMaterialZ,numberOfElements) ;   
357   fIntervalNumber = thisMaterialSandiaTable.SandiaMixing
358                           ( thisMaterialZ ,
359                      (*theMaterialTable)[materialIndex]->GetFractionVector() ,
360                             numberOfElements,fIntervalNumber) ;
361
362   fIntervalNumber--;
363
364      fEnergyInterval = new G4double[fIntervalNumber+2] ;
365      fA1             = new G4double[fIntervalNumber+2] ;
366      fA2             = new G4double[fIntervalNumber+2] ;
367      fA3             = new G4double[fIntervalNumber+2] ;
368      fA4             = new G4double[fIntervalNumber+2] ;
369
370      for(i=1;i<=fIntervalNumber;i++)
371      {
372  if((thisMaterialSandiaTable.GetPhotoAbsorpCof(i,0) >= maxEnergyTransfer) ||
373          i > fIntervalNumber)
374         {
375            fEnergyInterval[i] = maxEnergyTransfer ;
376            fIntervalNumber = i ;
377            break;
378         }
379   fEnergyInterval[i] = thisMaterialSandiaTable.GetPhotoAbsorpCof(i,0) ;
380   fA1[i]             = thisMaterialSandiaTable.GetPhotoAbsorpCof(i,1)*fDensity ;
381   fA2[i]             = thisMaterialSandiaTable.GetPhotoAbsorpCof(i,2)*fDensity ;
382   fA3[i]             = thisMaterialSandiaTable.GetPhotoAbsorpCof(i,3)*fDensity ;
383   fA4[i]             = thisMaterialSandiaTable.GetPhotoAbsorpCof(i,4)*fDensity ;
384
385      }   
386      if(fEnergyInterval[fIntervalNumber] != maxEnergyTransfer)
387      {
388         fIntervalNumber++;
389         fEnergyInterval[fIntervalNumber] = maxEnergyTransfer ;
390         fA1[fIntervalNumber] = fA1[fIntervalNumber-1] ;
391         fA2[fIntervalNumber] = fA2[fIntervalNumber-1] ;
392         fA3[fIntervalNumber] = fA3[fIntervalNumber-1] ;
393         fA4[fIntervalNumber] = fA4[fIntervalNumber-1] ;
394      }
395      for(i=1;i<=fIntervalNumber;i++)
396      {
397        // G4cout<<fEnergyInterval[i]<<"\t"<<fA1[i]<<"\t"<<fA2[i]<<"\t"
398        //   <<fA3[i]<<"\t"<<fA4[i]<<"\t"<<G4endl ;
399      }
400      // Now checking, if two borders are too close together
401
402      for(i=1;i<fIntervalNumber;i++)
403      {
404        if(fEnergyInterval[i+1]-fEnergyInterval[i] >
405           1.5*fDelta*(fEnergyInterval[i+1]+fEnergyInterval[i]))
406        {
407          continue ;
408        }
409        else
410        {
411          for(j=i;j<fIntervalNumber;j++)
412          {
413            fEnergyInterval[j] = fEnergyInterval[j+1] ;
414                        fA1[j] = fA1[j+1] ;
415                        fA2[j] = fA2[j+1] ;
416                        fA3[j] = fA3[j+1] ;
417                        fA4[j] = fA4[j+1] ;
418          }
419          fIntervalNumber-- ;
420          i-- ;
421        }
422      }
423
424      /* *********************************
425      fSplineEnergy          = new G4double[fMaxSplineSize] ;   
426      fRePartDielectricConst = new G4double[fMaxSplineSize] ;   
427      fImPartDielectricConst = new G4double[fMaxSplineSize] ;   
428      fIntegralTerm          = new G4double[fMaxSplineSize] ;   
429      fDifPAIxSection        = new G4double[fMaxSplineSize] ;   
430      fIntegralPAIxSection   = new G4double[fMaxSplineSize] ;   
431     
432      for(i=0;i<fMaxSplineSize;i++)
433      {
434         fSplineEnergy[i]          = 0.0 ;   
435         fRePartDielectricConst[i] = 0.0 ;   
436         fImPartDielectricConst[i] = 0.0 ;   
437         fIntegralTerm[i]          = 0.0 ;   
438         fDifPAIxSection[i]        = 0.0 ;   
439         fIntegralPAIxSection[i]   = 0.0 ;   
440      }
441      */ ////////////////////////
442
443      // Preparation of fSplineEnergy array corresponding to min ionisation, G~4
444     
445      G4double   betaGammaSqRef = 
446      fLorentzFactor[fRefGammaNumber]*fLorentzFactor[fRefGammaNumber] - 1;
447
448      NormShift(betaGammaSqRef) ;             
449      SplainPAI(betaGammaSqRef) ;
450     
451      // Preparation of integral PAI cross section for input betaGammaSq
452   
453      for(i = 1 ; i <= fSplineNumber ; i++)
454      {
455         fDifPAIxSection[i] = DifPAIxSection(i,betaGammaSq);
456         fdNdxCerenkov[i]   = PAIdNdxCerenkov(i,betaGammaSq);
457         fdNdxPlasmon[i]    = PAIdNdxPlasmon(i,betaGammaSq);
458      }
459      IntegralPAIxSection() ;
460      IntegralCerenkov() ;
461      IntegralPlasmon() ;
462     
463      //   delete[] fEnergyInterval ;
464      delete[] fA1 ;
465      delete[] fA2 ;
466      delete[] fA3 ;
467      delete[] fA4 ;   
468}
469
470
471////////////////////////////////////////////////////////////////////////////
472//
473// Destructor
474
475G4PAIxSection::~G4PAIxSection()
476{
477   /* ************************
478   delete[] fSplineEnergy          ;   
479   delete[] fRePartDielectricConst ;   
480   delete[] fImPartDielectricConst ;   
481   delete[] fIntegralTerm          ;   
482   delete[] fDifPAIxSection        ;   
483   delete[] fIntegralPAIxSection   ;
484   */ ////////////////////////
485}
486
487/////////////////////////////////////////////////////////////////////////
488//
489// General control function for class G4PAIxSection
490//
491
492void G4PAIxSection::InitPAI()
493{   
494   G4int i ;
495   G4double betaGammaSq = fLorentzFactor[fRefGammaNumber]*
496                          fLorentzFactor[fRefGammaNumber] - 1;
497
498   // Preparation of integral PAI cross section for reference gamma
499   
500   NormShift(betaGammaSq) ;             
501   SplainPAI(betaGammaSq) ;
502
503   IntegralPAIxSection() ;
504   IntegralCerenkov() ;
505   IntegralPlasmon() ;
506
507   for(i = 0 ; i<=fSplineNumber ; i++)
508   {
509      fPAItable[i][fRefGammaNumber] = fIntegralPAIxSection[i] ;
510      if(i != 0) 
511      {
512         fPAItable[i][0] = fSplineEnergy[i] ;
513      }
514   }
515   fPAItable[0][0] = fSplineNumber ;
516   
517   for(G4int j = 1 ; j < 112 ; j++)       // for other gammas
518   {
519      if( j == fRefGammaNumber ) continue ;
520     
521      betaGammaSq = fLorentzFactor[j]*fLorentzFactor[j] - 1 ;
522     
523      for(i = 1 ; i <= fSplineNumber ; i++)
524      {
525         fDifPAIxSection[i] = DifPAIxSection(i,betaGammaSq);
526         fdNdxCerenkov[i]   = PAIdNdxCerenkov(i,betaGammaSq);
527         fdNdxPlasmon[i]    = PAIdNdxPlasmon(i,betaGammaSq);
528      }
529      IntegralPAIxSection() ;
530      IntegralCerenkov() ;
531      IntegralPlasmon() ;
532     
533      for(i = 0 ; i <= fSplineNumber ; i++)
534      {
535         fPAItable[i][j] = fIntegralPAIxSection[i] ;
536      }
537   } 
538
539} 
540
541///////////////////////////////////////////////////////////////////////
542//
543// Shifting from borders to intervals Creation of first energy points
544//
545
546void G4PAIxSection::NormShift(G4double betaGammaSq)
547{
548  G4int i, j ;
549
550  for( i = 1 ; i <= fIntervalNumber-1 ; i++ )
551  {
552    for( j = 1 ; j <= 2 ; j++ )
553    {
554      fSplineNumber = (i-1)*2 + j ;
555
556      if( j == 1 ) fSplineEnergy[fSplineNumber] = fEnergyInterval[]*(1+fDelta);
557      else         fSplineEnergy[fSplineNumber] = fEnergyInterval[i+1]*(1-fDelta); 
558      //    G4cout<<"cn = "<<fSplineNumber<<"; "<<"energy = "
559      //  <<fSplineEnergy[fSplineNumber]<<G4endl;
560    }
561  }
562  fIntegralTerm[1]=RutherfordIntegral(1,fEnergyInterval[1],fSplineEnergy[1]);
563
564  j = 1 ;
565
566  for(i=2;i<=fSplineNumber;i++)
567  {
568    if(fSplineEnergy[i]<fEnergyInterval[j+1])
569    {
570         fIntegralTerm[i] = fIntegralTerm[i-1] + 
571                            RutherfordIntegral(j,fSplineEnergy[i-1],
572                                                 fSplineEnergy[i]   ) ;
573    }
574    else
575    {
576       G4double x = RutherfordIntegral(j,fSplineEnergy[i-1],
577                                           fEnergyInterval[j+1]   ) ;
578         j++;
579         fIntegralTerm[i] = fIntegralTerm[i-1] + x + 
580                            RutherfordIntegral(j,fEnergyInterval[j],
581                                                 fSplineEnergy[i]    ) ;
582    }
583    // G4cout<<i<<"\t"<<fSplineEnergy[i]<<"\t"<<fIntegralTerm[i]<<"\n"<<G4endl;
584  } 
585  fNormalizationCof = 2*pi*pi*hbarc*hbarc*fine_structure_const/electron_mass_c2 ;
586  fNormalizationCof *= fElectronDensity/fIntegralTerm[fSplineNumber] ;
587
588  // G4cout<<"fNormalizationCof = "<<fNormalizationCof<<G4endl ;
589
590          // Calculation of PAI differrential cross-section (1/(keV*cm))
591          // in the energy points near borders of energy intervals
592
593   for(G4int k=1;k<=fIntervalNumber-1;k++)
594   {
595      for(j=1;j<=2;j++)
596      {
597         i = (k-1)*2 + j ;
598         fImPartDielectricConst[i] = fNormalizationCof*
599                                     ImPartDielectricConst(k,fSplineEnergy[i]);
600         fRePartDielectricConst[i] = fNormalizationCof*
601                                     RePartDielectricConst(fSplineEnergy[i]);
602         fIntegralTerm[i] *= fNormalizationCof;
603
604         fDifPAIxSection[i] = DifPAIxSection(i,betaGammaSq);
605         fdNdxCerenkov[i]   = PAIdNdxCerenkov(i,betaGammaSq);
606         fdNdxPlasmon[i]    = PAIdNdxPlasmon(i,betaGammaSq);
607      }
608   }
609
610}  // end of NormShift
611
612/////////////////////////////////////////////////////////////////////////
613//
614// Creation of new energy points as geometrical mean of existing
615// one, calculation PAI_cs for them, while the error of logarithmic
616// linear approximation would be smaller than 'fError'
617
618void
619   G4PAIxSection::SplainPAI(G4double betaGammaSq)
620{
621   G4int k = 1 ;
622   G4int i = 1 ;
623
624   while ( (i < fSplineNumber) && (fSplineNumber < fMaxSplineSize-1) )
625   {
626      if(fSplineEnergy[i+1] > fEnergyInterval[k+1])
627      {
628          k++ ;   // Here next energy point is in next energy interval
629          i++;
630          continue;
631      }
632                       // Shifting of arrayes for inserting the geometrical
633                       // average of 'i' and 'i+1' energy points to 'i+1' place
634      fSplineNumber++;
635
636      for(G4int j = fSplineNumber; j >= i+2 ; j-- )
637      {
638         fSplineEnergy[j]          = fSplineEnergy[j-1];
639         fImPartDielectricConst[j] = fImPartDielectricConst[j-1];
640         fRePartDielectricConst[j] = fRePartDielectricConst[j-1];
641         fIntegralTerm[j]          = fIntegralTerm[j-1];
642
643         fDifPAIxSection[j] = fDifPAIxSection[j-1];
644         fdNdxCerenkov[j]   = fdNdxCerenkov[j-1];
645         fdNdxPlasmon[j]    = fdNdxPlasmon[j-1];
646      }
647      G4double x1  = fSplineEnergy[i];
648      G4double x2  = fSplineEnergy[i+1];
649      G4double yy1 = fDifPAIxSection[i];
650      G4double y2  = fDifPAIxSection[i+1];
651
652      G4double en1 = sqrt(x1*x2);
653      fSplineEnergy[i+1] = en1;
654
655                 // Calculation of logarithmic linear approximation
656                 // in this (enr) energy point, which number is 'i+1' now
657
658      G4double a = log10(y2/yy1)/log10(x2/x1);
659      G4double b = log10(yy1) - a*log10(x1);
660      G4double y = a*log10(en1) + b ;
661      y = pow(10.,y);
662
663                 // Calculation of the PAI dif. cross-section at this point
664
665      fImPartDielectricConst[i+1] = fNormalizationCof*
666                                    ImPartDielectricConst(k,fSplineEnergy[i+1]);
667      fRePartDielectricConst[i+1] = fNormalizationCof*
668                                    RePartDielectricConst(fSplineEnergy[i+1]);
669      fIntegralTerm[i+1] = fIntegralTerm[i] + fNormalizationCof*
670                           RutherfordIntegral(k,fSplineEnergy[i],
671                                                fSplineEnergy[i+1]);
672
673      fDifPAIxSection[i+1] = DifPAIxSection(i+1,betaGammaSq);
674      fdNdxCerenkov[i+1]   = PAIdNdxCerenkov(i+1,betaGammaSq);
675      fdNdxPlasmon[i+1]    = PAIdNdxPlasmon(i+1,betaGammaSq);
676
677                  // Condition for next division of this segment or to pass
678                  // to higher energies
679
680      G4double x = 2*(fDifPAIxSection[i+1] - y)/(fDifPAIxSection[i+1] + y);
681
682      if( x < 0 ) 
683      {
684         x = -x ;
685      }
686      if( x > fError && fSplineNumber < fMaxSplineSize-1 )
687      {
688         continue;  // next division
689      }
690      i += 2;  // pass to next segment
691
692   }   // close 'while'
693
694}  // end of SplainPAI
695
696
697////////////////////////////////////////////////////////////////////
698//
699// Integration over electrons that could be considered
700// quasi-free at energy transfer of interest
701
702G4double G4PAIxSection::RutherfordIntegral( G4int k,
703                                            G4double x1,
704                                            G4double x2   )
705{
706   G4double  c1, c2, c3 ;
707   // G4cout<<"RI: x1 = "<<x1<<"; "<<"x2 = "<<x2<<G4endl;   
708   c1 = (x2 - x1)/x1/x2 ;
709   c2 = (x2 - x1)*(x2 + x1)/x1/x1/x2/x2 ;
710   c3 = (x2 - x1)*(x1*x1 + x1*x2 + x2*x2)/x1/x1/x1/x2/x2/x2 ;
711   // G4cout<<" RI: c1 = "<<c1<<"; "<<"c2 = "<<c2<<"; "<<"c3 = "<<c3<<G4endl;   
712   
713   return  fA1[k]*log(x2/x1) + fA2[k]*c1 + fA3[k]*c2/2 + fA4[k]*c3/3 ;
714
715}   // end of RutherfordIntegral
716
717
718/////////////////////////////////////////////////////////////////
719//
720// Imaginary part of dielectric constant
721// (G4int k - interval number, G4double en1 - energy point)
722
723G4double G4PAIxSection::ImPartDielectricConst( G4int    k ,
724                                               G4double energy1 )
725{
726   G4double energy2,energy3,energy4,result;
727
728   energy2 = energy1*energy1;
729   energy3 = energy2*energy1;
730   energy4 = energy3*energy1;
731   
732   result = fA1[k]/energy1+fA2[k]/energy2+fA3[k]/energy3+fA4[k]/energy4 ; 
733   result *=hbarc/energy1 ;
734   
735   return result ;
736
737}  // end of ImPartDielectricConst
738
739
740//////////////////////////////////////////////////////////////////////////////
741//
742// Real part of dielectric constant minus unit: epsilon_1 - 1
743// (G4double enb - energy point)
744//
745
746G4double G4PAIxSection::RePartDielectricConst(G4double enb)
747{       
748   G4double x0, x02, x03, x04, x05, x1, x2, xx1 ,xx2 , xx12,
749            c1, c2, c3, cof1, cof2, xln1, xln2, xln3, result ;
750
751   x0 = enb ;
752   result = 0 ;
753   
754   for(G4int i=1;i<=fIntervalNumber-1;i++)
755   {
756      x1 = fEnergyInterval[i] ;
757      x2 = fEnergyInterval[i+1] ;
758      xx1 = x1 - x0 ;
759      xx2 = x2 - x0 ;
760      xx12 = xx2/xx1 ;
761     
762      if(xx12<0)
763      {
764         xx12 = -xx12;
765      }
766      xln1 = log(x2/x1) ;
767      xln2 = log(xx12) ;
768      xln3 = log((x2 + x0)/(x1 + x0)) ;
769      x02 = x0*x0 ;
770      x03 = x02*x0 ;
771      x04 = x03*x0 ;
772      x05 = x04*x0;
773      c1  = (x2 - x1)/x1/x2 ;
774      c2  = (x2 - x1)*(x2 +x1)/x1/x1/x2/x2 ;
775      c3  = (x2 -x1)*(x1*x1 + x1*x2 + x2*x2)/x1/x1/x1/x2/x2/x2 ;
776
777      result -= (fA1[i]/x02 + fA3[i]/x04)*xln1 ;
778      result -= (fA2[i]/x02 + fA4[i]/x04)*c1 ;
779      result -= fA3[i]*c2/2/x02 ;
780      result -= fA4[i]*c3/3/x02 ;
781
782      cof1 = fA1[i]/x02 + fA3[i]/x04 ;
783      cof2 = fA2[i]/x03 + fA4[i]/x05 ;
784
785      result += 0.5*(cof1 +cof2)*xln2 ;
786      result += 0.5*(cof1 - cof2)*xln3 ;
787   } 
788   result *= 2*hbarc/pi ;
789   
790   return result ;
791
792}   // end of RePartDielectricConst
793
794//////////////////////////////////////////////////////////////////////
795//
796// PAI differential cross-section in terms of
797// simplified Allison's equation
798//
799
800G4double G4PAIxSection::DifPAIxSection( G4int              i ,
801                                        G4double betaGammaSq  )
802{       
803   G4double be2,cof,x1,x2,x3,x4,x5,x6,x7,x8,result ;
804   //G4double beta, be4 ;
805   G4double be4 ;
806   G4double betaBohr2 = fine_structure_const*fine_structure_const ;
807   G4double betaBohr4 = betaBohr2*betaBohr2*4.0 ;
808   be2 = betaGammaSq/(1 + betaGammaSq) ;
809   be4 = be2*be2 ;
810   //  beta = sqrt(be2) ;
811   cof = 1 ;
812   x1 = log(2*electron_mass_c2/fSplineEnergy[i]) ;
813
814   if( betaGammaSq < 0.01 ) x2 = log(be2) ;
815   else
816   {
817     x2 = -log( (1/betaGammaSq - fRePartDielectricConst[i])*
818                (1/betaGammaSq - fRePartDielectricConst[i]) + 
819                fImPartDielectricConst[i]*fImPartDielectricConst[i] )/2 ;
820   }
821   if( fImPartDielectricConst[i] == 0.0 ||betaGammaSq < 0.01 )
822   {
823     x6=0 ;
824   }
825   else
826   {
827     x3 = -fRePartDielectricConst[i] + 1/betaGammaSq ;
828     x5 = -1 - fRePartDielectricConst[i] +
829          be2*((1 +fRePartDielectricConst[i])*(1 + fRePartDielectricConst[i]) +
830          fImPartDielectricConst[i]*fImPartDielectricConst[i]) ;
831
832     x7 = atan2(fImPartDielectricConst[i],x3) ;
833     x6 = x5 * x7 ;
834   }
835    // if(fImPartDielectricConst[i] == 0) x6 = 0 ;
836   
837   x4 = ((x1 + x2)*fImPartDielectricConst[i] + x6)/hbarc ;
838   //   if( x4 < 0.0 ) x4 = 0.0 ;
839   x8 = (1 + fRePartDielectricConst[i])*(1 + fRePartDielectricConst[i]) + 
840        fImPartDielectricConst[i]*fImPartDielectricConst[i] ;
841
842   result = (x4 + cof*fIntegralTerm[i]/fSplineEnergy[i]/fSplineEnergy[i]) ;
843   if(result < 1.0e-8) result = 1.0e-8 ;
844   result *= fine_structure_const/be2/pi ;
845   //   result *= (1-exp(-beta/betaBohr))*(1-exp(-beta/betaBohr)) ;
846   //  result *= (1-exp(-be2/betaBohr2)) ;
847   result *= (1-exp(-be4/betaBohr4)) ;
848   if(fDensity >= 0.1)
849   { 
850      result /= x8 ;
851   }
852   return result ;
853
854} // end of DifPAIxSection
855
856//////////////////////////////////////////////////////////////////////////
857//
858// Calculation od dN/dx of collisions with creation of Cerenkov pseudo-photons
859
860G4double G4PAIxSection::PAIdNdxCerenkov( G4int    i ,
861                                         G4double betaGammaSq  )
862{       
863   G4double cof, logarithm, x3, x5, argument, modul2, dNdxC ; 
864   G4double be2, be4, betaBohr2,betaBohr4,cofBetaBohr ;
865
866   cof         = 1.0 ;
867   cofBetaBohr = 4.0 ;
868   betaBohr2   = fine_structure_const*fine_structure_const ;
869   betaBohr4   = betaBohr2*betaBohr2*cofBetaBohr ;
870
871   be2 = betaGammaSq/(1 + betaGammaSq) ;
872   be4 = be2*be2 ;
873
874   if( betaGammaSq < 0.01 ) logarithm = log(1.0+betaGammaSq) ; // 0.0 ;
875   else
876   {
877     logarithm  = -log( (1/betaGammaSq - fRePartDielectricConst[i])*
878                        (1/betaGammaSq - fRePartDielectricConst[i]) + 
879                        fImPartDielectricConst[i]*fImPartDielectricConst[i] )*0.5 ;
880     logarithm += log(1+1.0/betaGammaSq) ;
881   }
882
883   if( fImPartDielectricConst[i] == 0.0 || betaGammaSq < 0.01 )
884   {
885     argument = 0.0 ;
886   }
887   else
888   {
889     x3 = -fRePartDielectricConst[i] + 1.0/betaGammaSq ;
890     x5 = -1.0 - fRePartDielectricConst[i] +
891          be2*((1.0 +fRePartDielectricConst[i])*(1.0 + fRePartDielectricConst[i]) +
892          fImPartDielectricConst[i]*fImPartDielectricConst[i]) ;
893     if( x3 == 0.0 ) argument = 0.5*pi;
894     else            argument = atan2(fImPartDielectricConst[i],x3) ;
895     argument *= x5  ;
896   }   
897   dNdxC = ( logarithm*fImPartDielectricConst[i] + argument )/hbarc ;
898 
899   if(dNdxC < 1.0e-8) dNdxC = 1.0e-8 ;
900
901   dNdxC *= fine_structure_const/be2/pi ;
902
903   dNdxC *= (1-exp(-be4/betaBohr4)) ;
904
905   if(fDensity >= 0.1)
906   { 
907      modul2 = (1.0 + fRePartDielectricConst[i])*(1.0 + fRePartDielectricConst[i]) + 
908                    fImPartDielectricConst[i]*fImPartDielectricConst[i] ;
909      dNdxC /= modul2 ;
910   }
911   return dNdxC ;
912
913} // end of PAIdNdxCerenkov
914
915//////////////////////////////////////////////////////////////////////////
916//
917// Calculation od dN/dx of collisions with creation of longitudinal EM
918// excitations (plasmons, delta-electrons)
919
920G4double G4PAIxSection::PAIdNdxPlasmon( G4int    i ,
921                                        G4double betaGammaSq  )
922{       
923   G4double cof, resonance, modul2, dNdxP ;
924   G4double be2, be4, betaBohr2, betaBohr4, cofBetaBohr ;
925
926   cof = 1 ;
927   cofBetaBohr = 4.0 ;
928   betaBohr2   = fine_structure_const*fine_structure_const ;
929   betaBohr4   = betaBohr2*betaBohr2*cofBetaBohr ;
930
931   be2 = betaGammaSq/(1 + betaGammaSq) ;
932   be4 = be2*be2 ;
933 
934   resonance = log(2*electron_mass_c2*be2/fSplineEnergy[i]) ; 
935   resonance *= fImPartDielectricConst[i]/hbarc ;
936
937
938   dNdxP = ( resonance + cof*fIntegralTerm[i]/fSplineEnergy[i]/fSplineEnergy[i] ) ;
939
940   if( dNdxP < 1.0e-8 ) dNdxP = 1.0e-8 ;
941
942   dNdxP *= fine_structure_const/be2/pi ;
943   dNdxP *= (1-exp(-be4/betaBohr4)) ;
944
945   if( fDensity >= 0.1 )
946   { 
947     modul2 = (1 + fRePartDielectricConst[i])*(1 + fRePartDielectricConst[i]) + 
948        fImPartDielectricConst[i]*fImPartDielectricConst[i] ;
949     dNdxP /= modul2 ;
950   }
951   return dNdxP ;
952
953} // end of PAIdNdxPlasmon
954
955////////////////////////////////////////////////////////////////////////
956//
957// Calculation of the PAI integral cross-section
958// fIntegralPAIxSection[1] = specific primary ionisation, 1/cm
959// and fIntegralPAIxSection[0] = mean energy loss per cm  in keV/cm
960
961void G4PAIxSection::IntegralPAIxSection()
962{
963  fIntegralPAIxSection[fSplineNumber] = 0 ;
964  fIntegralPAIdEdx[fSplineNumber]     = 0 ;
965  fIntegralPAIxSection[0]             = 0 ;
966  G4int k = fIntervalNumber -1 ;
967
968  for(G4int i = fSplineNumber-1 ; i >= 1 ; i--)
969  {
970    if(fSplineEnergy[i] >= fEnergyInterval[k])
971    {
972      fIntegralPAIxSection[i] = fIntegralPAIxSection[i+1] + SumOverInterval(i) ;
973      fIntegralPAIdEdx[i] = fIntegralPAIdEdx[i+1] + SumOverIntervaldEdx(i) ;
974    }
975    else
976    {
977      fIntegralPAIxSection[i] = fIntegralPAIxSection[i+1] + 
978                                   SumOverBorder(i+1,fEnergyInterval[k]) ;
979      fIntegralPAIdEdx[i] = fIntegralPAIdEdx[i+1] + 
980                                   SumOverBorderdEdx(i+1,fEnergyInterval[k]) ;
981      k-- ;
982    }
983  }
984}   // end of IntegralPAIxSection
985
986////////////////////////////////////////////////////////////////////////
987//
988// Calculation of the PAI Cerenkov integral cross-section
989// fIntegralCrenkov[1] = specific Crenkov ionisation, 1/cm
990// and fIntegralCerenkov[0] = mean Cerenkov loss per cm  in keV/cm
991
992void G4PAIxSection::IntegralCerenkov()
993{
994  G4int i, k ;
995   fIntegralCerenkov[fSplineNumber] = 0 ;
996   fIntegralCerenkov[0] = 0 ;
997   k = fIntervalNumber -1 ;
998
999   for( i = fSplineNumber-1 ; i >= 1 ; i-- )
1000   {
1001      if(fSplineEnergy[i] >= fEnergyInterval[k])
1002      {
1003        fIntegralCerenkov[i] = fIntegralCerenkov[i+1] + SumOverInterCerenkov(i) ;
1004        // G4cout<<"int: i = "<<i<<"; sumC = "<<fIntegralCerenkov[i]<<G4endl;
1005      }
1006      else
1007      {
1008        fIntegralCerenkov[i] = fIntegralCerenkov[i+1] + 
1009                                   SumOverBordCerenkov(i+1,fEnergyInterval[k]) ;
1010        k-- ;
1011        // G4cout<<"bord: i = "<<i<<"; sumC = "<<fIntegralCerenkov[i]<<G4endl;
1012      }
1013   }
1014
1015}   // end of IntegralCerenkov
1016
1017////////////////////////////////////////////////////////////////////////
1018//
1019// Calculation of the PAI Plasmon integral cross-section
1020// fIntegralPlasmon[1] = splasmon primary ionisation, 1/cm
1021// and fIntegralPlasmon[0] = mean plasmon loss per cm  in keV/cm
1022
1023void G4PAIxSection::IntegralPlasmon()
1024{
1025   fIntegralPlasmon[fSplineNumber] = 0 ;
1026   fIntegralPlasmon[0] = 0 ;
1027   G4int k = fIntervalNumber -1 ;
1028   for(G4int i=fSplineNumber-1;i>=1;i--)
1029   {
1030      if(fSplineEnergy[i] >= fEnergyInterval[k])
1031      {
1032        fIntegralPlasmon[i] = fIntegralPlasmon[i+1] + SumOverInterPlasmon(i) ;
1033      }
1034      else
1035      {
1036        fIntegralPlasmon[i] = fIntegralPlasmon[i+1] + 
1037                                   SumOverBordPlasmon(i+1,fEnergyInterval[k]) ;
1038        k-- ;
1039      }
1040   }
1041
1042}   // end of IntegralPlasmon
1043
1044//////////////////////////////////////////////////////////////////////
1045//
1046// Calculation the PAI integral cross-section inside
1047// of interval of continuous values of photo-ionisation
1048// cross-section. Parameter  'i' is the number of interval.
1049
1050G4double G4PAIxSection::SumOverInterval( G4int i )
1051{         
1052   G4double x0,x1,y0,yy1,a,b,c,result ;
1053
1054   x0 = fSplineEnergy[i] ;
1055   x1 = fSplineEnergy[i+1] ;
1056   y0 = fDifPAIxSection[i] ;
1057   yy1 = fDifPAIxSection[i+1];
1058   c = x1/x0;
1059   a = log10(yy1/y0)/log10(c) ;
1060   // b = log10(y0) - a*log10(x0) ;
1061   b = y0/pow(x0,a) ;
1062   a += 1 ;
1063   if(a == 0) 
1064   {
1065      result = b*log(x1/x0) ;
1066   }
1067   else
1068   {
1069      result = y0*(x1*pow(c,a-1) - x0)/a ;
1070   }
1071   a++;
1072   if(a == 0) 
1073   {
1074      fIntegralPAIxSection[0] += b*log(x1/x0) ;
1075   }
1076   else
1077   {
1078      fIntegralPAIxSection[0] += y0*(x1*x1*pow(c,a-2) - x0*x0)/a ;
1079   }
1080   return result ;
1081
1082} //  end of SumOverInterval
1083
1084/////////////////////////////////
1085
1086G4double G4PAIxSection::SumOverIntervaldEdx( G4int i )
1087{         
1088   G4double x0,x1,y0,yy1,a,b,c,result ;
1089
1090   x0 = fSplineEnergy[i] ;
1091   x1 = fSplineEnergy[i+1] ;
1092   y0 = fDifPAIxSection[i] ;
1093   yy1 = fDifPAIxSection[i+1];
1094   c = x1/x0;
1095   a = log10(yy1/y0)/log10(c) ;
1096   // b = log10(y0) - a*log10(x0) ;
1097   b = y0/pow(x0,a) ;
1098   a += 2 ;
1099   if(a == 0) 
1100   {
1101     result = b*log(x1/x0) ;
1102   }
1103   else
1104   {
1105     result = y0*(x1*x1*pow(c,a-2) - x0*x0)/a ;
1106   }
1107   return result ;
1108
1109} //  end of SumOverInterval
1110
1111//////////////////////////////////////////////////////////////////////
1112//
1113// Calculation the PAI Cerenkov integral cross-section inside
1114// of interval of continuous values of photo-ionisation Cerenkov
1115// cross-section. Parameter  'i' is the number of interval.
1116
1117G4double G4PAIxSection::SumOverInterCerenkov( G4int i )
1118{         
1119   G4double x0,x1,y0,yy1,a,b,c,result ;
1120
1121   x0  = fSplineEnergy[i] ;
1122   x1  = fSplineEnergy[i+1] ;
1123   y0  = fdNdxCerenkov[i] ;
1124   yy1 = fdNdxCerenkov[i+1];
1125   // G4cout<<"SumC, i = "<<i<<"; x0 ="<<x0<<"; x1 = "<<x1
1126   //   <<"; y0 = "<<y0<<"; yy1 = "<<yy1<<G4endl;
1127
1128   c = x1/x0;
1129   a = log10(yy1/y0)/log10(c) ;
1130   b = y0/pow(x0,a) ;
1131
1132   a += 1.0 ;
1133   if(a == 0) result = b*log(c) ;
1134   else       result = y0*(x1*pow(c,a-1) - x0)/a ;   
1135   a += 1.0 ;
1136
1137   if( a == 0 ) fIntegralCerenkov[0] += b*log(x1/x0) ;
1138   else         fIntegralCerenkov[0] += y0*(x1*x1*pow(c,a-2) - x0*x0)/a ;
1139   //  G4cout<<"a = "<<a<<"; b = "<<b<<"; result = "<<result<<G4endl;   
1140   return result ;
1141
1142} //  end of SumOverInterCerenkov
1143
1144//////////////////////////////////////////////////////////////////////
1145//
1146// Calculation the PAI Plasmon integral cross-section inside
1147// of interval of continuous values of photo-ionisation Plasmon
1148// cross-section. Parameter  'i' is the number of interval.
1149
1150G4double G4PAIxSection::SumOverInterPlasmon( G4int i )
1151{         
1152   G4double x0,x1,y0,yy1,a,b,c,result ;
1153
1154   x0  = fSplineEnergy[i] ;
1155   x1  = fSplineEnergy[i+1] ;
1156   y0  = fdNdxPlasmon[i] ;
1157   yy1 = fdNdxPlasmon[i+1];
1158   c =x1/x0;
1159   a = log10(yy1/y0)/log10(c) ;
1160   // b = log10(y0) - a*log10(x0) ;
1161   b = y0/pow(x0,a) ;
1162
1163   a += 1.0 ;
1164   if(a == 0) result = b*log(x1/x0) ;
1165   else       result = y0*(x1*pow(c,a-1) - x0)/a ;   
1166   a += 1.0 ;
1167
1168   if( a == 0 ) fIntegralPlasmon[0] += b*log(x1/x0) ;
1169   else         fIntegralPlasmon[0] += y0*(x1*x1*pow(c,a-2) - x0*x0)/a ;
1170   
1171   return result ;
1172
1173} //  end of SumOverInterPlasmon
1174
1175///////////////////////////////////////////////////////////////////////////////
1176//
1177// Integration of PAI cross-section for the case of
1178// passing across border between intervals
1179
1180G4double G4PAIxSection::SumOverBorder( G4int      i , 
1181                                       G4double en0    )
1182{               
1183   G4double x0,x1,y0,yy1,a,b,c,d,e0,result ;
1184
1185   e0 = en0 ;
1186   x0 = fSplineEnergy[i] ;
1187   x1 = fSplineEnergy[i+1] ;
1188   y0 = fDifPAIxSection[i] ;
1189   yy1 = fDifPAIxSection[i+1] ;
1190
1191   c = x1/x0;
1192   d = e0/x0;   
1193   a = log10(yy1/y0)/log10(x1/x0) ;
1194   // b0 = log10(y0) - a*log10(x0) ;
1195   b = y0/pow(x0,a);  // pow(10.,b) ;
1196   
1197   a += 1 ;
1198   if(a == 0)
1199   {
1200      result = b*log(x0/e0) ;
1201   }
1202   else
1203   {
1204      result = y0*(x0 - e0*pow(d,a-1))/a ;
1205   }
1206   a++ ;
1207   if(a == 0)
1208   {
1209      fIntegralPAIxSection[0] += b*log(x0/e0) ;
1210   }
1211   else 
1212   {
1213      fIntegralPAIxSection[0] += y0*(x0*x0 - e0*e0*pow(d,a-2))/a ;
1214   }
1215   x0 = fSplineEnergy[i - 1] ;
1216   x1 = fSplineEnergy[i - 2] ;
1217   y0 = fDifPAIxSection[i - 1] ;
1218   yy1 = fDifPAIxSection[i - 2] ;
1219
1220   c = x1/x0;
1221   d = e0/x0;   
1222   a = log10(yy1/y0)/log10(x1/x0) ;
1223   //  b0 = log10(y0) - a*log10(x0) ;
1224   b = y0/pow(x0,a) ;
1225   a += 1 ;
1226   if(a == 0)
1227   {
1228      result += b*log(e0/x0) ;
1229   }
1230   else
1231   {
1232      result += y0*(e0*pow(d,a-1) - x0)/a ;
1233   }
1234   a++ ;
1235   if(a == 0) 
1236   {
1237      fIntegralPAIxSection[0] += b*log(e0/x0) ;
1238   }
1239   else
1240   {
1241      fIntegralPAIxSection[0] += y0*(e0*e0*pow(d,a-2) - x0*x0)/a ;
1242   }
1243   return result ;
1244
1245} 
1246
1247///////////////////////////////////////////////////////////////////////
1248
1249G4double G4PAIxSection::SumOverBorderdEdx( G4int      i , 
1250                                       G4double en0    )
1251{               
1252   G4double x0,x1,y0,yy1,a,b,c,d,e0,result ;
1253
1254   e0 = en0 ;
1255   x0 = fSplineEnergy[i] ;
1256   x1 = fSplineEnergy[i+1] ;
1257   y0 = fDifPAIxSection[i] ;
1258   yy1 = fDifPAIxSection[i+1] ;
1259
1260   c = x1/x0;
1261   d = e0/x0;   
1262   a = log10(yy1/y0)/log10(x1/x0) ;
1263   // b0 = log10(y0) - a*log10(x0) ;
1264   b = y0/pow(x0,a);  // pow(10.,b) ;
1265   
1266   a += 2 ;
1267   if(a == 0)
1268   {
1269      result = b*log(x0/e0) ;
1270   }
1271   else 
1272   {
1273      result = y0*(x0*x0 - e0*e0*pow(d,a-2))/a ;
1274   }
1275   x0 = fSplineEnergy[i - 1] ;
1276   x1 = fSplineEnergy[i - 2] ;
1277   y0 = fDifPAIxSection[i - 1] ;
1278   yy1 = fDifPAIxSection[i - 2] ;
1279
1280   c = x1/x0;
1281   d = e0/x0;   
1282   a = log10(yy1/y0)/log10(x1/x0) ;
1283   //  b0 = log10(y0) - a*log10(x0) ;
1284   b = y0/pow(x0,a) ;
1285   a += 2 ;
1286   if(a == 0) 
1287   {
1288      result += b*log(e0/x0) ;
1289   }
1290   else
1291   {
1292      result += y0*(e0*e0*pow(d,a-2) - x0*x0)/a ;
1293   }
1294   return result ;
1295
1296} 
1297
1298///////////////////////////////////////////////////////////////////////////////
1299//
1300// Integration of Cerenkov cross-section for the case of
1301// passing across border between intervals
1302
1303G4double G4PAIxSection::SumOverBordCerenkov( G4int      i , 
1304                                             G4double en0    )
1305{               
1306   G4double x0,x1,y0,yy1,a,b,e0,c,d,result ;
1307
1308   e0 = en0 ;
1309   x0 = fSplineEnergy[i] ;
1310   x1 = fSplineEnergy[i+1] ;
1311   y0 = fdNdxCerenkov[i] ;
1312   yy1 = fdNdxCerenkov[i+1] ;
1313
1314   //  G4cout<<G4endl;
1315   //  G4cout<<"SumBordC, i = "<<i<<"; en0 = "<<en0<<"; x0 ="<<x0<<"; x1 = "<<x1
1316   //     <<"; y0 = "<<y0<<"; yy1 = "<<yy1<<G4endl;
1317   c = x1/x0 ;
1318   d = e0/x0 ;
1319   a = log10(yy1/y0)/log10(c) ;
1320   // b0 = log10(y0) - a*log10(x0) ;
1321   b = y0/pow(x0,a); // pow(10.,b0) ;   
1322   
1323   a += 1.0 ;
1324   if( a == 0 ) result = b*log(x0/e0) ;
1325   else         result = y0*(x0 - e0*pow(d,a-1))/a ;   
1326   a += 1.0 ;
1327
1328   if( a == 0 ) fIntegralCerenkov[0] += b*log(x0/e0) ;
1329   else         fIntegralCerenkov[0] += y0*(x0*x0 - e0*e0*pow(d,a-2))/a ;
1330
1331// G4cout<<"a = "<<a<<"; b0 = "<<b0<<"; b = "<<b<<"; result = "<<result<<G4endl;
1332   
1333   x0  = fSplineEnergy[i - 1] ;
1334   x1  = fSplineEnergy[i - 2] ;
1335   y0  = fdNdxCerenkov[i - 1] ;
1336   yy1 = fdNdxCerenkov[i - 2] ;
1337
1338   // G4cout<<"x0 ="<<x0<<"; x1 = "<<x1
1339   //    <<"; y0 = "<<y0<<"; yy1 = "<<yy1<<G4endl;
1340
1341   c = x1/x0 ;
1342   d = e0/x0 ;
1343   a  = log10(yy1/y0)/log10(x1/x0) ;
1344   // b0 = log10(y0) - a*log10(x0) ;
1345   b  =  y0/pow(x0,a);  // pow(10.,b0) ;
1346
1347   a += 1.0 ;
1348   if( a == 0 ) result += b*log(e0/x0) ;
1349   else         result += y0*(e0*pow(d,a-1) - x0 )/a ;
1350   a += 1.0 ;
1351
1352   if( a == 0 )   fIntegralCerenkov[0] += b*log(e0/x0) ;
1353   else           fIntegralCerenkov[0] += y0*(e0*e0*pow(d,a-2) - x0*x0)/a ;
1354
1355   // G4cout<<"a = "<<a<<"; b0 = "<<b0<<"; b = "
1356   // <<b<<"; result = "<<result<<G4endl;   
1357
1358   return result ;
1359
1360} 
1361
1362///////////////////////////////////////////////////////////////////////////////
1363//
1364// Integration of Plasmon cross-section for the case of
1365// passing across border between intervals
1366
1367G4double G4PAIxSection::SumOverBordPlasmon( G4int      i , 
1368                                             G4double en0    )
1369{               
1370   G4double x0,x1,y0,yy1,a,b,c,d,e0,result ;
1371
1372   e0 = en0 ;
1373   x0 = fSplineEnergy[i] ;
1374   x1 = fSplineEnergy[i+1] ;
1375   y0 = fdNdxPlasmon[i] ;
1376   yy1 = fdNdxPlasmon[i+1] ;
1377
1378   c = x1/x0 ;
1379   d = e0/x0 ;   
1380   a = log10(yy1/y0)/log10(c) ;
1381   //  b0 = log10(y0) - a*log10(x0) ;
1382   b = y0/pow(x0,a); //pow(10.,b) ;
1383   
1384   a += 1.0 ;
1385   if( a == 0 ) result = b*log(x0/e0) ;
1386   else         result = y0*(x0 - e0*pow(d,a-1))/a ;   
1387   a += 1.0 ;
1388
1389   if( a == 0 ) fIntegralPlasmon[0] += b*log(x0/e0) ;
1390   else         fIntegralPlasmon[0] += y0*(x0*x0 - e0*e0*pow(d,a-2))/a ;
1391   
1392   x0 = fSplineEnergy[i - 1] ;
1393   x1 = fSplineEnergy[i - 2] ;
1394   y0 = fdNdxPlasmon[i - 1] ;
1395   yy1 = fdNdxPlasmon[i - 2] ;
1396
1397   c = x1/x0 ;
1398   d = e0/x0 ;
1399   a = log10(yy1/y0)/log10(c) ;
1400   // b0 = log10(y0) - a*log10(x0) ;
1401   b = y0/pow(x0,a);// pow(10.,b0) ;
1402
1403   a += 1.0 ;
1404   if( a == 0 ) result += b*log(e0/x0) ;
1405   else         result += y0*(e0*pow(d,a-1) - x0)/a ;
1406   a += 1.0 ;
1407
1408   if( a == 0 )   fIntegralPlasmon[0] += b*log(e0/x0) ;
1409   else           fIntegralPlasmon[0] += y0*(e0*e0*pow(d,a-2) - x0*x0)/a ;
1410   
1411   return result ;
1412
1413} 
1414
1415/////////////////////////////////////////////////////////////////////////
1416//
1417//
1418
1419G4double G4PAIxSection::GetStepEnergyLoss( G4double step )
1420{ 
1421  G4int iTransfer  ;
1422  G4long numOfCollisions ;
1423  G4double loss = 0.0 ;
1424  G4double meanNumber, position ;
1425
1426  // G4cout<<" G4PAIxSection::GetStepEnergyLoss "<<G4endl ;
1427
1428
1429
1430  meanNumber = fIntegralPAIxSection[1]*step ;
1431  numOfCollisions = G4Poisson(meanNumber) ;
1432
1433  //   G4cout<<"numOfCollisions = "<<numOfCollisions<<G4endl ;
1434
1435  while(numOfCollisions)
1436  {
1437    position = fIntegralPAIxSection[1]*G4UniformRand() ;
1438
1439    for( iTransfer=1 ; iTransfer<=fSplineNumber ; iTransfer++ )
1440    {
1441        if( position >= fIntegralPAIxSection[iTransfer] ) break ;
1442    }
1443    loss += fSplineEnergy[iTransfer]  ;
1444    numOfCollisions-- ;
1445  }
1446  // G4cout<<"PAI energy loss = "<<loss/keV<<" keV"<<G4endl ;
1447
1448  return loss ;
1449}
1450
1451/////////////////////////////////////////////////////////////////////////
1452//
1453//
1454
1455G4double G4PAIxSection::GetStepCerenkovLoss( G4double step )
1456{ 
1457  G4int iTransfer  ;
1458  G4long numOfCollisions ;
1459  G4double loss = 0.0 ;
1460  G4double meanNumber, position ;
1461
1462  // G4cout<<" G4PAIxSection::GetStepCreLosnkovs "<<G4endl ;
1463
1464
1465
1466  meanNumber = fIntegralCerenkov[1]*step ;
1467  numOfCollisions = G4Poisson(meanNumber) ;
1468
1469  //   G4cout<<"numOfCollisions = "<<numOfCollisions<<G4endl ;
1470
1471  while(numOfCollisions)
1472  {
1473    position = fIntegralCerenkov[1]*G4UniformRand() ;
1474
1475    for( iTransfer=1 ; iTransfer<=fSplineNumber ; iTransfer++ )
1476    {
1477        if( position >= fIntegralCerenkov[iTransfer] ) break ;
1478    }
1479    loss += fSplineEnergy[iTransfer]  ;
1480    numOfCollisions-- ;
1481  }
1482  // G4cout<<"PAI Cerenkov loss = "<<loss/keV<<" keV"<<G4endl ;
1483
1484  return loss ;
1485}
1486
1487/////////////////////////////////////////////////////////////////////////
1488//
1489//
1490
1491G4double G4PAIxSection::GetStepPlasmonLoss( G4double step )
1492{ 
1493  G4int iTransfer  ;
1494  G4long numOfCollisions ;
1495  G4double loss = 0.0 ;
1496  G4double meanNumber, position ;
1497
1498  // G4cout<<" G4PAIxSection::GetStepCreLosnkovs "<<G4endl ;
1499
1500
1501
1502  meanNumber = fIntegralPlasmon[1]*step ;
1503  numOfCollisions = G4Poisson(meanNumber) ;
1504
1505  //   G4cout<<"numOfCollisions = "<<numOfCollisions<<G4endl ;
1506
1507  while(numOfCollisions)
1508  {
1509    position = fIntegralPlasmon[1]*G4UniformRand() ;
1510
1511    for( iTransfer=1 ; iTransfer<=fSplineNumber ; iTransfer++ )
1512    {
1513        if( position >= fIntegralPlasmon[iTransfer] ) break ;
1514    }
1515    loss += fSplineEnergy[iTransfer]  ;
1516    numOfCollisions-- ;
1517  }
1518  // G4cout<<"PAI Plasmon loss = "<<loss/keV<<" keV"<<G4endl ;
1519
1520  return loss ;
1521}
1522
1523
1524
1525/////////////////////////////////////////////////////////////////////////////
1526//
1527// Init  array of Lorentz factors
1528//
1529
1530G4int G4PAIxSection::fNumberOfGammas = 111 ;
1531
1532const G4double G4PAIxSection::fLorentzFactor[112] =     // fNumberOfGammas+1
1533{
15340.0,
15351.094989e+00, 1.107813e+00, 1.122369e+00, 1.138890e+00, 1.157642e+00,
15361.178925e+00, 1.203082e+00, 1.230500e+00, 1.261620e+00, 1.296942e+00, // 10
15371.337032e+00, 1.382535e+00, 1.434181e+00, 1.492800e+00, 1.559334e+00,
15381.634850e+00, 1.720562e+00, 1.817845e+00, 1.928263e+00, 2.053589e+00, // 20
15392.195835e+00, 2.357285e+00, 2.540533e+00, 2.748522e+00, 2.984591e+00,
15403.252533e+00, 3.556649e+00, 3.901824e+00, 4.293602e+00, 4.738274e+00, // 30
15415.242981e+00, 5.815829e+00, 6.466019e+00, 7.203990e+00, 8.041596e+00,
15428.992288e+00, 1.007133e+01, 1.129606e+01, 1.268614e+01, 1.426390e+01, // 40
15431.605467e+01, 1.808721e+01, 2.039417e+01, 2.301259e+01, 2.598453e+01,
15442.935771e+01, 3.318630e+01, 3.753180e+01, 4.246399e+01, 4.806208e+01, // 50
15455.441597e+01, 6.162770e+01, 6.981310e+01, 7.910361e+01, 8.964844e+01,
15461.016169e+02, 1.152013e+02, 1.306197e+02, 1.481198e+02, 1.679826e+02, // 60
15471.905270e+02, 2.161152e+02, 2.451581e+02, 2.781221e+02, 3.155365e+02,
15483.580024e+02, 4.062016e+02, 4.609081e+02, 5.230007e+02, 5.934765e+02, // 70
15496.734672e+02, 7.642575e+02, 8.673056e+02, 9.842662e+02, 1.117018e+03,
15501.267692e+03, 1.438709e+03, 1.632816e+03, 1.853128e+03, 2.103186e+03, // 80
15512.387004e+03, 2.709140e+03, 3.074768e+03, 3.489760e+03, 3.960780e+03,
15524.495394e+03, 5.102185e+03, 5.790900e+03, 6.572600e+03, 7.459837e+03, // 90
15538.466860e+03, 9.609843e+03, 1.090714e+04, 1.237959e+04, 1.405083e+04,
15541.594771e+04, 1.810069e+04, 2.054434e+04, 2.331792e+04, 2.646595e+04, // 100
15553.003901e+04, 3.409446e+04, 3.869745e+04, 4.392189e+04, 4.985168e+04,
15565.658206e+04, 6.422112e+04, 7.289153e+04, 8.273254e+04, 9.390219e+04, // 110
15571.065799e+05
1558} ;
1559
1560///////////////////////////////////////////////////////////////////////
1561//
1562// The number of gamma for creation of  spline (near ion-min , G ~ 4 )
1563//
1564
1565const
1566G4int G4PAIxSection::fRefGammaNumber = 29 ; 
1567
1568   
1569//   
1570// end of G4PAIxSection implementation file
1571//
1572////////////////////////////////////////////////////////////////////////////
1573
Note: See TracBrowser for help on using the repository browser.