Geant4.10
 All Data Structures 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 //
36 /// \file hadronic/Hadr02/src/G4Type1GlauberParameterisation.cc
37 /// \brief Implementation of the G4Type1GlauberParameterisation class
38 //
39 // $Id: G4Type1GlauberParameterisation.cc 77519 2013-11-25 10:54:57Z gcosmo $
40 //
41 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
42 //
43 // MODULE: G4Type1GlauberParameterisation.cc
44 //
45 // Version: 0.B
46 // Date: 02/04/08
47 // Author: P R Truscott
48 // Organisation: QinetiQ Ltd, UK
49 // Customer: ESA/ESTEC, NOORDWIJK
50 // Contract: 19770/06/NL/JD
51 //
52 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
53 ///////////////////////////////////////////////////////////////////////////////
54 //
55 #ifdef G4_USE_DPMJET
56 
58 #include "G4PhysicalConstants.hh"
59 #include "G4SystemOfUnits.hh"
60 
61 using namespace std;
62 
63 //
64 //
65 // The following function performs a polynomial least squares fit to double
66 // precision data. It forms part of the CERN mathlib. This is a really
67 // beyond standard policy and will eventually be changed to a C++ function.
68 //
69 extern "C" {void dlsqpm_ (int*,double*,double*,int*,double*,double*,int*);}
70 
71 ////////////////////////////////////////////////////////////////////////////////
72 //
74 {
75  limit1 = 0.1;
76  limit2 = 0.60;
77  limit3 = 0.95;
78  limit4 = 0.9999;
79 
80  maxArrayp = 200;
81  maxigp = 24;
82 
83  for (G4int ig=0; ig<maxigp; ig++) {
84  for (G4int j=0; j<10; j++) {
85  paramn[ig][j] = 0.0;
86  paramn[ig][j] = 0.0;
87  }
88  mun1[ig] = 0.0;
89  mun2[ig] = 0.0;
90  cn[ig] = 0.0;
91  mum1[ig] = 0.0;
92  mum2[ig] = 0.0;
93  cm[ig] = 0.0;
94  }
95 }
96 ////////////////////////////////////////////////////////////////////////////////
97 //
99 {;}
100 ////////////////////////////////////////////////////////////////////////////////
101 //
103  (const G4double *bsite, G4double *p) const
104 {
105 //
106 //
107 // Initialise parameters.
108 //
109  G4int pt1 = -1;
110  G4int pt2 = -1;
111  G4int pt3 = -1;
112  G4int pt4 = -1;
113 //
114 //
115 // Locate transitions between different parts of the curve where different
116 // fits are used.
117 //
118  G4double ib[200];
119  G4double lnib[200];
120  G4double lnbsite[200];
121  for (G4int i=0; i<maxArrayp; i++) {
122  ib[i] = (G4double) i;
123  lnib[i] = std::log(ib[i]);
124  if (bsite[i] < 1.0E-10) lnbsite[i] = -23.02585093;
125  else lnbsite[i] = std::log(bsite[i]);
126  if (pt1 == -1) {
127  if (bsite[i] >= limit1) pt1 = i;
128  }
129  else if (pt2 == -1) {
130  if (bsite[i] >= limit2) pt2 = i;
131  }
132  else if (pt3 == -1) {
133  if (bsite[i] >= limit3) pt3 = i;
134  }
135  else if (pt4 == -1) {
136  if (bsite[i] >= limit4) pt4 = i;
137  }
138  }
139 //
140 //
141 // First section determines the power-law fits for the low and intermediate b
142 // values;
143 //
144  G4int deltan = pt2 - pt1;
145  G4int M = 1;
146  G4double a1[2];
147  G4double sd;
148  G4int ifail;
149  dlsqpm_ (&deltan,&lnbsite[pt1],&lnib[pt1],&M,&a1[0],&sd,&ifail);
150 
151  G4double c1 = a1[0];
152  G4double M1 = a1[1];
153 
154 // G4double M2 = (lnib[3] - lnib[2]) / (lnbsite[3] - lnbsite[2]);
155 // G4double c2 = lnib[2] - M2*lnbsite[2];
156  deltan = 3;
157  dlsqpm_ (&deltan,&lnbsite[1],&lnib[1],&M,&a1[0],&sd,&ifail);
158 
159  G4double c2 = a1[0];
160  G4double M2 = a1[1];
161 
162  p[0] = std::exp(c2);
163  p[1] = M2;
164  p[2] = std::exp(c1);
165  p[3] = M1;
166  if (std::abs(M2-M1) > 1.0E-10) {
167  p[4] = exp(-(c2-c1)/(M2-M1));
168  }
169  else {
170  p[4] = limit2 / 2.0;
171  }
172 //
173 //
174 // This next bit solves for gamma to determine the inflection at high-b values.
175 // The algorthM used is EXTREEEEEMELY crude .... but practical and robust.
176 // It's a linear search.
177 //
178  G4double delta = 1.0E+99;
179  G4double gam = 0.0;
180  for (G4int ig = 120; ig < 1000; ig++) {
181  G4double DELTA = 0.0;
182  G4double GAMMA = (G4double) ig / 100.0;
183  G4double EXPON = p[3] / GAMMA;
184  for (G4int i = pt2; i<pt3; i++) {
185  G4double f = bsite[i];
186  G4double B = p[2] * std::pow(f,p[3]) /
187  std::pow((1.0-std::pow(f,GAMMA)),EXPON);
188  G4double epsilon = std::abs((ib[i]-B)/ib[i]);
189  if (epsilon > DELTA) DELTA = epsilon;
190  }
191  if (DELTA < delta) {
192  gam = GAMMA;
193  delta = DELTA;
194  }
195  }
196  p[5] = gam;
197 //
198 //
199 // For the final part of the curve, we use a cubic polynomial
200 // fit to -ln(1-bsite)
201 // versus ib. This does seem to work quite well.
202 //
203  G4double phi[200];
204  for (G4int i = pt3; i<pt4; i++) {
205  phi[i] = -std::log(1.0 - bsite[i]);
206  }
207  deltan = pt4-pt3;
208  M = 3;
209  G4double a2[4];
210 
211  dlsqpm_ (&deltan,&phi[pt3],&ib[pt3],&M,&a2[0],&sd,&ifail);
212 
213  p[6] = a2[0];
214  p[7] = a2[1];
215  p[8] = a2[2];
216  p[9] = a2[3];
217 
218  return 0.0;
219 }
220 ////////////////////////////////////////////////////////////////////////////////
221 //
222 // GetValueN
223 //
224 G4double
226  const G4double ppn) const
227 {
228  G4int ig = 0;
229  if (ppn < 1.0E-10) {
230  return 0;
231  }
232  else {
233  ig = G4int(2.0*std::log10(ppn)) - 2;
234  }
235  if (ig < 0) ig = 0;
236  else if (ig > 23) ig = 23;
237 
238  G4double v = 0.0;
239  if (f <= paramn[ig][4]) {
240  v = paramn[ig][0] * std::pow(f,paramn[ig][1]);
241  }
242  else if (f <= limit3) {
243  v = paramn[ig][2] * std::pow(f,paramn[ig][3]) /
244  std::pow((1.0 - std::pow(f,paramn[ig][5])),paramn[ig][3]/paramn[ig][5]);
245  }
246  else {
247  G4double l = -std::log(1.0-f);
248  v = paramn[ig][6] +
249  paramn[ig][7]*l +
250  paramn[ig][8]*l*l +
251  paramn[ig][9]*std::pow(l,3.0);
252  }
253 
254  return v;
255 }
256 ////////////////////////////////////////////////////////////////////////////////
257 //
258 // GetValueM
259 //
260 G4double
262  const G4double ppn) const
263 {
264  G4int ig = 0;
265  if (ppn < 1.0E-10) {
266  return 0;
267  }
268  else {
269  ig = G4int(2.0*std::log10(ppn)) - 2;
270  }
271  if (ig < 0) ig = 0;
272  else if (ig > 23) ig = 23;
273 
274  G4double v = 0.0;
275  if (f <= paramm[ig][4]) {
276  v = paramm[ig][0] * std::pow(f,paramm[ig][1]);
277  }
278  else if (f <= limit3) {
279  v = paramm[ig][2] * std::pow(f,paramm[ig][3]) /
280  std::pow((1.0 - std::pow(f,paramm[ig][5])),paramm[ig][3]/paramm[ig][5]);
281  }
282  else {
283  G4double l = -std::log(1.0-f);
284  v = paramn[ig][6] +
285  paramn[ig][7]*l +
286  paramn[ig][8]*l*l +
287  paramn[ig][9]*std::pow(l,3.0);
288  }
289 
290  return v;
291 }
292 ////////////////////////////////////////////////////////////////////////////////
293 //
294 // GetInverseValueN
295 //
296 /*G4double G4Type1GlauberParameterisation::GetInverseValueN (const G4int b,
297  const G4double ppn) const
298 {
299  G4int ig = 0;
300  if (ppn < 1.0E-10) {
301  return 0;
302  }
303  else {
304  ig = G4int(2.0*std::log10(ppn)) - 2;
305  }
306  if (ig > 23) ig = 23;
307 
308  return GetInverseValueN(b,ig);
309 }*/
310 ////////////////////////////////////////////////////////////////////////////////
311 //
312 // GetInverseValueM
313 //
314 /*G4double G4Type1GlauberParameterisation::GetInverseValueM (const G4int b,
315  const G4double ppn) const
316 {
317  G4int ig = 0;
318  if (ppn < 1.0E-10) {
319  return 0;
320  }
321  else {
322  ig = G4int(2.0*std::log10(ppn)) - 2;
323  }
324  if (ig > 23) ig = 23;
325 
326  return GetInverseValueN(b,ig);
327 }*/
328 ////////////////////////////////////////////////////////////////////////////////
329 //
330 // GetInverseValueN
331 //
332 /*G4double G4Type1GlauberParameterisation::GetInverseValueN (const G4int b,
333  const G4int ig) const
334 {
335  G4double v = 0.0;
336  G4double x = (G4double) b;
337  if (b <= 1) {
338  v = 0.0;
339  }
340  else {
341  G4double f1 = 1.0 + std::pow(paramn[ig][0]/x,mun1[ig]);
342  G4double f2 = 1.0 + std::pow(cn[ig]/x,mun2[ig]);
343  v = std::pow(f1*f2,1.0/paramn[ig][5]);
344  }
345 
346  return v;
347 }*/
348 ////////////////////////////////////////////////////////////////////////////////
349 //
350 // GetInverseValueM
351 //
352 /*G4double G4Type1GlauberParameterisation::GetInverseValueM (const G4int b,
353  const G4int ig) const
354 {
355  G4double v = 0.0;
356  G4double x = (G4double) b;
357  if (b <= 1) {
358  v = 0.0;
359  }
360  else {
361  G4double f1 = 1.0 + std::pow(paramm[ig][0]/x,mum1[ig]);
362  G4double f2 = 1.0 + std::pow(cm[ig]/x,mum2[ig]);
363  v = std::pow(f1*f2,1.0/paramm[ig][5]);
364  }
365 
366  return v;
367 }*/
368 ////////////////////////////////////////////////////////////////////////////////
369 //
370 #endif
G4double GetParameterisedValueN(const G4double f, const G4double ppn) const
const char * p
Definition: xmltok.h:285
int G4int
Definition: G4Types.hh:78
G4double GetFitParameters(const G4double *bsite, G4double *p) const
Definition of the G4Type1GlauberParameterisation class.
double G4double
Definition: G4Types.hh:76
tuple c1
Definition: plottest35.py:14
G4double GetParameterisedValueM(const G4double f, const G4double ppn) const