Geant4  10.02.p02
G4INCLCrossSectionsMultiPions.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 // INCL++ intra-nuclear cascade model
27 // Alain Boudard, CEA-Saclay, France
28 // Joseph Cugnon, University of Liege, Belgium
29 // Jean-Christophe David, CEA-Saclay, France
30 // Pekka Kaitaniemi, CEA-Saclay, France, and Helsinki Institute of Physics, Finland
31 // Sylvie Leray, CEA-Saclay, France
32 // Davide Mancusi, CEA-Saclay, France
33 //
34 #define INCLXX_IN_GEANT4_MODE 1
35 
36 #include "globals.hh"
37 
39 #include "G4INCLKinematicsUtils.hh"
40 #include "G4INCLParticleTable.hh"
41 #include "G4INCLLogger.hh"
42 // #include <cassert>
43 
44 namespace G4INCL {
45 
46  template<G4int N>
48  static G4double eval(const G4double pLab, const G4double oneOverThreshold, HornerCoefficients<N> const &coeffs) {
49  const G4double pMeV = pLab*1E3;
51  const G4double xrat=ekin*oneOverThreshold;
52  const G4double x=std::log(xrat);
53  return HornerEvaluator<N>::eval(x, coeffs) * x * std::exp(-0.5*x);
54  }
55  };
56 
59 
60  const G4double CrossSectionsMultiPions::s11pzOOT = 0.0035761542037692665889;
61  const G4double CrossSectionsMultiPions::s01ppOOT = 0.003421025623481919853;
62  const G4double CrossSectionsMultiPions::s01pzOOT = 0.0035739814152966403123;
63  const G4double CrossSectionsMultiPions::s11pmOOT = 0.0034855350296270480281;
64  const G4double CrossSectionsMultiPions::s12pmOOT = 0.0016672224074691565119;
65  const G4double CrossSectionsMultiPions::s12ppOOT = 0.0016507643038726931312;
66  const G4double CrossSectionsMultiPions::s12zzOOT = 0.0011111111111111111111;
68  const G4double CrossSectionsMultiPions::s02pmOOT = 0.0016661112962345883443;
69  const G4double CrossSectionsMultiPions::s12mzOOT = 0.0017047391749062392793;
70 
72  s11pzHC(-2.228000000000294018,8.7560000000005723725,-0.61000000000023239325,-5.4139999999999780324,3.3338333333333348023,-0.75835000000000022049,0.060623611111111114688),
73  s01ppHC(2.0570000000126518344,-6.029000000012135826,36.768500000002462784,-45.275666666666553533,25.112666666666611953,-7.2174166666666639187,1.0478875000000000275,-0.060804365079365080846),
74  s01pzHC(0.18030000000000441851,7.8700999999999953598,-4.0548999999999990425,0.555199999999999959),
75  s11pmHC(0.20590000000000031866,3.3450999999999993936,-1.4401999999999997825,0.17076666666666664973),
76  s12pmHC(-0.77235999999999901328,4.2626599999999991117,-1.9008899999999997323,0.30192266666666663379,-0.012270833333333331986),
77  s12ppHC(-0.75724999999999975664,2.0934399999999998565,-0.3803099999999999814),
78  s12zzHC(-0.89599999999996965072,7.882999999999978632,-7.1049999999999961928,1.884333333333333089),
79  s02pzHC(-1.0579999999999967036,11.113999999999994089,-8.5259999999999990196,2.0051666666666666525),
80  s02pmHC(2.4009000000012553286,-7.7680000000013376183,20.619000000000433505,-16.429666666666723928,5.2525708333333363472,-0.58969166666666670206),
81  s12mzHC(-0.21858699999999976269,1.9148999999999999722,-0.31727500000000001065,-0.027695000000000000486)
82  {
83  }
84 
85  G4double CrossSectionsMultiPions::NNElastic(Particle const * const part1, Particle const * const part2) {
86 
87  /* The NN cross section is parametrised as a function of the lab momentum
88  * of one of the nucleons. For NDelta or DeltaDelta, the physical
89  * assumption is that the cross section is the same as NN *for the same
90  * total CM energy*. Thus, we calculate s from the particles involved, and
91  * we convert this value to the lab momentum of a nucleon *as if this were
92  * an NN collision*.
93  */
95 
96  if(part1->isNucleon() && part2->isNucleon()) { // NN
97  const G4int i = ParticleTable::getIsospin(part1->getType())
99  return NNElasticFixed(s, i);
100  }
101  else { // Nucleon-Delta and Delta-Delta
103  if (plab < 0.440) {
104  return 34.*std::pow(plab/0.4, (-2.104));
105  }
106  else if (plab < 0.800) {
107  return 23.5+1000.*std::pow(plab-0.7, 4);
108  }
109  else if (plab <= 2.0) {
110  return 1250./(50.+plab)-4.*std::pow(plab-1.3, 2);
111  }
112  else {
113  return 77./(plab+1.5);
114  }
115  }
116  }
117 
119 
120  /* From NNElastic, with isospin fixed and for NN only.
121  */
122 
124 
125  if (i == 0) { // pn
126  if (plab < 0.446) {
127  G4double alp=std::log(plab);
128  return 6.3555*std::exp(-3.2481*alp-0.377*alp*alp);
129  }
130  else if (plab < 0.851) {
131  return 33.+196.*std::pow(std::fabs(plab-0.95),2.5);
132  }
133  else if (plab <= 2.0) {
134  return 31./std::sqrt(plab);
135  }
136  else {
137  return 77./(plab+1.5);
138  }
139  }
140  else { // pp and nn
141  if (plab < 0.440) {
142  return 34.*std::pow(plab/0.4, (-2.104));
143  }
144  else if (plab < 0.8067) {
145  return 23.5+1000.*std::pow(plab-0.7, 4);
146  }
147  else if (plab <= 2.0) {
148  return 1250./(50.+plab)-4.*std::pow(plab-1.3, 2);
149  }
150  else if (plab <= 3.0956) {
151  return 77./(plab+1.5);
152  }
153  else {
154  G4double alp=std::log(plab);
155  return 11.2+25.5*std::pow(plab, -1.12)+0.151*std::pow(alp, 2)-1.62*alp;
156  }
157  }
158  }
159 
160  G4double CrossSectionsMultiPions::NNTot(Particle const * const part1, Particle const * const part2) {
161 
164 
165  if(part1->isNucleon() && part2->isNucleon()) { // NN
166  const G4double s = KinematicsUtils::squareTotalEnergyInCM(part1, part2);
167  return NNTotFixed(s, i);
168  }
169  else if (part1->isDelta() && part2->isDelta()) { // Delta-Delta
170  return elastic(part1, part2);
171  }
172  else { // Nucleon-Delta
173  return NDeltaToNN(part1, part2) + elastic(part1, part2);
174  }
175  }
176 
178 
179  /* From NNTot, with isospin fixed and for NN only.
180  */
181 
183 
184  if (i == 0) { // pn
185  if (plab < 0.446) {
186  G4double alp=std::log(plab);
187  return 6.3555*std::exp(-3.2481*alp-0.377*std::pow(alp, 2));
188  }
189  else if (plab < 1.0) {
190  return 33.+196.*std::sqrt(std::pow(std::fabs(plab-0.95),5));
191  }
192  else if (plab < 1.924) {
193  return 24.2+8.9*plab;
194  }
195  else {
196  G4double alp=std::log(plab);
197  return 48.9-33.7*std::pow(plab, -3.08)+0.619*std::pow(alp, 2)-5.12*alp;
198  }
199  }
200  else { // pp and nn
201  if (plab < 0.440) {
202  return 34.*std::pow(plab/0.4, (-2.104));
203  }
204  else if (plab < 0.8734) {
205  return 23.5+1000.*std::pow(plab-0.7, 4);
206  }
207  else if (plab < 1.5) {
208  return 23.5+24.6/(1.+std::exp(-10.*(plab-1.2)));
209  }
210  else if (plab < 3.0044) {
211  return 41.+60.*(plab-0.9)*std::exp(-1.2*plab);
212  }
213  else {
214  G4double alp=std::log(plab);
215  return 45.6+219.*std::pow(plab, -4.23)+0.41*std::pow(alp, 2)-3.41*alp;
216  }
217  }
218  }
219 
221 
222  const G4double s = ener*ener;
223  G4double sincl;
224 
225  if (iso != 0) {
226  if(s>=4074595.287720512986) { // plab>800 MeV/c
227  sincl = NNTotFixed(s, 2)-NNElasticFixed(s, 2);
228  }
229  else {
230  sincl = 0. ;
231  }
232  } else {
233  if(s>=4074595.287720512986) { // plab>800 MeV/c
234  sincl = 2*(NNTotFixed(s, 0)-NNElasticFixed(s, 0))-(NNTotFixed(s, 2)-NNElasticFixed(s, 2));
235  }
236  else {
237  return 0. ;
238  }
239  }
240  if (sincl < 0.) sincl = 0.;
241  return sincl;
242  }
243 
245 
246  /* Article J. Physique 48 (1987)1901-1924 "Energy dependence of
247  nucleon-cucleon inelastic total cross-sections."
248  J. Bystricky, P. La France, F. Lehar, F. Perrot, T. Siemiarczuk & P. Winternitz
249  S11PZ= section pp->pp pi0
250  S01PP= section pp->pn pi+
251  S01PZ= section pn->pn pi0
252  S11PM= section pn->pp pi-
253  S= X-Section, 1st number : 1 if pp and 0 if pn
254  2nd number = number of pions, PP= pi+; PZ= pi0 ; PM= pi-
255  */
256 
257  const G4double s = ener*ener;
259 
260  G4double snnpit1=0.;
261  G4double snnpit=0.;
262  G4double s11pz=0.;
263  G4double s01pp=0.;
264  G4double s01pz=0.;
265  G4double s11pm=0.;
266 
267  if ((iso != 0) && (plab < 2.1989)) {
268  snnpit = xsiso - NNTwoPi(ener, iso, xsiso);
269  if (snnpit < 1.e-8) snnpit=0.;
270  return snnpit;
271  }
272  else if ((iso == 0) && (plab < 1.7369)) {
273  snnpit = xsiso;
274  if (snnpit < 1.e-8) snnpit=0.;
275  return snnpit;
276  }
277 
278 //s11pz
279  if (plab > 18.) {
280  s11pz=55.185/std::pow((0.1412*plab+5),2);
281  }
282  else if (plab > 13.9) {
283  G4double alp=std::log(plab);
284  s11pz=6.67-13.3*std::pow(plab, -6.18)+0.456*alp*alp-3.29*alp;
285  }
286  else if (plab >= 0.7765) {
288  s11pz=b*b;
289  }
290 //s01pp
291  if (plab >= 0.79624) {
293  s01pp=b*b;
294  }
295 
296 // channel T=1
297  snnpit1=s11pz+s01pp;
298  if (snnpit1 < 1.e-8) snnpit1=0.;
299  if (iso != 0) {
300  return snnpit1;
301  }
302 
303 //s01pz
304  if (plab > 4.5) {
305  s01pz=15289.4/std::pow((11.573*plab+5),2);
306  }
307  else if (plab >= 0.777) {
309  s01pz=b*b;
310  }
311 //s11pm
312  if (plab > 14.) {
313  s11pm=46.68/std::pow((0.2231*plab+5),2);
314  }
315  else if (plab >= 0.788) {
317  s11pm=b*b;
318  }
319 
320 // channel T=0
321  snnpit=2*(s01pz+2*s11pm)-snnpit1;
322  if (snnpit < 1.e-8) snnpit=0.;
323  return snnpit;
324  }
325 
326  G4double CrossSectionsMultiPions::NNTwoPi(const G4double ener, const G4int iso, const G4double xsiso) {
327 
328  /* Article J. Physique 48 (1987)1901-1924 "Energy dependence of nucleon-cucleon inelastic total cross-sections."
329  J. Bystricky, P. La France, F. Lehar, F. Perrot, T. Siemiarczuk & P. Winternitz
330  S12PM : pp -> pp Pi+ Pi-
331  S12ZZ : pp -> pp Pi0 Pi0
332  S12PP : pp -> nn Pi+ Pi+
333  S02PZ : pp -> pn Pi+ Pi0
334  S02PM : pn -> pn Pi+ Pi-
335  S12MZ : pn -> pp Pi- Pi0
336  */
337 
338  const G4double s = ener*ener;
340 
341  G4double snn2pit=0.;
342  G4double s12pm=0.;
343  G4double s12pp=0.;
344  G4double s12zz=0.;
345  G4double s02pz=0.;
346  G4double s02pm=0.;
347  G4double s12mz=0.;
348 
349  if (iso==0 && plab<3.3) {
350  snn2pit = xsiso - NNOnePiOrDelta(ener, iso, xsiso);
351  if (snn2pit < 1.e-8) snn2pit=0.;
352  return snn2pit;
353  }
354 
355  if (iso != 0) {
356 //s12pm
357  if (plab > 15.) {
358  s12pm=25.977/plab;
359  }
360  else if (plab >= 1.3817) {
362  s12pm=b*b;
363  }
364 //s12pp
365  if (plab > 10.) {
366  s12pp=141.505/std::pow((-0.1016*plab-7),2);
367  }
368  else if (plab >= 1.5739) {
370  s12pp=b*b;
371  }
372  }
373 //s12zz
374  if (plab > 4.) {
375  s12zz=97.355/std::pow((1.1579*plab+5),2);
376  }
377  else if (plab >= 1.72207) {
379  s12zz=b*b;
380  }
381 //s02pz
382  if (plab > 4.5) {
383  s02pz=178.082/std::pow((0.2014*plab+5),2);
384  }
385  else if (plab >= 1.5656) {
387  s02pz=b*b;
388  }
389 
390 // channel T=1
391  if (iso != 0) {
392  snn2pit=s12pm+s12pp+s12zz+s02pz;
393  if (snn2pit < 1.e-8) snn2pit=0.;
394  return snn2pit;
395  }
396 
397 //s02pm
398  if (plab > 5.) {
399  s02pm=135.826/std::pow(plab,2);
400  }
401  else if (plab >= 1.21925) {
403  s02pm=b*b;
404  }
405 //s12mz
406  if (plab >= 1.29269) {
408  s12mz=b*b;
409  }
410 
411 // channel T=0
412  snn2pit=3*(s02pm+0.5*s12mz-0.5*s02pz-s12zz);
413  if (snn2pit < 1.e-8) snn2pit=0.;
414  return snn2pit;
415  }
416 
417  G4double CrossSectionsMultiPions::NNThreePi(const G4double ener, const G4int iso, const G4double xsiso, const G4double xs1pi, const G4double xs2pi) {
418 
419  const G4double s = ener*ener;
421 
422  G4double snn3pit=0.;
423 
424  if (iso == 0) {
425 // channel T=0
426  if (plab > 7.2355) {
427  return 46.72/std::pow((plab - 5.8821),2);
428  }
429  else {
430  snn3pit=xsiso-xs1pi-xs2pi;
431  if (snn3pit < 1.e-8) snn3pit=0.;
432  return snn3pit;
433  }
434  }
435  else {
436 // channel T=1
437  if (plab > 7.206) {
438  return 5592.92/std::pow((plab+14.9764),2);
439  }
440  else if (plab > 2.1989){
441  snn3pit=xsiso-xs1pi-xs2pi;
442  if (snn3pit < 1.e-8) snn3pit=0.;
443  return snn3pit;
444  }
445  else return snn3pit;
446  }
447  }
448 
449  G4double CrossSectionsMultiPions::NNOnePi(Particle const * const particle1, Particle const * const particle2) {
450  // Cross section for nucleon-nucleon directly producing one pion
451 
452  const G4int iso=ParticleTable::getIsospin(particle1->getType()) + ParticleTable::getIsospin(particle2->getType());
453  if (iso!=0)
454  return 0.;
455 
456  const G4double ener=KinematicsUtils::totalEnergyInCM(particle1, particle2);
457 
458  const G4double xsiso2=NNInelasticIso(ener, 2);
459  const G4double xsiso0=NNInelasticIso(ener, 0);
460  return 0.25*(NNOnePiOrDelta(ener, 0, xsiso0)+ NNOnePiOrDelta(ener, 2, xsiso2));
461  }
462 
463  G4double CrossSectionsMultiPions::NNOnePiOrDelta(Particle const * const particle1, Particle const * const particle2) {
464  // Cross section for nucleon-nucleon directly producing one pion or producing a nucleon-delta pair
465  const G4double ener=KinematicsUtils::totalEnergyInCM(particle1, particle2);
466  const G4int iso=ParticleTable::getIsospin(particle1->getType()) + ParticleTable::getIsospin(particle2->getType());
467 
468  const G4double xsiso2=NNInelasticIso(ener, 2);
469  if (iso != 0)
470  return NNOnePiOrDelta(ener, iso, xsiso2);
471  else {
472  const G4double xsiso0=NNInelasticIso(ener, 0);
473  return 0.5*(NNOnePiOrDelta(ener, 0, xsiso0)+ NNOnePiOrDelta(ener, 2, xsiso2));
474  }
475  }
476 
477  G4double CrossSectionsMultiPions::NNTwoPi(Particle const * const particle1, Particle const * const particle2) {
478  //
479  // Nucleon-Nucleon producing one pion cross sections
480  //
481  const G4double ener=KinematicsUtils::totalEnergyInCM(particle1, particle2);
482  const G4int iso=ParticleTable::getIsospin(particle1->getType()) + ParticleTable::getIsospin(particle2->getType());
483 
484 
485  const G4double xsiso2=NNInelasticIso(ener, 2);
486  if (iso != 0) {
487  return NNTwoPi(ener, 2, xsiso2);
488  }
489  else {
490  const G4double xsiso0=NNInelasticIso(ener, 0);
491  return 0.5*(NNTwoPi(ener, 0, xsiso0)+ NNTwoPi(ener, 2, xsiso2));
492  }
493  return 0.0; // Should never reach this point
494  }
495 
496  G4double CrossSectionsMultiPions::NNThreePi(Particle const * const particle1, Particle const * const particle2) {
497  //
498  // Nucleon-Nucleon producing one pion cross sections
499  //
500 
501  const G4double ener=KinematicsUtils::totalEnergyInCM(particle1, particle2);
502  const G4int iso=ParticleTable::getIsospin(particle1->getType()) + ParticleTable::getIsospin(particle2->getType());
503 
504 
505  const G4double xsiso2=NNInelasticIso(ener, 2);
506  const G4double xs1pi2=NNOnePiOrDelta(ener, 2, xsiso2);
507  const G4double xs2pi2=NNTwoPi(ener, 2, xsiso2);
508  if (iso != 0)
509  return NNThreePi(ener, 2, xsiso2, xs1pi2, xs2pi2);
510  else {
511  const G4double xsiso0=NNInelasticIso(ener, 0);
512  const G4double xs1pi0=NNOnePiOrDelta(ener, 0, xsiso0);
513  const G4double xs2pi0=NNTwoPi(ener, 0, xsiso0);
514  return 0.5*(NNThreePi(ener, 0, xsiso0, xs1pi0, xs2pi0)+ NNThreePi(ener, 2, xsiso2, xs1pi2, xs2pi2));
515  }
516  }
517 
518  G4double CrossSectionsMultiPions::NNFourPi(Particle const * const particle1, Particle const * const particle2) {
519  const G4double s = KinematicsUtils::squareTotalEnergyInCM(particle1, particle2);
520  if(s<6.25E6)
521  return 0.;
522  const G4double sigma = NNTot(particle1, particle2) - NNElastic(particle1, particle2) - NNOnePiOrDelta(particle1, particle2) - NNTwoPi(particle1, particle2) - NNThreePi(particle1, particle2);
523  return ((sigma>0.) ? sigma : 0.);
524  }
525 
526  G4double CrossSectionsMultiPions::NNToxPiNN(const G4int xpi, Particle const * const particle1, Particle const * const particle2) {
527  //
528  // Nucleon-Nucleon producing xpi pions cross sections
529  //
530 // assert(xpi>0 && xpi<=nMaxPiNN);
531 // assert(particle1->isNucleon() && particle2->isNucleon());
532 
533  if (xpi == 1)
534  return NNOnePi(particle1, particle2);
535  else if (xpi == 2)
536  return NNTwoPi(particle1, particle2);
537  else if (xpi == 3)
538  return NNThreePi(particle1, particle2);
539  else if (xpi == 4)
540  return NNFourPi(particle1, particle2);
541  else // should never reach this point
542  return 0.;
543  }
544 
545 
547  // HE and LE pi- p and pi+ n
548  G4double ramass = 0.0;
549 
550  if(x <= 1306.0) {
551  G4double y = x*x;
552  G4double q2;
553  q2=(y-std::pow(1076.0, 2))*(y-std::pow(800.0, 2))/(4.0*y);
554  if (q2 > 0.) {
555  G4double q3=std::pow(q2, 3./2.);
556  G4double f3=q3/(q3+std::pow(180.0, 3));
557  G4double sdel;
558  sdel=326.5/(std::pow((x-1215.0-ramass)*2.0/110.0,2)+1.0);
559  return sdel*f3*(1.0-5.0*ramass/1215.0);
560  }
561  else {
562  return 0;
563  }
564  }
565  if(x <= 1754.0) {
566  return -2.33730e-06*std::pow(x, 3)+1.13819e-02*std::pow(x,2)
567  -1.83993e+01*x+9893.4;
568  } else if (x <= 2150.0) {
569  return 1.13531e-06*std::pow(x, 3)-6.91694e-03*std::pow(x, 2)
570  +1.39907e+01*x-9360.76;
571  } else {
572  return -3.18087*std::log(x)+52.9784;
573  }
574  }
575 
577  // HE pi- p and pi+ n
578  G4double ramass = 0.0;
579 
580  if(x <= 1275.8) {
581  G4double y = x*x;
582  G4double q2;
583  q2=(y-std::pow(1076.0, 2))*(y-std::pow(800.0, 2))/(4.0*y);
584  if (q2 > 0.) {
585  G4double q3=std::pow(q2, 3./2.);
586  G4double f3=q3/(q3+std::pow(180.0, 3));
587  G4double sdel;
588  sdel=326.5/(std::pow((x-1215.0-ramass)*2.0/110.0,2)+1.0);
589  return sdel*f3*(1.0-5.0*ramass/1215.0)/3.;
590  }
591  else {
592  return 0;
593  }
594  }
595  if(x <= 1495.0) {
596  return 0.00120683*(x-1372.52)*(x-1372.52)+26.2058;
597  } else if(x <= 1578.0) {
598  return 1.15873e-05*x*x+49965.6/((x-1519.59)*(x-1519.59)+2372.55);
599  } else if(x <= 2028.4) {
600  return 34.0248+43262.2/((x-1681.65)*(x-1681.65)+1689.35);
601  } else if(x <= 7500.0) {
602  return 3.3e-7*(x-7500.0)*(x-7500.0)+24.5;
603  } else {
604  return 24.5;
605  }
606  }
607 
608  G4double CrossSectionsMultiPions::total(Particle const * const p1, Particle const * const p2) {
609  G4double inelastic;
610  if(p1->isNucleon() && p2->isNucleon()) {
611  return NNTot(p1, p2);
612  } else if((p1->isNucleon() && p2->isDelta()) ||
613  (p1->isDelta() && p2->isNucleon())) {
614  inelastic = NDeltaToNN(p1, p2);
615  } else if((p1->isNucleon() && p2->isPion()) ||
616  (p1->isPion() && p2->isNucleon())) {
617  return piNTot(p1,p2);
618  } else {
619  inelastic = 0.;
620  }
621 
622  return inelastic + elastic(p1, p2);
623  }
624 
625 
626  G4double CrossSectionsMultiPions::piNIne(Particle const * const particle1, Particle const * const particle2) {
627  // piN inelastic cross section (Delta excluded)
628 
629  const Particle *pion;
630  const Particle *nucleon;
631  if(particle1->isNucleon()) {
632  nucleon = particle1;
633  pion = particle2;
634  } else {
635  pion = particle1;
636  nucleon = particle2;
637  }
638 // assert(pion->isPion());
639 
640  const G4double pLab = KinematicsUtils::momentumInLab(pion, nucleon);
641 
642  // these limits correspond to sqrt(s)=1230 and 20000 MeV
643  if(pLab>212677. || pLab<296.367)
644  return 0.0;
645 
646  const G4int ipit3 = ParticleTable::getIsospin(pion->getType());
647  const G4int ind2t3 = ParticleTable::getIsospin(nucleon->getType());
648  const G4int cg = 4 + ind2t3*ipit3;
649 // assert(cg==2 || cg==4 || cg==6);
650 
651  const G4double p1=1e-3*pLab;
652  const G4double p2=std::log(p1);
653  G4double xpipp = 0.0;
654  G4double xpimp = 0.0;
655 
656  if(cg!=2) {
657  // x-section pi+ p inelastique :
658  if(p1<=0.75)
659  xpipp=17.965*std::pow(p1, 5.4606);
660  else
661  xpipp=24.3-12.3*std::pow(p1, -1.91)+0.324*p2*p2-2.44*p2;
662  if(cg==6)
663  // cas pi+ p et pi- n
664  return xpipp;
665  }
666 
667  // x-section pi- p inelastique :
668  if(p1 <= 0.4731)
669  xpimp=0;
670  else
671  xpimp=26.6-7.18*std::pow(p1, -1.86)+0.327*p2*p2-2.81*p2;
672  if(xpimp<0.)
673  xpimp=0;
674 
675  if(cg==2) // cas pi- p et pi+ n
676  return xpimp;
677  else // cas pi0 p et pi0 n
678  return 0.5*(xpipp+xpimp);
679  }
680 
681  G4double CrossSectionsMultiPions::piNToDelta(Particle const * const particle1, Particle const * const particle2) {
682  // piN Delta production
683 
684  G4double x = KinematicsUtils::totalEnergyInCM(particle1, particle2);
685  if(x>20000.) return 0.0; // no cross section above this value
686 
687  G4int ipit3 = 0;
688  G4int ind2t3 = 0;
689  const G4double ramass = 0.0;
690 
691  if(particle1->isPion()) {
692  ipit3 = ParticleTable::getIsospin(particle1->getType());
693  ind2t3 = ParticleTable::getIsospin(particle2->getType());
694  } else if(particle2->isPion()) {
695  ipit3 = ParticleTable::getIsospin(particle2->getType());
696  ind2t3 = ParticleTable::getIsospin(particle1->getType());
697  }
698 
699  const G4double y=x*x;
700  const G4double q2=(y-1076.0*1076.0)*(y-800.0*800.0)/y/4.0;
701  if (q2 <= 0.) {
702  return 0.0;
703  }
704  const G4double q3 = std::pow(std::sqrt(q2),3);
705  const G4double f3 = q3/(q3 + 5832000.); // 5832000 = 180^3
706  G4double sdelResult = 326.5/(std::pow((x-1215.0-ramass)*2.0/(110.0-ramass), 2)+1.0);
707  sdelResult = sdelResult*(1.0-5.0*ramass/1215.0);
708  const G4int cg = 4 + ind2t3*ipit3;
709  sdelResult = sdelResult*f3*cg/6.0;
710 
711  return sdelResult;
712  }
713 
714  G4double CrossSectionsMultiPions::piNTot(Particle const * const particle1, Particle const * const particle2) {
715  // FUNCTION SPN(X,IND2T3,IPIT3,f17)
716  // SIGMA(PI+ + P) IN THE (3,3) REGION
717  // NEW FIT BY J.VANDERMEULEN + FIT BY Th AOUST ABOVE (3,3) RES
718  // CONST AT LOW AND VERY HIGH ENERGY
719  // COMMON/BL8/RATHR,RAMASS REL21800
720  // integer f17
721  // RATHR and RAMASS are always 0.0!!!
722 
723  G4double x = KinematicsUtils::totalEnergyInCM(particle1, particle2);
724 
725  G4int ipit3 = 0;
726  G4int ind2t3 = 0;
727 
728  if(particle1->isPion()) {
729  ipit3 = ParticleTable::getIsospin(particle1->getType());
730  ind2t3 = ParticleTable::getIsospin(particle2->getType());
731  } else if(particle2->isPion()) {
732  ipit3 = ParticleTable::getIsospin(particle2->getType());
733  ind2t3 = ParticleTable::getIsospin(particle1->getType());
734  }
735 
736  G4double spnResult=0.0;
737 
738  // HE pi+ p and pi- n
739  if((ind2t3 == 1 && ipit3 == 2) || (ind2t3 == -1 && ipit3 == -2))
740  spnResult=spnPiPlusPHE(x);
741  else if((ind2t3 == 1 && ipit3 == -2) || (ind2t3 == -1 && ipit3 == 2))
742  spnResult=spnPiMinusPHE(x);
743  else if(ipit3 == 0) spnResult = (spnPiPlusPHE(x) + spnPiMinusPHE(x))/2.0; // (spnpipphe(x)+spnpimphe(x))/2.0
744  else {
745  INCL_ERROR("Unknown configuration!\n" << particle1->print() << particle2->print() << '\n');
746  }
747 
748  return spnResult;
749  }
750 
751  G4double CrossSectionsMultiPions::NDeltaToNN(Particle const * const p1, Particle const * const p2) {
753  if(isospin==4 || isospin==-4) return 0.0;
754 
756  G4double Ecm = std::sqrt(s);
757  G4int deltaIsospin;
758  G4double deltaMass;
759  if(p1->isDelta()) {
760  deltaIsospin = ParticleTable::getIsospin(p1->getType());
761  deltaMass = p1->getMass();
762  } else {
763  deltaIsospin = ParticleTable::getIsospin(p2->getType());
764  deltaMass = p2->getMass();
765  }
766 
767  if(Ecm <= 938.3 + deltaMass) {
768  return 0.0;
769  }
770 
771  if(Ecm < 938.3 + deltaMass + 2.0) {
772  Ecm = 938.3 + deltaMass + 2.0;
773  s = Ecm*Ecm;
774  }
775 
777  (s - std::pow(ParticleTable::effectiveNucleonMass + deltaMass, 2));
778  const G4double y = s/(s - std::pow(deltaMass - ParticleTable::effectiveNucleonMass, 2));
779  /* Concerning the way we calculate the lab momentum, see the considerations
780  * in CrossSections::elasticNNLegacy().
781  */
782  G4double sDelta;
783  const G4double xsiso2=NNInelasticIso(Ecm, 2);
784  if (isospin != 0)
785  sDelta = NNOnePiOrDelta(Ecm, isospin, xsiso2);
786  else {
787  const G4double xsiso0=NNInelasticIso(Ecm, 0);
788  sDelta = 0.25*(NNOnePiOrDelta(Ecm, 0, xsiso0)+ NNOnePiOrDelta(Ecm, 2, xsiso2));
789  }
790  G4double result = 0.5 * x * y * sDelta;
791  /* modification for pion-induced cascade (see JC and MC LEMAIRE,NPA489(88)781
792  * result=3.*result
793  * pi absorption increased also for internal pions (7/3/01)
794  */
795  result *= 3.*(32.0 + isospin * isospin * (deltaIsospin * deltaIsospin - 5))/64.0;
796  result /= 1.0 + 0.25 * (isospin * isospin);
797  return result;
798  }
799 
800  G4double CrossSectionsMultiPions::NNToNDelta(Particle const * const p1, Particle const * const p2) {
801 // assert(p1->isNucleon() && p2->isNucleon());
803  G4double sigma = NNOnePiOrDelta(p1, p2);
804  if(isospin==0)
805  sigma *= 0.5;
806  return sigma;
807  }
808 
809  G4double CrossSectionsMultiPions::elastic(Particle const * const p1, Particle const * const p2) {
810  if(!p1->isPion() && !p2->isPion()){
811  return NNElastic(p1, p2);
812  }
813  else if (p1->isNucleon() || p2->isNucleon()){
814  G4double pielas = piNTot(p1,p2) - piNIne(p1,p2) - piNToDelta(p1,p2);
815  if (pielas < 0.){
816  pielas = 0.;
817  }
818 // return piNTot(p1,p2) - piNIne(p1,p2) - piNToDelta(p1,p2);
819  return pielas;
820  }
821  else {
822  return 0.0;
823  }
824  }
825 
827  G4double x = 0.001 * pl; // Change to GeV
828  if(iso != 0) {
829  if(pl <= 2000.0) {
830  x = std::pow(x, 8);
831  return 5.5e-6 * x/(7.7 + x);
832  } else {
833  return (5.34 + 0.67*(x - 2.0)) * 1.0e-6;
834  }
835  } else {
836  if(pl < 800.0) {
837  G4double b = (7.16 - 1.63*x) * 1.0e-6;
838  return b/(1.0 + std::exp(-(x - 0.45)/0.05));
839  } else if(pl < 1100.0) {
840  return (9.87 - 4.88 * x) * 1.0e-6;
841  } else {
842  return (3.68 + 0.76*x) * 1.0e-6;
843  }
844  }
845  return 0.0; // Should never reach this point
846  }
847 
848 
849  G4double CrossSectionsMultiPions::piNToxPiN(const G4int xpi, Particle const * const particle1, Particle const * const particle2) {
850  //
851  // pion-Nucleon producing xpi pions cross sections
852  //
853 // assert(xpi>1 && xpi<=nMaxPiPiN);
854 // assert((particle1->isNucleon() && particle2->isPion()) || (particle1->isPion() && particle2->isNucleon()));
855  if (xpi == 2)
856  return piNOnePi(particle1,particle2);
857  else if (xpi == 3)
858  return piNTwoPi(particle1,particle2);
859  else if (xpi == 4) {
860  const G4double piNThreePi = piNIne(particle1,particle2) - piNOnePi(particle1,particle2) - piNTwoPi(particle1,particle2);
861  return piNThreePi;
862  } else // should never reach this point
863  return 0.0;
864  }
865 
866  G4double CrossSectionsMultiPions::piNOnePi(Particle const * const particle1, Particle const * const particle2) {
867  const Particle *pion;
868  const Particle *nucleon;
869  if(particle1->isNucleon()) {
870  nucleon = particle1;
871  pion = particle2;
872  } else {
873  pion = particle1;
874  nucleon = particle2;
875  }
876 // assert(pion->isPion());
877 
878  const G4double pLab = KinematicsUtils::momentumInLab(pion, nucleon);
879 
880  // this limit corresponds to sqrt(s)=1230 MeV
881  if(pLab<296.367)
882  return 0.0;
883 
884  const G4int ipi = ParticleTable::getIsospin(pion->getType());
885  const G4int ind2 = ParticleTable::getIsospin(nucleon->getType());
886  const G4int cg = 4 + ind2*ipi;
887 // assert(cg==2 || cg==4 || cg==6);
888 
889  const G4double p1=1e-3*pLab;
890  G4double tamp6=0.;
891  G4double tamp2=0.;
892 
893  // X-SECTION PI+ P INELASTIQUE :
894  if(cg != 2) {
895  if(pLab < 1532.52) // corresponds to sqrt(s)=1946 MeV
896  tamp6=piNIne(particle1, particle2);
897  else
898  tamp6=0.204+18.2*std::pow(p1, -1.72)+6.33*std::pow(p1, -1.13);
899  if (cg == 6) // CAS PI+ P ET PI- N
900  return tamp6;
901  }
902 
903  // X-SECTION PI- P INELASTIQUE :
904  if (pLab < 1228.06) // corresponds to sqrt(s)=1794 MeV
905  tamp2=piNIne(particle1, particle2);
906  else
907  tamp2=9.04*std::pow(p1, -1.17)+18.*std::pow(p1, -1.21); // tamp2=9.04*std::pow(p1, -1.17)+(13.5*std::pow(p1, -1.21))*4./3.;
908  if (tamp2 < 0.0) tamp2=0;
909 
910  if (cg == 2) // CAS PI- P ET PI+ N
911  return tamp2;
912  else {
913  // CAS PI0 P ET PI0 N
914  G4double s1pin = 0.5*(tamp6+tamp2);
915  const G4double inelastic = piNIne(particle1, particle2);
916  if (s1pin > inelastic)
917  s1pin = inelastic;
918  return s1pin;
919  }
920  }
921 
922  G4double CrossSectionsMultiPions::piNTwoPi(Particle const * const particle1, Particle const * const particle2) {
923  //
924  // pion-nucleon interaction, producing 2 pions
925  // fit from Landolt-Bornstein multiplied by factor determined with evaluation of total xs
926  //
927 
928  const Particle *pion;
929  const Particle *nucleon;
930  if(particle1->isNucleon()) {
931  nucleon = particle1;
932  pion = particle2;
933  } else {
934  pion = particle1;
935  nucleon = particle2;
936  }
937 // assert(pion->isPion());
938 
939  const G4double pLab = KinematicsUtils::momentumInLab(pion, nucleon);
940 
941  // this limit corresponds to sqrt(s)=1230 MeV
942  if(pLab<296.367)
943  return 0.0;
944 
945  const G4int ipi = ParticleTable::getIsospin(pion->getType());
946  const G4int ind2 = ParticleTable::getIsospin(nucleon->getType());
947  const G4int cg = 4 + ind2*ipi;
948 // assert(cg==2 || cg==4 || cg==6);
949 
950  const G4double p1=1e-3*pLab;
951  G4double tamp6=0.;
952  G4double tamp2=0.;
953 
954  // X-SECTION PI+ P INELASTIQUE :
955  if(cg!=2) {
956  if(pLab < 2444.7) // corresponds to sqrt(s)=2344 MeV
957  tamp6=piNIne(particle1, particle2)-piNOnePi(particle1, particle2);
958  else
959  tamp6=1.59+25.5*std::pow(p1, -1.04); // tamp6=(0.636+10.2*std::pow(p1, -1.04))*15./6.;
960 
961  if(cg==6) // CAS PI+ P ET PI- N
962  return tamp6;
963  }
964 
965  // X-SECTION PI- P INELASTIQUE :
966  if(pLab<2083.63) // corresponds to sqrt(s)=2195 MeV
967  tamp2=piNIne(particle1, particle2)-piNOnePi(particle1, particle2);
968  else
969  tamp2=2.457794117647+18.066176470588*std::pow(p1, -0.92); // tamp2=(0.619+4.55*std::pow(p1, -0.92))*135./34.;
970 
971  if(cg==2) // CAS PI- P ET PI+ N
972  return tamp2;
973  else {
974  // CAS PI0 P ET PI0 N
975  const G4double s2pin=0.5*(tamp6+tamp2);
976  return s2pin;
977  }
978  }
979 
980 } // namespace G4INCL
981 
virtual G4double NNToxPiNN(const G4int xpi, Particle const *const p1, Particle const *const p2)
Cross section for X pion production - NN Channel.
static const G4double s01pzOOT
One over threshold for s01pz.
virtual G4double NNToNDelta(Particle const *const p1, Particle const *const p2)
Cross section for Delta production - NN Channel.
virtual G4double NNOnePiOrDelta(const G4double ener, const G4int iso, const G4double xsiso)
Cross section for direct 1-pion production + delta production - NN entrance channel.
G4double getMass() const
Get the cached particle mass.
G4double NNInelasticIso(const G4double ener, const G4int iso)
Internal implementation of the isospin dependent NN reaction cross section.
static const G4double s12mzOOT
One over threshold for s12mz.
G4bool pion(G4int ityp)
G4double piNIne(Particle const *const p1, Particle const *const p2)
virtual G4double NNTwoPi(const G4double ener, const G4int iso, const G4double xsiso)
Cross section for direct 2-pion production - NN entrance channel.
static const G4double s12ppOOT
One over threshold for s12pp.
G4double squareTotalEnergyInCM(Particle const *const p1, Particle const *const p2)
virtual G4double piNToDelta(Particle const *const p1, Particle const *const p2)
Cross section for Delta production - piN Channel.
G4double NNElasticFixed(const G4double s, const G4int i)
Internal implementation of the NN elastic cross section with fixed isospin.
const HornerC4 s12zzHC
Horner coefficients for s12zz.
#define INCL_ERROR(x)
G4bool isDelta() const
Is it a Delta?
std::string print() const
virtual G4double piNToxPiN(const G4int xpi, Particle const *const p1, Particle const *const p2)
Cross section for X pion production - piN Channel.
G4double spnPiPlusPHE(const G4double x)
Internal function for pion cross sections.
const HornerC4 s02pzHC
Horner coefficients for s02pz.
int G4int
Definition: G4Types.hh:78
virtual G4double NNThreePi(const G4double ener, const G4int iso, const G4double xsiso, const G4double xs1pi, const G4double xs2pi)
Cross section for direct 3-pion production - NN entrance channel.
G4double NNElastic(Particle const *const part1, Particle const *const part2)
Internal implementation of the NN elastic cross section.
const HornerC8 s01ppHC
Horner coefficients for s01pp.
virtual G4double NNOnePi(Particle const *const part1, Particle const *const part2)
Cross section for direct 1-pion production - NN entrance channel.
static const G4double s01ppOOT
One over threshold for s01pp.
G4double NNTot(Particle const *const part1, Particle const *const part2)
Internal implementation of the NN total cross section.
static const G4int nMaxPiNN
Maximum number of outgoing pions in NN collisions.
virtual G4double piNTwoPi(Particle const *const p1, Particle const *const p2)
Cross section for Two (more) pion production - piN entrance channel.
static const double s
Definition: G4SIunits.hh:168
const HornerC4 s01pzHC
Horner coefficients for s01pz.
G4bool nucleon(G4int ityp)
G4double piNTot(Particle const *const p1, Particle const *const p2)
virtual G4double elastic(Particle const *const p1, Particle const *const p2)
Elastic particle-particle cross section.
const HornerC3 s12ppHC
Horner coefficients for s12pp.
static const G4double s11pmOOT
One over threshold for s11pm.
virtual G4double NNFourPi(Particle const *const part1, Particle const *const part2)
Cross section for direct 4-pion production - NN entrance channel.
virtual G4double NDeltaToNN(Particle const *const p1, Particle const *const p2)
Cross section for NDelta->NN.
static const G4double f3
const HornerC7 s11pzHC
Horner coefficients for s11pz.
G4int getIsospin(const ParticleType t)
Get the isospin of a particle.
const G4double effectiveNucleonMass2
static const G4double s02pzOOT
One over threshold for s02pz.
G4INCL::ParticleType getType() const
Get the particle type.
static G4double eval(const G4double pLab, const G4double oneOverThreshold, HornerCoefficients< N > const &coeffs)
static const G4double s12pmOOT
One over threshold for s12pm.
const G4double x[NPOINTSGL]
static const G4double s12zzOOT
One over threshold for s12zz.
G4double NNTotFixed(const G4double s, const G4int i)
Internal implementation of the NN total cross section with fixed isospin.
static const G4double s11pzOOT
One over threshold for s11pz.
G4bool isNucleon() const
Is this a nucleon?
const HornerC4 s12mzHC
Horner coefficients for s12mz.
static const G4double s02pmOOT
One over threshold for s02pm.
G4double momentumInLab(Particle const *const p1, Particle const *const p2)
gives the momentum in the lab frame of two particles.
virtual G4double calculateNNAngularSlope(G4double energyCM, G4int iso)
Calculate the slope of the NN DDXS.
double G4double
Definition: G4Types.hh:76
G4double totalEnergyInCM(Particle const *const p1, Particle const *const p2)
const HornerC4 s11pmHC
Horner coefficients for s11pm.
G4bool isPion() const
Is this a pion?
G4double spnPiMinusPHE(const G4double x)
Internal function for pion cross sections.
static G4double eval(const G4double x, HornerCoefficients< N > const &coeffs)
virtual G4double total(Particle const *const p1, Particle const *const p2)
Total (elastic+inelastic) particle-particle cross section.
const G4double effectiveNucleonMass
static const G4int nMaxPiPiN
Maximum number of outgoing pions in piN collisions.
virtual G4double piNOnePi(Particle const *const p1, Particle const *const p2)
Cross section for One (more) pion production - piN entrance channel.
Cross sections used in INCL Multipions.
const HornerC6 s02pmHC
Horner coefficients for s02pm.
const HornerC5 s12pmHC
Horner coefficients for s12pm.