ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4Pow.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4Pow.cc
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 // -------------------------------------------------------------------
28 //
29 // GEANT4 Class file
30 //
31 //
32 // File name: G4Pow
33 //
34 // Author: Vladimir Ivanchenko
35 //
36 // Creation date: 23.05.2009
37 //
38 // Modifications:
39 // 08.01.2011 V.Ivanchenko extended maxZ from 256 to 512
40 // 02.05.2013 V.Ivanchenko added expA and logX methods,
41 // revised A13, logA, powZ, powA to improved accuracy
42 // 23.03.2018 M.Novak increased accuracy of A13 on the most critical
43 // [1/4,4] interval by introducing a denser(0.25) grid
44 //
45 // -------------------------------------------------------------------
46 
47 #include "G4Pow.hh"
48 #include "G4Threading.hh"
49 
51 
52 // -------------------------------------------------------------------
53 
55 {
56  if (fpInstance == 0)
57  {
58  static G4Pow geant4pow;
59  fpInstance = &geant4pow;
60  }
61  return fpInstance;
62 }
63 
64 // -------------------------------------------------------------------
65 
67  : onethird(1.0/3.0), max2(5)
68 {
69 #ifdef G4MULTITHREADED
71  {
72  G4Exception ("G4Pow::G4Pow()", "InvalidSetup", FatalException,
73  "Attempt to instantiate G4Pow in worker thread!");
74  }
75 #endif
76  const G4int maxZ = 512;
77  const G4int maxZfact = 170;
78  const G4int numLowA = 17;
79 
80  maxA = -0.6 + maxZ;
81  maxLowA = 4.0;
82  maxA2 = 1.25 + max2*0.2;
83  maxAexp = -0.76+ maxZfact*0.5;
84 
85  ener.resize(max2+1,1.0);
86  logen.resize(max2+1,0.0);
87  lz2.resize(max2+1,0.0);
88  pz13.resize(maxZ,0.0);
89  lowa13.resize(numLowA,0.0);
90  lz.resize(maxZ,0.0);
91  fexp.resize(maxZfact,0.0);
92  fact.resize(maxZfact,0.0);
93  logfact.resize(maxZ,0.0);
94 
95  G4double f = 1.0;
96  G4double logf = 0.0;
97  fact[0] = 1.0;
98  fexp[0] = 1.0;
99 
100  for(G4int i=1; i<=max2; ++i)
101  {
102  ener[i] = powN(500.,i);
103  logen[i]= G4Log(ener[i]);
104  lz2[i] = G4Log(1.0 + i*0.2);
105  }
106 
107  for(G4int i=1; i<maxZ; ++i)
108  {
109  G4double x = G4double(i);
110  pz13[i] = std::pow(x,onethird);
111  lz[i] = G4Log(x);
112  if(i < maxZfact)
113  {
114  f *= x;
115  fact[i] = f;
116  fexp[i] = G4Exp(0.5*i);
117  }
118  logf += lz[i];
119  logfact[i] = logf;
120  }
121 
122  for (G4int i=4; i<numLowA; ++i) {
123  lowa13[i] = std::pow(0.25*i,onethird);
124  }
125 
126 }
127 
128 // -------------------------------------------------------------------
129 
131 {}
132 
133 // -------------------------------------------------------------------
134 
136  G4double res = 0.;
137  if (A>0.) {
138  const bool invert = (A<1.);
139  const G4double a = invert ? 1./A : A;
140  res = (a<maxLowA) ? A13Low(a, invert) : A13High(a, invert);
141  }
142  return res;
143 }
144 
145 // -------------------------------------------------------------------
146 
147 G4double G4Pow::A13High(const G4double a, const bool invert) const {
148  G4double res;
149  if (a<maxA) {
150  const G4int i = static_cast<G4int>(a+0.5);
151  const G4double x = (a/i-1.)*onethird;
152  res = pz13[i]*(1.+x-x*x*(1.-1.666667*x));
153  } else {
154  res = G4Exp(G4Log(a)*onethird);
155  }
156  res = invert ? 1./res : res;
157  return res;
158 }
159 
160 // -------------------------------------------------------------------
161 
162 G4double G4Pow::A13Low(const G4double a, const bool invert) const {
163  G4double res;
164  const G4int i = static_cast<G4int>(4.*(a+0.125));
165  const G4double y = 0.25*i;
166  const G4double x = (a/y-1.)*onethird;
167  res = lowa13[i]*(1.+x-x*x*(1.-1.666667*x));
168  res = invert ? 1./res : res;
169  return res;
170 }
171 
172 // -------------------------------------------------------------------
173 
175 {
176  if(0.0 == x) { return 0.0; }
177  if(std::abs(n) > 8) { return std::pow(x, G4double(n)); }
178  G4double res = 1.0;
179  if(n >= 0) { for(G4int i=0; i<n; ++i) { res *= x; } }
180  else if(n < 0)
181  {
182  G4double y = 1.0/x;
183  G4int nn = -n;
184  for(G4int i=0; i<nn; ++i) { res *= y; }
185  }
186  return res;
187 }