Geant4  10.01.p01
G4ChipsPionMinusElasticXS.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 //
27 // $Id: G4ChipsPionMinusElasticXS.cc 88983 2015-03-17 10:24:43Z gcosmo $
28 //
29 //
30 // G4 Physics class: G4ChipsPionMinusElasticXS for pA elastic cross sections
31 // Created: M.V. Kossov, CERN/ITEP(Moscow), 21-Jan-10
32 // The last update: M.V. Kossov, CERN/ITEP (Moscow) 21-Jan-10
33 //
34 // -------------------------------------------------------------------------------
35 // Short description: Interaction cross-sections for the elastic process.
36 // Class extracted from CHIPS and integrated in Geant4 by W.Pokorski
37 // -------------------------------------------------------------------------------
38 //
39 
41 #include "G4SystemOfUnits.hh"
42 #include "G4DynamicParticle.hh"
43 #include "G4ParticleDefinition.hh"
44 #include "G4PionMinus.hh"
45 #include "G4Nucleus.hh"
46 #include "G4ParticleTable.hh"
47 #include "G4NucleiProperties.hh"
48 #include "G4IonTable.hh"
49 
50 // factory
51 #include "G4CrossSectionFactory.hh"
52 //
54 
55 G4ChipsPionMinusElasticXS::G4ChipsPionMinusElasticXS():G4VCrossSectionDataSet(Default_Name()), nPoints(128), nLast(nPoints-1)
56 {
57  lPMin=-8.; //Min tabulated logarithmMomentum(D)
58  lPMax= 8.; //Max tabulated logarithmMomentum(D)
59  dlnP=(lPMax-lPMin)/nLast;//LogStep inTheTable(D)
60  onlyCS=true;//Flag toCalcul OnlyCS(not Si/Bi)(L)
61  lastSIG=0.; //Last calculated cross section (L)
62  lastLP=-10.;//Last log(mom_of IncidentHadron)(L)
63  lastTM=0.; //Last t_maximum (L)
64  theSS=0.; //TheLastSqSlope of 1st difr.Max(L)
65  theS1=0.; //TheLastMantissa of 1st difr.Max(L)
66  theB1=0.; //TheLastSlope of 1st difruct.Max(L)
67  theS2=0.; //TheLastMantissa of 2nd difr.Max(L)
68  theB2=0.; //TheLastSlope of 2nd difruct.Max(L)
69  theS3=0.; //TheLastMantissa of 3d difr. Max(L)
70  theB3=0.; //TheLastSlope of 3d difruct. Max(L)
71  theS4=0.; //TheLastMantissa of 4th difr.Max(L)
72  theB4=0.; //TheLastSlope of 4th difruct.Max(L)
73  lastTZ=0; // Last atomic number of the target
74  lastTN=0; // Last # of neutrons in the target
75  lastPIN=0.; // Last initialized max momentum
76  lastCST=0; // Elastic cross-section table
77  lastPAR=0; // Parameters ForFunctionCalculation
78  lastSST=0; // E-dep of SqardSlope of 1st difMax
79  lastS1T=0; // E-dep of mantissa of 1st dif.Max
80  lastB1T=0; // E-dep of the slope of 1st difMax
81  lastS2T=0; // E-dep of mantissa of 2nd difrMax
82  lastB2T=0; // E-dep of the slope of 2nd difMax
83  lastS3T=0; // E-dep of mantissa of 3d difr.Max
84  lastB3T=0; // E-dep of the slope of 3d difrMax
85  lastS4T=0; // E-dep of mantissa of 4th difrMax
86  lastB4T=0; // E-dep of the slope of 4th difMax
87  lastN=0; // The last N of calculated nucleus
88  lastZ=0; // The last Z of calculated nucleus
89  lastP=0.; // LastUsed in CrossSection Momentum
90  lastTH=0.; // Last threshold momentum
91  lastCS=0.; // Last value of the Cross Section
92  lastI=0; // The last position in the DAMDB
93 }
94 
96 {
97  std::vector<G4double*>::iterator pos;
98  for (pos=CST.begin(); pos<CST.end(); pos++)
99  { delete [] *pos; }
100  CST.clear();
101  for (pos=PAR.begin(); pos<PAR.end(); pos++)
102  { delete [] *pos; }
103  PAR.clear();
104  for (pos=SST.begin(); pos<SST.end(); pos++)
105  { delete [] *pos; }
106  SST.clear();
107  for (pos=S1T.begin(); pos<S1T.end(); pos++)
108  { delete [] *pos; }
109  S1T.clear();
110  for (pos=B1T.begin(); pos<B1T.end(); pos++)
111  { delete [] *pos; }
112  B1T.clear();
113  for (pos=S2T.begin(); pos<S2T.end(); pos++)
114  { delete [] *pos; }
115  S2T.clear();
116  for (pos=B2T.begin(); pos<B2T.end(); pos++)
117  { delete [] *pos; }
118  B2T.clear();
119  for (pos=S3T.begin(); pos<S3T.end(); pos++)
120  { delete [] *pos; }
121  S3T.clear();
122  for (pos=B3T.begin(); pos<B3T.end(); pos++)
123  { delete [] *pos; }
124  B3T.clear();
125  for (pos=S4T.begin(); pos<S4T.end(); pos++)
126  { delete [] *pos; }
127  S4T.clear();
128  for (pos=B4T.begin(); pos<B4T.end(); pos++)
129  { delete [] *pos; }
130  B4T.clear();
131 }
132 
133 
135  const G4Element*,
136  const G4Material*)
137 {
138  return true;
139 }
140 
141 // The main member function giving the collision cross section (P is in IU, CS is in mb)
142 // Make pMom in independent units ! (Now it is MeV)
144  const G4Isotope*,
145  const G4Element*,
146  const G4Material*)
147 {
148  G4double pMom=Pt->GetTotalMomentum();
149  G4int tgN = A - tgZ;
150 
151  return GetChipsCrossSection(pMom, tgZ, tgN, -212);
152 }
153 
155 {
156 
157  G4double pEn=pMom;
158  G4bool fCS = false;
159  onlyCS=fCS;
160 
161  G4bool in=false; // By default the isotope must be found in the AMDB
162  lastP = 0.; // New momentum history (nothing to compare with)
163  lastN = tgN; // The last N of the calculated nucleus
164  lastZ = tgZ; // The last Z of the calculated nucleus
165  lastI = colN.size(); // Size of the Associative Memory DB in the heap
166  if(lastI) for(G4int i=0; i<lastI; i++) // Loop over proj/tgZ/tgN lines of DB
167  { // The nucleus with projPDG is found in AMDB
168  if(colN[i]==tgN && colZ[i]==tgZ) // Isotope is foind in AMDB
169  {
170  lastI=i;
171  lastTH =colTH[i]; // Last THreshold (A-dependent)
172  if(pEn<=lastTH)
173  {
174  return 0.; // Energy is below the Threshold value
175  }
176  lastP =colP [i]; // Last Momentum (A-dependent)
177  lastCS =colCS[i]; // Last CrossSect (A-dependent)
178  // if(std::fabs(lastP/pMom-1.)<tolerance) //VI (do not use tolerance)
179  if(lastP == pMom) // Do not recalculate
180  {
181  CalculateCrossSection(fCS,-1,i,-211,lastZ,lastN,pMom); // Update param's only
182  return lastCS*millibarn; // Use theLastCS
183  }
184  in = true; // This is the case when the isotop is found in DB
185  // Momentum pMom is in IU ! @@ Units
186  lastCS=CalculateCrossSection(fCS,-1,i,-211,lastZ,lastN,pMom); // read & update
187  if(lastCS<=0. && pEn>lastTH) // Correct the threshold
188  {
189  lastTH=pEn;
190  }
191  break; // Go out of the LOOP with found lastI
192  }
193  } // End of attampt to find the nucleus in DB
194  if(!in) // This nucleus has not been calculated previously
195  {
197  lastCS=CalculateCrossSection(fCS,0,lastI,-211,lastZ,lastN,pMom);//calculate&create
198  if(lastCS<=0.)
199  {
200  lastTH = 0; //ThresholdEnergy(tgZ, tgN); // The Threshold Energy which is now the last
201  if(pEn>lastTH)
202  {
203  lastTH=pEn;
204  }
205  }
206  colN.push_back(tgN);
207  colZ.push_back(tgZ);
208  colP.push_back(pMom);
209  colTH.push_back(lastTH);
210  colCS.push_back(lastCS);
211  return lastCS*millibarn;
212  } // End of creation of the new set of parameters
213  else
214  {
215  colP[lastI]=pMom;
216  colCS[lastI]=lastCS;
217  }
218  return lastCS*millibarn;
219 }
220 
221 // Calculation of total elastic cross section (p in IU, CS in mb) @@ Units (?)
222 // F=0 - create AMDB, F=-1 - read&update AMDB, F=1 - update AMDB (sinchro with higher AMDB)
224  G4int PDG, G4int tgZ, G4int tgN, G4double pIU)
225 {
226  G4double pMom=pIU/GeV; // All calculations are in GeV
227  onlyCS=CS; // Flag to calculate only CS (not Si/Bi)
228  lastLP=std::log(pMom); // Make a logarithm of the momentum for calculation
229  if(F) // This isotope was found in AMDB =>RETRIEVE/UPDATE
230  {
231  if(F<0) // the AMDB must be loded
232  {
233  lastPIN = PIN[I]; // Max log(P) initialised for this table set
234  lastPAR = PAR[I]; // Pointer to the parameter set
235  lastCST = CST[I]; // Pointer to the total sross-section table
236  lastSST = SST[I]; // Pointer to the first squared slope
237  lastS1T = S1T[I]; // Pointer to the first mantissa
238  lastB1T = B1T[I]; // Pointer to the first slope
239  lastS2T = S2T[I]; // Pointer to the second mantissa
240  lastB2T = B2T[I]; // Pointer to the second slope
241  lastS3T = S3T[I]; // Pointer to the third mantissa
242  lastB3T = B3T[I]; // Pointer to the rhird slope
243  lastS4T = S4T[I]; // Pointer to the 4-th mantissa
244  lastB4T = B4T[I]; // Pointer to the 4-th slope
245  }
246  if(lastLP>lastPIN && lastLP<lPMax)
247  {
248  lastPIN=GetPTables(lastLP,lastPIN,PDG,tgZ,tgN);// Can update upper logP-Limit in tabs
249  PIN[I]=lastPIN; // Remember the new P-Limit of the tables
250  }
251  }
252  else // This isotope wasn't initialized => CREATE
253  {
254  lastPAR = new G4double[nPoints]; // Allocate memory for parameters of CS function
255  lastPAR[nLast]=0; // Initialization for VALGRIND
256  lastCST = new G4double[nPoints]; // Allocate memory for Tabulated CS function
257  lastSST = new G4double[nPoints]; // Allocate memory for Tabulated first sqaredSlope
258  lastS1T = new G4double[nPoints]; // Allocate memory for Tabulated first mantissa
259  lastB1T = new G4double[nPoints]; // Allocate memory for Tabulated first slope
260  lastS2T = new G4double[nPoints]; // Allocate memory for Tabulated second mantissa
261  lastB2T = new G4double[nPoints]; // Allocate memory for Tabulated second slope
262  lastS3T = new G4double[nPoints]; // Allocate memory for Tabulated third mantissa
263  lastB3T = new G4double[nPoints]; // Allocate memory for Tabulated third slope
264  lastS4T = new G4double[nPoints]; // Allocate memory for Tabulated 4-th mantissa
265  lastB4T = new G4double[nPoints]; // Allocate memory for Tabulated 4-th slope
266  lastPIN = GetPTables(lastLP,lPMin,PDG,tgZ,tgN); // Returns the new P-limit for tables
267  PIN.push_back(lastPIN); // Fill parameters of CS function to AMDB
268  PAR.push_back(lastPAR); // Fill parameters of CS function to AMDB
269  CST.push_back(lastCST); // Fill Tabulated CS function to AMDB
270  SST.push_back(lastSST); // Fill Tabulated first sq.slope to AMDB
271  S1T.push_back(lastS1T); // Fill Tabulated first mantissa to AMDB
272  B1T.push_back(lastB1T); // Fill Tabulated first slope to AMDB
273  S2T.push_back(lastS2T); // Fill Tabulated second mantissa to AMDB
274  B2T.push_back(lastB2T); // Fill Tabulated second slope to AMDB
275  S3T.push_back(lastS3T); // Fill Tabulated third mantissa to AMDB
276  B3T.push_back(lastB3T); // Fill Tabulated third slope to AMDB
277  S4T.push_back(lastS4T); // Fill Tabulated 4-th mantissa to AMDB
278  B4T.push_back(lastB4T); // Fill Tabulated 4-th slope to AMDB
279  } // End of creation/update of the new set of parameters and tables
280  // =----------= NOW Update (if necessary) and Calculate the Cross Section =-----------=
281  if(lastLP>lastPIN && lastLP<lPMax)
282  {
283  lastPIN = GetPTables(lastLP,lastPIN,PDG,tgZ,tgN);
284  }
285  if(!onlyCS) lastTM=GetQ2max(PDG, tgZ, tgN, pMom); // Calculate (-t)_max=Q2_max (GeV2)
286  if(lastLP>lPMin && lastLP<=lastPIN) // Linear fit is made using precalculated tables
287  {
288  if(lastLP==lastPIN)
289  {
290  G4double shift=(lastLP-lPMin)/dlnP+.000001; // Log distance from lPMin
291  G4int blast=static_cast<int>(shift); // this is a bin number of the lower edge (0)
292  if(blast<0 || blast>=nLast) G4cout<<"G4QEleastCS::CCS:b="<<blast<<","<<nLast<<G4endl;
293  lastSIG = lastCST[blast];
294  if(!onlyCS) // Skip the differential cross-section parameters
295  {
296  theSS = lastSST[blast];
297  theS1 = lastS1T[blast];
298  theB1 = lastB1T[blast];
299  theS2 = lastS2T[blast];
300  theB2 = lastB2T[blast];
301  theS3 = lastS3T[blast];
302  theB3 = lastB3T[blast];
303  theS4 = lastS4T[blast];
304  theB4 = lastB4T[blast];
305  }
306  }
307  else
308  {
309  G4double shift=(lastLP-lPMin)/dlnP; // a shift from the beginning of the table
310  G4int blast=static_cast<int>(shift); // the lower bin number
311  if(blast<0) blast=0;
312  if(blast>=nLast) blast=nLast-1; // low edge of the last bin
313  shift-=blast; // step inside the unit bin
314  G4int lastL=blast+1; // the upper bin number
315  G4double SIGL=lastCST[blast]; // the basic value of the cross-section
316  lastSIG= SIGL+shift*(lastCST[lastL]-SIGL); // calculated total elastic cross-section
317  if(!onlyCS) // Skip the differential cross-section parameters
318  {
319  G4double SSTL=lastSST[blast]; // the low bin of the first squared slope
320  theSS=SSTL+shift*(lastSST[lastL]-SSTL); // the basic value of the first sq.slope
321  G4double S1TL=lastS1T[blast]; // the low bin of the first mantissa
322  theS1=S1TL+shift*(lastS1T[lastL]-S1TL); // the basic value of the first mantissa
323  G4double B1TL=lastB1T[blast]; // the low bin of the first slope
324  theB1=B1TL+shift*(lastB1T[lastL]-B1TL); // the basic value of the first slope
325  G4double S2TL=lastS2T[blast]; // the low bin of the second mantissa
326  theS2=S2TL+shift*(lastS2T[lastL]-S2TL); // the basic value of the second mantissa
327  G4double B2TL=lastB2T[blast]; // the low bin of the second slope
328  theB2=B2TL+shift*(lastB2T[lastL]-B2TL); // the basic value of the second slope
329  G4double S3TL=lastS3T[blast]; // the low bin of the third mantissa
330  theS3=S3TL+shift*(lastS3T[lastL]-S3TL); // the basic value of the third mantissa
331  G4double B3TL=lastB3T[blast]; // the low bin of the third slope
332  theB3=B3TL+shift*(lastB3T[lastL]-B3TL); // the basic value of the third slope
333  G4double S4TL=lastS4T[blast]; // the low bin of the 4-th mantissa
334  theS4=S4TL+shift*(lastS4T[lastL]-S4TL); // the basic value of the 4-th mantissa
335  G4double B4TL=lastB4T[blast]; // the low bin of the 4-th slope
336  theB4=B4TL+shift*(lastB4T[lastL]-B4TL); // the basic value of the 4-th slope
337  }
338  }
339  }
340  else lastSIG=GetTabValues(lastLP, PDG, tgZ, tgN); // Direct calculation beyond the table
341  if(lastSIG<0.) lastSIG = 0.; // @@ a Warning print can be added
342  return lastSIG;
343 }
344 
345 // It has parameter sets for all tZ/tN/PDG, using them the tables can be created/updated
347  G4int tgZ, G4int tgN)
348 {
349  // @@ At present all nA==pA ---------> Each neucleus can have not more than 51 parameters
350  static const G4double pwd=2727;
351  const G4int n_pimpel=38; // #of parameters for pp-elastic (<nPoints=128)
352  // -0- -1- -2- -3- -4- -5- -6- -7- -8- -9--10-11-12-
353  G4double pimp_el[n_pimpel]={1.27,1.53,.0676,3.5,.36,.04,.017,.0025,.0557,2.4,7.,.7,.6,
354  .05,5.,74.,3.,3.4,.2,.17,.001,8.,.055,3.64,5.e-5,4000.,1500.,
355  .46,1.2e6,3.5e6,5.e-5,1.e10,8.5e8,1.e10,1.1,3.4e6,6.8e6,0.};
356  // -13-14--15--16--17-18--19--20--21- -22- -23- -24- -25- -26-
357  // -27--28- -29- -30- -31- -32- -33- -34- -35- -36- -37-
358  if(PDG ==-211)
359  {
360  // -- Total pp elastic cross section cs & s1/b1 (main), s2/b2 (tail1), s3/b3 (tail2) --
361  //p2=p*p;p3=p2*p;sp=sqrt(p);p2s=p2*sp;lp=log(p);dl1=lp-(3.=par(3));p4=p2*p2; p=|3-mom|
362  //CS=2.865/p2s/(1+.0022/p2s)+(18.9+.6461*dl1*dl1+9./p)/(1.+.425*lp)/(1.+.4276/p4);
363  // par(0) par(7) par(1) par(2) par(4) par(5) par(6)
364  //dl2=lp-5., s1=(74.+3.*dl2*dl2)/(1+3.4/p4/p)+(.2/p2+17.*p)/(p4+.001*sp),
365  // par(8) par(9) par(10) par(11) par(12)par(13) par(14)
366  // b1=8.*p**.055/(1.+3.64/p3); s2=5.e-5+4000./(p4+1500.*p); b2=.46+1.2e6/(p4+3.5e6/sp);
367  // par(15) par(16) par(17) par(18) par(19) par(20) par(21) par(22) par(23)
368  // s3=5.e-5+1.e10/(p4*p4+8.5e8*p2+1.e10); b3=1.1+3.4e6/(p4+6.8e6); ss=0.
369  // par(24) par(25) par(26) par(27) par(28) par(29) par(30) par(31)
370  //
371  if(lastPAR[nLast]!=pwd) // A unique flag to avoid the repeatable definition
372  {
373  if ( tgZ == 1 && tgN == 0 )
374  {
375  for (G4int ip=0; ip<n_pimpel; ip++) lastPAR[ip]=pimp_el[ip]; // PiMinus+P
376  }
377  else
378  {
379  G4double a=tgZ+tgN;
380  G4double sa=std::sqrt(a);
381  G4double ssa=std::sqrt(sa);
382  G4double asa=a*sa;
383  G4double a2=a*a;
384  G4double a3=a2*a;
385  G4double a4=a3*a;
386  G4double a5=a4*a;
387  G4double a6=a4*a2;
388  G4double a7=a6*a;
389  G4double a8=a7*a;
390  G4double a9=a8*a;
391  G4double a10=a5*a5;
392  G4double a12=a6*a6;
393  G4double a14=a7*a7;
394  G4double a16=a8*a8;
395  G4double a17=a16*a;
396  //G4double a20=a16*a4;
397  G4double a32=a16*a16;
398  // Reaction cross-section parameters (pel=peh_fit.f)
399  lastPAR[0]=(.95*sa+2.E5/a16)/(1.+17/a); // p1
400  lastPAR[1]=a/(1./4.4+1./a); // p2
401  lastPAR[2]=.22/std::pow(a,.33); // p3
402  lastPAR[3]=.5*a/(1.+3./a+1800./a8); // p4
403  lastPAR[4]=3.E-4*std::pow(a,.32)/(1.+14./a2); // p5
404  lastPAR[5]=0.; // p6 not used
405  lastPAR[6]=(.55+.001*a2)/(1.+4.E-4*a2); // p7
406  lastPAR[7]=(.0002/asa+4.E-9*a)/(1.+9./a4); // p8
407  lastPAR[8]=0.; // p9 not used
408  // @@ the differential cross-section is parameterized separately for A>6 & A<7
409  if(a<6.5)
410  {
411  G4double a28=a16*a12;
412  // The main pre-exponent (pel_sg)
413  lastPAR[ 9]=4000*a; // p1
414  lastPAR[10]=1.2e7*a8+380*a17; // p2
415  lastPAR[11]=.7/(1.+4.e-12*a16); // p3
416  lastPAR[12]=2.5/a8/(a4+1.e-16*a32); // p4
417  lastPAR[13]=.28*a; // p5
418  lastPAR[14]=1.2*a2+2.3; // p6
419  lastPAR[15]=3.8/a; // p7
420  // The main slope (pel_sl)
421  lastPAR[16]=.01/(1.+.0024*a5); // p1
422  lastPAR[17]=.2*a; // p2
423  lastPAR[18]=9.e-7/(1.+.035*a5); // p3
424  lastPAR[19]=(42.+2.7e-11*a16)/(1.+.14*a); // p4
425  // The main quadratic (pel_sh)
426  lastPAR[20]=2.25*a3; // p1
427  lastPAR[21]=18.; // p2
428  lastPAR[22]=2.4e-3*a8/(1.+2.6e-4*a7); // p3
429  lastPAR[23]=3.5e-36*a32*a8/(1.+5.e-15*a32/a); // p4
430  // The 1st max pre-exponent (pel_qq)
431  lastPAR[24]=1.e5/(a8+2.5e12/a16); // p1
432  lastPAR[25]=8.e7/(a12+1.e-27*a28*a28); // p2
433  lastPAR[26]=.0006*a3; // p3
434  // The 1st max slope (pel_qs)
435  lastPAR[27]=10.+4.e-8*a12*a; // p1
436  lastPAR[28]=.114; // p2
437  lastPAR[29]=.003; // p3
438  lastPAR[30]=2.e-23; // p4
439  // The effective pre-exponent (pel_ss)
440  lastPAR[31]=1./(1.+.0001*a8); // p1
441  lastPAR[32]=1.5e-4/(1.+5.e-6*a12); // p2
442  lastPAR[33]=.03; // p3
443  // The effective slope (pel_sb)
444  lastPAR[34]=a/2; // p1
445  lastPAR[35]=2.e-7*a4; // p2
446  lastPAR[36]=4.; // p3
447  lastPAR[37]=64./a3; // p4
448  // The gloria pre-exponent (pel_us)
449  lastPAR[38]=1.e8*std::exp(.32*asa); // p1
450  lastPAR[39]=20.*std::exp(.45*asa); // p2
451  lastPAR[40]=7.e3+2.4e6/a5; // p3
452  lastPAR[41]=2.5e5*std::exp(.085*a3); // p4
453  lastPAR[42]=2.5*a; // p5
454  // The gloria slope (pel_ub)
455  lastPAR[43]=920.+.03*a8*a3; // p1
456  lastPAR[44]=93.+.0023*a12; // p2
457  }
458  else
459  {
460  G4double p1a10=2.2e-28*a10;
461  G4double r4a16=6.e14/a16;
462  G4double s4a16=r4a16*r4a16;
463  // a24
464  // a36
465  // The main pre-exponent (peh_sg)
466  lastPAR[ 9]=4.5*std::pow(a,1.15); // p1
467  lastPAR[10]=.06*std::pow(a,.6); // p2
468  lastPAR[11]=.6*a/(1.+2.e15/a16); // p3
469  lastPAR[12]=.17/(a+9.e5/a3+1.5e33/a32); // p4
470  lastPAR[13]=(.001+7.e-11*a5)/(1.+4.4e-11*a5); // p5
471  lastPAR[14]=(p1a10*p1a10+2.e-29)/(1.+2.e-22*a12); // p6
472  // The main slope (peh_sl)
473  lastPAR[15]=400./a12+2.e-22*a9; // p1
474  lastPAR[16]=1.e-32*a12/(1.+5.e22/a14); // p2
475  lastPAR[17]=1000./a2+9.5*sa*ssa; // p3
476  lastPAR[18]=4.e-6*a*asa+1.e11/a16; // p4
477  lastPAR[19]=(120./a+.002*a2)/(1.+2.e14/a16); // p5
478  lastPAR[20]=9.+100./a; // p6
479  // The main quadratic (peh_sh)
480  lastPAR[21]=.002*a3+3.e7/a6; // p1
481  lastPAR[22]=7.e-15*a4*asa; // p2
482  lastPAR[23]=9000./a4; // p3
483  // The 1st max pre-exponent (peh_qq)
484  lastPAR[24]=.0011*asa/(1.+3.e34/a32/a4); // p1
485  lastPAR[25]=1.e-5*a2+2.e14/a16; // p2
486  lastPAR[26]=1.2e-11*a2/(1.+1.5e19/a12); // p3
487  lastPAR[27]=.016*asa/(1.+5.e16/a16); // p4
488  // The 1st max slope (peh_qs)
489  lastPAR[28]=.002*a4/(1.+7.e7/std::pow(a-6.83,14)); // p1
490  lastPAR[29]=2.e6/a6+7.2/std::pow(a,.11); // p2
491  lastPAR[30]=11.*a3/(1.+7.e23/a16/a8); // p3
492  lastPAR[31]=100./asa; // p4
493  // The 2nd max pre-exponent (peh_ss)
494  lastPAR[32]=(.1+4.4e-5*a2)/(1.+5.e5/a4); // p1
495  lastPAR[33]=3.5e-4*a2/(1.+1.e8/a8); // p2
496  lastPAR[34]=1.3+3.e5/a4; // p3
497  lastPAR[35]=500./(a2+50.)+3; // p4
498  lastPAR[36]=1.e-9/a+s4a16*s4a16; // p5
499  // The 2nd max slope (peh_sb)
500  lastPAR[37]=.4*asa+3.e-9*a6; // p1
501  lastPAR[38]=.0005*a5; // p2
502  lastPAR[39]=.002*a5; // p3
503  lastPAR[40]=10.; // p4
504  // The effective pre-exponent (peh_us)
505  lastPAR[41]=.05+.005*a; // p1
506  lastPAR[42]=7.e-8/sa; // p2
507  lastPAR[43]=.8*sa; // p3
508  lastPAR[44]=.02*sa; // p4
509  lastPAR[45]=1.e8/a3; // p5
510  lastPAR[46]=3.e32/(a32+1.e32); // p6
511  // The effective slope (peh_ub)
512  lastPAR[47]=24.; // p1
513  lastPAR[48]=20./sa; // p2
514  lastPAR[49]=7.e3*a/(sa+1.); // p3
515  lastPAR[50]=900.*sa/(1.+500./a3); // p4
516  }
517  // Parameter for lowEnergyNeutrons
518  lastPAR[51]=1.e15+2.e27/a4/(1.+2.e-18*a16);
519  }
520  lastPAR[nLast]=pwd;
521  // and initialize the zero element of the table
522  G4double lp=lPMin; // ln(momentum)
523  G4bool memCS=onlyCS; // ??
524  onlyCS=false;
525  lastCST[0]=GetTabValues(lp, PDG, tgZ, tgN); // Calculate AMDB tables
526  onlyCS=memCS;
527  lastSST[0]=theSS;
528  lastS1T[0]=theS1;
529  lastB1T[0]=theB1;
530  lastS2T[0]=theS2;
531  lastB2T[0]=theB2;
532  lastS3T[0]=theS3;
533  lastB3T[0]=theB3;
534  lastS4T[0]=theS4;
535  lastB4T[0]=theB4;
536  }
537  if(LP>ILP)
538  {
539  G4int ini = static_cast<int>((ILP-lPMin+.000001)/dlnP)+1; // already inited till this
540  if(ini<0) ini=0;
541  if(ini<nPoints)
542  {
543  G4int fin = static_cast<int>((LP-lPMin)/dlnP)+1; // final bin of initialization
544  if(fin>=nPoints) fin=nLast; // Limit of the tabular initialization
545  if(fin>=ini)
546  {
547  G4double lp=0.;
548  for(G4int ip=ini; ip<=fin; ip++) // Calculate tabular CS,S1,B1,S2,B2,S3,B3
549  {
550  lp=lPMin+ip*dlnP; // ln(momentum)
551  G4bool memCS=onlyCS;
552  onlyCS=false;
553  lastCST[ip]=GetTabValues(lp, PDG, tgZ, tgN); // Calculate AMDB tables (ret CS)
554  onlyCS=memCS;
555  lastSST[ip]=theSS;
556  lastS1T[ip]=theS1;
557  lastB1T[ip]=theB1;
558  lastS2T[ip]=theS2;
559  lastB2T[ip]=theB2;
560  lastS3T[ip]=theS3;
561  lastB3T[ip]=theB3;
562  lastS4T[ip]=theS4;
563  lastB4T[ip]=theB4;
564  }
565  return lp;
566  }
567  else G4cout<<"*Warning*G4ChipsPionMinusElasticXS::GetPTables: PDG="<<PDG
568  <<", Z="<<tgZ<<", N="<<tgN<<", i="<<ini<<" > fin="<<fin<<", LP="<<LP
569  <<" > ILP="<<ILP<<" nothing is done!"<<G4endl;
570  }
571  else G4cout<<"*Warning*G4ChipsPionMinusElasticXS::GetPTables: PDG="<<PDG
572  <<", Z="<<tgZ<<", N="<<tgN<<", i="<<ini<<">= max="<<nPoints<<", LP="<<LP
573  <<" > ILP="<<ILP<<", lPMax="<<lPMax<<" nothing is done!"<<G4endl;
574  }
575  }
576  else
577  {
578  // G4cout<<"*Error*G4ChipsPionMinusElasticXS::GetPTables: PDG="<<PDG<<", Z="<<tgZ
579  // <<", N="<<tgN<<", while it is defined only for PDG=-211"<<G4endl;
580  // throw G4QException("G4ChipsPionMinusElasticXS::GetPTables:onlyPipA implemented");
582  ed << "PDG = " << PDG << ", Z = " << tgZ << ", N = " << tgN
583  << ", while it is defined only for PDG=-211 (pi-)" << G4endl;
584  G4Exception("G4ChipsPionMinusElasticXS::GetPTables()", "HAD_CHPS_0000",
585  FatalException, ed);
586  }
587  return ILP;
588 }
589 
590 // Returns Q2=-t in independent units (MeV^2) (all internal calculations are in GeV)
592 {
593  static const G4double GeVSQ=gigaelectronvolt*gigaelectronvolt;
594  static const G4double third=1./3.;
595  static const G4double fifth=1./5.;
596  static const G4double sevth=1./7.;
597  if(PDG!=-211)G4cout<<"Warning*G4ChipsPionMinusElasticXS::GetExT:PDG="<<PDG<<G4endl;
598  if(onlyCS)G4cout<<"Warning*G4ChipsPionMinusElasticXS::GetExchanT:onlyCS=1"<<G4endl;
599  if(lastLP<-4.3) return lastTM*GeVSQ*G4UniformRand();// S-wave for p<14 MeV/c (kinE<.1MeV)
600  G4double q2=0.;
601  if(tgZ==1 && tgN==0) // ===> p+p=p+p
602  {
603  G4double E1=lastTM*theB1;
604  G4double R1=(1.-std::exp(-E1));
605  G4double E2=lastTM*theB2;
606  G4double R2=(1.-std::exp(-E2*E2*E2));
607  G4double E3=lastTM*theB3;
608  G4double R3=(1.-std::exp(-E3));
609  G4double I1=R1*theS1/theB1;
610  G4double I2=R2*theS2;
611  G4double I3=R3*theS3;
612  G4double I12=I1+I2;
613  G4double rand=(I12+I3)*G4UniformRand();
614  if (rand<I1 )
615  {
616  G4double ran=R1*G4UniformRand();
617  if(ran>1.) ran=1.;
618  q2=-std::log(1.-ran)/theB1;
619  }
620  else if(rand<I12)
621  {
622  G4double ran=R2*G4UniformRand();
623  if(ran>1.) ran=1.;
624  q2=-std::log(1.-ran);
625  if(q2<0.) q2=0.;
626  q2=std::pow(q2,third)/theB2;
627  }
628  else
629  {
630  G4double ran=R3*G4UniformRand();
631  if(ran>1.) ran=1.;
632  q2=-std::log(1.-ran)/theB3;
633  }
634  }
635  else
636  {
637  G4double a=tgZ+tgN;
639  G4double R1=(1.-std::exp(-E1));
640  G4double tss=theSS+theSS; // for future solution of quadratic equation (imediate check)
641  G4double tm2=lastTM*lastTM;
642  G4double E2=lastTM*tm2*theB2; // power 3 for lowA, 5 for HighA (1st)
643  if(a>6.5)E2*=tm2; // for heavy nuclei
644  G4double R2=(1.-std::exp(-E2));
645  G4double E3=lastTM*theB3;
646  if(a>6.5)E3*=tm2*tm2*tm2; // power 1 for lowA, 7 (2nd) for HighA
647  G4double R3=(1.-std::exp(-E3));
648  G4double E4=lastTM*theB4;
649  G4double R4=(1.-std::exp(-E4));
650  G4double I1=R1*theS1;
651  G4double I2=R2*theS2;
652  G4double I3=R3*theS3;
653  G4double I4=R4*theS4;
654  G4double I12=I1+I2;
655  G4double I13=I12+I3;
656  G4double rand=(I13+I4)*G4UniformRand();
657  if(rand<I1)
658  {
659  G4double ran=R1*G4UniformRand();
660  if(ran>1.) ran=1.;
661  q2=-std::log(1.-ran)/theB1;
662  if(std::fabs(tss)>1.e-7) q2=(std::sqrt(theB1*(theB1+(tss+tss)*q2))-theB1)/tss;
663  }
664  else if(rand<I12)
665  {
666  G4double ran=R2*G4UniformRand();
667  if(ran>1.) ran=1.;
668  q2=-std::log(1.-ran)/theB2;
669  if(q2<0.) q2=0.;
670  if(a<6.5) q2=std::pow(q2,third);
671  else q2=std::pow(q2,fifth);
672  }
673  else if(rand<I13)
674  {
675  G4double ran=R3*G4UniformRand();
676  if(ran>1.) ran=1.;
677  q2=-std::log(1.-ran)/theB3;
678  if(q2<0.) q2=0.;
679  if(a>6.5) q2=std::pow(q2,sevth);
680  }
681  else
682  {
683  G4double ran=R4*G4UniformRand();
684  if(ran>1.) ran=1.;
685  q2=-std::log(1.-ran)/theB4;
686  if(a<6.5) q2=lastTM-q2; // u reduced for lightA (starts from 0)
687  }
688  }
689  if(q2<0.) q2=0.;
690  if(!(q2>=-1.||q2<=1.)) G4cout<<"*NAN*G4QElasticCrossSect::GetExchangeT: -t="<<q2<<G4endl;
691  if(q2>lastTM)
692  {
693  q2=lastTM;
694  }
695  return q2*GeVSQ;
696 }
697 
698 // Returns B in independent units (MeV^-2) (all internal calculations are in GeV) see ExT
700 {
701  static const G4double GeVSQ=gigaelectronvolt*gigaelectronvolt;
702  if(onlyCS)G4cout<<"Warning*G4ChipsPionMinusElasticXS::GetSlope:onlCS=true"<<G4endl;
703  if(lastLP<-4.3) return 0.; // S-wave for p<14 MeV/c (kinE<.1MeV)
704  if(PDG !=-211)
705  {
706  // G4cout<<"*Error*G4ChipsPionMinusElasticXS::GetSlope: PDG="<<PDG<<", Z="<<tgZ
707  // <<", N="<<tgN<<", while it is defined only for PDG=-211"<<G4endl;
708  // throw G4QException("G4ChipsPionMinusElasticXS::GetSlope: pipA are implemented");
710  ed << "PDG = " << PDG << ", Z = " << tgZ << ", N = " << tgN
711  << ", while it is defined only for PDG=-211" << G4endl;
712  G4Exception("G4ChipsPionMinusElasticXS::GetSlope()", "HAD_CHPS_0000",
713  FatalException, ed);
714  }
715  if(theB1<0.) theB1=0.;
716  if(!(theB1>=-1.||theB1<=1.))G4cout<<"*NAN*G4QElasticCrossSect::Getslope:"<<theB1<<G4endl;
717  return theB1/GeVSQ;
718 }
719 
720 // Returns half max(Q2=-t) in independent units (MeV^2)
722 {
723  static const G4double HGeVSQ=gigaelectronvolt*gigaelectronvolt/2.;
724  return lastTM*HGeVSQ;
725 }
726 
727 // lastLP is used, so calculating tables, one need to remember and then recover lastLP
729  G4int tgN)
730 {
731  if(PDG!=-211)G4cout<<"*Warn*G4ChipsPionMinusElasticXS::GetTabV: PDG="<<PDG<<G4endl;
732  if(tgZ<0 || tgZ>92)
733  {
734  G4cout<<"*Warning*G4QPionPlusElCS::GetTabValue:(1-92) No isotopes for Z="<<tgZ<<G4endl;
735  return 0.;
736  }
737  G4int iZ=tgZ-1; // Z index
738  if(iZ<0)
739  {
740  iZ=0; // conversion of the neutron target to the proton target
741  tgZ=1;
742  tgN=0;
743  }
744  G4double p=std::exp(lp); // momentum
745  G4double sp=std::sqrt(p); // sqrt(p)
746  G4double p2=p*p;
747  G4double p3=p2*p;
748  G4double p4=p3*p;
749  if ( tgZ == 1 && tgN == 0 ) // PiMin+P
750  {
751  G4double dl2=lp-lastPAR[14];
752  theSS=lastPAR[37];
753  theS1=(lastPAR[15]+lastPAR[16]*dl2*dl2)/(1.+lastPAR[17]/p4/p)+
754  (lastPAR[18]/p2+lastPAR[19]*p)/(p4+lastPAR[20]*sp);
755  theB1=lastPAR[21]*std::pow(p,lastPAR[22])/(1.+lastPAR[23]/p3);
756  theS2=lastPAR[24]+lastPAR[25]/(p4+lastPAR[26]*p);
757  theB2=lastPAR[27]+lastPAR[28]/(p4+lastPAR[29]/sp);
758  theS3=lastPAR[30]+lastPAR[31]/(p4*p4+lastPAR[32]*p2+lastPAR[33]);
759  theB3=lastPAR[34]+lastPAR[35]/(p4+lastPAR[36]);
760  theS4=0.;
761  theB4=0.;
762  // Returns the total elastic pim-p cross-section (to avoid spoiling lastSIG)
763  G4double lr=lp+lastPAR[0]; // lr
764  G4double ld=lp-lastPAR[14];
765  G4double dl3=lp+lastPAR[4]; // lm
766  G4double dl4=lp-lastPAR[6]; // lh
767 //G4cout<<"lastPAR[13] "<<lastPAR[13]<<" lastPAR[6] "<<lastPAR[6]<<" lastPAR[7] "<<lastPAR[7]<<G4endl;
768  return lastPAR[1]/(lr*lr+lastPAR[2])+
769  (lastPAR[8]*ld*ld+lastPAR[9]+lastPAR[10]/sp)/(1.+lastPAR[11]/p4)+
770  lastPAR[12]/(dl3*dl3+lastPAR[5])+lastPAR[13]/(dl4*dl4+lastPAR[7]);
771  }
772  else
773  {
774  G4double p5=p4*p;
775  G4double p6=p5*p;
776  G4double p8=p6*p2;
777  G4double p10=p8*p2;
778  G4double p12=p10*p2;
779  G4double p16=p8*p8;
780  //G4double p24=p16*p8;
781  G4double dl=lp-5.;
782  G4double a=tgZ+tgN;
783  G4double pah=std::pow(p,a/2);
784  G4double pa=pah*pah;
785  G4double pa2=pa*pa;
786  if(a<6.5)
787  {
788  theS1=lastPAR[9]/(1.+lastPAR[10]*p4*pa)+lastPAR[11]/(p4+lastPAR[12]*p4/pa2)+
789  (lastPAR[13]*dl*dl+lastPAR[14])/(1.+lastPAR[15]/p2);
790  theB1=(lastPAR[16]+lastPAR[17]*p2)/(p4+lastPAR[18]/pah)+lastPAR[19];
791  theSS=lastPAR[20]/(1.+lastPAR[21]/p2)+lastPAR[22]/(p6/pa+lastPAR[23]/p16);
792  theS2=lastPAR[24]/(pa/p2+lastPAR[25]/p4)+lastPAR[26];
793  theB2=lastPAR[27]*std::pow(p,lastPAR[28])+lastPAR[29]/(p8+lastPAR[30]/p16);
794  theS3=lastPAR[31]/(pa*p+lastPAR[32]/pa)+lastPAR[33];
795  theB3=lastPAR[34]/(p3+lastPAR[35]/p6)+lastPAR[36]/(1.+lastPAR[37]/p2);
796  theS4=p2*(pah*lastPAR[38]*std::exp(-pah*lastPAR[39])+
797  lastPAR[40]/(1.+lastPAR[41]*std::pow(p,lastPAR[42])));
798  theB4=lastPAR[43]*pa/p2/(1.+pa*lastPAR[44]);
799  }
800  else
801  {
802  theS1=lastPAR[9]/(1.+lastPAR[10]/p4)+lastPAR[11]/(p4+lastPAR[12]/p2)+
803  lastPAR[13]/(p5+lastPAR[14]/p16);
804  theB1=(lastPAR[15]/p8+lastPAR[19])/(p+lastPAR[16]/std::pow(p,lastPAR[20]))+
805  lastPAR[17]/(1.+lastPAR[18]/p4);
806  theSS=lastPAR[21]/(p4/std::pow(p,lastPAR[23])+lastPAR[22]/p4);
807  theS2=lastPAR[24]/p4/(std::pow(p,lastPAR[25])+lastPAR[26]/p12)+lastPAR[27];
808  theB2=lastPAR[28]/std::pow(p,lastPAR[29])+lastPAR[30]/std::pow(p,lastPAR[31]);
809  theS3=lastPAR[32]/std::pow(p,lastPAR[35])/(1.+lastPAR[36]/p12)+
810  lastPAR[33]/(1.+lastPAR[34]/p6);
811  theB3=lastPAR[37]/p8+lastPAR[38]/p2+lastPAR[39]/(1.+lastPAR[40]/p8);
812  theS4=(lastPAR[41]/p4+lastPAR[46]/p)/(1.+lastPAR[42]/p10)+
813  (lastPAR[43]+lastPAR[44]*dl*dl)/(1.+lastPAR[45]/p12);
814  theB4=lastPAR[47]/(1.+lastPAR[48]/p)+lastPAR[49]*p4/(1.+lastPAR[50]*p5);
815  }
816  // Returns the total elastic (n/p)A cross-section (to avoid spoiling lastSIG)
817  // p1 p2 p3
818  return (lastPAR[0]*dl*dl+lastPAR[1])/(1.+lastPAR[2]/p8)+
819  lastPAR[3]/(p4+lastPAR[4]/p3)+lastPAR[6]/(p4+lastPAR[7]/p4);
820  // p4 p5 p7 p8
821  }
822  return 0.;
823 } // End of GetTableValues
824 
825 // Returns max -t=Q2 (GeV^2) for the momentum pP(GeV) and the target nucleus (tgN,tgZ)
827  G4double pP)
828 {
829  static const G4double mPi= G4PionMinus::PionMinus()->GetPDGMass()*.001; // MeV to GeV
830  static const G4double mPi2= mPi*mPi;
831 
832  G4double pP2=pP*pP; // squared momentum of the projectile
833  if(tgZ || tgN>-1) // ---> pipA
834  {
835  G4double mt=G4ParticleTable::GetParticleTable()->GetIonTable()->GetIon(tgZ,tgZ+tgN,0)->GetPDGMass()*.001; // Target mass in GeV
836 
837  G4double dmt=mt+mt;
838  G4double mds=dmt*std::sqrt(pP2+mPi2)+mPi2+mt*mt; // Mondelstam mds
839  return dmt*dmt*pP2/mds;
840  }
841  else
842  {
844  ed << "PDG = " << PDG << ",Z = " << tgZ << ",N = " << tgN
845  << ", while it is defined only for p projectiles & Z_target>0" << G4endl;
846  G4Exception("G4ChipsPionMinusElasticXS::GetQ2max()", "HAD_CHPS_0000",
847  FatalException, ed);
848  return 0;
849  }
850 }
virtual G4double GetIsoCrossSection(const G4DynamicParticle *, G4int tgZ, G4int A, const G4Isotope *iso=0, const G4Element *elm=0, const G4Material *mat=0)
std::ostringstream G4ExceptionDescription
Definition: globals.hh:76
G4ParticleDefinition * GetIon(G4int Z, G4int A, G4int lvl=0)
Definition: G4IonTable.cc:463
G4double GetExchangeT(G4int tZ, G4int tN, G4int pPDG)
static const G4double a4
G4double a
Definition: TRTMaterials.hh:39
int G4int
Definition: G4Types.hh:78
G4double GetTotalMomentum() const
G4IonTable * GetIonTable() const
#define G4UniformRand()
Definition: Randomize.hh:95
G4GLOB_DLL std::ostream G4cout
G4double GetQ2max(G4int pPDG, G4int tgZ, G4int tgN, G4double pP)
virtual G4bool IsIsoApplicable(const G4DynamicParticle *Pt, G4int Z, G4int A, const G4Element *elm, const G4Material *mat)
bool G4bool
Definition: G4Types.hh:79
static const double GeV
Definition: G4SIunits.hh:196
static const G4double A[nN]
static const G4double a3
virtual G4double GetChipsCrossSection(G4double momentum, G4int Z, G4int N, G4int pdg)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
G4_DECLARE_XS_FACTORY(G4ChipsPionMinusElasticXS)
G4double GetPDGMass() const
static G4ParticleTable * GetParticleTable()
static G4PionMinus * PionMinus()
Definition: G4PionMinus.cc:98
static const double gigaelectronvolt
Definition: G4SIunits.hh:188
static const double millibarn
Definition: G4SIunits.hh:96
G4double GetPTables(G4double lpP, G4double lPm, G4int PDG, G4int tZ, G4int tN)
G4double GetSlope(G4int tZ, G4int tN, G4int pPDG)
#define G4endl
Definition: G4ios.hh:61
G4double GetTabValues(G4double lp, G4int pPDG, G4int tgZ, G4int tgN)
G4double CalculateCrossSection(G4bool CS, G4int F, G4int I, G4int pPDG, G4int Z, G4int N, G4double pP)
static const G4double a5
double G4double
Definition: G4Types.hh:76
static const G4double pos
static const G4double a2