Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/electromagnetic/standard/src/G4PAIModelData.cc

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

Diff markup

Differences between /processes/electromagnetic/standard/src/G4PAIModelData.cc (Version 11.3.0) and /processes/electromagnetic/standard/src/G4PAIModelData.cc (Version 10.7.p3)


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                         3 // * License and Disclaimer                                           *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th      5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided      6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License      7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/      8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.           9 // * include a list of copyright holders.                             *
 10 // *                                               10 // *                                                                  *
 11 // * Neither the authors of this software syst     11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file      15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitatio     16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                               17 // *                                                                  *
 18 // * This  code  implementation is the result      18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboratio     19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distri     20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  ag     21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publicati     22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Sof     23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // *******************************************     24 // ********************************************************************
 25 //                                                 25 //
 26 //                                                 26 //
 27 // -------------------------------------------     27 // -------------------------------------------------------------------
 28 //                                                 28 //
 29 // GEANT4 Class                                    29 // GEANT4 Class
 30 // File name:     G4PAIModelData.cc                30 // File name:     G4PAIModelData.cc
 31 //                                                 31 //
 32 // Author:        V. Ivanchenko based on V.Gri     32 // Author:        V. Ivanchenko based on V.Grichine code of G4PAIModel
 33 //                                                 33 //
 34 // Creation date: 16.08.2013                       34 // Creation date: 16.08.2013
 35 //                                                 35 //
 36 // Modifications:                                  36 // Modifications:
 37 //                                                 37 //
 38                                                    38 
 39 #include "G4PAIModelData.hh"                       39 #include "G4PAIModelData.hh"
 40 #include "G4PAIModel.hh"                           40 #include "G4PAIModel.hh"
 41                                                    41 
 42 #include "G4SystemOfUnits.hh"                      42 #include "G4SystemOfUnits.hh"
 43 #include "G4PhysicalConstants.hh"                  43 #include "G4PhysicalConstants.hh"
 44                                                    44 
 45 #include "G4PhysicsLogVector.hh"                   45 #include "G4PhysicsLogVector.hh"
 46 #include "G4PhysicsFreeVector.hh"                  46 #include "G4PhysicsFreeVector.hh"
 47 #include "G4PhysicsTable.hh"                       47 #include "G4PhysicsTable.hh"
 48 #include "G4MaterialCutsCouple.hh"                 48 #include "G4MaterialCutsCouple.hh"
 49 #include "G4SandiaTable.hh"                        49 #include "G4SandiaTable.hh"
 50 #include "Randomize.hh"                            50 #include "Randomize.hh"
 51 #include "G4Poisson.hh"                            51 #include "G4Poisson.hh"
 52                                                    52 
 53 //////////////////////////////////////////////     53 ////////////////////////////////////////////////////////////////////////
 54                                                    54 
 55 using namespace std;                               55 using namespace std;
 56                                                    56 
 57 G4PAIModelData::G4PAIModelData(G4double tmin,      57 G4PAIModelData::G4PAIModelData(G4double tmin, G4double tmax, G4int ver)
 58 {                                                  58 { 
 59   const G4int nPerDecade = 10;                     59   const G4int nPerDecade = 10; 
 60   const G4double lowestTkin = 50*keV;              60   const G4double lowestTkin = 50*keV;
 61   const G4double highestTkin = 10*TeV;             61   const G4double highestTkin = 10*TeV;
 62                                                    62 
 63   fPAIySection.SetVerbose(ver);                    63   fPAIySection.SetVerbose(ver);
 64                                                    64 
 65   fLowestKineticEnergy  = std::max(tmin, lowes     65   fLowestKineticEnergy  = std::max(tmin, lowestTkin);
 66   fHighestKineticEnergy = tmax;                    66   fHighestKineticEnergy = tmax;
 67   if(tmax < 10*fLowestKineticEnergy) {             67   if(tmax < 10*fLowestKineticEnergy) { 
 68     fHighestKineticEnergy = 10*fLowestKineticE     68     fHighestKineticEnergy = 10*fLowestKineticEnergy;
 69   } else if(tmax > highestTkin) {                  69   } else if(tmax > highestTkin) {
 70     fHighestKineticEnergy = std::max(highestTk     70     fHighestKineticEnergy = std::max(highestTkin, 10*fLowestKineticEnergy);
 71   }                                                71   }
 72   fTotBin = (G4int)(nPerDecade*                    72   fTotBin = (G4int)(nPerDecade*
 73         std::log10(fHighestKineticEnergy/fLowe     73         std::log10(fHighestKineticEnergy/fLowestKineticEnergy));
 74                                                    74 
 75   fParticleEnergyVector = new G4PhysicsLogVect     75   fParticleEnergyVector = new G4PhysicsLogVector(fLowestKineticEnergy,
 76              fHighestKineticEnergy,                76              fHighestKineticEnergy,
 77              fTotBin);                             77              fTotBin);
 78   if(0 < ver) {                                    78   if(0 < ver) {
 79     G4cout << "### G4PAIModelData: Nbins= " <<     79     G4cout << "### G4PAIModelData: Nbins= " << fTotBin
 80      << " Tlowest(keV)= " << lowestTkin/keV        80      << " Tlowest(keV)= " << lowestTkin/keV
 81      << " Tmin(keV)= " << fLowestKineticEnergy     81      << " Tmin(keV)= " << fLowestKineticEnergy/keV 
 82      << " Tmax(GeV)= " << fHighestKineticEnerg     82      << " Tmax(GeV)= " << fHighestKineticEnergy/GeV 
 83      << G4endl;                                    83      << G4endl;
 84   }                                                84   }
 85 }                                                  85 }
 86                                                    86 
 87 //////////////////////////////////////////////     87 ////////////////////////////////////////////////////////////////////////////
 88                                                    88 
 89 G4PAIModelData::~G4PAIModelData()                  89 G4PAIModelData::~G4PAIModelData()
 90 {                                                  90 {
 91   std::size_t n = fPAIxscBank.size();          <<  91   size_t n = fPAIxscBank.size();
 92   if(0 < n) {                                      92   if(0 < n) {
 93     for(std::size_t i=0; i<n; ++i) {           <<  93     for(size_t i=0; i<n; ++i) {
 94       if(fPAIxscBank[i]) {                         94       if(fPAIxscBank[i]) {
 95         fPAIxscBank[i]->clearAndDestroy();         95         fPAIxscBank[i]->clearAndDestroy();
 96   delete fPAIxscBank[i];                           96   delete fPAIxscBank[i];
 97       }                                            97       }
 98       if(fPAIdEdxBank[i]) {                        98       if(fPAIdEdxBank[i]) {
 99         fPAIdEdxBank[i]->clearAndDestroy();        99         fPAIdEdxBank[i]->clearAndDestroy();
100   delete fPAIdEdxBank[i];                         100   delete fPAIdEdxBank[i];
101       }                                           101       }
102       delete fdEdxTable[i];                       102       delete fdEdxTable[i];
103     }                                             103     }
104   }                                               104   }
105   delete fParticleEnergyVector;                   105   delete fParticleEnergyVector;
106 }                                                 106 }
107                                                   107 
108 //////////////////////////////////////////////    108 ///////////////////////////////////////////////////////////////////////////////
109                                                   109 
110 void G4PAIModelData::Initialise(const G4Materi    110 void G4PAIModelData::Initialise(const G4MaterialCutsCouple* couple,
111                                 G4PAIModel* mo    111                                 G4PAIModel* model)
112 {                                                 112 {
113   const G4Material* mat = couple->GetMaterial(    113   const G4Material* mat = couple->GetMaterial();     
114   fSandia.Initialize(const_cast<G4Material*>(m    114   fSandia.Initialize(const_cast<G4Material*>(mat));
115                                                   115 
116   auto PAItransferTable = new G4PhysicsTable(f << 116   G4PhysicsTable* PAItransferTable = new G4PhysicsTable(fTotBin+1);
117   auto PAIdEdxTable = new G4PhysicsTable(fTotB << 117   G4PhysicsTable* PAIdEdxTable = new G4PhysicsTable(fTotBin+1);
118   auto dEdxMeanVector =                        << 118   G4PhysicsLogVector* dEdxMeanVector =
119     new G4PhysicsLogVector(fLowestKineticEnerg    119     new G4PhysicsLogVector(fLowestKineticEnergy,
120          fHighestKineticEnergy,                   120          fHighestKineticEnergy,
121          fTotBin);                                121          fTotBin);
122   // low energy Sandia interval                   122   // low energy Sandia interval
123   G4double Tmin = fSandia.GetSandiaMatTablePAI    123   G4double Tmin = fSandia.GetSandiaMatTablePAI(0,0); 
124                                                   124 
125   // energy safety                                125   // energy safety
126   static const G4double deltaLow = 100.*eV;       126   static const G4double deltaLow = 100.*eV; 
127                                                   127 
128   for (G4int i = 0; i <= fTotBin; ++i) {          128   for (G4int i = 0; i <= fTotBin; ++i) {
129                                                   129 
130     G4double kinEnergy = fParticleEnergyVector    130     G4double kinEnergy = fParticleEnergyVector->Energy(i);
131     G4double Tmax = model->ComputeMaxEnergy(ki    131     G4double Tmax = model->ComputeMaxEnergy(kinEnergy);
132     G4double tau = kinEnergy/proton_mass_c2;      132     G4double tau = kinEnergy/proton_mass_c2;
133     G4double bg2 = tau*( tau + 2. );              133     G4double bg2 = tau*( tau + 2. );
134                                                   134 
135     if (Tmax < Tmin + deltaLow ) { Tmax = Tmin    135     if (Tmax < Tmin + deltaLow ) { Tmax = Tmin + deltaLow; }
136                                                   136 
137     fPAIySection.Initialize(mat, Tmax, bg2, &f    137     fPAIySection.Initialize(mat, Tmax, bg2, &fSandia);
138                                                   138     
139     //G4cout << i << ". TransferMax(keV)= "<<     139     //G4cout << i << ". TransferMax(keV)= "<< Tmax/keV  
140     //     << "  E(MeV)= " << kinEnergy/MeV <<    140     //     << "  E(MeV)= " << kinEnergy/MeV << G4endl;
141                                                   141     
142     G4int n = fPAIySection.GetSplineSize();       142     G4int n = fPAIySection.GetSplineSize();
143     G4int kmin = 0;                               143     G4int kmin = 0;
144     for(G4int k = 0; k < n; ++k) {                144     for(G4int k = 0; k < n; ++k) {
145       if(fPAIySection.GetIntegralPAIySection(k    145       if(fPAIySection.GetIntegralPAIySection(k+1) <= 0.0) { 
146   kmin = k;                                       146   kmin = k;
147       } else {                                    147       } else {
148   break;                                          148   break;
149       }                                           149       }
150     }                                             150     }
151     n -= kmin;                                    151     n -= kmin;
152                                                   152 
153     auto transferVector = new G4PhysicsFreeVec << 153     G4PhysicsFreeVector* transferVector = new G4PhysicsFreeVector(n);
154     auto dEdxVector = new G4PhysicsFreeVector( << 154     G4PhysicsFreeVector* dEdxVector = new G4PhysicsFreeVector(n);
155                                                   155 
156     //G4double tr0 = 0.0;                         156     //G4double tr0 = 0.0;
157     G4double tr = 0.0;                            157     G4double tr = 0.0;
158     for(G4int k = kmin; k < n; ++k)               158     for(G4int k = kmin; k < n; ++k)
159     {                                             159     {
160       G4double t  = fPAIySection.GetSplineEner    160       G4double t  = fPAIySection.GetSplineEnergy(k+1);
161       tr = fPAIySection.GetIntegralPAIySection    161       tr = fPAIySection.GetIntegralPAIySection(k+1);
162       //if(tr >= tr0) { tr0 = tr; }               162       //if(tr >= tr0) { tr0 = tr; }
163       //else { G4cout << "G4PAIModelData::Init    163       //else { G4cout << "G4PAIModelData::Initialise Warning: Ekin(MeV)= "
164       //        << t/MeV << " IntegralTransfer    164       //        << t/MeV << " IntegralTransfer= " << tr 
165       //        << " < " << tr0 << G4endl; }      165       //        << " < " << tr0 << G4endl; }
166       transferVector->PutValue(k, t, t*tr);       166       transferVector->PutValue(k, t, t*tr);
167       dEdxVector->PutValue(k, t, fPAIySection.    167       dEdxVector->PutValue(k, t, fPAIySection.GetIntegralPAIdEdx(k+1));
168     }                                             168     }
169     //G4cout << "TransferVector:" << G4endl;      169     //G4cout << "TransferVector:" << G4endl;
170     //G4cout << *transferVector << G4endl;        170     //G4cout << *transferVector << G4endl;
171     //G4cout << "DEDXVector:" << G4endl;          171     //G4cout << "DEDXVector:" << G4endl;
172     //G4cout << *dEdxVector << G4endl;            172     //G4cout << *dEdxVector << G4endl;
173                                                   173 
174     G4double ionloss = std::max(fPAIySection.G << 174     G4double ionloss = fPAIySection.GetMeanEnergyLoss();//  total <dE/dx>
                                                   >> 175 
                                                   >> 176     if(ionloss < 0.0) ionloss = 0.0; 
                                                   >> 177 
175     dEdxMeanVector->PutValue(i,ionloss);          178     dEdxMeanVector->PutValue(i,ionloss);
176                                                   179 
177     PAItransferTable->insertAt(i,transferVecto    180     PAItransferTable->insertAt(i,transferVector);
178     PAIdEdxTable->insertAt(i,dEdxVector);         181     PAIdEdxTable->insertAt(i,dEdxVector);
179                                                   182 
                                                   >> 183     //transferVector->SetSpline(true);
                                                   >> 184     //transferVector->FillSecondDerivatives();
                                                   >> 185     //dEdxVector->SetSpline(true);
                                                   >> 186     //dEdxVector->FillSecondDerivatives();
                                                   >> 187 
180   } // end of Tkin loop`                          188   } // end of Tkin loop`
181   fPAIxscBank.push_back(PAItransferTable);        189   fPAIxscBank.push_back(PAItransferTable);
182   fPAIdEdxBank.push_back(PAIdEdxTable);           190   fPAIdEdxBank.push_back(PAIdEdxTable);
183   //G4cout << "dEdxMeanVector: " << G4endl;       191   //G4cout << "dEdxMeanVector: " << G4endl;
184   //G4cout << *dEdxMeanVector << G4endl;          192   //G4cout << *dEdxMeanVector << G4endl;
                                                   >> 193   /*
                                                   >> 194   dEdxMeanVector->SetSpline(true);
                                                   >> 195   dEdxMeanVector->FillSecondDerivatives();
                                                   >> 196   */
185   fdEdxTable.push_back(dEdxMeanVector);           197   fdEdxTable.push_back(dEdxMeanVector);
186 }                                                 198 }
187                                                   199 
188 //////////////////////////////////////////////    200 //////////////////////////////////////////////////////////////////////////////
189                                                   201 
190 G4double G4PAIModelData::DEDXPerVolume(G4int c    202 G4double G4PAIModelData::DEDXPerVolume(G4int coupleIndex, G4double scaledTkin,
191        G4double cut) const                        203        G4double cut) const
192 {                                                 204 {
193   // VI: iPlace is the low edge index of the b    205   // VI: iPlace is the low edge index of the bin
194   // iPlace is in interval from 0 to (N-1)        206   // iPlace is in interval from 0 to (N-1)
195   std::size_t iPlace(0);                       << 207   size_t iPlace = fParticleEnergyVector->FindBin(scaledTkin, 0);
196   G4double dEdx = fdEdxTable[coupleIndex]->Val << 208   size_t nPlace = fParticleEnergyVector->GetVectorLength() - 1;
197   std::size_t nPlace = fParticleEnergyVector-> << 
198   /*                                              209   /*
199   G4cout << "G4PAIModelData::DEDXPerVolume: co    210   G4cout << "G4PAIModelData::DEDXPerVolume: coupleIdx= " << coupleIndex
200    << " Tscaled= " << scaledTkin << " cut= " <    211    << " Tscaled= " << scaledTkin << " cut= " << cut 
201    << " iPlace= " << iPlace << " nPlace= " <<     212    << " iPlace= " << iPlace << " nPlace= " << nPlace << G4endl;
202   */                                              213   */
203   G4bool one = true;                              214   G4bool one = true;
204   if(scaledTkin >= fParticleEnergyVector->Ener    215   if(scaledTkin >= fParticleEnergyVector->Energy(nPlace)) { iPlace = nPlace; }
205   else if(scaledTkin > fParticleEnergyVector->    216   else if(scaledTkin > fParticleEnergyVector->Energy(0)) { 
206     one = false;                                  217     one = false; 
207   }                                               218   }
208                                                   219 
209   // VI: apply interpolation of the vector        220   // VI: apply interpolation of the vector
                                                   >> 221   G4double dEdx = fdEdxTable[coupleIndex]->Value(scaledTkin);
210   G4double del  = (*(fPAIdEdxBank[coupleIndex]    222   G4double del  = (*(fPAIdEdxBank[coupleIndex]))(iPlace)->Value(cut);
211   //G4cout << "dEdx= " << dEdx << " del= " <<     223   //G4cout << "dEdx= " << dEdx << " del= " << del << G4endl;
212   if(!one) {                                      224   if(!one) {
213     G4double del2 = (*(fPAIdEdxBank[coupleInde    225     G4double del2 = (*(fPAIdEdxBank[coupleIndex]))(iPlace+1)->Value(cut);
214     G4double E1 = fParticleEnergyVector->Energ    226     G4double E1 = fParticleEnergyVector->Energy(iPlace); 
215     G4double E2 = fParticleEnergyVector->Energ    227     G4double E2 = fParticleEnergyVector->Energy(iPlace+1);
216     G4double W  = 1.0/(E2 - E1);                  228     G4double W  = 1.0/(E2 - E1);
217     G4double W1 = (E2 - scaledTkin)*W;            229     G4double W1 = (E2 - scaledTkin)*W;
218     G4double W2 = (scaledTkin - E1)*W;            230     G4double W2 = (scaledTkin - E1)*W;
219     del *= W1;                                    231     del *= W1;
220     del += W2*del2;                               232     del += W2*del2;
221   }                                               233   }
222   dEdx -= del;                                    234   dEdx -= del;
223   //G4cout << "dEdx= " << dEdx << " del= " <<     235   //G4cout << "dEdx= " << dEdx << " del= " << del << G4endl;
224                                                   236 
225   dEdx = std::max(dEdx, 0.);                      237   dEdx = std::max(dEdx, 0.); 
226   return dEdx;                                    238   return dEdx;
227 }                                                 239 }
228                                                   240 
229 //////////////////////////////////////////////    241 /////////////////////////////////////////////////////////////////////////
230                                                   242 
231 G4double                                          243 G4double 
232 G4PAIModelData::CrossSectionPerVolume(G4int co    244 G4PAIModelData::CrossSectionPerVolume(G4int coupleIndex, 
233               G4double scaledTkin,                245               G4double scaledTkin,
234               G4double tcut, G4double tmax) co    246               G4double tcut, G4double tmax) const
235 {                                                 247 {
236   G4double cross, cross1, cross2;                 248   G4double cross, cross1, cross2;
237                                                   249 
238   // iPlace is in interval from 0 to (N-1)        250   // iPlace is in interval from 0 to (N-1)
239   std::size_t iPlace = fParticleEnergyVector-> << 251   size_t iPlace = fParticleEnergyVector->FindBin(scaledTkin, 0);
240   std::size_t nPlace = fParticleEnergyVector-> << 252   size_t nPlace = fParticleEnergyVector->GetVectorLength() - 1;
241                                                   253 
242   G4bool one = true;                              254   G4bool one = true;
243   if(scaledTkin >= fParticleEnergyVector->Ener    255   if(scaledTkin >= fParticleEnergyVector->Energy(nPlace)) { iPlace = nPlace; }
244   else if(scaledTkin > fParticleEnergyVector->    256   else if(scaledTkin > fParticleEnergyVector->Energy(0)) { 
245     one = false;                                  257     one = false; 
246   }                                               258   }
247   G4PhysicsTable* table = fPAIxscBank[coupleIn    259   G4PhysicsTable* table = fPAIxscBank[coupleIndex];
248                                                   260 
249   //G4cout<<"iPlace = "<<iPlace<<"; tmax = "      261   //G4cout<<"iPlace = "<<iPlace<<"; tmax = "
250   // <<tmax<<"; cutEnergy = "<<cutEnergy<<G4en    262   // <<tmax<<"; cutEnergy = "<<cutEnergy<<G4endl;  
251   cross1 = (*table)(iPlace)->Value(tmax)/tmax;    263   cross1 = (*table)(iPlace)->Value(tmax)/tmax;
252   //G4cout<<"cross1 = "<<cross1<<G4endl;          264   //G4cout<<"cross1 = "<<cross1<<G4endl;  
253   cross2 = (*table)(iPlace)->Value(tcut)/tcut;    265   cross2 = (*table)(iPlace)->Value(tcut)/tcut;
254   //G4cout<<"cross2 = "<<cross2<<G4endl;          266   //G4cout<<"cross2 = "<<cross2<<G4endl;  
255   cross  = (cross2-cross1);                       267   cross  = (cross2-cross1);
256   //G4cout<<"cross = "<<cross<<G4endl;            268   //G4cout<<"cross = "<<cross<<G4endl;  
257   if(!one) {                                      269   if(!one) {
258     cross2 = (*table)(iPlace+1)->Value(tcut)/t    270     cross2 = (*table)(iPlace+1)->Value(tcut)/tcut 
259       - (*table)(iPlace+1)->Value(tmax)/tmax;     271       - (*table)(iPlace+1)->Value(tmax)/tmax;
260                                                   272 
261     G4double E1 = fParticleEnergyVector->Energ    273     G4double E1 = fParticleEnergyVector->Energy(iPlace); 
262     G4double E2 = fParticleEnergyVector->Energ    274     G4double E2 = fParticleEnergyVector->Energy(iPlace+1);
263     G4double W  = 1.0/(E2 - E1);                  275     G4double W  = 1.0/(E2 - E1);
264     G4double W1 = (E2 - scaledTkin)*W;            276     G4double W1 = (E2 - scaledTkin)*W;
265     G4double W2 = (scaledTkin - E1)*W;            277     G4double W2 = (scaledTkin - E1)*W;
266     cross *= W1;                                  278     cross *= W1;
267     cross += W2*cross2;                           279     cross += W2*cross2;
268   }                                               280   }
269                                                   281 
270   cross = std::max(cross, 0.0);                   282   cross = std::max(cross, 0.0); 
271   return cross;                                   283   return cross;
272 }                                                 284 }
273                                                   285 
274 //////////////////////////////////////////////    286 ///////////////////////////////////////////////////////////////////////
275                                                   287 
276 G4double G4PAIModelData::SampleAlongStepTransf    288 G4double G4PAIModelData::SampleAlongStepTransfer(G4int coupleIndex, 
277                                                   289                                                  G4double kinEnergy,
278              G4double scaledTkin,                 290              G4double scaledTkin,
279              G4double tmax,                       291              G4double tmax,
280              G4double stepFactor) const           292              G4double stepFactor) const
281 {                                                 293 {
282   //G4cout << "=== G4PAIModelData::SampleAlong    294   //G4cout << "=== G4PAIModelData::SampleAlongStepTransfer" << G4endl;
283   G4double loss = 0.0;                            295   G4double loss = 0.0;
284                                                   296 
285   std::size_t iPlace = fParticleEnergyVector-> << 297   size_t iPlace = fParticleEnergyVector->FindBin(scaledTkin, 0);
286   std::size_t nPlace = fParticleEnergyVector-> << 298   size_t nPlace = fParticleEnergyVector->GetVectorLength() - 1;
287                                                   299  
288   G4bool one = true;                              300   G4bool one = true;
289   if(scaledTkin >= fParticleEnergyVector->Ener    301   if(scaledTkin >= fParticleEnergyVector->Energy(nPlace)) { iPlace = nPlace; }
290   else if(scaledTkin > fParticleEnergyVector->    302   else if(scaledTkin > fParticleEnergyVector->Energy(0)) { 
291     one = false;                                  303     one = false; 
292   }                                               304   }
293                                                   305 
294   G4double meanNumber = 0.0;                      306   G4double meanNumber = 0.0;
295   G4double meanN11 = 0.0;                         307   G4double meanN11 = 0.0;
296   G4double meanN12 = 0.0;                         308   G4double meanN12 = 0.0;
297   G4double meanN21 = 0.0;                         309   G4double meanN21 = 0.0;
298   G4double meanN22 = 0.0;                         310   G4double meanN22 = 0.0;
299                                                   311 
300   G4PhysicsVector* v1 = (*(fPAIxscBank[coupleI    312   G4PhysicsVector* v1 = (*(fPAIxscBank[coupleIndex]))(iPlace);
301   G4PhysicsVector* v2 = nullptr;               << 313   G4PhysicsVector* v2 = 0;
302                                                   314 
303   G4double e1 = v1->Energy(0);                    315   G4double e1 = v1->Energy(0);
304   G4double e2 = std::min(tmax, v1->GetMaxEnerg    316   G4double e2 = std::min(tmax, v1->GetMaxEnergy());
305                                                   317 
306   if(e2 >= e1) {                                  318   if(e2 >= e1) {
307     meanN11 = (*v1)[0]/e1;                        319     meanN11 = (*v1)[0]/e1;
308     meanN12 = v1->Value(e2)/e2;                   320     meanN12 = v1->Value(e2)/e2;
309     meanNumber = (meanN11 - meanN12)*stepFacto    321     meanNumber = (meanN11 - meanN12)*stepFactor;
310   }                                               322   }
311   //G4cout<<"iPlace = "<<iPlace<< " meanN11= "    323   //G4cout<<"iPlace = "<<iPlace<< " meanN11= " << meanN11
312   //  << " meanN12= " << meanN12 << G4endl;       324   //  << " meanN12= " << meanN12 << G4endl;
313                                                   325 
314   G4double W1 = 1.0;                              326   G4double W1 = 1.0;
315   G4double W2 = 0.0;                              327   G4double W2 = 0.0;
316   if(!one) {                                      328   if(!one) {
317     v2 = (*(fPAIxscBank[coupleIndex]))(iPlace+    329     v2 = (*(fPAIxscBank[coupleIndex]))(iPlace+1);
318                                                   330 
319     e1 = v2->Energy(0);                           331     e1 = v2->Energy(0);
320     e2 = std::min(tmax, v2->GetMaxEnergy());      332     e2 = std::min(tmax, v2->GetMaxEnergy());
321     if(e2 >= e1) {                                333     if(e2 >= e1) {
322       meanN21 = (*v2)[0]/e1;                      334       meanN21 = (*v2)[0]/e1;
323       meanN22 = v2->Value(e2)/e2;                 335       meanN22 = v2->Value(e2)/e2;
324       G4double E1 = fParticleEnergyVector->Ene    336       G4double E1 = fParticleEnergyVector->Energy(iPlace); 
325       G4double E2 = fParticleEnergyVector->Ene    337       G4double E2 = fParticleEnergyVector->Energy(iPlace+1);
326       G4double W = 1.0/(E2 - E1);                 338       G4double W = 1.0/(E2 - E1);
327       W1 = (E2 - scaledTkin)*W;                   339       W1 = (E2 - scaledTkin)*W;
328       W2 = (scaledTkin - E1)*W;                   340       W2 = (scaledTkin - E1)*W;
329       meanNumber *= W1;                           341       meanNumber *= W1;
330       meanNumber += (meanN21 - meanN22)*stepFa    342       meanNumber += (meanN21 - meanN22)*stepFactor*W2;
331     }                                             343     }
332   }                                               344   }
333                                                   345 
334   if(meanNumber < 0.0) { return loss; }           346   if(meanNumber < 0.0) { return loss; }
335   G4int numOfCollisions = (G4int)G4Poisson(mea << 347   G4int numOfCollisions = G4Poisson(meanNumber);
336                                                   348 
337   //G4cout << "meanNumber= " <<  meanNumber <<    349   //G4cout << "meanNumber= " <<  meanNumber << " N= " << numOfCollisions << G4endl;
338                                                   350 
339   if(0 == numOfCollisions) { return loss; }       351   if(0 == numOfCollisions) { return loss; }
340                                                   352 
341   G4double position, omega, omega2;               353   G4double position, omega, omega2;
342   for(G4int i=0; i< numOfCollisions; ++i) {       354   for(G4int i=0; i< numOfCollisions; ++i) {
343     G4double rand = G4UniformRand();              355     G4double rand = G4UniformRand();
344     position = meanN12 + (meanN11 - meanN12)*r    356     position = meanN12 + (meanN11 - meanN12)*rand;
345     omega = GetEnergyTransfer(coupleIndex, iPl    357     omega = GetEnergyTransfer(coupleIndex, iPlace, position);
346     //G4cout << "omega(keV)= " << omega/keV <<    358     //G4cout << "omega(keV)= " << omega/keV << G4endl;
347     if(!one) {                                    359     if(!one) {
348       position = meanN22 + (meanN21 - meanN22)    360       position = meanN22 + (meanN21 - meanN22)*rand;
349       omega2 = GetEnergyTransfer(coupleIndex,     361       omega2 = GetEnergyTransfer(coupleIndex, iPlace+1, position);
350       omega *= W1;                                362       omega *= W1;
351       omega += omega2*W2;                         363       omega += omega2*W2;
352     }                                             364     }
353     //G4cout << "omega(keV)= " << omega/keV <<    365     //G4cout << "omega(keV)= " << omega/keV << G4endl;
354                                                   366 
355     loss += omega;                                367     loss += omega;
356     if(loss > kinEnergy) { break; }               368     if(loss > kinEnergy) { break; }
357   }                                               369   }
358                                                   370   
359   //G4cout<<"PAIModelData AlongStepLoss = "<<l    371   //G4cout<<"PAIModelData AlongStepLoss = "<<loss/keV<<" keV"<<G4endl; 
360   if(loss > kinEnergy) { loss = kinEnergy; }      372   if(loss > kinEnergy) { loss = kinEnergy; }
361   else if(loss < 0.)   { loss = 0.; }             373   else if(loss < 0.)   { loss = 0.; }
362   return loss;                                    374   return loss;
363 }                                                 375 }
364                                                   376 
365 //////////////////////////////////////////////    377 ///////////////////////////////////////////////////////////////////////
366 //                                                378 //
367 // Returns post step PAI energy transfer > cut    379 // Returns post step PAI energy transfer > cut electron energy 
368 // according to passed scaled kinetic energy o    380 // according to passed scaled kinetic energy of particle
369                                                   381 
370 G4double G4PAIModelData::SamplePostStepTransfe    382 G4double G4PAIModelData::SamplePostStepTransfer(G4int coupleIndex, 
371             G4double scaledTkin,                  383             G4double scaledTkin,
372             G4double tmin,                        384             G4double tmin,
373             G4double tmax) const                  385             G4double tmax) const
374 {                                                 386 {  
375   //G4cout<<"=== G4PAIModelData::SamplePostSte    387   //G4cout<<"=== G4PAIModelData::SamplePostStepTransfer idx= "<< coupleIndex 
376   //  << " Tkin= " << scaledTkin << "  Tmax= "    388   //  << " Tkin= " << scaledTkin << "  Tmax= " << tmax << G4endl;
377   G4double transfer = 0.0;                        389   G4double transfer = 0.0;
378   G4double rand = G4UniformRand();                390   G4double rand = G4UniformRand();
379                                                   391 
380   std::size_t nPlace = fParticleEnergyVector-> << 392   size_t nPlace = fParticleEnergyVector->GetVectorLength() - 1;
381   std::size_t iPlace = fParticleEnergyVector-> << 393   size_t iPlace = fParticleEnergyVector->FindBin(scaledTkin, 0);
382                                                   394 
383   G4bool one = true;                              395   G4bool one = true;
384   if(scaledTkin >= fParticleEnergyVector->Ener    396   if(scaledTkin >= fParticleEnergyVector->Energy(nPlace)) { iPlace = nPlace; }
385   else if(scaledTkin > fParticleEnergyVector->    397   else if(scaledTkin > fParticleEnergyVector->Energy(0)) { 
386     one = false;                                  398     one = false; 
387   }                                               399   }
388   G4PhysicsTable* table = fPAIxscBank[coupleIn    400   G4PhysicsTable* table = fPAIxscBank[coupleIndex];
389   G4PhysicsVector* v1 = (*table)[iPlace];         401   G4PhysicsVector* v1 = (*table)[iPlace];
390                                                   402 
391   G4double emin = std::max(tmin, v1->Energy(0)    403   G4double emin = std::max(tmin, v1->Energy(0));
392   G4double emax = std::min(tmax, v1->GetMaxEne    404   G4double emax = std::min(tmax, v1->GetMaxEnergy());
393   if(emax < emin) { return transfer; }            405   if(emax < emin) { return transfer; }
394                                                   406 
395   G4double dNdx1 = v1->Value(emin)/emin;          407   G4double dNdx1 = v1->Value(emin)/emin;  
396   G4double dNdx2 = v1->Value(emax)/emax;          408   G4double dNdx2 = v1->Value(emax)/emax;  
397   /*                                              409   /*
398   G4cout << "iPlace= " << iPlace << " nPlace=     410   G4cout << "iPlace= " << iPlace << " nPlace= " << nPlace 
399    << "  emin= " << emin << "  emax= " << emax    411    << "  emin= " << emin << "  emax= " << emax 
400    << " dNdx1= " << dNdx1 << " dNdx2= " << dNd    412    << " dNdx1= " << dNdx1 << " dNdx2= " << dNdx2
401    << " one: " << one << G4endl;                  413    << " one: " << one << G4endl;
402   */                                              414   */
403   G4double position = dNdx2 + (dNdx1 - dNdx2)*    415   G4double position = dNdx2 + (dNdx1 - dNdx2)*rand;
404   transfer = GetEnergyTransfer(coupleIndex, iP    416   transfer = GetEnergyTransfer(coupleIndex, iPlace, position);
405                                                   417 
406   //G4cout<<"PAImodel PostStepTransfer = "<<tr    418   //G4cout<<"PAImodel PostStepTransfer = "<<transfer/keV<<" keV"
407   //  << " position= " << position << G4endl;     419   //  << " position= " << position << G4endl; 
408                                                   420 
409   if(!one) {                                      421   if(!one) {
410                                                   422 
411     G4PhysicsVector* v2 = (*table)[iPlace+1];     423     G4PhysicsVector* v2 = (*table)[iPlace+1];
412     emin = std::max(tmin, v2->Energy(0));         424     emin = std::max(tmin, v2->Energy(0));
413     emax = std::min(tmax, v2->GetMaxEnergy());    425     emax = std::min(tmax, v2->GetMaxEnergy());
414     if(emin <= emax) {                            426     if(emin <= emax) {
415       dNdx1 = v2->Value(emin)/emin;               427       dNdx1 = v2->Value(emin)/emin;  
416       dNdx2 = v2->Value(emax)/emax;               428       dNdx2 = v2->Value(emax)/emax;  
417                                                   429 
418       //G4cout << "  emax2= " << emax             430       //G4cout << "  emax2= " << emax 
419       //     << " dNdx2= " << dNdx2 << " dNdx1    431       //     << " dNdx2= " << dNdx2 << " dNdx1= " << dNdx1 << G4endl;
420                                                   432 
421       G4double E1 = fParticleEnergyVector->Ene    433       G4double E1 = fParticleEnergyVector->Energy(iPlace); 
422       G4double E2 = fParticleEnergyVector->Ene    434       G4double E2 = fParticleEnergyVector->Energy(iPlace+1);
423       G4double W  = 1.0/(E2 - E1);                435       G4double W  = 1.0/(E2 - E1);
424       G4double W1 = (E2 - scaledTkin)*W;          436       G4double W1 = (E2 - scaledTkin)*W;
425       G4double W2 = (scaledTkin - E1)*W;          437       G4double W2 = (scaledTkin - E1)*W;
426                                                   438     
427       //G4cout<< "E1= " << E1 << " E2= " << E2    439       //G4cout<< "E1= " << E1 << " E2= " << E2 <<" iPlace= " << iPlace 
428       //    << " W1= " << W1 << " W2= " << W2     440       //    << " W1= " << W1 << " W2= " << W2 <<G4endl;
429                                                   441     
430       position = dNdx2 + (dNdx1 - dNdx2)*rand;    442       position = dNdx2 + (dNdx1 - dNdx2)*rand;
431       G4double tr2 = GetEnergyTransfer(coupleI    443       G4double tr2 = GetEnergyTransfer(coupleIndex, iPlace+1, position);
432                                                   444 
433       //G4cout<<"PAImodel PostStepTransfer1 =     445       //G4cout<<"PAImodel PostStepTransfer1 = "<<tr2/keV<<" keV"
434       //    << " position= " << position << G4    446       //    << " position= " << position << G4endl; 
435       transfer *= W1;                             447       transfer *= W1;
436       transfer += tr2*W2;                         448       transfer += tr2*W2;
437     }                                             449     }
438   }                                               450   }
439   //G4cout<<"PAImodel PostStepTransfer = "<<tr    451   //G4cout<<"PAImodel PostStepTransfer = "<<transfer/keV<<" keV"
440   //  << " position= " << position << G4endl;     452   //  << " position= " << position << G4endl; 
441   transfer = std::max(transfer, 0.0);             453   transfer = std::max(transfer, 0.0);
442   return transfer;                                454   return transfer;
443 }                                                 455 }
444                                                   456 
445 //////////////////////////////////////////////    457 ///////////////////////////////////////////////////////////////////////
446 //                                                458 //
447 // Returns PAI energy transfer according to pa    459 // Returns PAI energy transfer according to passed 
448 // indexes of particle kinetic enegry and rand    460 // indexes of particle kinetic enegry and random x-section
449                                                   461 
450 G4double G4PAIModelData::GetEnergyTransfer(G4i    462 G4double G4PAIModelData::GetEnergyTransfer(G4int coupleIndex, 
451              std::size_t iPlace,               << 463              size_t iPlace, 
452              G4double position) const             464              G4double position) const
453 {                                                 465 { 
454   G4PhysicsVector* v = (*(fPAIxscBank[coupleIn    466   G4PhysicsVector* v = (*(fPAIxscBank[coupleIndex]))(iPlace); 
455   if(position*v->Energy(0) >= (*v)[0]) { retur    467   if(position*v->Energy(0) >= (*v)[0]) { return v->Energy(0); }
456                                                   468 
457   std::size_t iTransferMax = v->GetVectorLengt << 469   size_t iTransferMax = v->GetVectorLength() - 1;
458                                                   470 
459   std::size_t iTransfer;                       << 471   size_t iTransfer;
460   G4double x1(0.0), x2(0.0), y1(0.0), y2(0.0),    472   G4double x1(0.0), x2(0.0), y1(0.0), y2(0.0), energyTransfer;
461                                                   473 
462   //G4cout << "iPlace= " << iPlace << " iTrans    474   //G4cout << "iPlace= " << iPlace << " iTransferMax= " << iTransferMax << G4endl;
463   for(iTransfer=1; iTransfer<=iTransferMax; ++    475   for(iTransfer=1; iTransfer<=iTransferMax; ++iTransfer) {
464     x2 = v->Energy(iTransfer);                    476     x2 = v->Energy(iTransfer);
465     y2 = (*v)[iTransfer]/x2;                      477     y2 = (*v)[iTransfer]/x2;
466     if(position >= y2) { break; }                 478     if(position >= y2) { break; }
467     if(iTransfer == iTransferMax) { return v->    479     if(iTransfer == iTransferMax) { return v->GetMaxEnergy(); }
468   }                                               480   }
469                                                   481 
470   x1 = v->Energy(iTransfer-1);                    482   x1 = v->Energy(iTransfer-1);
471   y1 = (*v)[iTransfer-1]/x1;                      483   y1 = (*v)[iTransfer-1]/x1;
472   /*                                              484   /*
473   G4cout << "i= " << iTransfer << " imax= " <<    485   G4cout << "i= " << iTransfer << " imax= " << iTransferMax
474      << " x1= " << x1 << " x2= " << x2            486      << " x1= " << x1 << " x2= " << x2 
475      << " y1= " << y1 << " y2= " << y2 << G4en    487      << " y1= " << y1 << " y2= " << y2 << G4endl;
476   */                                              488   */
477   energyTransfer = x1;                            489   energyTransfer = x1;
478   if ( x1 != x2 ) {                               490   if ( x1 != x2 ) {
479     if ( y1 == y2  ) {                            491     if ( y1 == y2  ) {
480       energyTransfer += (x2 - x1)*G4UniformRan    492       energyTransfer += (x2 - x1)*G4UniformRand();
481     } else {                                      493     } else {
482       if(x1*1.1 < x2) {                           494       if(x1*1.1 < x2) {
483   const G4int nbins = 5;                          495   const G4int nbins = 5;
484         G4double del = (x2 - x1)/G4int(nbins);    496         G4double del = (x2 - x1)/G4int(nbins);
485         x2 = x1;                                  497         x2 = x1;
486         for(G4int i=1; i<=nbins; ++i) {           498         for(G4int i=1; i<=nbins; ++i) {
487           x2 += del;                              499           x2 += del;
488           y2 = v->Value(x2)/x2;                   500           y2 = v->Value(x2)/x2;
489           if(position >= y2) {                    501           if(position >= y2) { 
490       break;                                      502       break; 
491     }                                             503     }
492           x1 = x2;                                504           x1 = x2;
493           y1 = y2;                                505           y1 = y2;
494   }                                               506   }
495       }                                           507       }
496       //G4cout << "x1(keV)= " << x1/keV << " x    508       //G4cout << "x1(keV)= " << x1/keV << " x2(keV)= " << x2/keV
497       //   << " y1= " << y1 << " y2= " << y2 <    509       //   << " y1= " << y1 << " y2= " << y2 << " pos= " << position << G4endl;
498       energyTransfer = (y2 - y1)*x1*x2/(positi    510       energyTransfer = (y2 - y1)*x1*x2/(position*(x1 - x2) - y1*x1 + y2*x2);
499     }                                             511     }
500   }                                               512   }
501   //G4cout << "x1(keV)= " << x1/keV << " x2(ke    513   //G4cout << "x1(keV)= " << x1/keV << " x2(keV)= " << x2/keV
502   //   << " y1= " << y1 << " y2= " << y2 << "     514   //   << " y1= " << y1 << " y2= " << y2 << " pos= " << position
503   //   << " E(keV)= " << energyTransfer/keV <<    515   //   << " E(keV)= " << energyTransfer/keV << G4endl; 
504   return energyTransfer;                          516   return energyTransfer;
505 }                                                 517 }
506                                                   518 
507 //////////////////////////////////////////////    519 //////////////////////////////////////////////////////////////////////
508                                                   520 
509                                                   521