Geant4  10.01.p03
G4DiffuseElastic.cc
Go to the documentation of this file.
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 // $Id: G4DiffuseElastic.cc 95251 2016-02-02 10:39:57Z gcosmo $
27 //
28 //
29 // Physics model class G4DiffuseElastic
30 //
31 //
32 // G4 Model: optical diffuse elastic scattering with 4-momentum balance
33 //
34 // 24-May-07 V. Grichine
35 //
36 // 21.10.15 V. Grichine
37 // Bug fixed in BuildAngleTable, improving accuracy for
38 // angle bins at high energies > 50 GeV for pions.
39 //
40 
41 #include "G4DiffuseElastic.hh"
42 #include "G4ParticleTable.hh"
43 #include "G4ParticleDefinition.hh"
44 #include "G4IonTable.hh"
45 #include "G4NucleiProperties.hh"
46 
47 #include "Randomize.hh"
48 #include "G4Integrator.hh"
49 #include "globals.hh"
50 #include "G4PhysicalConstants.hh"
51 #include "G4SystemOfUnits.hh"
52 
53 #include "G4Proton.hh"
54 #include "G4Neutron.hh"
55 #include "G4Deuteron.hh"
56 #include "G4Alpha.hh"
57 #include "G4PionPlus.hh"
58 #include "G4PionMinus.hh"
59 
60 #include "G4Element.hh"
61 #include "G4ElementTable.hh"
62 #include "G4NistManager.hh"
63 #include "G4PhysicsTable.hh"
64 #include "G4PhysicsLogVector.hh"
65 #include "G4PhysicsFreeVector.hh"
66 
68 //
69 // Test Constructor. Just to check xsc
70 
71 
73  : G4HadronElastic("DiffuseElastic"), fParticle(0)
74 {
75  SetMinEnergy( 0.01*MeV ); // 0.01*GeV );
76  SetMaxEnergy( 1.*TeV );
77  verboseLevel = 0;
78  lowEnergyRecoilLimit = 100.*keV;
79  lowEnergyLimitQ = 0.0*GeV;
80  lowEnergyLimitHE = 0.0*GeV;
81  lowestEnergyLimit= 0.0*keV;
82  plabLowLimit = 20.0*MeV;
83 
90 
91  fEnergyBin = 200;
92  fAngleBin = 200;
93 
95  fAngleTable = 0;
96 
97  fParticle = 0;
98  fWaveVector = 0.;
99  fAtomicWeight = 0.;
100  fAtomicNumber = 0.;
101  fNuclearRadius = 0.;
102  fBeta = 0.;
103  fZommerfeld = 0.;
104  fAm = 0.;
105  fAddCoulomb = false;
106 }
107 
109 //
110 // Destructor
111 
113 {
114  if ( fEnergyVector )
115  {
116  delete fEnergyVector;
117  fEnergyVector = 0;
118  }
119  for ( std::vector<G4PhysicsTable*>::iterator it = fAngleBank.begin();
120  it != fAngleBank.end(); ++it )
121  {
122  if ( (*it) ) (*it)->clearAndDestroy();
123 
124  delete *it;
125  *it = 0;
126  }
127  fAngleTable = 0;
128 }
129 
131 //
132 // Initialisation for given particle using element table of application
133 
135 {
136 
137  // fEnergyVector = new G4PhysicsLogVector( theMinEnergy, theMaxEnergy, fEnergyBin );
138 
139  const G4ElementTable* theElementTable = G4Element::GetElementTable();
140 
141  size_t jEl, numOfEl = G4Element::GetNumberOfElements();
142 
143  for( jEl = 0; jEl < numOfEl; ++jEl) // application element loop
144  {
145  fAtomicNumber = (*theElementTable)[jEl]->GetZ(); // atomic number
148 
149  if( verboseLevel > 0 )
150  {
151  G4cout<<"G4DiffuseElastic::Initialise() the element: "
152  <<(*theElementTable)[jEl]->GetName()<<G4endl;
153  }
155  fElementNameVector.push_back((*theElementTable)[jEl]->GetName());
156 
157  BuildAngleTable();
158  fAngleBank.push_back(fAngleTable);
159  }
160  return;
161 }
162 
164 //
165 // return differential elastic cross section d(sigma)/d(omega)
166 
167 G4double
169  G4double theta,
170  G4double momentum,
171  G4double A )
172 {
173  fParticle = particle;
174  fWaveVector = momentum/hbarc;
175  fAtomicWeight = A;
176  fAddCoulomb = false;
178 
180 
181  return sigma;
182 }
183 
185 //
186 // return invariant differential elastic cross section d(sigma)/d(tMand)
187 
188 G4double
190  G4double tMand,
191  G4double plab,
192  G4double A, G4double Z )
193 {
194  G4double m1 = particle->GetPDGMass();
195  G4LorentzVector lv1(0.,0.,plab,std::sqrt(plab*plab+m1*m1));
196 
197  G4int iZ = static_cast<G4int>(Z+0.5);
198  G4int iA = static_cast<G4int>(A+0.5);
199  G4ParticleDefinition * theDef = 0;
200 
201  if (iZ == 1 && iA == 1) theDef = theProton;
202  else if (iZ == 1 && iA == 2) theDef = theDeuteron;
203  else if (iZ == 1 && iA == 3) theDef = G4Triton::Triton();
204  else if (iZ == 2 && iA == 3) theDef = G4He3::He3();
205  else if (iZ == 2 && iA == 4) theDef = theAlpha;
206  else theDef = G4ParticleTable::GetParticleTable()->GetIonTable()->GetIon(iZ,iA,0);
207 
208  G4double tmass = theDef->GetPDGMass();
209 
210  G4LorentzVector lv(0.0,0.0,0.0,tmass);
211  lv += lv1;
212 
213  G4ThreeVector bst = lv.boostVector();
214  lv1.boost(-bst);
215 
216  G4ThreeVector p1 = lv1.vect();
217  G4double ptot = p1.mag();
218  G4double ptot2 = ptot*ptot;
219  G4double cost = 1 - 0.5*std::fabs(tMand)/ptot2;
220 
221  if( cost >= 1.0 ) cost = 1.0;
222  else if( cost <= -1.0) cost = -1.0;
223 
224  G4double thetaCMS = std::acos(cost);
225 
226  G4double sigma = GetDiffuseElasticXsc( particle, thetaCMS, ptot, A);
227 
228  sigma *= pi/ptot2;
229 
230  return sigma;
231 }
232 
234 //
235 // return differential elastic cross section d(sigma)/d(omega) with Coulomb
236 // correction
237 
238 G4double
240  G4double theta,
241  G4double momentum,
242  G4double A, G4double Z )
243 {
244  fParticle = particle;
245  fWaveVector = momentum/hbarc;
246  fAtomicWeight = A;
247  fAtomicNumber = Z;
249  fAddCoulomb = false;
250 
251  G4double z = particle->GetPDGCharge();
252 
253  G4double kRt = fWaveVector*fNuclearRadius*theta;
254  G4double kRtC = 1.9;
255 
256  if( z && (kRt > kRtC) )
257  {
258  fAddCoulomb = true;
259  fBeta = CalculateParticleBeta( particle, momentum);
261  fAm = CalculateAm( momentum, fZommerfeld, fAtomicNumber);
262  }
264 
265  return sigma;
266 }
267 
269 //
270 // return invariant differential elastic cross section d(sigma)/d(tMand) with Coulomb
271 // correction
272 
273 G4double
275  G4double tMand,
276  G4double plab,
277  G4double A, G4double Z )
278 {
279  G4double m1 = particle->GetPDGMass();
280 
281  G4LorentzVector lv1(0.,0.,plab,std::sqrt(plab*plab+m1*m1));
282 
283  G4int iZ = static_cast<G4int>(Z+0.5);
284  G4int iA = static_cast<G4int>(A+0.5);
285 
286  G4ParticleDefinition* theDef = 0;
287 
288  if (iZ == 1 && iA == 1) theDef = theProton;
289  else if (iZ == 1 && iA == 2) theDef = theDeuteron;
290  else if (iZ == 1 && iA == 3) theDef = G4Triton::Triton();
291  else if (iZ == 2 && iA == 3) theDef = G4He3::He3();
292  else if (iZ == 2 && iA == 4) theDef = theAlpha;
293  else theDef = G4ParticleTable::GetParticleTable()->GetIonTable()->GetIon(iZ,iA,0);
294 
295  G4double tmass = theDef->GetPDGMass();
296 
297  G4LorentzVector lv(0.0,0.0,0.0,tmass);
298  lv += lv1;
299 
300  G4ThreeVector bst = lv.boostVector();
301  lv1.boost(-bst);
302 
303  G4ThreeVector p1 = lv1.vect();
304  G4double ptot = p1.mag();
305  G4double ptot2 = ptot*ptot;
306  G4double cost = 1 - 0.5*std::fabs(tMand)/ptot2;
307 
308  if( cost >= 1.0 ) cost = 1.0;
309  else if( cost <= -1.0) cost = -1.0;
310 
311  G4double thetaCMS = std::acos(cost);
312 
313  G4double sigma = GetDiffuseElasticSumXsc( particle, thetaCMS, ptot, A, Z );
314 
315  sigma *= pi/ptot2;
316 
317  return sigma;
318 }
319 
321 //
322 // return invariant differential elastic cross section d(sigma)/d(tMand) with Coulomb
323 // correction
324 
325 G4double
327  G4double tMand,
328  G4double plab,
329  G4double A, G4double Z )
330 {
331  G4double m1 = particle->GetPDGMass();
332  G4LorentzVector lv1(0.,0.,plab,std::sqrt(plab*plab+m1*m1));
333 
334  G4int iZ = static_cast<G4int>(Z+0.5);
335  G4int iA = static_cast<G4int>(A+0.5);
336  G4ParticleDefinition * theDef = 0;
337 
338  if (iZ == 1 && iA == 1) theDef = theProton;
339  else if (iZ == 1 && iA == 2) theDef = theDeuteron;
340  else if (iZ == 1 && iA == 3) theDef = G4Triton::Triton();
341  else if (iZ == 2 && iA == 3) theDef = G4He3::He3();
342  else if (iZ == 2 && iA == 4) theDef = theAlpha;
343  else theDef = G4ParticleTable::GetParticleTable()->GetIonTable()->GetIon(iZ,iA,0);
344 
345  G4double tmass = theDef->GetPDGMass();
346 
347  G4LorentzVector lv(0.0,0.0,0.0,tmass);
348  lv += lv1;
349 
350  G4ThreeVector bst = lv.boostVector();
351  lv1.boost(-bst);
352 
353  G4ThreeVector p1 = lv1.vect();
354  G4double ptot = p1.mag();
355  G4double ptot2 = ptot*ptot;
356  G4double cost = 1 - 0.5*std::fabs(tMand)/ptot2;
357 
358  if( cost >= 1.0 ) cost = 1.0;
359  else if( cost <= -1.0) cost = -1.0;
360 
361  G4double thetaCMS = std::acos(cost);
362 
363  G4double sigma = GetCoulombElasticXsc( particle, thetaCMS, ptot, Z );
364 
365  sigma *= pi/ptot2;
366 
367  return sigma;
368 }
369 
371 //
372 // return differential elastic probability d(probability)/d(omega)
373 
374 G4double
375 G4DiffuseElastic::GetDiffElasticProb( // G4ParticleDefinition* particle,
376  G4double theta
377  // G4double momentum,
378  // G4double A
379  )
380 {
381  G4double sigma, bzero, bzero2, bonebyarg, bonebyarg2, damp, damp2;
382  G4double delta, diffuse, gamma;
383  G4double e1, e2, bone, bone2;
384 
385  // G4double wavek = momentum/hbarc; // wave vector
386  // G4double r0 = 1.08*fermi;
387  // G4double rad = r0*std::pow(A, 1./3.);
388 
389  if (fParticle == theProton)
390  {
391  diffuse = 0.63*fermi;
392  gamma = 0.3*fermi;
393  delta = 0.1*fermi*fermi;
394  e1 = 0.3*fermi;
395  e2 = 0.35*fermi;
396  }
397  else if (fParticle == theNeutron)
398  {
399  diffuse = 0.63*fermi; // 1.63*fermi; //
400  G4double k0 = 1*GeV/hbarc;
401  diffuse *= k0/fWaveVector;
402 
403  gamma = 0.3*fermi;
404  delta = 0.1*fermi*fermi;
405  e1 = 0.3*fermi;
406  e2 = 0.35*fermi;
407  }
408  else // as proton, if were not defined
409  {
410  diffuse = 0.63*fermi;
411  gamma = 0.3*fermi;
412  delta = 0.1*fermi*fermi;
413  e1 = 0.3*fermi;
414  e2 = 0.35*fermi;
415  }
416  G4double kr = fWaveVector*fNuclearRadius; // wavek*rad;
417  G4double kr2 = kr*kr;
418  G4double krt = kr*theta;
419 
420  bzero = BesselJzero(krt);
421  bzero2 = bzero*bzero;
422  bone = BesselJone(krt);
423  bone2 = bone*bone;
424  bonebyarg = BesselOneByArg(krt);
425  bonebyarg2 = bonebyarg*bonebyarg;
426 
427  G4double lambda = 15.; // 15 ok
428 
429  // G4double kgamma = fWaveVector*gamma; // wavek*delta;
430 
431  G4double kgamma = lambda*(1.-std::exp(-fWaveVector*gamma/lambda)); // wavek*delta;
432  G4double kgamma2 = kgamma*kgamma;
433 
434  // G4double dk2t = delta*fWaveVector*fWaveVector*theta; // delta*wavek*wavek*theta;
435  // G4double dk2t2 = dk2t*dk2t;
436  // G4double pikdt = pi*fWaveVector*diffuse*theta;// pi*wavek*diffuse*theta;
437 
438  G4double pikdt = lambda*(1.-std::exp(-pi*fWaveVector*diffuse*theta/lambda)); // wavek*delta;
439 
440  damp = DampFactor(pikdt);
441  damp2 = damp*damp;
442 
443  G4double mode2k2 = (e1*e1+e2*e2)*fWaveVector*fWaveVector;
444  G4double e2dk3t = -2.*e2*delta*fWaveVector*fWaveVector*fWaveVector*theta;
445 
446 
447  sigma = kgamma2;
448  // sigma += dk2t2;
449  sigma *= bzero2;
450  sigma += mode2k2*bone2 + e2dk3t*bzero*bone;
451  sigma += kr2*bonebyarg2;
452  sigma *= damp2; // *rad*rad;
453 
454  return sigma;
455 }
456 
458 //
459 // return differential elastic probability d(probability)/d(omega) with
460 // Coulomb correction
461 
462 G4double
463 G4DiffuseElastic::GetDiffElasticSumProb( // G4ParticleDefinition* particle,
464  G4double theta
465  // G4double momentum,
466  // G4double A
467  )
468 {
469  G4double sigma, bzero, bzero2, bonebyarg, bonebyarg2, damp, damp2;
470  G4double delta, diffuse, gamma;
471  G4double e1, e2, bone, bone2;
472 
473  // G4double wavek = momentum/hbarc; // wave vector
474  // G4double r0 = 1.08*fermi;
475  // G4double rad = r0*std::pow(A, 1./3.);
476 
477  G4double kr = fWaveVector*fNuclearRadius; // wavek*rad;
478  G4double kr2 = kr*kr;
479  G4double krt = kr*theta;
480 
481  bzero = BesselJzero(krt);
482  bzero2 = bzero*bzero;
483  bone = BesselJone(krt);
484  bone2 = bone*bone;
485  bonebyarg = BesselOneByArg(krt);
486  bonebyarg2 = bonebyarg*bonebyarg;
487 
488  if (fParticle == theProton)
489  {
490  diffuse = 0.63*fermi;
491  // diffuse = 0.6*fermi;
492  gamma = 0.3*fermi;
493  delta = 0.1*fermi*fermi;
494  e1 = 0.3*fermi;
495  e2 = 0.35*fermi;
496  }
497  else if (fParticle == theNeutron)
498  {
499  diffuse = 0.63*fermi;
500  // diffuse = 0.6*fermi;
501  G4double k0 = 1*GeV/hbarc;
502  diffuse *= k0/fWaveVector;
503  gamma = 0.3*fermi;
504  delta = 0.1*fermi*fermi;
505  e1 = 0.3*fermi;
506  e2 = 0.35*fermi;
507  }
508  else // as proton, if were not defined
509  {
510  diffuse = 0.63*fermi;
511  gamma = 0.3*fermi;
512  delta = 0.1*fermi*fermi;
513  e1 = 0.3*fermi;
514  e2 = 0.35*fermi;
515  }
516  G4double lambda = 15.; // 15 ok
517  // G4double kgamma = fWaveVector*gamma; // wavek*delta;
518  G4double kgamma = lambda*(1.-std::exp(-fWaveVector*gamma/lambda)); // wavek*delta;
519 
520  // G4cout<<"kgamma = "<<kgamma<<G4endl;
521 
522  if(fAddCoulomb) // add Coulomb correction
523  {
524  G4double sinHalfTheta = std::sin(0.5*theta);
525  G4double sinHalfTheta2 = sinHalfTheta*sinHalfTheta;
526 
527  kgamma += 0.5*fZommerfeld/kr/(sinHalfTheta2+fAm); // correction at J0()
528  // kgamma += 0.65*fZommerfeld/kr/(sinHalfTheta2+fAm); // correction at J0()
529  }
530 
531  G4double kgamma2 = kgamma*kgamma;
532 
533  // G4double dk2t = delta*fWaveVector*fWaveVector*theta; // delta*wavek*wavek*theta;
534  // G4cout<<"dk2t = "<<dk2t<<G4endl;
535  // G4double dk2t2 = dk2t*dk2t;
536  // G4double pikdt = pi*fWaveVector*diffuse*theta;// pi*wavek*diffuse*theta;
537 
538  G4double pikdt = lambda*(1.-std::exp(-pi*fWaveVector*diffuse*theta/lambda)); // wavek*delta;
539 
540  // G4cout<<"pikdt = "<<pikdt<<G4endl;
541 
542  damp = DampFactor(pikdt);
543  damp2 = damp*damp;
544 
545  G4double mode2k2 = (e1*e1+e2*e2)*fWaveVector*fWaveVector;
546  G4double e2dk3t = -2.*e2*delta*fWaveVector*fWaveVector*fWaveVector*theta;
547 
548  sigma = kgamma2;
549  // sigma += dk2t2;
550  sigma *= bzero2;
551  sigma += mode2k2*bone2;
552  sigma += e2dk3t*bzero*bone;
553 
554  // sigma += kr2*(1 + 8.*fZommerfeld*fZommerfeld/kr2)*bonebyarg2; // correction at J1()/()
555  sigma += kr2*bonebyarg2; // correction at J1()/()
556 
557  sigma *= damp2; // *rad*rad;
558 
559  return sigma;
560 }
561 
562 
564 //
565 // return differential elastic probability d(probability)/d(t) with
566 // Coulomb correction. It is called from BuildAngleTable()
567 
568 G4double
570 {
571  G4double theta;
572 
573  theta = std::sqrt(alpha);
574 
575  // theta = std::acos( 1 - alpha/2. );
576 
577  G4double sigma, bzero, bzero2, bonebyarg, bonebyarg2, damp, damp2;
578  G4double delta, diffuse, gamma;
579  G4double e1, e2, bone, bone2;
580 
581  // G4double wavek = momentum/hbarc; // wave vector
582  // G4double r0 = 1.08*fermi;
583  // G4double rad = r0*std::pow(A, 1./3.);
584 
585  G4double kr = fWaveVector*fNuclearRadius; // wavek*rad;
586  G4double kr2 = kr*kr;
587  G4double krt = kr*theta;
588 
589  bzero = BesselJzero(krt);
590  bzero2 = bzero*bzero;
591  bone = BesselJone(krt);
592  bone2 = bone*bone;
593  bonebyarg = BesselOneByArg(krt);
594  bonebyarg2 = bonebyarg*bonebyarg;
595 
596  if ( fParticle == theProton )
597  {
598  diffuse = 0.63*fermi;
599  // diffuse = 0.6*fermi;
600  gamma = 0.3*fermi;
601  delta = 0.1*fermi*fermi;
602  e1 = 0.3*fermi;
603  e2 = 0.35*fermi;
604  }
605  else if ( fParticle == theNeutron )
606  {
607  diffuse = 0.63*fermi;
608  // diffuse = 0.6*fermi;
609  // G4double k0 = 0.8*GeV/hbarc;
610  // diffuse *= k0/fWaveVector;
611  gamma = 0.3*fermi;
612  delta = 0.1*fermi*fermi;
613  e1 = 0.3*fermi;
614  e2 = 0.35*fermi;
615  }
616  else // as proton, if were not defined
617  {
618  diffuse = 0.63*fermi;
619  gamma = 0.3*fermi;
620  delta = 0.1*fermi*fermi;
621  e1 = 0.3*fermi;
622  e2 = 0.35*fermi;
623  }
624  G4double lambda = 15.; // 15 ok
625  // G4double kgamma = fWaveVector*gamma; // wavek*delta;
626  G4double kgamma = lambda*(1.-std::exp(-fWaveVector*gamma/lambda)); // wavek*delta;
627 
628  // G4cout<<"kgamma = "<<kgamma<<G4endl;
629 
630  if( fAddCoulomb ) // add Coulomb correction
631  {
632  G4double sinHalfTheta = theta*0.5; // std::sin(0.5*theta);
633  G4double sinHalfTheta2 = sinHalfTheta*sinHalfTheta;
634 
635  kgamma += 0.5*fZommerfeld/kr/(sinHalfTheta2+fAm); // correction at J0()
636  // kgamma += 0.65*fZommerfeld/kr/(sinHalfTheta2+fAm); // correction at J0()
637  }
638  G4double kgamma2 = kgamma*kgamma;
639 
640  // G4double dk2t = delta*fWaveVector*fWaveVector*theta; // delta*wavek*wavek*theta;
641  // G4cout<<"dk2t = "<<dk2t<<G4endl;
642  // G4double dk2t2 = dk2t*dk2t;
643  // G4double pikdt = pi*fWaveVector*diffuse*theta;// pi*wavek*diffuse*theta;
644 
645  G4double pikdt = lambda*(1. - std::exp( -pi*fWaveVector*diffuse*theta/lambda ) ); // wavek*delta;
646 
647  // G4cout<<"pikdt = "<<pikdt<<G4endl;
648 
649  damp = DampFactor( pikdt );
650  damp2 = damp*damp;
651 
652  G4double mode2k2 = ( e1*e1 + e2*e2 )*fWaveVector*fWaveVector;
653  G4double e2dk3t = -2.*e2*delta*fWaveVector*fWaveVector*fWaveVector*theta;
654 
655  sigma = kgamma2;
656  // sigma += dk2t2;
657  sigma *= bzero2;
658  sigma += mode2k2*bone2;
659  sigma += e2dk3t*bzero*bone;
660 
661  // sigma += kr2*(1 + 8.*fZommerfeld*fZommerfeld/kr2)*bonebyarg2; // correction at J1()/()
662  sigma += kr2*bonebyarg2; // correction at J1()/()
663 
664  sigma *= damp2; // *rad*rad;
665 
666  return sigma;
667 }
668 
669 
671 //
672 // return differential elastic probability 2*pi*sin(theta)*d(probability)/d(omega)
673 
674 G4double
676 {
677  G4double result;
678 
679  result = GetDiffElasticSumProbA(alpha);
680 
681  // result *= 2*pi*std::sin(theta);
682 
683  return result;
684 }
685 
687 //
688 // return integral elastic cross section d(sigma)/d(omega) integrated 0 - theta
689 
690 G4double
692  G4double theta,
693  G4double momentum,
694  G4double A )
695 {
696  G4double result;
697  fParticle = particle;
698  fWaveVector = momentum/hbarc;
699  fAtomicWeight = A;
700 
702 
703 
705 
706  // result = integral.Legendre10(this,&G4DiffuseElastic::GetIntegrandFunction, 0., theta );
707  result = integral.Legendre96(this,&G4DiffuseElastic::GetIntegrandFunction, 0., theta );
708 
709  return result;
710 }
711 
713 //
714 // Return inv momentum transfer -t > 0
715 
717 {
718  G4double theta = SampleThetaCMS( aParticle, p, A); // sample theta in cms
719  G4double t = 2*p*p*( 1 - std::cos(theta) ); // -t !!!
720  return t;
721 }
722 
724 //
725 // Return scattering angle sampled in cms
726 
727 
728 G4double
730  G4double momentum, G4double A)
731 {
732  G4int i, iMax = 100;
733  G4double norm, result, theta1, theta2, thetaMax, sum = 0.;
734 
735  fParticle = particle;
736  fWaveVector = momentum/hbarc;
737  fAtomicWeight = A;
738 
740 
741  thetaMax = 10.174/fWaveVector/fNuclearRadius;
742 
743  if (thetaMax > pi) thetaMax = pi;
744 
746 
747  // result = integral.Legendre10(this,&G4DiffuseElastic::GetIntegrandFunction, 0., theta );
748  norm = integral.Legendre96(this,&G4DiffuseElastic::GetIntegrandFunction, 0., thetaMax );
749 
750  norm *= G4UniformRand();
751 
752  for(i = 1; i <= iMax; i++)
753  {
754  theta1 = (i-1)*thetaMax/iMax;
755  theta2 = i*thetaMax/iMax;
756  sum += integral.Legendre10(this,&G4DiffuseElastic::GetIntegrandFunction, theta1, theta2);
757 
758  if ( sum >= norm )
759  {
760  result = 0.5*(theta1 + theta2);
761  break;
762  }
763  }
764  if (i > iMax ) result = 0.5*(theta1 + theta2);
765 
766  G4double sigma = pi*thetaMax/iMax;
767 
768  result += G4RandGauss::shoot(0.,sigma);
769 
770  if(result < 0.) result = 0.;
771  if(result > thetaMax) result = thetaMax;
772 
773  return result;
774 }
775 
779 //
780 // Return inv momentum transfer -t > 0 from initialisation table
781 
783  G4int Z, G4int A)
784 {
785  fParticle = aParticle;
786  G4double m1 = fParticle->GetPDGMass(), t;
787  G4double totElab = std::sqrt(m1*m1+p*p);
789  G4LorentzVector lv1(p,0.0,0.0,totElab);
790  G4LorentzVector lv(0.0,0.0,0.0,mass2);
791  lv += lv1;
792 
793  G4ThreeVector bst = lv.boostVector();
794  lv1.boost(-bst);
795 
796  G4ThreeVector p1 = lv1.vect();
797  G4double momentumCMS = p1.mag();
798 
799  if( aParticle == theNeutron)
800  {
801  G4double Tmax = NeutronTuniform( Z );
802  G4double pCMS2 = momentumCMS*momentumCMS;
803  G4double Tkin = std::sqrt(pCMS2+m1*m1)-m1;
804 
805  if( Tkin <= Tmax )
806  {
807  t = 4.*pCMS2*G4UniformRand();
808  // G4cout<<Tkin<<", "<<Tmax<<", "<<std::sqrt(t)<<"; ";
809  return t;
810  }
811  }
812 
813  t = SampleTableT( aParticle, momentumCMS, G4double(Z), G4double(A) ); // sample theta2 in cms
814 
815  return t;
816 }
817 
819 
821 {
822  G4double elZ = G4double(Z);
823  elZ -= 1.;
824  // G4double Tkin = 20.*std::exp(-elZ/10.) + 1.;
825  G4double Tkin = 12.*std::exp(-elZ/10.) + 1.;
826  return Tkin;
827 }
828 
829 
831 //
832 // Return inv momentum transfer -t > 0 from initialisation table
833 
835  G4double Z, G4double A)
836 {
837  G4double alpha = SampleTableThetaCMS( aParticle, p, Z, A); // sample theta2 in cms
838  G4double t = 2*p*p*( 1 - std::cos(std::sqrt(alpha)) ); // -t !!!
839  // G4double t = p*p*alpha; // -t !!!
840  return t;
841 }
842 
844 //
845 // Return scattering angle2 sampled in cms according to precalculated table.
846 
847 
848 G4double
850  G4double momentum, G4double Z, G4double A)
851 {
852  size_t iElement;
853  G4int iMomentum, iAngle;
854  G4double randAngle, position, theta1, theta2, E1, E2, W1, W2, W;
855  G4double m1 = particle->GetPDGMass();
856 
857  for(iElement = 0; iElement < fElementNumberVector.size(); iElement++)
858  {
859  if( std::fabs(Z - fElementNumberVector[iElement]) < 0.5) break;
860  }
861  if ( iElement == fElementNumberVector.size() )
862  {
863  InitialiseOnFly(Z,A); // table preparation, if needed
864 
865  // iElement--;
866 
867  // G4cout << "G4DiffuseElastic: Element with atomic number " << Z
868  // << " is not found, return zero angle" << G4endl;
869  // return 0.; // no table for this element
870  }
871  // G4cout<<"iElement = "<<iElement<<G4endl;
872 
873  fAngleTable = fAngleBank[iElement];
874 
875  G4double kinE = std::sqrt(momentum*momentum + m1*m1) - m1;
876 
877  for( iMomentum = 0; iMomentum < fEnergyBin; iMomentum++)
878  {
879  if( kinE < fEnergyVector->GetLowEdgeEnergy(iMomentum) ) break;
880  }
881  if ( iMomentum >= fEnergyBin ) iMomentum = fEnergyBin-1; // kinE is more then theMaxEnergy
882  if ( iMomentum < 0 ) iMomentum = 0; // against negative index, kinE < theMinEnergy
883 
884  // G4cout<<"iMomentum = "<<iMomentum<<G4endl;
885 
886  if (iMomentum == fEnergyBin -1 || iMomentum == 0 ) // the table edges
887  {
888  position = (*(*fAngleTable)(iMomentum))(fAngleBin-2)*G4UniformRand();
889 
890  // G4cout<<"position = "<<position<<G4endl;
891 
892  for(iAngle = 0; iAngle < fAngleBin-1; iAngle++)
893  {
894  if( position > (*(*fAngleTable)(iMomentum))(iAngle) ) break;
895  }
896  if (iAngle >= fAngleBin-1) iAngle = fAngleBin-2;
897 
898  // G4cout<<"iAngle = "<<iAngle<<G4endl;
899 
900  randAngle = GetScatteringAngle(iMomentum, iAngle, position);
901 
902  // G4cout<<"randAngle = "<<randAngle<<G4endl;
903  }
904  else // kinE inside between energy table edges
905  {
906  // position = (*(*fAngleTable)(iMomentum))(fAngleBin-2)*G4UniformRand();
907  position = (*(*fAngleTable)(iMomentum))(0)*G4UniformRand();
908 
909  // G4cout<<"position = "<<position<<G4endl;
910 
911  for(iAngle = 0; iAngle < fAngleBin-1; iAngle++)
912  {
913  // if( position < (*(*fAngleTable)(iMomentum))(iAngle) ) break;
914  if( position > (*(*fAngleTable)(iMomentum))(iAngle) ) break;
915  }
916  if (iAngle >= fAngleBin-1) iAngle = fAngleBin-2;
917 
918  // G4cout<<"iAngle = "<<iAngle<<G4endl;
919 
920  theta2 = GetScatteringAngle(iMomentum, iAngle, position);
921 
922  // G4cout<<"theta2 = "<<theta2<<G4endl;
923  E2 = fEnergyVector->GetLowEdgeEnergy(iMomentum);
924 
925  // G4cout<<"E2 = "<<E2<<G4endl;
926 
927  iMomentum--;
928 
929  // position = (*(*fAngleTable)(iMomentum))(fAngleBin-2)*G4UniformRand();
930 
931  // G4cout<<"position = "<<position<<G4endl;
932 
933  for(iAngle = 0; iAngle < fAngleBin-1; iAngle++)
934  {
935  // if( position < (*(*fAngleTable)(iMomentum))(iAngle) ) break;
936  if( position > (*(*fAngleTable)(iMomentum))(iAngle) ) break;
937  }
938  if (iAngle >= fAngleBin-1) iAngle = fAngleBin-2;
939 
940  theta1 = GetScatteringAngle(iMomentum, iAngle, position);
941 
942  // G4cout<<"theta1 = "<<theta1<<G4endl;
943 
944  E1 = fEnergyVector->GetLowEdgeEnergy(iMomentum);
945 
946  // G4cout<<"E1 = "<<E1<<G4endl;
947 
948  W = 1.0/(E2 - E1);
949  W1 = (E2 - kinE)*W;
950  W2 = (kinE - E1)*W;
951 
952  randAngle = W1*theta1 + W2*theta2;
953 
954  // randAngle = theta2;
955  // G4cout<<"randAngle = "<<randAngle<<G4endl;
956  }
957  // G4double angle = randAngle;
958  // if (randAngle > 0.) randAngle /= 2*pi*std::sin(angle);
959 
960  if(randAngle < 0.) randAngle = 0.;
961 
962  return randAngle;
963 }
964 
966 //
967 // Initialisation for given particle on fly using new element number
968 
970 {
971  fAtomicNumber = Z; // atomic number
972  fAtomicWeight = G4NistManager::Instance()->GetAtomicMassAmu( static_cast< G4int >( Z ) );
973 
975 
976  if( verboseLevel > 0 )
977  {
978  G4cout<<"G4DiffuseElastic::InitialiseOnFly() the element with Z = "
979  <<Z<<"; and A = "<<A<<G4endl;
980  }
982 
983  BuildAngleTable();
984 
985  fAngleBank.push_back(fAngleTable);
986 
987  return;
988 }
989 
991 //
992 // Build for given particle and element table of momentum, angle probability.
993 // For the moment in lab system.
994 
996 {
997  G4int i, j;
998  G4double partMom, kinE, a = 0., z = fParticle->GetPDGCharge(), m1 = fParticle->GetPDGMass();
999  G4double alpha1, alpha2, alphaMax, alphaCoulomb, delta = 0., sum = 0.;
1000 
1002 
1004 
1005  for( i = 0; i < fEnergyBin; i++)
1006  {
1007  kinE = fEnergyVector->GetLowEdgeEnergy(i);
1008  partMom = std::sqrt( kinE*(kinE + 2*m1) );
1009 
1010  fWaveVector = partMom/hbarc;
1011 
1013  G4double kR2 = kR*kR;
1014  G4double kRmax = 18.6; // 10.6; 10.6, 18, 10.174; ~ 3 maxima of J1 or 15., 25.
1015  G4double kRcoul = 1.9; // 1.2; 1.4, 2.5; // on the first slope of J1
1016  // G4double kRlim = 1.2;
1017  // G4double kRlim2 = kRlim*kRlim/kR2;
1018 
1019  alphaMax = kRmax*kRmax/kR2;
1020 
1021 
1022  // if (alphaMax > 4.) alphaMax = 4.; // vmg05-02-09: was pi2
1023  // if ( alphaMax > 4. || alphaMax < 1. ) alphaMax = 15.; // vmg27.11.14
1024 
1025  // if ( alphaMax > 4. || alphaMax < 1. ) alphaMax = CLHEP::pi*CLHEP::pi; // vmg06.01.15
1026 
1027  // G4cout<<"alphaMax = "<<alphaMax<<", ";
1028 
1029  if ( alphaMax >= CLHEP::pi*CLHEP::pi ) alphaMax = CLHEP::pi*CLHEP::pi; // vmg21.10.15
1030 
1031  alphaCoulomb = kRcoul*kRcoul/kR2;
1032 
1033  if( z )
1034  {
1035  a = partMom/m1; // beta*gamma for m1
1036  fBeta = a/std::sqrt(1+a*a);
1038  fAm = CalculateAm( partMom, fZommerfeld, fAtomicNumber);
1039  }
1040  G4PhysicsFreeVector* angleVector = new G4PhysicsFreeVector(fAngleBin-1);
1041 
1042  // G4PhysicsLogVector* angleBins = new G4PhysicsLogVector( 0.001*alphaMax, alphaMax, fAngleBin );
1043 
1044  G4double delth = alphaMax/fAngleBin;
1045 
1046  sum = 0.;
1047 
1048  // fAddCoulomb = false;
1049  fAddCoulomb = true;
1050 
1051  // for(j = 1; j < fAngleBin; j++)
1052  for(j = fAngleBin-1; j >= 1; j--)
1053  {
1054  // alpha1 = angleBins->GetLowEdgeEnergy(j-1);
1055  // alpha2 = angleBins->GetLowEdgeEnergy(j);
1056 
1057  // alpha1 = alphaMax*(j-1)/fAngleBin;
1058  // alpha2 = alphaMax*( j )/fAngleBin;
1059 
1060  alpha1 = delth*(j-1);
1061  // if(alpha1 < kRlim2) alpha1 = kRlim2;
1062  alpha2 = alpha1 + delth;
1063 
1064  // if( ( alpha2 > alphaCoulomb ) && z ) fAddCoulomb = true;
1065  if( ( alpha1 < alphaCoulomb ) && z ) fAddCoulomb = false;
1066 
1067  delta = integral.Legendre10(this, &G4DiffuseElastic::GetIntegrandFunction, alpha1, alpha2);
1068  // delta = integral.Legendre96(this, &G4DiffuseElastic::GetIntegrandFunction, alpha1, alpha2);
1069 
1070  sum += delta;
1071 
1072  angleVector->PutValue( j-1 , alpha1, sum ); // alpha2
1073  // G4cout<<"j-1 = "<<j-1<<"; alpha2 = "<<alpha2<<"; sum = "<<sum<<G4endl;
1074  }
1075  fAngleTable->insertAt(i,angleVector);
1076 
1077  // delete[] angleVector;
1078  // delete[] angleBins;
1079  }
1080  return;
1081 }
1082 
1084 //
1085 //
1086 
1087 G4double
1089 {
1090  G4double x1, x2, y1, y2, randAngle;
1091 
1092  if( iAngle == 0 )
1093  {
1094  randAngle = (*fAngleTable)(iMomentum)->GetLowEdgeEnergy(iAngle);
1095  // iAngle++;
1096  }
1097  else
1098  {
1099  if ( iAngle >= G4int((*fAngleTable)(iMomentum)->GetVectorLength()) )
1100  {
1101  iAngle = (*fAngleTable)(iMomentum)->GetVectorLength() - 1;
1102  }
1103  y1 = (*(*fAngleTable)(iMomentum))(iAngle-1);
1104  y2 = (*(*fAngleTable)(iMomentum))(iAngle);
1105 
1106  x1 = (*fAngleTable)(iMomentum)->GetLowEdgeEnergy(iAngle-1);
1107  x2 = (*fAngleTable)(iMomentum)->GetLowEdgeEnergy(iAngle);
1108 
1109  if ( x1 == x2 ) randAngle = x2;
1110  else
1111  {
1112  if ( y1 == y2 ) randAngle = x1 + ( x2 - x1 )*G4UniformRand();
1113  else
1114  {
1115  randAngle = x1 + ( position - y1 )*( x2 - x1 )/( y2 - y1 );
1116  }
1117  }
1118  }
1119  return randAngle;
1120 }
1121 
1122 
1123 
1125 //
1126 // Return scattering angle sampled in lab system (target at rest)
1127 
1128 
1129 
1130 G4double
1132  G4double tmass, G4double A)
1133 {
1134  const G4ParticleDefinition* theParticle = aParticle->GetDefinition();
1135  G4double m1 = theParticle->GetPDGMass();
1136  G4double plab = aParticle->GetTotalMomentum();
1137  G4LorentzVector lv1 = aParticle->Get4Momentum();
1138  G4LorentzVector lv(0.0,0.0,0.0,tmass);
1139  lv += lv1;
1140 
1141  G4ThreeVector bst = lv.boostVector();
1142  lv1.boost(-bst);
1143 
1144  G4ThreeVector p1 = lv1.vect();
1145  G4double ptot = p1.mag();
1146  G4double tmax = 4.0*ptot*ptot;
1147  G4double t = 0.0;
1148 
1149 
1150  //
1151  // Sample t
1152  //
1153 
1154  t = SampleT( theParticle, ptot, A);
1155 
1156  // NaN finder
1157  if(!(t < 0.0 || t >= 0.0))
1158  {
1159  if (verboseLevel > 0)
1160  {
1161  G4cout << "G4DiffuseElastic:WARNING: A = " << A
1162  << " mom(GeV)= " << plab/GeV
1163  << " S-wave will be sampled"
1164  << G4endl;
1165  }
1166  t = G4UniformRand()*tmax;
1167  }
1168  if(verboseLevel>1)
1169  {
1170  G4cout <<" t= " << t << " tmax= " << tmax
1171  << " ptot= " << ptot << G4endl;
1172  }
1173  // Sampling of angles in CM system
1174 
1175  G4double phi = G4UniformRand()*twopi;
1176  G4double cost = 1. - 2.0*t/tmax;
1177  G4double sint;
1178 
1179  if( cost >= 1.0 )
1180  {
1181  cost = 1.0;
1182  sint = 0.0;
1183  }
1184  else if( cost <= -1.0)
1185  {
1186  cost = -1.0;
1187  sint = 0.0;
1188  }
1189  else
1190  {
1191  sint = std::sqrt((1.0-cost)*(1.0+cost));
1192  }
1193  if (verboseLevel>1)
1194  {
1195  G4cout << "cos(t)=" << cost << " std::sin(t)=" << sint << G4endl;
1196  }
1197  G4ThreeVector v1(sint*std::cos(phi),sint*std::sin(phi),cost);
1198  v1 *= ptot;
1199  G4LorentzVector nlv1(v1.x(),v1.y(),v1.z(),std::sqrt(ptot*ptot + m1*m1));
1200 
1201  nlv1.boost(bst);
1202 
1203  G4ThreeVector np1 = nlv1.vect();
1204 
1205  // G4double theta = std::acos( np1.z()/np1.mag() ); // degree;
1206 
1207  G4double theta = np1.theta();
1208 
1209  return theta;
1210 }
1211 
1213 //
1214 // Return scattering angle in lab system (target at rest) knowing theta in CMS
1215 
1216 
1217 
1218 G4double
1220  G4double tmass, G4double thetaCMS)
1221 {
1222  const G4ParticleDefinition* theParticle = aParticle->GetDefinition();
1223  G4double m1 = theParticle->GetPDGMass();
1224  // G4double plab = aParticle->GetTotalMomentum();
1225  G4LorentzVector lv1 = aParticle->Get4Momentum();
1226  G4LorentzVector lv(0.0,0.0,0.0,tmass);
1227 
1228  lv += lv1;
1229 
1230  G4ThreeVector bst = lv.boostVector();
1231 
1232  lv1.boost(-bst);
1233 
1234  G4ThreeVector p1 = lv1.vect();
1235  G4double ptot = p1.mag();
1236 
1237  G4double phi = G4UniformRand()*twopi;
1238  G4double cost = std::cos(thetaCMS);
1239  G4double sint;
1240 
1241  if( cost >= 1.0 )
1242  {
1243  cost = 1.0;
1244  sint = 0.0;
1245  }
1246  else if( cost <= -1.0)
1247  {
1248  cost = -1.0;
1249  sint = 0.0;
1250  }
1251  else
1252  {
1253  sint = std::sqrt((1.0-cost)*(1.0+cost));
1254  }
1255  if (verboseLevel>1)
1256  {
1257  G4cout << "cos(tcms)=" << cost << " std::sin(tcms)=" << sint << G4endl;
1258  }
1259  G4ThreeVector v1(sint*std::cos(phi),sint*std::sin(phi),cost);
1260  v1 *= ptot;
1261  G4LorentzVector nlv1(v1.x(),v1.y(),v1.z(),std::sqrt(ptot*ptot + m1*m1));
1262 
1263  nlv1.boost(bst);
1264 
1265  G4ThreeVector np1 = nlv1.vect();
1266 
1267 
1268  G4double thetaLab = np1.theta();
1269 
1270  return thetaLab;
1271 }
1273 //
1274 // Return scattering angle in CMS system (target at rest) knowing theta in Lab
1275 
1276 
1277 
1278 G4double
1280  G4double tmass, G4double thetaLab)
1281 {
1282  const G4ParticleDefinition* theParticle = aParticle->GetDefinition();
1283  G4double m1 = theParticle->GetPDGMass();
1284  G4double plab = aParticle->GetTotalMomentum();
1285  G4LorentzVector lv1 = aParticle->Get4Momentum();
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::sin(tlab)=" << sint << G4endl;
1318  }
1319  G4ThreeVector v1(sint*std::cos(phi),sint*std::sin(phi),cost);
1320  v1 *= plab;
1321  G4LorentzVector nlv1(v1.x(),v1.y(),v1.z(),std::sqrt(plab*plab + m1*m1));
1322 
1323  nlv1.boost(-bst);
1324 
1325  G4ThreeVector np1 = nlv1.vect();
1326 
1327 
1328  G4double thetaCMS = np1.theta();
1329 
1330  return thetaCMS;
1331 }
1332 
1334 //
1335 // Test for given particle and element table of momentum, angle probability.
1336 // For the moment in lab system.
1337 
1339  G4double Z, G4double A)
1340 {
1341  fAtomicNumber = Z; // atomic number
1342  fAtomicWeight = A; // number of nucleons
1344 
1345 
1346 
1347  G4cout<<"G4DiffuseElastic::TestAngleTable() init the element with Z = "
1348  <<Z<<"; and A = "<<A<<G4endl;
1349 
1351 
1352 
1353 
1354 
1355  G4int i=0, j;
1356  G4double a = 0., z = theParticle->GetPDGCharge(), m1 = fParticle->GetPDGMass();
1357  G4double alpha1=0., alpha2=0., alphaMax=0., alphaCoulomb=0.;
1358  G4double deltaL10 = 0., deltaL96 = 0., deltaAG = 0.;
1359  G4double sumL10 = 0.,sumL96 = 0.,sumAG = 0.;
1360  G4double epsilon = 0.001;
1361 
1363 
1365 
1366  fWaveVector = partMom/hbarc;
1367 
1369  G4double kR2 = kR*kR;
1370  G4double kRmax = 10.6; // 10.6, 18, 10.174; ~ 3 maxima of J1 or 15., 25.
1371  G4double kRcoul = 1.2; // 1.4, 2.5; // on the first slope of J1
1372 
1373  alphaMax = kRmax*kRmax/kR2;
1374 
1375  if (alphaMax > 4.) alphaMax = 4.; // vmg05-02-09: was pi2
1376 
1377  alphaCoulomb = kRcoul*kRcoul/kR2;
1378 
1379  if( z )
1380  {
1381  a = partMom/m1; // beta*gamma for m1
1382  fBeta = a/std::sqrt(1+a*a);
1384  fAm = CalculateAm( partMom, fZommerfeld, fAtomicNumber);
1385  }
1386  G4PhysicsFreeVector* angleVector = new G4PhysicsFreeVector(fAngleBin-1);
1387 
1388  // G4PhysicsLogVector* angleBins = new G4PhysicsLogVector( 0.001*alphaMax, alphaMax, fAngleBin );
1389 
1390 
1391  fAddCoulomb = false;
1392 
1393  for(j = 1; j < fAngleBin; j++)
1394  {
1395  // alpha1 = angleBins->GetLowEdgeEnergy(j-1);
1396  // alpha2 = angleBins->GetLowEdgeEnergy(j);
1397 
1398  alpha1 = alphaMax*(j-1)/fAngleBin;
1399  alpha2 = alphaMax*( j )/fAngleBin;
1400 
1401  if( ( alpha2 > alphaCoulomb ) && z ) fAddCoulomb = true;
1402 
1403  deltaL10 = integral.Legendre10(this, &G4DiffuseElastic::GetIntegrandFunction, alpha1, alpha2);
1404  deltaL96 = integral.Legendre96(this, &G4DiffuseElastic::GetIntegrandFunction, alpha1, alpha2);
1405  deltaAG = integral.AdaptiveGauss(this, &G4DiffuseElastic::GetIntegrandFunction,
1406  alpha1, alpha2,epsilon);
1407 
1408  // G4cout<<alpha1<<"\t"<<std::sqrt(alpha1)/degree<<"\t"
1409  // <<deltaL10<<"\t"<<deltaL96<<"\t"<<deltaAG<<G4endl;
1410 
1411  sumL10 += deltaL10;
1412  sumL96 += deltaL96;
1413  sumAG += deltaAG;
1414 
1415  G4cout<<alpha1<<"\t"<<std::sqrt(alpha1)/degree<<"\t"
1416  <<sumL10<<"\t"<<sumL96<<"\t"<<sumAG<<G4endl;
1417 
1418  angleVector->PutValue( j-1 , alpha1, sumL10 ); // alpha2
1419  }
1420  fAngleTable->insertAt(i,angleVector);
1421  fAngleBank.push_back(fAngleTable);
1422 
1423  /*
1424  // Integral over all angle range - Bad accuracy !!!
1425 
1426  sumL10 = integral.Legendre10(this, &G4DiffuseElastic::GetIntegrandFunction, 0., alpha2);
1427  sumL96 = integral.Legendre96(this, &G4DiffuseElastic::GetIntegrandFunction, 0., alpha2);
1428  sumAG = integral.AdaptiveGauss(this, &G4DiffuseElastic::GetIntegrandFunction,
1429  0., alpha2,epsilon);
1430  G4cout<<G4endl;
1431  G4cout<<alpha2<<"\t"<<std::sqrt(alpha2)/degree<<"\t"
1432  <<sumL10<<"\t"<<sumL96<<"\t"<<sumAG<<G4endl;
1433  */
1434  return;
1435 }
1436 
1437 //
1438 //
G4double ThetaCMStoThetaLab(const G4DynamicParticle *aParticle, G4double tmass, G4double thetaCMS)
G4double Legendre10(T &typeT, F f, G4double a, G4double b)
ThreeVector shoot(const G4int Ap, const G4int Af)
G4double IntegralElasticProb(const G4ParticleDefinition *particle, G4double theta, G4double momentum, G4double A)
G4double CalculateNuclearRad(G4double A)
static const double MeV
Definition: G4SIunits.hh:193
static G4double GetNuclearMass(const G4double A, const G4double Z)
G4double Legendre96(T &typeT, F f, G4double a, G4double b)
G4double CalculateZommerfeld(G4double beta, G4double Z1, G4double Z2)
void PutValue(size_t binNumber, G4double binValue, G4double dataValue)
G4double BesselJzero(G4double z)
CLHEP::Hep3Vector G4ThreeVector
void InitialiseOnFly(G4double Z, G4double A)
G4double z
Definition: TRTMaterials.hh:39
G4double GetInvElasticXsc(const G4ParticleDefinition *particle, G4double theta, G4double momentum, G4double A, G4double Z)
G4ParticleDefinition * GetIon(G4int Z, G4int A, G4int lvl=0)
Definition: G4IonTable.cc:463
const G4double pi
static const G4double e2
std::vector< G4String > fElementNameVector
G4double NeutronTuniform(G4int Z)
G4ParticleDefinition * theProton
G4ParticleDefinition * GetDefinition() const
G4double a
Definition: TRTMaterials.hh:39
G4double GetDiffElasticSumProb(G4double theta)
G4double SampleThetaCMS(const G4ParticleDefinition *aParticle, G4double p, G4double A)
G4double GetLowEdgeEnergy(size_t binNumber) const
G4double GetScatteringAngle(G4int iMomentum, G4int iAngle, G4double position)
G4double BesselJone(G4double z)
G4double SampleT(const G4ParticleDefinition *aParticle, G4double p, G4double A)
int G4int
Definition: G4Types.hh:78
G4double SampleTableT(const G4ParticleDefinition *aParticle, G4double p, G4double Z, G4double A)
static G4NistManager * Instance()
G4double SampleThetaLab(const G4HadProjectile *aParticle, G4double tmass, G4double A)
G4double GetCoulombElasticXsc(const G4ParticleDefinition *particle, G4double theta, G4double momentum, G4double Z)
G4double AdaptiveGauss(T &typeT, F f, G4double a, G4double b, G4double e)
G4double GetTotalMomentum() const
const G4ParticleDefinition * thePionPlus
G4double CalculateAm(G4double momentum, G4double n, G4double Z)
const G4ParticleDefinition * thePionMinus
void SetMinEnergy(G4double anEnergy)
G4IonTable * GetIonTable() const
#define position
Definition: xmlparse.cc:605
#define G4UniformRand()
Definition: Randomize.hh:93
G4GLOB_DLL std::ostream G4cout
static size_t GetNumberOfElements()
Definition: G4Element.cc:410
const G4ParticleDefinition * GetDefinition() const
virtual ~G4DiffuseElastic()
G4double GetDiffElasticProb(G4double theta)
std::vector< G4PhysicsTable * > fAngleBank
const G4double p1
static G4Triton * Triton()
Definition: G4Triton.cc:95
static G4Proton * Proton()
Definition: G4Proton.cc:93
static G4PionPlus * PionPlus()
Definition: G4PionPlus.cc:98
static const double GeV
Definition: G4SIunits.hh:196
G4double GetDiffuseElasticXsc(const G4ParticleDefinition *particle, G4double theta, G4double momentum, G4double A)
void TestAngleTable(const G4ParticleDefinition *theParticle, G4double partMom, G4double Z, G4double A)
static G4Neutron * Neutron()
Definition: G4Neutron.cc:104
static const G4double A[nN]
const G4LorentzVector & Get4Momentum() const
static G4Deuteron * Deuteron()
Definition: G4Deuteron.cc:94
G4LorentzVector Get4Momentum() const
static const G4double e1
G4ParticleDefinition * theAlpha
G4double DampFactor(G4double z)
G4PhysicsLogVector * fEnergyVector
G4double GetPDGMass() const
static G4ParticleTable * GetParticleTable()
G4double lowEnergyRecoilLimit
static G4PionMinus * PionMinus()
Definition: G4PionMinus.cc:98
G4double GetInvElasticSumXsc(const G4ParticleDefinition *particle, G4double tMand, G4double momentum, G4double A, G4double Z)
G4double GetDiffElasticSumProbA(G4double alpha)
G4double GetAtomicMassAmu(const G4String &symb) const
static const double degree
Definition: G4SIunits.hh:125
void insertAt(size_t, G4PhysicsVector *)
void SetMaxEnergy(const G4double anEnergy)
G4double GetDiffuseElasticSumXsc(const G4ParticleDefinition *particle, G4double theta, G4double momentum, G4double A, G4double Z)
G4double CalculateParticleBeta(const G4ParticleDefinition *particle, G4double momentum)
G4ParticleDefinition * theDeuteron
#define G4endl
Definition: G4ios.hh:61
G4double BesselOneByArg(G4double z)
static const double TeV
Definition: G4SIunits.hh:197
G4double ThetaLabToThetaCMS(const G4DynamicParticle *aParticle, G4double tmass, G4double thetaLab)
static G4Alpha * Alpha()
Definition: G4Alpha.cc:89
static const double keV
Definition: G4SIunits.hh:195
const G4ParticleDefinition * fParticle
G4double SampleTableThetaCMS(const G4ParticleDefinition *aParticle, G4double p, G4double Z, G4double A)
virtual G4double SampleInvariantT(const G4ParticleDefinition *p, G4double plab, G4int Z, G4int A)
std::vector< G4Element * > G4ElementTable
double G4double
Definition: G4Types.hh:76
static G4ElementTable * GetElementTable()
Definition: G4Element.cc:403
G4double GetPDGCharge() const
static const G4double alpha
std::vector< G4double > fElementNumberVector
static G4He3 * He3()
Definition: G4He3.cc:94
G4double GetInvCoulombElasticXsc(const G4ParticleDefinition *particle, G4double tMand, G4double momentum, G4double A, G4double Z)
G4PhysicsTable * fAngleTable
static const double fermi
Definition: G4SIunits.hh:93
G4double GetIntegrandFunction(G4double theta)
G4double GetTotalMomentum() const
CLHEP::HepLorentzVector G4LorentzVector
G4ParticleDefinition * theNeutron