b2ca816cb61b8b5e425b4600039c4fed4534026f
[physik/morpheus.git] / main.c
1 /*
2  * morpheus - main.c
3  *
4  * this program tries helping to understand the amorphous depuration
5  * and recrystallization of SiCx while ion implanation. hopefully the program 
6  * will simulate the stabilization of the selforganizing structure in the
7  * observed behaviour.
8  *
9  * refs: 
10  *  - J. K. N. Lindner. Habilationsschrift, Universitaet Augsburg.
11  *  - Maik Haeberlen. Diplomarbeit, Universitaet Augsburg.
12  */
13
14 #define _GNU_SOURCE
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <sys/types.h>
19 #include <sys/stat.h>
20 #include <fcntl.h>
21 #include <unistd.h>
22
23 /* important defines */
24 #include "defines.h"
25
26 /* function prototypes */
27 #include "random.h"
28 #include "display.h"
29
30 /* global variables */
31 u32 *rand_buf,*rand_current;
32 char random_file[MAX_CHARS_RANDOM_FILE];
33 u32 gr;
34 int random_fd; /* /dev/urandom file descriptor */
35
36 int usage()
37 {
38  puts("usage:");
39  puts("-h: help");
40  printf("-a <value> \t slope of nuclear energy loss (default %d)\n",DEFAULT_SLOPE_NEL);
41  printf("-c <value> \t nuclear enery loss at depths 0 (default %d)\n",DEFAULT_START_NEL);
42  printf("-x <value> \t # x cells (default %d)\n",DEFAULT_X_SEG);
43  printf("-y <value> \t # y cells (default %d)\n",DEFAULT_Y_SEG);
44  printf("-z <value> \t # z cells (default %d)\n",DEFAULT_Z_SEG);
45  printf("-s <value> \t # steps to calculate (default %d)\n",DEFAULT_STEPS);
46  puts("-X <value> \t display area intercept point x (default # x celss / 2)");
47  puts("-Y <value> \t display area intercept point y (default # y cells / 2)");
48  puts("-Z <value> \t display area intercept point z (default # z cells / 2)");
49  printf("-d <value> \t refresh every <value> loops (default %d)\n",DEFAULT_DISPLAY_REF_RATE);
50  printf("-r <value> \t pressure range from amorphous SiCx (default %d)\n",DEFAULT_A_P_RANGE);
51  printf("-f <value> \t faktor for pressure from amorphous SiCx (default %f)\n",DEFAULT_A_P_FAKTOR);
52  printf("-p <value> \t p0 for probability of cell getting amorph (default %f)\n",DEFAULT_A_P_P0);
53  printf("-C <value> \t C start concentration (default %d)\n",DEFAULT_C_DIST_START_CONC);
54  printf("-S <value> \t slope of linear C distribution (default %d)\n",DEFAULT_C_DIST_SLOPE);
55  puts("-R <file> \t read random data from file (default not used)");
56  puts("-D <file> \t dump cell info into <file> (default not used)");
57  puts("-L <file> \t load cell info and display it (default no)");
58  puts("-n \t do not wait for user interaction (default no)");
59  return -23;
60 }
61
62 int make_amorph(cell *cell)
63 {
64  cell->status|=AMORPH;
65  return 23;
66 }
67
68 int make_cryst(cell *cell)
69 {
70  cell->status&=~AMORPH;
71  return 23;
72 }
73
74 int load_from_file(char *file,display *display)
75 {
76  int load_file_fd;
77
78  if((load_file_fd=open(file,O_RDONLY))<0)
79  {
80   puts("cannot open load file");
81   return -23;
82  }
83  if(read(load_file_fd,&(display->max_x),sizeof(u32))<sizeof(u32))
84  {
85   puts("failed reading max x");
86   return-23;
87  }
88  if(read(load_file_fd,&(display->max_y),sizeof(u32))<sizeof(u32))
89  {
90   puts("failed reading max y");
91   return -23;
92  }
93  if(read(load_file_fd,&(display->max_z),sizeof(u32))<sizeof(u32))
94  {
95   puts("failed reading max z");
96   return -23;
97  }
98  if(read(load_file_fd,display->cell_p,display->max_x*display->max_y*display->max_z*sizeof(cell))<display->max_x*display->max_y*display->max_z*sizeof(cell))
99  {
100   puts("failed reading cell info from file");
101   return -23;
102  }
103  close(load_file_fd);
104  puts("loaded file");
105  return 23;
106 }
107
108 int save_to_file(char *file,display *display)
109 {
110  int save_file_fd;
111
112  if((save_file_fd=open(file,O_CREAT|O_WRONLY|O_TRUNC))<0)
113  {
114   puts("cannot open save file");
115   return -23;
116  }
117  if(write(save_file_fd,&(display->max_x),sizeof(u32))<sizeof(u32))
118  {
119   puts("failed saving max x");
120   return -23;
121  }
122  if(write(save_file_fd,&(display->max_y),sizeof(u32))<sizeof(u32))
123  {
124   puts("failed saving max y");
125   return -23;
126  }
127  if(write(save_file_fd,&(display->max_z),sizeof(u32))<sizeof(u32))
128  {
129   puts("failed saving max z");
130   return -23;
131  }
132  if(write(save_file_fd,display->cell_p,display->max_x*display->max_y*display->max_z*sizeof(cell))!=display->max_x*display->max_y*display->max_z*sizeof(cell))
133  {
134   puts("saving file failed");
135   return -23;
136  }
137  close(save_file_fd);
138  puts("saved file");
139  return 23;
140 }
141
142 int distrib_c_conc(cell *cell_p,int c_c0,int c_slope,u32 c_conc,u32 x_max,u32 y_max,u32 z_max)
143 {
144  int i,j;
145  u32 area,c_area,total,count;
146  u32 x,y,z,sum_c_z;
147
148  total=0;
149  area=x_max*y_max;
150  sum_c_z=c_c0*z_max+c_slope*gr;
151
152  for(i=0;i<z_max;i++)
153  {
154   count=0;
155   c_area=(c_conc*(c_c0+(i+1)*c_slope))/sum_c_z;
156   for(j=0;j<area;j++)
157   {
158    if(!(cell_p+j+i*area)->status&AMORPH) count++; 
159   }
160   for(j=0;j<area;j++)
161   {
162    if(!(cell_p+j+i*area)->status&AMORPH)
163    { 
164     (cell_p+j+i*area)->conc=c_area/count;
165     total+=c_area/count;
166    }
167   }
168   j=0;
169   while(j<c_area%count)
170   {
171    x=rand_get(x_max);
172    y=rand_get(y_max);
173    if(!(cell_p+x+y*x_max+i*area)->status&AMORPH)
174    {
175     (cell_p+x+y*x_max+i*area)->conc+=1;
176     total++;
177     j++;
178    }
179   }
180  }
181  i=0;
182  while(i<c_conc-total)
183  {
184   x=rand_get(x_max);
185   y=rand_get(y_max);
186   z=rand_get_lgp(c_slope,c_c0,z_max);
187   if(!(cell_p+x+y*x_max+z*area)->status&AMORPH)
188   {
189    (cell_p+x+y*x_max+z*area)->conc+=1;
190    i++;
191   }
192  }
193  return 23;
194 }
195
196 /* look at cell ... */
197 int process_cell(cell *cell_p,u32 x,u32 y,u32 z,u32 x_max,u32 y_max,u32 z_max,int range,double faktor,double p0,u32 *c_conc)
198 {
199  cell *this_cell;
200  int i,j,k;
201  double pressure;
202
203  this_cell=cell_p+x+y*x_max+z*x_max*y_max;
204  pressure=p0*URAND_2BYTE_MAX;
205
206  for(i=-range;i<=range;i++)
207  {
208   for(j=-range;j<=range;j++)
209   {
210    // z relaxation, no pressure in z direction
211    // for(k=-range;k<=range;k++)
212    // {
213     if(!(i==0 && j==0)) //  && k==0))
214     {
215      // if((cell_p+((x+x_max+i)%x_max)+((y+j+y_max)%y_max)*x_max+((z+k+z_max)%z_max)*x_max*y_max)->status&AMORPH) pressure+=faktor*URAND_2BYTE_MAX/(i*i+j*j+k*k);
216      if((cell_p+((x+x_max+i)%x_max)+((y+j+y_max)%y_max)*x_max+z*x_max*y_max)->status&AMORPH) pressure+=faktor*URAND_2BYTE_MAX/(i*i+j*j);
217     }
218    // }
219   }
220  }
221  pressure*=this_cell->conc;
222  if(this_cell->status&AMORPH)
223  {
224   /* wrong probability! just test by now ...*/
225   if(rand_get(URAND_2BYTE_MAX)>pressure)
226   {
227     make_cryst(this_cell);
228     *c_conc=*c_conc+1+this_cell->conc;
229   } else *c_conc+=1;
230  } else
231  {
232   if(rand_get(URAND_2BYTE_MAX)<=pressure)
233   {
234    make_amorph(this_cell);
235    *c_conc=*c_conc+1-this_cell->conc;
236   } else *c_conc+=1;
237  }
238  return 23;
239 }
240
241 int main(int argc,char **argv) 
242 {
243  u32 x_cell,y_cell,z_cell; /* amount of segments */
244  u32 x,y,z; /* cells */
245  int i; /* for counting */
246  int slope_nel,start_nel; /* nuclear energy loss: slope, constant */
247  int a_p_range; /* p. range of amorphous sic */
248  double a_p_faktor,a_p_p0; /* p0 and faktor of amorphous sic */
249  int c_dist_c0,c_dist_slope; /* c start concentration and linear slope of c distribution */
250  u32 c_conc;
251  int steps; /* # steps */
252  cell *cell_p;
253  struct __display display;
254  u32 display_x,display_y,display_z; /* intercept point of diplayed areas */
255  u32 display_refresh_rate; /* refresh rate for display */
256  int quit=0; /* continue/quit status */
257  char save_file[MAX_CHARS_SAVE_FILE];
258  char load_file[MAX_CHARS_LOAD_FILE];
259  unsigned char no_wait;
260
261  printfd("debug: sizeof my u32 variable: %d\n",sizeof(u32));
262  printfd("debug: sizeof my cell struct: %d\n",sizeof(cell));
263
264  /* default values */
265  x_cell=DEFAULT_X_SEG;
266  y_cell=DEFAULT_Y_SEG;
267  z_cell=DEFAULT_Z_SEG;
268  slope_nel=DEFAULT_SLOPE_NEL;
269  start_nel=DEFAULT_START_NEL;
270  a_p_range=DEFAULT_A_P_RANGE;
271  a_p_faktor=DEFAULT_A_P_FAKTOR;
272  a_p_p0=DEFAULT_A_P_P0;
273  c_dist_c0=DEFAULT_C_DIST_START_CONC;
274  c_dist_slope=DEFAULT_C_DIST_SLOPE;
275  c_conc=DEFAULT_C_C0;
276  steps=DEFAULT_STEPS;
277  display_x=x_cell/2;
278  display_y=y_cell/2;
279  display_z=z_cell/2;
280  display_refresh_rate=DEFAULT_DISPLAY_REF_RATE;
281  strcpy(random_file,"");
282  strcpy(save_file,"");
283  strcpy(load_file,"");
284  no_wait=0;
285  
286  /* parse command args */
287  for(i=1;i<argc;i++)
288  {
289   if(argv[i][0]=='-')
290   {
291    switch(argv[i][1])
292    {
293     case 'h':
294      usage();
295      return 23;
296      break;
297     case 'a':
298      slope_nel=atoi(argv[++i]);
299      break;
300     case 'c':
301      start_nel=atoi(argv[++i]);
302      break;
303     case 'x':
304      x_cell=atoi(argv[++i]);
305      break;
306     case 'y':
307      y_cell=atoi(argv[++i]);
308      break;
309     case 'z':
310      z_cell=atoi(argv[++i]);
311      break;
312     case 's':
313      steps=atoi(argv[++i]);
314      break;
315     case 'X':
316      display_x=atoi(argv[++i]);
317      break;
318     case 'Y':
319      display_y=atoi(argv[++i]);
320      break;
321     case 'Z':
322      display_z=atoi(argv[++i]);
323      break;
324     case 'd':
325      display_refresh_rate=atoi(argv[++i]);
326      break;
327     case 'r':
328      a_p_range=atoi(argv[++i]);
329      break;
330     case 'f':
331      a_p_faktor=atof(argv[++i]);
332      break;
333     case 'p':
334      a_p_p0=atof(argv[++i]);
335      break;
336     case 'b':
337      c_conc=atoi(argv[++i]);
338      break;
339     case 'C':
340      c_dist_c0=atoi(argv[++i]);
341      break;
342     case 'S':
343      c_dist_slope=atoi(argv[++i]);
344      break;
345     case 'R':
346      strcpy(random_file,argv[++i]);
347      break;
348     case 'D':
349      strcpy(save_file,argv[++i]);
350      break;
351     case 'L':
352      strcpy(load_file,argv[++i]);
353      break;
354     case 'n':
355      no_wait=1;
356      break;
357     default:
358      usage();
359      return -23;
360    }
361   } else usage();
362  }
363
364  /* open random fd */
365  if(!strcmp(random_file,""))
366  {
367   if((random_fd=open("/dev/urandom",O_RDONLY))<0)
368   {
369    puts("cannot open /dev/urandom");
370    return -23;
371   }
372  } else
373  {
374   if((random_fd=open(random_file,O_RDONLY))<0)
375   {
376    puts("cannot open random file");
377    return -23;
378   }
379  }
380  /* allocate random number buffer */
381  printf("malloc will free %d bytes now ...\n",RAND_BUF_SIZE);
382  if((rand_buf=(u32 *)malloc(RAND_BUF_SIZE))==NULL)
383  {
384   puts("failed allocating memory for random numbers");
385   return -23;
386  }
387  rand_current=rand_buf+RAND_BUF_SIZE;
388
389  /* calculate gr one time! */
390  gr=0;
391  for(i=1;i<=z_cell;i++) gr+=i;
392  printfd("debug: gr = %d\n",gr);
393
394  /* allocate cells */
395  printf("malloc will free %d bytes now ...\n",x_cell*y_cell*z_cell*sizeof(cell));
396  if((cell_p=(cell *)malloc(x_cell*y_cell*z_cell*sizeof(cell)))==NULL)
397  {
398   puts("failed allocating memory for cells");
399   return -23;
400  }
401  memset(cell_p,0,x_cell*y_cell*z_cell*sizeof(cell));
402
403  /* load from file */
404  if(strcmp(load_file,""))
405  {
406   display.cell_p=cell_p;
407   load_from_file(load_file,&display);
408   x_cell=display.max_x;
409   y_cell=display.max_y;
410   z_cell=display.max_z;
411  }
412
413  /* init display */
414  printfd("debug: init display now ...\n");
415  display_init(x_cell,y_cell,z_cell,&display,cell_p,&argc,argv);
416
417  /* main routine */
418  
419  /* did we load from file? */
420  if(!strcmp(load_file,""))
421  {
422
423  printfd("debug: starting main routine ...\n");
424  for(display.step=0;display.step<steps;display.step++)
425  {
426   x=rand_get(x_cell);
427   y=rand_get(y_cell);
428   z=rand_get_lgp(slope_nel,start_nel,z_cell);
429
430   /* distribute c concentration */
431   distrib_c_conc(cell_p,c_dist_c0,c_dist_slope,c_conc,x_cell,y_cell,z_cell);
432
433   process_cell(cell_p,x,y,z,x_cell,y_cell,z_cell,a_p_range,a_p_faktor,a_p_p0,&c_conc);
434
435   /* display stuff */
436   if((display.step%display_refresh_rate)==0)
437    display_draw(&display,display_x,display_y,display_z);
438  }
439
440  }
441
442  if(strcmp(save_file,"")) save_to_file(save_file,&display);
443
444  printfd("debug: main routine finished!\n");
445   
446  /* display again and listen for events */
447  display_draw(&display,display_x,display_y,display_z);
448
449  if(!no_wait)
450  {
451   display_event_init(&display);
452
453   while(!quit)
454   {
455    display_scan_event(&display,&display_x,&display_y,&display_z,&quit);
456    display_draw(&display,display_x,display_y,display_z);
457   }
458  }
459
460  display_release(&display);
461
462  return 23;
463 }