Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4QPionPlusElasticCrossSection.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$
28//
29//
30// G4 Physics class: G4QPionPlusElasticCrossSection 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 G4QElastic process
36// -------------------------------------------------------------------------------
37
38//#define debug
39//#define isodebug
40//#define pdebug
41//#define ppdebug
42//#define tdebug
43//#define sdebug
44
46#include "G4SystemOfUnits.hh"
47
48// Initialization of the static parameters
49const G4int G4QPionPlusElasticCrossSection::nPoints=128;//#ofPt in AMDB table(>anyPar)(D)
50const G4int G4QPionPlusElasticCrossSection::nLast=nPoints-1;// theLastElement inTheTable(D)
51G4double G4QPionPlusElasticCrossSection::lPMin=-8.; // Min tabulated logarithmMomentum(D)
52G4double G4QPionPlusElasticCrossSection::lPMax= 8.; // Max tabulated logarithmMomentum(D)
53G4double G4QPionPlusElasticCrossSection::dlnP=(lPMax-lPMin)/nLast;// LogStep inTheTable(D)
54G4bool G4QPionPlusElasticCrossSection::onlyCS=true;// Flag toCalcul OnlyCS(not Si/Bi)(L)
55G4double G4QPionPlusElasticCrossSection::lastSIG=0.; // Last calculated cross section (L)
56G4double G4QPionPlusElasticCrossSection::lastLP=-10.;// Last log(mom_of IncidentHadron)(L)
57G4double G4QPionPlusElasticCrossSection::lastTM=0.; // Last t_maximum (L)
58G4double G4QPionPlusElasticCrossSection::theSS=0.; // TheLastSqSlope of 1st difr.Max(L)
59G4double G4QPionPlusElasticCrossSection::theS1=0.; // TheLastMantissa of 1st difr.Max(L)
60G4double G4QPionPlusElasticCrossSection::theB1=0.; // TheLastSlope of 1st difruct.Max(L)
61G4double G4QPionPlusElasticCrossSection::theS2=0.; // TheLastMantissa of 2nd difr.Max(L)
62G4double G4QPionPlusElasticCrossSection::theB2=0.; // TheLastSlope of 2nd difruct.Max(L)
63G4double G4QPionPlusElasticCrossSection::theS3=0.; // TheLastMantissa of 3d difr. Max(L)
64G4double G4QPionPlusElasticCrossSection::theB3=0.; // TheLastSlope of 3d difruct. Max(L)
65G4double G4QPionPlusElasticCrossSection::theS4=0.; // TheLastMantissa of 4th difr.Max(L)
66G4double G4QPionPlusElasticCrossSection::theB4=0.; // TheLastSlope of 4th difruct.Max(L)
67G4int G4QPionPlusElasticCrossSection::lastTZ=0; // Last atomic number of the target
68G4int G4QPionPlusElasticCrossSection::lastTN=0; // Last # of neutrons in the target
69G4double G4QPionPlusElasticCrossSection::lastPIN=0.; // Last initialized max momentum
70G4double* G4QPionPlusElasticCrossSection::lastCST=0; // Elastic cross-section table
71G4double* G4QPionPlusElasticCrossSection::lastPAR=0; // ParametersForFunctionalCalculation
72G4double* G4QPionPlusElasticCrossSection::lastSST=0; // E-dep of SqaredSlope of 1st difMax
73G4double* G4QPionPlusElasticCrossSection::lastS1T=0; // E-dep of mantissa of 1st dif.Max
74G4double* G4QPionPlusElasticCrossSection::lastB1T=0; // E-dep of the slope of 1st difMax
75G4double* G4QPionPlusElasticCrossSection::lastS2T=0; // E-dep of mantissa of 2nd difrMax
76G4double* G4QPionPlusElasticCrossSection::lastB2T=0; // E-dep of the slope of 2nd difMax
77G4double* G4QPionPlusElasticCrossSection::lastS3T=0; // E-dep of mantissa of 3d difr.Max
78G4double* G4QPionPlusElasticCrossSection::lastB3T=0; // E-dep of the slope of 3d difrMax
79G4double* G4QPionPlusElasticCrossSection::lastS4T=0; // E-dep of mantissa of 4th difrMax
80G4double* G4QPionPlusElasticCrossSection::lastB4T=0; // E-dep of the slope of 4th difMax
81G4int G4QPionPlusElasticCrossSection::lastN=0; // The last N of calculated nucleus
82G4int G4QPionPlusElasticCrossSection::lastZ=0; // The last Z of calculated nucleus
83G4double G4QPionPlusElasticCrossSection::lastP=0.; // LastUsed in cross section Momentum
84G4double G4QPionPlusElasticCrossSection::lastTH=0.; // Last threshold momentum
85G4double G4QPionPlusElasticCrossSection::lastCS=0.; // Last value of the Cross Section
86G4int G4QPionPlusElasticCrossSection::lastI=0; // The last position in the DAMDB
87
88std::vector<G4double*> G4QPionPlusElasticCrossSection::PAR;// Vector of pars forFunctCalcul
89std::vector<G4double*> G4QPionPlusElasticCrossSection::CST;// Vector of cross-section table
90std::vector<G4double*> G4QPionPlusElasticCrossSection::SST;// Vector of the 1st SquareSlope
91std::vector<G4double*> G4QPionPlusElasticCrossSection::S1T;// Vector of the 1st mantissa
92std::vector<G4double*> G4QPionPlusElasticCrossSection::B1T;// Vector of the 1st slope
93std::vector<G4double*> G4QPionPlusElasticCrossSection::S2T;// Vector of the 2nd mantissa
94std::vector<G4double*> G4QPionPlusElasticCrossSection::B2T;// Vector of the 2nd slope
95std::vector<G4double*> G4QPionPlusElasticCrossSection::S3T;// Vector of the 3d mantissa
96std::vector<G4double*> G4QPionPlusElasticCrossSection::B3T;// Vector of the 3d slope
97std::vector<G4double*> G4QPionPlusElasticCrossSection::S4T;// Vector of the 4th mantissa(g)
98std::vector<G4double*> G4QPionPlusElasticCrossSection::B4T;// Vector of the 4th slope(glor)
99
101{
102}
103
105{
106 std::vector<G4double*>::iterator pos;
107 for (pos=CST.begin(); pos<CST.end(); pos++)
108 { delete [] *pos; }
109 CST.clear();
110 for (pos=PAR.begin(); pos<PAR.end(); pos++)
111 { delete [] *pos; }
112 PAR.clear();
113 for (pos=SST.begin(); pos<SST.end(); pos++)
114 { delete [] *pos; }
115 SST.clear();
116 for (pos=S1T.begin(); pos<S1T.end(); pos++)
117 { delete [] *pos; }
118 S1T.clear();
119 for (pos=B1T.begin(); pos<B1T.end(); pos++)
120 { delete [] *pos; }
121 B1T.clear();
122 for (pos=S2T.begin(); pos<S2T.end(); pos++)
123 { delete [] *pos; }
124 S2T.clear();
125 for (pos=B2T.begin(); pos<B2T.end(); pos++)
126 { delete [] *pos; }
127 B2T.clear();
128 for (pos=S3T.begin(); pos<S3T.end(); pos++)
129 { delete [] *pos; }
130 S3T.clear();
131 for (pos=B3T.begin(); pos<B3T.end(); pos++)
132 { delete [] *pos; }
133 B3T.clear();
134 for (pos=S4T.begin(); pos<S4T.end(); pos++)
135 { delete [] *pos; }
136 S4T.clear();
137 for (pos=B4T.begin(); pos<B4T.end(); pos++)
138 { delete [] *pos; }
139 B4T.clear();
140}
141
142// Returns Pointer to the G4VQCrossSection class
144{
145 static G4QPionPlusElasticCrossSection theCrossSection;//StaticBody of theQEl CrossSection
146#ifdef pdebug
147 G4cout<<"G4QPiPlElCS::GetCS: PiPlus Elastic pointer is taken"<<G4endl;
148#endif
149 return &theCrossSection;
150}
151
152// The main member function giving the collision cross section (P is in IU, CS is in mb)
153// Make pMom in independent units ! (Now it is MeV)
155 G4int tgZ, G4int tgN, G4int pPDG)
156{
157 static std::vector <G4int> colN; // Vector of N for calculated nuclei (isotops)
158 static std::vector <G4int> colZ; // Vector of Z for calculated nuclei (isotops)
159 static std::vector <G4double> colP; // Vector of last momenta for the reaction
160 static std::vector <G4double> colTH; // Vector of energy thresholds for the reaction
161 static std::vector <G4double> colCS; // Vector of last cross sections for the reaction
162 // ***---*** End of the mandatory Static Definitions of the Associative Memory ***---***
163 G4double pEn=pMom;
164 onlyCS=fCS;
165#ifdef pdebug
166 G4cout<<"G4QPElCS::GetCS:>>> f="<<fCS<<", p="<<pMom<<", Z="<<tgZ<<"("<<lastZ<<") ,N="
167 <<tgN<<"("<<lastN<<"), T="<<pEn<<"("<<lastTH<<")"<<",Sz="<<colN.size()<<G4endl;
168 //CalculateCrossSection(fCS,-27,j,pPDG,lastZ,lastN,pMom); // DUMMY TEST
169#endif
170 if(pPDG!= 211)
171 {
172 G4cout<<"*Warning*G4QPionPlusElCS::GetCS:**> Found pPDG="<<pPDG<<" =--=> CS=0"<<G4endl;
173 //CalculateCrossSection(fCS,-27,j,pPDG,lastZ,lastN,pMom); // DUMMY TEST
174 return 0.; // projectile PDG=0 is a mistake (?!) @@
175 }
176 G4bool in=false; // By default the isotope must be found in the AMDB
177 lastP = 0.; // New momentum history (nothing to compare with)
178 lastN = tgN; // The last N of the calculated nucleus
179 lastZ = tgZ; // The last Z of the calculated nucleus
180 lastI = colN.size(); // Size of the Associative Memory DB in the heap
181 if(lastI) for(G4int i=0; i<lastI; i++) // Loop over proj/tgZ/tgN lines of DB
182 { // The nucleus with projPDG is found in AMDB
183 if(colN[i]==tgN && colZ[i]==tgZ) // Isotope is foind in AMDB
184 {
185 lastI=i;
186 lastTH =colTH[i]; // Last THreshold (A-dependent)
187#ifdef debug
188 G4cout<<"G4QElCS::GetCS:*Found* P="<<pMom<<",Threshold="<<lastTH<<",i="<<i<<G4endl;
189 //CalculateCrossSection(fCS,-27,i,pPDG,lastZ,lastN,pMom); // DUMMY TEST
190#endif
191 if(pEn<=lastTH)
192 {
193#ifdef debug
194 G4cout<<"G4QElCS::GetCS:Found T="<<pEn<<" < Threshold="<<lastTH<<",CS=0"<<G4endl;
195 //CalculateCrossSection(fCS,-27,i,pPDG,lastZ,lastN,pMom); // DUMMY TEST
196#endif
197 return 0.; // Energy is below the Threshold value
198 }
199 lastP =colP [i]; // Last Momentum (A-dependent)
200 lastCS =colCS[i]; // Last CrossSect (A-dependent)
201 // if(std::fabs(lastP/pMom-1.)<tolerance) //VI (do not use tolerance)
202 if(lastP == pMom) // Do not recalculate
203 {
204#ifdef debug
205 G4cout<<"G4QElCS::GetCS:P="<<pMom<<",CS="<<lastCS*millibarn<<G4endl;
206#endif
207 CalculateCrossSection(fCS,-1,i,pPDG,lastZ,lastN,pMom); // Update param's only
208 return lastCS*millibarn; // Use theLastCS
209 }
210 in = true; // This is the case when the isotop is found in DB
211 // Momentum pMom is in IU ! @@ Units
212#ifdef debug
213 G4cout<<"G4QElCS::G:UpdateDB P="<<pMom<<",f="<<fCS<<",I="<<lastI<<",i="<<i<<G4endl;
214#endif
215 lastCS=CalculateCrossSection(fCS,-1,i,pPDG,lastZ,lastN,pMom); // read & update
216#ifdef debug
217 G4cout<<"G4QElCS::GetCrosSec: *****> New (inDB) Calculated CS="<<lastCS<<G4endl;
218 //CalculateCrossSection(fCS,-27,i,pPDG,lastZ,lastN,pMom); // DUMMY TEST
219#endif
220 if(lastCS<=0. && pEn>lastTH) // Correct the threshold
221 {
222#ifdef debug
223 G4cout<<"G4QElCS::GetCS: New T="<<pEn<<"(CS=0) > Threshold="<<lastTH<<G4endl;
224#endif
225 lastTH=pEn;
226 }
227 break; // Go out of the LOOP with found lastI
228 }
229#ifdef debug
230 G4cout<<"---G4QElCrossSec::GetCrosSec:pPDG="<<pPDG<<",i="<<i<<",N="<<colN[i]
231 <<",Z["<<i<<"]="<<colZ[i]<<G4endl;
232 //CalculateCrossSection(fCS,-27,i,pPDG,lastZ,lastN,pMom); // DUMMY TEST
233#endif
234 } // End of attampt to find the nucleus in DB
235 if(!in) // This nucleus has not been calculated previously
236 {
237#ifdef debug
238 G4cout<<"G4QElCS::GetCrosSec:CalcNew P="<<pMom<<",f="<<fCS<<",lastI="<<lastI<<G4endl;
239#endif
240 //!!The slave functions must provide cross-sections in millibarns (mb) !! (not in IU)
241 lastCS=CalculateCrossSection(fCS,0,lastI,pPDG,lastZ,lastN,pMom);//calculate&create
242 if(lastCS<=0.)
243 {
244 lastTH = ThresholdEnergy(tgZ, tgN); // The Threshold Energy which is now the last
245#ifdef debug
246 G4cout<<"G4QElCrossSection::GetCrossSect: NewThresh="<<lastTH<<",T="<<pEn<<G4endl;
247#endif
248 if(pEn>lastTH)
249 {
250#ifdef debug
251 G4cout<<"G4QElCS::GetCS: First T="<<pEn<<"(CS=0) > Threshold="<<lastTH<<G4endl;
252#endif
253 lastTH=pEn;
254 }
255 }
256#ifdef debug
257 G4cout<<"G4QElCS::GetCrosSec: New CS="<<lastCS<<",lZ="<<lastN<<",lN="<<lastZ<<G4endl;
258 //CalculateCrossSection(fCS,-27,lastI,pPDG,lastZ,lastN,pMom); // DUMMY TEST
259#endif
260 colN.push_back(tgN);
261 colZ.push_back(tgZ);
262 colP.push_back(pMom);
263 colTH.push_back(lastTH);
264 colCS.push_back(lastCS);
265#ifdef debug
266 G4cout<<"G4QElCS::GetCS:1st,P="<<pMom<<"(MeV),CS="<<lastCS*millibarn<<"(mb)"<<G4endl;
267 //CalculateCrossSection(fCS,-27,lastI,pPDG,lastZ,lastN,pMom); // DUMMY TEST
268#endif
269 return lastCS*millibarn;
270 } // End of creation of the new set of parameters
271 else
272 {
273#ifdef debug
274 G4cout<<"G4QElCS::GetCS: Update lastI="<<lastI<<G4endl;
275#endif
276 colP[lastI]=pMom;
277 colCS[lastI]=lastCS;
278 }
279#ifdef debug
280 G4cout<<"G4QElCS::GetCrSec:End,P="<<pMom<<"(MeV),CS="<<lastCS*millibarn<<"(mb)"<<G4endl;
281 //CalculateCrossSection(fCS,-27,lastI,pPDG,lastZ,lastN,pMom); // DUMMY TEST
282 G4cout<<"G4QElCS::GetCrSec:***End***, onlyCS="<<onlyCS<<G4endl;
283#endif
284 return lastCS*millibarn;
285}
286
287// Calculation of total elastic cross section (p in IU, CS in mb) @@ Units (?)
288// F=0 - create AMDB, F=-1 - read&update AMDB, F=1 - update AMDB (sinchro with higher AMDB)
290 G4int PDG, G4int tgZ, G4int tgN, G4double pIU)
291{
292 // *** Begin of Associative Memory DB for acceleration of the cross section calculations
293 static std::vector <G4double> PIN; // Vector of max initialized log(P) in the table
294 // *** End of Static Definitions (Associative Memory Data Base) ***
295 G4double pMom=pIU/GeV; // All calculations are in GeV
296 onlyCS=CS; // Flag to calculate only CS (not Si/Bi)
297#ifdef debug
298 G4cout<<"G4QPionPlusElasticCroS::CalcCS:->onlyCS="<<onlyCS<<",F="<<F<<",p="<<pIU<<G4endl;
299#endif
300 lastLP=std::log(pMom); // Make a logarithm of the momentum for calculation
301 if(F) // This isotope was found in AMDB =>RETRIEVE/UPDATE
302 {
303 if(F<0) // the AMDB must be loded
304 {
305 lastPIN = PIN[I]; // Max log(P) initialised for this table set
306 lastPAR = PAR[I]; // Pointer to the parameter set
307 lastCST = CST[I]; // Pointer to the total sross-section table
308 lastSST = SST[I]; // Pointer to the first squared slope
309 lastS1T = S1T[I]; // Pointer to the first mantissa
310 lastB1T = B1T[I]; // Pointer to the first slope
311 lastS2T = S2T[I]; // Pointer to the second mantissa
312 lastB2T = B2T[I]; // Pointer to the second slope
313 lastS3T = S3T[I]; // Pointer to the third mantissa
314 lastB3T = B3T[I]; // Pointer to the rhird slope
315 lastS4T = S4T[I]; // Pointer to the 4-th mantissa
316 lastB4T = B4T[I]; // Pointer to the 4-th slope
317#ifdef debug
318 G4cout<<"G4QElasticCS::CalcCS: DB is updated for I="<<I<<",*,PIN4="<<PIN[4]<<G4endl;
319#endif
320 }
321#ifdef debug
322 G4cout<<"G4QPionPlusElasticCroS::CalcCS:*read*, LP="<<lastLP<<",PIN="<<lastPIN<<G4endl;
323#endif
324 if(lastLP>lastPIN && lastLP<lPMax)
325 {
326 lastPIN=GetPTables(lastLP,lastPIN,PDG,tgZ,tgN);// Can update upper logP-Limit in tabs
327#ifdef debug
328 G4cout<<"G4QElCS::CalcCS:*updated(I)*,LP="<<lastLP<<"<IN["<<I<<"]="<<lastPIN<<G4endl;
329#endif
330 PIN[I]=lastPIN; // Remember the new P-Limit of the tables
331 }
332 }
333 else // This isotope wasn't initialized => CREATE
334 {
335 lastPAR = new G4double[nPoints]; // Allocate memory for parameters of CS function
336 lastPAR[nLast]=0; // Initialization for VALGRIND
337 lastCST = new G4double[nPoints]; // Allocate memory for Tabulated CS function
338 lastSST = new G4double[nPoints]; // Allocate memory for Tabulated first sqaredSlope
339 lastS1T = new G4double[nPoints]; // Allocate memory for Tabulated first mantissa
340 lastB1T = new G4double[nPoints]; // Allocate memory for Tabulated first slope
341 lastS2T = new G4double[nPoints]; // Allocate memory for Tabulated second mantissa
342 lastB2T = new G4double[nPoints]; // Allocate memory for Tabulated second slope
343 lastS3T = new G4double[nPoints]; // Allocate memory for Tabulated third mantissa
344 lastB3T = new G4double[nPoints]; // Allocate memory for Tabulated third slope
345 lastS4T = new G4double[nPoints]; // Allocate memory for Tabulated 4-th mantissa
346 lastB4T = new G4double[nPoints]; // Allocate memory for Tabulated 4-th slope
347#ifdef debug
348 G4cout<<"G4QPionPlusElasticCroS::CalcCS:*ini*,lastLP="<<lastLP<<",min="<<lPMin<<G4endl;
349#endif
350 lastPIN = GetPTables(lastLP,lPMin,PDG,tgZ,tgN); // Returns the new P-limit for tables
351#ifdef debug
352 G4cout<<"G4QPiPlElCS::CCS:i,Z="<<tgZ<<",N="<<tgN<<",PDG="<<PDG<<",LP"<<lastPIN<<G4endl;
353#endif
354 PIN.push_back(lastPIN); // Fill parameters of CS function to AMDB
355 PAR.push_back(lastPAR); // Fill parameters of CS function to AMDB
356 CST.push_back(lastCST); // Fill Tabulated CS function to AMDB
357 SST.push_back(lastSST); // Fill Tabulated first sq.slope to AMDB
358 S1T.push_back(lastS1T); // Fill Tabulated first mantissa to AMDB
359 B1T.push_back(lastB1T); // Fill Tabulated first slope to AMDB
360 S2T.push_back(lastS2T); // Fill Tabulated second mantissa to AMDB
361 B2T.push_back(lastB2T); // Fill Tabulated second slope to AMDB
362 S3T.push_back(lastS3T); // Fill Tabulated third mantissa to AMDB
363 B3T.push_back(lastB3T); // Fill Tabulated third slope to AMDB
364 S4T.push_back(lastS4T); // Fill Tabulated 4-th mantissa to AMDB
365 B4T.push_back(lastB4T); // Fill Tabulated 4-th slope to AMDB
366 } // End of creation/update of the new set of parameters and tables
367 // =-----------= NOW Update (if necessary) and Calculate the Cross Section =----------=
368#ifdef debug
369 G4cout<<"G4QElCS::CalcCS:?update?,LP="<<lastLP<<",IN="<<lastPIN<<",ML="<<lPMax<<G4endl;
370#endif
371 if(lastLP>lastPIN && lastLP<lPMax)
372 {
373 lastPIN = GetPTables(lastLP,lastPIN,PDG,tgZ,tgN);
374#ifdef debug
375 G4cout<<"G4QElCS::CalcCS: *updated(O)*, LP="<<lastLP<<" < IN="<<lastPIN<<G4endl;
376#endif
377 }
378#ifdef debug
379 G4cout<<"G4QElastCS::CalcCS: lastLP="<<lastLP<<",lPM="<<lPMin<<",lPIN="<<lastPIN<<G4endl;
380#endif
381 if(!onlyCS) lastTM=GetQ2max(PDG, tgZ, tgN, pMom); // Calculate (-t)_max=Q2_max (GeV2)
382#ifdef debug
383 G4cout<<"G4QElasticCrosSec::CalcCS:oCS="<<onlyCS<<",-t="<<lastTM<<", p="<<lastLP<<G4endl;
384#endif
385 if(lastLP>lPMin && lastLP<=lastPIN) // Linear fit is made using precalculated tables
386 {
387 if(lastLP==lastPIN)
388 {
389 G4double shift=(lastLP-lPMin)/dlnP+.000001; // Log distance from lPMin
390 G4int blast=static_cast<int>(shift); // this is a bin number of the lower edge (0)
391 if(blast<0 || blast>=nLast) G4cout<<"G4QEleastCS::CCS:b="<<blast<<","<<nLast<<G4endl;
392 lastSIG = lastCST[blast];
393 if(!onlyCS) // Skip the differential cross-section parameters
394 {
395 theSS = lastSST[blast];
396 theS1 = lastS1T[blast];
397 theB1 = lastB1T[blast];
398 theS2 = lastS2T[blast];
399 theB2 = lastB2T[blast];
400 theS3 = lastS3T[blast];
401 theB3 = lastB3T[blast];
402 theS4 = lastS4T[blast];
403 theB4 = lastB4T[blast];
404 }
405#ifdef debug
406 G4cout<<"G4QPionPlusElasticCroS::CalculateCS:(E) S1="<<theS1<<", B1="<<theB1<<G4endl;
407#endif
408 }
409 else
410 {
411 G4double shift=(lastLP-lPMin)/dlnP; // a shift from the beginning of the table
412 G4int blast=static_cast<int>(shift); // the lower bin number
413 if(blast<0) blast=0;
414 if(blast>=nLast) blast=nLast-1; // low edge of the last bin
415 shift-=blast; // step inside the unit bin
416 G4int lastL=blast+1; // the upper bin number
417 G4double SIGL=lastCST[blast]; // the basic value of the cross-section
418 lastSIG= SIGL+shift*(lastCST[lastL]-SIGL); // calculated total elastic cross-section
419#ifdef debug
420 G4cout<<"G4QElCS::CalcCrossSection: Sig="<<lastSIG<<", P="<<pMom<<", Z="<<tgZ<<", N="
421 <<tgN<<", PDG="<<PDG<<", onlyCS="<<onlyCS<<G4endl;
422#endif
423 if(!onlyCS) // Skip the differential cross-section parameters
424 {
425 G4double SSTL=lastSST[blast]; // the low bin of the first squared slope
426 theSS=SSTL+shift*(lastSST[lastL]-SSTL); // the basic value of the first sq.slope
427 G4double S1TL=lastS1T[blast]; // the low bin of the first mantissa
428 theS1=S1TL+shift*(lastS1T[lastL]-S1TL); // the basic value of the first mantissa
429 G4double B1TL=lastB1T[blast]; // the low bin of the first slope
430#ifdef debug
431 G4cout<<"G4QElCS::CalcCrossSection:bl="<<blast<<",ls="<<lastL<<",SL="<<S1TL<<",SU="
432 <<lastS1T[lastL]<<",BL="<<B1TL<<",BU="<<lastB1T[lastL]<<G4endl;
433#endif
434 theB1=B1TL+shift*(lastB1T[lastL]-B1TL); // the basic value of the first slope
435 G4double S2TL=lastS2T[blast]; // the low bin of the second mantissa
436 theS2=S2TL+shift*(lastS2T[lastL]-S2TL); // the basic value of the second mantissa
437 G4double B2TL=lastB2T[blast]; // the low bin of the second slope
438 theB2=B2TL+shift*(lastB2T[lastL]-B2TL); // the basic value of the second slope
439 G4double S3TL=lastS3T[blast]; // the low bin of the third mantissa
440 theS3=S3TL+shift*(lastS3T[lastL]-S3TL); // the basic value of the third mantissa
441#ifdef debug
442 G4cout<<"G4QElCS::CCS: s3l="<<S3TL<<",sh3="<<shift<<",s3h="<<lastS3T[lastL]<<",b="
443 <<blast<<",l="<<lastL<<G4endl;
444#endif
445 G4double B3TL=lastB3T[blast]; // the low bin of the third slope
446 theB3=B3TL+shift*(lastB3T[lastL]-B3TL); // the basic value of the third slope
447 G4double S4TL=lastS4T[blast]; // the low bin of the 4-th mantissa
448 theS4=S4TL+shift*(lastS4T[lastL]-S4TL); // the basic value of the 4-th mantissa
449#ifdef debug
450 G4cout<<"G4QElCS::CCS: s4l="<<S4TL<<",sh4="<<shift<<",s4h="<<lastS4T[lastL]<<",b="
451 <<blast<<",l="<<lastL<<G4endl;
452#endif
453 G4double B4TL=lastB4T[blast]; // the low bin of the 4-th slope
454 theB4=B4TL+shift*(lastB4T[lastL]-B4TL); // the basic value of the 4-th slope
455 }
456#ifdef debug
457 G4cout<<"G4QPionPlusElasticCroS::CalculateCS:(I) S1="<<theS1<<", B1="<<theB1<<G4endl;
458#endif
459 }
460 }
461 else lastSIG=GetTabValues(lastLP, PDG, tgZ, tgN); // Direct calculation beyond the table
462 if(lastSIG<0.) lastSIG = 0.; // @@ a Warning print can be added
463#ifdef debug
464 G4cout<<"G4QPionPlusElasticCrossSection::CalculateCS: END, onlyCS="<<onlyCS<<G4endl;
465#endif
466 return lastSIG;
467}
468
469// It has parameter sets for all tZ/tN/PDG, using them the tables can be created/updated
470G4double G4QPionPlusElasticCrossSection::GetPTables(G4double LP, G4double ILP, G4int PDG,
471 G4int tgZ, G4int tgN)
472{
473 // @@ At present all nA==pA ---------> Each neucleus can have not more than 51 parameters
474 static const G4double pwd=2727;
475 const G4int n_pippel=35; // #of parameters for pip_p-elastic (<nPoints=128)
476 // -0- -1- -2- -3- -4- -5- -6- -7--8--9--10-11-12--13-
477 G4double pipp_el[n_pippel]={1.27,13.,.0676,3.5,.32,.0576,.0557,2.4,6.,3.,.7,5.,74.,3.,
478 3.4,.2,.17,.001,8.,.055,3.64,5.e-5,4000.,1500.,.46,1.2e6,
479 3.5e6,5.e-5,1.e10,8.5e8,1.e10,1.1,3.4e6,6.8e6,0.};
480 // -14--15--16--17--18- -19--20- -21- -22- -23- -24- -25-
481 // -26- -27- -28- -29- -30- -31- -32- -33- -34-
482 if(PDG == 211)
483 {
484 // -- Total pp elastic cross section cs & s1/b1 (main), s2/b2 (tail1), s3/b3 (tail2) --
485 //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|
486 //CS=2.865/p2s/(1+.0022/p2s)+(18.9+.6461*dl1*dl1+9./p)/(1.+.425*lp)/(1.+.4276/p4);
487 // par(0) par(7) par(1) par(2) par(4) par(5) par(6)
488 //dl2=lp-5., s1=(74.+3.*dl2*dl2)/(1+3.4/p4/p)+(.2/p2+17.*p)/(p4+.001*sp),
489 // par(8) par(9) par(10) par(11) par(12)par(13) par(14)
490 // b1=8.*p**.055/(1.+3.64/p3); s2=5.e-5+4000./(p4+1500.*p); b2=.46+1.2e6/(p4+3.5e6/sp);
491 // par(15) par(16) par(17) par(18) par(19) par(20) par(21) par(22) par(23)
492 // s3=5.e-5+1.e10/(p4*p4+8.5e8*p2+1.e10); b3=1.1+3.4e6/(p4+6.8e6); ss=0.
493 // par(24) par(25) par(26) par(27) par(28) par(29) par(30) par(31)
494 //
495 if(lastPAR[nLast]!=pwd) // A unique flag to avoid the repeatable definition
496 {
497 if ( tgZ == 1 && tgN == 0 )
498 {
499 for (G4int ip=0; ip<n_pippel; ip++) lastPAR[ip]=pipp_el[ip]; // PiPlus+P
500 }
501 else
502 {
503 G4double a=tgZ+tgN;
504 G4double sa=std::sqrt(a);
505 G4double ssa=std::sqrt(sa);
506 G4double asa=a*sa;
507 G4double a2=a*a;
508 G4double a3=a2*a;
509 G4double a4=a3*a;
510 G4double a5=a4*a;
511 G4double a6=a4*a2;
512 G4double a7=a6*a;
513 G4double a8=a7*a;
514 G4double a9=a8*a;
515 G4double a10=a5*a5;
516 G4double a12=a6*a6;
517 G4double a14=a7*a7;
518 G4double a16=a8*a8;
519 G4double a17=a16*a;
520 //G4double a20=a16*a4;
521 G4double a32=a16*a16;
522 // Reaction cross-section parameters (pel=peh_fit.f)
523 lastPAR[0]=(.95*sa+2.E5/a16)/(1.+17/a); // p1
524 lastPAR[1]=a/(1./4.4+1./a); // p2
525 lastPAR[2]=.22/std::pow(a,.33); // p3
526 lastPAR[3]=.5*a/(1.+3./a+1800./a8); // p4
527 lastPAR[4]=3.E-4*std::pow(a,.32)/(1.+14./a2); // p5
528 lastPAR[5]=0.; // p6 not used
529 lastPAR[6]=(.55+.001*a2)/(1.+4.E-4*a2); // p7
530 lastPAR[7]=(.0002/asa+4.E-9*a)/(1.+9./a4); // p8
531 lastPAR[8]=0.; // p9 not used
532 // @@ the differential cross-section is parameterized separately for A>6 & A<7
533 if(a<6.5)
534 {
535 G4double a28=a16*a12;
536 // The main pre-exponent (pel_sg)
537 lastPAR[ 9]=4000*a; // p1
538 lastPAR[10]=1.2e7*a8+380*a17; // p2
539 lastPAR[11]=.7/(1.+4.e-12*a16); // p3
540 lastPAR[12]=2.5/a8/(a4+1.e-16*a32); // p4
541 lastPAR[13]=.28*a; // p5
542 lastPAR[14]=1.2*a2+2.3; // p6
543 lastPAR[15]=3.8/a; // p7
544 // The main slope (pel_sl)
545 lastPAR[16]=.01/(1.+.0024*a5); // p1
546 lastPAR[17]=.2*a; // p2
547 lastPAR[18]=9.e-7/(1.+.035*a5); // p3
548 lastPAR[19]=(42.+2.7e-11*a16)/(1.+.14*a); // p4
549 // The main quadratic (pel_sh)
550 lastPAR[20]=2.25*a3; // p1
551 lastPAR[21]=18.; // p2
552 lastPAR[22]=2.4e-3*a8/(1.+2.6e-4*a7); // p3
553 lastPAR[23]=3.5e-36*a32*a8/(1.+5.e-15*a32/a); // p4
554 // The 1st max pre-exponent (pel_qq)
555 lastPAR[24]=1.e5/(a8+2.5e12/a16); // p1
556 lastPAR[25]=8.e7/(a12+1.e-27*a28*a28); // p2
557 lastPAR[26]=.0006*a3; // p3
558 // The 1st max slope (pel_qs)
559 lastPAR[27]=10.+4.e-8*a12*a; // p1
560 lastPAR[28]=.114; // p2
561 lastPAR[29]=.003; // p3
562 lastPAR[30]=2.e-23; // p4
563 // The effective pre-exponent (pel_ss)
564 lastPAR[31]=1./(1.+.0001*a8); // p1
565 lastPAR[32]=1.5e-4/(1.+5.e-6*a12); // p2
566 lastPAR[33]=.03; // p3
567 // The effective slope (pel_sb)
568 lastPAR[34]=a/2; // p1
569 lastPAR[35]=2.e-7*a4; // p2
570 lastPAR[36]=4.; // p3
571 lastPAR[37]=64./a3; // p4
572 // The gloria pre-exponent (pel_us)
573 lastPAR[38]=1.e8*std::exp(.32*asa); // p1
574 lastPAR[39]=20.*std::exp(.45*asa); // p2
575 lastPAR[40]=7.e3+2.4e6/a5; // p3
576 lastPAR[41]=2.5e5*std::exp(.085*a3); // p4
577 lastPAR[42]=2.5*a; // p5
578 // The gloria slope (pel_ub)
579 lastPAR[43]=920.+.03*a8*a3; // p1
580 lastPAR[44]=93.+.0023*a12; // p2
581#ifdef debug
582 G4cout<<"G4QElCS::CalcCS:la "<<lastPAR[38]<<", "<<lastPAR[39]<<", "<<lastPAR[40]
583 <<", "<<lastPAR[42]<<", "<<lastPAR[43]<<", "<<lastPAR[44]<<G4endl;
584#endif
585 }
586 else
587 {
588 G4double p1a10=2.2e-28*a10;
589 G4double r4a16=6.e14/a16;
590 G4double s4a16=r4a16*r4a16;
591 // a24
592 // a36
593 // The main pre-exponent (peh_sg)
594 lastPAR[ 9]=4.5*std::pow(a,1.15); // p1
595 lastPAR[10]=.06*std::pow(a,.6); // p2
596 lastPAR[11]=.6*a/(1.+2.e15/a16); // p3
597 lastPAR[12]=.17/(a+9.e5/a3+1.5e33/a32); // p4
598 lastPAR[13]=(.001+7.e-11*a5)/(1.+4.4e-11*a5); // p5
599 lastPAR[14]=(p1a10*p1a10+2.e-29)/(1.+2.e-22*a12); // p6
600 // The main slope (peh_sl)
601 lastPAR[15]=400./a12+2.e-22*a9; // p1
602 lastPAR[16]=1.e-32*a12/(1.+5.e22/a14); // p2
603 lastPAR[17]=1000./a2+9.5*sa*ssa; // p3
604 lastPAR[18]=4.e-6*a*asa+1.e11/a16; // p4
605 lastPAR[19]=(120./a+.002*a2)/(1.+2.e14/a16); // p5
606 lastPAR[20]=9.+100./a; // p6
607 // The main quadratic (peh_sh)
608 lastPAR[21]=.002*a3+3.e7/a6; // p1
609 lastPAR[22]=7.e-15*a4*asa; // p2
610 lastPAR[23]=9000./a4; // p3
611 // The 1st max pre-exponent (peh_qq)
612 lastPAR[24]=.0011*asa/(1.+3.e34/a32/a4); // p1
613 lastPAR[25]=1.e-5*a2+2.e14/a16; // p2
614 lastPAR[26]=1.2e-11*a2/(1.+1.5e19/a12); // p3
615 lastPAR[27]=.016*asa/(1.+5.e16/a16); // p4
616 // The 1st max slope (peh_qs)
617 lastPAR[28]=.002*a4/(1.+7.e7/std::pow(a-6.83,14)); // p1
618 lastPAR[29]=2.e6/a6+7.2/std::pow(a,.11); // p2
619 lastPAR[30]=11.*a3/(1.+7.e23/a16/a8); // p3
620 lastPAR[31]=100./asa; // p4
621 // The 2nd max pre-exponent (peh_ss)
622 lastPAR[32]=(.1+4.4e-5*a2)/(1.+5.e5/a4); // p1
623 lastPAR[33]=3.5e-4*a2/(1.+1.e8/a8); // p2
624 lastPAR[34]=1.3+3.e5/a4; // p3
625 lastPAR[35]=500./(a2+50.)+3; // p4
626 lastPAR[36]=1.e-9/a+s4a16*s4a16; // p5
627 // The 2nd max slope (peh_sb)
628 lastPAR[37]=.4*asa+3.e-9*a6; // p1
629 lastPAR[38]=.0005*a5; // p2
630 lastPAR[39]=.002*a5; // p3
631 lastPAR[40]=10.; // p4
632 // The effective pre-exponent (peh_us)
633 lastPAR[41]=.05+.005*a; // p1
634 lastPAR[42]=7.e-8/sa; // p2
635 lastPAR[43]=.8*sa; // p3
636 lastPAR[44]=.02*sa; // p4
637 lastPAR[45]=1.e8/a3; // p5
638 lastPAR[46]=3.e32/(a32+1.e32); // p6
639 // The effective slope (peh_ub)
640 lastPAR[47]=24.; // p1
641 lastPAR[48]=20./sa; // p2
642 lastPAR[49]=7.e3*a/(sa+1.); // p3
643 lastPAR[50]=900.*sa/(1.+500./a3); // p4
644#ifdef debug
645 G4cout<<"G4QElCS::CalcCS:ha "<<lastPAR[41]<<", "<<lastPAR[42]<<", "<<lastPAR[43]
646 <<", "<<lastPAR[44]<<", "<<lastPAR[45]<<", "<<lastPAR[46]<<G4endl;
647#endif
648 }
649 // Parameter for lowEnergyNeutrons
650 lastPAR[51]=1.e15+2.e27/a4/(1.+2.e-18*a16);
651 }
652 lastPAR[nLast]=pwd;
653 // and initialize the zero element of the table
654 G4double lp=lPMin; // ln(momentum)
655 G4bool memCS=onlyCS; // ??
656 onlyCS=false;
657 lastCST[0]=GetTabValues(lp, PDG, tgZ, tgN); // Calculate AMDB tables
658 onlyCS=memCS;
659 lastSST[0]=theSS;
660 lastS1T[0]=theS1;
661 lastB1T[0]=theB1;
662 lastS2T[0]=theS2;
663 lastB2T[0]=theB2;
664 lastS3T[0]=theS3;
665 lastB3T[0]=theB3;
666 lastS4T[0]=theS4;
667 lastB4T[0]=theB4;
668#ifdef debug
669 G4cout<<"G4QPionPlusElasticCrossSection::GetPTables:ip=0(init), lp="<<lp<<",S1="
670 <<theS1<<",B1="<<theB1<<",S2="<<theS2<<",B2="<<theB3<<",S3="<<theS3
671 <<",B3="<<theB3<<",S4="<<theS4<<",B4="<<theB4<<G4endl;
672#endif
673 }
674 if(LP>ILP)
675 {
676 G4int ini = static_cast<int>((ILP-lPMin+.000001)/dlnP)+1; // already inited till this
677 if(ini<0) ini=0;
678 if(ini<nPoints)
679 {
680 G4int fin = static_cast<int>((LP-lPMin)/dlnP)+1; // final bin of initialization
681 if(fin>=nPoints) fin=nLast; // Limit of the tabular initialization
682 if(fin>=ini)
683 {
684 G4double lp=0.;
685 for(G4int ip=ini; ip<=fin; ip++) // Calculate tabular CS,S1,B1,S2,B2,S3,B3
686 {
687 lp=lPMin+ip*dlnP; // ln(momentum)
688 G4bool memCS=onlyCS;
689 onlyCS=false;
690 lastCST[ip]=GetTabValues(lp, PDG, tgZ, tgN); // Calculate AMDB tables (ret CS)
691 onlyCS=memCS;
692 lastSST[ip]=theSS;
693 lastS1T[ip]=theS1;
694 lastB1T[ip]=theB1;
695 lastS2T[ip]=theS2;
696 lastB2T[ip]=theB2;
697 lastS3T[ip]=theS3;
698 lastB3T[ip]=theB3;
699 lastS4T[ip]=theS4;
700 lastB4T[ip]=theB4;
701#ifdef debug
702 G4cout<<"G4QPionPlusElasticCrossSection::GetPTables:ip="<<ip<<",lp="<<lp
703 <<",S1="<<theS1<<",B1="<<theB1<<",S2="<<theS2<<",B2="<<theB2<<",S3="
704 <<theS3<<",B3="<<theB3<<",S4="<<theS4<<",B4="<<theB4<<G4endl;
705#endif
706 }
707 return lp;
708 }
709 else G4cout<<"*Warning*G4QPionPlusElasticCrossSection::GetPTables: PDG="<<PDG
710 <<", Z="<<tgZ<<", N="<<tgN<<", i="<<ini<<" > fin="<<fin<<", LP="<<LP
711 <<" > ILP="<<ILP<<" nothing is done!"<<G4endl;
712 }
713 else G4cout<<"*Warning*G4QPionPlusElasticCrossSection::GetPTables: PDG="<<PDG<<", Z="
714 <<tgZ<<", N="<<tgN<<", i="<<ini<<">= max="<<nPoints<<", LP="<<LP
715 <<" > ILP="<<ILP<<", lPMax="<<lPMax<<" nothing is done!"<<G4endl;
716 }
717#ifdef debug
718 else G4cout<<"*Warning*G4QPionPlusElasticCrossSection::GetPTabl:PDG="<<PDG<<", Z="<<tgZ
719 <<", N="<<tgN<<", LP="<<LP<<" <= ILP="<<ILP<<" nothing is done!"<<G4endl;
720#endif
721 }
722 else
723 {
724 // G4cout<<"*Error*G4QPionPlusElasticCrossSection::GetPTables: PDG="<<PDG<<", Z="<<tgZ
725 // <<", N="<<tgN<<", while it is defined only for PDG=211"<<G4endl;
726 // throw G4QException("G4QPionPlusElasticCrossSection::GetPTables:only pipA implemented");
728 ed << "PDG = " << PDG << ", Z = " << tgZ << ", N = " << tgN
729 << ", while it is defined only for PDG=211 (pi+)" << G4endl;
730 G4Exception("G4QPionPlusElasticCrossSection::GetPTables()", "HAD_CHPS_0000",
731 FatalException, ed);
732 }
733 return ILP;
734}
735
736// Returns Q2=-t in independent units (MeV^2) (all internal calculations are in GeV)
738{
739 static const G4double GeVSQ=gigaelectronvolt*gigaelectronvolt;
740 static const G4double third=1./3.;
741 static const G4double fifth=1./5.;
742 static const G4double sevth=1./7.;
743#ifdef tdebug
744 G4cout<<"G4QPiPlElCS::GetExcT: F="<<onlyCS<<",Z="<<tgZ<<",N="<<tgN<<",PDG="<<PDG<<G4endl;
745#endif
746 if(PDG!= 211)G4cout<<"*Warning*G4QPionPlusElasticCrossSection::GetExT:PDG="<<PDG<<G4endl;
747 if(onlyCS)G4cout<<"*Warning*G4QPionPlusElasticCrossSection::GetExchanT:onlyCS=1"<<G4endl;
748 if(lastLP<-4.3) return lastTM*GeVSQ*G4UniformRand();// S-wave for p<14 MeV/c (kinE<.1MeV)
749 G4double q2=0.;
750 if(tgZ==1 && tgN==0) // ===> p+p=p+p
751 {
752#ifdef tdebug
753 G4cout<<"G4QElasticCS::GetExchangeT: TM="<<lastTM<<",S1="<<theS1<<",B1="<<theB1<<",S2="
754 <<theS2<<",B2="<<theB2<<",S3="<<theS3<<",B3="<<theB3<<",GeV2="<<GeVSQ<<G4endl;
755#endif
756 G4double E1=lastTM*theB1;
757 G4double R1=(1.-std::exp(-E1));
758#ifdef tdebug
759 G4double ts1=-std::log(1.-R1)/theB1;
760 G4double ds1=std::fabs(ts1-lastTM)/lastTM;
761 if(ds1>.0001)
762 G4cout<<"*Warning*G4QElCS::GetExT:1p "<<ts1<<"#"<<lastTM<<",d="<<ds1
763 <<",R1="<<R1<<",E1="<<E1<<G4endl;
764#endif
765 G4double E2=lastTM*theB2;
766 G4double R2=(1.-std::exp(-E2*E2*E2));
767#ifdef tdebug
768 G4double ts2=std::pow(-std::log(1.-R2),.333333333)/theB2;
769 G4double ds2=std::fabs(ts2-lastTM)/lastTM;
770 if(ds2>.0001)
771 G4cout<<"*Warning*G4QElCS::GetExT:2p "<<ts2<<"#"<<lastTM<<",d="<<ds2
772 <<",R2="<<R2<<",E2="<<E2<<G4endl;
773#endif
774 G4double E3=lastTM*theB3;
775 G4double R3=(1.-std::exp(-E3));
776#ifdef tdebug
777 G4double ts3=-std::log(1.-R3)/theB3;
778 G4double ds3=std::fabs(ts3-lastTM)/lastTM;
779 if(ds3>.0001)
780 G4cout<<"*Warning*G4QElCS::GetExT:3p "<<ts3<<"#"<<lastTM<<",d="<<ds3
781 <<",R3="<<R1<<",E3="<<E3<<G4endl;
782#endif
783 G4double I1=R1*theS1/theB1;
784 G4double I2=R2*theS2;
785 G4double I3=R3*theS3;
786 G4double I12=I1+I2;
787 G4double rand=(I12+I3)*G4UniformRand();
788 if (rand<I1 )
789 {
790 G4double ran=R1*G4UniformRand();
791 if(ran>1.) ran=1.;
792 q2=-std::log(1.-ran)/theB1;
793 }
794 else if(rand<I12)
795 {
796 G4double ran=R2*G4UniformRand();
797 if(ran>1.) ran=1.;
798 q2=-std::log(1.-ran);
799 if(q2<0.) q2=0.;
800 q2=std::pow(q2,third)/theB2;
801 }
802 else
803 {
804 G4double ran=R3*G4UniformRand();
805 if(ran>1.) ran=1.;
806 q2=-std::log(1.-ran)/theB3;
807 }
808 }
809 else
810 {
811 G4double a=tgZ+tgN;
812#ifdef tdebug
813 G4cout<<"G4QElCS::GetExT: a="<<a<<",t="<<lastTM<<",S1="<<theS1<<",B1="<<theB1<<",SS="
814 <<theSS<<",S2="<<theS2<<",B2="<<theB2<<",S3="<<theS3<<",B3="<<theB3<<",S4="
815 <<theS4<<",B4="<<theB4<<G4endl;
816#endif
817 G4double E1=lastTM*(theB1+lastTM*theSS);
818 G4double R1=(1.-std::exp(-E1));
819 G4double tss=theSS+theSS; // for future solution of quadratic equation (imediate check)
820#ifdef tdebug
821 G4double ts1=-std::log(1.-R1)/theB1;
822 if(std::fabs(tss)>1.e-7) ts1=(std::sqrt(theB1*(theB1+(tss+tss)*ts1))-theB1)/tss;
823 G4double ds1=(ts1-lastTM)/lastTM;
824 if(ds1>.0001)
825 G4cout<<"*Warning*G4QElCS::GetExT:1a "<<ts1<<"#"<<lastTM<<",d="<<ds1
826 <<",R1="<<R1<<",E1="<<E1<<G4endl;
827#endif
828 G4double tm2=lastTM*lastTM;
829 G4double E2=lastTM*tm2*theB2; // power 3 for lowA, 5 for HighA (1st)
830 if(a>6.5)E2*=tm2; // for heavy nuclei
831 G4double R2=(1.-std::exp(-E2));
832#ifdef tdebug
833 G4double ts2=-std::log(1.-R2)/theB2;
834 if(a<6.5)ts2=std::pow(ts2,third);
835 else ts2=std::pow(ts2,fifth);
836 G4double ds2=std::fabs(ts2-lastTM)/lastTM;
837 if(ds2>.0001)
838 G4cout<<"*Warning*G4QElCS::GetExT:2a "<<ts2<<"#"<<lastTM<<",d="<<ds2
839 <<",R2="<<R2<<",E2="<<E2<<G4endl;
840#endif
841 G4double E3=lastTM*theB3;
842 if(a>6.5)E3*=tm2*tm2*tm2; // power 1 for lowA, 7 (2nd) for HighA
843 G4double R3=(1.-std::exp(-E3));
844#ifdef tdebug
845 G4double ts3=-std::log(1.-R3)/theB3;
846 if(a>6.5)ts3=std::pow(ts3,sevth);
847 G4double ds3=std::fabs(ts3-lastTM)/lastTM;
848 if(ds3>.0001)
849 G4cout<<"*Warning*G4QElCS::GetExT:3a "<<ts3<<"#"<<lastTM<<",d="<<ds3
850 <<",R3="<<R3<<",E3="<<E3<<G4endl;
851#endif
852 G4double E4=lastTM*theB4;
853 G4double R4=(1.-std::exp(-E4));
854#ifdef tdebug
855 G4double ts4=-std::log(1.-R4)/theB4;
856 G4double ds4=std::fabs(ts4-lastTM)/lastTM;
857 if(ds4>.0001)
858 G4cout<<"*Warning*G4QElCS::GetExT:4a "<<ts4<<"#"<<lastTM<<",d="<<ds4
859 <<",R4="<<R4<<",E4="<<E4<<G4endl;
860#endif
861 G4double I1=R1*theS1;
862 G4double I2=R2*theS2;
863 G4double I3=R3*theS3;
864 G4double I4=R4*theS4;
865 G4double I12=I1+I2;
866 G4double I13=I12+I3;
867 G4double rand=(I13+I4)*G4UniformRand();
868#ifdef tdebug
869 G4cout<<"G4QElCS::GtExT:1="<<I1<<",2="<<I2<<",3="<<I3<<",4="<<I4<<",r="<<rand<<G4endl;
870#endif
871 if(rand<I1)
872 {
873 G4double ran=R1*G4UniformRand();
874 if(ran>1.) ran=1.;
875 q2=-std::log(1.-ran)/theB1;
876 if(std::fabs(tss)>1.e-7) q2=(std::sqrt(theB1*(theB1+(tss+tss)*q2))-theB1)/tss;
877#ifdef tdebug
878 G4cout<<"G4QElCS::GetExT:Q2="<<q2<<",ss="<<tss/2<<",b1="<<theB1<<",t1="<<ts1<<G4endl;
879#endif
880 }
881 else if(rand<I12)
882 {
883 G4double ran=R2*G4UniformRand();
884 if(ran>1.) ran=1.;
885 q2=-std::log(1.-ran)/theB2;
886 if(q2<0.) q2=0.;
887 if(a<6.5) q2=std::pow(q2,third);
888 else q2=std::pow(q2,fifth);
889#ifdef tdebug
890 G4cout<<"G4QElCS::GetExT: Q2="<<q2<<", r2="<<R2<<", b2="<<theB2<<",t2="<<ts2<<G4endl;
891#endif
892 }
893 else if(rand<I13)
894 {
895 G4double ran=R3*G4UniformRand();
896 if(ran>1.) ran=1.;
897 q2=-std::log(1.-ran)/theB3;
898 if(q2<0.) q2=0.;
899 if(a>6.5) q2=std::pow(q2,sevth);
900#ifdef tdebug
901 G4cout<<"G4QElCS::GetExT:Q2="<<q2<<", r3="<<R2<<", b3="<<theB2<<",t3="<<ts2<<G4endl;
902#endif
903 }
904 else
905 {
906 G4double ran=R4*G4UniformRand();
907 if(ran>1.) ran=1.;
908 q2=-std::log(1.-ran)/theB4;
909 if(a<6.5) q2=lastTM-q2; // u reduced for lightA (starts from 0)
910#ifdef tdebug
911 G4cout<<"G4QElCS::GetExT:Q2="<<q2<<",m="<<lastTM<<",b4="<<theB3<<",t4="<<ts3<<G4endl;
912#endif
913 }
914 }
915 if(q2<0.) q2=0.;
916 if(!(q2>=-1.||q2<=1.)) G4cout<<"*NAN*G4QElasticCrossSect::GetExchangeT: -t="<<q2<<G4endl;
917 if(q2>lastTM)
918 {
919#ifdef tdebug
920 G4cout<<"*Warning*G4QElasticCrossSect::GetExT:-t="<<q2<<">"<<lastTM<<G4endl;
921#endif
922 q2=lastTM;
923 }
924 return q2*GeVSQ;
925}
926
927// Returns B in independent units (MeV^-2) (all internal calculations are in GeV) see ExT
929{
930 static const G4double GeVSQ=gigaelectronvolt*gigaelectronvolt;
931#ifdef tdebug
932 G4cout<<"G4QElasticCS::GetSlope:"<<onlyCS<<", Z="<<tgZ<<",N="<<tgN<<",PDG="<<PDG<<G4endl;
933#endif
934 if(onlyCS)G4cout<<"Warning*G4QPionPlusElasticCrossSection::GetSlope:onlyCS=true"<<G4endl;
935 if(lastLP<-4.3) return 0.; // S-wave for p<14 MeV/c (kinE<.1MeV)
936 if(PDG != 211)
937 {
938 // G4cout<<"*Error*G4QPionPlusElasticCrossSection::GetSlope: PDG="<<PDG<<", Z="<<tgZ
939 // <<", N="<<tgN<<", while it is defined only for PDG=211"<<G4endl;
940 // throw G4QException("G4QPionPlusElasticCrossSection::GetSlope: pipA are implemented");
942 ed << "PDG = " << PDG << ", Z = " << tgZ << ", N = " << tgN
943 << ", while it is defined only for PDG=211 (pi-)" << G4endl;
944 G4Exception("G4QPionPlusElasticCrossSection::GetSlope()", "HAD_CHPS_000",
945 FatalException, ed);
946 }
947 if(theB1<0.) theB1=0.;
948 if(!(theB1>=-1.||theB1<=1.))G4cout<<"*NAN*G4QElasticCrossSect::Getslope:"<<theB1<<G4endl;
949 return theB1/GeVSQ;
950}
951
952// Returns half max(Q2=-t) in independent units (MeV^2)
954{
955 static const G4double HGeVSQ=gigaelectronvolt*gigaelectronvolt/2.;
956 return lastTM*HGeVSQ;
957}
958
959// lastLP is used, so calculating tables, one need to remember and then recover lastLP
960G4double G4QPionPlusElasticCrossSection::GetTabValues(G4double lp, G4int PDG, G4int tgZ,
961 G4int tgN)
962{
963 if(PDG!= 211)G4cout<<"Warning*G4QPionPlusElasticCrossSection::GetTabV:PDG="<<PDG<<G4endl;
964 if(tgZ<0 || tgZ>92)
965 {
966 G4cout<<"*Warning*G4QPionPlusElCS::GetTabValue:(1-92) No isotopes for Z="<<tgZ<<G4endl;
967 return 0.;
968 }
969 G4int iZ=tgZ-1; // Z index
970 if(iZ<0)
971 {
972 iZ=0; // conversion of the neutron target to the proton target
973 tgZ=1;
974 tgN=0;
975 }
976 //if(nN[iZ][0] < 0)
977 //{
978#ifdef isodebug
979 // G4cout<<"*Warning*G4QElasticCS::GetTabValue: No isotopes for Z="<<tgZ<<G4endl;
980#endif
981 // return 0.;
982 //}
983#ifdef debug
984 G4cout<<"G4QElasticCS::GetTabVal: lp="<<lp<<",Z="<<tgZ<<",N="<<tgN<<",PDG="<<PDG<<G4endl;
985#endif
986 G4double p=std::exp(lp); // momentum
987 G4double sp=std::sqrt(p); // sqrt(p)
988 G4double p2=p*p;
989 G4double p3=p2*p;
990 G4double p4=p2*p2;
991 if ( tgZ == 1 && tgN == 0 ) // PiPlus+P
992 {
993 G4double dl2=lp-lastPAR[11];
994 theSS=lastPAR[34];
995 theS1=(lastPAR[12]+lastPAR[13]*dl2*dl2)/(1.+lastPAR[14]/p4/p)+
996 (lastPAR[15]/p2+lastPAR[16]*p)/(p4+lastPAR[17]*sp);
997 theB1=lastPAR[18]*std::pow(p,lastPAR[19])/(1.+lastPAR[20]/p3);
998 theS2=lastPAR[21]+lastPAR[22]/(p4+lastPAR[23]*p);
999 theB2=lastPAR[24]+lastPAR[25]/(p4+lastPAR[26]/sp);
1000 theS3=lastPAR[27]+lastPAR[28]/(p4*p4+lastPAR[29]*p2+lastPAR[30]);
1001 theB3=lastPAR[31]+lastPAR[32]/(p4+lastPAR[33]);
1002 theS4=0.;
1003 theB4=0.;
1004#ifdef tdebug
1005 G4cout<<"G4QElasticCS::GetTableValues:(pp) TM="<<lastTM<<",S1="<<theS1<<",B1="<<theB1
1006 <<",S2="<<theS2<<",B2="<<theB2<<",S3="<<theS1<<",B3="<<theB1<<G4endl;
1007#endif
1008 // Returns the total elastic pip-p cross-section (to avoid spoiling lastSIG)
1009 G4double dl1=lp+lastPAR[0]; // lr
1010 G4double lr2=dl1*dl1; // lr2
1011 G4double dl3=lp-lastPAR[3]; // ld
1012 G4double dl4=lp-lastPAR[4]; // lm
1013 return lastPAR[1]/(lr2+lr2*lr2+lastPAR[2])+(lastPAR[6]*dl3*dl3+lastPAR[7]+
1014 lastPAR[8]/sp)/(1.+lastPAR[9]/p4)+lastPAR[10]/(dl4*dl4+lastPAR[5]);
1015 }
1016 else
1017 {
1018 G4double p5=p4*p;
1019 G4double p6=p5*p;
1020 G4double p8=p6*p2;
1021 G4double p10=p8*p2;
1022 G4double p12=p10*p2;
1023 G4double p16=p8*p8;
1024 //G4double p24=p16*p8;
1025 G4double dl=lp-5.;
1026 G4double a=tgZ+tgN;
1027 G4double pah=std::pow(p,a/2);
1028 G4double pa=pah*pah;
1029 G4double pa2=pa*pa;
1030 if(a<6.5)
1031 {
1032 theS1=lastPAR[9]/(1.+lastPAR[10]*p4*pa)+lastPAR[11]/(p4+lastPAR[12]*p4/pa2)+
1033 (lastPAR[13]*dl*dl+lastPAR[14])/(1.+lastPAR[15]/p2);
1034 theB1=(lastPAR[16]+lastPAR[17]*p2)/(p4+lastPAR[18]/pah)+lastPAR[19];
1035 theSS=lastPAR[20]/(1.+lastPAR[21]/p2)+lastPAR[22]/(p6/pa+lastPAR[23]/p16);
1036 theS2=lastPAR[24]/(pa/p2+lastPAR[25]/p4)+lastPAR[26];
1037 theB2=lastPAR[27]*std::pow(p,lastPAR[28])+lastPAR[29]/(p8+lastPAR[30]/p16);
1038 theS3=lastPAR[31]/(pa*p+lastPAR[32]/pa)+lastPAR[33];
1039 theB3=lastPAR[34]/(p3+lastPAR[35]/p6)+lastPAR[36]/(1.+lastPAR[37]/p2);
1040 theS4=p2*(pah*lastPAR[38]*std::exp(-pah*lastPAR[39])+
1041 lastPAR[40]/(1.+lastPAR[41]*std::pow(p,lastPAR[42])));
1042 theB4=lastPAR[43]*pa/p2/(1.+pa*lastPAR[44]);
1043#ifdef tdebug
1044 G4cout<<"G4QElCS::GetTabV: lA, p="<<p<<",S1="<<theS1<<",B1="<<theB1<<",SS="<<theSS
1045 <<",S2="<<theS2<<",B2="<<theB2<<",S3="<<theS3<<",B3="<<theB3<<",S4="<<theS4
1046 <<",B4="<<theB4<<G4endl;
1047#endif
1048 }
1049 else
1050 {
1051 theS1=lastPAR[9]/(1.+lastPAR[10]/p4)+lastPAR[11]/(p4+lastPAR[12]/p2)+
1052 lastPAR[13]/(p5+lastPAR[14]/p16);
1053 theB1=(lastPAR[15]/p8+lastPAR[19])/(p+lastPAR[16]/std::pow(p,lastPAR[20]))+
1054 lastPAR[17]/(1.+lastPAR[18]/p4);
1055 theSS=lastPAR[21]/(p4/std::pow(p,lastPAR[23])+lastPAR[22]/p4);
1056 theS2=lastPAR[24]/p4/(std::pow(p,lastPAR[25])+lastPAR[26]/p12)+lastPAR[27];
1057 theB2=lastPAR[28]/std::pow(p,lastPAR[29])+lastPAR[30]/std::pow(p,lastPAR[31]);
1058 theS3=lastPAR[32]/std::pow(p,lastPAR[35])/(1.+lastPAR[36]/p12)+
1059 lastPAR[33]/(1.+lastPAR[34]/p6);
1060 theB3=lastPAR[37]/p8+lastPAR[38]/p2+lastPAR[39]/(1.+lastPAR[40]/p8);
1061 theS4=(lastPAR[41]/p4+lastPAR[46]/p)/(1.+lastPAR[42]/p10)+
1062 (lastPAR[43]+lastPAR[44]*dl*dl)/(1.+lastPAR[45]/p12);
1063 theB4=lastPAR[47]/(1.+lastPAR[48]/p)+lastPAR[49]*p4/(1.+lastPAR[50]*p5);
1064#ifdef tdebug
1065 G4cout<<"G4QElCS::GetTabV: hA, p="<<p<<",S1="<<theS1<<",B1="<<theB1<<",SS="<<theSS
1066 <<",S2="<<theS2<<",B2="<<theB2<<",S3="<<theS3<<",B3="<<theB3<<",S4="<<theS4
1067 <<",B4="<<theB4<<G4endl;
1068#endif
1069 }
1070 // Returns the total elastic (n/p)A cross-section (to avoid spoiling lastSIG)
1071#ifdef tdebug
1072 G4cout<<"G4QElCS::GetTabV: PDG="<<PDG<<",P="<<p<<",N="<<tgN<<",Z="<<tgZ<<G4endl;
1073#endif
1074 // p1 p2 p3
1075 return (lastPAR[0]*dl*dl+lastPAR[1])/(1.+lastPAR[2]/p8)+
1076 lastPAR[3]/(p4+lastPAR[4]/p3)+lastPAR[6]/(p4+lastPAR[7]/p4);
1077 // p4 p5 p7 p8
1078 }
1079 return 0.;
1080} // End of GetTableValues
1081
1082// Returns max -t=Q2 (GeV^2) for the momentum pP(GeV) and the target nucleus (tgN,tgZ)
1083G4double G4QPionPlusElasticCrossSection::GetQ2max(G4int PDG, G4int tgZ, G4int tgN,
1084 G4double pP)
1085{
1086 //static const G4double mNeut= G4QPDGCode(2112).GetMass()*.001; // MeV to GeV
1087 static const G4double mPi= G4QPDGCode(211).GetMass()*.001; // pion mass MeV to GeV
1088 //static const G4double mProt= G4QPDGCode(2212).GetMass()*.001; // MeV to GeV
1089 //static const G4double mLamb= G4QPDGCode(3122).GetMass()*.001; // MeV to GeV
1090 //static const G4double mHe3 = G4QPDGCode(2112).GetNuclMass(2,1,0)*.001; // MeV to GeV
1091 //static const G4double mAlph = G4QPDGCode(2112).GetNuclMass(2,2,0)*.001; // MeV to GeV
1092 //static const G4double mDeut = G4QPDGCode(2112).GetNuclMass(1,1,0)*.001; // MeV to GeV
1093 static const G4double mPi2= mPi*mPi;
1094 //static const G4double mProt2= mProt*mProt;
1095 //static const G4double mNeut2= mNeut*mNeut;
1096 //static const G4double mDeut2= mDeut*mDeut;
1097 G4double pP2=pP*pP; // squared momentum of the projectile
1098 if(tgZ || tgN>-1) // ---> pipA
1099 {
1100 G4double mt=G4QPDGCode(90000000+tgZ*1000+tgN).GetMass()*.001; // Target mass in GeV
1101 G4double dmt=mt+mt;
1102 G4double s_value=dmt*std::sqrt(pP2+mPi2)+mPi2+mt*mt; // Mondelstam s
1103 return dmt*dmt*pP2/s_value;
1104 }
1105 else
1106 {
1107 // G4cout<<"*Error*G4QPionPlusElasticCrossSection::GetQ2max:PDG="<<PDG<<", Z="<<tgZ<<",N="
1108 // <<tgN<<", while it is defined only for p projectiles & Z_target>0"<<G4endl;
1109 // throw G4QException("G4QPionPlusElasticCrossSection::GetQ2max: only pipA implemented");
1111 ed << "PDG = " << PDG << ", Z = " << tgZ << ",N = " << tgN
1112 << ", while it is defined only for p projectiles & Z_target>0" << G4endl;
1113 G4Exception("G4QPionPlusElasticCrossSection::GetQ2max()", "HAD_CHPS_0000",
1114 FatalException, ed);
1115 return 0;
1116 }
1117}
@ FatalException
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 G4cout
#define G4UniformRand()
Definition: Randomize.hh:53
G4double GetMass()
Definition: G4QPDGCode.cc:693
G4double CalculateCrossSection(G4bool CS, G4int F, G4int I, G4int pPDG, G4int Z, G4int N, G4double pP)
G4double GetExchangeT(G4int tZ, G4int tN, G4int pPDG)
virtual G4double GetCrossSection(G4bool fCS, G4double pMom, G4int tgZ, G4int tgN, G4int pPDG=2212)
G4double GetSlope(G4int tZ, G4int tN, G4int pPDG)
virtual G4double ThresholdEnergy(G4int Z, G4int N, G4int PDG=0)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
std::ostringstream G4ExceptionDescription
Definition: globals.hh:76