source: trunk/source/processes/electromagnetic/lowenergy/src/G4PenelopeInterpolator.cc @ 1196

Last change on this file since 1196 was 819, checked in by garnier, 16 years ago

import all except CVS

File size: 7.0 KB
Line 
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// Author:  Luciano Pandola (Luciano.Pandola@cern.ch)
29//
30// History:
31// -----------
32// 17 Feb 2003   LP        Created
33// 17 Dec 2003   LP        Removed memory leak
34// 17 Mar 2004   LP        Removed unnecessary calls to std::pow(a,b)
35//
36// -------------------------------------------------------------------
37
38#include "G4PenelopeInterpolator.hh"
39#include "G4DataVector.hh"
40
41G4PenelopeInterpolator::G4PenelopeInterpolator(G4double* pX,G4double* pY,G4int nOfData,G4double S1,G4double SN) :
42  a(0),b(0),c(0),d(0),x(0),y(0)
43{
44  // pX = X grid points (ascending order)
45  // pY = corresponding function values
46  // nOfData = number of points in the grid > 4
47  // S1 and S2 = second derivatives at X[0] and X[nOfData-1]
48  a = new G4DataVector;
49  b = new G4DataVector;
50  c = new G4DataVector;
51  d = new G4DataVector;
52
53  if (nOfData < 4 )
54    {
55      G4String excep = "Spline interpolation cannot be performed with less than 4 points";
56      G4Exception(excep);
57    }
58
59  G4int N1=nOfData-1;
60  G4int N2=nOfData-2;
61  G4int i;
62  G4int k=0;
63  G4DataVector A(N1),B(N2),D(nOfData);//auxiliary arrays
64  A.clear();
65  B.clear();
66  D.clear();
67  for (i=0;i<N1;i++){
68    if ((pX[i+1]-pX[i]) < 1.0e-13) 
69      {
70        G4String excep = "Spline x values not in increasing order";
71        G4Exception(excep);
72      }
73    A.push_back(pX[i+1]-pX[i]);
74    D.push_back((pY[i+1]-pY[i])/A[i]);
75  }
76 
77  //Symmetric coefficient matrix
78  for (i=0;i<N2;i++){
79    B.push_back(2.0*(A[i]+A[i+1]));
80    k=N1-i-1;
81    D[k]=6.0*(D[k]-D[k-1]);
82  }
83  D[1]=D[1]-A[0]*S1;
84  D[N1-1]=D[N1-1]-A[N1-1]*SN;
85 
86  //Gauss solution of the tridiagonal system
87  for (i=1;i<N2;i++){
88    G4double R=A[i]/B[i-1];
89    B[i]=B[i]-R*A[i];
90    D[i+1]=D[i+1]-R*D[i];
91  }
92
93  //The sigma coefficients are stored in array D
94  D[N1-1]=D[N1-1]/B[N2-1];
95  for (i=1;i<N2;i++){
96    k=N1-i-1;
97    D[k]=(D[k]-A[k]*D[k+1])/B[k-1];
98  }
99  D.push_back(SN);
100
101  //Spline coefficients
102  G4double SI1=S1;
103  G4double SI=0,H=0,HI=0;
104  G4double store=0;
105  G4double help1=0;
106  G4double help2=0;
107
108  for (i=0;i<N1;i++){
109    SI=SI1;
110    SI1=D[i+1];
111    H=A[i];
112    HI=1.0/H;
113    help1 = pX[i+1]*pX[i+1]*pX[i+1];
114    help2 = pX[i]*pX[i]*pX[i];
115    store=HI*(SI*help1-SI1*help2)/6.0+HI*(pY[i]*pX[i+1]-pY[i+1]*pX[i])+
116      H*(SI1*pX[i]-SI*pX[i+1])/6.0;
117    a->push_back(store);
118    store=(HI/2.0)*(SI1*(pX[i]*pX[i])-SI*(pX[i+1]*pX[i+1]))+HI*(pY[i+1]-pY[i])+(H/6.0)*(SI-SI1);
119    b->push_back(store);
120    store=(HI/2.0)*(SI*pX[i+1]-SI1*pX[i]);
121    c->push_back(store);
122    store=(HI/6.0)*(SI1-SI);
123    d->push_back(store);
124  }
125  //Natural cubic spline for x > x[nOfData-1]
126  G4double FN=pY[nOfData-1];
127  store=(*b)[N1-1]+pX[nOfData-1]*(2.0*(*c)[N1-1]+pX[nOfData-1]*3.0*(*d)[N1-1]);
128  a->push_back(FN-pX[nOfData-1]*store);
129  b->push_back(store);
130  c->push_back(0.0);
131  d->push_back(0.0);
132
133  x = new G4DataVector;
134  y = new G4DataVector;
135
136  for (i=0;i<nOfData;i++){
137    x->push_back(pX[i]);
138    y->push_back(pY[i]);
139  }
140  return;
141}
142
143G4PenelopeInterpolator::~G4PenelopeInterpolator()
144{
145  delete a;
146  delete b;
147  delete c;
148  delete d;
149  delete x;
150  delete y;
151}
152
153G4double G4PenelopeInterpolator::CubicSplineInterpolation(G4double xx)
154{
155  G4double interp=0;
156  G4int index = FindBin(xx);
157  interp=(*a)[index]+xx*((*b)[index]+xx*((*c)[index]+xx*(*d)[index]));
158  return interp;
159}
160
161G4double G4PenelopeInterpolator::FirstDerivative(G4double xx)
162{
163  G4double interp=0;
164  G4int index = FindBin(xx);
165  interp=(*b)[index]+xx*((*c)[index]*2.0+xx*(*d)[index]*3.0);
166  return interp;
167}
168
169G4double G4PenelopeInterpolator::CalculateMomentum(G4double UpperLimit,
170                                                          G4int MomentumOrder)
171{
172  G4int i;
173  G4int nOfData = (G4int) x->size();
174  const G4double eps=1.0e-35;
175  if (MomentumOrder < -1) G4Exception("Calculate Momentum: error 0");
176  if (nOfData < 2) G4Exception("Calculate Momentum: error 1");
177  if ((*x)[0]<0) G4Exception("Calculate Momentum: error 2");
178  for (i=1;i<nOfData;i++)
179    {
180      if ((*x)[i]<0) G4Exception("Calculate Momentum: error 3");
181      if ((*x)[i] < (*x)[i-1]) G4Exception ("Calculate Momentum: error 4");
182    }
183
184  G4double RMom=0.0;
185  if (UpperLimit < (*x)[0]) return RMom;
186  G4int iend=0;
187  G4double xt=std::min(UpperLimit,(*x)[nOfData-1]);
188  G4double x1,x2,y1,y2;
189  G4double xtc,dx,dy,a1,b1,ds;
190  for (i=0;i<(nOfData-1);i++){
191    x1=std::max((*x)[i],eps);
192    y1=(*y)[i];
193    x2=std::max((*x)[i+1],eps);
194    y2=(*y)[i+1];
195    if (xt < x2) 
196      {
197      xtc=xt;
198      iend=1;
199      }
200    else
201      {
202        xtc=x2;
203      }
204    dx=x2-x1;
205    dy=y2-y1;
206    if (std::abs(dx) > (1e-14*std::abs(dy))) 
207      {
208        b1=dy/dx;
209        a1=y1-b1*x1;
210        if (MomentumOrder == -1) 
211          {
212            ds=a1*std::log(xtc/x1)+b1*(xtc-x1);
213          }
214        else
215          {
216            ds=a1*(std::pow(xtc,MomentumOrder+1)-std::pow(x1,MomentumOrder+1))/ ((G4double) (MomentumOrder+1))+
217              b1*(std::pow(xtc,MomentumOrder+2)-std::pow(x1,MomentumOrder+2))/((G4double) (MomentumOrder+2));
218          }
219      }
220    else
221      {
222        ds=0.5*(y1+y2)*std::pow((xtc-x1),MomentumOrder);
223      }
224    RMom += ds;
225    if (iend != 0) return RMom;
226  }
227  return RMom;
228}
229                     
230G4int G4PenelopeInterpolator::FindBin(G4double xx)
231{
232  //Finds the interval x[i],x[i+1] which contains the value xx
233
234  G4int nbOfPoints=x->size();
235 
236  if (xx > (*x)[nbOfPoints-1])
237    {
238      return (nbOfPoints-1);
239    }
240  if (xx < (*x)[0])
241    {
242      return 0;
243    }
244  G4int i=0,i1=nbOfPoints-1;
245  do{
246    G4int it=(i+i1)/2;
247    if (xx > (*x)[it]) 
248      {
249        i=it;
250      }
251    else
252      {
253        i1=it;
254      }
255  } while((i1-i) > 1);
256  return i;
257}
258
259
260
261 
Note: See TracBrowser for help on using the repository browser.