Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/electromagnetic/adjoint/src/G4VEmAdjointModel.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/adjoint/src/G4VEmAdjointModel.cc (Version 11.3.0) and /processes/electromagnetic/adjoint/src/G4VEmAdjointModel.cc (Version 2.0)


  1 //                                                  1 
  2 // *******************************************    
  3 // * License and Disclaimer                       
  4 // *                                              
  5 // * The  Geant4 software  is  copyright of th    
  6 // * the Geant4 Collaboration.  It is provided    
  7 // * conditions of the Geant4 Software License    
  8 // * LICENSE and available at  http://cern.ch/    
  9 // * include a list of copyright holders.         
 10 // *                                              
 11 // * Neither the authors of this software syst    
 12 // * institutes,nor the agencies providing fin    
 13 // * work  make  any representation or  warran    
 14 // * regarding  this  software system or assum    
 15 // * use.  Please see the license in the file     
 16 // * for the full disclaimer and the limitatio    
 17 // *                                              
 18 // * This  code  implementation is the result     
 19 // * technical work of the GEANT4 collaboratio    
 20 // * By using,  copying,  modifying or  distri    
 21 // * any work based  on the software)  you  ag    
 22 // * use  in  resulting  scientific  publicati    
 23 // * acceptance of all terms of the Geant4 Sof    
 24 // *******************************************    
 25 //                                                
 26                                                   
 27 #include "G4VEmAdjointModel.hh"                   
 28                                                   
 29 #include "G4AdjointCSManager.hh"                  
 30 #include "G4AdjointElectron.hh"                   
 31 #include "G4AdjointGamma.hh"                      
 32 #include "G4AdjointInterpolator.hh"               
 33 #include "G4AdjointPositron.hh"                   
 34 #include "G4Electron.hh"                          
 35 #include "G4Gamma.hh"                             
 36 #include "G4Integrator.hh"                        
 37 #include "G4ParticleChange.hh"                    
 38 #include "G4ProductionCutsTable.hh"               
 39 #include "G4TrackStatus.hh"                       
 40                                                   
 41 //////////////////////////////////////////////    
 42 G4VEmAdjointModel::G4VEmAdjointModel(const G4S    
 43   : fName(nam)                                    
 44 {                                                 
 45   fCSManager = G4AdjointCSManager::GetAdjointC    
 46   fCSManager->RegisterEmAdjointModel(this);       
 47 }                                                 
 48                                                   
 49 ///////////////////////////////////e//////////    
 50 G4VEmAdjointModel::~G4VEmAdjointModel()           
 51 {                                                 
 52   delete fCSMatrixProdToProjBackScat;             
 53   fCSMatrixProdToProjBackScat = nullptr;          
 54                                                   
 55   delete fCSMatrixProjToProjBackScat;             
 56   fCSMatrixProjToProjBackScat = nullptr;          
 57 }                                                 
 58                                                   
 59 //////////////////////////////////////////////    
 60 G4double G4VEmAdjointModel::AdjointCrossSectio    
 61   const G4MaterialCutsCouple* aCouple, G4doubl    
 62   G4bool isScatProjToProj)                        
 63 {                                                 
 64   DefineCurrentMaterial(aCouple);                 
 65   fPreStepEnergy = primEnergy;                    
 66                                                   
 67   std::vector<G4double>* CS_Vs_Element = &fEle    
 68   if(isScatProjToProj)                            
 69     CS_Vs_Element = &fElementCSScatProjToProj;    
 70   fLastCS =                                       
 71     fCSManager->ComputeAdjointCS(fCurrentMater    
 72                                  fTcutSecond,     
 73   if(isScatProjToProj)                            
 74     fLastAdjointCSForScatProjToProj = fLastCS;    
 75   else                                            
 76     fLastAdjointCSForProdToProj = fLastCS;        
 77                                                   
 78   return fLastCS;                                 
 79 }                                                 
 80                                                   
 81 //////////////////////////////////////////////    
 82 G4double G4VEmAdjointModel::DiffCrossSectionPe    
 83   G4double kinEnergyProj, G4double kinEnergyPr    
 84 {                                                 
 85   G4double dSigmadEprod = 0.;                     
 86   G4double Emax_proj    = GetSecondAdjEnergyMa    
 87   G4double Emin_proj    = GetSecondAdjEnergyMi    
 88                                                   
 89   // the produced particle should have a kinet    
 90   if(kinEnergyProj > Emin_proj && kinEnergyPro    
 91   {                                               
 92     G4double E1     = kinEnergyProd;              
 93     G4double E2     = kinEnergyProd * 1.000001    
 94     G4double sigma1 = fDirectModel->ComputeCro    
 95       fDirectPrimaryPart, kinEnergyProj, Z, A,    
 96     G4double sigma2 = fDirectModel->ComputeCro    
 97       fDirectPrimaryPart, kinEnergyProj, Z, A,    
 98                                                   
 99     dSigmadEprod = (sigma1 - sigma2) / (E2 - E    
100   }                                               
101   return dSigmadEprod;                            
102 }                                                 
103                                                   
104 //////////////////////////////////////////////    
105 G4double G4VEmAdjointModel::DiffCrossSectionPe    
106   G4double kinEnergyProj, G4double kinEnergySc    
107 {                                                 
108   G4double kinEnergyProd = kinEnergyProj - kin    
109   G4double dSigmadEprod;                          
110   if(kinEnergyProd <= 0.)                         
111     dSigmadEprod = 0.;                            
112   else                                            
113     dSigmadEprod =                                
114       DiffCrossSectionPerAtomPrimToSecond(kinE    
115   return dSigmadEprod;                            
116 }                                                 
117                                                   
118 //////////////////////////////////////////////    
119 G4double G4VEmAdjointModel::DiffCrossSectionPe    
120   const G4Material* aMaterial, G4double kinEne    
121 {                                                 
122   G4double dSigmadEprod = 0.;                     
123   G4double Emax_proj    = GetSecondAdjEnergyMa    
124   G4double Emin_proj    = GetSecondAdjEnergyMi    
125                                                   
126   if(kinEnergyProj > Emin_proj && kinEnergyPro    
127   {                                               
128     G4double E1     = kinEnergyProd;              
129     G4double E2     = kinEnergyProd * 1.0001;     
130     G4double sigma1 = fDirectModel->CrossSecti    
131       aMaterial, fDirectPrimaryPart, kinEnergy    
132     G4double sigma2 = fDirectModel->CrossSecti    
133       aMaterial, fDirectPrimaryPart, kinEnergy    
134     dSigmadEprod = (sigma1 - sigma2) / (E2 - E    
135   }                                               
136   return dSigmadEprod;                            
137 }                                                 
138                                                   
139 //////////////////////////////////////////////    
140 G4double G4VEmAdjointModel::DiffCrossSectionPe    
141   const G4Material* aMaterial, G4double kinEne    
142   G4double kinEnergyScatProj)                     
143 {                                                 
144   G4double kinEnergyProd = kinEnergyProj - kin    
145   G4double dSigmadEprod;                          
146   if(kinEnergyProd <= 0.)                         
147     dSigmadEprod = 0.;                            
148   else                                            
149     dSigmadEprod = DiffCrossSectionPerVolumePr    
150       aMaterial, kinEnergyProj, kinEnergyProd)    
151   return dSigmadEprod;                            
152 }                                                 
153                                                   
154 //////////////////////////////////////////////    
155 G4double G4VEmAdjointModel::DiffCrossSectionFu    
156 {                                                 
157   G4double bias_factor =                          
158     fCsBiasingFactor * fKinEnergyProdForIntegr    
159                                                   
160   if(fUseMatrixPerElement)                        
161   {                                               
162     return DiffCrossSectionPerAtomPrimToSecond    
163              kinEnergyProj, fKinEnergyProdForI    
164              fASelectedNucleus) *                 
165            bias_factor;                           
166   }                                               
167   else                                            
168   {                                               
169     return DiffCrossSectionPerVolumePrimToSeco    
170              fSelectedMaterial, kinEnergyProj,    
171            bias_factor;                           
172   }                                               
173 }                                                 
174                                                   
175 //////////////////////////////////////////////    
176 G4double G4VEmAdjointModel::DiffCrossSectionFu    
177 {                                                 
178   G4double bias_factor =                          
179     fCsBiasingFactor * fKinEnergyScatProjForIn    
180   if(fUseMatrixPerElement)                        
181   {                                               
182     return DiffCrossSectionPerAtomPrimToScatPr    
183              kinEnergyProj, fKinEnergyScatProj    
184              fASelectedNucleus) *                 
185            bias_factor;                           
186   }                                               
187   else                                            
188   {                                               
189     return DiffCrossSectionPerVolumePrimToScat    
190              fSelectedMaterial, kinEnergyProj,    
191              fKinEnergyScatProjForIntegration)    
192            bias_factor;                           
193   }                                               
194 }                                                 
195                                                   
196 //////////////////////////////////////////////    
197 std::vector<std::vector<G4double>*>               
198 G4VEmAdjointModel::ComputeAdjointCrossSectionV    
199   G4double kinEnergyProd, G4double Z, G4double    
200   G4int nbin_pro_decade)  // nb bins per order    
201 {                                                 
202   G4Integrator<G4VEmAdjointModel, G4double (G4    
203     integral;                                     
204   fASelectedNucleus            = G4lrint(A);      
205   fZSelectedNucleus            = G4lrint(Z);      
206   fKinEnergyProdForIntegration = kinEnergyProd    
207                                                   
208   // compute the vector of integrated cross se    
209   G4double minEProj = GetSecondAdjEnergyMinFor    
210   G4double maxEProj = GetSecondAdjEnergyMaxFor    
211   G4double E1       = minEProj;                   
212   std::vector<G4double>* log_ESec_vector = new    
213   std::vector<G4double>* log_Prob_vector = new    
214   log_ESec_vector->push_back(std::log(E1));       
215   log_Prob_vector->push_back(-50.);               
216                                                   
217   G4double E2 =                                   
218     std::pow(10., G4double(G4int(std::log10(mi    
219                     nbin_pro_decade);             
220   G4double fE = std::pow(10., 1. / nbin_pro_de    
221                                                   
222   if(std::pow(fE, 5.) > (maxEProj / minEProj))    
223     fE = std::pow(maxEProj / minEProj, 0.2);      
224                                                   
225   G4double int_cross_section = 0.;                
226   // Loop checking, 07-Aug-2015, Vladimir Ivan    
227   while(E1 < maxEProj * 0.9999999)                
228   {                                               
229     int_cross_section +=                          
230       integral.Simpson(this, &G4VEmAdjointMode    
231                        std::min(E2, maxEProj *    
232     log_ESec_vector->push_back(std::log(std::m    
233     log_Prob_vector->push_back(std::log(int_cr    
234     E1 = E2;                                      
235     E2 *= fE;                                     
236   }                                               
237   std::vector<std::vector<G4double>*> res_mat;    
238   if(int_cross_section > 0.)                      
239   {                                               
240     res_mat.push_back(log_ESec_vector);           
241     res_mat.push_back(log_Prob_vector);           
242   }                                               
243   else {                                          
244   delete  log_ESec_vector;                        
245   delete  log_Prob_vector;                        
246   }                                               
247   return res_mat;                                 
248 }                                                 
249                                                   
250 //////////////////////////////////////////////    
251 std::vector<std::vector<G4double>*>               
252 G4VEmAdjointModel::ComputeAdjointCrossSectionV    
253   G4double kinEnergyScatProj, G4double Z, G4do    
254   G4int nbin_pro_decade)  // nb bins pro order    
255 {                                                 
256   G4Integrator<G4VEmAdjointModel, G4double (G4    
257     integral;                                     
258   fASelectedNucleus                = G4lrint(A    
259   fZSelectedNucleus                = G4lrint(Z    
260   fKinEnergyScatProjForIntegration = kinEnergy    
261                                                   
262   // compute the vector of integrated cross se    
263   G4double minEProj = GetSecondAdjEnergyMinFor    
264   G4double maxEProj = GetSecondAdjEnergyMaxFor    
265   G4double dEmax    = maxEProj - kinEnergyScat    
266   G4double dEmin    = GetLowEnergyLimit();        
267   G4double dE1      = dEmin;                      
268   G4double dE2      = dEmin;                      
269                                                   
270   std::vector<G4double>* log_ESec_vector = new    
271   std::vector<G4double>* log_Prob_vector = new    
272   log_ESec_vector->push_back(std::log(dEmin));    
273   log_Prob_vector->push_back(-50.);               
274   G4int nbins = std::max(G4int(std::log10(dEma    
275   G4double fE = std::pow(dEmax / dEmin, 1. / n    
276                                                   
277   G4double int_cross_section = 0.;                
278   // Loop checking, 07-Aug-2015, Vladimir Ivan    
279   while(dE1 < dEmax * 0.9999999999999)            
280   {                                               
281     dE2 = dE1 * fE;                               
282     int_cross_section +=                          
283       integral.Simpson(this, &G4VEmAdjointMode    
284                        minEProj + dE1, std::mi    
285     log_ESec_vector->push_back(std::log(std::m    
286     log_Prob_vector->push_back(std::log(int_cr    
287     dE1 = dE2;                                    
288   }                                               
289                                                   
290   std::vector<std::vector<G4double>*> res_mat;    
291   if(int_cross_section > 0.)                      
292   {                                               
293     res_mat.push_back(log_ESec_vector);           
294     res_mat.push_back(log_Prob_vector);           
295   }                                               
296   else {                                          
297     delete  log_ESec_vector;                      
298     delete  log_Prob_vector;                      
299   }                                               
300                                                   
301   return res_mat;                                 
302 }                                                 
303                                                   
304 //////////////////////////////////////////////    
305 std::vector<std::vector<G4double>*>               
306 G4VEmAdjointModel::ComputeAdjointCrossSectionV    
307   G4Material* aMaterial, G4double kinEnergyPro    
308   G4int nbin_pro_decade)  // nb bins pro order    
309 {                                                 
310   G4Integrator<G4VEmAdjointModel, G4double (G4    
311     integral;                                     
312   fSelectedMaterial            = aMaterial;       
313   fKinEnergyProdForIntegration = kinEnergyProd    
314                                                   
315   // compute the vector of integrated cross se    
316   G4double minEProj = GetSecondAdjEnergyMinFor    
317   G4double maxEProj = GetSecondAdjEnergyMaxFor    
318   G4double E1       = minEProj;                   
319   std::vector<G4double>* log_ESec_vector = new    
320   std::vector<G4double>* log_Prob_vector = new    
321   log_ESec_vector->push_back(std::log(E1));       
322   log_Prob_vector->push_back(-50.);               
323                                                   
324   G4double E2 =                                   
325     std::pow(10., G4double(G4int(std::log10(mi    
326                     nbin_pro_decade);             
327   G4double fE = std::pow(10., 1. / nbin_pro_de    
328                                                   
329   if(std::pow(fE, 5.) > (maxEProj / minEProj))    
330     fE = std::pow(maxEProj / minEProj, 0.2);      
331                                                   
332   G4double int_cross_section = 0.;                
333   // Loop checking, 07-Aug-2015, Vladimir Ivan    
334   while(E1 < maxEProj * 0.9999999)                
335   {                                               
336     int_cross_section +=                          
337       integral.Simpson(this, &G4VEmAdjointMode    
338                        std::min(E2, maxEProj *    
339     log_ESec_vector->push_back(std::log(std::m    
340     log_Prob_vector->push_back(std::log(int_cr    
341     E1 = E2;                                      
342     E2 *= fE;                                     
343   }                                               
344   std::vector<std::vector<G4double>*> res_mat;    
345                                                   
346   if(int_cross_section > 0.)                      
347   {                                               
348     res_mat.push_back(log_ESec_vector);           
349     res_mat.push_back(log_Prob_vector);           
350   }                                               
351   else {                                          
352     delete  log_ESec_vector;                      
353     delete  log_Prob_vector;                      
354   }                                               
355   return res_mat;                                 
356 }                                                 
357                                                   
358 //////////////////////////////////////////////    
359 std::vector<std::vector<G4double>*>               
360 G4VEmAdjointModel::ComputeAdjointCrossSectionV    
361   G4Material* aMaterial, G4double kinEnergySca    
362   G4int nbin_pro_decade)  // nb bins pro order    
363 {                                                 
364   G4Integrator<G4VEmAdjointModel, G4double (G4    
365     integral;                                     
366   fSelectedMaterial                = aMaterial    
367   fKinEnergyScatProjForIntegration = kinEnergy    
368                                                   
369   // compute the vector of integrated cross se    
370   G4double minEProj = GetSecondAdjEnergyMinFor    
371   G4double maxEProj = GetSecondAdjEnergyMaxFor    
372                                                   
373   G4double dEmax = maxEProj - kinEnergyScatPro    
374   G4double dEmin = GetLowEnergyLimit();           
375   G4double dE1   = dEmin;                         
376   G4double dE2   = dEmin;                         
377                                                   
378   std::vector<G4double>* log_ESec_vector = new    
379   std::vector<G4double>* log_Prob_vector = new    
380   log_ESec_vector->push_back(std::log(dEmin));    
381   log_Prob_vector->push_back(-50.);               
382   G4int nbins = std::max(int(std::log10(dEmax     
383   G4double fE = std::pow(dEmax / dEmin, 1. / n    
384                                                   
385   G4double int_cross_section = 0.;                
386   // Loop checking, 07-Aug-2015, Vladimir Ivan    
387   while(dE1 < dEmax * 0.9999999999999)            
388   {                                               
389     dE2 = dE1 * fE;                               
390     int_cross_section +=                          
391       integral.Simpson(this, &G4VEmAdjointMode    
392                        minEProj + dE1, std::mi    
393     log_ESec_vector->push_back(std::log(std::m    
394     log_Prob_vector->push_back(std::log(int_cr    
395     dE1 = dE2;                                    
396   }                                               
397                                                   
398   std::vector<std::vector<G4double>*> res_mat;    
399   if(int_cross_section > 0.)                      
400   {                                               
401     res_mat.push_back(log_ESec_vector);           
402     res_mat.push_back(log_Prob_vector);           
403   }                                               
404   else {                                          
405     delete  log_ESec_vector;                      
406     delete  log_Prob_vector;                      
407   }                                               
408                                                   
409   return res_mat;                                 
410 }                                                 
411                                                   
412 //////////////////////////////////////////////    
413 G4double G4VEmAdjointModel::SampleAdjSecEnergy    
414   std::size_t MatrixIndex, G4double aPrimEnerg    
415 {                                                 
416   G4AdjointCSMatrix* theMatrix = (*fCSMatrixPr    
417   if(isScatProjToProj)                            
418     theMatrix = (*fCSMatrixProjToProjBackScat)    
419   std::vector<G4double>* theLogPrimEnergyVecto    
420     theMatrix->GetLogPrimEnergyVector();          
421                                                   
422   if(theLogPrimEnergyVector->empty())             
423   {                                               
424     G4cout << "No data are contained in the gi    
425     G4cout << "The sampling procedure will be     
426     return 0.;                                    
427   }                                               
428                                                   
429   G4AdjointInterpolator* theInterpolator = G4A    
430   G4double aLogPrimEnergy                = std    
431   G4int ind = (G4int)theInterpolator->FindPosi    
432     aLogPrimEnergy, *theLogPrimEnergyVector);     
433                                                   
434   G4double aLogPrimEnergy1, aLogPrimEnergy2;      
435   G4double aLogCS1, aLogCS2;                      
436   G4double log01, log02;                          
437   std::vector<G4double>* aLogSecondEnergyVecto    
438   std::vector<G4double>* aLogSecondEnergyVecto    
439   std::vector<G4double>* aLogProbVector1          
440   std::vector<G4double>* aLogProbVector2          
441   std::vector<std::size_t>* aLogProbVectorInde    
442   std::vector<std::size_t>* aLogProbVectorInde    
443                                                   
444   theMatrix->GetData(ind, aLogPrimEnergy1, aLo    
445                      aLogSecondEnergyVector1,     
446            aLogProbVectorIndex1 );                
447   theMatrix->GetData(ind + 1, aLogPrimEnergy2,    
448                      aLogSecondEnergyVector2,     
449                      aLogProbVectorIndex2);       
450                                                   
451   if (! (aLogProbVector1 && aLogProbVector2 &&    
452            aLogSecondEnergyVector1 && aLogSeco    
453    return  0.;                                    
454   }                                               
455                                                   
456   G4double rand_var     = G4UniformRand();        
457   G4double log_rand_var = std::log(rand_var);     
458   G4double log_Tcut     = std::log(fTcutSecond    
459   G4double Esec         = 0.;                     
460   G4double log_dE1, log_dE2;                      
461   G4double log_rand_var1, log_rand_var2;          
462   G4double log_E1, log_E2;                        
463   log_rand_var1 = log_rand_var;                   
464   log_rand_var2 = log_rand_var;                   
465                                                   
466   G4double Emin = 0.;                             
467   G4double Emax = 0.;                             
468   if(theMatrix->IsScatProjToProj())               
469   {  // case where Tcut plays a role              
470     Emin = GetSecondAdjEnergyMinForScatProjToP    
471     Emax = GetSecondAdjEnergyMaxForScatProjToP    
472     G4double dE = 0.;                             
473     if(Emin < Emax)                               
474     {                                             
475       if(fApplyCutInRange)                        
476       {                                           
477         if(fSecondPartSameType && fTcutSecond     
478           return aPrimEnergy;                     
479                                                   
480         log_rand_var1 = log_rand_var +            
481                         theInterpolator->Inter    
482                           log_Tcut, *aLogSecon    
483         log_rand_var2 = log_rand_var +            
484                         theInterpolator->Inter    
485                           log_Tcut, *aLogSecon    
486       }                                           
487       log_dE1 = theInterpolator->Interpolate(l    
488                                              *    
489       log_dE2 = theInterpolator->Interpolate(l    
490                                              *    
491       dE      = std::exp(theInterpolator->Line    
492         aLogPrimEnergy, aLogPrimEnergy1, aLogP    
493     }                                             
494                                                   
495     Esec = aPrimEnergy + dE;                      
496     Esec = std::max(Esec, Emin);                  
497     Esec = std::min(Esec, Emax);                  
498   }                                               
499   else                                            
500   {  // Tcut condition is already full-filled     
501                                                   
502     log_E1 = theInterpolator->Interpolate(log_    
503                                           *aLo    
504     log_E2 = theInterpolator->Interpolate(log_    
505                                           *aLo    
506                                                   
507     Esec = std::exp(theInterpolator->LinearInt    
508       aLogPrimEnergy, aLogPrimEnergy1, aLogPri    
509     Emin = GetSecondAdjEnergyMinForProdToProj(    
510     Emax = GetSecondAdjEnergyMaxForProdToProj(    
511     Esec = std::max(Esec, Emin);                  
512     Esec = std::min(Esec, Emax);                  
513   }                                               
514   return Esec;                                    
515 }                                                 
516                                                   
517 //////////////////////////////////////////////    
518 G4double G4VEmAdjointModel::SampleAdjSecEnergy    
519   G4double aPrimEnergy, G4bool isScatProjToPro    
520 {                                                 
521   SelectCSMatrix(isScatProjToProj);               
522   return SampleAdjSecEnergyFromCSMatrix(fCSMat    
523                                         isScat    
524 }                                                 
525                                                   
526 //////////////////////////////////////////////    
527 void G4VEmAdjointModel::SelectCSMatrix(G4bool     
528 {                                                 
529   fCSMatrixUsed = 0;                              
530   if(!fUseMatrixPerElement)                       
531     fCSMatrixUsed = fCurrentMaterial->GetIndex    
532   else if(!fOneMatrixForAllElements)              
533   {  // Select Material                           
534     std::vector<G4double>* CS_Vs_Element = &fE    
535     fLastCS                              = fLa    
536     if(!isScatProjToProj)                         
537     {                                             
538       CS_Vs_Element = &fElementCSProdToProj;      
539       fLastCS       = fLastAdjointCSForProdToP    
540     }                                             
541     G4double SumCS = 0.;                          
542     std::size_t ind = 0;                          
543     for(std::size_t i = 0; i < CS_Vs_Element->    
544     {                                             
545       SumCS += (*CS_Vs_Element)[i];               
546       if(G4UniformRand() <= SumCS / fLastCS)      
547       {                                           
548         ind = i;                                  
549         break;                                    
550       }                                           
551     }                                             
552     fCSMatrixUsed = fCurrentMaterial->GetEleme    
553   }                                               
554 }                                                 
555                                                   
556 //////////////////////////////////////////////    
557 G4double G4VEmAdjointModel::SampleAdjSecEnergy    
558   G4double prim_energy, G4bool isScatProjToPro    
559 {                                                 
560   // here we try to use the rejection method      
561   constexpr G4int iimax = 1000;                   
562   G4double E            = 0.;                     
563   G4double x, xmin, greject;                      
564   if(isScatProjToProj)                            
565   {                                               
566     G4double Emax = GetSecondAdjEnergyMaxForSc    
567     G4double Emin = prim_energy + fTcutSecond;    
568     xmin          = Emin / Emax;                  
569     G4double grejmax =                            
570       DiffCrossSectionPerAtomPrimToScatPrim(Em    
571                                                   
572     G4int ii = 0;                                 
573     do                                            
574     {                                             
575       // q = G4UniformRand();                     
576       x = 1. / (G4UniformRand() * (1. / xmin -    
577       E = x * Emax;                               
578       greject =                                   
579         DiffCrossSectionPerAtomPrimToScatPrim(    
580       ++ii;                                       
581       if(ii >= iimax)                             
582       {                                           
583         break;                                    
584       }                                           
585     }                                             
586     // Loop checking, 07-Aug-2015, Vladimir Iv    
587     while(greject < G4UniformRand() * grejmax)    
588   }                                               
589   else                                            
590   {                                               
591     G4double Emax = GetSecondAdjEnergyMaxForPr    
592     G4double Emin = GetSecondAdjEnergyMinForPr    
593     xmin          = Emin / Emax;                  
594     G4double grejmax =                            
595       DiffCrossSectionPerAtomPrimToSecond(Emin    
596     G4int ii = 0;                                 
597     do                                            
598     {                                             
599       x       = std::pow(xmin, G4UniformRand()    
600       E       = x * Emax;                         
601       greject = DiffCrossSectionPerAtomPrimToS    
602       ++ii;                                       
603       if(ii >= iimax)                             
604       {                                           
605         break;                                    
606       }                                           
607     }                                             
608     // Loop checking, 07-Aug-2015, Vladimir Iv    
609     while(greject < G4UniformRand() * grejmax)    
610   }                                               
611                                                   
612   return E;                                       
613 }                                                 
614                                                   
615 //////////////////////////////////////////////    
616 void G4VEmAdjointModel::CorrectPostStepWeight(    
617                                                   
618                                                   
619                                                   
620                                                   
621 {                                                 
622   G4double new_weight = old_weight;               
623   G4double w_corr =                               
624     fCSManager->GetPostStepWeightCorrection()     
625                                                   
626   fLastCS = fLastAdjointCSForScatProjToProj;      
627   if(!isScatProjToProj)                           
628     fLastCS = fLastAdjointCSForProdToProj;        
629   if((adjointPrimKinEnergy - fPreStepEnergy) /    
630   {                                               
631     G4double post_stepCS = AdjointCrossSection    
632       fCurrentCouple, adjointPrimKinEnergy, is    
633     if(post_stepCS > 0. && fLastCS > 0.)          
634       w_corr *= post_stepCS / fLastCS;            
635   }                                               
636                                                   
637   new_weight *= w_corr;                           
638   new_weight *= projectileKinEnergy / adjointP    
639   // This is needed due to the biasing of diff    
640   // by the factor adjointPrimKinEnergy/projec    
641                                                   
642   fParticleChange->SetParentWeightByProcess(fa    
643   fParticleChange->SetSecondaryWeightByProcess    
644   fParticleChange->ProposeParentWeight(new_wei    
645 }                                                 
646                                                   
647 //////////////////////////////////////////////    
648 G4double G4VEmAdjointModel::GetSecondAdjEnergy    
649   G4double kinEnergyScatProj)                     
650 {                                                 
651   G4double maxEProj = GetHighEnergyLimit();       
652   if(fSecondPartSameType)                         
653     maxEProj = std::min(kinEnergyScatProj * 2.    
654   return maxEProj;                                
655 }                                                 
656                                                   
657 //////////////////////////////////////////////    
658 G4double G4VEmAdjointModel::GetSecondAdjEnergy    
659   G4double primAdjEnergy, G4double tcut)          
660 {                                                 
661   G4double Emin = primAdjEnergy;                  
662   if(fApplyCutInRange)                            
663     Emin += tcut;                                 
664   return Emin;                                    
665 }                                                 
666                                                   
667 //////////////////////////////////////////////    
668 G4double G4VEmAdjointModel::GetSecondAdjEnergy    
669 {                                                 
670   return fHighEnergyLimit;                        
671 }                                                 
672                                                   
673 //////////////////////////////////////////////    
674 G4double G4VEmAdjointModel::GetSecondAdjEnergy    
675   G4double primAdjEnergy)                         
676 {                                                 
677   G4double minEProj = primAdjEnergy;              
678   if(fSecondPartSameType)                         
679     minEProj = primAdjEnergy * 2.;                
680   return minEProj;                                
681 }                                                 
682                                                   
683 //////////////////////////////////////////////    
684 void G4VEmAdjointModel::DefineCurrentMaterial(    
685   const G4MaterialCutsCouple* couple)             
686 {                                                 
687   if(couple != fCurrentCouple)                    
688   {                                               
689     fCurrentCouple   = const_cast<G4MaterialCu    
690     fCurrentMaterial = const_cast<G4Material*>    
691     std::size_t idx       = 56;                   
692     fTcutSecond      = 1.e-11;                    
693     if(fAdjEquivDirectSecondPart)                 
694     {                                             
695       if(fAdjEquivDirectSecondPart == G4Adjoin    
696         idx = 0;                                  
697       else if(fAdjEquivDirectSecondPart == G4A    
698         idx = 1;                                  
699       else if(fAdjEquivDirectSecondPart == G4A    
700         idx = 2;                                  
701       if(idx < 56)                                
702       {                                           
703         const std::vector<G4double>* aVec =       
704           G4ProductionCutsTable::GetProduction    
705             idx);                                 
706         fTcutSecond = (*aVec)[couple->GetIndex    
707       }                                           
708     }                                             
709   }                                               
710 }                                                 
711                                                   
712 //////////////////////////////////////////////    
713 void G4VEmAdjointModel::SetHighEnergyLimit(G4d    
714 {                                                 
715   fHighEnergyLimit = aVal;                        
716   if(fDirectModel)                                
717     fDirectModel->SetHighEnergyLimit(aVal);       
718 }                                                 
719                                                   
720 //////////////////////////////////////////////    
721 void G4VEmAdjointModel::SetLowEnergyLimit(G4do    
722 {                                                 
723   fLowEnergyLimit = aVal;                         
724   if(fDirectModel)                                
725     fDirectModel->SetLowEnergyLimit(aVal);        
726 }                                                 
727                                                   
728 //////////////////////////////////////////////    
729 void G4VEmAdjointModel::SetAdjointEquivalentOf    
730   G4ParticleDefinition* aPart)                    
731 {                                                 
732   fAdjEquivDirectPrimPart = aPart;                
733   if(fAdjEquivDirectPrimPart->GetParticleName(    
734     fDirectPrimaryPart = G4Electron::Electron(    
735   else if(fAdjEquivDirectPrimPart->GetParticle    
736     fDirectPrimaryPart = G4Gamma::Gamma();        
737 }                                                 
738