00001 /* 00002 This file belongs to Aeneas. Aeneas is a GNU package released under GPL 3. 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 <aeneas@southnovel.eu> 00010 00011 This program is free software; you can redistribute it and/or modify 00012 it under the terms of the GNU General Public License as published by 00013 the Free Software Foundation; either version 3, or (at your option) 00014 any later version. 00015 00016 This program is distributed in the hope that it will be useful, 00017 but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 GNU General Public License for more details. 00020 00021 You should have received a copy of the GNU General Public License 00022 along with this program. If not, see <http://www.gnu.org/licenses/>. 00023 */ 00024 00025 // Created on : 17 june 2007, Siracusa, Jean Michel Sellier 00026 // Last modified : 16 september 2007, Siracusa, Jean Michel Sellier 00027 00028 // The input file unit is the micron 00029 // Purpose : Load the 3D msh (Version 1.0) format device.msh 00030 00031 // warning! this subroutine has to be used only if the user is 00032 // well experienced with GMSH. 00033 00034 void load_mshV1(char inp[]) 00035 { 00036 int i; 00037 int dum; 00038 int nodes_offset=0; 00039 int elements_offset=0; 00040 char s[180]; 00041 00042 FILE *fp; 00043 00044 fp=fopen(inp,"r"); 00045 00046 // check the existence of the input file 00047 // ************************************* 00048 // if the file does not exist the code close the PETSc library and exit. 00049 if(fp==NULL){ 00050 printf("INPUT file 'device.msh' does not exist\nexit\n"); 00051 exit(0); 00052 } 00053 00054 // ************************************************************* 00055 // Load 'device.geo' and store the mesh in the correct arrays 00056 // ************************************************************* 00057 00058 // Check if the first row is $NOD, which is equivalent to check if 00059 // the file is really a msh v1.0 file. 00060 fscanf(fp,"%s",s); 00061 if(strcmp(s,"$NOD")!=0){ 00062 printf("load_smhV1.0 error : the input file is not in msh v1.0 format!\n"); 00063 printf("loaded value is : %s\n",s); 00064 exit(0); 00065 } 00066 // Read the number of vertices 00067 // *************************** 00068 // Ng = number of vertices of the mesh (nombre total de noeuds du maillage) 00069 fscanf(fp,"%d",&Ng); 00070 printf("Number of vertices = %d\n",Ng); 00071 00072 // allocation for i_front 00073 /* printf("Allocating memory for mesh arrays...\n"); 00074 i_front = malloc((Ng+1)*sizeof(int)); 00075 if(i_front==NULL){ 00076 printf("load_mshV1 : not enough memory for V allocation!\n"); 00077 exit(0); 00078 } 00079 for(i=0;i<3;i++){ 00080 coord[i] = malloc((Ng+1)*sizeof(double)); 00081 if(coord[i]==NULL){ 00082 printf("load_mshV1 : not enough memory for coord[%d] allocation!\n",i); 00083 exit(0); 00084 } 00085 }*/ 00086 00087 00088 // read the global coordinate of the mesh vertices and related reference number 00089 // **************************************************************************** 00090 // i_front[i] = reference number of the i-th vertex (nombre de reference du noeud) 00091 // This number = 0 if we are inside the device 00092 // '' != 0 if we are on the frontier 00093 // In this latter case this number makes one understand what 00094 // kind of boundary conditions one has to impose on that vertex. 00095 // coord[0][i] = global coordinate x of the i-th vertex (i=0..Ng-1) 00096 // coord[1][i] = global coordinate y of the i-th vertex 00097 // coord[2][i] = global coordinate z of the i-th vertex 00098 // French comment: 00099 // Pour k=0..dim-1 (dim = dimension de l'espace) et n=0..Ng-1, coord[k][n] est la k-ieme 00100 // coordonee du noeud de numero global n. 00101 00102 00103 for(i=0;i<Ng;i++){ 00104 fscanf(fp,"%d",&dum); 00105 if(i==0) nodes_offset=dum; 00106 // printf("dum = %d\n",dum); 00107 fscanf(fp,"%lg %lg %lg\n",&coord[0][dum-nodes_offset], 00108 &coord[1][dum-nodes_offset], 00109 &coord[2][dum-nodes_offset]); 00110 coord[0][dum-nodes_offset]*=1.e-6; 00111 coord[1][dum-nodes_offset]*=1.e-6; 00112 coord[2][dum-nodes_offset]*=1.e-6; 00113 00114 // printf("%d %2.20g %2.20g %2.20g\n",dum-nodes_offset, 00115 // coord[0][dum-nodes_offset], 00116 // coord[1][dum-nodes_offset], 00117 // coord[2][dum-nodes_offset]); 00118 } 00119 00120 // Read informations about the various tetrahedra 00121 // ********************************************** 00122 // (this gives us informations about the definition of tetrahedra) 00123 // i_dom[i] = reference number of the i-th tetrahedra 00124 // noeud_geo[0][i] = global number of the first vertex in the i-th tetrahedra 00125 // noeud_geo[1][i] = global number of the second vertex in the i-th tetrahedra 00126 // noeud_geo[2][i] = global number of the third vertex in the i-th tetrahedra 00127 // noeud_geo[3][i] = global number of the fourth vertex in the i-th tetrahedra 00128 00129 // check if the msh input file is not corrupted 00130 fscanf(fp,"%s\n",s); 00131 if(strcmp(s,"$ENDNOD")!=0){ 00132 printf("load_smhV1.0 error : the input file is probably corrupted...!\n"); 00133 printf("loaded value is : %s\n",s); 00134 printf("the expected value should be : $ENDNOD.\n"); 00135 exit(0); 00136 } 00137 00138 fscanf(fp,"%s\n",s); 00139 if(strcmp(s,"$ELM")!=0){ 00140 printf("load_smhV1.0 error : the input file is probably corrupted...!\n"); 00141 printf("loaded value is : %s\n",s); 00142 printf("the expected value should be : $ELM.\n"); 00143 exit(0); 00144 } 00145 00146 fscanf(fp,"%d",&dum); 00147 Ne=0; 00148 int flag=0; 00149 for(i=0;i<dum;i++){ 00150 int j; 00151 int eltype=0; 00152 int ref; 00153 int nonodes; 00154 int dum2; 00155 // printf("i=%d\n",i); 00156 fscanf(fp,"%d %d %*d %*d %d",&ref,&eltype,&nonodes); 00157 // printf("%d %d\n",ref,eltype); 00158 if(eltype==4) flag=1; 00159 if(flag==0) elements_offset=ref+1; 00160 // printf("eo=%d\n",elements_offset); 00161 if(eltype!=4) for(j=1;j<=nonodes;j++) fscanf(fp,"%*d\n"); 00162 if(eltype==4) 00163 for(j=1;j<=nonodes;j++){ 00164 fscanf(fp,"%d",&dum2); 00165 // noeud_geo[j-1][ref-elements_offset]=dum2-nodes_offset+1; 00166 } 00167 // if(eltype==4) printf("%d %d %d %d %d\n",ref-elements_offset, 00168 // noeud_geo[0][ref-elements_offset], 00169 // noeud_geo[1][ref-elements_offset], 00170 // noeud_geo[2][ref-elements_offset], 00171 // noeud_geo[3][ref-elements_offset]); 00172 if(eltype==4) Ne++; 00173 } 00174 00175 printf("Number of elements (tetrahedra) = %d\n",Ne); 00176 00177 // allocation for i_dom 00178 /* i_dom = malloc((Ne+1)*sizeof(int)); 00179 for(i=0;i<4;i++) noeud_geo[i] = malloc((Ne+1)*sizeof(int)); 00180 if(i_dom==NULL){ 00181 printf("load_mesh : not enough memory for i_front allocation!\n"); 00182 exit(0); 00183 }*/ 00184 00185 fclose(fp); 00186 00187 // read the file a second time for the noeud_geo array 00188 // --------------------------------------------------- 00189 fp=fopen(inp,"r"); 00190 fscanf(fp,"%*s"); fscanf(fp,"%*d"); 00191 for(i=0;i<Ng;i++){ 00192 fscanf(fp,"%d",&dum); fscanf(fp,"%*g %*g %*g\n"); 00193 } 00194 fscanf(fp,"%s\n",s); fscanf(fp,"%s\n",s); 00195 fscanf(fp,"%d",&dum); 00196 Ne=0; 00197 flag=0; 00198 for(i=0;i<dum;i++){ 00199 int j, eltype=0, ref, nonodes, dum2; 00200 fscanf(fp,"%d %d %*d %*d %d",&ref,&eltype,&nonodes); 00201 if(eltype==4) flag=1; 00202 if(flag==0) elements_offset=ref+1; 00203 if(eltype!=4) for(j=1;j<=nonodes;j++) fscanf(fp,"%*d\n"); 00204 if(eltype==4) 00205 for(j=1;j<=nonodes;j++){ 00206 fscanf(fp,"%d",&dum2); 00207 noeud_geo[j-1][ref-elements_offset]=dum2-nodes_offset+1; 00208 } 00209 if(eltype==4) Ne++; 00210 } 00211 fclose(fp); 00212 // --------------------------------------------------- 00213 00214 // various dynamical allocations 00215 #include "../services/dynamical_allocations.h" 00216 }