Geant4 10.7.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4ElasticHadrNucleusHE.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// The generator of high energy hadron-nucleus elastic scattering
27// The hadron kinetic energy T > 1 GeV
28// N.Starkov 2003.
29//
30// 19.11.05 The HE elastic scattering on proton is added (N.Starkov)
31// 16.11.06 The low energy boundary is shifted to T = 400 MeV (N.Starkov)
32// 23.11.06 General cleanup, ONQ0=3, use pointer instead of particle name (VI)
33// 02.05.07 Scale sampled t as p^2 (VI)
34// 15.05.07 Redesign and cleanup (V.Ivanchenko)
35// 17.05.07 cleanup (V.Grichine)
36// 19.04.12 Fixed reproducibility violation (A.Ribon)
37// 12.06.12 Fixed warnings of shadowed variables (A.Ribon)
38//
39
42#include "G4SystemOfUnits.hh"
43#include "Randomize.hh"
44#include "G4ios.hh"
45#include "G4ParticleTable.hh"
46#include "G4NucleiProperties.hh"
47#include "G4IonTable.hh"
48#include "G4Proton.hh"
49#include "G4PionPlus.hh"
50#include "G4PionMinus.hh"
51#include "G4NistManager.hh"
54#include "G4Material.hh"
55#include "G4Element.hh"
56#include "G4Log.hh"
57#include "G4Exp.hh"
58
59using namespace std;
60
61const G4int G4ElasticHadrNucleusHE::fHadronCode[] =
62{211,-211,2112,2212,321,-321,130,310,311,-311,
63 3122,3222,3112,3212,3312,3322,3334,
64 -2212,-2112,-3122,-3222,-3112,-3212,-3312,-3322,-3334};
65
66const G4int G4ElasticHadrNucleusHE::fHadronType[] =
67{2,3,6,0,4,5,4,4,4,5,
68 0,0,0,0,0,0,0,
69 1,7,1,1,1,1,1,1,1};
70
71const G4int G4ElasticHadrNucleusHE::fHadronType1[] =
72{3,4,1,0,5,6,5,5,5,6,
73 0,0,0,0,0,0,0,
74 2,2,2,2,2,2,2,2,2};
75
76G4double G4ElasticHadrNucleusHE::fLineF[] = {0.0};
77G4double G4ElasticHadrNucleusHE::fEnergy[] = {0.0};
78G4double G4ElasticHadrNucleusHE::fLowEdgeEnergy[] = {0.0};
79G4double G4ElasticHadrNucleusHE::fBinom[240][240] = {{0.0}};
80
82G4ElasticHadrNucleusHE::fElasticData[NHADRONS][ZMAX] = {{nullptr}};
83
84#ifdef G4MULTITHREADED
85 G4Mutex G4ElasticHadrNucleusHE::elasticMutex = G4MUTEX_INITIALIZER;
86#endif
87
88G4bool G4ElasticHadrNucleusHE::fStoreToFile = false;
89G4bool G4ElasticHadrNucleusHE::fRetrieveFromFile = false;
90
91const G4double invGeV = 1.0/CLHEP::GeV;
92const G4double MbToGeV2 = 2.568;
93const G4double GeV2 = CLHEP::GeV*CLHEP::GeV;
94const G4double invGeV2 = 1.0/GeV2;
95const G4double protonM = CLHEP::proton_mass_c2*invGeV;
97
98///////////////////////////////////////////////////////////////
99
101 G4int Z, G4int A, const G4double* e)
102{
103 G4double massGeV = p->GetPDGMass()*invGeV;
104 G4double mass2GeV2= massGeV*massGeV;
105
106 DefineNucleusParameters(A);
107 G4double limitQ2 = 35./(R1*R1); // (GeV/c)^2
108
110 massA2 = massA*massA;
111 /*
112 G4cout << " G4ElasticData for " << p->GetParticleName()
113 << " Z= " << Z << " A= " << A << " R1= " << R1
114 << " R2= " << R2 << G4endl;
115 */
116 for(G4int kk = 0; kk<NENERGY; ++kk)
117 {
118 G4double elab = e[kk] + massGeV;
119 G4double plab2= e[kk]*(e[kk] + 2.0*massGeV);
120 G4double Q2m = 4.0*plab2*massA2/(mass2GeV2 + massA2 + 2.*massA*elab);
121
122 if(Z == 1 && p == G4Proton::Proton()) { Q2m *= 0.5; }
123
124 maxQ2[kk] = Q2m;
125 /*
126 G4cout << " Ekin= " << e[kk] << " Q2m= " << Q2m
127 << " limitQ2= " << limitQ2 << G4endl;
128 */
129 }
130
131 dQ2 = limitQ2/(G4double)(ONQ2-2);
132}
133
134/////////////////////////////////////////////////////////////////////////
135
136void G4ElasticData::DefineNucleusParameters(G4int A)
137{
138 switch (A) {
139 case 207:
140 case 208:
141 R1 = 20.5;
142 R2 = 15.74;
143 Pnucl = 0.4;
144 Aeff = 0.7;
145 break;
146 case 237:
147 case 238:
148 R1 = 21.7;
149 R2 = 16.5;
150 Pnucl = 0.4;
151 Aeff = 0.7;
152 break;
153 case 90:
154 case 91:
155 R1 = 16.5;
156 R2 = 11.62;
157 Pnucl = 0.4;
158 Aeff = 0.7;
159 break;
160 case 58:
161 case 59:
162 R1 = 15.75;
163 R2 = 9.9;
164 Pnucl = 0.45;
165 Aeff = 0.85;
166 break;
167 case 48:
168 case 47:
169 R1 = 14.0;
170 R2 = 9.26;
171 Pnucl = 0.31;
172 Aeff = 0.75;
173 break;
174 case 40:
175 case 41:
176 R1 = 13.3;
177 R2 = 9.26;
178 Pnucl = 0.31;
179 Aeff = 0.75;
180 break;
181 case 28:
182 case 29:
183 R1 = 12.0;
184 R2 = 7.64;
185 Pnucl = 0.253;
186 Aeff = 0.8;
187 break;
188 case 16:
189 R1 = 10.50;
190 R2 = 5.5;
191 Pnucl = 0.7;
192 Aeff = 0.98;
193 break;
194 case 12:
195 R1 = 9.3936;
196 R2 = 4.63;
197 Pnucl = 0.7;
198 Aeff = 1.0;
199 break;
200 case 11:
201 R1 = 9.0;
202 R2 = 5.42;
203 Pnucl = 0.19;
204 Aeff = 0.9;
205 break;
206 case 9:
207 R1 = 9.9;
208 R2 = 6.5;
209 Pnucl = 0.690;
210 Aeff = 0.95;
211 break;
212 case 4:
213 R1 = 5.3;
214 R2 = 3.7;
215 Pnucl = 0.4;
216 Aeff = 0.75;
217 break;
218 case 1:
219 R1 = 4.5;
220 R2 = 2.3;
221 Pnucl = 0.177;
222 Aeff = 0.9;
223 break;
224 default:
225 R1 = 4.45*G4Exp(G4Log((G4double)(A - 1))*0.309)*0.9;
226 R2 = 2.3 *G4Exp(G4Log((G4double)A)* 0.36);
227
228 if(A < 100 && A > 3) { Pnucl = 0.176 + 0.00275*A; }
229 else { Pnucl = 0.4; }
230 //G4cout<<" Deault: A= "<<A<<" R1 R2 Aeff Pnucl "<<R1<<" "<<R2<<" "
231 // <<Aeff<<" "<<Pnucl<<G4endl;
232
233 if(A >= 100) { Aeff = 0.7; }
234 else if(A < 100 && A > 75) { Aeff = 1.5 - 0.008*A; }
235 else { Aeff = 0.9; }
236 break;
237 }
238 //G4cout<<" Result: A= "<<A<<" R1 R2 Aeff Pnucl "<<R1<<" "<<R2<<" "
239 // <<Aeff<<" "<<Pnucl<<G4endl;
240}
241
242////////////////////////////////////////////////////////////////////
243
245 : G4HadronElastic(name), fDirectory(nullptr), isMaster(false)
246{
247 dQ2 = hMass = hMass2 = hLabMomentum = hLabMomentum2 = HadrEnergy
248 = R1 = R2 = Pnucl = Aeff = HadrTot = HadrSlope = HadrReIm = TotP = DDSect2
249 = DDSect3 = ConstU = Slope1 = Slope2 = Coeff1 = Coeff2
250 = Slope0 = Coeff0 = aAIm = aDIm = Dtot11 = Q2max = 0.0;
251 iHadrCode = iHadron = iHadron1 = 0;
252
253 verboseLevel = 0;
254 ekinLowLimit = 400.0*CLHEP::MeV;
255
256 BoundaryP[0]=9.0; BoundaryTG[0]=5.0;BoundaryTL[0]=0.;
257 BoundaryP[1]=20.0;BoundaryTG[1]=1.5;BoundaryTL[1]=0.;
258 BoundaryP[2]=5.0; BoundaryTG[2]=1.0;BoundaryTL[2]=1.5;
259 BoundaryP[3]=8.0; BoundaryTG[3]=3.0;BoundaryTL[3]=0.;
260 BoundaryP[4]=7.0; BoundaryTG[4]=3.0;BoundaryTL[4]=0.;
261 BoundaryP[5]=5.0; BoundaryTG[5]=2.0;BoundaryTL[5]=0.;
262 BoundaryP[6]=5.0; BoundaryTG[6]=1.5;BoundaryTL[6]=3.0;
263
264 nistManager = G4NistManager::Instance();
265
266 if(fEnergy[0] == 0.0) {
267#ifdef G4MULTITHREADED
268 G4MUTEXLOCK(&elasticMutex);
269 if(fEnergy[0] == 0.0) {
270#endif
271 isMaster = true;
272 Binom();
273 // energy in GeV
274 fEnergy[0] = 0.4;
275 fEnergy[1] = 0.6;
276 fEnergy[2] = 0.8;
277 fEnergy[3] = 1.0;
278 fLowEdgeEnergy[0] = 0.0;
279 fLowEdgeEnergy[1] = 0.5;
280 fLowEdgeEnergy[2] = 0.7;
281 fLowEdgeEnergy[3] = 0.9;
282 G4double f = G4Exp(G4Log(10.)*0.1);
283 G4double e = f*f;
284 for(G4int i=4; i<NENERGY; ++i) {
285 fEnergy[i] = e;
286 fLowEdgeEnergy[i] = e/f;
287 e *= f*f;
288 }
289 if(verboseLevel > 0) {
290 G4cout << "### G4ElasticHadrNucleusHE: energy points in GeV" << G4endl;
291 for(G4int i=0; i<NENERGY; ++i) {
292 G4cout << " " << i << " " << fLowEdgeEnergy[i]
293 << " " << fEnergy[i] << G4endl;
294 }
295 }
296#ifdef G4MULTITHREADED
297 }
298 G4MUTEXUNLOCK(&elasticMutex);
299#endif
300 }
301}
302
303///////////////////////////////////////////////////////////////////
304
305void G4ElasticHadrNucleusHE::ModelDescription(std::ostream& outFile) const
306{
307 outFile << "G4ElasticHadrNucleusHE is a hadron-nucleus elastic scattering\n"
308 << "model developed by N. Starkov which uses a Glauber model\n"
309 << "parameterization to calculate the final state. It is valid\n"
310 << "for all hadrons with incident momentum above 0.4 GeV/c.\n";
311}
312
313///////////////////////////////////////////////////////////////////
314
316{
317 if(isMaster) {
318 for(G4int j = 0; j < NHADRONS; ++j) {
319 for(G4int k = 0; k < ZMAX; ++k) {
320 G4ElasticData* ptr = fElasticData[j][k];
321 if(ptr) {
322 delete ptr;
323 fElasticData[j][k] = nullptr;
324 for(G4int l = j+1; l < NHADRONS; ++l) {
325 if(ptr == fElasticData[l][k]) { fElasticData[l][k] = nullptr; }
326 }
327 }
328 }
329 }
330 delete fDirectory;
331 fDirectory = nullptr;
332 }
333}
334
335///////////////////////////////////////////////////////////////////
336
338{
339 if(!isMaster) { return; }
340 G4ProductionCutsTable* theCoupleTable=
342 size_t numOfCouples = theCoupleTable->GetTableSize();
343
344 for(G4int i=0; i<2; ++i) {
346 if(1 == i) { p = G4PionMinus::PionMinus(); }
347 iHadrCode = fHadronCode[i];
348 iHadron = fHadronType[i];
349 iHadron1 = fHadronType1[i];
350 hMass = p->GetPDGMass()*invGeV;
351 hMass2 = hMass*hMass;
352 for(size_t j=0; j<numOfCouples; ++j) {
353 auto mat = theCoupleTable->GetMaterialCutsCouple(j)->GetMaterial();
354 auto elmVec = mat->GetElementVector();
355 size_t numOfElem = mat->GetNumberOfElements();
356 for(size_t k=0; k<numOfElem; ++k) {
357 G4int Z = std::min((*elmVec)[k]->GetZasInt(), ZMAX-1);
358 if(!fElasticData[i][Z]) {
359 if(1 == i && Z > 1) {
360 fElasticData[1][Z] = fElasticData[0][Z];
361 } else {
362 FillData(p, i, Z);
363 }
364 }
365 }
366 }
367 }
368}
369
370////////////////////////////////////////////////////////////////////
371
374 G4double inLabMom,
375 G4int iZ, G4int A)
376{
377 G4double mass = p->GetPDGMass();
378 G4double kine = sqrt(inLabMom*inLabMom + mass*mass) - mass;
379 if(kine <= ekinLowLimit) {
380 return G4HadronElastic::SampleInvariantT(p,inLabMom,iZ,A);
381 }
382 G4int Z = std::min(iZ,ZMAX-1);
383 G4double Q2 = 0.0;
384 iHadrCode = p->GetPDGEncoding();
385
386 // below computations in GeV/c
387 hMass = mass*invGeV;
388 hMass2 = hMass*hMass;
389 G4double plab = inLabMom*invGeV;
391
392 if(verboseLevel > 1) {
393 G4cout<< "G4ElasticHadrNucleusHE::SampleT: "
394 << " for " << p->GetParticleName()
395 << " at Z= " << Z << " A= " << A
396 << " plab(GeV)= " << plab
397 << " hadrCode= " << iHadrCode
398 << G4endl;
399 }
400 iHadron = -1;
401 G4int idx;
402 for(idx=0; idx<NHADRONS; ++idx) {
403 if(iHadrCode == fHadronCode[idx]) {
404 iHadron = fHadronType[idx];
405 iHadron1 = fHadronType1[idx];
406 break;
407 }
408 }
409 // Hadron is not in the list
410 if(0 > iHadron) { return 0.0; }
411
412 if(Z==1) {
413 Q2 = HadronProtonQ2(plab, tmax);
414
415 if (verboseLevel>1) {
416 G4cout<<" Proton : Q2 "<<Q2<<G4endl;
417 }
418 } else {
419 const G4ElasticData* ElD1 = fElasticData[idx][Z];
420
421 // Construct elastic data
422 if(!ElD1) {
423 FillData(p, idx, Z);
424 ElD1 = fElasticData[idx][Z];
425 if(!ElD1) { return 0.0; }
426 }
427
428 // sample scattering
429 Q2 = HadronNucleusQ2_2(ElD1, plab, tmax);
430
431 if(verboseLevel > 1) {
432 G4cout<<" SampleT: Q2(GeV^2)= "<<Q2<< " t/tmax= "
433 << Q2/tmax <<G4endl;
434 }
435 }
436 return Q2*GeV2;
437}
438
439////////////////////////////////////////////////////////////////
440
441void G4ElasticHadrNucleusHE::FillData(const G4ParticleDefinition* p,
442 G4int idx, G4int Z)
443{
444#ifdef G4MULTITHREADED
445 G4MUTEXLOCK(&elasticMutex);
446 if(!fElasticData[idx][Z]) {
447#endif
448 G4int A = G4lrint(nistManager->GetAtomicMassAmu(Z));
449 G4ElasticData* pElD = new G4ElasticData(p, Z, A, fEnergy);
450 if(fRetrieveFromFile) {
451 std::ostringstream ss;
452 InFileName(ss, p, Z);
453 std::ifstream infile(ss.str(), std::ios::in);
454 for(G4int i=0; i<NENERGY; ++i) {
455 if(ReadLine(infile, pElD->fCumProb[i])) {
456 continue;
457 } else {
458 fRetrieveFromFile = false;
459 break;
460 }
461 }
462 infile.close();
463 }
464 R1 = pElD->R1;
465 R2 = pElD->R2;
466 Aeff = pElD->Aeff;
467 Pnucl = pElD->Pnucl;
468 dQ2 = pElD->dQ2;
469 if(verboseLevel > 0) {
470 G4cout<<"### FillData for " << p->GetParticleName()
471 << " Z= " << Z << " idx= " << idx << " iHadron= " << iHadron
472 <<" iHadron1= " << iHadron1 << " iHadrCode= " << iHadrCode
473 <<"\n R1= " << R1 << " R2= " << R2 << " Aeff= " << Aeff
474 <<" Pnucl= " << Pnucl << G4endl;
475 }
476
477 if(!fRetrieveFromFile) {
478 for(G4int i=0; i<NENERGY; ++i) {
479 G4double T = fEnergy[i];
480 hLabMomentum2 = T*(T + 2.*hMass);
481 hLabMomentum = std::sqrt(hLabMomentum2);
482 HadrEnergy = hMass + T;
483 DefineHadronValues(Z);
484 Q2max = pElD->maxQ2[i];
485
486 G4int length = FillFq2(A);
487 (pElD->fCumProb[i]).reserve(length);
488 G4double norm = 1.0/fLineF[length-1];
489
490 if(verboseLevel > 0) {
491 G4cout << "### i= " << i << " Z= " << Z << " A= " << A
492 << " length= " << length << " Q2max= " << Q2max << G4endl;
493 }
494
495 (pElD->fCumProb[i]).push_back(0.0);
496 for(G4int ii=1; ii<length-1; ++ii) {
497 (pElD->fCumProb[i]).push_back(fLineF[ii]*norm);
498 if(verboseLevel > 2) {
499 G4cout << " ii= " << ii << " val= "
500 << (pElD->fCumProb[i])[ii] << G4endl;
501 }
502 }
503 (pElD->fCumProb[i]).push_back(1.0);
504 }
505 }
506
507 if(fStoreToFile) {
508 std::ostringstream ss;
509 OutFileName(ss, p, Z);
510 std::ofstream fileout(ss.str());
511 for(G4int i=0; i<NENERGY; ++i) {
512 WriteLine(fileout, pElD->fCumProb[i]);
513 }
514 fileout.close();
515 }
516
517 if(verboseLevel > 0) {
518 G4cout << " G4ElasticHadrNucleusHE::FillData done for idx= " << idx
519 << " for " << p->GetParticleName() << " Z= " << Z
520 << " A= " << A << G4endl;
521 }
522 fElasticData[idx][Z] = pElD;
523
524#ifdef G4MULTITHREADED
525 }
526 G4MUTEXUNLOCK(&elasticMutex);
527#endif
528}
529
530////////////////////////////////////////////////////////////////
531
532void G4ElasticHadrNucleusHE::InterpolateHN(G4int n, const G4double EnP[],
533 const G4double C0P[], const G4double C1P[],
534 const G4double B0P[], const G4double B1P[])
535{
536 G4int i;
537
538 for(i=1; i<n; ++i) { if(hLabMomentum <= EnP[i]) { break; } }
539 if(i == n) { i = n - 1; }
540
541 Coeff0 = LineInterpol(EnP[i], EnP[i-1], C0P[i], C0P[i-1], hLabMomentum);
542 Coeff1 = LineInterpol(EnP[i], EnP[i-1], C1P[i], C1P[i-1], hLabMomentum);
543 Slope0 = LineInterpol(EnP[i], EnP[i-1], B0P[i], B0P[i-1], hLabMomentum);
544 Slope1 = LineInterpol(EnP[i], EnP[i-1], B1P[i], B1P[i-1], hLabMomentum);
545
546// G4cout<<" InterpolHN: n i "<<n<<" "<<i<<" Mom "
547// <<hLabMomentum<<G4endl;
548}
549
550//////////////////////////////////////////////////////////////////////////
551
553G4ElasticHadrNucleusHE::HadronNucleusQ2_2(const G4ElasticData* pElD,
554 G4double plab, G4double tmax)
555{
556 G4double ekin = std::sqrt(hMass2 + plab*plab) - hMass;
557
558 if(verboseLevel > 1) {
559 G4cout<<"Q2_2: ekin(GeV)= " << ekin << " plab(GeV/c)= " << plab
560 <<" tmax(GeV2)= " << tmax <<G4endl;
561 }
562 // Find closest energy bin
563 G4int idx;
564 for(idx=0; idx<NENERGY-1; ++idx) {
565 if(ekin <= fLowEdgeEnergy[idx+1]) { break; }
566 }
567 //G4cout << " idx= " << idx << G4endl;
568
569 // Select kinematics for node energy
570 R1 = pElD->R1;
571 dQ2 = pElD->dQ2;
572 Q2max = pElD->maxQ2[idx];
573 G4int length = (pElD->fCumProb[idx]).size();
574
575 G4double Rand = G4UniformRand();
576
577 G4int iNumbQ2 = 0;
578 for(iNumbQ2=1; iNumbQ2<length; ++iNumbQ2) {
579 if(Rand <= (pElD->fCumProb[idx])[iNumbQ2]) { break; }
580 }
581 iNumbQ2 = std::min(iNumbQ2, length - 1);
582 G4double Q2 = GetQ2_2(iNumbQ2, length, pElD->fCumProb[idx], Rand);
583 Q2 = std::min(Q2, Q2max);
584 Q2 *= tmax/Q2max;
585
586 if(verboseLevel > 1) {
587 G4cout<<" HadrNucleusQ2_2(2): Q2= "<<Q2<<" iNumbQ2= " << iNumbQ2
588 << " rand= " << Rand << " Q2max= " << Q2max
589 << " tmax= " << tmax << G4endl;
590 }
591 return Q2;
592}
593
594///////////////////////////////////////////////////////////////////////
595//
596// The randomization of one dimensional array
597//
598
599G4double G4ElasticHadrNucleusHE::GetQ2_2(G4int kk, G4int kmax,
600 const std::vector<G4double>& F,
601 G4double ranUni)
602{
603 //G4cout << "GetQ2_2 kk= " << kk << " kmax= " << kmax << " size= "
604 // << F.size() << " rand= " << ranUni << G4endl;
605 if(kk == kmax-1) {
606 G4double X1 = dQ2*kk;
607 G4double F1 = F[kk-1];
608 G4double X2 = Q2max;
609 G4double xx = R1*(X2 - X1);
610 xx = (xx > 20.) ? 0.0 : G4Exp(-xx);
611 G4double Y = X1 - G4Log(1.0 - (ranUni - F1)*(1.0 - xx)/(1.0 - F1))/R1;
612 return Y;
613 }
614 G4double F1, F2, F3, X1, X2, X3;
615
616 if(kk == 1 || kk == 0) {
617 F1 = F[0];
618 F2 = F[1];
619 F3 = F[2];
620 X1 = 0.0;
621 X2 = dQ2;
622 X3 = dQ2*2;
623 } else {
624 F1 = F[kk-2];
625 F2 = F[kk-1];
626 F3 = F[kk];
627 X1 = dQ2*(kk-2);
628 X2 = dQ2*(kk-1);
629 X3 = dQ2*kk;
630 }
631 if(verboseLevel > 1) {
632 G4cout << "GetQ2_2 kk= " << kk << " X2= " << X2 << " X3= " << X3
633 << " F2= " << F2 << " F3= " << F3 << " Rndm= " << ranUni << G4endl;
634 }
635
636 G4double F12 = F1*F1;
637 G4double F22 = F2*F2;
638 G4double F32 = F3*F3;
639
640 G4double D0 = F12*F2+F1*F32+F3*F22-F32*F2-F22*F1-F12*F3;
641
642 if(verboseLevel > 2) {
643 G4cout << " X1= " << X1 << " F1= " << F1 << " D0= "
644 << D0 << G4endl;
645 }
646 G4double Y;
647 if(std::abs(D0) < 1.e-9) {
648 Y = X2 + (ranUni - F2)*(X3 - X2)/(F3 - F2);
649 } else {
650 G4double DA = X1*F2+X3*F1+X2*F3-X3*F2-X1*F3-X2*F1;
651 G4double DB = X2*F12+X1*F32+X3*F22-X2*F32-X3*F12-X1*F22;
652 G4double DC = X3*F2*F12+X2*F1*F32+X1*F3*F22
653 -X1*F2*F32-X2*F3*F12-X3*F1*F22;
654 Y = (DA*ranUni*ranUni + DB*ranUni + DC)/D0;
655 }
656 return Y;
657}
658
659////////////////////////////////////////////////////////////////////////
660
661G4int G4ElasticHadrNucleusHE::FillFq2(G4int A)
662{
663 G4double curQ2, curSec;
664 G4double curSum = 0.0;
665 G4double totSum = 0.0;
666
667 G4double ddQ2 = dQ2*0.1;
668 G4double Q2l = 0.0;
669
670 G4int ii = 0;
671 for(ii=1; ii<ONQ2-1; ++ii) {
672 curSum = curSec = 0.0;
673
674 for(G4int jj=0; jj<10; ++jj) {
675 curQ2 = Q2l+(jj + 0.5)*ddQ2;
676 if(curQ2 >= Q2max) { break; }
677 curSec = HadrNucDifferCrSec(A, curQ2);
678 curSum += curSec;
679 }
680 G4double del = (curQ2 >= Q2max) ? Q2max - Q2l : dQ2;
681 Q2l += del;
682 curSum *= del*0.1;
683 totSum += curSum;
684 fLineF[ii] = totSum;
685 if (verboseLevel>2) {
686 G4cout<<ii << ". FillFq2: A= " << A << " Q2= "<<Q2l<<" dQ2= "
687 <<dQ2<<" Tot= "<<totSum << " dTot " <<curSum
688 <<" curSec= " <<curSec<<G4endl;
689 }
690 if(totSum*1.e-4 > curSum || Q2l >= Q2max) { break; }
691 }
692 ii = std::min(ii, ONQ2-2);
693 curQ2 = Q2l;
694 G4double xx = R1*(Q2max - curQ2);
695 if(xx > 0.0) {
696 xx = (xx > 20.) ? 0.0 : G4Exp(-xx);
697 curSec = HadrNucDifferCrSec(A, curQ2);
698 totSum += curSec*(1.0 - xx)/R1;
699 }
700 fLineF[ii + 1] = totSum;
701 if (verboseLevel>1) {
702 G4cout << "### FillFq2 done curQ2= " << curQ2 << " Q2max= "<< Q2max
703 << " sumG= " << fLineF[ONQ2-2] << " totSum= " << totSum
704 << " Nbins= " << ii + 1 << G4endl;
705 }
706 return ii + 2;
707}
708
709////////////////////////////////////////////////////////////////////////
710
711G4double G4ElasticHadrNucleusHE::GetLightFq2(G4int Z, G4int A, G4double Q2)
712{
713 // Scattering off proton
714 if(Z == 1)
715 {
716 G4double SqrQ2 = std::sqrt(Q2);
717 G4double valueConstU = 2.*(hMass2 + protonM2) - Q2;
718
719 G4double y = (1.-Coeff1-Coeff0)/HadrSlope*(1.-G4Exp(-HadrSlope*Q2))
720 + Coeff0*(1.-G4Exp(-Slope0*Q2))
721 + Coeff2/Slope2*G4Exp(Slope2*valueConstU)*(G4Exp(Slope2*Q2)-1.)
722 + 2.*Coeff1/Slope1*(1./Slope1-(1./Slope1+SqrQ2)*G4Exp(-Slope1*SqrQ2));
723
724 return y;
725 }
726
727 // The preparing of probability function
728
729 G4double prec = A > 208 ? 1.0e-7 : 1.0e-6;
730
731 G4double Stot = HadrTot*MbToGeV2; // Gev^-2
732 G4double Bhad = HadrSlope; // GeV^-2
733 G4double Asq = 1+HadrReIm*HadrReIm;
734 G4double Rho2 = std::sqrt(Asq);
735
736 if(verboseLevel >1) {
737 G4cout<<" Fq2 Before for i Tot B Im "<<HadrTot<<" "<<HadrSlope<<" "
738 <<HadrReIm<<G4endl;
739 }
740 if(verboseLevel > 1) {
741 G4cout << "GetFq2: Stot= " << Stot << " Bhad= " << Bhad
742 <<" Im "<<HadrReIm
743 << " Asq= " << Asq << G4endl;
744 G4cout << "R1= " << R1 << " R2= " << R2 << " Pnucl= " << Pnucl <<G4endl;
745 }
746 G4double R12 = R1*R1;
747 G4double R22 = R2*R2;
748 G4double R12B = R12+2*Bhad;
749 G4double R22B = R22+2*Bhad;
750
751 G4double Norm = (R12*R1-Pnucl*R22*R2); // HP->Aeff;
752
753 G4double R13 = R12*R1/R12B;
754 G4double R23 = Pnucl*R22*R2/R22B;
755 G4double Unucl = Stot/twopi*R13/Norm;
756 G4double UnucRho2 = -Unucl*Rho2;
757
758 G4double FiH = std::asin(HadrReIm/Rho2);
759 G4double NN2 = R23/R13;
760
761 if(verboseLevel > 2) {
762 G4cout << "UnucRho2= " << UnucRho2 << " FiH= " << FiH << " NN2= " << NN2
763 << " Norm= " << Norm << G4endl;
764 }
765 G4double Prod0 = 0.;
766 G4double N1 = -1.0;
767
768 for(G4int i1 = 1; i1<= A; ++i1) ////++++++++++ i1
769 {
770 N1 *= (-Unucl*Rho2*(A-i1+1)/(G4double)i1);
771 G4double Prod1 = 0.;
772 G4double N2 = -1.;
773
774 for(G4int i2 = 1; i2<=A; ++i2) ////+++++++++ i2
775 {
776 N2 *= (-Unucl*Rho2*(A-i2+1)/(G4double)i2);
777 G4double Prod2 = 0;
778 G4double N5 = -1/NN2;
779 for(G4int j2=0; j2<= i2; ++j2) ////+++++++++ j2
780 {
781 G4double Prod3 = 0;
782 G4double exp2 = 1./((G4double)j2/R22B+(G4double)(i2-j2)/R12B);
783 N5 *= (-NN2);
784 G4double N4 = -1./NN2;
785 for(G4int j1=0; j1<=i1; ++j1) ////++++++++ j1
786 {
787 G4double exp1 = 1./((G4double)j1/R22B+(G4double)(i1-j1)/R12B);
788 G4double dddd = 0.25*(exp1+exp2);
789 N4 *= (-NN2);
790 Prod3 +=
791 N4*exp1*exp2*(1.-G4Exp(-Q2*dddd))*GetBinomCof(i1,j1)/dddd;
792 } // j1
793 Prod2 += Prod3*N5*GetBinomCof(i2,j2);
794 } // j2
795 Prod1 += Prod2*N2*std::cos(FiH*(i1-i2));
796
797 if (std::abs(Prod2*N2/Prod1)<prec) break;
798 } // i2
799 Prod0 += Prod1*N1;
800 if(std::abs(N1*Prod1/Prod0) < prec) break;
801 } // i1
802
803 const G4double fact = 0.25*CLHEP::pi/MbToGeV2;
804 Prod0 *= fact; // This is in mb
805
806 if(verboseLevel>1) {
807 G4cout << "GetLightFq2 Z= " << Z << " A= " << A
808 <<" Q2= " << Q2 << " Res= " << Prod0 << G4endl;
809 }
810 return Prod0;
811}
812
813///////////////////////////////////////////////////////////////////
814
816G4ElasticHadrNucleusHE::HadrNucDifferCrSec(G4int A, G4double aQ2)
817{
818 // ------ All external kinematical variables are in MeV -------
819 // ------ but internal in GeV !!!! ------
820
821 // Scattering of proton
822 if(A == 1)
823 {
824 G4double SqrQ2 = std::sqrt(aQ2);
825 G4double valueConstU = hMass2 + protonM2-2*protonM*HadrEnergy - aQ2;
826
827 BoundaryTL[0] = Q2max;
828 BoundaryTL[1] = Q2max;
829 BoundaryTL[3] = Q2max;
830 BoundaryTL[4] = Q2max;
831 BoundaryTL[5] = Q2max;
832
833 G4double dSigPodT = HadrTot*HadrTot*(1+HadrReIm*HadrReIm)*
834 ( Coeff1*G4Exp(-Slope1*SqrQ2)+
835 Coeff2*G4Exp( Slope2*(valueConstU)+aQ2)+
836 (1-Coeff1-Coeff0)*G4Exp(-HadrSlope*aQ2)+
837 Coeff0*G4Exp(-Slope0*aQ2) )*2.568/(16*pi);
838
839 return dSigPodT;
840 }
841
842 G4double Stot = HadrTot*MbToGeV2;
843 G4double Bhad = HadrSlope;
844 G4double Asq = 1+HadrReIm*HadrReIm;
845 G4double Rho2 = std::sqrt(Asq);
846 G4double R12 = R1*R1;
847 G4double R22 = R2*R2;
848 G4double R12B = R12+2*Bhad;
849 G4double R22B = R22+2*Bhad;
850 G4double R12Ap = R12+20;
851 G4double R22Ap = R22+20;
852 G4double R13Ap = R12*R1/R12Ap;
853 G4double R23Ap = R22*R2*Pnucl/R22Ap;
854 G4double R23dR13 = R23Ap/R13Ap;
855 G4double R12Apd = 2/R12Ap;
856 G4double R22Apd = 2/R22Ap;
857 G4double R12ApdR22Ap = 0.5*(R12Apd+R22Apd);
858
859 G4double DDSec1p = (DDSect2+DDSect3*G4Log(0.53*HadrEnergy/R1));
860 G4double DDSec2p = (DDSect2+DDSect3*G4Log(0.53*HadrEnergy/
861 std::sqrt((R12+R22)*0.5)));
862 G4double DDSec3p = (DDSect2+DDSect3*G4Log(0.53*HadrEnergy/R2));
863
864 G4double Norm = (R12*R1-Pnucl*R22*R2)*Aeff;
865 G4double R13 = R12*R1/R12B;
866 G4double R23 = Pnucl*R22*R2/R22B;
867 G4double Unucl = Stot/(twopi*Norm)*R13;
868 G4double UnuclScr = Stot/(twopi*Norm)*R13Ap;
869 G4double SinFi = HadrReIm/Rho2;
870 G4double FiH = std::asin(SinFi);
871 G4double N = -1;
872 G4double N2 = R23/R13;
873
874 G4double ImElasticAmpl0 = 0;
875 G4double ReElasticAmpl0 = 0;
876 G4double Tot1=0, exp1;
877
878 for(G4int i=1; i<=A; ++i) {
879 N *= (-Unucl*Rho2*(A-i+1)/(G4double)i);
880 G4double N4 = 1;
881 G4double medTot = R12B/(G4double)i;
882 G4double Prod1 = G4Exp(-aQ2*R12B/(G4double)(4*i))*medTot;
883
884 for(G4int l=1; l<=i; ++l) {
885 exp1 = l/R22B+(i-l)/R12B;
886 N4 *= (-N2*(i-l+1)/(G4double)l);
887 G4double expn4 = N4/exp1;
888 Prod1 += expn4*G4Exp(-aQ2/(exp1*4));
889 medTot += expn4;
890 } // end l
891
892 G4double dcos = N*std::cos(FiH*i);
893 ReElasticAmpl0 += Prod1*N*std::sin(FiH*i);
894 ImElasticAmpl0 += Prod1*dcos;
895 Tot1 += medTot*dcos;
896 if(std::abs(Prod1*N/ImElasticAmpl0) < 0.000001) break;
897 } // i
898
899 static const G4double pi25 = CLHEP::pi/2.568;
900 ImElasticAmpl0 *= pi25; // The amplitude in mB
901 ReElasticAmpl0 *= pi25; // The amplitude in mB
902 Tot1 *= 2*pi25;
903
904 G4double C1 = R13Ap*R13Ap*0.5*DDSec1p;
905 G4double C2 = 2*R23Ap*R13Ap*0.5*DDSec2p;
906 G4double C3 = R23Ap*R23Ap*0.5*DDSec3p;
907
908 G4double N1p = 1;
909 G4double Din1 = 0.5*(C1*G4Exp(-aQ2/8*R12Ap)/2*R12Ap-
910 C2/R12ApdR22Ap*G4Exp(-aQ2/(4*R12ApdR22Ap))+
911 C3*R22Ap/2*G4Exp(-aQ2/8*R22Ap));
912
913 G4double DTot1 = 0.5*(C1*0.5*R12Ap-C2/R12ApdR22Ap+C3*R22Ap*0.5);
914
915 for(G4int i=1; i<= A-2; ++i) {
916 N1p *= (-UnuclScr*Rho2*(A-i-1)/(G4double)i);
917 G4double N2p = 1;
918 G4double Din2 = 0;
919 G4double DmedTot = 0;
920 G4double BinCoeff = 1.0;
921 for(G4int l=0; l<=i; ++l) {
922 if(l > 0) { BinCoeff *= (i-l+1)/(G4double)l; }
923
924 exp1 = l/R22B+(i-l)/R12B;
925 G4double exp1p = exp1+R12Apd;
926 G4double exp2p = exp1+R12ApdR22Ap;
927 G4double exp3p = exp1+R22Apd;
928
929 Din2 += N2p*BinCoeff*(C1/exp1p*G4Exp(-aQ2/(4*exp1p))-
930 C2/exp2p*G4Exp(-aQ2/(4*exp2p))+
931 C3/exp3p*G4Exp(-aQ2/(4*exp3p)));
932
933 DmedTot += N2p*BinCoeff*(C1/exp1p-C2/exp2p+C3/exp3p);
934
935 N2p *= -R23dR13;
936 } // l
937
938 G4double dcos = N1p*std::cos(FiH*i)/(G4double)((i+2)*(i+1));
939 Din1 += Din2*dcos;
940 DTot1 += DmedTot*dcos;
941
942 if(std::abs(Din2*N1p/Din1) < 0.000001) break;
943 } // i
944 G4double gg = (G4double)(A*(A-1)*4)/(Norm*Norm);
945
946 Din1 *= (-gg);
947 DTot1 *= 5*gg;
948
949 // ---------------- dSigma/d|-t|, mb/(GeV/c)^-2 -----------------
950
951 G4double DiffCrSec2 = (ReElasticAmpl0*ReElasticAmpl0+
952 (ImElasticAmpl0+Din1)*
953 (ImElasticAmpl0+Din1))/twopi;
954
955 Tot1 -= DTot1;
956 Dtot11 = DTot1;
957 aAIm = ImElasticAmpl0;
958 aDIm = Din1;
959
960 return DiffCrSec2; // dSig/d|-t|, mb/(GeV/c)^-2
961}
962
963////////////////////////////////////////////////////////////////
964
965void G4ElasticHadrNucleusHE::DefineHadronValues(G4int Z)
966{
967 G4double sHadr = 2.*HadrEnergy*protonM+protonM2+hMass2;
968 G4double sqrS = std::sqrt(sHadr);
969
970 if(verboseLevel>2) {
971 G4cout << "GetHadrValues: Z= " << Z << " iHadr= " << iHadron
972 << " E(GeV)= " << HadrEnergy << " sqrS= " << sqrS
973 << " plab= " << hLabMomentum
974 <<" E - m "<<HadrEnergy - hMass<< G4endl;
975 }
976 G4double TotN = 0.0;
977 G4double logE = G4Log(HadrEnergy);
978 G4double logS = G4Log(sHadr);
979 TotP = 0.0;
980
981 switch (iHadron) {
982 case 0: // proton, neutron
983 case 6:
984
985 if(hLabMomentum > 10) {
986 TotP = TotN = 7.5*logE - 40.12525 + 103*G4Exp(-logS*0.165);// mb
987
988 } else {
989 // ================== neutron ================
990
991 if( hLabMomentum > 1.4 ) {
992 TotN = 33.3+15.2*(hLabMomentum2-1.35)/
993 (G4Exp(G4Log(hLabMomentum)*2.37)+0.95);
994
995 } else if(hLabMomentum > 0.8) {
996 G4double A0 = logE + 0.0513;
997 TotN = 33.0 + 25.5*A0*A0;
998 } else {
999 G4double A0 = logE - 0.2634; // log(1.3)
1000 TotN = 33.0 + 30.*A0*A0*A0*A0;
1001 }
1002 // ================= proton ===============
1003
1004 if(hLabMomentum >= 1.05) {
1005 TotP = 39.0+75.*(hLabMomentum-1.2)/(hLabMomentum2*hLabMomentum+0.15);
1006 } else if(hLabMomentum >= 0.7) {
1007 G4double A0 = logE + 0.3147;
1008 TotP = 23.0 + 40.*A0*A0;
1009 } else {
1010 TotP = 23.+50.*G4Exp(G4Log(G4Log(0.73/hLabMomentum))*3.5);
1011 }
1012 }
1013 HadrTot = 0.5*(TotP+TotN);
1014 // ...................................................
1015 // Proton slope
1016 if(hLabMomentum >= 2.) { HadrSlope = 5.44 + 0.88*logS; }
1017 else if(hLabMomentum >= 0.5) { HadrSlope = 3.73*hLabMomentum-0.37; }
1018 else { HadrSlope = 1.5; }
1019
1020 // ...................................................
1021 if(hLabMomentum >= 1.2) {
1022 HadrReIm = 0.13*(logS - 5.8579332)*G4Exp(-logS*0.18);
1023 } else if(hLabMomentum >= 0.6) {
1024 HadrReIm = -75.5*(G4Exp(G4Log(hLabMomentum)*0.25)-0.95)/
1025 (G4Exp(G4Log(3*hLabMomentum)*2.2)+1);
1026 } else {
1027 HadrReIm = 15.5*hLabMomentum/(27*hLabMomentum2*hLabMomentum+2);
1028 }
1029 // ...................................................
1030 DDSect2 = 2.2; //mb*GeV-2
1031 DDSect3 = 0.6; //mb*GeV-2
1032 // ================== lambda ==================
1033 if( iHadrCode == 3122) {
1034 HadrTot *= 0.88;
1035 HadrSlope *=0.85;
1036 // ================== sigma + ==================
1037 } else if( iHadrCode == 3222) {
1038 HadrTot *=0.81;
1039 HadrSlope *=0.85;
1040 // ================== sigma 0,- ==================
1041 } else if(iHadrCode == 3112 || iHadrCode == 3212 ) {
1042 HadrTot *=0.88;
1043 HadrSlope *=0.85;
1044 // =================== xi =================
1045 } else if( iHadrCode == 3312 || iHadrCode == 3322 ) {
1046 HadrTot *=0.77;
1047 HadrSlope *=0.75;
1048 // ================= omega =================
1049 } else if( iHadrCode == 3334) {
1050 HadrTot *=0.78;
1051 HadrSlope *=0.7;
1052 }
1053 break;
1054 // ===========================================================
1055 case 1: // antiproton
1056 case 7: // antineutron
1057
1058 HadrTot = 5.2+5.2*logE + 123.2/sqrS; // mb
1059 HadrSlope = 8.32+0.57*logS; //(GeV/c)^-2
1060
1061 if( HadrEnergy < 1000 ) {
1062 HadrReIm = 0.06*(sqrS-2.236)*(sqrS-14.14)*G4Exp(-logS*0.8);
1063 } else {
1064 HadrReIm = 0.6*(logS - 5.8579332)*G4Exp(-logS*0.25);
1065 }
1066 DDSect2 = 11; //mb*(GeV/c)^-2
1067 DDSect3 = 3; //mb*(GeV/c)^-2
1068 // ================== lambda ==================
1069 if( iHadrCode == -3122) {
1070 HadrTot *= 0.88;
1071 HadrSlope *=0.85;
1072 // ================== sigma + ==================
1073 } else if( iHadrCode == -3222) {
1074 HadrTot *=0.81;
1075 HadrSlope *=0.85;
1076 // ================== sigma 0,- ==================
1077 } else if(iHadrCode == -3112 || iHadrCode == -3212 ) {
1078 HadrTot *=0.88;
1079 HadrSlope *=0.85;
1080 // =================== xi =================
1081 } else if( iHadrCode == -3312 || iHadrCode == -3322 ) {
1082 HadrTot *=0.77;
1083 HadrSlope *=0.75;
1084 // ================= omega =================
1085 } else if( iHadrCode == -3334) {
1086 HadrTot *=0.78;
1087 HadrSlope *=0.7;
1088 }
1089 break;
1090 // -------------------------------------------
1091 case 2: // pi plus, pi minus
1092 case 3:
1093
1094 if(hLabMomentum >= 3.5) {
1095 TotP = 10.6+2.*logE + 25.*G4Exp(-logE*0.43); // mb
1096 // =========================================
1097 } else if(hLabMomentum >= 1.15) {
1098 G4double x = (hLabMomentum - 2.55)/0.55;
1099 G4double y = (hLabMomentum - 1.47)/0.225;
1100 TotP = 3.2*G4Exp(-x*x) + 12.*G4Exp(-y*y) + 27.5;
1101 // =========================================
1102 } else if(hLabMomentum >= 0.4) {
1103 TotP = 88*(logE+0.2877)*(logE+0.2877)+14.0;
1104 // =========================================
1105 } else {
1106 G4double x = (hLabMomentum - 0.29)/0.085;
1107 TotP = 20. + 180.*G4Exp(-x*x);
1108 }
1109 // -------------------------------------------
1110
1111 if(hLabMomentum >= 3.0 ) {
1112 TotN = 10.6 + 2.*logE + 30.*G4Exp(-logE*0.43); // mb
1113 } else if(hLabMomentum >= 1.3) {
1114 G4double x = (hLabMomentum - 2.1)/0.4;
1115 G4double y = (hLabMomentum - 1.4)/0.12;
1116 TotN = 36.1+0.079 - 4.313*logE + 3.*G4Exp(-x*x) + 1.5*G4Exp(-y*y);
1117 } else if(hLabMomentum >= 0.65) {
1118 G4double x = (hLabMomentum - 0.72)/0.06;
1119 G4double y = (hLabMomentum - 1.015)/0.075;
1120 TotN = 36.1 + 10.*G4Exp(-x*x) + 24*G4Exp(-y*y);
1121 } else if(hLabMomentum >= 0.37) {
1122 G4double x = G4Log(hLabMomentum/0.48);
1123 TotN = 26. + 110.*x*x;
1124 } else {
1125 G4double x = (hLabMomentum - 0.29)/0.07;
1126 TotN = 28.0 + 40.*G4Exp(-x*x);
1127 }
1128 HadrTot = (TotP+TotN)*0.5;
1129 // ........................................
1130 HadrSlope = 7.28+0.245*logS; // GeV-2
1131 HadrReIm = 0.2*(logS - 4.6051702)*G4Exp(-logS*0.15);
1132
1133 DDSect2 = 0.7; //mb*GeV-2
1134 DDSect3 = 0.27; //mb*GeV-2
1135
1136 break;
1137 // ==========================================================
1138 case 4: // K plus
1139
1140 HadrTot = 10.6+1.8*logE + 9.0*G4Exp(-logE*0.55); // mb
1141 if(HadrEnergy>100) { HadrSlope = 15.0; }
1142 else { HadrSlope = 1.0+1.76*logS - 2.84/sqrS; } // GeV-2
1143
1144 HadrReIm = 0.4*(sHadr-20)*(sHadr-150)*G4Exp(-G4Log(sHadr+50)*2.1);
1145 DDSect2 = 0.7; //mb*GeV-2
1146 DDSect3 = 0.21; //mb*GeV-2
1147 break;
1148 // =========================================================
1149 case 5: // K minus
1150
1151 HadrTot = 10+1.8*logE + 25./sqrS; // mb
1152 HadrSlope = 6.98+0.127*logS; // GeV-2
1153 HadrReIm = 0.4*(sHadr-20)*(sHadr-20)*G4Exp(-G4Log(sHadr+50)*2.1);
1154 DDSect2 = 0.7; //mb*GeV-2
1155 DDSect3 = 0.27; //mb*GeV-2
1156 break;
1157 }
1158 // =========================================================
1159 if(verboseLevel>2) {
1160 G4cout << "HadrTot= " << HadrTot << " HadrSlope= " << HadrSlope
1161 << " HadrReIm= " << HadrReIm << " DDSect2= " << DDSect2
1162 << " DDSect3= " << DDSect3 << G4endl;
1163 }
1164 if(Z != 1) return;
1165
1166 // Scattering of protons
1167
1168 Coeff0 = Coeff1 = Coeff2 = 0.0;
1169 Slope0 = Slope1 = 1.0;
1170 Slope2 = 5.0;
1171
1172 // data for iHadron=0
1173 static const G4double EnP0[6]={1.5,3.0,5.0,9.0,14.0,19.0};
1174 static const G4double C0P0[6]={0.15,0.02,0.06,0.08,0.0003,0.0002};
1175 static const G4double C1P0[6]={0.05,0.02,0.03,0.025,0.0,0.0};
1176 static const G4double B0P0[6]={1.5,2.5,3.0,4.5,1.4,1.25};
1177 static const G4double B1P0[6]={5.0,1.0,3.5,4.0,4.8,4.8};
1178
1179 // data for iHadron=6,7
1180 static const G4double EnN[5]={1.5,5.0,10.0,14.0,20.0};
1181 static const G4double C0N[5]={0.0,0.0,0.02,0.02,0.01};
1182 static const G4double C1N[5]={0.06,0.008,0.0015,0.001,0.0003};
1183 static const G4double B0N[5]={1.5,2.5,3.8,3.8,3.5};
1184 static const G4double B1N[5]={1.5,2.2,3.6,4.5,4.8};
1185
1186 // data for iHadron=1
1187 static const G4double EnP[2]={1.5,4.0};
1188 static const G4double C0P[2]={0.001,0.0005};
1189 static const G4double C1P[2]={0.003,0.001};
1190 static const G4double B0P[2]={2.5,4.5};
1191 static const G4double B1P[2]={1.0,4.0};
1192
1193 // data for iHadron=2
1194 static const G4double EnPP[4]={1.0,2.0,3.0,4.0};
1195 static const G4double C0PP[4]={0.0,0.0,0.0,0.0};
1196 static const G4double C1PP[4]={0.15,0.08,0.02,0.01};
1197 static const G4double B0PP[4]={1.5,2.8,3.8,3.8};
1198 static const G4double B1PP[4]={0.8,1.6,3.6,4.6};
1199
1200 // data for iHadron=3
1201 static const G4double EnPPN[4]={1.0,2.0,3.0,4.0};
1202 static const G4double C0PPN[4]={0.0,0.0,0.0,0.0};
1203 static const G4double C1PPN[4]={0.0,0.0,0.0,0.0};
1204 static const G4double B0PPN[4]={1.5,2.8,3.8,3.8};
1205 static const G4double B1PPN[4]={0.8,1.6,3.6,4.6};
1206
1207 // data for iHadron=4
1208 static const G4double EnK[4]={1.4,2.33,3.0,5.0};
1209 static const G4double C0K[4]={0.0,0.0,0.0,0.0};
1210 static const G4double C1K[4]={0.01,0.007,0.005,0.003};
1211 static const G4double B0K[4]={1.5,2.0,3.8,3.8};
1212 static const G4double B1K[4]={1.6,1.6,1.6,1.6};
1213
1214 // data for iHadron=5
1215 static const G4double EnKM[2]={1.4,4.0};
1216 static const G4double C0KM[2]={0.006,0.002};
1217 static const G4double C1KM[2]={0.00,0.00};
1218 static const G4double B0KM[2]={2.5,3.5};
1219 static const G4double B1KM[2]={1.6,1.6};
1220
1221 switch(iHadron) {
1222 case 0:
1223
1224 if(hLabMomentum <BoundaryP[0]) {
1225 InterpolateHN(6,EnP0,C0P0,C1P0,B0P0,B1P0);
1226 }
1227 Coeff2 = 0.8/hLabMomentum2;
1228 break;
1229
1230 case 6:
1231
1232 if(hLabMomentum < BoundaryP[1]) {
1233 InterpolateHN(5,EnN,C0N,C1N,B0N,B1N);
1234 }
1235 Coeff2 = 0.8/hLabMomentum2;
1236 break;
1237
1238 case 1:
1239 case 7:
1240 if(hLabMomentum < BoundaryP[2]) {
1241 InterpolateHN(2,EnP,C0P,C1P,B0P,B1P);
1242 }
1243 break;
1244
1245 case 2:
1246
1247 if(hLabMomentum < BoundaryP[3]) {
1248 InterpolateHN(4,EnPP,C0PP,C1PP,B0PP,B1PP);
1249 }
1250 Coeff2 = 0.02/hLabMomentum;
1251 break;
1252
1253 case 3:
1254
1255 if(hLabMomentum < BoundaryP[4]) {
1256 InterpolateHN(4,EnPPN,C0PPN,C1PPN,B0PPN,B1PPN);
1257 }
1258 Coeff2 = 0.02/hLabMomentum;
1259 break;
1260
1261 case 4:
1262
1263 if(hLabMomentum < BoundaryP[5]) {
1264 InterpolateHN(4,EnK,C0K,C1K,B0K,B1K);
1265 }
1266 if(hLabMomentum < 1) { Coeff2 = 0.34; }
1267 else { Coeff2 = 0.34/(hLabMomentum2*hLabMomentum); }
1268 break;
1269
1270 case 5:
1271 if(hLabMomentum < BoundaryP[6]) {
1272 InterpolateHN(2,EnKM,C0KM,C1KM,B0KM,B1KM);
1273 }
1274 if(hLabMomentum < 1) { Coeff2 = 0.01; }
1275 else { Coeff2 = 0.01/(hLabMomentum2*hLabMomentum); }
1276 break;
1277 }
1278
1279 if(verboseLevel > 2) {
1280 G4cout<<" HadrVal : Plasb "<<hLabMomentum
1281 <<" iHadron "<<iHadron<<" HadrTot "<<HadrTot<<G4endl;
1282 }
1283}
1284
1285///////////////////////////////////////////////////////////////////
1286
1287G4double G4ElasticHadrNucleusHE::GetFt(G4double Q2)
1288{
1289 G4double Fdistr=0;
1290 G4double SqrQ2 = std::sqrt(Q2);
1291
1292 Fdistr = (1-Coeff1-Coeff0) / HadrSlope*(1-G4Exp(-HadrSlope*Q2))
1293 + Coeff0*(1-G4Exp(-Slope0*Q2))
1294 + Coeff2/Slope2*G4Exp(Slope2*ConstU)*(G4Exp(Slope2*Q2)-1)
1295 + 2*Coeff1/Slope1*(1/Slope1-(1/Slope1+SqrQ2)*G4Exp(-Slope1*SqrQ2));
1296
1297 if (verboseLevel>1) {
1298 G4cout<<"Old: Coeff0 Coeff1 Coeff2 "<<Coeff0<<" "
1299 <<Coeff1<<" "<<Coeff2<<" Slope Slope0 Slope1 Slope2 "
1300 <<HadrSlope<<" "<<Slope0<<" "<<Slope1<<" "<<Slope2
1301 <<" Fdistr "<<Fdistr<<G4endl;
1302 }
1303 return Fdistr;
1304}
1305
1306///////////////////////////////////////////////////////////////////
1307
1308G4double
1309G4ElasticHadrNucleusHE::HadronProtonQ2(G4double plab, G4double tmax)
1310{
1311 hLabMomentum = plab;
1312 hLabMomentum2 = hLabMomentum*hLabMomentum;
1313 HadrEnergy = std::sqrt(hMass2 + hLabMomentum2);
1314 DefineHadronValues(1);
1315
1316 G4double Sh = 2.0*protonM*HadrEnergy+protonM2+hMass2; // GeV
1317 ConstU = 2*protonM2+2*hMass2-Sh;
1318
1319 BoundaryTL[0] = tmax;
1320 BoundaryTL[1] = tmax;
1321 BoundaryTL[3] = tmax;
1322 BoundaryTL[4] = tmax;
1323 BoundaryTL[5] = tmax;
1324
1325 G4double MaxTR = (plab < BoundaryP[iHadron1]) ?
1326 BoundaryTL[iHadron1] : BoundaryTG[iHadron1];
1327
1328 if (verboseLevel>1) {
1329 G4cout<<"3 GetKin. : iHadron1 "<<iHadron1
1330 <<" Bound.P[iHadron1] "<<BoundaryP[iHadron1]
1331 <<" Bound.TL[iHadron1] "<<BoundaryTL[iHadron1]
1332 <<" Bound.TG[iHadron1] "<<BoundaryTG[iHadron1]
1333 <<" MaxT MaxTR "<<tmax<<" "<<MaxTR<<G4endl;
1334 }
1335
1336 G4double rand = G4UniformRand();
1337
1338 G4double DDD0=MaxTR*0.5, DDD1=0.0, DDD2=MaxTR;
1339
1340 G4double norm = 1.0/GetFt(MaxTR);
1341 G4double delta = GetFt(DDD0)*norm - rand;
1342
1343 static const G4int maxNumberOfLoops = 10000;
1344 G4int loopCounter = -1;
1345 while ( (std::abs(delta) > 0.0001) &&
1346 ++loopCounter < maxNumberOfLoops ) /* Loop checking, 10.08.2015, A.Ribon */
1347 {
1348 if(delta>0)
1349 {
1350 DDD2 = DDD0;
1351 DDD0 = (DDD0+DDD1)*0.5;
1352 }
1353 else if(delta<0.0)
1354 {
1355 DDD1 = DDD0;
1356 DDD0 = (DDD0+DDD2)*0.5;
1357 }
1358 delta = GetFt(DDD0)*norm - rand;
1359 }
1360 return (loopCounter >= maxNumberOfLoops) ? 0.0 : DDD0;
1361}
1362
1363///////////////////////////////////////////////////////////////////
1364
1365void G4ElasticHadrNucleusHE::Binom()
1366{
1367 for(G4int N = 0; N < 240; ++N) {
1368 G4double J = 1.0;
1369 for(G4int M = 0; M <= N; ++M) {
1370 G4double Fact1 = 1.0;
1371 if (N > 0 && N > M && M > 0 ) {
1372 J *= (G4double)(N-M+1)/(G4double)M;
1373 Fact1 = J;
1374 }
1375 fBinom[N][M] = Fact1;
1376 }
1377 }
1378}
1379
1380///////////////////////////////////////////////////////////
1381
1382void
1383G4ElasticHadrNucleusHE::InFileName(std::ostringstream& ss,
1384 const G4ParticleDefinition* p, G4int Z)
1385{
1386 if(!fDirectory) {
1387 fDirectory = std::getenv("G4LEDATA");
1388 if (fDirectory) {
1389 ss << fDirectory << "/";
1390 }
1391 }
1392 OutFileName(ss, p, Z);
1393}
1394
1395///////////////////////////////////////////////////////////
1396
1397void
1398G4ElasticHadrNucleusHE::OutFileName(std::ostringstream& ss,
1399 const G4ParticleDefinition* p, G4int Z)
1400{
1401 ss << "hedata/" << p->GetParticleName() << Z << ".dat";
1402}
1403
1404///////////////////////////////////////////////////////////
1405
1406G4bool G4ElasticHadrNucleusHE::ReadLine(std::ifstream& infile,
1407 std::vector<G4double>& v)
1408{
1409 G4int n(0);
1410 infile >> n;
1411 if (infile.fail()) { return false; }
1412 if(n > 0) {
1413 v.reserve(n);
1414 G4double x(0.0);
1415 for(G4int i=0; i<n; ++i) {
1416 infile >> x;
1417 if (infile.fail()) { return false; }
1418 v.emplace_back(x);
1419 }
1420 }
1421 return true;
1422}
1423
1424///////////////////////////////////////////////////////////
1425
1426void G4ElasticHadrNucleusHE::WriteLine(std::ofstream& outfile,
1427 std::vector<G4double>& v)
1428{
1429 G4int n = v.size();
1430 outfile << n << G4endl;
1431 if(n > 0) {
1432 for(G4int i=0; i<n; ++i) {
1433 outfile << v[i] << " ";
1434 }
1435 outfile << G4endl;
1436 }
1437}
1438
1439///////////////////////////////////////////////////////////
1440
1441
double Y(double density)
double A(double temperature)
const G4double invGeV2
const G4double protonM2
const G4double protonM
const G4double GeV2
const G4double invGeV
const G4double MbToGeV2
#define F22
#define F32
#define F12
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
Definition: G4Exp.hh:179
G4double G4Log(G4double x)
Definition: G4Log.hh:226
#define G4MUTEX_INITIALIZER
Definition: G4Threading.hh:85
#define G4MUTEXLOCK(mutex)
Definition: G4Threading.hh:251
#define G4MUTEXUNLOCK(mutex)
Definition: G4Threading.hh:254
std::mutex G4Mutex
Definition: G4Threading.hh:81
double G4double
Definition: G4Types.hh:83
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
const double C2
#define C1
#define C3
#define G4UniformRand()
Definition: Randomize.hh:52
G4ElasticData(const G4ParticleDefinition *h, G4int Z, G4int A, const G4double *e)
G4ElasticHadrNucleusHE(const G4String &name="hElasticGlauber")
void ModelDescription(std::ostream &) const override
G4double SampleInvariantT(const G4ParticleDefinition *p, G4double plab, G4int Z, G4int A) override
G4double SampleInvariantT(const G4ParticleDefinition *p, G4double plab, G4int Z, G4int A) override
const G4Material * GetMaterial() const
const G4ElementVector * GetElementVector() const
Definition: G4Material.hh:188
static G4NistManager * Instance()
G4double GetAtomicMassAmu(const G4String &symb) const
static G4double GetNuclearMass(const G4double A, const G4double Z)
const G4String & GetParticleName() const
static G4PionMinus * PionMinus()
Definition: G4PionMinus.cc:97
static G4PionPlus * PionPlus()
Definition: G4PionPlus.cc:97
const G4MaterialCutsCouple * GetMaterialCutsCouple(G4int i) const
std::size_t GetTableSize() const
static G4ProductionCutsTable * GetProductionCutsTable()
static G4Proton * Proton()
Definition: G4Proton.cc:92
int G4lrint(double ad)
Definition: templates.hh:134