Geant4  9.6.p02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4Type1GlauberParameterisation.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 // * *
21 // * Parts of this code which have been developed by QinetiQ Ltd *
22 // * under contract to the European Space Agency (ESA) are the *
23 // * intellectual property of ESA. Rights to use, copy, modify and *
24 // * redistribute this software for general public use are granted *
25 // * in compliance with any licensing, distribution and development *
26 // * policy adopted by the Geant4 Collaboration. This code has been *
27 // * written by QinetiQ Ltd for the European Space Agency, under ESA *
28 // * contract 19770/06/NL/JD (Technology Research Programme). *
29 // * *
30 // * By using, copying, modifying or distributing the software (or *
31 // * any work based on the software) you agree to acknowledge its *
32 // * use in resulting scientific publications, and indicate your *
33 // * acceptance of all terms of the Geant4 Software license. *
34 // ********************************************************************
35 //
38 //
39 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
40 //
41 // MODULE: G4Type1GlauberParameterisation.cc
42 //
43 // Version: 0.B
44 // Date: 02/04/08
45 // Author: P R Truscott
46 // Organisation: QinetiQ Ltd, UK
47 // Customer: ESA/ESTEC, NOORDWIJK
48 // Contract: 19770/06/NL/JD
49 //
50 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
52 //
53 #ifdef G4_USE_DPMJET
54 
55 
57 
58 using namespace std;
59 
60 //
61 //
62 // The following function performs a polynomial least squares fit to double
63 // precision data. It forms part of the CERN mathlib. This is a really
64 // beyond standard policy and will eventually be changed to a C++ function.
65 //
66 extern "C" {void dlsqpm_ (int*,double*,double*,int*,double*,double*,int*);}
67 
69 //
71 {
72  limit1 = 0.1;
73  limit2 = 0.60;
74  limit3 = 0.95;
75  limit4 = 0.9999;
76 
77  maxArrayp = 200;
78  maxigp = 24;
79 
80  for (G4int ig=0; ig<maxigp; ig++) {
81  for (G4int j=0; j<10; j++) {
82  paramn[ig][j] = 0.0;
83  paramn[ig][j] = 0.0;
84  }
85  mun1[ig] = 0.0;
86  mun2[ig] = 0.0;
87  cn[ig] = 0.0;
88  mum1[ig] = 0.0;
89  mum2[ig] = 0.0;
90  cm[ig] = 0.0;
91  }
92 }
94 //
96 {;}
98 //
100  (const G4double *bsite, G4double *p) const
101 {
102 //
103 //
104 // Initialise parameters.
105 //
106  G4int pt1 = -1;
107  G4int pt2 = -1;
108  G4int pt3 = -1;
109  G4int pt4 = -1;
110 //
111 //
112 // Locate transitions between different parts of the curve where different
113 // fits are used.
114 //
115  G4double ib[200];
116  G4double lnib[200];
117  G4double lnbsite[200];
118  for (G4int i=0; i<maxArrayp; i++) {
119  ib[i] = (G4double) i;
120  lnib[i] = std::log(ib[i]);
121  if (bsite[i] < 1.0E-10) lnbsite[i] = -23.02585093;
122  else lnbsite[i] = std::log(bsite[i]);
123  if (pt1 == -1) {
124  if (bsite[i] >= limit1) pt1 = i;
125  }
126  else if (pt2 == -1) {
127  if (bsite[i] >= limit2) pt2 = i;
128  }
129  else if (pt3 == -1) {
130  if (bsite[i] >= limit3) pt3 = i;
131  }
132  else if (pt4 == -1) {
133  if (bsite[i] >= limit4) pt4 = i;
134  }
135  }
136 //
137 //
138 // First section determines the power-law fits for the low and intermediate b
139 // values;
140 //
141  G4int deltan = pt2 - pt1;
142  G4int m = 1;
143  G4double a1[2];
144  G4double sd;
145  G4int ifail;
146  dlsqpm_ (&deltan,&lnbsite[pt1],&lnib[pt1],&m,&a1[0],&sd,&ifail);
147 
148  G4double c1 = a1[0];
149  G4double m1 = a1[1];
150 
151 // G4double m2 = (lnib[3] - lnib[2]) / (lnbsite[3] - lnbsite[2]);
152 // G4double c2 = lnib[2] - m2*lnbsite[2];
153  deltan = 3;
154  dlsqpm_ (&deltan,&lnbsite[1],&lnib[1],&m,&a1[0],&sd,&ifail);
155 
156  G4double c2 = a1[0];
157  G4double m2 = a1[1];
158 
159  p[0] = std::exp(c2);
160  p[1] = m2;
161  p[2] = std::exp(c1);
162  p[3] = m1;
163  if (std::abs(m2-m1) > 1.0E-10) {
164  p[4] = exp(-(c2-c1)/(m2-m1));
165  }
166  else {
167  p[4] = limit2 / 2.0;
168  }
169 //
170 //
171 // This next bit solves for gamma to determine the inflection at high-b values.
172 // The algorthm used is EXTREEEEEMELY crude .... but practical and robust.
173 // It's a linear search.
174 //
175  G4double delta = 1.0E+99;
176  G4double gam = 0.0;
177  for (G4int ig = 120; ig < 1000; ig++) {
178  G4double DELTA = 0.0;
179  G4double GAMMA = (G4double) ig / 100.0;
180  G4double EXPON = p[3] / GAMMA;
181  for (G4int i = pt2; i<pt3; i++) {
182  G4double f = bsite[i];
183  G4double B = p[2] * std::pow(f,p[3]) / std::pow((1.0-std::pow(f,GAMMA)),EXPON);
184  G4double epsilon = std::abs((ib[i]-B)/ib[i]);
185  if (epsilon > DELTA) DELTA = epsilon;
186  }
187  if (DELTA < delta) {
188  gam = GAMMA;
189  delta = DELTA;
190  }
191  }
192  p[5] = gam;
193 //
194 //
195 // For the final part of the curve, we use a cubic polynomial fit to -ln(1-bsite)
196 // versus ib. This does seem to work quite well.
197 //
198  G4double phi[200];
199  for (G4int i = pt3; i<pt4; i++) {
200  phi[i] = -std::log(1.0 - bsite[i]);
201  }
202  deltan = pt4-pt3;
203  m = 3;
204  G4double a2[4];
205 
206  dlsqpm_ (&deltan,&phi[pt3],&ib[pt3],&m,&a2[0],&sd,&ifail);
207 
208  p[6] = a2[0];
209  p[7] = a2[1];
210  p[8] = a2[2];
211  p[9] = a2[3];
212 
213  return 0.0;
214 }
216 //
217 // GetValueN
218 //
220  const G4double ppn) const
221 {
222  G4int ig = 0;
223  if (ppn < 1.0E-10) {
224  return 0;
225  }
226  else {
227  ig = G4int(2.0*std::log10(ppn)) - 2;
228  }
229  if (ig < 0) ig = 0;
230  else if (ig > 23) ig = 23;
231 
232  G4double v = 0.0;
233  if (f <= paramn[ig][4]) {
234  v = paramn[ig][0] * std::pow(f,paramn[ig][1]);
235  }
236  else if (f <= limit3) {
237  v = paramn[ig][2] * std::pow(f,paramn[ig][3]) /
238  std::pow((1.0 - std::pow(f,paramn[ig][5])),paramn[ig][3]/paramn[ig][5]);
239  }
240  else {
241  G4double l = -std::log(1.0-f);
242  v = paramn[ig][6] +
243  paramn[ig][7]*l +
244  paramn[ig][8]*l*l +
245  paramn[ig][9]*std::pow(l,3.0);
246  }
247 
248  return v;
249 }
251 //
252 // GetValueM
253 //
255  const G4double ppn) const
256 {
257  G4int ig = 0;
258  if (ppn < 1.0E-10) {
259  return 0;
260  }
261  else {
262  ig = G4int(2.0*std::log10(ppn)) - 2;
263  }
264  if (ig < 0) ig = 0;
265  else if (ig > 23) ig = 23;
266 
267  G4double v = 0.0;
268  if (f <= paramm[ig][4]) {
269  v = paramm[ig][0] * std::pow(f,paramm[ig][1]);
270  }
271  else if (f <= limit3) {
272  v = paramm[ig][2] * std::pow(f,paramm[ig][3]) /
273  std::pow((1.0 - std::pow(f,paramm[ig][5])),paramm[ig][3]/paramm[ig][5]);
274  }
275  else {
276  G4double l = -std::log(1.0-f);
277  v = paramn[ig][6] +
278  paramn[ig][7]*l +
279  paramn[ig][8]*l*l +
280  paramn[ig][9]*std::pow(l,3.0);
281  }
282 
283  return v;
284 }
286 //
287 // GetInverseValueN
288 //
289 /*G4double G4Type1GlauberParameterisation::GetInverseValueN (const G4int b,
290  const G4double ppn) const
291 {
292  G4int ig = 0;
293  if (ppn < 1.0E-10) {
294  return 0;
295  }
296  else {
297  ig = G4int(2.0*std::log10(ppn)) - 2;
298  }
299  if (ig > 23) ig = 23;
300 
301  return GetInverseValueN(b,ig);
302 }*/
304 //
305 // GetInverseValueM
306 //
307 /*G4double G4Type1GlauberParameterisation::GetInverseValueM (const G4int b,
308  const G4double ppn) const
309 {
310  G4int ig = 0;
311  if (ppn < 1.0E-10) {
312  return 0;
313  }
314  else {
315  ig = G4int(2.0*std::log10(ppn)) - 2;
316  }
317  if (ig > 23) ig = 23;
318 
319  return GetInverseValueN(b,ig);
320 }*/
322 //
323 // GetInverseValueN
324 //
325 /*G4double G4Type1GlauberParameterisation::GetInverseValueN (const G4int b,
326  const G4int ig) const
327 {
328  G4double v = 0.0;
329  G4double x = (G4double) b;
330  if (b <= 1) {
331  v = 0.0;
332  }
333  else {
334  G4double f1 = 1.0 + std::pow(paramn[ig][0]/x,mun1[ig]);
335  G4double f2 = 1.0 + std::pow(cn[ig]/x,mun2[ig]);
336  v = std::pow(f1*f2,1.0/paramn[ig][5]);
337  }
338 
339  return v;
340 }*/
342 //
343 // GetInverseValueM
344 //
345 /*G4double G4Type1GlauberParameterisation::GetInverseValueM (const G4int b,
346  const G4int ig) const
347 {
348  G4double v = 0.0;
349  G4double x = (G4double) b;
350  if (b <= 1) {
351  v = 0.0;
352  }
353  else {
354  G4double f1 = 1.0 + std::pow(paramm[ig][0]/x,mum1[ig]);
355  G4double f2 = 1.0 + std::pow(cm[ig]/x,mum2[ig]);
356  v = std::pow(f1*f2,1.0/paramm[ig][5]);
357  }
358 
359  return v;
360 }*/
362 //
363 #endif