added diffusion of c ions
[physik/nlsop.git] / nlsop.c
1 /*
2  * nlsop.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 #include "nlsop.h"
24
25 #include "dfbapi.h"
26 #include "random.h"
27
28 #define MAKE_AMORPH(N) *(N)|=AMORPH
29 #define MAKE_CRYST(N) *(N)&=~AMORPH
30
31 int usage(void)
32 {
33  puts("usage:");
34  puts("-h \t\t help");
35  puts("-n \t\t no user interaction");
36  printf("-a <value> \t slope of nuclear energy loss (default %f)\n",A_EL);
37  printf("-b <value> \t nuclear energy loss offset (default %f)\n",B_EL);
38  printf("-x <value> \t # x cells (default %d)\n",X);
39  printf("-y <value> \t # x cells (default %d)\n",Y);
40  printf("-z <value> \t # x cells (default %d)\n",Z);
41  /*
42  printf("-X <value> \t display x (default %d)\n",X/2-1);
43  printf("-Y <value> \t display y (default %d)\n",Y/2-1);
44  printf("-Z <value> \t display z (default %d)\n",Z/2-1);
45  */
46  printf("-s <value> \t steps (default %d)\n",STEPS);
47  printf("-d <value> \t refresh display (default %d)\n",REFRESH);
48  printf("-r <value> \t amorphous influence range (default %d)\n",RANGE);
49  printf("-f <value> \t pressure = <value> * 1/distance^2 (default %f)\n",A_AP);
50  printf("-p <value> \t pressure offset (default %f)\n",B_AP);
51  printf("-A <value> \t slope of linear c distribution (default %f)\n",A_CD);
52  printf("-B <value> \t linear c distribution offset (default %f)\n",B_CD);
53  /*
54  printf("-C <value> \t initial c concentration (default %d)\n",CC);
55  */
56  printf("-D <value> \t diffusion rate from cryst to amorph cells (default %f)\n",D_R);
57  puts("-L <file> \t load from file");
58  puts("-S <file> \t save to file");
59  puts("-R <file> \t read from random file");
60  
61  return 1;
62 }
63
64 int process_cell(d3_lattice *d3_l,u32 x,u32 y,u32 z,int r,double a,double b,int *t_c)
65 {
66  unsigned char *thiz;
67  int *conc;
68  int i,j;
69  double p;
70
71  thiz=d3_l->status+x+y*d3_l->max_x+z*d3_l->max_x*d3_l->max_y;
72  conc=d3_l->extra+x+y*d3_l->max_x+z*d3_l->max_x*d3_l->max_y;
73  p=b*URAND_MAX;
74  for(i=-r;i<=r;i++)
75  {
76   for(j=-r;j<=r;j++)
77   {
78    if(!(i==0 && j==0))
79    {
80     if(*(d3_l->status+((x+d3_l->max_x+i)%d3_l->max_x)+((y+d3_l->max_y+j)%d3_l->max_x)*d3_l->max_x+z*d3_l->max_x*d3_l->max_y)&AMORPH) p+=a*URAND_MAX/(i*i+j*j);
81    } 
82   }
83  }
84  if(!(*thiz&AMORPH))
85  {
86   if(get_rand(URAND_MAX)<=p)
87   {
88    MAKE_AMORPH(thiz);
89    // *t_c=*t_c+1-*conc;
90   } // else *t_c+=1;
91  } else
92  {
93   /* assume 1-p probability */
94   if(get_rand(URAND_MAX)>p)
95   {
96    MAKE_CRYST(thiz);
97    // *t_c=*t_c+1+*conc;
98   } // else *t_c+=1;
99  }
100  
101  *t_c+=1;
102
103  return 1;
104 }
105
106 int distrib_c(d3_lattice *d3_l,double d_r,double a,double b)
107 {
108  u32 x,y,z;
109  int i,j,k,c;
110  int offset,off;
111  int carry;
112
113  /* put one c ion somewhere in the lattice */
114  x=get_rand(d3_l->max_x);
115  y=get_rand(d3_l->max_y);
116  z=get_rand_lgp(d3_l->max_z,a,b);
117  *(d3_l->extra+x+y*d3_l->max_x+z*d3_l->max_x*d3_l->max_y)+=1;
118
119  /* diffusion in layer */
120  for(i=0;i<d3_l->max_x;i++)
121  {
122   for(j=0;j<d3_l->max_y;j++)
123   {
124    for(k=0;k<d3_l->max_z;k++)
125    {
126     offset=i+j*d3_l->max_x+k*d3_l->max_x*d3_l->max_y;
127     /* case amorph */
128     if(*(d3_l->status+offset)&AMORPH)
129     {
130      /* look at neighbours and move c ions */
131      for(c=-1;c<=1;c++)
132      {
133       if(c!=0)
134       {
135        off=((i+d3_l->max_x+c)%d3_l->max_x)+j*d3_l->max_x+k*d3_l->max_x*d3_l->max_y;
136        /* case neighbour not amorph */
137        if(!(*(d3_l->status+off)&AMORPH)) carry=(int)(d_r*(*(d3_l->extra+off)));
138        /* case neighbour amorph */
139        else carry=(*(d3_l->extra+off)-*(d3_l->extra+offset))/2;
140        if(carry!=0)
141        {
142         *(d3_l->extra+offset)+=carry;
143         *(d3_l->extra+off)-=carry;
144        }
145       }
146      }
147      for(c=-1;c<=1;c++)
148      {
149       if(c!=0)
150       {
151        off=i+((j+c+d3_l->max_y)%d3_l->max_y)*d3_l->max_x+k*d3_l->max_x*d3_l->max_y;
152        /* case neighbour not amorph */  
153        if(!(*(d3_l->status+off)&AMORPH)) carry=(int)(d_r*(*(d3_l->extra+off)));                             
154        /* case neighbour amorph */
155        else carry=(*(d3_l->extra+off)-*(d3_l->extra+offset))/2;
156        if(carry!=0)
157        {
158         *(d3_l->extra+offset)+=carry; 
159         *(d3_l->extra+off)-=carry; 
160        }
161       }
162      }
163     } else
164     /* case not amorph */
165     {
166      /* look at neighbours and move c ions */     
167      for(c=-1;c<=1;c++) 
168      {
169       if(c!=0)
170       {
171        off=i+((j+c+d3_l->max_y)%d3_l->max_y)*d3_l->max_x+k*d3_l->max_x*d3_l->max_y;
172        /* case neighbour not amorph */
173        if(!(*(d3_l->status+off)&AMORPH))
174        {
175         carry=(*(d3_l->extra+off)-*(d3_l->extra+offset))/2;
176         if(carry!=0)
177         {
178          *(d3_l->extra+offset)+=carry;
179          *(d3_l->extra+off)-=carry;
180         }
181        }
182       }
183      }
184     }
185    } /* for z */
186   } /* for y */
187  } /* for x */
188
189  return 1;
190 }
191
192 int distrib_c_old(d3_lattice *d3_l,int t_c,double a,double b)
193 {
194  int i,j,k,total,area;
195  double sum;
196  int temp,left;
197  int *area_h;
198  u32 x,y,z;
199
200  area=d3_l->max_x*d3_l->max_y;
201  area_h=(int *)malloc(d3_l->max_z*sizeof(int));
202
203  total=0;
204  sum=b*d3_l->max_z+a*d3_l->max_z*(d3_l->max_z+1)/2;
205  for(i=0;i<d3_l->max_z;i++)
206  {
207   area_h[i]=0;
208   for(j=0;j<area;j++)
209   {
210    if(!(*(d3_l->status+(i*area)+j)&AMORPH))
211    {
212     area_h[i]+=1;
213    }
214   }
215   temp=(int)((i+1)*a+b)*t_c/(sum*area_h[i]);
216   for(j=0;j<area;j++)
217   {
218    if(!(*(d3_l->status+(i*area)+j)&AMORPH))
219    {
220     *(d3_l->extra+(i*area)+j)=temp;
221     total+=temp;
222    }
223   }
224   left=(int)(((i+1)*a+b)*t_c/sum)%area_h[i];
225   while(left)
226   {
227    x=get_rand(d3_l->max_x);
228    y=get_rand(d3_l->max_y);
229    if(!(*(d3_l->status+(i*area)+x+y*d3_l->max_x)&AMORPH))
230    {
231     *(d3_l->extra+(i*area)+x+y*d3_l->max_x)+=1;
232     total+=1;
233     left-=1;
234    }
235   }
236  }
237  left=t_c-total;
238  while(left)
239  {
240   x=get_rand(d3_l->max_x);
241   y=get_rand(d3_l->max_y);
242   z=get_rand_lgp(d3_l->max_z,a,b);
243   if(!(*(d3_l->status+x+y*d3_l->max_x+z*area)&AMORPH))
244   {
245    *(d3_l->extra+x+y*d3_l->max_x+z*area)+=1;
246    left-=1;
247   }
248  }
249  free(area_h);
250
251  return 1;
252 }
253
254 int save_to_file(char *sf,d3_lattice *d3_l,info *my_inf)
255 {
256  int sf_fd,c;
257
258  if((sf_fd=open(sf,O_WRONLY|O_CREAT))<0)
259  {
260   puts("cannot open save file");
261   return -1;
262  }
263  if(write(sf_fd,d3_l,sizeof(d3_lattice))<sizeof(d3_lattice))
264  {
265   puts("failed saving d3 lattice struct");
266   return -1;
267  }
268  if(write(sf_fd,my_inf,sizeof(info))<sizeof(info))
269  {
270   puts("failed saving info struct");
271   return-1;
272  }
273  c=d3_l->max_x*d3_l->max_y*d3_l->max_z;
274  if(write(sf_fd,d3_l->status,c*sizeof(unsigned char))<c*sizeof(unsigned char))
275  {
276   puts("failed saving status of d3 lattice sites");
277   return -1;
278  }
279  if(write(sf_fd,d3_l->extra,c*sizeof(int))<c*sizeof(int))
280  {
281   puts("failed saving sites concentration");
282   return -1;
283  }
284  close(sf_fd);
285
286  return 1;
287 }
288
289 int load_from_file(char *lf,d3_lattice *d3_l,info *my_inf)
290 {
291  int lf_fd,c;
292
293  if((lf_fd=open(lf,O_RDONLY))<0)
294  {
295   puts("cannot open load file");
296   return -1;
297  }
298  if(read(lf_fd,d3_l,sizeof(d3_lattice))<sizeof(d3_lattice))
299  {
300   puts("failed reading d3 lattice struct");
301   return -1;
302  }
303  if(read(lf_fd,my_inf,sizeof(info))<sizeof(info))
304  {
305   puts("failed reading info struct");
306   return-1;
307  }
308  c=d3_l->max_x*d3_l->max_y*d3_l->max_z;
309  if((d3_l->status=(unsigned char*)malloc(c*sizeof(unsigned char)))==NULL)
310  {
311   puts("cannot allocate status buffer");
312   return -1;
313  }
314  if((d3_l->extra=(int *)malloc(c*sizeof(int)))==NULL)
315  {
316   puts("cannot allocate concentration buffer");
317   return -1;
318  }
319  if(read(lf_fd,d3_l->status,c*sizeof(unsigned char))<c*sizeof(unsigned char))
320  {
321   puts("failed reading status of d3 lattice sites");
322   return -1;
323  }
324  if(read(lf_fd,d3_l->extra,c*sizeof(int))<c*sizeof(int))
325  {
326   puts("failed reading sites concentration");
327   return -1;
328  }
329  close(lf_fd);
330
331  return 1;
332 }
333
334 int main(int argc,char **argv)
335 {
336  u32 max_x,max_y,max_z,x,y,z,x_c,y_c,z_c;
337  int i,quit,escape,nowait;
338  int refresh;
339  char s_file[MAX_CHARS];
340  char l_file[MAX_CHARS];
341  char r_file[MAX_CHARS];
342  char x_txt[MAX_TXT];
343  char y_txt[MAX_TXT];
344  char z_txt[MAX_TXT];
345  char status_txt[MAX_TXT];
346  char conc_txt[MAX_TXT];
347  char steps_txt[MAX_TXT];
348  char cc_txt[MAX_TXT];
349  char a_txt[MAX_TXT];
350  char s_txt[MAX_TXT];
351  char ap_txt[MAX_TXT];
352  char el_txt[MAX_TXT];
353  char cd_txt[MAX_TXT];
354  char r_txt[MAX_TXT];
355  char ap2_txt[MAX_TXT];
356  char cd2_txt[MAX_TXT];
357  char el2_txt[MAX_TXT];
358  char dr_txt[MAX_TXT];
359  char *arg_v[MAX_ARGV];
360  d3_lattice d3_l;
361  info my_info;
362
363  max_x=X;
364  max_y=Y;
365  max_z=Z;
366  my_info.steps=STEPS;
367  my_info.range=RANGE;
368  refresh=REFRESH;
369  my_info.a_el=A_EL;
370  my_info.b_el=B_EL;
371  my_info.a_cd=A_CD;
372  my_info.b_cd=B_CD;
373  my_info.a_ap=A_AP;
374  my_info.b_ap=B_AP;
375  my_info.cc=CC;
376  my_info.d_r=D_R;
377  nowait=0;
378  quit=0;
379  escape=0;
380  strcpy(s_file,"");
381  strcpy(l_file,"");
382  strcpy(r_file,"");
383
384  for(i=1;i<argc;i++)
385  {
386   if(argv[i][0]=='-')
387   {
388    switch(argv[i][1])
389    {
390     case 'h':
391      usage();
392      return -1;
393     case 'n':
394      nowait=1;
395      break;
396     case 'a':
397      my_info.a_el=atof(argv[++i]);
398      break;
399     case 'b':
400      my_info.b_el=atof(argv[++i]);
401      break;
402     case 'x':
403      max_x=atoi(argv[++i]);
404      break;
405     case 'y':
406      max_y=atoi(argv[++i]);
407      break;
408     case 'z':
409      max_z=atoi(argv[++i]);
410      break;
411     /*
412     case 'X':
413      x=atoi(argv[++i]);
414      break;
415     case 'Y':
416      y=atoi(argv[++i]);
417      break;
418     case 'Z':
419      z=atoi(argv[++i]);
420      break;
421     */
422     case 's':
423      my_info.steps=atoi(argv[++i]);
424      break;
425     case 'd':
426      refresh=atoi(argv[++i]);
427      break;
428     case 'r':
429      my_info.range=atoi(argv[++i]);
430      break;
431     case 'f':
432      my_info.a_ap=atof(argv[++i]);
433      break;
434     case 'p':
435      my_info.b_ap=atof(argv[++i]);
436      break;
437     case 'A':
438      my_info.a_cd=atof(argv[++i]);
439      break;
440     case 'B':
441      my_info.b_cd=atof(argv[++i]);
442      break;
443     /*
444     case 'C':
445      my_info.cc=atoi(argv[++i]);
446      break;
447     */
448     case 'D':
449      my_info.d_r=atof(argv[++i]);
450      break;
451     case 'L':
452      strcpy(l_file,argv[++i]);
453      break;
454     case 'S':
455      strcpy(s_file,argv[++i]);
456      break;
457     case 'R':
458      strcpy(r_file,argv[++i]);
459      break;
460     default:
461      usage();
462      return -1;
463    }
464   } else usage();
465  }
466
467  x=max_x/2-1;
468  y=max_y/2-1;
469  z=max_z/2-1;
470
471
472
473  if(!strcmp(r_file,"")) rand_init(NULL);
474  else rand_init(r_file);
475
476  if(!strcmp(l_file,""))
477  {
478   i=max_x*max_y*max_z;
479   d3_lattice_init(&argc,argv,&d3_l,max_x,max_y,max_z);
480   if((d3_l.status=(unsigned char *)malloc(i*sizeof(unsigned char)))==NULL)
481   {
482    puts("failed allocating status buffer");
483    return -1;
484   }
485   memset(d3_l.status,0,i*sizeof(unsigned char));
486   if((d3_l.extra=(int *)malloc(i*sizeof(int)))==NULL)
487   {
488    puts("failed allocating concentration buffer");
489    return -1;
490   }
491   memset(d3_l.extra,0,i*sizeof(int));
492  } else
493  {
494   load_from_file(l_file,&d3_l,&my_info);
495   d3_lattice_init(&argc,argv,&d3_l,d3_l.max_x,d3_l.max_y,d3_l.max_z);
496  }
497
498  d3_event_init(&d3_l);
499
500  strcpy(a_txt,"args:");
501  sprintf(s_txt,"steps: %d",my_info.steps);
502  sprintf(r_txt,"pressure range: %d",my_info.range);
503  sprintf(ap_txt,"pressure faktor: %.2f",my_info.a_ap);
504  sprintf(ap2_txt,"pressure offset: %.2f",my_info.b_ap);
505  sprintf(el_txt,"energy loss slope: %.2f",my_info.a_el);
506  sprintf(el2_txt,"energy loss offset: %.2f",my_info.b_el);
507  sprintf(cd_txt,"c distrib slope: %.2f",my_info.a_cd);
508  sprintf(cd2_txt,"c distrib offset: %.2f",my_info.b_cd);
509  sprintf(dr_txt,"diffusion rate: %.2f",my_info.d_r);
510  arg_v[1]=x_txt;
511  arg_v[2]=y_txt;
512  arg_v[3]=z_txt;
513  arg_v[4]=NULL;
514  arg_v[5]=status_txt;
515  arg_v[6]=conc_txt;
516  arg_v[7]=NULL;
517  arg_v[8]=NULL;
518  arg_v[9]=NULL;
519  arg_v[10]=steps_txt;;
520  arg_v[11]=cc_txt;
521  arg_v[12]=NULL;
522  arg_v[13]=NULL;
523  arg_v[14]=a_txt;
524  arg_v[15]=NULL;
525  arg_v[16]=s_txt;
526  arg_v[17]=r_txt;
527  arg_v[18]=ap_txt;
528  arg_v[19]=ap2_txt;
529  arg_v[20]=el_txt;
530  arg_v[21]=el2_txt;
531  arg_v[22]=cd_txt;
532  arg_v[23]=cd2_txt;
533  arg_v[24]=dr_txt;
534
535  if(!strcmp(l_file,""))
536  {
537   i=0;
538   while((i<my_info.steps) && (quit==0) && (escape==0))
539   {
540    x_c=get_rand(d3_l.max_x);
541    y_c=get_rand(d3_l.max_y);
542    z_c=get_rand_lgp(d3_l.max_z,my_info.a_el,my_info.b_el);
543    distrib_c(&d3_l,my_info.d_r,my_info.a_cd,my_info.b_cd);
544    process_cell(&d3_l,x_c,y_c,z_c,my_info.range,my_info.a_ap,my_info.b_ap,&(my_info.cc));
545    if(i%refresh==0)
546    {
547     sprintf(x_txt,"x: %d",x+1);
548     sprintf(y_txt,"y: %d",y+1);
549     sprintf(z_txt,"z: %d",z+1);
550     sprintf(status_txt,"status: %c",(*(d3_l.status+x+y*d3_l.max_x+z*d3_l.max_x*d3_l.max_y)&AMORPH)?'a':'c');
551     sprintf(conc_txt,"conc: %d",*(d3_l.extra+x+y*d3_l.max_x+z*d3_l.max_x*d3_l.max_y));
552     sprintf(steps_txt,"step: %d",i);
553     sprintf(cc_txt,"total c: %d",my_info.cc);
554     d3_lattice_draw(&d3_l,x,y,z,24,arg_v);
555     // scan_event(&d3_l,&x,&y,&z,&quit,&escape);
556    }
557    i++;
558   }
559  }
560
561  if(strcmp(s_file,"")) save_to_file(s_file,&d3_l,&my_info);
562
563  while((quit==0) && (escape==0) && (nowait==0))
564  {
565   sprintf(x_txt,"x: %d",x+1);
566   sprintf(y_txt,"y: %d",y+1);
567   sprintf(z_txt,"z: %d",z+1);
568   sprintf(status_txt,"status: %c",(*(d3_l.status+x+y*d3_l.max_x+z*d3_l.max_x*d3_l.max_y)&AMORPH)?'a':'c');
569   sprintf(conc_txt,"conc: %d",*(d3_l.extra+x+y*d3_l.max_x+z*d3_l.max_x*d3_l.max_y));
570   strcpy(steps_txt,"step: end!");
571   sprintf(cc_txt,"total c: %d",my_info.cc);
572   d3_lattice_draw(&d3_l,x,y,z,24,arg_v);
573   scan_event(&d3_l,&x,&y,&z,&quit,&escape);
574  }
575
576  d3_lattice_release(&d3_l);
577
578  return 1;
579 }