BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
Loading...
Searching...
No Matches
BDSSpecialFunctions.cc
1/*
2Beam Delivery Simulation (BDSIM) Copyright (C) BDSIM Collaboration, 2001 - 2026.
3
4This file is part of BDSIM.
5
6BDSIM is free software: you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published
8by the Free Software Foundation version 3 of the License.
9
10BDSIM is distributed in the hope that it will be useful, but
11WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with BDSIM. If not, see <http://www.gnu.org/licenses/>.
17*/
18#include "BDSSpecialFunctions.hh"
19#include "BDSUtilities.hh"
20
21#include "G4Types.hh"
22
23#include "CLHEP/Units/SystemOfUnits.h"
24
25#include <cmath>
26
27G4double BDS::CEL(G4double kc,
28 G4double p,
29 G4double c,
30 G4double s,
31 G4int nIterationLimit)
32{
33 if (!BDS::IsFinite(kc))
34 {return NAN;}
35
36 G4double errtol = 0.000001;
37 G4double k = std::abs(kc);
38 G4double pp = p;
39 G4double cc = c;
40 G4double ss = s;
41 G4double em = 1.0;
42 if (p > 0)
43 {
44 pp = std::sqrt(p);
45 ss = s/pp;
46 }
47 else
48 {
49 G4double f = kc * kc;
50 G4double q = 1.0 - f;
51 G4double g = 1.0 - pp;
52 f = f - pp;
53 q = q * (ss - c * pp);
54 pp = std::sqrt(f / g);
55 cc = (c - ss) / g;
56 ss = -q / (g * g * pp) + cc * pp;
57 }
58
59 G4double f = cc;
60 cc = cc + ss/pp;
61 G4double g = k/pp;
62 ss = 2*(ss + f*g);
63 pp = g + pp;
64 g = em;
65 em = k + em;
66 G4double kk = k;
67 G4int nLoop = 0;
68 while ( (std::abs(g-k) > g*errtol) && nLoop < nIterationLimit)
69 {
70 k = 2*std::sqrt(kk);
71 kk = k*em;
72 f = cc;
73 cc = cc + ss/pp;
74 g = kk / pp;
75 ss = 2*(ss + f*g);
76 pp = g + pp;
77 g = em;
78 em = k + em;
79 nLoop++;
80 }
81 G4double result = CLHEP::halfpi*(ss + cc*em)/( em*(em + pp) );
82 return result;
83}
G4double CEL(G4double kc, G4double p, G4double c, G4double s, G4int nIterationLimit=1000)
G4bool IsFinite(G4double value, G4double tolerance=std::numeric_limits< double >::epsilon())