Main Page | Directories | File List | File Members

drift.h File Reference

#include "../linear_solver/ludcmp.h"
#include "../linear_solver/lubksb.h"

Go to the source code of this file.

Functions

void drift (double tau)


Function Documentation

void drift double  tau  ) 
 

Definition at line 29 of file drift.h.

References alphaK, b, coord, EG, EL, EMIN, Ex, Ey, Ez, HBAR, HHM, HM, i_dom, i_front, IV, KX, KY, KZ, L, M, MSTAR, noeud_geo, NOVALLEY, OHMIC, P, p, Q, QH, rnd(), SCHOTTKY, SIO2, vois, and z.

Referenced by ensemble_montecarlo().

00030 {
00031  register int j;
00032  int n=4;
00033  int p=0;
00034  int ifr[3]={0.,0.,0.};
00035  int indx[5];
00036  double d;
00037  double a[5][5],b[5];
00038  double dkx,dky,dkz;
00039  double hmt, x, y, z;
00040  double ksquared,gk,thesquareroot;
00041 
00042  if(IV==9) return;
00043 // if(EL==-1) return; // just in case...
00044  if(i_dom[EL]==SIO2) return;
00045 
00046 // Valid for every material
00047  dkx=-QH*0.25*(Ex[noeud_geo[0][EL]-1]+Ex[noeud_geo[1][EL]-1]
00048               +Ex[noeud_geo[2][EL]-1]+Ex[noeud_geo[3][EL]-1])*tau;
00049  dky=-QH*0.25*(Ey[noeud_geo[0][EL]-1]+Ey[noeud_geo[1][EL]-1]
00050               +Ey[noeud_geo[2][EL]-1]+Ey[noeud_geo[3][EL]-1])*tau;
00051  dkz=-QH*0.25*(Ez[noeud_geo[0][EL]-1]+Ez[noeud_geo[1][EL]-1]
00052               +Ez[noeud_geo[2][EL]-1]+Ez[noeud_geo[3][EL]-1])*tau;
00053 // printf("KX=%g KY=%g KZ=%g\n",KX,KY,KZ);
00054 // printf("dkx=%g dky=%g dkz=%g\n",dkx,dky,dkz);
00055  
00056  x=y=z=0.;
00057  for(j=0;j<4;j++){
00058   x+=L[j]*coord[0][noeud_geo[j][EL]-1];
00059   y+=L[j]*coord[1][noeud_geo[j][EL]-1];
00060   z+=L[j]*coord[2][noeud_geo[j][EL]-1];
00061  }
00062  x/=4.; y/=4.; z/=4.;
00063 //if(z<-1.){
00064 //   printf("%g %g %g %g %g\n",L[0],L[1],L[2],L[3],L[0]+L[1]+L[2]+L[3]); 
00065 //   for(j=0;j<4;j++) printf("%d %g %g %g\n",j,coord[0][noeud_geo[j][EL]-1],coord[1][noeud_geo[j][EL]-1],coord[2][noeud_geo[j][EL]-1]);
00066 //   printf("%d %d x = %g y = %g z = %g\n",EL,noeud_geo[3][EL]-1,x,y,z);
00067 //}
00068 
00069 // x*=1.e-6; y*=1.e-6; z*=1.e-6;
00070   
00071  if(i_dom[EL]!=SIO2){
00072 // Electron drift process
00073    hmt=HM[i_dom[EL]][IV]*tau;
00074    ksquared=KX*KX+KY*KY+KZ*KZ;
00075    gk=HHM[i_dom[EL]][IV]*ksquared;
00076    thesquareroot=sqrt(1.+4.*alphaK[i_dom[EL]][IV]*gk);
00077 //   printf("!!! %g\n",thesquareroot);
00078  }
00079 // updating the position and pseudo-wave vector
00080 // (second order Runge-Kutta method)
00081 //printf("hmt = %g\n",hmt);
00082 // printf("X=%g Y=%g Z=%g\n",x,y,z);
00083 // printf("KX=%g KY=%g KZ=%g\n",KX,KY,KZ);
00084 // printf("dkx=%g dky=%g dkz=%g\n",dkx,dky,dkz);
00085 // printf("hmt = %g sq= %g\n",hmt,thesquareroot);
00086 // printf("%g %g %g\n",hmt*(KX+0.5*dkx)/thesquareroot,hmt*(KY+0.5*dky)/thesquareroot,
00087 //                     hmt*(KZ+0.5*dkz)/thesquareroot);
00088    x+=hmt*(KX+0.5*dkx)/thesquareroot;
00089    y+=hmt*(KY+0.5*dky)/thesquareroot;
00090    z+=hmt*(KZ+0.5*dkz)/thesquareroot;
00091    KX+=dkx;
00092    KY+=dky;
00093    KZ+=dkz;
00094 // printf("X=%g Y=%g Z=%g\n\n",x,y,z);
00095 
00096 // updating the barycentric coordinates
00097 //   x*=1.e6; y*=1.e6; z*=1.e6;
00098 //if(z>1.5) printf("x = %g y = %g z = %g\n",x,y,z);
00099 //   memset(&a,0,sizeof(a));
00100 //   memset(&b,0,sizeof(b));
00101    {int k;
00102     for(k=0;k<4;k++){
00103       a[1][k+1]=coord[0][noeud_geo[k][EL]-1];
00104       a[2][k+1]=coord[1][noeud_geo[k][EL]-1];
00105       a[3][k+1]=coord[2][noeud_geo[k][EL]-1];
00106       a[4][k+1]=1.;
00107    }}
00108    b[1]=4.*x;
00109    b[2]=4.*y;
00110    b[3]=4.*z;
00111    b[4]=4.;
00112 //printf("%g %g %g\n",coord[0][noeud_geo[1][EL]-1],coord[1][noeud_geo[1][EL]-1],
00113 //                    coord[2][noeud_geo[1][EL]-1]);
00114 //printf("%g %g %g\n",x,y,z);
00115 //printf("EL = %d\n",EL);
00116 //     {int ii,jj;
00117 //     for(ii=1;ii<=4;ii++){
00118 //        for(jj=1;jj<=4;jj++) printf("a[%d][%d] = %g   ",ii,jj,a[ii][jj]);
00119 //        printf("\n");
00120 //     }}
00121 // LU decomposition solver A.x=b
00122 #include "../linear_solver/ludcmp.h"
00123 #include "../linear_solver/lubksb.h"
00124 //   printf("before %g %g %g %g\n",L[0],L[1],L[2],L[3]);
00125    for(j=0;j<4;j++) L[j]=b[j+1];
00126 //   printf("** %g %g %g %g %g\n",L[0],L[1],L[2],L[3],L[0]+L[1]+L[2]+L[3]);
00127    if(L[0]<0. || L[1]<0. || L[2]<0. || L[3]<0.) goto label1;
00128    else return;
00129    label1:
00130 //    printf("EL = %d %g %g %g %g\n",EL,L[0],L[1],L[2],L[3]);
00131 //   printf("star %g %g %g %g %g\n",L[0],L[1],L[2],L[3],L[0]+L[1]+L[2]+L[3]);
00132     for(j=0;j<4;j++) if(L[j]<0.) p=j;
00133 // on the boundaries
00134 // =================
00135     if(p==0){
00136       ifr[0]=i_front[noeud_geo[1][EL]-1];
00137       ifr[1]=i_front[noeud_geo[2][EL]-1];
00138       ifr[2]=i_front[noeud_geo[3][EL]-1];
00139     }
00140     if(p==1){
00141       ifr[0]=i_front[noeud_geo[0][EL]-1];
00142       ifr[1]=i_front[noeud_geo[2][EL]-1];
00143       ifr[2]=i_front[noeud_geo[3][EL]-1];
00144     }
00145     if(p==2){
00146       ifr[0]=i_front[noeud_geo[0][EL]-1];
00147       ifr[1]=i_front[noeud_geo[1][EL]-1];
00148       ifr[2]=i_front[noeud_geo[3][EL]-1];
00149     }
00150     if(p==3){
00151       ifr[0]=i_front[noeud_geo[0][EL]-1];
00152       ifr[1]=i_front[noeud_geo[1][EL]-1];
00153       ifr[2]=i_front[noeud_geo[2][EL]-1];
00154     }
00155 // Schottky contact
00156     if(vois[p][EL]==-1 &&
00157        (ifr[0]==SCHOTTKY &&
00158         ifr[1]==SCHOTTKY &&
00159         ifr[2]==SCHOTTKY)){
00160             IV=9;
00161             return;
00162         }
00163 // ohmic contacts
00164     if(vois[p][EL]==-1 &&
00165        (ifr[0]==OHMIC &&
00166         ifr[1]==OHMIC &&
00167         ifr[2]==OHMIC)){
00168             IV=9;
00169             return;
00170         }
00171 // insulator contacts
00172     if(vois[p][EL]==-1 || i_dom[vois[p][EL]]==SIO2/* &&
00173        (ifr[0]==INSULATOR ||
00174         ifr[1]==INSULATOR ||
00175         ifr[2]==INSULATOR)*/){
00176         reflection:;
00177         double max=-4.;
00178         double x[2],y[2],z[2];
00179 // initial position
00180         x[0]=(L[0]*coord[0][noeud_geo[0][EL]-1]+
00181               L[1]*coord[0][noeud_geo[1][EL]-1]+
00182               L[2]*coord[0][noeud_geo[2][EL]-1]+
00183               L[3]*coord[0][noeud_geo[3][EL]-1])/(L[0]+L[1]+L[2]+L[3]);
00184         y[0]=(L[0]*coord[1][noeud_geo[0][EL]-1]+
00185               L[1]*coord[1][noeud_geo[1][EL]-1]+
00186               L[2]*coord[1][noeud_geo[2][EL]-1]+
00187               L[3]*coord[1][noeud_geo[3][EL]-1])/(L[0]+L[1]+L[2]+L[3]);
00188         z[0]=(L[0]*coord[2][noeud_geo[0][EL]-1]+
00189               L[1]*coord[2][noeud_geo[1][EL]-1]+
00190               L[2]*coord[2][noeud_geo[2][EL]-1]+
00191               L[3]*coord[2][noeud_geo[3][EL]-1])/(L[0]+L[1]+L[2]+L[3]);
00192         if(L[0]>L[1] && L[0]>L[2]) max=L[0];
00193         if(L[1]>L[0] && L[1]>L[2]) max=L[1];
00194         if(L[2]>L[1] && L[2]>L[0]) max=L[2];
00195         for(j=0;j<3;j++){
00196           L[j]/=max;
00197           if(L[j]<0.) L[j]=-L[j];
00198 //          L[j]=rnd();
00199         }
00200 // this is an elastic scattering
00201        L[3]=4.-(L[0]+L[1]+L[2]);
00202 // final position
00203         x[1]=(L[0]*coord[0][noeud_geo[0][EL]-1]+
00204               L[1]*coord[0][noeud_geo[1][EL]-1]+
00205               L[2]*coord[0][noeud_geo[2][EL]-1]+
00206               L[3]*coord[0][noeud_geo[3][EL]-1])/(L[0]+L[1]+L[2]+L[3]);
00207         y[1]=(L[0]*coord[1][noeud_geo[0][EL]-1]+
00208               L[1]*coord[1][noeud_geo[1][EL]-1]+
00209               L[2]*coord[1][noeud_geo[2][EL]-1]+
00210               L[3]*coord[1][noeud_geo[3][EL]-1])/(L[0]+L[1]+L[2]+L[3]);
00211         z[1]=(L[0]*coord[2][noeud_geo[0][EL]-1]+
00212               L[1]*coord[2][noeud_geo[1][EL]-1]+
00213               L[2]*coord[2][noeud_geo[2][EL]-1]+
00214               L[3]*coord[2][noeud_geo[3][EL]-1])/(L[0]+L[1]+L[2]+L[3]);
00215 // update the pseudo-wave vector
00216        KX=(x[1]-x[0])/tau;
00217        KY=(y[1]-y[0])/tau;
00218        KZ=(z[1]-z[0])/tau;
00219        return;
00220     }
00221 // scattering on SiO2
00222 /*    if(i_dom[vois[p][EL]]==SIO2){
00223         double max;
00224         if(L[0]>L[1] && L[0]>L[2]) max=L[0];
00225         if(L[1]>L[0] && L[1]>L[2]) max=L[1];
00226         if(L[2]>L[1] && L[2]>L[0]) max=L[2];
00227         for(j=0;j<3;j++){
00228           L[j]/=max;
00229           if(L[j]<0.) L[j]=-L[j];
00230         }
00231 // this is an elastic scattering
00232        L[3]=4.-(L[0]+L[1]+L[2]);
00233        return;
00234     }*/
00235 // in case of abrupt heterojunction, one has
00236 // to calculate the reflection and transmission
00237 // probability in order to see jow the particle
00238 // behaves.
00239    if(i_dom[EL]!=i_dom[vois[p][EL]] && i_dom[vois[p][EL]]!=SIO2
00240                                     && i_dom[vois[p][EL]]!=-1){
00241 //     printf("############### %d %d\n",EL,vois[p][EL]);
00242 //     printf("*************** %d %d\n\n",i_dom[EL],i_dom[vois[p][EL]]);
00243      double k1,k2,T,R;
00244      double ksquared,thesquareroot,energy;
00245 // calculates the particle energy
00246      ksquared=P[n][1]*P[n][1]+P[n][2]*P[n][2]+P[n][3]*P[n][3];
00247      thesquareroot=sqrt(1.+4.*alphaK[i_dom[EL]][IV]*HHM[i_dom[EL]][IV]*ksquared);
00248      energy=(thesquareroot-1.)/(2.*alphaK[i_dom[EL]][IV]);
00249      if(IV==2) energy+=EG[i_dom[EL]];
00250      energy*=Q; // <--- energy in Joule
00251 // calculates the Transmission probability
00252      k1=sqrt(2.*MSTAR[i_dom[EL]][IV]*M*energy)/HBAR;
00253      if(IV==2 && NOVALLEY[i_dom[vois[p][EL]]]==1){
00254       if((energy+(EMIN[i_dom[EL]][IV]-EMIN[i_dom[vois[p][EL]]][1])*Q)<0.) goto reflection;
00255       k2=sqrt(2.*MSTAR[i_dom[vois[p][EL]]][1]*M*
00256              (energy-(EMIN[i_dom[EL]][IV]-EMIN[i_dom[vois[p][EL]]][IV])*Q))/HBAR;
00257      }
00258      else{
00259       if((energy+(EMIN[i_dom[EL]][IV]-EMIN[i_dom[vois[p][EL]]][IV])*Q)<0.) goto reflection;
00260       k2=sqrt(2.*MSTAR[i_dom[vois[p][EL]]][IV]*M*
00261              (energy+(EMIN[i_dom[EL]][IV]-EMIN[i_dom[vois[p][EL]]][IV])*Q))/HBAR;
00262      }
00263      if(IV==2 && NOVALLEY[i_dom[vois[p][EL]]]==1){
00264        T=pow(2.*(k1/(MSTAR[i_dom[EL]][IV]*M))
00265          /(k1/(MSTAR[i_dom[EL]][IV]*M)+k2/(MSTAR[i_dom[vois[p][EL]]][1]*M)),2.);
00266        R=pow((k1/(MSTAR[i_dom[EL]][IV]*M)-k2/(MSTAR[i_dom[vois[p][EL]]][1]*M))
00267          /(k1/(MSTAR[i_dom[EL]][IV]*M)+k2/(MSTAR[i_dom[vois[p][EL]]][1]*M)),2.);
00268      }
00269      else{
00270        T=pow(2.*(k1/(MSTAR[i_dom[EL]][IV]*M))
00271          /(k1/(MSTAR[i_dom[EL]][IV]*M)+k2/(MSTAR[i_dom[vois[p][EL]]][IV]*M)),2.);
00272        R=pow((k1/(MSTAR[i_dom[EL]][IV]*M)-k2/(MSTAR[i_dom[vois[p][EL]]][IV]*M))
00273             /(k1/(MSTAR[i_dom[EL]][IV]*M)+k2/(MSTAR[i_dom[vois[p][EL]]][IV]*M)),2.);
00274      }
00275 //     printf("k1 = %g     k2 = %g   R = %g  T = %g\n",k1,k2,R*R/(R*R+T*T),T*T/(R*R+T*T)); 
00276      if(rnd()<R*R/(R*R+T*T)) goto reflection;
00277    }
00278 
00279 //   transmission:;
00280 // inside the device (between two different tetrahedra of the same material)
00281    EL=vois[p][EL];
00282 //   printf("new EL=%d\n",EL);
00283 //   printf("%g %g %g %g %g\n",L[0],L[1],L[2],L[3],L[0]+L[1]+L[2]+L[3]);
00284       memset(&a,0,sizeof(a));
00285       memset(&b,0,sizeof(b));
00286       {int k;
00287        for(k=0;k<4;k++){
00288          a[1][k+1]=coord[0][noeud_geo[k][EL]-1];
00289          a[2][k+1]=coord[1][noeud_geo[k][EL]-1];
00290          a[3][k+1]=coord[2][noeud_geo[k][EL]-1];
00291          a[4][k+1]=1.;
00292       }}
00293       b[1]=4.*x;
00294       b[2]=4.*y;
00295       b[3]=4.*z;
00296       b[4]=4.;
00297 // LU decomposition solver A.x=b
00298 #include "../linear_solver/ludcmp.h"
00299 #include "../linear_solver/lubksb.h"
00300       for(j=0;j<4;j++) L[j]=b[j+1];
00301       if(L[0]>=0. && L[1]>=0. && L[2]>=0. && L[3]>=0.){
00302 //         printf("final %g %g %g %g %g\n",L[0],L[1],L[2],L[3],L[0]+L[1]+L[2]+L[3]);
00303          return;
00304       }
00305       else goto label1;
00306 }


© sourcejam.com 2005-2008