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