Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
G4QBesIKJY.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// ---------------- G4QBesIKJY ----------------
30// by Mikhail Kossov, Sept 1999.
31// class for Bessel I0/I1 and K0/K1 functions in CHIPS Model
32// -------------------------------------------------------------------
33// Short description: Bessel functions class (can be substituted)
34// -------------------------------------------------------------------
35
36//#define debug
37//#define pdebug
38
39#include "G4QBesIKJY.hh"
40
41// Constructor
43{
44 ex=false;
45 switch (type)
46 {
47 case BessI0:
48 nu=0;
49 ik=true;
50 ij=true;
51 break;
52 case BessI1:
53 nu=1;
54 ik=true;
55 ij=true;
56 break;
57 case EBessI0:
58 nu=0;
59 ex=true;
60 ik=true;
61 ij=true;
62 break;
63 case EBessI1:
64 nu=1;
65 ex=true;
66 ik=true;
67 ij=true;
68 break;
69 case BessJ0:
70 nu=0;
71 ik=true;
72 ij=false;
73 break;
74 case BessJ1:
75 nu=1;
76 ik=true;
77 ij=false;
78 break;
79 case BessK0:
80 nu=0;
81 ik=false;
82 ij=true;
83 break;
84 case BessK1:
85 nu=1;
86 ik=false;
87 ij=true;
88 break;
89 case EBessK0:
90 nu=0;
91 ex=true;
92 ik=false;
93 ij=true;
94 break;
95 case EBessK1:
96 nu=1;
97 ex=true;
98 ik=false;
99 ij=true;
100 break;
101 case BessY0:
102 nu=0;
103 ik=false;
104 ij=false;
105 break;
106 case BessY1:
107 nu=1;
108 ik=false;
109 ij=false;
110 break;
111 }
112}
113
115
117{
118 static const G4int nat1 = 15; // a # of attempts to reach the X<1 accuracy
119 static const G4int nat2 = nat1+nat1; // a # of attempts to reach the X<5 accuracy
120 static const G4int npi = 25;
121 static const G4int npil = npi-1;
122 static const G4int npk = 17;
123 static const G4int npkl = npk-1;
124 static const G4int npj = 20;
125 static const G4int npjl = npj-1;
126 static const G4complex CI(0,1);
127 static const G4double EPS = 1.E-15;
128 static const G4double Z1 = 1.;
129 static const G4double HF = Z1/2;
130 static const G4double R8 = HF/4;
131 static const G4double R32 = R8/4;
132 static const G4double PI = 3.14159265358979324;
133 static const G4double CE = 0.57721566490153286;
134 static const G4double PIH = PI/2;
135 static const G4double PI4 = PIH/2; // PI/4
136 static const G4double PI3 = PIH+PI4; // 3*PI/4
137 static const G4double RPIH = 2./PI;
138 static const G4double RPI2 = RPIH/4;
139
140 static const G4double CI0[npi]={+1.00829205458740032E0,
141 +.00845122624920943E0,+.00012700630777567E0,+.00007247591099959E0,
142 +.00000513587726878E0,+.00000056816965808E0,+.00000008513091223E0,
143 +.00000001238425364E0,+.00000000029801672E0,-.00000000078956698E0,
144 -.00000000033127128E0,-.00000000004497339E0,+.00000000001799790E0,
145 +.00000000000965748E0,+.00000000000038604E0,-.00000000000104039E0,
146 -.00000000000023950E0,+.00000000000009554E0,+.00000000000004443E0,
147 -.00000000000000859E0,-.00000000000000709E0,+.00000000000000087E0,
148 +.00000000000000112E0,-.00000000000000012E0,-.00000000000000018E0};
149
150 static const G4double CI1[npi]={+.975800602326285926E0,
151 -.024467442963276385E0,-.000277205360763829E0,-.000009732146728020E0,
152 -.000000629724238640E0,-.000000065961142154E0,-.000000009613872919E0,
153 -.000000001401140901E0,-.000000000047563167E0,+.000000000081530681E0,
154 +.000000000035408148E0,+.000000000005102564E0,-.000000000001804409E0,
155 -.000000000001023594E0,-.000000000000052678E0,+.000000000000107094E0,
156 +.000000000000026120E0,-.000000000000009561E0,-.000000000000004713E0,
157 +.000000000000000829E0,+.000000000000000743E0,-.000000000000000080E0,
158 -.000000000000000117E0,+.000000000000000011E0,+.000000000000000019E0};
159
160 static const G4double CK0[npk]={+.988408174230825800E0,-.011310504646928281E0,
161 +.000269532612762724E0,-.000011106685196665E0,+.000000632575108500E0,
162 -.000000045047337641E0,+.000000003792996456E0,-.000000000364547179E0,
163 +.000000000039043756E0,-.000000000004579936E0,+.000000000000580811E0,
164 -.000000000000078832E0,+.000000000000011360E0,-.000000000000001727E0,
165 +.000000000000000275E0,-.000000000000000046E0,+.000000000000000008E0};
166
167 static const G4double CK1[npk]={+1.035950858772358331E0,+.035465291243331114E0,
168 -.000468475028166889E0,+.000016185063810053E0,-.000000845172048124E0,
169 +.000000057132218103E0,-.000000004645554607E0,+.000000000435417339E0,
170 -.000000000045757297E0,+.000000000005288133E0,-.000000000000662613E0,
171 +.000000000000089048E0,-.000000000000012726E0,+.000000000000001921E0,
172 -.000000000000000305E0,+.000000000000000050E0,-.000000000000000009E0};
173
174 static const G4double CA[npk]={+.157727971474890120E0,-.008723442352852221E0,
175 +.265178613203336810E0,-.370094993872649779E0,+.158067102332097261E0,
176 -.034893769411408885E0,+.004819180069467605E0,-.000460626166206275E0,
177 +.000032460328821005E0,-.000001761946907762E0,+.000000076081635924E0,
178 -.000000002679253531E0,+.000000000078486963E0,-.000000000001943835E0,
179 +.000000000000041253E0,-.000000000000000759E0,+.000000000000000012E0};
180
181 static const G4double CB[npk]={-.021505111449657551E0,-.275118133043518791E0,
182 +.198605634702554156E0,+.234252746109021802E0,-.165635981713650413E0,
183 +.044621379540669282E0,-.006932286291523188E0,+.000719117403752303E0,
184 -.000053925079722939E0,+.000003076493288108E0,-.000000138457181230E0,
185 +.000000005051054369E0,-.000000000152582850E0,+.000000000003882867E0,
186 -.000000000000084429E0,+.000000000000001587E0,-.000000000000000026E0};
187
188 static const G4complex CC[npj]={
189 G4complex(+.998988089858965153E0,-.012331520578544144E0),
190 G4complex(-.001338428549971856E0,-.012249496281259475E0),
191 G4complex(-.000318789878061893E0,+.000096494184993423E0),
192 G4complex(+.000008511232210657E0,+.000013655570490357E0),
193 G4complex(+.000000691542349139E0,-.000000851806644426E0),
194 G4complex(-.000000090770101537E0,-.000000027244053414E0),
195 G4complex(+.000000001454928079E0,+.000000009646421338E0),
196 G4complex(+.000000000926762487E0,-.000000000683347518E0),
197 G4complex(-.000000000139166198E0,-.000000000060627380E0),
198 G4complex(+.000000000003237975E0,+.000000000021695716E0),
199 G4complex(+.000000000002535357E0,-.000000000002304899E0),
200 G4complex(-.000000000000559090E0,-.000000000000122554E0),
201 G4complex(+.000000000000041919E0,+.000000000000092314E0),
202 G4complex(+.000000000000008733E0,-.000000000000016778E0),
203 G4complex(-.000000000000003619E0,+.000000000000000754E0),
204 G4complex(+.000000000000000594E0,+.000000000000000462E0),
205 G4complex(-.000000000000000010E0,-.000000000000000159E0),
206 G4complex(-.000000000000000024E0,+.000000000000000025E0),
207 G4complex(+.000000000000000008E0,+.000000000000000000E0),
208 G4complex(-.000000000000000001E0,-.000000000000000001E0)};
209
210 static const G4double CD[npk]={+0.648358770605264921E0,-1.191801160541216873E0,
211 +1.287994098857677620E0,-0.661443934134543253E0,+0.177709117239728283E0,
212 -0.029175524806154208E0,+0.003240270182683857E0,-0.000260444389348581E0,
213 +0.000015887019239932E0,-0.000000761758780540E0,+0.000000029497070073E0,
214 -0.000000000942421298E0,+0.000000000025281237E0,-0.000000000000577740E0,
215 +0.000000000000011386E0,-0.000000000000000196E0,+0.000000000000000003E0};
216
217 static const G4double EE[npk]={-.040172946544414076E0,-.444447147630558063E0,
218 -.022719244428417736E0,+.206644541017490520E0,-.086671697056948524E0,
219 +.017636703003163134E0,-.002235619294485095E0,+.000197062302701541E0,
220 -.000012885853299241E0,+.000000652847952359E0,-.000000026450737175E0,
221 +.000000000878030117E0,-.000000000024343279E0,+.000000000000572612E0,
222 -.000000000000011578E0,+.000000000000000203E0,-.000000000000000003E0};
223
224 static const G4complex CF[npj]={
225 G4complex(+1.001702234853820996E0,+.037261715000537654E0),
226 G4complex(+.002255572846561180E0,+.037145322479807690E0),
227 G4complex(+.000543216487508013E0,-.000137263238201907E0),
228 G4complex(-.000011179461895408E0,-.000019851294687597E0),
229 G4complex(-.000000946901382392E0,+.000001070014057386E0),
230 G4complex(+.000000111032677121E0,+.000000038305261714E0),
231 G4complex(-.000000001294398927E0,-.000000011628723277E0),
232 G4complex(-.000000001114905944E0,+.000000000759733092E0),
233 G4complex(+.000000000157637232E0,+.000000000075476075E0),
234 G4complex(-.000000000002830457E0,-.000000000024752781E0),
235 G4complex(-.000000000002932169E0,+.000000000002493893E0),
236 G4complex(+.000000000000617809E0,+.000000000000156198E0),
237 G4complex(-.000000000000043162E0,-.000000000000103385E0),
238 G4complex(-.000000000000010133E0,+.000000000000018129E0),
239 G4complex(+.000000000000003973E0,-.000000000000000709E0),
240 G4complex(-.000000000000000632E0,-.000000000000000520E0),
241 G4complex(+.000000000000000006E0,+.000000000000000172E0),
242 G4complex(+.000000000000000027E0,-.000000000000000026E0),
243 G4complex(-.000000000000000008E0,-.000000000000000000E0),
244 G4complex(+.000000000000000001E0,+.000000000000000001E0)};
245 // -------------------------------------------------------------------------------------
246 G4double H=0.; // Prototype of the result
247 if (ij) // I/K Bessel functions
248 {
249 if (ik) // I0/I1/EI0/EI1 Bessel functions (symmetric)
250 {
251 G4double V=std::abs(X);
252 G4double CJ=0.; // Prototype of the element of the CI0/CI1 matrix
253 if (V < 8.)
254 {
255 G4double HFV=HF*V;
256 G4double Y=HFV*HFV;
257 G4int V3=nu+1;
258 G4int XL=V3+1;
259 G4int XLI=XL+1;
260 G4int XLD=XLI+1;
261 G4int W1=XLD+1;
262 G4double A0=1.;
263 G4double DY=Y+Y;
264 G4double A1=1.+DY/(XLI*V3);
265 G4double A2=1.+Y*(4.+(DY+Y)/(XLD*XL))/(W1*V3);
266 G4double B0=1.;
267 G4double B1=1.-Y/XLI;
268 G4double B2=1.-Y*(1.-Y/(XLD+XLD))/W1;
269 G4int V1=3-XL;
270 G4double V2=V3+V3;
271 G4double C=0.;
272 for (G4int N=3; N<=30; N++)
273 {
274 G4double C0=C;
275 G4double FN=N;
276 W1=W1+2;
277 G4int W2=W1-1;
278 G4int W3=W2-1;
279 G4int W4=W3-1;
280 G4int W5=W4-1;
281 G4int W6=W5-1;
282 V1=V1+1;
283 V2=V2+1;
284 V3=V3+1;
285 G4double U1=FN*W4;
286 G4double E=V3/(U1*W3);
287 G4double U2=E*Y;
288 G4double F1=1.+Y*V1/(U1*W1);
289 G4double F2=(1.+Y*V2/(V3*W2*W5))*U2;
290 G4double F3=-Y*Y*U2/(W4*W5*W5*W6);
291 G4double A=F1*A2+F2*A1+F3*A0;
292 G4double B=F1*B2+F2*B1+F3*B0;
293 C=A/B;
294 if (std::abs(C0-C) < EPS*std::abs(C)) break;
295 A0=A1; A1=A2; A2=A; B0=B1; B1=B2; B2=B;
296 }
297 H=C;
298 if (nu==1) H*=HF*X;
299 if (ex) H*=std::exp(-V);
300 }
301 else
302 {
303 G4double P=16./V-1.;
304 G4double ALFA=P+P;
305 G4double B1=0.;
306 G4double B2=0.;
307 for (G4int I=npil; I>=0; I--)
308 {
309 if (!nu) CJ=CI0[I];
310 else CJ=CI1[I];
311 G4double B0=CJ+ALFA*B1-B2;
312 B2=B1;
313 B1=B0;
314 }
315 H=std::sqrt(RPI2/V)*(B1-P*B2);
316 if (nu && X < 0.) H=-H;
317 if (!ex) H*=std::exp(V);
318 }
319 }
320 else // K0/K1/EK0/EK1 Bessel functions
321 {
322#ifdef debug
323 G4cout<<"G4BesIKJY: ------------>> K is called, X="<<X<<",n="<<nu<<",E="<<ex<<G4endl;
324#endif
325 G4double CK=0.; // Prototype of the element of the CI0/CI1 matrix
326 if (X < 0.)
327 {
328 G4cout<<"G4BesIKJY::NegativeArg in K-BessFun X="<<X<<", n="<<nu<<",E="<<ex<<G4endl;
329 return H;
330 }
331 else if (X < 1.)
332 {
333#ifdef debug
334 G4cout<<"G4BesIKJY: -->> [ X < 1 ] is called, X="<<X<<",n="<<nu<<",E="<<ex<<G4endl;
335#endif
336 G4double B=HF*X;
337 G4double BK=-(std::log(B)+CE);
338 G4double F=BK;
339 G4double P=HF;
340 G4double Q=HF;
341 G4double C=1.;
342 G4double D=B*B;
343 G4double BK1=P;
344 for (G4int N=1; N<=nat1; N++) // @@ "nat" can be increased
345 {
346 G4double FN=N;
347 P/=FN;
348 Q/=FN;
349 F=(F+P+Q)/FN;
350 C*=D/FN;
351 G4double G=C*(P-FN*F);
352 G4double R=C*F;
353 BK=BK+R;
354 BK1=BK1+G;
355 if (BK1*R+std::abs(G)*BK < EPS*BK*BK1) break;
356 }
357 if (nu==1) H=BK1/B;
358 else H=BK;
359 if (ex) H*=std::exp(X);
360 }
361 else if (X < 5.)
362 {
363#ifdef debug
364 G4cout<<"G4BesIKJY: -->> [ X < 5 ] is called, X="<<X<<",n="<<nu<<",E="<<ex<<G4endl;
365#endif
366 G4int NUS=0; // @@ NU**2 for future NU>1 applications
367 if (nu==1) NUS=1;
368 G4double DNUS=NUS+NUS;
369 G4double XN=DNUS+DNUS;
370 G4double A=9.-XN;
371 G4double B=25.-XN;
372 G4double C=768*X*X;
373 G4double HX=16*X;
374 G4double C0=HX+HX+HX;;
375 G4double A0=1.;
376 G4double A1=(HX+7.+XN)/A;
377 G4double A2=(C+C0*(XN+23.)+XN*(XN+62.)+129.)/(A*B);
378 G4double B0=1.;
379 G4double B1=(HX+9.-XN)/A;
380 G4double B2=(C+C0*B)/(A*B)+1.;
381 C=0.;
382 for (G4int N=3; N<=nat2; N++)
383 {
384 C0=C;
385 G4double FN=N;
386 G4double FN2=FN+FN;
387 G4double FNP=FN2+1.;
388 G4double FN1=FN2-1.;
389 G4double FNM=FN1-4.;
390 G4double FN3=FN1/(FN2-3.);
391 G4double FN4=12*FN*FN-(1.-XN);
392 G4double FN5=16*FN1*X;
393 G4double RAN=1./(FNP*FNP-XN);
394 G4double F1=FN3*(FN4-20*FN)+FN5;
395 G4double F2=28*FN-FN4-8.+FN5;
396 G4double F3=FN3*(FNM*FNM-XN);
397 A=(F1*A2+F2*A1+F3*A0)*RAN;
398 B=(F1*B2+F2*B1+F3*B0)*RAN;
399 C=A/B;
400 if (std::abs(C0-C) < EPS*std::abs(C)) break;
401 A0=A1; A1=A2; A2=A; B0=B1; B1=B2; B2=B;
402 }
403 H=C/std::sqrt(RPIH*X);
404 if (!ex) H*=std::exp(-X);
405 }
406 else
407 {
408#ifdef debug
409 G4cout<<"G4BesIKJY: ->> [ X >= 5 ] is called, X="<<X<<",n="<<nu<<",E="<<ex<<G4endl;
410#endif
411 G4double P=10./X-1.;
412 G4double ALFA=P+P;
413 G4double B1=0.;
414 G4double B2=0.;
415#ifdef debug
416 G4cout<<"G4BesIKJY: ->> [ X >= 5 ] is called, X="<<X<<",n="<<nu<<",E="<<ex<<G4endl;
417#endif
418 for (G4int I=npkl; I>=0; I--)
419 {
420 if (!nu) CK=CK0[I];
421 else CK=CK1[I];
422 G4double B0=CK+ALFA*B1-B2;
423 B2=B1;
424 B1=B0;
425 }
426 H=std::sqrt(PIH/X)*(B1-P*B2);
427 if (!ex) H*=std::exp(-X);
428 }
429 }
430 }
431 else
432 {
433 if (!ik && X < 0.)
434 {
435 G4cout<<"G4BesIKJY::NegativeArgument in Y BesselFunction X="<<X<<", nu="<<nu<<G4endl;
436 return H;
437 }
438 G4double V=std::abs(X);
439 if (!nu) // J0/Y0 Bessel functions
440 {
441 if (V < 8.)
442 {
443 G4double P=R32*V*V-1.;
444 G4double ALFA=P+P;
445 G4double B1=0.;
446 G4double B2=0.;
447 for (G4int IT=npkl; IT>=0; IT--)
448 {
449 G4double B0=CA[IT]+ALFA*B1-B2;
450 B2=B1;
451 B1=B0;
452 }
453 H=B1-P*B2;
454 if (!ik)
455 {
456 B1=0.;
457 B2=0.;
458 for (G4int JT=npkl; JT>=0; JT--)
459 {
460 G4double B0=CB[JT]+ALFA*B1-B2;
461 B2=B1;
462 B1=B0;
463 }
464 H=RPIH*(CE+std::log(HF*X))*H+B1-P*B2;
465 }
466 }
467 else
468 {
469 G4double P=10./V-1.;
470 G4double ALFA=P+P;
471 G4complex CB1(0.,0.);
472 G4complex CB2(0.,0.);
473 for (G4int IT=npjl; IT>=0; IT--)
474 {
475 G4complex CB0=CC[IT]+ALFA*CB1-CB2;
476 CB2=CB1;
477 CB1=CB0;
478 }
479 CB1=std::sqrt(RPIH/V)*std::exp(CI*(V-PI4))*(CB1-P*CB2);
480 if (ik) H=real(CB1);
481 else H=real(-CI*CB1);
482 }
483 }
484 else // J1/Y1 Bessel functions
485 {
486 if (V < 8.)
487 {
488 G4double Y=R8*V;
489 G4double Y2=Y*Y;
490 G4double P=Y2+Y2-1.;
491 G4double ALFA=P+P;
492 G4double B1=0.;
493 G4double B2=0.;
494 for (G4int IT=npkl; IT>=0; IT--)
495 {
496 G4double B0=CD[IT]+ALFA*B1-B2;
497 B2=B1;
498 B1=B0;
499 }
500 H=Y*(B1-P*B2);
501 if (!ik)
502 {
503 B1=0.;
504 B2=0.;
505 for (G4int JT=npkl; JT>=0; JT--)
506 {
507 G4double B0=EE[JT]+ALFA*B1-B2;
508 B2=B1;
509 B1=B0;
510 }
511 H=RPIH*((CE+std::log(HF*X))*H-1./X)+Y*(B1-B2);
512 }
513 }
514 else
515 {
516 G4double P=10./V-1.;
517 G4double ALFA=P+P;
518 G4complex CB1(0.,0.);
519 G4complex CB2(0.,0.);
520 for (G4int IT=npjl; IT>=0; IT--)
521 {
522 G4complex CB0=CF[IT]+ALFA*CB1-CB2;
523 CB2=CB1;
524 CB1=CB0;
525 }
526 CB1=std::sqrt(RPIH/V)*std::exp(CI*(V-PI3))*(CB1-P*CB2);
527 if (ik) H=real(CB1);
528 else H=real(-CI*CB1);
529 }
530 if (X < 0.) H=-H;
531 }
532 }
533 return H;
534}
G4QBIType
Definition: G4QBesIKJY.hh:43
@ BessJ0
Definition: G4QBesIKJY.hh:43
@ BessY0
Definition: G4QBesIKJY.hh:44
@ BessJ1
Definition: G4QBesIKJY.hh:43
@ BessY1
Definition: G4QBesIKJY.hh:44
@ BessK1
Definition: G4QBesIKJY.hh:44
@ EBessK1
Definition: G4QBesIKJY.hh:44
@ EBessK0
Definition: G4QBesIKJY.hh:44
@ BessK0
Definition: G4QBesIKJY.hh:44
@ EBessI1
Definition: G4QBesIKJY.hh:43
@ EBessI0
Definition: G4QBesIKJY.hh:43
@ BessI1
Definition: G4QBesIKJY.hh:43
@ BessI0
Definition: G4QBesIKJY.hh:43
double G4double
Definition: G4Types.hh:64
int G4int
Definition: G4Types.hh:66
std::complex< G4double > G4complex
Definition: G4Types.hh:69
#define G4endl
Definition: G4ios.hh:52
G4DLLIMPORT std::ostream G4cout
G4double operator()(G4double x) const
Definition: G4QBesIKJY.cc:116
G4QBesIKJY(G4QBIType type=BessI0)
Definition: G4QBesIKJY.cc:42
#define V1(a, b, c)
#define V2(a, b, c)