Main Page | Directories | File List | File Members

ensemble_montecarlo.h

Go to the documentation of this file.
00001 /*
00002    This file belongs to Aeneas. Aeneas is a GNU package released under GPL 3 license.
00003    This code is a simulator for Submicron 3D Semiconductor Devices. 
00004    It implements the Monte Carlo transport in 3D tetrahedra meshes
00005    for the simulation of the semiclassical Boltzmann equation for both electrons.
00006    It also includes all the relevant quantum effects for nanodevices.
00007 
00008    Copyright (C) 2007 Jean Michel Sellier <sellier@dmi.unict.it>
00009  
00010    This program is free software; you can redistribute it and/or modify
00011    it under the terms of the GNU General Public License as published by
00012    the Free Software Foundation; either version 3, or (at your option)
00013    any later version.
00014 
00015    This program is distributed in the hope that it will be useful,
00016    but WITHOUT ANY WARRANTY; without even the implied warranty of
00017    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018    GNU General Public License for more details.
00019 
00020    You should have received a copy of the GNU General Public License
00021    along with this program. If not, see <http://www.gnu.org/licenses/>.
00022 */
00023 
00024 // Created on : 11 june 2007, Siracusa, Jean Michel Sellier
00025 // Last modified : 16 august 2007, Siracusa, Jean Michel Sellier
00026 
00027 // this is the ensemble MC algorithm
00028 
00029 void ensemble_montecarlo(void)
00030 {
00031  long int n=1;
00032  int i,ni,j;
00033  double tdt,ti,tau;
00034 
00035  tdt=TEMPO+DT;
00036 
00037  do{
00038     IV=(int)(P[n][0]);
00039     KX=P[n][1];
00040     KY=P[n][2];
00041     KZ=P[n][3];
00042     TS=P[n][4];
00043     L[0]=P[n][5];
00044     L[1]=P[n][6];
00045     L[2]=P[n][7];
00046     L[3]=P[n][8];
00047 // printf("before  %g %g %g %g %g\n",L[0],L[1],L[2],L[3],L[0]+L[1]+L[2]+L[3]);
00048     EL=(int)(P[n][9]);
00049 //    if(i_dom[EL]==SIO2) printf("SIO2!!!\n");
00050     ti=TEMPO;
00051 
00052     while(TS<=tdt){
00053        tau=TS-ti;
00054 //       printf("tau = %g\n",tau);
00055        drift(tau);
00056 //       printf("drift...scat\n");
00057        scat(i_dom[EL]);
00058        ti=TS;
00059        TS=ti-log(rnd())/GM[i_dom[EL]];
00060     }
00061     tau=tdt-ti;
00062     drift(tau);
00063 
00064 // ==============================================
00065      if(IV!=9){
00066        P[n][0]=IV;
00067        P[n][1]=KX;
00068        P[n][2]=KY;
00069        P[n][3]=KZ;
00070        P[n][4]=TS;
00071        P[n][5]=L[0];
00072        P[n][6]=L[1];
00073        P[n][7]=L[2];
00074        P[n][8]=L[3];
00075        P[n][9]=EL;
00076        n++;
00077      }
00078 // if IV=9 then the super-particle has been eliminated
00079      if(IV==9){
00080        for(i=1;i<=9;i++) P[n][i]=P[INUM][i];
00081        INUM--;
00082      }
00083 //  printf("n = %d INUM = %d\n",n,INUM);
00084   }while(n<INUM);
00085 
00086 // computes the number of electrons in every element
00087   for(i=0;i<Ne;i++) NOELEC[i]=0.;
00088   for(n=1;n<=INUM;n++){
00089    int el;
00090    el=(int)(P[n][9]);
00091    if(i_dom[el]==SIO2) NOELEC[el]=0;
00092    if(i_dom[el]!=SIO2) NOELEC[el]++;
00093   }
00094 //  for(i=0;i<Ne;i++) printf("NOELEC[%d]=%d\n",i,NOELEC[i]);
00095   
00096 // create particles
00097 // ================
00098 // this part of the code maintains a perfect charge neutrality
00099 // on the ohmic contacts.
00100   for(i=0;i<Ne;i++){
00101    int np;
00102    if((i_front[noeud_geo[0][i]-1]==OHMIC 
00103     && i_front[noeud_geo[1][i]-1]==OHMIC 
00104     && i_front[noeud_geo[2][i]-1]==OHMIC) ||
00105     (i_front[noeud_geo[0][i]-1]==OHMIC
00106     && i_front[noeud_geo[2][i]-1]==OHMIC
00107     && i_front[noeud_geo[3][i]-1]==OHMIC) ||
00108     (i_front[noeud_geo[0][i]-1]==OHMIC
00109     && i_front[noeud_geo[1][i]-1]==OHMIC
00110     && i_front[noeud_geo[3][i]-1]==OHMIC) ||
00111     (i_front[noeud_geo[1][i]-1]==OHMIC
00112     && i_front[noeud_geo[2][i]-1]==OHMIC
00113     && i_front[noeud_geo[3][i]-1]==OHMIC)){
00114 // np = the number of electrons that one should always find in the i-th element
00115 // (i.e. for maintaining the charge-neutrality).
00116     np=(int)(ND[i]*VOLUME[i]/EPP[i]+0.5);
00117     if(ND[i]==0.) np=0;
00118 // the number of electrons to be injected in order to maintain the
00119 // charge neutrality.
00120     ni=np-NOELEC[i];
00121 //    ni/=2; // <--- "Tomizawa's trick"
00122 //    printf("ni = %d np = %d noelec = %d\n",ni,np,NOELEC[i]);
00123     if(ni>0){
00124       n=0;
00125       for(j=1;j<=ni;j++){
00126 // the following "if" is extremely important in order to avoid
00127 // particle creations in the SiO2 regions!
00128         if(i_dom[i]!=SIO2){
00129          n++;
00130          creation(i,TEMPO);
00131          P[INUM+n][0]=IV;
00132          P[INUM+n][1]=KX;
00133          P[INUM+n][2]=KY;
00134          P[INUM+n][3]=KZ;
00135          P[INUM+n][4]=TS;
00136          P[INUM+n][5]=L[0];
00137          P[INUM+n][6]=L[1];
00138          P[INUM+n][7]=L[2];
00139          P[INUM+n][8]=L[3];
00140          P[INUM+n][9]=i;
00141         }
00142       } // end of j-cycle
00143       INUM += n;
00144     } // end of if(ni>0) control
00145    } // end of if i_front...
00146   } // end of i-cycle
00147 
00148  printf("Actual number of electron super-particles = %d\n",INUM);
00149  if(INUM>NPMAX){
00150    printf("ensemble_montecarlo : too big actual number of particles\n");
00151    exit(EXIT_FAILURE);
00152  }
00153 }

© sourcejam.com 2005-2008