Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/hadronic/models/coherent_elastic/src/G4NuclNuclDiffuseElastic.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/hadronic/models/coherent_elastic/src/G4NuclNuclDiffuseElastic.cc (Version 11.3.0) and /processes/hadronic/models/coherent_elastic/src/G4NuclNuclDiffuseElastic.cc (Version 9.2.p4)


  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 //                                                
 28 // Physics model class G4NuclNuclDiffuseElasti    
 29 //                                                
 30 //                                                
 31 // G4 Model: optical diffuse elastic scatterin    
 32 //                                                
 33 // 24-May-07 V. Grichine                          
 34 //                                                
 35                                                   
 36 #include "G4NuclNuclDiffuseElastic.hh"            
 37 #include "G4ParticleTable.hh"                     
 38 #include "G4ParticleDefinition.hh"                
 39 #include "G4IonTable.hh"                          
 40 #include "G4NucleiProperties.hh"                  
 41                                                   
 42 #include "Randomize.hh"                           
 43 #include "G4Integrator.hh"                        
 44 #include "globals.hh"                             
 45 #include "G4PhysicalConstants.hh"                 
 46 #include "G4SystemOfUnits.hh"                     
 47                                                   
 48 #include "G4Proton.hh"                            
 49 #include "G4Neutron.hh"                           
 50 #include "G4Deuteron.hh"                          
 51 #include "G4Alpha.hh"                             
 52 #include "G4PionPlus.hh"                          
 53 #include "G4PionMinus.hh"                         
 54                                                   
 55 #include "G4Element.hh"                           
 56 #include "G4ElementTable.hh"                      
 57 #include "G4NistManager.hh"                       
 58 #include "G4PhysicsTable.hh"                      
 59 #include "G4PhysicsLogVector.hh"                  
 60 #include "G4PhysicsFreeVector.hh"                 
 61 #include "G4HadronicParameters.hh"                
 62                                                   
 63 //////////////////////////////////////////////    
 64 //                                                
 65 // Test Constructor. Just to check xsc            
 66                                                   
 67                                                   
 68 G4NuclNuclDiffuseElastic::G4NuclNuclDiffuseEla    
 69   : G4HadronElastic("NNDiffuseElastic"), fPart    
 70 {                                                 
 71   SetMinEnergy( 50*MeV );                         
 72   SetMaxEnergy( G4HadronicParameters::Instance    
 73   verboseLevel = 0;                               
 74   lowEnergyRecoilLimit = 100.*keV;                
 75   lowEnergyLimitQ  = 0.0*GeV;                     
 76   lowEnergyLimitHE = 0.0*GeV;                     
 77   lowestEnergyLimit= 0.0*keV;                     
 78   plabLowLimit     = 20.0*MeV;                    
 79                                                   
 80   theProton   = G4Proton::Proton();               
 81   theNeutron  = G4Neutron::Neutron();             
 82   theDeuteron = G4Deuteron::Deuteron();           
 83   theAlpha    = G4Alpha::Alpha();                 
 84   thePionPlus = G4PionPlus::PionPlus();           
 85   thePionMinus= G4PionMinus::PionMinus();         
 86                                                   
 87   fEnergyBin = 300;  // Increased from the ori    
 88   fAngleBin  = 200;                               
 89                                                   
 90   fEnergyVector =  new G4PhysicsLogVector( the    
 91   fAngleTable = 0;                                
 92                                                   
 93   fParticle = 0;                                  
 94   fWaveVector = 0.;                               
 95   fAtomicWeight = 0.;                             
 96   fAtomicNumber = 0.;                             
 97   fNuclearRadius = 0.;                            
 98   fBeta = 0.;                                     
 99   fZommerfeld = 0.;                               
100   fAm = 0.;                                       
101   fAddCoulomb = false;                            
102   // Ranges of angle table relative to current    
103                                                   
104   // Empirical parameters                         
105                                                   
106   fCofAlphaMax     = 1.5;                         
107   fCofAlphaCoulomb = 0.5;                         
108                                                   
109   fProfileDelta  = 1.;                            
110   fProfileAlpha  = 0.5;                           
111                                                   
112   fCofLambda = 1.0;                               
113   fCofDelta  = 0.04;                              
114   fCofAlpha  = 0.095;                             
115                                                   
116   fNuclearRadius1 = fNuclearRadius2 = fNuclear    
117     = fRutherfordRatio = fCoulombPhase0 = fHal    
118     = fRutherfordTheta = fProfileLambda = fCof    
119     = fSumSigma = fEtaRatio = fReZ = 0.0;         
120   fMaxL = 0;                                      
121                                                   
122   fNuclearRadiusCof = 1.0;                        
123   fCoulombMuC = 0.0;                              
124 }                                                 
125                                                   
126 //////////////////////////////////////////////    
127 //                                                
128 // Destructor                                     
129                                                   
130 G4NuclNuclDiffuseElastic::~G4NuclNuclDiffuseEl    
131 {                                                 
132   if ( fEnergyVector ) {                          
133     delete fEnergyVector;                         
134     fEnergyVector = 0;                            
135   }                                               
136                                                   
137   for ( std::vector<G4PhysicsTable*>::iterator    
138         it != fAngleBank.end(); ++it ) {          
139     if ( (*it) ) (*it)->clearAndDestroy();        
140     delete *it;                                   
141     *it = 0;                                      
142   }                                               
143   fAngleTable = 0;                                
144 }                                                 
145                                                   
146 //////////////////////////////////////////////    
147 //                                                
148 // Initialisation for given particle using ele    
149                                                   
150 void G4NuclNuclDiffuseElastic::Initialise()       
151 {                                                 
152                                                   
153   // fEnergyVector = new G4PhysicsLogVector( t    
154                                                   
155   const G4ElementTable* theElementTable = G4El    
156   std::size_t jEl, numOfEl = G4Element::GetNum    
157                                                   
158   // projectile radius                            
159                                                   
160   G4double A1 = G4double( fParticle->GetBaryon    
161   G4double R1 = CalculateNuclearRad(A1);          
162                                                   
163   for(jEl = 0 ; jEl < numOfEl; ++jEl) // appli    
164   {                                               
165     fAtomicNumber = (*theElementTable)[jEl]->G    
166     fAtomicWeight = G4NistManager::Instance()-    
167                                                   
168     fNuclearRadius = CalculateNuclearRad(fAtom    
169     fNuclearRadius += R1;                         
170                                                   
171     if(verboseLevel > 0)                          
172     {                                             
173       G4cout<<"G4NuclNuclDiffuseElastic::Initi    
174       <<(*theElementTable)[jEl]->GetName()<<G4    
175     }                                             
176     fElementNumberVector.push_back(fAtomicNumb    
177     fElementNameVector.push_back((*theElementT    
178                                                   
179     BuildAngleTable();                            
180     fAngleBank.push_back(fAngleTable);            
181   }                                               
182 }                                                 
183                                                   
184                                                   
185 //////////////////////////////////////////////    
186 //                                                
187 // return differential elastic cross section d    
188                                                   
189 G4double                                          
190 G4NuclNuclDiffuseElastic::GetDiffuseElasticXsc    
191                                         G4doub    
192                       G4double momentum,          
193                                         G4doub    
194 {                                                 
195   fParticle      = particle;                      
196   fWaveVector    = momentum/hbarc;                
197   fAtomicWeight  = A;                             
198   fAddCoulomb    = false;                         
199   fNuclearRadius = CalculateNuclearRad(A);        
200                                                   
201   G4double sigma = fNuclearRadius*fNuclearRadi    
202                                                   
203   return sigma;                                   
204 }                                                 
205                                                   
206 //////////////////////////////////////////////    
207 //                                                
208 // return invariant differential elastic cross    
209                                                   
210 G4double                                          
211 G4NuclNuclDiffuseElastic::GetInvElasticXsc( co    
212                                         G4doub    
213                       G4double plab,              
214                                         G4doub    
215 {                                                 
216   G4double m1 = particle->GetPDGMass();           
217   G4LorentzVector lv1(0.,0.,plab,std::sqrt(pla    
218                                                   
219   G4int iZ = static_cast<G4int>(Z+0.5);           
220   G4int iA = static_cast<G4int>(A+0.5);           
221   G4ParticleDefinition * theDef = 0;              
222                                                   
223   if      (iZ == 1 && iA == 1) theDef = thePro    
224   else if (iZ == 1 && iA == 2) theDef = theDeu    
225   else if (iZ == 1 && iA == 3) theDef = G4Trit    
226   else if (iZ == 2 && iA == 3) theDef = G4He3:    
227   else if (iZ == 2 && iA == 4) theDef = theAlp    
228   else theDef = G4ParticleTable::GetParticleTa    
229                                                   
230   G4double tmass = theDef->GetPDGMass();          
231                                                   
232   G4LorentzVector lv(0.0,0.0,0.0,tmass);          
233   lv += lv1;                                      
234                                                   
235   G4ThreeVector bst = lv.boostVector();           
236   lv1.boost(-bst);                                
237                                                   
238   G4ThreeVector p1 = lv1.vect();                  
239   G4double ptot    = p1.mag();                    
240   G4double ptot2 = ptot*ptot;                     
241   G4double cost = 1 - 0.5*std::fabs(tMand)/pto    
242                                                   
243   if( cost >= 1.0 )      cost = 1.0;              
244   else if( cost <= -1.0) cost = -1.0;             
245                                                   
246   G4double thetaCMS = std::acos(cost);            
247                                                   
248   G4double sigma = GetDiffuseElasticXsc( parti    
249                                                   
250   sigma *= pi/ptot2;                              
251                                                   
252   return sigma;                                   
253 }                                                 
254                                                   
255 //////////////////////////////////////////////    
256 //                                                
257 // return differential elastic cross section d    
258 // correction                                     
259                                                   
260 G4double                                          
261 G4NuclNuclDiffuseElastic::GetDiffuseElasticSum    
262                                         G4doub    
263                       G4double momentum,          
264                                         G4doub    
265 {                                                 
266   fParticle      = particle;                      
267   fWaveVector    = momentum/hbarc;                
268   fAtomicWeight  = A;                             
269   fAtomicNumber  = Z;                             
270   fNuclearRadius = CalculateNuclearRad(A);        
271   fAddCoulomb    = false;                         
272                                                   
273   G4double z     = particle->GetPDGCharge();      
274                                                   
275   G4double kRt   = fWaveVector*fNuclearRadius*    
276   G4double kRtC  = 1.9;                           
277                                                   
278   if( z && (kRt > kRtC) )                         
279   {                                               
280     fAddCoulomb = true;                           
281     fBeta       = CalculateParticleBeta( parti    
282     fZommerfeld = CalculateZommerfeld( fBeta,     
283     fAm         = CalculateAm( momentum, fZomm    
284   }                                               
285   G4double sigma = fNuclearRadius*fNuclearRadi    
286                                                   
287   return sigma;                                   
288 }                                                 
289                                                   
290 //////////////////////////////////////////////    
291 //                                                
292 // return invariant differential elastic cross    
293 // correction                                     
294                                                   
295 G4double                                          
296 G4NuclNuclDiffuseElastic::GetInvElasticSumXsc(    
297                                         G4doub    
298                       G4double plab,              
299                                         G4doub    
300 {                                                 
301   G4double m1 = particle->GetPDGMass();           
302                                                   
303   G4LorentzVector lv1(0.,0.,plab,std::sqrt(pla    
304                                                   
305   G4int iZ = static_cast<G4int>(Z+0.5);           
306   G4int iA = static_cast<G4int>(A+0.5);           
307                                                   
308   G4ParticleDefinition* theDef = 0;               
309                                                   
310   if      (iZ == 1 && iA == 1) theDef = thePro    
311   else if (iZ == 1 && iA == 2) theDef = theDeu    
312   else if (iZ == 1 && iA == 3) theDef = G4Trit    
313   else if (iZ == 2 && iA == 3) theDef = G4He3:    
314   else if (iZ == 2 && iA == 4) theDef = theAlp    
315   else theDef = G4ParticleTable::GetParticleTa    
316                                                   
317   G4double tmass = theDef->GetPDGMass();          
318                                                   
319   G4LorentzVector lv(0.0,0.0,0.0,tmass);          
320   lv += lv1;                                      
321                                                   
322   G4ThreeVector bst = lv.boostVector();           
323   lv1.boost(-bst);                                
324                                                   
325   G4ThreeVector p1 = lv1.vect();                  
326   G4double ptot    = p1.mag();                    
327   G4double ptot2   = ptot*ptot;                   
328   G4double cost    = 1 - 0.5*std::fabs(tMand)/    
329                                                   
330   if( cost >= 1.0 )      cost = 1.0;              
331   else if( cost <= -1.0) cost = -1.0;             
332                                                   
333   G4double thetaCMS = std::acos(cost);            
334                                                   
335   G4double sigma = GetDiffuseElasticSumXsc( pa    
336                                                   
337   sigma *= pi/ptot2;                              
338                                                   
339   return sigma;                                   
340 }                                                 
341                                                   
342 //////////////////////////////////////////////    
343 //                                                
344 // return invariant differential elastic cross    
345 // correction                                     
346                                                   
347 G4double                                          
348 G4NuclNuclDiffuseElastic::GetInvCoulombElastic    
349                                         G4doub    
350                       G4double plab,              
351                                         G4doub    
352 {                                                 
353   G4double m1 = particle->GetPDGMass();           
354   G4LorentzVector lv1(0.,0.,plab,std::sqrt(pla    
355                                                   
356   G4int iZ = static_cast<G4int>(Z+0.5);           
357   G4int iA = static_cast<G4int>(A+0.5);           
358   G4ParticleDefinition * theDef = 0;              
359                                                   
360   if      (iZ == 1 && iA == 1) theDef = thePro    
361   else if (iZ == 1 && iA == 2) theDef = theDeu    
362   else if (iZ == 1 && iA == 3) theDef = G4Trit    
363   else if (iZ == 2 && iA == 3) theDef = G4He3:    
364   else if (iZ == 2 && iA == 4) theDef = theAlp    
365   else theDef = G4ParticleTable::GetParticleTa    
366                                                   
367   G4double tmass = theDef->GetPDGMass();          
368                                                   
369   G4LorentzVector lv(0.0,0.0,0.0,tmass);          
370   lv += lv1;                                      
371                                                   
372   G4ThreeVector bst = lv.boostVector();           
373   lv1.boost(-bst);                                
374                                                   
375   G4ThreeVector p1 = lv1.vect();                  
376   G4double ptot    = p1.mag();                    
377   G4double ptot2 = ptot*ptot;                     
378   G4double cost = 1 - 0.5*std::fabs(tMand)/pto    
379                                                   
380   if( cost >= 1.0 )      cost = 1.0;              
381   else if( cost <= -1.0) cost = -1.0;             
382                                                   
383   G4double thetaCMS = std::acos(cost);            
384                                                   
385   G4double sigma = GetCoulombElasticXsc( parti    
386                                                   
387   sigma *= pi/ptot2;                              
388                                                   
389   return sigma;                                   
390 }                                                 
391                                                   
392 //////////////////////////////////////////////    
393 //                                                
394 // return differential elastic probability d(p    
395                                                   
396 G4double                                          
397 G4NuclNuclDiffuseElastic::GetDiffElasticProb(     
398                                         G4doub    
399           //  G4double momentum,                  
400           // G4double A                           
401                                      )            
402 {                                                 
403   G4double sigma, bzero, bzero2, bonebyarg, bo    
404   G4double delta, diffuse, gamma;                 
405   G4double e1, e2, bone, bone2;                   
406                                                   
407   // G4double wavek = momentum/hbarc;  // wave    
408   // G4double r0    = 1.08*fermi;                 
409   // G4double rad   = r0*G4Pow::GetInstance()-    
410                                                   
411   G4double kr    = fWaveVector*fNuclearRadius;    
412   G4double kr2   = kr*kr;                         
413   G4double krt   = kr*theta;                      
414                                                   
415   bzero      = BesselJzero(krt);                  
416   bzero2     = bzero*bzero;                       
417   bone       = BesselJone(krt);                   
418   bone2      = bone*bone;                         
419   bonebyarg  = BesselOneByArg(krt);               
420   bonebyarg2 = bonebyarg*bonebyarg;               
421                                                   
422   // VI - Coverity complains                      
423   /*                                              
424   if (fParticle == theProton)                     
425   {                                               
426     diffuse = 0.63*fermi;                         
427     gamma   = 0.3*fermi;                          
428     delta   = 0.1*fermi*fermi;                    
429     e1      = 0.3*fermi;                          
430     e2      = 0.35*fermi;                         
431   }                                               
432   else // as proton, if were not defined          
433   {                                               
434   */                                              
435     diffuse = 0.63*fermi;                         
436     gamma   = 0.3*fermi;                          
437     delta   = 0.1*fermi*fermi;                    
438     e1      = 0.3*fermi;                          
439     e2      = 0.35*fermi;                         
440     //}                                           
441   G4double lambda = 15.; // 15 ok                 
442                                                   
443   //  G4double kgamma    = fWaveVector*gamma;     
444                                                   
445   G4double kgamma    = lambda*(1.-G4Exp(-fWave    
446   G4double kgamma2   = kgamma*kgamma;             
447                                                   
448   // G4double dk2t  = delta*fWaveVector*fWaveV    
449   // G4double dk2t2 = dk2t*dk2t;                  
450   // G4double pikdt = pi*fWaveVector*diffuse*t    
451                                                   
452   G4double pikdt    = lambda*(1.-G4Exp(-pi*fWa    
453                                                   
454   damp           = DampFactor(pikdt);             
455   damp2          = damp*damp;                     
456                                                   
457   G4double mode2k2 = (e1*e1+e2*e2)*fWaveVector    
458   G4double e2dk3t  = -2.*e2*delta*fWaveVector*    
459                                                   
460                                                   
461   sigma  = kgamma2;                               
462   // sigma  += dk2t2;                             
463   sigma *= bzero2;                                
464   sigma += mode2k2*bone2 + e2dk3t*bzero*bone;     
465   sigma += kr2*bonebyarg2;                        
466   sigma *= damp2;          // *rad*rad;           
467                                                   
468   return sigma;                                   
469 }                                                 
470                                                   
471 //////////////////////////////////////////////    
472 //                                                
473 // return differential elastic probability d(p    
474 // Coulomb correction                             
475                                                   
476 G4double                                          
477 G4NuclNuclDiffuseElastic::GetDiffElasticSumPro    
478                                         G4doub    
479           //  G4double momentum,                  
480           // G4double A                           
481                                      )            
482 {                                                 
483   G4double sigma, bzero, bzero2, bonebyarg, bo    
484   G4double delta, diffuse, gamma;                 
485   G4double e1, e2, bone, bone2;                   
486                                                   
487   // G4double wavek = momentum/hbarc;  // wave    
488   // G4double r0    = 1.08*fermi;                 
489   // G4double rad   = r0*G4Pow::GetInstance()-    
490                                                   
491   G4double kr    = fWaveVector*fNuclearRadius;    
492   G4double kr2   = kr*kr;                         
493   G4double krt   = kr*theta;                      
494                                                   
495   bzero      = BesselJzero(krt);                  
496   bzero2     = bzero*bzero;                       
497   bone       = BesselJone(krt);                   
498   bone2      = bone*bone;                         
499   bonebyarg  = BesselOneByArg(krt);               
500   bonebyarg2 = bonebyarg*bonebyarg;               
501                                                   
502   if (fParticle == theProton)                     
503   {                                               
504     diffuse = 0.63*fermi;                         
505     // diffuse = 0.6*fermi;                       
506     gamma   = 0.3*fermi;                          
507     delta   = 0.1*fermi*fermi;                    
508     e1      = 0.3*fermi;                          
509     e2      = 0.35*fermi;                         
510   }                                               
511   else // as proton, if were not defined          
512   {                                               
513     diffuse = 0.63*fermi;                         
514     gamma   = 0.3*fermi;                          
515     delta   = 0.1*fermi*fermi;                    
516     e1      = 0.3*fermi;                          
517     e2      = 0.35*fermi;                         
518   }                                               
519   G4double lambda = 15.; // 15 ok                 
520   // G4double kgamma    = fWaveVector*gamma;      
521   G4double kgamma    = lambda*(1.-G4Exp(-fWave    
522                                                   
523   // G4cout<<"kgamma = "<<kgamma<<G4endl;         
524                                                   
525   if(fAddCoulomb)  // add Coulomb correction      
526   {                                               
527     G4double sinHalfTheta  = std::sin(0.5*thet    
528     G4double sinHalfTheta2 = sinHalfTheta*sinH    
529                                                   
530     kgamma += 0.5*fZommerfeld/kr/(sinHalfTheta    
531   // kgamma += 0.65*fZommerfeld/kr/(sinHalfThe    
532   }                                               
533                                                   
534   G4double kgamma2   = kgamma*kgamma;             
535                                                   
536   // G4double dk2t  = delta*fWaveVector*fWaveV    
537   //   G4cout<<"dk2t = "<<dk2t<<G4endl;           
538   // G4double dk2t2 = dk2t*dk2t;                  
539   // G4double pikdt = pi*fWaveVector*diffuse*t    
540                                                   
541   G4double pikdt    = lambda*(1.-G4Exp(-pi*fWa    
542                                                   
543   // G4cout<<"pikdt = "<<pikdt<<G4endl;           
544                                                   
545   damp           = DampFactor(pikdt);             
546   damp2          = damp*damp;                     
547                                                   
548   G4double mode2k2 = (e1*e1+e2*e2)*fWaveVector    
549   G4double e2dk3t  = -2.*e2*delta*fWaveVector*    
550                                                   
551   sigma  = kgamma2;                               
552   // sigma += dk2t2;                              
553   sigma *= bzero2;                                
554   sigma += mode2k2*bone2;                         
555   sigma += e2dk3t*bzero*bone;                     
556                                                   
557   // sigma += kr2*(1 + 8.*fZommerfeld*fZommerf    
558   sigma += kr2*bonebyarg2;  // correction at J    
559                                                   
560   sigma *= damp2;          // *rad*rad;           
561                                                   
562   return sigma;                                   
563 }                                                 
564                                                   
565                                                   
566 //////////////////////////////////////////////    
567 //                                                
568 // return differential elastic probability d(p    
569 // Coulomb correction                             
570                                                   
571 G4double                                          
572 G4NuclNuclDiffuseElastic::GetDiffElasticSumPro    
573 {                                                 
574   G4double theta;                                 
575                                                   
576   theta = std::sqrt(alpha);                       
577                                                   
578   // theta = std::acos( 1 - alpha/2. );           
579                                                   
580   G4double sigma, bzero, bzero2, bonebyarg, bo    
581   G4double delta, diffuse, gamma;                 
582   G4double e1, e2, bone, bone2;                   
583                                                   
584   // G4double wavek = momentum/hbarc;  // wave    
585   // G4double r0    = 1.08*fermi;                 
586   // G4double rad   = r0*G4Pow::GetInstance()-    
587                                                   
588   G4double kr    = fWaveVector*fNuclearRadius;    
589   G4double kr2   = kr*kr;                         
590   G4double krt   = kr*theta;                      
591                                                   
592   bzero      = BesselJzero(krt);                  
593   bzero2     = bzero*bzero;                       
594   bone       = BesselJone(krt);                   
595   bone2      = bone*bone;                         
596   bonebyarg  = BesselOneByArg(krt);               
597   bonebyarg2 = bonebyarg*bonebyarg;               
598                                                   
599   if (fParticle == theProton)                     
600   {                                               
601     diffuse = 0.63*fermi;                         
602     // diffuse = 0.6*fermi;                       
603     gamma   = 0.3*fermi;                          
604     delta   = 0.1*fermi*fermi;                    
605     e1      = 0.3*fermi;                          
606     e2      = 0.35*fermi;                         
607   }                                               
608   else // as proton, if were not defined          
609   {                                               
610     diffuse = 0.63*fermi;                         
611     gamma   = 0.3*fermi;                          
612     delta   = 0.1*fermi*fermi;                    
613     e1      = 0.3*fermi;                          
614     e2      = 0.35*fermi;                         
615   }                                               
616   G4double lambda = 15.; // 15 ok                 
617   // G4double kgamma    = fWaveVector*gamma;      
618   G4double kgamma    = lambda*(1.-G4Exp(-fWave    
619                                                   
620   // G4cout<<"kgamma = "<<kgamma<<G4endl;         
621                                                   
622   if(fAddCoulomb)  // add Coulomb correction      
623   {                                               
624     G4double sinHalfTheta  = theta*0.5; // std    
625     G4double sinHalfTheta2 = sinHalfTheta*sinH    
626                                                   
627     kgamma += 0.5*fZommerfeld/kr/(sinHalfTheta    
628   // kgamma += 0.65*fZommerfeld/kr/(sinHalfThe    
629   }                                               
630                                                   
631   G4double kgamma2   = kgamma*kgamma;             
632                                                   
633   // G4double dk2t  = delta*fWaveVector*fWaveV    
634   //   G4cout<<"dk2t = "<<dk2t<<G4endl;           
635   // G4double dk2t2 = dk2t*dk2t;                  
636   // G4double pikdt = pi*fWaveVector*diffuse*t    
637                                                   
638   G4double pikdt    = lambda*(1.-G4Exp(-pi*fWa    
639                                                   
640   // G4cout<<"pikdt = "<<pikdt<<G4endl;           
641                                                   
642   damp           = DampFactor(pikdt);             
643   damp2          = damp*damp;                     
644                                                   
645   G4double mode2k2 = (e1*e1+e2*e2)*fWaveVector    
646   G4double e2dk3t  = -2.*e2*delta*fWaveVector*    
647                                                   
648   sigma  = kgamma2;                               
649   // sigma += dk2t2;                              
650   sigma *= bzero2;                                
651   sigma += mode2k2*bone2;                         
652   sigma += e2dk3t*bzero*bone;                     
653                                                   
654   // sigma += kr2*(1 + 8.*fZommerfeld*fZommerf    
655   sigma += kr2*bonebyarg2;  // correction at J    
656                                                   
657   sigma *= damp2;          // *rad*rad;           
658                                                   
659   return sigma;                                   
660 }                                                 
661                                                   
662                                                   
663 //////////////////////////////////////////////    
664 //                                                
665 // return differential elastic probability 2*p    
666                                                   
667 G4double                                          
668 G4NuclNuclDiffuseElastic::GetIntegrandFunction    
669 {                                                 
670   G4double result;                                
671                                                   
672   result  = GetDiffElasticSumProbA(alpha);        
673                                                   
674   // result *= 2*pi*std::sin(theta);              
675                                                   
676   return result;                                  
677 }                                                 
678                                                   
679 //////////////////////////////////////////////    
680 //                                                
681 // return integral elastic cross section d(sig    
682                                                   
683 G4double                                          
684 G4NuclNuclDiffuseElastic::IntegralElasticProb(    
685                                         G4doub    
686                       G4double momentum,          
687                                         G4doub    
688 {                                                 
689   G4double result;                                
690   fParticle      = particle;                      
691   fWaveVector    = momentum/hbarc;                
692   fAtomicWeight  = A;                             
693                                                   
694   fNuclearRadius = CalculateNuclearRad(A);        
695                                                   
696                                                   
697   G4Integrator<G4NuclNuclDiffuseElastic,G4doub    
698                                                   
699   // result = integral.Legendre10(this,&G4Nucl    
700   result = integral.Legendre96(this,&G4NuclNuc    
701                                                   
702   return result;                                  
703 }                                                 
704                                                   
705 //////////////////////////////////////////////    
706 //                                                
707 // Return inv momentum transfer -t > 0            
708                                                   
709 G4double G4NuclNuclDiffuseElastic::SampleT( co    
710               G4double p, G4double A)             
711 {                                                 
712   G4double theta = SampleThetaCMS( aParticle,     
713   G4double t     = 2*p*p*( 1 - std::cos(theta)    
714   return t;                                       
715 }                                                 
716                                                   
717 //////////////////////////////////////////////    
718 //                                                
719 // Return scattering angle sampled in cms         
720                                                   
721                                                   
722 G4double                                          
723 G4NuclNuclDiffuseElastic::SampleThetaCMS(const    
724                                        G4doubl    
725 {                                                 
726   G4int i, iMax = 100;                            
727   G4double norm, theta1, theta2, thetaMax;        
728   G4double result = 0., sum = 0.;                 
729                                                   
730   fParticle      = particle;                      
731   fWaveVector    = momentum/hbarc;                
732   fAtomicWeight  = A;                             
733                                                   
734   fNuclearRadius = CalculateNuclearRad(A);        
735                                                   
736   thetaMax = 10.174/fWaveVector/fNuclearRadius    
737                                                   
738   if (thetaMax > pi) thetaMax = pi;               
739                                                   
740   G4Integrator<G4NuclNuclDiffuseElastic,G4doub    
741                                                   
742   // result = integral.Legendre10(this,&G4Nucl    
743   norm = integral.Legendre96(this,&G4NuclNuclD    
744                                                   
745   norm *= G4UniformRand();                        
746                                                   
747   for(i = 1; i <= iMax; i++)                      
748   {                                               
749     theta1 = (i-1)*thetaMax/iMax;                 
750     theta2 = i*thetaMax/iMax;                     
751     sum   += integral.Legendre10(this,&G4NuclN    
752                                                   
753     if ( sum >= norm )                            
754     {                                             
755       result = 0.5*(theta1 + theta2);             
756       break;                                      
757     }                                             
758   }                                               
759   if (i > iMax ) result = 0.5*(theta1 + theta2    
760                                                   
761   G4double sigma = pi*thetaMax/iMax;              
762                                                   
763   result += G4RandGauss::shoot(0.,sigma);         
764                                                   
765   if(result < 0.) result = 0.;                    
766   if(result > thetaMax) result = thetaMax;        
767                                                   
768   return result;                                  
769 }                                                 
770                                                   
771 //////////////////////////////////////////////    
772 /////////////////////  Table preparation and r    
773                                                   
774 //////////////////////////////////////////////    
775 //                                                
776 // Interface function. Return inv momentum tra    
777                                                   
778 G4double G4NuclNuclDiffuseElastic::SampleInvar    
779                                                   
780 {                                                 
781   fParticle = aParticle;                          
782   fAtomicNumber = G4double(Z);                    
783   fAtomicWeight = G4double(A);                    
784                                                   
785   G4double t(0.), m1 = fParticle->GetPDGMass()    
786   G4double totElab = std::sqrt(m1*m1+p*p);        
787   G4double mass2 = G4NucleiProperties::GetNucl    
788   G4LorentzVector lv1(p,0.0,0.0,totElab);         
789   G4LorentzVector  lv(0.0,0.0,0.0,mass2);         
790   lv += lv1;                                      
791                                                   
792   G4ThreeVector bst = lv.boostVector();           
793   lv1.boost(-bst);                                
794                                                   
795   G4ThreeVector p1 = lv1.vect();                  
796   G4double momentumCMS = p1.mag();                
797                                                   
798   // t = SampleTableT( aParticle,  momentumCMS    
799                                                   
800   t = SampleCoulombMuCMS( aParticle,  momentum    
801                                                   
802                                                   
803   return t;                                       
804 }                                                 
805                                                   
806 //////////////////////////////////////////////    
807 //                                                
808 // Return inv momentum transfer -t > 0 as Coul    
809                                                   
810 G4double G4NuclNuclDiffuseElastic::SampleCoulo    
811 {                                                 
812   G4double t(0.), rand(0.), mu(0.);               
813                                                   
814   G4double A1 = G4double( aParticle->GetBaryon    
815   G4double R1 = CalculateNuclearRad(A1);          
816                                                   
817   fNuclearRadius  = CalculateNuclearRad(fAtomi    
818   fNuclearRadius += R1;                           
819                                                   
820   InitDynParameters(fParticle, p);                
821                                                   
822   fCoulombMuC = fHalfRutThetaTg2/(1.+fHalfRutT    
823                                                   
824   rand = G4UniformRand();                         
825                                                   
826   // sample (1-cosTheta) in 0 < Theta < ThetaC    
827                                                   
828   mu  = fCoulombMuC*rand*fAm;                     
829   mu /= fAm + fCoulombMuC*( 1. - rand );          
830                                                   
831   t = 4.*p*p*mu;                                  
832                                                   
833   return t;                                       
834 }                                                 
835                                                   
836                                                   
837 //////////////////////////////////////////////    
838 //                                                
839 // Return inv momentum transfer -t > 0 from in    
840                                                   
841 G4double G4NuclNuclDiffuseElastic::SampleTable    
842                                                   
843 {                                                 
844   G4double alpha = SampleTableThetaCMS( aParti    
845   // G4double t     = 2*p*p*( 1 - std::cos(std    
846   G4double t     = p*p*alpha;             // -    
847   return t;                                       
848 }                                                 
849                                                   
850 //////////////////////////////////////////////    
851 //                                                
852 // Return scattering angle2 sampled in cms acc    
853                                                   
854                                                   
855 G4double                                          
856 G4NuclNuclDiffuseElastic::SampleTableThetaCMS(    
857                                        G4doubl    
858 {                                                 
859   std::size_t iElement;                           
860   G4int iMomentum, iAngle;                        
861   G4double randAngle, position, theta1, theta2    
862   G4double m1 = particle->GetPDGMass();           
863                                                   
864   for(iElement = 0; iElement < fElementNumberV    
865   {                                               
866     if( std::fabs(Z - fElementNumberVector[iEl    
867   }                                               
868   if ( iElement == fElementNumberVector.size()    
869   {                                               
870     InitialiseOnFly(Z,A); // table preparation    
871                                                   
872     // iElement--;                                
873                                                   
874     // G4cout << "G4NuclNuclDiffuseElastic: El    
875     // << " is not found, return zero angle" <    
876     // return 0.; // no table for this element    
877   }                                               
878   // G4cout<<"iElement = "<<iElement<<G4endl;     
879                                                   
880   fAngleTable = fAngleBank[iElement];             
881                                                   
882   G4double kinE = std::sqrt(momentum*momentum     
883                                                   
884   for( iMomentum = 0; iMomentum < fEnergyBin;     
885   {                                               
886     // G4cout<<iMomentum<<", kinE = "<<kinE/Me    
887                                                   
888     if( kinE < fEnergyVector->GetLowEdgeEnergy    
889   }                                               
890   // G4cout<<"iMomentum = "<<iMomentum<<", fEn    
891                                                   
892                                                   
893   if ( iMomentum >= fEnergyBin ) iMomentum = f    
894   if ( iMomentum < 0 )           iMomentum = 0    
895                                                   
896                                                   
897   if (iMomentum == fEnergyBin -1 || iMomentum     
898   {                                               
899     position = (*(*fAngleTable)(iMomentum))(fA    
900                                                   
901     // G4cout<<"position = "<<position<<G4endl    
902                                                   
903     for(iAngle = 0; iAngle < fAngleBin-1; iAng    
904     {                                             
905       if( position < (*(*fAngleTable)(iMomentu    
906     }                                             
907     if (iAngle >= fAngleBin-1) iAngle = fAngle    
908                                                   
909     // G4cout<<"iAngle = "<<iAngle<<G4endl;       
910                                                   
911     randAngle = GetScatteringAngle(iMomentum,     
912                                                   
913     // G4cout<<"randAngle = "<<randAngle<<G4en    
914   }                                               
915   else  // kinE inside between energy table ed    
916   {                                               
917     // position = (*(*fAngleTable)(iMomentum))    
918     position = (*(*fAngleTable)(iMomentum))(0)    
919                                                   
920     // G4cout<<"position = "<<position<<G4endl    
921                                                   
922     for(iAngle = 0; iAngle < fAngleBin-1; iAng    
923     {                                             
924       // if( position < (*(*fAngleTable)(iMome    
925       if( position > (*(*fAngleTable)(iMomentu    
926     }                                             
927     if (iAngle >= fAngleBin-1) iAngle = fAngle    
928                                                   
929     // G4cout<<"iAngle = "<<iAngle<<G4endl;       
930                                                   
931     theta2  = GetScatteringAngle(iMomentum, iA    
932                                                   
933     // G4cout<<"theta2 = "<<theta2<<G4endl;       
934                                                   
935     E2 = fEnergyVector->GetLowEdgeEnergy(iMome    
936                                                   
937     // G4cout<<"E2 = "<<E2<<G4endl;               
938                                                   
939     iMomentum--;                                  
940                                                   
941     // position = (*(*fAngleTable)(iMomentum))    
942                                                   
943     // G4cout<<"position = "<<position<<G4endl    
944                                                   
945     for(iAngle = 0; iAngle < fAngleBin-1; iAng    
946     {                                             
947       // if( position < (*(*fAngleTable)(iMome    
948       if( position > (*(*fAngleTable)(iMomentu    
949     }                                             
950     if (iAngle >= fAngleBin-1) iAngle = fAngle    
951                                                   
952     theta1  = GetScatteringAngle(iMomentum, iA    
953                                                   
954     // G4cout<<"theta1 = "<<theta1<<G4endl;       
955                                                   
956     E1 = fEnergyVector->GetLowEdgeEnergy(iMome    
957                                                   
958     // G4cout<<"E1 = "<<E1<<G4endl;               
959                                                   
960     W  = 1.0/(E2 - E1);                           
961     W1 = (E2 - kinE)*W;                           
962     W2 = (kinE - E1)*W;                           
963                                                   
964     randAngle = W1*theta1 + W2*theta2;            
965                                                   
966     // randAngle = theta2;                        
967   }                                               
968   // G4double angle = randAngle;                  
969   // if (randAngle > 0.) randAngle /= 2*pi*std    
970   // G4cout<<"randAngle = "<<randAngle/degree<    
971                                                   
972   return randAngle;                               
973 }                                                 
974                                                   
975 //////////////////////////////////////////////    
976 //                                                
977 // Initialisation for given particle on fly us    
978                                                   
979 void G4NuclNuclDiffuseElastic::InitialiseOnFly    
980 {                                                 
981   fAtomicNumber  = Z;     // atomic number        
982   fAtomicWeight  = G4NistManager::Instance()->    
983                                                   
984   G4double A1 = G4double( fParticle->GetBaryon    
985   G4double R1 = CalculateNuclearRad(A1);          
986                                                   
987   fNuclearRadius = CalculateNuclearRad(fAtomic    
988                                                   
989   if( verboseLevel > 0 )                          
990   {                                               
991     G4cout<<"G4NuclNuclDiffuseElastic::Initial    
992     <<Z<<"; and A = "<<A<<G4endl;                 
993   }                                               
994   fElementNumberVector.push_back(fAtomicNumber    
995                                                   
996   BuildAngleTable();                              
997                                                   
998   fAngleBank.push_back(fAngleTable);              
999                                                   
1000   return;                                        
1001 }                                                
1002                                                  
1003 /////////////////////////////////////////////    
1004 //                                               
1005 // Build for given particle and element table    
1006 // For the moment in lab system.                 
1007                                                  
1008 void G4NuclNuclDiffuseElastic::BuildAngleTabl    
1009 {                                                
1010   G4int i, j;                                    
1011   G4double partMom, kinE, m1 = fParticle->Get    
1012   G4double alpha1, alpha2, alphaMax, alphaCou    
1013                                                  
1014   // G4cout<<"particle z = "<<z<<"; particle     
1015                                                  
1016   G4Integrator<G4NuclNuclDiffuseElastic,G4dou    
1017                                                  
1018   fAngleTable = new G4PhysicsTable(fEnergyBin    
1019                                                  
1020   for( i = 0; i < fEnergyBin; i++)               
1021   {                                              
1022     kinE        = fEnergyVector->GetLowEdgeEn    
1023                                                  
1024     // G4cout<<G4endl;                           
1025     // G4cout<<"kinE = "<<kinE/MeV<<" MeV"<<G    
1026                                                  
1027     partMom     = std::sqrt( kinE*(kinE + 2*m    
1028                                                  
1029     InitDynParameters(fParticle, partMom);       
1030                                                  
1031     alphaMax = fRutherfordTheta*fCofAlphaMax;    
1032                                                  
1033     if(alphaMax > pi) alphaMax = pi;             
1034                                                  
1035     // VI: Coverity complain                     
1036     //alphaMax = pi2;                            
1037                                                  
1038     alphaCoulomb = fRutherfordTheta*fCofAlpha    
1039                                                  
1040     // G4cout<<"alphaCoulomb = "<<alphaCoulom    
1041                                                  
1042     G4PhysicsFreeVector* angleVector = new G4    
1043                                                  
1044     // G4PhysicsLogVector*  angleBins = new G    
1045                                                  
1046     G4double delth = (alphaMax-alphaCoulomb)/    
1047                                                  
1048     sum = 0.;                                    
1049                                                  
1050     // fAddCoulomb = false;                      
1051     fAddCoulomb = true;                          
1052                                                  
1053     // for(j = 1; j < fAngleBin; j++)            
1054     for(j = fAngleBin-1; j >= 1; j--)            
1055     {                                            
1056       // alpha1 = angleBins->GetLowEdgeEnergy    
1057       // alpha2 = angleBins->GetLowEdgeEnergy    
1058                                                  
1059       // alpha1 = alphaMax*(j-1)/fAngleBin;      
1060       // alpha2 = alphaMax*( j )/fAngleBin;      
1061                                                  
1062       alpha1 = alphaCoulomb + delth*(j-1);       
1063       // if(alpha1 < kRlim2) alpha1 = kRlim2;    
1064       alpha2 = alpha1 + delth;                   
1065                                                  
1066       delta = integral.Legendre10(this, &G4Nu    
1067       // delta = integral.Legendre96(this, &G    
1068                                                  
1069       sum += delta;                              
1070                                                  
1071       angleVector->PutValue( j-1 , alpha1, su    
1072       // G4cout<<"j-1 = "<<j-1<<"; alpha2 = "    
1073     }                                            
1074     fAngleTable->insertAt(i,angleVector);        
1075                                                  
1076     // delete[] angleVector;                     
1077     // delete[] angleBins;                       
1078   }                                              
1079   return;                                        
1080 }                                                
1081                                                  
1082 /////////////////////////////////////////////    
1083 //                                               
1084 //                                               
1085                                                  
1086 G4double                                         
1087 G4NuclNuclDiffuseElastic:: GetScatteringAngle    
1088 {                                                
1089  G4double x1, x2, y1, y2, randAngle;             
1090                                                  
1091   if( iAngle == 0 )                              
1092   {                                              
1093     randAngle = (*fAngleTable)(iMomentum)->Ge    
1094     // iAngle++;                                 
1095   }                                              
1096   else                                           
1097   {                                              
1098     if ( iAngle >= G4int((*fAngleTable)(iMome    
1099     {                                            
1100       iAngle = G4int((*fAngleTable)(iMomentum    
1101     }                                            
1102     y1 = (*(*fAngleTable)(iMomentum))(iAngle-    
1103     y2 = (*(*fAngleTable)(iMomentum))(iAngle)    
1104                                                  
1105     x1 = (*fAngleTable)(iMomentum)->GetLowEdg    
1106     x2 = (*fAngleTable)(iMomentum)->GetLowEdg    
1107                                                  
1108     if ( x1 == x2 )   randAngle = x2;            
1109     else                                         
1110     {                                            
1111       if ( y1 == y2 ) randAngle = x1 + ( x2 -    
1112       else                                       
1113       {                                          
1114         randAngle = x1 + ( position - y1 )*(     
1115       }                                          
1116     }                                            
1117   }                                              
1118   return randAngle;                              
1119 }                                                
1120                                                  
1121                                                  
1122                                                  
1123 /////////////////////////////////////////////    
1124 //                                               
1125 // Return scattering angle sampled in lab sys    
1126                                                  
1127                                                  
1128                                                  
1129 G4double                                         
1130 G4NuclNuclDiffuseElastic::SampleThetaLab( con    
1131                                         G4dou    
1132 {                                                
1133   const G4ParticleDefinition* theParticle = a    
1134   G4double m1 = theParticle->GetPDGMass();       
1135   G4double plab = aParticle->GetTotalMomentum    
1136   G4LorentzVector lv1 = aParticle->Get4Moment    
1137   G4LorentzVector lv(0.0,0.0,0.0,tmass);         
1138   lv += lv1;                                     
1139                                                  
1140   G4ThreeVector bst = lv.boostVector();          
1141   lv1.boost(-bst);                               
1142                                                  
1143   G4ThreeVector p1 = lv1.vect();                 
1144   G4double ptot    = p1.mag();                   
1145   G4double tmax    = 4.0*ptot*ptot;              
1146   G4double t       = 0.0;                        
1147                                                  
1148                                                  
1149   //                                             
1150   // Sample t                                    
1151   //                                             
1152                                                  
1153   t = SampleT( theParticle, ptot, A);            
1154                                                  
1155   // NaN finder                                  
1156   if(!(t < 0.0 || t >= 0.0))                     
1157   {                                              
1158     if (verboseLevel > 0)                        
1159     {                                            
1160       G4cout << "G4NuclNuclDiffuseElastic:WAR    
1161        << " mom(GeV)= " << plab/GeV              
1162              << " S-wave will be sampled"        
1163        << G4endl;                                
1164     }                                            
1165     t = G4UniformRand()*tmax;                    
1166   }                                              
1167   if(verboseLevel>1)                             
1168   {                                              
1169     G4cout <<" t= " << t << " tmax= " << tmax    
1170      << " ptot= " << ptot << G4endl;             
1171   }                                              
1172   // Sampling of angles in CM system             
1173                                                  
1174   G4double phi  = G4UniformRand()*twopi;         
1175   G4double cost = 1. - 2.0*t/tmax;               
1176   G4double sint;                                 
1177                                                  
1178   if( cost >= 1.0 )                              
1179   {                                              
1180     cost = 1.0;                                  
1181     sint = 0.0;                                  
1182   }                                              
1183   else if( cost <= -1.0)                         
1184   {                                              
1185     cost = -1.0;                                 
1186     sint =  0.0;                                 
1187   }                                              
1188   else                                           
1189   {                                              
1190     sint = std::sqrt((1.0-cost)*(1.0+cost));     
1191   }                                              
1192   if (verboseLevel>1)                            
1193   {                                              
1194     G4cout << "cos(t)=" << cost << " std::sin    
1195   }                                              
1196   G4ThreeVector v1(sint*std::cos(phi),sint*st    
1197   v1 *= ptot;                                    
1198   G4LorentzVector nlv1(v1.x(),v1.y(),v1.z(),s    
1199                                                  
1200   nlv1.boost(bst);                               
1201                                                  
1202   G4ThreeVector np1 = nlv1.vect();               
1203                                                  
1204     // G4double theta = std::acos( np1.z()/np    
1205                                                  
1206   G4double theta = np1.theta();                  
1207                                                  
1208   return theta;                                  
1209 }                                                
1210                                                  
1211 /////////////////////////////////////////////    
1212 //                                               
1213 // Return scattering angle in lab system (tar    
1214                                                  
1215                                                  
1216                                                  
1217 G4double                                         
1218 G4NuclNuclDiffuseElastic::ThetaCMStoThetaLab(    
1219                                         G4dou    
1220 {                                                
1221   const G4ParticleDefinition* theParticle = a    
1222   G4double m1 = theParticle->GetPDGMass();       
1223   // G4double plab = aParticle->GetTotalMomen    
1224   G4LorentzVector lv1 = aParticle->Get4Moment    
1225   G4LorentzVector lv(0.0,0.0,0.0,tmass);         
1226                                                  
1227   lv += lv1;                                     
1228                                                  
1229   G4ThreeVector bst = lv.boostVector();          
1230                                                  
1231   lv1.boost(-bst);                               
1232                                                  
1233   G4ThreeVector p1 = lv1.vect();                 
1234   G4double ptot    = p1.mag();                   
1235                                                  
1236   G4double phi  = G4UniformRand()*twopi;         
1237   G4double cost = std::cos(thetaCMS);            
1238   G4double sint;                                 
1239                                                  
1240   if( cost >= 1.0 )                              
1241   {                                              
1242     cost = 1.0;                                  
1243     sint = 0.0;                                  
1244   }                                              
1245   else if( cost <= -1.0)                         
1246   {                                              
1247     cost = -1.0;                                 
1248     sint =  0.0;                                 
1249   }                                              
1250   else                                           
1251   {                                              
1252     sint = std::sqrt((1.0-cost)*(1.0+cost));     
1253   }                                              
1254   if (verboseLevel>1)                            
1255   {                                              
1256     G4cout << "cos(tcms)=" << cost << " std::    
1257   }                                              
1258   G4ThreeVector v1(sint*std::cos(phi),sint*st    
1259   v1 *= ptot;                                    
1260   G4LorentzVector nlv1(v1.x(),v1.y(),v1.z(),s    
1261                                                  
1262   nlv1.boost(bst);                               
1263                                                  
1264   G4ThreeVector np1 = nlv1.vect();               
1265                                                  
1266                                                  
1267   G4double thetaLab = np1.theta();               
1268                                                  
1269   return thetaLab;                               
1270 }                                                
1271                                                  
1272 /////////////////////////////////////////////    
1273 //                                               
1274 // Return scattering angle in CMS system (tar    
1275                                                  
1276                                                  
1277                                                  
1278 G4double                                         
1279 G4NuclNuclDiffuseElastic::ThetaLabToThetaCMS(    
1280                                         G4dou    
1281 {                                                
1282   const G4ParticleDefinition* theParticle = a    
1283   G4double m1 = theParticle->GetPDGMass();       
1284   G4double plab = aParticle->GetTotalMomentum    
1285   G4LorentzVector lv1 = aParticle->Get4Moment    
1286   G4LorentzVector lv(0.0,0.0,0.0,tmass);         
1287                                                  
1288   lv += lv1;                                     
1289                                                  
1290   G4ThreeVector bst = lv.boostVector();          
1291                                                  
1292   // lv1.boost(-bst);                            
1293                                                  
1294   // G4ThreeVector p1 = lv1.vect();              
1295   // G4double ptot    = p1.mag();                
1296                                                  
1297   G4double phi  = G4UniformRand()*twopi;         
1298   G4double cost = std::cos(thetaLab);            
1299   G4double sint;                                 
1300                                                  
1301   if( cost >= 1.0 )                              
1302   {                                              
1303     cost = 1.0;                                  
1304     sint = 0.0;                                  
1305   }                                              
1306   else if( cost <= -1.0)                         
1307   {                                              
1308     cost = -1.0;                                 
1309     sint =  0.0;                                 
1310   }                                              
1311   else                                           
1312   {                                              
1313     sint = std::sqrt((1.0-cost)*(1.0+cost));     
1314   }                                              
1315   if (verboseLevel>1)                            
1316   {                                              
1317     G4cout << "cos(tlab)=" << cost << " std::    
1318   }                                              
1319   G4ThreeVector v1(sint*std::cos(phi),sint*st    
1320   v1 *= plab;                                    
1321   G4LorentzVector nlv1(v1.x(),v1.y(),v1.z(),s    
1322                                                  
1323   nlv1.boost(-bst);                              
1324                                                  
1325   G4ThreeVector np1 = nlv1.vect();               
1326                                                  
1327                                                  
1328   G4double thetaCMS = np1.theta();               
1329                                                  
1330   return thetaCMS;                               
1331 }                                                
1332                                                  
1333 /////////////////////////////////////////////    
1334 //                                               
1335 // Test for given particle and element table     
1336 // For the moment in lab system.                 
1337                                                  
1338 void G4NuclNuclDiffuseElastic::TestAngleTable    
1339                                             G    
1340 {                                                
1341   fAtomicNumber  = Z;     // atomic number       
1342   fAtomicWeight  = A;     // number of nucleo    
1343   fNuclearRadius = CalculateNuclearRad(fAtomi    
1344                                                  
1345                                                  
1346                                                  
1347   G4cout<<"G4NuclNuclDiffuseElastic::TestAngl    
1348     <<Z<<"; and A = "<<A<<G4endl;                
1349                                                  
1350   fElementNumberVector.push_back(fAtomicNumbe    
1351                                                  
1352                                                  
1353                                                  
1354                                                  
1355   G4int i=0, j;                                  
1356   G4double a = 0., z = theParticle->GetPDGCha    
1357   G4double alpha1=0., alpha2=0., alphaMax=0.,    
1358   G4double deltaL10 = 0., deltaL96 = 0., delt    
1359   G4double sumL10 = 0.,sumL96 = 0.,sumAG = 0.    
1360   G4double epsilon = 0.001;                      
1361                                                  
1362   G4Integrator<G4NuclNuclDiffuseElastic,G4dou    
1363                                                  
1364   fAngleTable = new G4PhysicsTable(fEnergyBin    
1365                                                  
1366   fWaveVector = partMom/hbarc;                   
1367                                                  
1368   G4double kR     = fWaveVector*fNuclearRadiu    
1369   G4double kR2    = kR*kR;                       
1370   G4double kRmax  = 10.6; // 10.6, 18, 10.174    
1371   G4double kRcoul = 1.2; // 1.4, 2.5; // on t    
1372                                                  
1373   alphaMax = kRmax*kRmax/kR2;                    
1374                                                  
1375   if (alphaMax > 4.) alphaMax = 4.;  // vmg05    
1376                                                  
1377   alphaCoulomb = kRcoul*kRcoul/kR2;              
1378                                                  
1379   if( z )                                        
1380   {                                              
1381       a           = partMom/m1; // beta*gamma    
1382       fBeta       = a/std::sqrt(1+a*a);          
1383       fZommerfeld = CalculateZommerfeld( fBet    
1384       fAm         = CalculateAm( partMom, fZo    
1385   }                                              
1386   G4PhysicsFreeVector* angleVector = new G4Ph    
1387                                                  
1388   // G4PhysicsLogVector*  angleBins = new G4P    
1389                                                  
1390                                                  
1391   fAddCoulomb = false;                           
1392                                                  
1393   for(j = 1; j < fAngleBin; j++)                 
1394   {                                              
1395       // alpha1 = angleBins->GetLowEdgeEnergy    
1396       // alpha2 = angleBins->GetLowEdgeEnergy    
1397                                                  
1398     alpha1 = alphaMax*(j-1)/fAngleBin;           
1399     alpha2 = alphaMax*( j )/fAngleBin;           
1400                                                  
1401     if( ( alpha2 > alphaCoulomb ) && z ) fAdd    
1402                                                  
1403     deltaL10 = integral.Legendre10(this, &G4N    
1404     deltaL96 = integral.Legendre96(this, &G4N    
1405     deltaAG  = integral.AdaptiveGauss(this, &    
1406                                        alpha1    
1407                                                  
1408       // G4cout<<alpha1<<"\t"<<std::sqrt(alph    
1409       //     <<deltaL10<<"\t"<<deltaL96<<"\t"    
1410                                                  
1411     sumL10 += deltaL10;                          
1412     sumL96 += deltaL96;                          
1413     sumAG  += deltaAG;                           
1414                                                  
1415     G4cout<<alpha1<<"\t"<<std::sqrt(alpha1)/d    
1416             <<sumL10<<"\t"<<sumL96<<"\t"<<sum    
1417                                                  
1418     angleVector->PutValue( j-1 , alpha1, sumL    
1419   }                                              
1420   fAngleTable->insertAt(i,angleVector);          
1421   fAngleBank.push_back(fAngleTable);             
1422                                                  
1423   /*                                             
1424   // Integral over all angle range - Bad accu    
1425                                                  
1426   sumL10 = integral.Legendre10(this, &G4NuclN    
1427   sumL96 = integral.Legendre96(this, &G4NuclN    
1428   sumAG  = integral.AdaptiveGauss(this, &G4Nu    
1429                                        0., al    
1430   G4cout<<G4endl;                                
1431   G4cout<<alpha2<<"\t"<<std::sqrt(alpha2)/deg    
1432             <<sumL10<<"\t"<<sumL96<<"\t"<<sum    
1433   */                                             
1434   return;                                        
1435 }                                                
1436                                                  
1437 /////////////////////////////////////////////    
1438 //                                               
1439 //                                               
1440                                                  
1441  G4double G4NuclNuclDiffuseElastic::GetLegend    
1442 {                                                
1443   G4double legPol, epsilon = 1.e-6;              
1444   G4double x = std::cos(theta);                  
1445                                                  
1446   if     ( n  < 0 ) legPol = 0.;                 
1447   else if( n == 0 ) legPol = 1.;                 
1448   else if( n == 1 ) legPol = x;                  
1449   else if( n == 2 ) legPol = (3.*x*x-1.)/2.;     
1450   else if( n == 3 ) legPol = (5.*x*x*x-3.*x)/    
1451   else if( n == 4 ) legPol = (35.*x*x*x*x-30.    
1452   else if( n == 5 ) legPol = (63.*x*x*x*x*x-7    
1453   else if( n == 6 ) legPol = (231.*x*x*x*x*x*    
1454   else                                           
1455   {                                              
1456     // legPol = ( (2*n-1)*x*GetLegendrePol(n-    
1457                                                  
1458     legPol = std::sqrt( 2./(n*CLHEP::pi*std::    
1459   }                                              
1460   return legPol;                                 
1461 }                                                
1462                                                  
1463 /////////////////////////////////////////////    
1464 //                                               
1465 //                                               
1466                                                  
1467 G4complex G4NuclNuclDiffuseElastic::GetErfCom    
1468 {                                                
1469   G4int n;                                       
1470   G4double n2, cofn, shny, chny, fn, gn;         
1471                                                  
1472   G4double x = z.real();                         
1473   G4double y = z.imag();                         
1474                                                  
1475   G4double outRe = 0., outIm = 0.;               
1476                                                  
1477   G4double twox  = 2.*x;                         
1478   G4double twoxy = twox*y;                       
1479   G4double twox2 = twox*twox;                    
1480                                                  
1481   G4double cof1 = G4Exp(-x*x)/CLHEP::pi;         
1482                                                  
1483   G4double cos2xy = std::cos(twoxy);             
1484   G4double sin2xy = std::sin(twoxy);             
1485                                                  
1486   G4double twoxcos2xy = twox*cos2xy;             
1487   G4double twoxsin2xy = twox*sin2xy;             
1488                                                  
1489   for( n = 1; n <= nMax; n++)                    
1490   {                                              
1491     n2   = n*n;                                  
1492                                                  
1493     cofn = G4Exp(-0.5*n2)/(n2+twox2);  // /(n    
1494                                                  
1495     chny = std::cosh(n*y);                       
1496     shny = std::sinh(n*y);                       
1497                                                  
1498     fn  = twox - twoxcos2xy*chny + n*sin2xy*s    
1499     gn  =        twoxsin2xy*chny + n*cos2xy*s    
1500                                                  
1501     fn *= cofn;                                  
1502     gn *= cofn;                                  
1503                                                  
1504     outRe += fn;                                 
1505     outIm += gn;                                 
1506   }                                              
1507   outRe *= 2*cof1;                               
1508   outIm *= 2*cof1;                               
1509                                                  
1510   if(std::abs(x) < 0.0001)                       
1511   {                                              
1512     outRe += GetErf(x);                          
1513     outIm += cof1*y;                             
1514   }                                              
1515   else                                           
1516   {                                              
1517     outRe += GetErf(x) + cof1*(1-cos2xy)/twox    
1518     outIm += cof1*sin2xy/twox;                   
1519   }                                              
1520   return G4complex(outRe, outIm);                
1521 }                                                
1522                                                  
1523                                                  
1524 /////////////////////////////////////////////    
1525 //                                               
1526 //                                               
1527                                                  
1528 G4complex G4NuclNuclDiffuseElastic::GetErfInt    
1529 {                                                
1530   G4double outRe, outIm;                         
1531                                                  
1532   G4double x = z.real();                         
1533   G4double y = z.imag();                         
1534   fReZ       = x;                                
1535                                                  
1536   G4Integrator<G4NuclNuclDiffuseElastic,G4dou    
1537                                                  
1538   outRe = integral.Legendre96(this,&G4NuclNuc    
1539   outIm = integral.Legendre96(this,&G4NuclNuc    
1540                                                  
1541   outRe *= 2./std::sqrt(CLHEP::pi);              
1542   outIm *= 2./std::sqrt(CLHEP::pi);              
1543                                                  
1544   outRe += GetErf(x);                            
1545                                                  
1546   return G4complex(outRe, outIm);                
1547 }                                                
1548                                                  
1549 /////////////////////////////////////////////    
1550 //                                               
1551 //                                               
1552                                                  
1553                                                  
1554 G4complex G4NuclNuclDiffuseElastic::GammaLess    
1555 {                                                
1556   G4double sinThetaR      = 2.*fHalfRutThetaT    
1557   G4double cosHalfThetaR2 = 1./(1. + fHalfRut    
1558                                                  
1559   G4double u              = std::sqrt(0.5*fPr    
1560   G4double kappa          = u/std::sqrt(CLHEP    
1561   G4double dTheta         = theta - fRutherfo    
1562   u                      *= dTheta;              
1563   G4double u2             = u*u;                 
1564   G4double u2m2p3         = u2*2./3.;            
1565                                                  
1566   G4complex im            = G4complex(0.,1.);    
1567   G4complex order         = G4complex(u,u);      
1568   order                  /= std::sqrt(2.);       
1569                                                  
1570   G4complex gamma         = CLHEP::pi*kappa*G    
1571   G4complex a0            = 0.5*(1. + 4.*(1.+    
1572   G4complex a1            = 0.5*(1. + 2.*(1.+    
1573   G4complex out           = gamma*(1. - a1*dT    
1574                                                  
1575   return out;                                    
1576 }                                                
1577                                                  
1578 /////////////////////////////////////////////    
1579 //                                               
1580 //                                               
1581                                                  
1582 G4complex G4NuclNuclDiffuseElastic::GammaMore    
1583 {                                                
1584   G4double sinThetaR      = 2.*fHalfRutThetaT    
1585   G4double cosHalfThetaR2 = 1./(1. + fHalfRut    
1586                                                  
1587   G4double u              = std::sqrt(0.5*fPr    
1588   G4double kappa          = u/std::sqrt(CLHEP    
1589   G4double dTheta         = theta - fRutherfo    
1590   u                      *= dTheta;              
1591   G4double u2             = u*u;                 
1592   G4double u2m2p3         = u2*2./3.;            
1593                                                  
1594   G4complex im            = G4complex(0.,1.);    
1595   G4complex order         = G4complex(u,u);      
1596   order                  /= std::sqrt(2.);       
1597   G4complex gamma         = CLHEP::pi*kappa*G    
1598   G4complex a0            = 0.5*(1. + 4.*(1.+    
1599   G4complex a1            = 0.5*(1. + 2.*(1.+    
1600   G4complex out           = -gamma*(1. - a1*d    
1601                                                  
1602   return out;                                    
1603 }                                                
1604                                                  
1605 /////////////////////////////////////////////    
1606 //                                               
1607 //                                               
1608                                                  
1609  G4complex G4NuclNuclDiffuseElastic::Amplitud    
1610 {                                                
1611   G4double kappa = std::sqrt(0.5*fProfileLamb    
1612   G4complex out = G4complex(kappa/fWaveVector    
1613                                                  
1614   out *= PhaseNear(theta);                       
1615                                                  
1616   if( theta <= fRutherfordTheta )                
1617   {                                              
1618     out *= GammaLess(theta) + ProfileNear(the    
1619     // out *= GammaMore(theta) + ProfileNear(    
1620     out += CoulombAmplitude(theta);              
1621   }                                              
1622   else                                           
1623   {                                              
1624     out *= GammaMore(theta) + ProfileNear(the    
1625     // out *= GammaLess(theta) + ProfileNear(    
1626   }                                              
1627   return out;                                    
1628 }                                                
1629                                                  
1630 /////////////////////////////////////////////    
1631 //                                               
1632 //                                               
1633                                                  
1634 G4complex G4NuclNuclDiffuseElastic::Amplitude    
1635 {                                                
1636   G4double sinThetaR  = 2.*fHalfRutThetaTg/(1    
1637   G4double dTheta     = 0.5*(theta - fRutherf    
1638   G4double sindTheta  = std::sin(dTheta);        
1639   G4double persqrt2   = std::sqrt(0.5);          
1640                                                  
1641   G4complex order     = G4complex(persqrt2,pe    
1642   order              *= std::sqrt(0.5*fProfil    
1643   // order              *= std::sqrt(0.5*fPro    
1644                                                  
1645   G4complex out;                                 
1646                                                  
1647   if ( theta <= fRutherfordTheta )               
1648   {                                              
1649     out = 1. - 0.5*GetErfcInt(-order)*Profile    
1650   }                                              
1651   else                                           
1652   {                                              
1653     out = 0.5*GetErfcInt(order)*ProfileNear(t    
1654   }                                              
1655                                                  
1656   out *= CoulombAmplitude(theta);                
1657                                                  
1658   return out;                                    
1659 }                                                
1660                                                  
1661 /////////////////////////////////////////////    
1662 //                                               
1663 //                                               
1664                                                  
1665  G4complex G4NuclNuclDiffuseElastic::Amplitud    
1666 {                                                
1667   G4int n;                                       
1668   G4double T12b, b, b2; // cosTheta = std::co    
1669   G4complex out = G4complex(0.,0.), shiftC, s    
1670   G4complex im  = G4complex(0.,1.);              
1671                                                  
1672   for( n = 0; n < fMaxL; n++)                    
1673   {                                              
1674     shiftC = std::exp( im*2.*CalculateCoulomb    
1675     // b = ( fZommerfeld + std::sqrt( fZommer    
1676     b = ( std::sqrt( G4double(n*(n+1)) ) )/fW    
1677     b2 = b*b;                                    
1678     T12b = fSumSigma*G4Exp(-b2/fNuclearRadius    
1679     shiftN = std::exp( -0.5*(1.-im*fEtaRatio)    
1680     out +=  (2.*n+1.)*shiftC*shiftN*GetLegend    
1681   }                                              
1682   out /= 2.*im*fWaveVector;                      
1683   out += CoulombAmplitude(theta);                
1684   return out;                                    
1685 }                                                
1686                                                  
1687                                                  
1688 /////////////////////////////////////////////    
1689 //                                               
1690 //                                               
1691                                                  
1692  G4complex G4NuclNuclDiffuseElastic::Amplitud    
1693 {                                                
1694   G4int n;                                       
1695   G4double T12b, a, aTemp, b2, sinThetaH = st    
1696   G4double sinThetaH2 = sinThetaH*sinThetaH;     
1697   G4complex out = G4complex(0.,0.);              
1698   G4complex im  = G4complex(0.,1.);              
1699                                                  
1700   a  = -fSumSigma/CLHEP::twopi/fNuclearRadius    
1701   b2 = fWaveVector*fWaveVector*fNuclearRadius    
1702                                                  
1703   aTemp = a;                                     
1704                                                  
1705   for( n = 1; n < fMaxL; n++)                    
1706   {                                              
1707     T12b   = aTemp*G4Exp(-b2/n)/n;               
1708     aTemp *= a;                                  
1709     out   += T12b;                               
1710     G4cout<<"out = "<<out<<G4endl;               
1711   }                                              
1712   out *= -4.*im*fWaveVector/CLHEP::pi;           
1713   out += CoulombAmplitude(theta);                
1714   return out;                                    
1715 }                                                
1716                                                  
1717                                                  
1718 /////////////////////////////////////////////    
1719 //                                               
1720 // Test for given particle and element table     
1721 // For the partMom in CMS.                       
1722                                                  
1723 void G4NuclNuclDiffuseElastic::InitParameters    
1724                                           G4d    
1725 {                                                
1726   fAtomicNumber  = Z;     // atomic number       
1727   fAtomicWeight  = A;     // number of nucleo    
1728                                                  
1729   fNuclearRadius2 = CalculateNuclearRad(fAtom    
1730   G4double A1     = G4double( theParticle->Ge    
1731   fNuclearRadius1 = CalculateNuclearRad(A1);     
1732   // fNuclearRadius = std::sqrt(fNuclearRadiu    
1733   fNuclearRadius = fNuclearRadius1 + fNuclear    
1734                                                  
1735   G4double a = 0.;                               
1736   G4double z = theParticle->GetPDGCharge();      
1737   G4double m1 = theParticle->GetPDGMass();       
1738                                                  
1739   fWaveVector = partMom/CLHEP::hbarc;            
1740                                                  
1741   G4double lambda = fCofLambda*fWaveVector*fN    
1742   G4cout<<"kR = "<<lambda<<G4endl;               
1743                                                  
1744   if( z )                                        
1745   {                                              
1746     a           = partMom/m1; // beta*gamma f    
1747     fBeta       = a/std::sqrt(1+a*a);            
1748     fZommerfeld = CalculateZommerfeld( fBeta,    
1749     fRutherfordRatio = fZommerfeld/fWaveVecto    
1750     fAm         = CalculateAm( partMom, fZomm    
1751   }                                              
1752   G4cout<<"fZommerfeld = "<<fZommerfeld<<G4en    
1753   fProfileLambda = lambda; // *std::sqrt(1.-2    
1754   G4cout<<"fProfileLambda = "<<fProfileLambda    
1755   fProfileDelta  = fCofDelta*fProfileLambda;     
1756   fProfileAlpha  = fCofAlpha*fProfileLambda;     
1757                                                  
1758   CalculateCoulombPhaseZero();                   
1759   CalculateRutherfordAnglePar();                 
1760                                                  
1761   return;                                        
1762 }                                                
1763 /////////////////////////////////////////////    
1764 //                                               
1765 // Test for given particle and element table     
1766 // For the partMom in CMS.                       
1767                                                  
1768 void G4NuclNuclDiffuseElastic::InitDynParamet    
1769                                           G4d    
1770 {                                                
1771   G4double a = 0.;                               
1772   G4double z = theParticle->GetPDGCharge();      
1773   G4double m1 = theParticle->GetPDGMass();       
1774                                                  
1775   fWaveVector = partMom/CLHEP::hbarc;            
1776                                                  
1777   G4double lambda = fCofLambda*fWaveVector*fN    
1778                                                  
1779   if( z )                                        
1780   {                                              
1781     a           = partMom/m1; // beta*gamma f    
1782     fBeta       = a/std::sqrt(1+a*a);            
1783     fZommerfeld = CalculateZommerfeld( fBeta,    
1784     fRutherfordRatio = fZommerfeld/fWaveVecto    
1785     fAm         = CalculateAm( partMom, fZomm    
1786   }                                              
1787   fProfileLambda = lambda; // *std::sqrt(1.-2    
1788   fProfileDelta  = fCofDelta*fProfileLambda;     
1789   fProfileAlpha  = fCofAlpha*fProfileLambda;     
1790                                                  
1791   CalculateCoulombPhaseZero();                   
1792   CalculateRutherfordAnglePar();                 
1793                                                  
1794   return;                                        
1795 }                                                
1796                                                  
1797                                                  
1798 /////////////////////////////////////////////    
1799 //                                               
1800 // Test for given particle and element table     
1801 // For the partMom in CMS.                       
1802                                                  
1803 void G4NuclNuclDiffuseElastic::InitParameters    
1804                                           G4d    
1805 {                                                
1806   fAtomicNumber  = Z;     // target atomic nu    
1807   fAtomicWeight  = A;     // target number of    
1808                                                  
1809   fNuclearRadius2 = CalculateNuclearRad(fAtom    
1810   G4double A1     = G4double( aParticle->GetD    
1811   fNuclearRadius1 = CalculateNuclearRad(A1);     
1812   fNuclearRadiusSquare = fNuclearRadius1*fNuc    
1813                                                  
1814                                                  
1815   G4double a  = 0., kR12;                        
1816   G4double z  = aParticle->GetDefinition()->G    
1817   G4double m1 = aParticle->GetDefinition()->G    
1818                                                  
1819   fWaveVector = partMom/CLHEP::hbarc;            
1820                                                  
1821   G4double pN = A1 - z;                          
1822   if( pN < 0. ) pN = 0.;                         
1823                                                  
1824   G4double tN = A - Z;                           
1825   if( tN < 0. ) tN = 0.;                         
1826                                                  
1827   G4double pTkin = aParticle->GetKineticEnerg    
1828   pTkin /= A1;                                   
1829                                                  
1830                                                  
1831   fSumSigma = (Z*z+pN*tN)*GetHadronNucleonXsc    
1832               (z*tN+pN*Z)*GetHadronNucleonXsc    
1833                                                  
1834   G4cout<<"fSumSigma = "<<fSumSigma/CLHEP::mi    
1835   G4cout<<"pi*R2 = "<<CLHEP::pi*fNuclearRadiu    
1836   kR12 = fWaveVector*std::sqrt(fNuclearRadius    
1837   G4cout<<"k*sqrt(R2) = "<<kR12<<" "<<G4endl;    
1838   fMaxL = (G4int(kR12)+1)*4;                     
1839   G4cout<<"fMaxL = "<<fMaxL<<" "<<G4endl;        
1840                                                  
1841   if( z )                                        
1842   {                                              
1843       a           = partMom/m1; // beta*gamma    
1844       fBeta       = a/std::sqrt(1+a*a);          
1845       fZommerfeld = CalculateZommerfeld( fBet    
1846       fAm         = CalculateAm( partMom, fZo    
1847   }                                              
1848                                                  
1849   CalculateCoulombPhaseZero();                   
1850                                                  
1851                                                  
1852   return;                                        
1853 }                                                
1854                                                  
1855                                                  
1856 /////////////////////////////////////////////    
1857 //                                               
1858 // Returns nucleon-nucleon cross-section base    
1859 // data from mainly http://wwwppds.ihep.su:80    
1860 // projectile nucleon is pParticle with pTkin    
1861                                                  
1862 G4double                                         
1863 G4NuclNuclDiffuseElastic::GetHadronNucleonXsc    
1864                                                  
1865                                                  
1866 {                                                
1867   G4double xsection(0), /*Delta,*/ A0, B0;       
1868   G4double hpXsc(0);                             
1869   G4double hnXsc(0);                             
1870                                                  
1871                                                  
1872   G4double targ_mass     = tParticle->GetPDGM    
1873   G4double proj_mass     = pParticle->GetPDGM    
1874                                                  
1875   G4double proj_energy   = proj_mass + pTkin;    
1876   G4double proj_momentum = std::sqrt(pTkin*(p    
1877                                                  
1878   G4double sMand = CalcMandelstamS ( proj_mas    
1879                                                  
1880   sMand         /= CLHEP::GeV*CLHEP::GeV;  //    
1881   proj_momentum /= CLHEP::GeV;                   
1882   proj_energy   /= CLHEP::GeV;                   
1883   proj_mass     /= CLHEP::GeV;                   
1884   G4double logS = G4Log(sMand);                  
1885                                                  
1886   // General PDG fit constants                   
1887                                                  
1888                                                  
1889   // fEtaRatio=Re[f(0)]/Im[f(0)]                 
1890                                                  
1891   if( proj_momentum >= 1.2 )                     
1892   {                                              
1893     fEtaRatio  = 0.13*(logS - 5.8579332)*G4Po    
1894   }                                              
1895   else if( proj_momentum >= 0.6 )                
1896   {                                              
1897     fEtaRatio = -75.5*(G4Pow::GetInstance()->    
1898     (G4Pow::GetInstance()->powA(3*proj_moment    
1899   }                                              
1900   else                                           
1901   {                                              
1902     fEtaRatio = 15.5*proj_momentum/(27*proj_m    
1903   }                                              
1904   G4cout<<"fEtaRatio = "<<fEtaRatio<<G4endl;     
1905                                                  
1906   // xsc                                         
1907                                                  
1908   if( proj_momentum >= 10. ) // high energy:     
1909     // if( proj_momentum >= 2.)                  
1910   {                                              
1911     //Delta = 1.;                                
1912                                                  
1913     //if( proj_energy < 40. ) Delta = 0.916+0    
1914                                                  
1915     //AR-12Aug2016  if( proj_momentum >= 10.)    
1916     {                                            
1917         B0 = 7.5;                                
1918         A0 = 100. - B0*G4Log(3.0e7);             
1919                                                  
1920         xsection = A0 + B0*G4Log(proj_energy)    
1921                   + 103*G4Pow::GetInstance()-    
1922                      0.93827*0.93827,-0.165);    
1923     }                                            
1924   }                                              
1925   else // low energy pp = nn != np               
1926   {                                              
1927       if(pParticle == tParticle) // pp or nn     
1928       {                                          
1929         if( proj_momentum < 0.73 )               
1930         {                                        
1931           hnXsc = 23 + 50*( G4Pow::GetInstanc    
1932         }                                        
1933         else if( proj_momentum < 1.05  )         
1934         {                                        
1935           hnXsc = 23 + 40*(G4Log(proj_momentu    
1936                          (G4Log(proj_momentum    
1937         }                                        
1938         else  // if( proj_momentum < 10.  )      
1939         {                                        
1940           hnXsc = 39.0 +                         
1941               75*(proj_momentum - 1.2)/(G4Pow    
1942         }                                        
1943         xsection = hnXsc;                        
1944       }                                          
1945       else  // pn to be np                       
1946       {                                          
1947         if( proj_momentum < 0.8 )                
1948         {                                        
1949           hpXsc = 33+30*G4Pow::GetInstance()-    
1950         }                                        
1951         else if( proj_momentum < 1.4 )           
1952         {                                        
1953           hpXsc = 33+30*G4Pow::GetInstance()-    
1954         }                                        
1955         else    // if( proj_momentum < 10.  )    
1956         {                                        
1957           hpXsc = 33.3+                          
1958               20.8*(G4Pow::GetInstance()->pow    
1959                  (G4Pow::GetInstance()->powA(    
1960         }                                        
1961         xsection = hpXsc;                        
1962       }                                          
1963   }                                              
1964   xsection *= CLHEP::millibarn; // parametris    
1965   G4cout<<"xsection = "<<xsection/CLHEP::mill    
1966   return xsection;                               
1967 }                                                
1968                                                  
1969 /////////////////////////////////////////////    
1970 //                                               
1971 // The ratio el/ruth for Fresnel smooth nucle    
1972                                                  
1973 G4double G4NuclNuclDiffuseElastic::GetRatioGe    
1974 {                                                
1975   G4double sinThetaR  = 2.*fHalfRutThetaTg/(1    
1976   G4double dTheta     = 0.5*(theta - fRutherf    
1977   G4double sindTheta  = std::sin(dTheta);        
1978                                                  
1979   G4double prof       = Profile(theta);          
1980   G4double prof2      = prof*prof;               
1981   // G4double profmod    = std::abs(prof);       
1982   G4double order      = std::sqrt(fProfileLam    
1983                                                  
1984   order = std::abs(order); // since sin chang    
1985   // G4cout<<"order = "<<order<<G4endl;          
1986                                                  
1987   G4double cosFresnel = GetCint(order);          
1988   G4double sinFresnel = GetSint(order);          
1989                                                  
1990   G4double out;                                  
1991                                                  
1992   if ( theta <= fRutherfordTheta )               
1993   {                                              
1994     out  = 1. + 0.5*( (0.5-cosFresnel)*(0.5-c    
1995     out += ( cosFresnel + sinFresnel - 1. )*p    
1996   }                                              
1997   else                                           
1998   {                                              
1999     out = 0.5*( (0.5-cosFresnel)*(0.5-cosFres    
2000   }                                              
2001                                                  
2002   return out;                                    
2003 }                                                
2004                                                  
2005 /////////////////////////////////////////////    
2006 //                                               
2007 // For the calculation of arg Gamma(z) one ne    
2008 // of ln(Gamma(z))                               
2009                                                  
2010 G4complex G4NuclNuclDiffuseElastic::GammaLoga    
2011 {                                                
2012   const G4double cof[6] = { 76.18009172947146    
2013                              24.0140982408309    
2014                               0.1208650973866    
2015   G4int j;                                       
2016   G4complex z = zz - 1.0;                        
2017   G4complex tmp = z + 5.5;                       
2018   tmp -= (z + 0.5) * std::log(tmp);              
2019   G4complex ser = G4complex(1.000000000190015    
2020                                                  
2021   for ( j = 0; j <= 5; j++ )                     
2022   {                                              
2023     z += 1.0;                                    
2024     ser += cof[j]/z;                             
2025   }                                              
2026   return -tmp + std::log(2.5066282746310005*s    
2027 }                                                
2028                                                  
2029 /////////////////////////////////////////////    
2030 //                                               
2031 // Bessel J0 function based on rational appro    
2032 // J.F. Hart, Computer Approximations, New Yo    
2033                                                  
2034 G4double G4NuclNuclDiffuseElastic::BesselJzer    
2035 {                                                
2036   G4double modvalue, value2, fact1, fact2, ar    
2037                                                  
2038   modvalue = std::fabs(value);                   
2039                                                  
2040   if ( value < 8.0 && value > -8.0 )             
2041   {                                              
2042     value2 = value*value;                        
2043                                                  
2044     fact1  = 57568490574.0 + value2*(-1336259    
2045                            + value2*( 6516196    
2046                            + value2*(-1121442    
2047                            + value2*( 77392.3    
2048                            + value2*(-184.905    
2049                                                  
2050     fact2  = 57568490411.0 + value2*( 1029532    
2051                            + value2*( 9494680    
2052                            + value2*(59272.64    
2053                            + value2*(267.8532    
2054                            + value2*1.0          
2055                                                  
2056     bessel = fact1/fact2;                        
2057   }                                              
2058   else                                           
2059   {                                              
2060     arg    = 8.0/modvalue;                       
2061                                                  
2062     value2 = arg*arg;                            
2063                                                  
2064     shift  = modvalue-0.785398164;               
2065                                                  
2066     fact1  = 1.0 + value2*(-0.1098628627e-2      
2067                  + value2*(0.2734510407e-4       
2068                  + value2*(-0.2073370639e-5      
2069                  + value2*0.2093887211e-6        
2070                                                  
2071     fact2  = -0.1562499995e-1 + value2*(0.143    
2072                               + value2*(-0.69    
2073                               + value2*(0.762    
2074                               - value2*0.9349    
2075                                                  
2076     bessel = std::sqrt(0.636619772/modvalue)*    
2077   }                                              
2078   return bessel;                                 
2079 }                                                
2080                                                  
2081 /////////////////////////////////////////////    
2082 //                                               
2083 // Bessel J1 function based on rational appro    
2084 // J.F. Hart, Computer Approximations, New Yo    
2085                                                  
2086 G4double G4NuclNuclDiffuseElastic::BesselJone    
2087 {                                                
2088   G4double modvalue, value2, fact1, fact2, ar    
2089                                                  
2090   modvalue = std::fabs(value);                   
2091                                                  
2092   if ( modvalue < 8.0 )                          
2093   {                                              
2094     value2 = value*value;                        
2095                                                  
2096     fact1  = value*(72362614232.0 + value2*(-    
2097                                   + value2*(     
2098                                   + value2*(-    
2099                                   + value2*(     
2100                                   + value2*(-    
2101                                                  
2102     fact2  = 144725228442.0 + value2*(2300535    
2103                             + value2*(1858330    
2104                             + value2*(99447.4    
2105                             + value2*(376.999    
2106                             + value2*1.0         
2107     bessel = fact1/fact2;                        
2108   }                                              
2109   else                                           
2110   {                                              
2111     arg    = 8.0/modvalue;                       
2112                                                  
2113     value2 = arg*arg;                            
2114                                                  
2115     shift  = modvalue - 2.356194491;             
2116                                                  
2117     fact1  = 1.0 + value2*( 0.183105e-2          
2118                  + value2*(-0.3516396496e-4      
2119                  + value2*(0.2457520174e-5       
2120                  + value2*(-0.240337019e-6       
2121                                                  
2122     fact2 = 0.04687499995 + value2*(-0.200269    
2123                           + value2*( 0.844919    
2124                           + value2*(-0.882289    
2125                           + value2*0.10578741    
2126                                                  
2127     bessel = std::sqrt( 0.636619772/modvalue)    
2128                                                  
2129     if (value < 0.0) bessel = -bessel;           
2130   }                                              
2131   return bessel;                                 
2132 }                                                
2133                                                  
2134 //                                               
2135 //                                               
2136 /////////////////////////////////////////////    
2137