libcpixe/stop96.c

Go to the documentation of this file.
00001 
00002 /***************************************************************************
00003     Copyright (C) 2007 by Carlos Pascual-Izarra
00004     carlos.pascual_AT_users.sourceforge.net                                                  *
00005 
00006     This program is free software: you can redistribute it and/or modify
00007     it under the terms of the GNU General Public License as published by
00008     the Free Software Foundation, either version 3 of the License, or
00009     (at your option) any later version.
00010 
00011     This program is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014     GNU General Public License for more details.
00015 
00016     You should have received a copy of the GNU General Public License
00017     along with this program.  If not, see <http://www.gnu.org/licenses/>.
00018 
00019     -----------------------------------------------------------------
00020     STOP96.c: Ion stopping subroutines used by hotstop
00021     By Carlos Pascual-Izarra
00022     This is a C version of the STOP96 subroutine by J.F.Ziegler for
00023     being used in TRIM / SRIM. The original from Ziegler was written
00024     in BASIC.
00025 
00026     IMPORTANT:
00027     It must be clear that J.F.Ziegler or any other person related to
00028     TRIM/SRIM have absolutely no responsability of any limitation or
00029     bug related to the present code.
00030 
00031     The following is the license notice of SRIM:
00032 
00033     "SRIM.EXE, (C) 1984-2002, James F. Ziegler
00034     Permission to use, copy, modify and distribute
00035     this software for any non-commercial purpose and
00036     without fee is hereby granted, provided that
00037     this copyright and permission notice appear
00038     on all copies of the software. The name of
00039     the author may not be used in any advertising
00040     or publicity pertaining to the use of the software.
00041     The author makes no warranty or representations
00042     about the suitability of the software for any
00043     purpose. It is provided "AS IS" without any express
00044     or implied warranty, including the implied warranties
00045     of merchantability, fitness for a particular purpose
00046     and non-infringement. The author shall not be liable
00047     for any direct, indirect, special or consequential
00048     damages resulting from the loss of use, data or
00049     projects, whether in an action of contract or tort,
00050     arising out of or in connection with the use or
00051     performance of this software. Downloading any
00052     software from this site is implicit acceptance of
00053     these conditions. The term "SRIM" as used to
00054     refer to topics concerning the  Stopping and
00055     Range of Ions in Matter is copyright registered
00056     in the United States Copyright Office and may
00057     not be used for commercial purposes without permission.
00058     For commercial applications, licenses may be obtained
00059     for incorporating SRIM into applications by writing to
00060     SRIM.org."
00061 
00062  */
00067 #include <stdio.h>
00068 #include <stdlib.h>
00069 #include <math.h>     /* REMEMBER: use -lm when compiling */
00070 #include "stop96.h"  /*Contains the definitions for the stop96.c functions*/
00071 #include "compilopt.h"
00072 
00073 
00074 void readstopcoef(char *afilename, char *bfilename)
00075 {
00076 /*Fills the scoef[94,55] array with the data in SCOEF.95A and SCOEF.95B files*/
00077 /* scoef[94,55] must be previously declared as a global variable */
00078 /*Note: the row 0 and column 0 of scoef are not used to follow the BASIC standard of labelling arrays: SCOEF(1:93,1:55)*/
00079 
00080 FILE *afile, *bfile;
00081 int i,j;
00082 char stemp[300];
00083 
00084 /*Open files*/
00085 if (!(afile=fopen(afilename, "r"))){fprintf(stderr, "\ncannot open '%s' for read\n",afilename);exit(1);}
00086 if (!(bfile=fopen(bfilename, "r"))){fprintf(stderr, "\ncannot open '%s' for read\n",bfilename);exit(1);}
00087 
00088 /*Skip headers*/
00089 for(i=0;i<2;i++) fgets(stemp,300,afile) ;  /*Skip Headers in file A*/
00090 for(i=0;i<2;i++) fgets(stemp,300,bfile) ;  /*Skip Headers in file B*/
00091 
00092 /*fill scoef*/
00093 for(i=1;i<=93;i++) for(j=1;j<=16;j++)fscanf(afile,"%f",&scoef[i][j]);
00094 for(i=1;i<=93;i++) for(j=17;j<=54;j++)fscanf(bfile,"%f",&scoef[i][j]);
00095 
00096 
00097 /*Close files*/
00098 fclose(afile);
00099 fclose(bfile);
00100 }
00101 
00102 float pstop(int Z2, float E)
00103 {
00104 
00105 /* scoef[94,55] must be previously declared as a global variable */
00106 float X,SL,SH,ppower,Sproton;
00107 float PE0;
00108 PE0=10;
00109 /*High (E>10000keV/amu) energy stopping*/
00110 if(E>1e4){
00111   X=logf(E)/E;
00112   Sproton=scoef[Z2][17]+(scoef[Z2][18]*X)+(scoef[Z2][19]*X*X)+(scoef[Z2][20]/X);
00113   }
00114 /*Medium energies: (PE0<E<1e4)  , PE0=is the low limit for "medium" energy range (in kev/amu)*/
00115 else if (E>PE0){
00116   SL=scoef[Z2][9]*powf(E,scoef[Z2][10])+scoef[Z2][11]*powf(E,scoef[Z2][12]);
00117   SH=scoef[Z2][13]/powf(E,scoef[Z2][14])*logf((scoef[Z2][15]/E)+scoef[Z2][16]*E);
00118   Sproton=SL*SH/(SL+SH);
00119   }
00120 /*Low energies (E<PE0) : approx velocity proportional stopping power, conveniently scaled for continuity with medium E range*/
00121 else if(E>0){
00122   if(Z2<7)ppower=0.35; else ppower=0.45;
00123   SL=scoef[Z2][9]*powf(PE0,scoef[Z2][10])+scoef[Z2][11]*powf(PE0,scoef[Z2][12]);
00124   SH=scoef[Z2][13]/powf(PE0,scoef[Z2][14])*logf((scoef[Z2][15]/PE0)+scoef[Z2][16]*PE0);
00125   Sproton=(SL*SH/(SL+SH))*powf(E/PE0,ppower);
00126   }
00127 else Sproton=0.;
00128 
00129 return(Sproton);
00130 }
00131 
00132 
00133 float pstop_fit(int Z2,float E,float P0,float P1,float P2,float P3,float P4,float P5,float P6,float P7,float HE0,float HE1,float HE2,float HE3)
00134 {
00135 /*This function is identical to pstop but it gets all the parameters from its arguments instead of looking at scoef[Z2][x]*/
00136 float X,SL,SH,ppower,Sproton;
00137 float PE0;
00138 PE0=10;
00139 /*High (E>10000keV/amu) energy stopping*/
00140 if(E>1e4){
00141   X=logf(E)/E;
00142   Sproton=HE0+(HE1*X)+(HE2*X*X)+(HE3/X);
00143   }
00144 /*Medium energies: (PE0<E<1e4)  , PE0=is the low limit for "medium" energy range (in kev/amu)*/
00145 else if (E>PE0){
00146   SL=P0*powf(E,P1)+P2*powf(E,P3);
00147   SH=P4/powf(E,P5)*logf((P6/E)+P7*E);
00148   Sproton=SL*SH/(SL+SH);
00149   }
00150 /*Low energies (E<PE0) : approx velocity proportional stopping power, conveniently scaled for continuity with medium E range*/
00151 else if(E>0){
00152   if(Z2<7)ppower=0.35; else ppower=0.45;
00153   SL=P0*powf(PE0,P1)+P2*powf(PE0,P3);
00154   SH=P4/powf(PE0,P5)*logf((P6/PE0)+P7*PE0);
00155   Sproton=(SL*SH/(SL+SH))*powf(E/PE0,ppower);
00156   }
00157 else Sproton=0.;
00158 
00159 return(Sproton);
00160 }
00161 
00162 void stop96(int Z1, int Z2,float Ionweight, float *Ener, int nEner, float *SE){
00163 
00164 /*
00165 Z1=incident ion atomic number
00166 Z2=target atomic number
00167 M1=Weight of incident ion (if M1<1, the Most Abundant Isotope weight associated to Z1 in SCOEF.95A will be used)
00168 Ener= pointer to vector of nEner components storing the list of energies wanted (in keV)
00169 nEner=dim of Ener as well as of SE
00170 SE=pointer to a vector of nEner components where the resultin stoppings will be stored (ev/1e15atcm-2)
00171 
00172 
00173 */
00174 float M1,tempf,VFERMI,E,HE0,HE,B,HEH,YRMIN,VRMIN,V,VR,YR,Q,LAMBDA0,LAMBDA1,L,ZETA0,ZETA,VMIN,EEE,Sproton,EION,VFCORR0,VFCORR1,HIPOWER;
00175 int i,j;
00176 
00177 /*Do checks*/
00178 if(Z1<1 || Z1>92) {fprintf(stderr, "\nError: Z1 must be between 1 and 92 \n");exit(1);}
00179 if(Z2<1 || Z2>92) {fprintf(stderr, "\nError: Z2 must be between 1 and 92 \n");exit(1);}
00180 if(nEner<1){fprintf(stderr, "\nError: I need at least one energy  \n");exit(1);}
00181 
00182 
00183 /*Fill some variables with data*/
00184 VFERMI= scoef[Z2][7];       /*VFermi of Target*/
00185 if(Ionweight<1)M1=scoef[Z1][3]; else M1=Ionweight;    /*MOI weight if M1 wasn't specified*/
00186 
00187 /*Loop for stopping values*/
00188 for(i=0;i<nEner;i++){
00189   E=Ener[i]/M1;
00190 
00191   if(Z1==1){ /*stop_H*/
00192     SE[i]=pstop(Z2,E);
00193     }
00194 
00195 
00196   else if(Z1==2){ /*stop_He */
00197     HE0=1;                            /*Minimum limit for "medium" energy range for He (units=keV/amu)*/
00198     if(HE0>E)HE=HE0;else HE=E;        /*HE=max{E,HE0}*/
00199     B=logf(HE);
00200     tempf=.2865+.1266*B-.001429*B*B+.02402*B*B*B-.01135*powf(B,4)+.001475*powf(B,5);
00201     if(tempf>30) tempf=30;
00202     HEH=1.-expf(-tempf);
00203     /* ADD Z1^3 EFFECT TO HE/H STOPPING POWER RATIO, HEH */
00204     if(HE<1)HE=1;  /*I think this assertion is innecessary!!!! (it its in the original code but seems redundant)???????*/
00205     tempf=(1.+(.007+.00005*Z2)*expf(-powf(7.6-logf(HE),2)));
00206     HEH*=(tempf*tempf);
00207     SE[i]=pstop(Z2,HE)*HEH*4.;
00208     /* If E was lower than HE0 , CALC. HE VELOCITY PROPORTIONAL STOPPING (low energy range)*/
00209     if(HE0>E)SE[i]*=sqrtf(E/HE0);
00210     }
00211 
00212 
00213   else if(Z1>2){ /*stop_HI*/
00214     /*USE VELOCITY STOPPING FOR (YRMIN=VR/Z1**.67) <= 0.13  _OR_  VR<=1.0*/
00215     YRMIN=0.13;   /*Minimum limit for YR*/
00216     VRMIN=1.0;    /*Minimum limit for VR*/
00217     V=sqrtf(E/25.)/VFERMI;  /*V is the "relative velocity" but...relative to what????? (Fermi, Bohr,...????)*/
00218     if(V<1) VR=(3.*VFERMI/4.)*(1+(2.*V*V/3.)-powf(V,4.)/15.);
00219     else VR=V*VFERMI*(1.+1./(5.*V*V));
00220     /*put a minimum limit to VR*/
00221     if(VR<VRMIN)VR=VRMIN;
00222     /*calc YR as VR/Z1^(2/3) and put a minimum limit to it*/
00223     YR=VR/powf(Z1,.6667);
00224     if(YR<YRMIN)YR=YRMIN;
00225     /*Calculate the Ionization level (Q) of the ion at velocity YR*/
00226     tempf=-.803*powf(YR,0.3)+1.3167*powf(YR,0.6)+.38157*YR+.008983*YR*YR;
00227     if(tempf>50.)Q=1; else if(tempf<=0)Q=0; else  Q=1.-expf(-tempf);    /*It prevents underflow and wasting of time  in the Q calc. */
00228     /*NOW WE CONVERT IONIZATION LEVEL TO EFFECTIVE CHARGE
00229     ---------------------- Screening Distance of Ion (Lambda in B.& K.)*/
00230     for(j=22; j<=39 && scoef[93][j]<Q ;j++);j-=1;  /*Find Q Interpolation in SCOEF(93,22-39)*/
00231     if(j<22)j=22;else if(j>38)j=38; /*Boilerplate ??*/
00232     LAMBDA0=scoef[Z1][j];
00233     LAMBDA1=(Q-scoef[93][j])*(scoef[Z1][j+1]-scoef[Z1][j])/(scoef[93][j+1]-scoef[93][j]);
00234     L=(LAMBDA0+LAMBDA1)/powf(Z1,.33333);
00235     ZETA0=Q+(1./(2.*VFERMI*VFERMI))*(1.-Q)*logf(1+powf((4.*L*VFERMI/1.919),2));
00236     if(E>1)tempf=logf(E);else tempf=0;
00237     ZETA=ZETA0*(1.+(1./(Z1*Z1))*(.08+.0015*Z2)*expf(-powf((7.6-tempf),2)));
00238     /*Calculate stopping for low YR*/
00239     tempf=VRMIN/powf(Z1,.6667); if(tempf<YRMIN)tempf=YRMIN;
00240     if(YR<=tempf){
00241       tempf=YRMIN*powf(Z1,.6667);if(VRMIN<tempf)VRMIN=tempf; /*VRMIN must be >= YRMIN^(2/3)*/
00242       tempf=VRMIN*VRMIN-0.8*VFERMI*VFERMI; if(tempf<0)tempf=0;
00243       VMIN=.5*(VRMIN+sqrtf(tempf));
00244       EEE=25*VMIN*VMIN;
00245       Sproton=pstop(Z2,EEE);
00246       /*Add Fermi Velocity Correction to Low Energy value*/
00247       if(EEE<=9999)EION=EEE;else EION=9999; /*Correction is only valid for E <1E4 keV/amu*/
00248       for(j=41;j<=53 && scoef[93][j]<EION ;j++);j-=1;  /*Find E Interpolation in SCOEF(93,41-54)*/
00249       if(j<41)j=41;else if(j>53)j=53; /*Boilerplate ??*/
00250       VFCORR0=scoef[Z2][j];
00251       VFCORR1=(EION-scoef[93][j])*(scoef[Z2][j+1]-scoef[Z2][j])/(scoef[93][j+1]-scoef[93][j]);
00252       /*
00253       Following corrects for low-energy stopping, where little data exists.
00254       Traditionally, this is velocity-proportional stopping, however for
00255       light ions, light targets and semiconductors, a large variation exists.
00256       Note: HIPOWER down = Se up �� LAMBDA down = Se down
00257       */
00258       if(Z1==3)HIPOWER= 0.55;
00259       else if(Z2<7)HIPOWER= 0.375;
00260       else if(Z1<18 && (Z2==14 || Z2==32))HIPOWER= 0.375;
00261       else HIPOWER=.47; /*DEFAULT POWER IF NO SPECIAL CASE. TRIM-88 used 0.5*/
00262       SE[i]=Sproton*powf(ZETA*Z1,2)*(VFCORR0+VFCORR1)*powf((E/EEE),HIPOWER);
00263       }
00264     /*Calculate stopping for NOT low YR*/
00265     else{
00266       Sproton=pstop(Z2,E);
00267       /*Add Fermi Velocity Correction - 1995*/
00268       if(E<=9999)EION=E;else EION=9999; /*Correction is only valid for E <1E4 keV/amu*/
00269       for(j=41;j<=53 && scoef[93][j]<EION ;j++);j-=1;  /*Find E Interpolation in SCOEF(93,41-54)*/
00270       if(j<41)j=41;else if(j>53)j=53; /*Boilerplate ??*/
00271       VFCORR0=scoef[Z2][j];
00272       VFCORR1=(EION-scoef[93][j])*(scoef[Z2][j+1]-scoef[Z2][j])/(scoef[93][j+1]-scoef[93][j]);
00273       SE[i]=Sproton*powf(ZETA*Z1,2)*(VFCORR0+VFCORR1);
00274       }
00275  /*
00276  */
00277 
00278     }
00279   /*SE(I)=SE(I)*10     'This converts Stopping in eV/(1E15-cm2) to eV-A2  */
00280   }
00281 //for(i=0;i<nEner;i++)printf("---  %e\t%e\t%e\n",Ener[i],SE[i],pstop(14,Ener[i]));
00282 }
00283 
00284 
00285 void stop96d(int Z1, int Z2,double Ionweight, double *Ener, int nEner, double *SE){
00286 /*Note this is only a version of  stop96, for programs using
00287 double precission instead of "float". The internal calcs are still
00288  done in single precission!! */
00289 /*
00290 Z1=incident ion atomic number
00291 Z2=target atomic number
00292 M1=Weight of incident ion (if M1<1, the Most Abundant Isotope weight associated to Z1 in SCOEF.95A will be used)
00293 Ener= pointer to vector of nEner components storing the list of energies wanted (in keV)
00294 nEner=dim of Ener as well as of SE
00295 SE=pointer to a vector of nEner components where the resultin stoppings will be stored (ev/1e15atcm-2)
00296 */
00297 
00298 float tempf,VFERMI,E,HE0,HE,B,HEH,YRMIN,VRMIN,V,VR,YR,Q,LAMBDA0,LAMBDA1,L,ZETA0,ZETA,VMIN,EEE,Sproton,EION,VFCORR0,VFCORR1,HIPOWER,M1;
00299 int i,j;
00300 
00301 /*Do checks*/
00302 if(Z1<1 || Z1>92) {fprintf(stderr, "\nError: Z1 must be between 1 and 92 (%d)\n",Z1);exit(1);}
00303 if(Z2<1 || Z2>92) {fprintf(stderr, "\nError: Z2 must be between 1 and 92 (%d)\n",Z2);exit(1);}
00304 if(nEner<1){fprintf(stderr, "\nError: I need at least one energy  \n");exit(1);}
00305 
00306 /*Fill some variables with data*/
00307 VFERMI= scoef[Z2][7];       /*VFermi of Target*/
00308 if(Ionweight<1.)M1=scoef[Z1][3] ;else M1=(float)Ionweight;    /*MOI weight if M1 wasn't specified*/
00309 
00310 
00311 /*Loop for stopping values*/
00312 for(i=0;i<nEner;i++){
00313   E=(float)(Ener[i]/M1);
00314 
00315   if(Z1==1){ /*stop_H*/
00316     SE[i]=(double)pstop(Z2,E);
00317     }
00318 
00319 
00320   else if(Z1==2){ /*stop_He */
00321     HE0=1;                            /*Minimum limit for "medium" energy range for He (units=keV/amu)*/
00322     if(HE0>E)HE=HE0;else HE=E;        /*HE=max{E,HE0}*/
00323     B=logf(HE);
00324     tempf=.2865+.1266*B-.001429*B*B+.02402*B*B*B-.01135*powf(B,4)+.001475*powf(B,5);
00325     if(tempf>30) tempf=30;
00326     HEH=1.-expf(-tempf);
00327     /* ADD Z1^3 EFFECT TO HE/H STOPPING POWER RATIO, HEH */
00328     if(HE<1)HE=1;  /*I think this assertion is innecessary!!!! (it its in the original code but seems redundant)???????*/
00329     tempf=(1.+(.007+.00005*Z2)*expf(-powf(7.6-logf(HE),2)));
00330     HEH*=(tempf*tempf);
00331     SE[i]=(double)(pstop(Z2,HE)*HEH*4.);
00332     /* If E was lower than HE0 , CALC. HE VELOCITY PROPORTIONAL STOPPING (low energy range)*/
00333     if(HE0>E)SE[i]*=(double)sqrtf(E/HE0);
00334     }
00335 
00336 
00337   else if(Z1>2){ /*stop_HI*/
00338     /*USE VELOCITY STOPPING FOR (YRMIN=VR/Z1**.67) <= 0.13  _OR_  VR<=1.0*/
00339     YRMIN=0.13;   /*Minimum limit for YR*/
00340     VRMIN=1.0;    /*Minimum limit for VR*/
00341     V=sqrtf(E/25.)/VFERMI;  /*V is the "relative velocity" but...relative to what????? (Fermi, Bohr,...????)*/
00342     if(V<1) VR=(3.*VFERMI/4.)*(1+(2.*V*V/3.)-powf(V,4.)/15.);
00343     else VR=V*VFERMI*(1.+1./(5.*V*V));
00344     /*put a minimum limit to VR*/
00345     if(VR<VRMIN)VR=VRMIN;
00346     /*calc YR as VR/Z1^(2/3) and put a minimum limit to it*/
00347     YR=VR/powf(Z1,.6667);
00348     if(YR<YRMIN)YR=YRMIN;
00349     /*Calculate the Ionization level (Q) of the ion at velocity YR*/
00350     tempf=-.803*powf(YR,0.3)+1.3167*powf(YR,0.6)+.38157*YR+.008983*YR*YR;
00351     if(tempf>50.)Q=1; else if(tempf<=0)Q=0; else  Q=1.-expf(-tempf);    /*It prevents underflow and wasting of time  in the Q calc. */
00352     /*NOW WE CONVERT IONIZATION LEVEL TO EFFECTIVE CHARGE
00353     ---------------------- Screening Distance of Ion (Lambda in B.& K.)*/
00354     for(j=22; j<=39 && scoef[93][j]<Q ;j++);j-=1;  /*Find Q Interpolation in SCOEF(93,22-39)*/
00355     if(j<22)j=22;else if(j>38)j=38; /*Boilerplate ??*/
00356     LAMBDA0=scoef[Z1][j];
00357     LAMBDA1=(Q-scoef[93][j])*(scoef[Z1][j+1]-scoef[Z1][j])/(scoef[93][j+1]-scoef[93][j]);
00358     L=(LAMBDA0+LAMBDA1)/powf(Z1,.33333);
00359     ZETA0=Q+(1./(2.*VFERMI*VFERMI))*(1.-Q)*logf(1+powf((4.*L*VFERMI/1.919),2));
00360     if(E>1)tempf=logf(E);else tempf=0;
00361     ZETA=ZETA0*(1.+(1./(Z1*Z1))*(.08+.0015*Z2)*expf(-powf((7.6-tempf),2)));
00362     /*Calculate stopping for low YR*/
00363     tempf=VRMIN/powf(Z1,.6667); if(tempf<YRMIN)tempf=YRMIN;
00364     if(YR<=tempf){
00365       tempf=YRMIN*powf(Z1,.6667);if(VRMIN<tempf)VRMIN=tempf; /*VRMIN must be >= YRMIN^(2/3)*/
00366       tempf=VRMIN*VRMIN-0.8*VFERMI*VFERMI; if(tempf<0)tempf=0;
00367       VMIN=.5*(VRMIN+sqrtf(tempf));
00368       EEE=25*VMIN*VMIN;
00369       Sproton=pstop(Z2,EEE);
00370       /*Add Fermi Velocity Correction to Low Energy value*/
00371       if(EEE<=9999)EION=EEE;else EION=9999; /*Correction is only valid for E <1E4 keV/amu*/
00372       for(j=41;j<=53 && scoef[93][j]<EION ;j++);j-=1;  /*Find E Interpolation in SCOEF(93,41-54)*/
00373       if(j<41)j=41;else if(j>53)j=53; /*Boilerplate ??*/
00374       VFCORR0=scoef[Z2][j];
00375       VFCORR1=(EION-scoef[93][j])*(scoef[Z2][j+1]-scoef[Z2][j])/(scoef[93][j+1]-scoef[93][j]);
00376       /*
00377       Following corrects for low-energy stopping, where little data exists.
00378       Traditionally, this is velocity-proportional stopping, however for
00379       light ions, light targets and semiconductors, a large variation exists.
00380       Note: HIPOWER down = Se up �� LAMBDA down = Se down
00381       */
00382       if(Z1==3)HIPOWER= 0.55;
00383       else if(Z2<7)HIPOWER= 0.375;
00384       else if(Z1<18 && (Z2==14 || Z2==32))HIPOWER= 0.375;
00385       else HIPOWER=.47; /*DEFAULT POWER IF NO SPECIAL CASE. TRIM-88 used 0.5*/
00386       SE[i]=(double)(Sproton*powf(ZETA*Z1,2)*(VFCORR0+VFCORR1)*powf((E/EEE),HIPOWER));
00387       }
00388     /*Calculate stopping for NOT low YR*/
00389     else{
00390       Sproton=pstop(Z2,E);
00391       /*Add Fermi Velocity Correction - 1995*/
00392       if(E<=9999)EION=E;else EION=9999; /*Correction is only valid for E <1E4 keV/amu*/
00393       for(j=41;j<=53 && scoef[93][j]<EION ;j++);j-=1;  /*Find E Interpolation in SCOEF(93,41-54)*/
00394       if(j<41)j=41;else if(j>53)j=53; /*Boilerplate ??*/
00395       VFCORR0=scoef[Z2][j];
00396       VFCORR1=(EION-scoef[93][j])*(scoef[Z2][j+1]-scoef[Z2][j])/(scoef[93][j+1]-scoef[93][j]);
00397       SE[i]=(double)(Sproton*powf(ZETA*Z1,2)*(VFCORR0+VFCORR1));
00398       }
00399  /*
00400  */
00401 
00402     }
00403   /*SE(I)=SE(I)*10     'This converts Stopping in eV/(1E15-cm2) to eV-A2  */
00404   }
00405 //for(i=0;i<nEner;i++)printf("---  %e\t%e\t%e\n",Ener[i],SE[i],pstop(14,Ener[i]));
00406 }
00407 
00408 double nuclearstopping_ZBL(int Z1, int Z2,double Ionweight, double trgtweight, double *Ener, int nEner, double *SN)
00409 {
00410 /*
00411 nuclearstopping_ZBL calculates ZBL 1990 nuclear stopping powers
00412 */
00413 /*
00414 Z1=incident ion atomic number
00415 Z2=target atomic number
00416 Ionweight=Weight of incident ion (if Ionweight<1, the Most Abundant Isotope weight associated to Z1 in SCOEF.95A will be used)
00417 trgtweight=Weight of target atom (if trgtweight<1, the Most Abundant Isotope weight associated to Z2 in SCOEF.95A will be used)
00418 Ener= pointer to vector of nEner components storing the list of energies wanted (in keV)
00419 nEner=dim of Ener as well as of SE
00420 SN=pointer to a vector of nEner components where the resulting stoppings will be stored (ev/1e15atcm-2)
00421 
00422 Return value: spmax: maximum nuclear stopping power computed. If nEner=1, then spmax=SN[0] !!!
00423 
00424 IMPORTANT: SN and SP[] are returned in eV/(1e15at/cm2). Be careful of converting to keV/(1e15at/cm2) when using the value for internal Hotstop calcs
00425 */
00426 double M1,M2,EPSIL,temp,spmax;
00427 int i;
00428 
00429 /*Determine ion and target massess*/
00430 if(trgtweight<1.)M2=(double)scoef[Z2][3] ;else M2=(double)trgtweight;    /*MOI weight if M2 wasn't specified*/
00431 if(Ionweight<1.)M1=(double)scoef[Z1][3] ;else M1=(double)Ionweight;    /*MOI weight if M1 wasn't specified*/
00432 
00433 for(i=0,spmax=0;i<nEner;i++){
00434   /*Epsilon is the reduced energy of the ion/target combination.*/
00435   temp=(M1+M2)*(pow(Z1,0.23)+pow(Z2,0.23));
00436   EPSIL=32.53*M2*Ener[i]/(Z1*Z2*temp);
00437   if(EPSIL==0)SN[i]=0;
00438   else if(EPSIL>=30) SN[i]=log(EPSIL)/(2*EPSIL);
00439   else SN[i]=.5*log(1+1.1383*EPSIL)/(EPSIL+(.01321*pow(EPSIL,.21226))+(.19593*sqrt(EPSIL)));
00440   /*convert from LSS reduced units to eV-cm2/1E15 */
00441   SN[i]*=Z1*Z2*M1*8.462/temp;
00442   /*Find the maximum SN*/
00443   if(SN[i]>spmax)spmax=SN[i];
00444   }
00445 return(spmax);
00446 }
00447 
00448 /*
00449 int main(void)
00450 {
00451 float E,Sproton;
00452 int i,j,NE;
00453 float *S,*Ener;
00454 readstopcoef();
00455 NE=1000;
00456 if(!(S=calloc(NE,sizeof(float)))){fprintf(stderr,"\n Error allocating memory\n");exit(1);}
00457 if(!(Ener=calloc(NE,sizeof(float)))){fprintf(stderr,"\n Error allocating memory\n");exit(1);}
00458 for(i=0,E=0;i<NE;i++,E+=1.)Ener[i]=E;
00459 stop96(1,16,Ener,NE,S);
00460 for(i=0;i<NE;i++)printf("%e\t%e\n",Ener[i],S[i]);
00461 }
00462 */

Generated on Sat Dec 8 23:11:36 2007 for libCPIXE by  doxygen 1.5.4