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