Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
G4QAntiBaryonPlusNuclearCrossSection.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// The lust update: M.V. Kossov, CERN/ITEP(Moscow) 17-June-02
28// GEANT4 tag $Name: not supported by cvs2svn $
29//
30//
31// G4 Physics class: G4QAntiBaryonPlusNuclearCrossSection for gamma+A cross sections
32// Created: M.V. Kossov, CERN/ITEP(Moscow), 20-Dec-03
33// The last update: M.V. Kossov, CERN/ITEP (Moscow) 15-Feb-04
34// --------------------------------------------------------------------------------
35// ****************************************************************************************
36// This Header is a part of the CHIPS physics package (author: M. Kosov)
37// ****************************************************************************************
38// Short description: CHIPS cross-sections for AntiBaryon(plus)-nuclear interactions
39// -------------------------------------------------------------------------------------
40//
41//#define debug
42//#define pdebug
43//#define debug3
44//#define debugn
45//#define debugs
46
48#include "G4SystemOfUnits.hh"
49
50// Initialization of the
51G4double* G4QAntiBaryonPlusNuclearCrossSection::lastLEN=0; // PointerToLastArray ofLowEn CS
52G4double* G4QAntiBaryonPlusNuclearCrossSection::lastHEN=0; // PointerToLastArray ofHighEnCS
53G4int G4QAntiBaryonPlusNuclearCrossSection::lastN=0; // TheLastN of calculatedNucleus
54G4int G4QAntiBaryonPlusNuclearCrossSection::lastZ=0; // TheLastZ of calculatedNucleus
55G4double G4QAntiBaryonPlusNuclearCrossSection::lastP=0.; // LastUsedCrossSectionMomentum
56G4double G4QAntiBaryonPlusNuclearCrossSection::lastTH=0.; // Last threshold momentum
57G4double G4QAntiBaryonPlusNuclearCrossSection::lastCS=0.; // LastValue of the CrossSection
58G4int G4QAntiBaryonPlusNuclearCrossSection::lastI=0; // TheLastPosition in the DAMDB
59std::vector<G4double*>* G4QAntiBaryonPlusNuclearCrossSection::LEN =
60 new std::vector<G4double*>;
61std::vector<G4double*>* G4QAntiBaryonPlusNuclearCrossSection::HEN =
62 new std::vector<G4double*>;
63
64// Returns Pointer to the G4VQCrossSection class
66{
67 static G4QAntiBaryonPlusNuclearCrossSection theCrossSection;//Static body of CrossSection
68 return &theCrossSection;
69}
70
72{
73 G4int lens=LEN->size();
74 for(G4int i=0; i<lens; ++i) delete[] (*LEN)[i];
75 delete LEN;
76 G4int hens=HEN->size();
77 for(G4int i=0; i<hens; ++i) delete[] (*HEN)[i];
78 delete HEN;
79}
80
81// The main member function giving the collision cross section (P is in IU, CS is in mb)
82// Make pMom in independent units ! (Now it is MeV)
84 G4int tgZ, G4int tgN, G4int PDG)
85{
86 //A.R.23-Oct-2012 Shadowed variable static G4double tolerance=0.001; // Tolerance (0.1%) to consider as "the same mom"
87 static G4int j; // A#0f Z/N-records already tested in AMDB
88 static std::vector <G4int> colN; // Vector of N for calculated nuclei (isotops)
89 static std::vector <G4int> colZ; // Vector of Z for calculated nuclei (isotops)
90 static std::vector <G4double> colP; // Vector of last momenta for the reaction
91 static std::vector <G4double> colTH; // Vector of energy thresholds for the reaction
92 static std::vector <G4double> colCS; // Vector of last cross sections for the reaction
93 // ***---*** End of the mandatory Static Definitions of the Associative Memory ***---***
94#ifdef debug
95 G4cout<<"G4QaBPCS::GetCS:>>>f="<<fCS<<", p="<<pMom<<", Z="<<tgZ<<"("<<lastZ<<") ,N="<<tgN
96 <<"("<<lastN<<"),PDG="<<PDG<<", thresh="<<lastTH<<",Sz="<<colN.size()<<G4endl;
97#endif
98 if(PDG!=-3112 && PDG!=-3312 && PDG!=-3334)
99 G4cout<<"-Warning-G4QAntiBaryonPlusCS::GetCS: Not a PositiveAntiBar,PDG="<<PDG<<G4endl;
100 G4bool in=false; // By default the isotope must be found in the AMDB
101 if(tgN!=lastN || tgZ!=lastZ) // The nucleus was not the last used isotope
102 {
103 in = false; // By default the isotope haven't be found in AMDB
104 lastP = 0.; // New momentum history (nothing to compare with)
105 lastN = tgN; // The last N of the calculated nucleus
106 lastZ = tgZ; // The last Z of the calculated nucleus
107 lastI = colN.size(); // Size of the Associative Memory DB in the heap
108 j = 0; // A#0f records found in DB for this projectile
109#ifdef debug
110 G4cout<<"G4QABPNuclCS::GetCS: the amount of records in the AMDB lastI="<<lastI<<G4endl;
111#endif
112 if(lastI) for(G4int i=0; i<lastI; i++) // AMDB exists, try to find the (Z,N) isotope
113 {
114 if(colN[i]==tgN && colZ[i]==tgZ) // Try the record "i" in the AMDB
115 {
116 lastI=i; // Remember the index for future fast/last use
117 lastTH =colTH[i]; // The last THreshold (A-dependent)
118#ifdef debug
119 G4cout<<"G4QaBPCS::GetCS:*Found*P="<<pMom<<",Threshold="<<lastTH<<",j="<<j<<G4endl;
120#endif
121 if(pMom<=lastTH)
122 {
123#ifdef debug
124 G4cout<<"G4QPCS::GetCS:Found,P="<<pMom<<" < Threshold="<<lastTH<<",CS=0"<<G4endl;
125#endif
126 return 0.; // Energy is below the Threshold value
127 }
128 lastP =colP [i]; // Last Momentum (A-dependent)
129 lastCS =colCS[i]; // Last CrossSect (A-dependent)
130 if(std::fabs(lastP-pMom)<tolerance*pMom)
131 //if(lastP==pMom) // VI do not use tolerance
132 {
133#ifdef debug
134 G4cout<<"G4QaBPNCS::GetCS:.DoNothing.P="<<pMom<<",CS="<<lastCS*millibarn<<G4endl;
135#endif
136 //CalculateCrossSection(fCS,-1,j,PDG,lastZ,lastN,pMom); // Update param's only
137 return lastCS*millibarn; // Use theLastCS
138 }
139 in = true; // This is the case when the isotop is found in DB
140 // Momentum pMom is in IU ! @@ Units
141#ifdef debug
142 G4cout<<"G4QaBPNCS::G:UpdDB,P="<<pMom<<",f="<<fCS<<",lI="<<lastI<<",j="<<j<<G4endl;
143#endif
144 lastCS=CalculateCrossSection(fCS,-1,j,PDG,lastZ,lastN,pMom); // read & update
145#ifdef debug
146 G4cout<<"G4QaBPNuCS::GetCrosSec: *****> New (inDB) Calculated CS="<<lastCS<<G4endl;
147#endif
148 if(lastCS<=0. && pMom>lastTH) // Correct the threshold (@@ No intermediate Zeros)
149 {
150#ifdef debug
151 G4cout<<"G4QaBPNuCS::GetCS: New P="<<pMom<<"(CS=0) > Threshold="<<lastTH<<G4endl;
152#endif
153 lastCS=0.;
154 lastTH=pMom;
155 }
156 break; // Go out of the LOOP
157 }
158#ifdef debug
159 G4cout<<"-->G4QaBarPNucCrossSec::GetCrosSec: pPDG="<<PDG<<", j="<<j<<", N="<<colN[i]
160 <<",Z["<<i<<"]="<<colZ[i]<<G4endl;
161#endif
162 j++; // Increment a#0f records found in DB
163 }
164#ifdef debug
165 G4cout<<"-?-G4QaBPNCS::GeCS:R,Z="<<tgZ<<",N="<<tgN<<",in="<<in<<",j="<<j<<" ?"<<G4endl;
166#endif
167 if(!in) // This isotope has not been calculated previously
168 {
169#ifdef debug
170 G4cout<<"^^^G4QaBPCS::GetCS:CalcNewP="<<pMom<<", f="<<fCS<<", lastI="<<lastI<<G4endl;
171#endif
172 //!!The slave functions must provide cross-sections in millibarns (mb) !! (not in IU)
173 lastCS=CalculateCrossSection(fCS,0,j,PDG,lastZ,lastN,pMom); //calculate & create
174 //if(lastCS>0.) // It means that the AMBD was initialized
175 //{
176
177 lastTH = ThresholdEnergy(tgZ, tgN); // The Threshold Energy which is now the last
178#ifdef debug
179 G4cout<<"G4QaBPNucCrossSec::GetCrossSect: NewThresh="<<lastTH<<",P="<<pMom<<G4endl;
180#endif
181 colN.push_back(tgN);
182 colZ.push_back(tgZ);
183 colP.push_back(pMom);
184 colTH.push_back(lastTH);
185 colCS.push_back(lastCS);
186#ifdef debug
187 G4cout<<"G4QaBPNCS::GetCrosSec:lCS="<<lastCS<<",lZ="<<lastN<<",lN="<<lastZ<<G4endl;
188#endif
189 //} // M.K. Presence of H1 with high threshold breaks the syncronization
190#ifdef pdebug
191 G4cout<<"G4QaBPNCS::GCS:1st,P="<<pMom<<"(MeV),CS="<<lastCS*millibarn<<"(mb)"<<G4endl;
192#endif
193 return lastCS*millibarn;
194 } // End of creation of the new set of parameters
195 else
196 {
197#ifdef debug
198 G4cout<<"G4QaBarPNucCrossSect::GetCrosSect: Update lastI="<<lastI<<",j="<<j<<G4endl;
199#endif
200 colP[lastI]=pMom;
201 colCS[lastI]=lastCS;
202 }
203 } // End of parameters udate
204 else if(pMom<=lastTH)
205 {
206#ifdef debug
207 G4cout<<"G4QaBPNuCS::GetCS:CurrentP="<<pMom<<" < Threshold="<<lastTH<<", CS=0"<<G4endl;
208#endif
209 return 0.; // Momentum is below the Threshold Value -> CS=0
210 }
211 else if(std::fabs(lastP-pMom)<tolerance*pMom)
212 //else if(lastP==pMom) // VI do not use tolerance
213 {
214#ifdef debug
215 G4cout<<"G4QaBPCS::GetCS:OldNZ&P="<<lastP<<"="<<pMom<<",CS="<<lastCS*millibarn<<G4endl;
216#endif
217 return lastCS*millibarn; // Use theLastCS
218 }
219 else // It is the last used -> use the current tables
220 {
221#ifdef debug
222 G4cout<<"-!-G4QaBPCS::GeCS:UseCurP="<<pMom<<",f="<<fCS<<",I="<<lastI<<",j="<<j<<G4endl;
223#endif
224 lastCS=CalculateCrossSection(fCS,1,j,PDG,lastZ,lastN,pMom); // Only read and UpdateDB
225 lastP=pMom;
226 }
227#ifdef debug
228 G4cout<<"==>G4QaBPCS::GetCroSec:P="<<pMom<<"(MeV),CS="<<lastCS*millibarn<<"(mb)"<<G4endl;
229#endif
230 return lastCS*millibarn;
231}
232
233// The main member function giving the gamma-A cross section (E in GeV, CS in mb)
235 G4int, G4int targZ, G4int targN, G4double Momentum)
236{
237 static const G4double THmin=27.; // default minimum Momentum (MeV/c) Threshold
238 static const G4double THmiG=THmin*.001; // minimum Momentum (GeV/c) Threshold
239 static const G4double dP=10.; // step for the LEN (Low ENergy) table MeV/c
240 static const G4double dPG=dP*.001; // step for the LEN (Low ENergy) table GeV/c
241 static const G4int nL=105; // A#of LEN points in E (step 10 MeV/c)
242 static const G4double Pmin=THmin+(nL-1)*dP; // minP for the HighE part with safety
243 static const G4double Pmax=227000.; // maxP for the HEN (High ENergy) part 227 GeV
244 static const G4int nH=224; // A#of HEN points in lnE
245 static const G4double milP=std::log(Pmin);// Low logarithm energy for the HEN part
246 static const G4double malP=std::log(Pmax);// High logarithm energy (each 2.75 percent)
247 static const G4double dlP=(malP-milP)/(nH-1); // Step in log energy in the HEN part
248 static const G4double milPG=std::log(.001*Pmin);// Low logarithmEnergy for HEN part GeV/c
249#ifdef debug
250 G4cout<<"G4QaBPNuCS::CalCS:N="<<targN<<",Z="<<targZ<<",P="<<Momentum<<">"<<THmin<<G4endl;
251#endif
252 G4double sigma=0.;
253 if(F&&I) sigma=0.; // @@ *!* Fake line *!* to use F & I !!!Temporary!!!
254 //G4double A=targN+targZ; // A of the target
255#ifdef debug
256 G4cout<<"G4QaBarPNucCS::CalCS:A="<<A<<",F="<<F<<",I="<<I<<",nL="<<nL<<",nH="<<nH<<G4endl;
257#endif
258 if(F<=0) // This isotope was not the last used isotop
259 {
260 if(F<0) // This isotope was found in DAMDB =-----=> RETRIEVE
261 {
262 G4int sync=LEN->size();
263 if(sync<=I) G4cerr<<"*!*G4QaBarPNuclCS::CalcCrosSect: Sync="<<sync<<"<="<<I<<G4endl;
264 lastLEN=(*LEN)[I]; // Pointer to prepared LowEnergy cross sections
265 lastHEN=(*HEN)[I]; // Pointer to prepared High Energy cross sections
266 }
267 else // This isotope wasn't calculated before => CREATE
268 {
269 lastLEN = new G4double[nL]; // Allocate memory for the new LEN cross sections
270 lastHEN = new G4double[nH]; // Allocate memory for the new HEN cross sections
271 // --- Instead of making a separate function ---
272 G4double P=THmiG; // Table threshold in GeV/c
273 for(G4int n=0; n<nL; n++)
274 {
275 lastLEN[n] = CrossSectionLin(targZ, targN, P);
276 P+=dPG;
277 }
278 G4double lP=milPG;
279 for(G4int n=0; n<nH; n++)
280 {
281 lastHEN[n] = CrossSectionLog(targZ, targN, lP);
282 lP+=dlP;
283 }
284#ifdef debug
285 G4cout<<"-*->G4QaBarPNucCS::CalCS:Tab for Z="<<targZ<<",N="<<targN<<",I="<<I<<G4endl;
286#endif
287 // --- End of possible separate function
288 // *** The synchronization check ***
289 G4int sync=LEN->size();
290 if(sync!=I)
291 {
292 G4cerr<<"***G4QaBarPNuclCS::CalcCrossSect: Sinc="<<sync<<"#"<<I<<", Z=" <<targZ
293 <<", N="<<targN<<", F="<<F<<G4endl;
294 //G4Exception("G4PiMinusNuclearCS::CalculateCS:","39",FatalException,"DBoverflow");
295 }
296 LEN->push_back(lastLEN); // remember the Low Energy Table
297 HEN->push_back(lastHEN); // remember the High Energy Table
298 } // End of creation of the new set of parameters
299 } // End of parameters udate
300 // =--------------------= NOW the Magic Formula =--------------------=
301#ifdef debug
302 G4cout<<"G4QaBPNCS::CalCS:lTH="<<lastTH<<",Pmi="<<Pmin<<",dP="<<dP<<",dlP="<<dlP<<G4endl;
303#endif
304 if (Momentum<lastTH) return 0.; // It must be already checked in the interface class
305 else if (Momentum<Pmin) // High Energy region
306 {
307#ifdef debug
308 G4cout<<"G4QaBPNCS::CalcCS:bLEN nL="<<nL<<",TH="<<THmin<<",dP="<<dP<<G4endl;
309#endif
310 sigma=EquLinearFit(Momentum,nL,THmin,dP,lastLEN);
311#ifdef debugn
312 if(sigma<0.)
313 G4cout<<"G4QaBPNCS::CalcCS: E="<<Momentum<<",T="<<THmin<<",dP="<<dP<<G4endl;
314#endif
315 }
316 else if (Momentum<Pmax) // High Energy region
317 {
318 G4double lP=std::log(Momentum);
319#ifdef debug
320 G4cout<<"G4QaBarPNucCS::CalcCS:before HEN nH="<<nH<<",iE="<<milP<<",dlP="<<dlP<<G4endl;
321#endif
322 sigma=EquLinearFit(lP,nH,milP,dlP,lastHEN);
323 }
324 else // UHE region (calculation, not frequent)
325 {
326 G4double P=0.001*Momentum; // Approximation formula is for P in GeV/c
327 sigma=CrossSectionFormula(targZ, targN, P, std::log(P));
328 }
329#ifdef debug
330 G4cout<<"G4QAntiBaryonPlusNuclearCrossSection::CalcCS: CS="<<sigma<<G4endl;
331#endif
332 if(sigma<0.) return 0.;
333 return sigma;
334}
335
336// Electromagnetic momentum-threshold (in MeV/c)
337G4double G4QAntiBaryonPlusNuclearCrossSection::ThresholdMomentum(G4int tZ, G4int tN)
338{
339 static const G4double third=1./3.;
340 static const G4double prM = G4QPDGCode(2212).GetMass(); // Proton mass in MeV
341 static const G4double pM = G4QPDGCode(3112).GetMass(); // Projectile mass in MeV
342 static const G4double tpM= pM+pM; // Doubled projectile mass (MeV)
343 G4double tA=tZ+tN;
344 if(tZ<.99 || tN<0.) return 0.;
345 G4double dE=tZ/(1.+std::pow(tA,third)); // Safety for diffused edge of the nucleus (QE)
346 G4double tM=931.5*tA;
347 if(tZ==1 && tN==0) tM=prM; // A threshold on the free proton
348 G4double T=dE+dE*(dE/2+pM)/tM;
349 return std::sqrt(T*(tpM+T));
350}
351
352// Calculation formula for piMinus-nuclear inelastic cross-section (mb) (P in GeV/c)
353G4double G4QAntiBaryonPlusNuclearCrossSection::CrossSectionLin(G4int tZ, G4int tN,
354 G4double P)
355{
356 G4double lP=std::log(P);
357 return CrossSectionFormula(tZ, tN, P, lP);
358}
359
360// Calculation formula for piMinus-nuclear inelastic cross-section (mb) log(P in GeV/c)
361G4double G4QAntiBaryonPlusNuclearCrossSection::CrossSectionLog(G4int tZ, G4int tN,
362 G4double lP)
363{
364 G4double P=std::exp(lP);
365 return CrossSectionFormula(tZ, tN, P, lP);
366}
367// Calculation formula for piMinus-nuclear inelastic cross-section (mb) log(P in GeV/c)
368G4double G4QAntiBaryonPlusNuclearCrossSection::CrossSectionFormula(G4int tZ, G4int tN,
369 G4double P, G4double lP)
370{
371 G4double sigma=0.;
372 if(tZ==1 && !tN) // AntiBar-Prot interaction from G4QuasiElRatios
373 {
374 G4double ld=lP-3.5;
375 G4double ld2=ld*ld;
376 G4double ye=std::exp(lP*1.25);
377 G4double yt=std::exp(lP*0.35);
378 G4double El=80./(ye+1.);
379 G4double To=(80./yt+.3)/yt;
380 sigma=(To-El)+.2443*ld2+31.48;
381 }
382 else if(tZ==1 && tN==1)
383 {
384 G4double p2=P*P;
385 G4double p4=p2*p2;
386 G4double r=lP-3.7;
387 sigma=(0.6*r*r+67.+90.*std::exp(-lP*.666))/(1.+4.E-7/p4/p4);
388 }
389 else if(tZ<97 && tN<152) // General solution
390 {
391 G4double d=lP-4.2;
392 G4double sp=std::sqrt(P);
393 G4double p2=P*P;
394 G4double p4=p2*p2;
395 G4double a=tN+tZ; // A of the target
396 G4double sa=std::sqrt(a);
397 G4double a2=a*a;
398 G4double a3=a2*a;
399 G4double a4=a2*a2;
400 G4double a2s=a2*sa;
401 G4double c=(170.+3600./a2s)/(1.+65./a2s)+40.*std::pow(a,0.712)/(1.+12.2/a)/(1.+34./a2);
402 G4double r=(170.+0.01*a3)/(1.+a3/28000.);
403 G4double h=.016*(1.+1.5E-8*a3*a2s)/a4;
404 sigma=(c+d*d+r/sp)/(1.+h/p4/p4);
405#ifdef pdebug
406 G4cout<<"G4QAntiBarPlNucCS::CSForm: A="<<a<<",P="<<P<<",CS="<<sigma<<",c="<<c<<",g="<<g
407 <<",d="<<d<<",r="<<r<<",e="<<e<<",h="<<h<<G4endl;
408#endif
409 }
410 else
411 {
412 G4cerr<<"-Warning-G4QAntiBarPlNuclCroSect::CSForm:*Bad A* Z="<<tZ<<", N="<<tN<<G4endl;
413 sigma=0.;
414 }
415 if(sigma<0.) return 0.;
416 return sigma;
417}
double G4double
Definition: G4Types.hh:64
int G4int
Definition: G4Types.hh:66
bool G4bool
Definition: G4Types.hh:67
#define G4endl
Definition: G4ios.hh:52
G4DLLIMPORT std::ostream G4cerr
G4DLLIMPORT std::ostream G4cout
G4double CalculateCrossSection(G4bool CS, G4int F, G4int I, G4int PDG, G4int Z, G4int N, G4double Momentum)
virtual G4double GetCrossSection(G4bool fCS, G4double pMom, G4int tgZ, G4int tgN, G4int pPDG=-3112)
G4double GetMass()
Definition: G4QPDGCode.cc:693
G4double EquLinearFit(G4double X, G4int N, G4double X0, G4double DX, G4double *Y)
virtual G4double ThresholdEnergy(G4int Z, G4int N, G4int PDG=0)
static G4double tolerance