/home/cern/BDSIM_new/src/BDSSpline.cc

00001 /* BDSIM code.    Version 1.0
00002    Author: Grahame A. Blair, Royal Holloway, Univ. of London.
00003    Last modified 24.7.2002
00004    Copyright (c) 2002 by G.A.Blair.  ALL RIGHTS RESERVED. 
00005 */
00006 
00007 #include "globals.hh"
00008 #include "BDSSpline.hh"
00009 //---------------
00010 BDSSpline::BDSSpline(G4int nIn):n(nIn)
00011 {
00012   G4int i;
00013   u= *(new vDbl(n));
00014   tab=*(new vTab(n));
00015   for(i=0;i<n;i++) tab[i]=new BDSSpline_tab_entry();
00016 
00017 }
00018 
00019 void BDSSpline::initialise(vDbl* xIn,G4int xscalIn, 
00020                            vDbl* yIn,G4int yscalIn)
00021 {
00022   G4int i;
00023   G4double sig,p;  
00024   
00025   xscal=xscalIn;
00026   yscal=yscalIn;
00027   
00028   BDSSpline_tab_entry* tabEntry=tab[0];
00029 
00030   tabEntry->y2=0.0;
00031 
00032  
00033   for (i=0;i<n;i++)
00034     {
00035       BDSSpline_tab_entry* tabEntry=tab[i];
00036       switch (xscal){
00037       case 0:
00038         tabEntry->x=(*xIn)[i];
00039         break;
00040       case 1:
00041         tabEntry->x=log((*xIn)[i]);
00042         break;
00043       }
00044       switch (yscal){
00045       case 0:
00046         tabEntry->y=(*yIn)[i];
00047         break;
00048       case 1:
00049         tabEntry->y=log((*yIn)[i]);
00050         break;
00051       }     
00052     }
00053  
00054   u[0]=0.0;
00055   for (i=1;i<n-1;i++)
00056     {
00057       BDSSpline_tab_entry* tab_i=tab[i];
00058       BDSSpline_tab_entry* tab_im1=tab[i-1];
00059       BDSSpline_tab_entry* tab_ip1=tab[i+1];
00060 
00061       sig=(tab_i->x-tab_im1->x)/(tab_ip1->x-tab_im1->x);
00062       
00063       p=1.0/(sig*tab_im1->y2+2.0);
00064 
00065       tab_i->y2=(sig-1.0)*p;    
00066       u[i]=
00067         (6.0*((tab_ip1->y-tab_i->y)/(tab_ip1->x-tab_i->x) 
00068               -(tab_i->y-tab_im1->y)/(tab_i->x-tab_im1->x)) 
00069          /(tab_ip1->x -tab_im1->x)  - sig*u[i-1])*p;
00070     }
00071 
00072   BDSSpline_tab_entry* tab_nm1=tab[n-1];
00073 
00074   tab_nm1->y2=0.0;
00075   for (i=n-2;i>=0;i--)
00076     {
00077       BDSSpline_tab_entry* tab_i=tab[i];
00078       BDSSpline_tab_entry* tab_ip1=tab[i+1];
00079       
00080       tab_i->y2=tab_i->y2*tab_ip1->y2+u[i];
00081     }
00082 }
00083 
00084 G4double BDSSpline::integrate(G4double xIn)
00085 {
00086   int kmin,kmax,kpoint;
00087   double a,b,w;
00088 
00089   kmin=0;
00090   kmax=n-1;
00091 
00092   BDSSpline_tab_entry* tab_kmx=tab[kmax];
00093   BDSSpline_tab_entry* tab_kmn=tab[kmin];
00094   BDSSpline_tab_entry* tab_0=tab[0];
00095 
00096   switch(xscal){
00097   case 0:       
00098     break;
00099   case 1:
00100     xIn=log(xIn);
00101     break;
00102 }
00103  
00104   if (xIn>tab_kmx->x)
00105     {
00106       if (yscal)return exp(tab_kmx->y);
00107       else return tab_kmx->y; 
00108     }
00109   if (xIn<tab_0->x)
00110     {
00111       if (yscal) return exp(tab_0->y);
00112       else return tab_0->y;
00113     }
00114   while (kmax-kmin>1){
00115     kpoint=(kmax+kmin)/2;
00116     BDSSpline_tab_entry* tab_kpt=tab[kpoint];
00117     
00118     if (tab_kpt->x>xIn) kmax=kpoint;
00119     else kmin=kpoint;
00120   }
00121 
00122   w=tab_kmx->x - tab_kmn->x;
00123 
00124   a=(tab_kmx->x-xIn)/w;
00125 
00126   b=(xIn-tab_kmn->x)/w;
00127   G4double x=a*tab_kmn->y+b*tab_kmx->y+
00128     (a*(a*a-1.0)*tab_kmn->y2
00129      +b*(b*b-1.0)*tab_kmx->y2)*w*w/6.0;
00130 
00131   switch (yscal){
00132   case 0:
00133     return x;
00134   case 1:
00135     return exp(x);
00136   }
00137   return x;
00138 }
00139 
00140 
00141 BDSSpline::~BDSSpline()
00142 {
00143   size_t i;
00144   for(i=0;i<tab.size();i++)
00145     if(tab[i]) delete tab[i];
00146   if(&tab)delete &tab;
00147 
00148   if(&u) delete &u;
00149 
00150 }
00151 

Generated on Wed Mar 5 17:25:23 2008 for BDSIM by  doxygen 1.5.3