finished random reject method
[physik/nlsop.git] / nlsop.c
1 /*
2  * nlsop.c 
3  *
4  * author: frank zirkelbach (frank.zirkelbach@physik.uni-augsburg.de)
5  *
6  * this program tries helping to understand the amorphous depuration
7  * and recrystallization of SiCx while ion implantation at temperatures
8  * below 400 degree celsius.
9  * hopefully the program will simulate the stabilization of the
10  * selforganizing lamella structure in the observed behaviour.
11  *
12  * refs: 
13  *  - J. K. N. Lindner. Habilationsschrift, Universitaet Augsburg.
14  *  - Maik Haeberlen. Diplomarbeit, Universitaet Augsburg.
15  *
16  * Copyright (C) 2004 Frank Zirkelbach
17  *
18  * This program is free software; you can redistribute it and/or modify
19  * it under the terms of the GNU General Public License as published by
20  * the Free Software Foundation; either version 2 of the License, or
21  * (at your option) any later version.
22  *
23  * This program is distributed in the hope that it will be useful,
24  * but WITHOUT ANY WARRANTY; without even the implied warranty of
25  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26  * GNU General Public License for more details.
27  *
28  * You should have received a copy of the GNU General Public License
29  * along with this program; if not, write to the Free Software
30  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
31  *
32  */
33
34 #define _GNU_SOURCE
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <sys/types.h>
39 #include <sys/stat.h>
40 #include <fcntl.h>
41 #include <unistd.h>
42
43 #include "nlsop.h"
44
45 #include "dfbapi.h"
46 #include "random.h"
47
48 #define MAKE_AMORPH(N) *(N)|=AMORPH
49 #define MAKE_CRYST(N) *(N)&=~AMORPH
50
51 int usage(void)
52 {
53  puts("usage:");
54  puts("-h \t\t help");
55  puts("-n \t\t no user interaction");
56  puts("-Z \t\t cryst -> amorph c diffusion in z direction");
57  puts("-i \t\t no cryst to cryst diffusion");
58  printf("-a <value> \t slope of nuclear energy loss (default %f)\n",A_EL);
59  printf("-b <value> \t nuclear energy loss offset (default %f)\n",B_EL);
60  printf("-x <value> \t # x cells (default %d)\n",X);
61  printf("-y <value> \t # y cells (default %d)\n",Y);
62  printf("-z <value> \t # z cells (default %d)\n",Z);
63  printf("-s <value> \t steps (default %d)\n",STEPS);
64  printf("-d <value> \t refresh display (default %d)\n",REFRESH);
65  printf("-r <value> \t amorphous influence range (default %d)\n",RANGE);
66  printf("-f <value> \t pressure = <value> * 1/distance^2 (default %f)\n",A_AP);
67  printf("-p <value> \t pressure offset (default %f)\n",B_AP);
68  printf("-F <value> \t proportionality constant between c conc and ability to get amorphous (default %f)\n",A_CP);
69  printf("-A <value> \t slope of linear c distribution (default %f)\n",A_CD);
70  printf("-B <value> \t linear c distribution offset (default %f)\n",B_CD);
71  printf("-D <value> \t diffusion rate from cryst to amorph cells (default %f)\n",DR_AC);
72  printf("-c <value> \t diffusion rate in cryst cells (default %f)\n",DR_CC);
73  printf("-e <value> \t do diffusion every <value> steps (default %d)\n",DIFF_RATE);
74  puts("-g <file> <step> continue simulation from file and step (step > 0)!");
75  printf("-W <value> \t write every <value> steps to save file (default %d)\n",RESAVE);
76  puts("-C <file> \t convert file to gnuplot format");
77  puts("-L <file> \t load from file");
78  puts("-S <file> \t save to file");
79  puts("-R <file> \t read from random file");
80  puts("-P <file> \t specify implantation profile file");
81  printf("-H <value> \t collisions per ion in simulation window (default %d)\n",CPI);
82  
83  return 1;
84 }
85
86 int process_cell(d3_lattice *d3_l,u32 x,u32 y,u32 z,info *my_info)
87 {
88  unsigned char *thiz;
89  int *conc;
90  int i,j;
91  int off;
92  double p;
93
94  thiz=d3_l->status+x+y*d3_l->max_x+z*d3_l->max_x*d3_l->max_y;
95  conc=d3_l->extra+x+y*d3_l->max_x+z*d3_l->max_x*d3_l->max_y;
96  p=my_info->b_ap*URAND_MAX;
97  for(i=-(my_info->range);i<=my_info->range;i++)
98  {
99   for(j=-(my_info->range);j<=my_info->range;j++)
100   {
101    if(!(i==0 && j==0))
102    {
103     off=((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;
104     if(*(d3_l->status+off)&AMORPH) p+=my_info->a_ap*(*(d3_l->extra+off))*URAND_MAX/(i*i+j*j);
105    } 
106   }
107  }
108  p+=*conc*my_info->a_cp*URAND_MAX;
109  if(!(*thiz&AMORPH))
110  {
111   if(get_rand(URAND_MAX)<=p) MAKE_AMORPH(thiz);
112  } else
113  {
114   /* assume 1-p probability */
115   if(get_rand(URAND_MAX)>p) MAKE_CRYST(thiz);
116  }
117  
118  return 1;
119 }
120
121 int distrib_c(d3_lattice *d3_l,info *my_info,int step,double c_ratio,u32 rj_m,u32 *rj_g)
122 {
123  u32 x,y,z;
124  int i,j,k,c;
125  int offset,off;
126  int carry;
127
128  /* put one c ion somewhere in the lattice */
129  if(my_info->cc<c_ratio*step)
130  {
131   x=get_rand(d3_l->max_x);
132   y=get_rand(d3_l->max_y);
133   // printf("nd: %d %d\n",x,y);
134   // z=get_rand_lgp(d3_l->max_z,my_info->a_cd,my_info->b_cd);
135   z=get_rand_reject(d3_l->max_z,rj_m,rj_g);
136   // printf("%d\n",z);
137   *(d3_l->extra+x+y*d3_l->max_x+z*d3_l->max_x*d3_l->max_y)+=1;
138   (my_info->cc)++;
139  }
140
141  if(step%my_info->diff_rate==0)
142  {
143
144  for(i=0;i<d3_l->max_x;i++)
145  {
146   for(j=0;j<d3_l->max_y;j++)
147   {
148    for(k=0;k<d3_l->max_z;k++)
149    {
150     offset=i+j*d3_l->max_x+k*d3_l->max_x*d3_l->max_y;
151     /* case amorph: amorph <- cryst diffusion */
152     if(*(d3_l->status+offset)&AMORPH)
153     {
154      for(c=-1;c<=1;c++)
155      {
156       if(c!=0)
157       {
158        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;
159        carry=0;
160        if(!(*(d3_l->status+off)&AMORPH)) carry=(int)(my_info->dr_ac*(*(d3_l->extra+off)));
161        if(carry!=0)
162        {
163         *(d3_l->extra+offset)+=carry;
164         *(d3_l->extra+off)-=carry;
165        }
166       }
167      }
168      for(c=-1;c<=1;c++)
169      {
170       if(c!=0)
171       {
172        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;
173        carry=0;
174        if(!(*(d3_l->status+off)&AMORPH)) carry=(int)(my_info->dr_ac*(*(d3_l->extra+off)));
175        if(carry!=0)
176        {
177         *(d3_l->extra+offset)+=carry; 
178         *(d3_l->extra+off)-=carry; 
179        }
180       }
181      }
182      if(my_info->z_diff)
183      {
184       if(k!=0)
185       {
186        off=i+j*d3_l->max_x+(k-1)*d3_l->max_x*d3_l->max_y;
187        carry=0;
188        if(!*(d3_l->status+off)&AMORPH) carry=(int)(my_info->dr_ac*(*(d3_l->extra+off)));
189        if(carry!=0)
190        {
191         *(d3_l->extra+off)-=carry;
192         *(d3_l->extra+offset)+=carry;
193        }
194       }
195       if(k!=d3_l->max_z-1)
196       {
197        off=i+j*d3_l->max_x+(k+1)*d3_l->max_x*d3_l->max_y;
198        carry=0;
199        if(!*(d3_l->status+off)&AMORPH) carry=(int)(my_info->dr_ac*(*(d3_l->extra+off)));
200        if(carry!=0)
201        {
202         *(d3_l->extra+off)-=carry;
203         *(d3_l->extra+offset)+=carry;
204        }
205       }
206      }  
207     } else
208     /* case not amorph: cryst <-> cryst diffusion */
209     if(my_info->c_diff) {
210     /* if there is c diff, no diff in z-direction */
211     {
212      for(c=-1;c<=1;c++) 
213      {
214       if(c!=0)
215       {
216        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;
217        carry=0;
218        if(!(*(d3_l->status+off)&AMORPH))
219        {
220         carry=(int)(my_info->dr_cc*(*(d3_l->extra+off)-*(d3_l->extra+offset))/2);
221         if(carry!=0)
222         {
223          *(d3_l->extra+offset)+=carry;
224          *(d3_l->extra+off)-=carry;
225         }
226        }
227       }
228      }
229      for(c=-1;c<=1;c++)
230      {
231       if(c!=0)
232       {
233        off=((i+c+d3_l->max_x)%d3_l->max_x)+j*d3_l->max_x+k*d3_l->max_x*d3_l->max_y;
234        carry=0;
235        if(!(*(d3_l->status+off)&AMORPH))
236        {
237         carry=(int)(my_info->dr_cc*(*(d3_l->extra+off)-*(d3_l->extra+offset))/2);
238         if(carry!=0)
239         {
240          *(d3_l->extra+offset)+=carry;
241          *(d3_l->extra+off)-=carry;
242         }
243        }
244       }
245      }
246     }
247     /* end test */
248     }
249     /* */
250    } /* for z */
251   } /* for y */
252  } /* for x */
253
254  } /* if step modulo diff_rate == 0 */
255
256  return 1;
257 }
258
259 int calc_pressure(d3_lattice *d3_l,int range)
260 {
261  int i,j,off;
262  double count,max=0;
263  int x,y,z;
264
265  for(x=0;x<d3_l->max_x;x++)
266  {
267   for(y=0;y<d3_l->max_y;y++)
268   {
269    for(z=0;z<d3_l->max_z;z++)
270    {
271     count=0;
272     for(i=-range;i<=range;i++)
273     {
274      for(j=-range;j<=range;j++)
275      {
276       if(i!=0 && j!=0)
277       {
278        off=((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;
279        if(*(d3_l->status+off)&AMORPH) count+=((double)*(d3_l->extra+off))/(i*i+j*j);
280       }
281      }
282     }
283     if(count>max) max=count;
284    }
285   }
286  }
287
288  for(x=0;x<d3_l->max_x;x++)
289  {
290   for(y=0;y<d3_l->max_y;y++)
291   {
292    for(z=0;z<d3_l->max_z;z++)
293    {
294     count=0;
295     for(i=-range;i<=range;i++)
296     {
297      for(j=-range;j<=range;j++)
298      {
299       if(i!=0 && j!=0)
300       {
301        off=((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;
302        if(*(d3_l->status+off)&AMORPH) count+=((double)*(d3_l->extra+off))/(i*i+j*j);
303       }
304      }
305     }
306     *(unsigned char *)(d3_l->v_ptr+x+y*d3_l->max_x+z*d3_l->max_x*d3_l->max_y)=(unsigned char)(count*255/max);
307    }
308   }
309  }
310
311  return 1;
312 }
313
314 int calc_max_extra(d3_lattice *d3_l)
315 {
316  int x,y,z;
317  int off,max=0;
318
319  for(x=0;x<d3_l->max_x;x++)
320  {
321   for(y=0;y<d3_l->max_y;y++)
322   {
323    for(z=0;z<d3_l->max_z;z++)
324    {
325     off=x+y*d3_l->max_x+z*d3_l->max_x*d3_l->max_y;
326     if(*(d3_l->extra+off)>max) max=*(d3_l->extra+off);
327    }
328   }
329  }
330
331  return max;
332 }
333
334 int write_ac_distr(d3_lattice *d3_l,int ac_distr)
335 {
336  int fd,x,y,z;
337  int count=0,offset;
338  char file[16];
339
340  if(ac_distr==1) strcpy(file,"a.plot");
341  if(ac_distr==2) strcpy(file,"c.plot");
342  if(ac_distr==3) strcpy(file,"b.plot");
343
344  if((fd=open(file,O_WRONLY|O_CREAT))<0)
345  {
346   puts("cannot open plot file");
347   return -1;
348  }
349
350  for(z=0;z<d3_l->max_z;z++)
351  {
352   for(x=0;x<d3_l->max_x;x++)
353   {
354    for(y=0;y<d3_l->max_y;y++)
355    {
356     offset=x+y*d3_l->max_x+z*d3_l->max_x*d3_l->max_y;
357     if(ac_distr==1)
358      if(*(d3_l->status+offset)&AMORPH) count+=*(d3_l->extra+offset);
359     if(ac_distr==2)
360      if(!(*(d3_l->status+offset)&AMORPH)) count+=*(d3_l->extra+offset);
361     if(ac_distr==3) count+=*(d3_l->extra+offset);
362    }
363   }
364   dprintf(fd,"%d %d\n",z,count);
365  }
366  close(fd);
367  
368  return 1;
369 }
370
371 int write_bmp(d3_lattice *d3_l,int window,u32 x,u32 y,u32 z)
372 {
373  int fd,i,j,size=0,foo=0,end=0;
374  int width=0,height=0;
375  char bmpfile[MAX_CHARS];
376  char buf[128];
377
378  if(((window==4)||(window==5))&&(d3_l->max_z<FFT_HEIGHT) )
379  {
380   puts("error: z < FFT_HEIGHT!");
381   puts("not writing bmp file ...");
382   return -1;
383  }
384
385  if(window%3==1)
386  {
387   sprintf(bmpfile,"x-z_%d.bmp",y);
388   foo=3*d3_l->max_x;
389   if(window==1)
390   {
391    size=(foo+(4-foo%4))*d3_l->max_z;
392    height=d3_l->max_z;
393   }
394   else 
395   {
396    size=(foo+(4-foo%4))*FFT_HEIGHT;
397    end=d3_l->max_z-FFT_HEIGHT;
398    height=FFT_HEIGHT;
399   }
400   width=d3_l->max_x;
401  }
402  if(window%3==2)
403  {
404   sprintf(bmpfile,"y-z_%d.bmp",x);
405   foo=3*d3_l->max_y;
406   if(window==2)
407   {
408    size=(foo+(4-foo%4))*d3_l->max_z;
409    height=d3_l->max_z;
410   }
411   else 
412   {
413    size=(foo+(4-foo%4))*FFT_HEIGHT;
414    end=d3_l->max_z-FFT_HEIGHT;
415    height=FFT_HEIGHT;
416   }
417   width=d3_l->max_y;
418  }
419  if(window==3)
420  {
421   sprintf(bmpfile,"x-y_%d.bmp",z);
422   foo=3*d3_l->max_x;
423   size=(foo+(4-foo%4))*d3_l->max_y;
424   width=d3_l->max_x;
425   height=d3_l->max_y;
426  }
427
428  if((fd=open(bmpfile,O_WRONLY|O_CREAT))<0)
429  {
430   puts("cannot open bmp file");
431   return -1;
432  }
433
434  /* bmpheader */
435  buf[0]='B'; /* std header start */
436  buf[1]='M';
437  buf[2]=(size+0x36)&0xff; /* file size */
438  buf[3]=(size+0x36)>>8;
439  memset(buf+4,0,6);
440  buf[10]=0x36; /* offset to data */
441  memset(buf+11,0,3);
442  buf[14]=0x28; /* length of bmp info header */
443  memset(buf+15,0,3);
444  buf[18]=width&0xff; /* width and height */
445  buf[19]=width>>8;
446  memset(buf+20,0,2);
447  buf[22]=height&0xff;
448  buf[23]=height>>8;
449  memset(buf+24,0,2);
450  buf[26]=1; /* # planes -> 1 */
451  buf[27]=0;
452  buf[28]=24; /* bits per pixel -> 2^24 (true color) */
453  buf[29]=0;
454  memset(buf+30,0,4); /* compression -> none */
455  buf[34]=size&0xff; /* data size */
456  buf[35]=size>>8;
457  memset(buf+36,0,2);
458  buf[38]=0x12; /* res: pixel/meter */
459  buf[39]=0x0b;
460  memset(buf+40,0,2);
461  buf[42]=0x12;
462  buf[43]=0x0b;
463  memset(buf+44,0,2); 
464  memset(buf+46,0,8); /* no colors, no important colors */
465
466  if(write(fd,buf,54)<54)
467  {
468   puts("failed writing bmp header");
469   return -1;
470  }
471  if(window%3==1)
472  {
473   for(j=0;j<d3_l->max_z-end;j++)
474   {
475    for(i=0;i<d3_l->max_x;i++)
476    {
477     if(*(d3_l->status+i+y*d3_l->max_x+(d3_l->max_z-j-1)*d3_l->max_x*d3_l->max_y)&RED) memset(buf,0xff,3);
478     else memset(buf,0,3);
479     if(write(fd,buf,3)<3)
480     {
481      puts("failed writing rgb values to bmp file");
482      return-1;
483     }
484    }
485    if(foo%4)
486    {
487     memset(buf,0,4-foo%4);
488     if(write(fd,buf,4-foo%4)<4-foo%4)
489     {
490      puts("failed writing 4 byte ending");
491      return -1;
492     }
493    } 
494   }
495  }
496  if(window%3==2)
497  {
498   for(j=0;j<d3_l->max_z-end;j++)
499   {
500    for(i=0;i<d3_l->max_y;i++)
501    {
502     if(*(d3_l->status+x+i*d3_l->max_x+(d3_l->max_z-j-1)*d3_l->max_x*d3_l->max_y)&RED) memset(buf,0xff,3);
503     else memset(buf,0,3);
504     if(write(fd,buf,3)<3)
505     {
506      puts("failed writing rgb values to bmp file");
507      return-1;
508     }
509    }
510    if(foo%4)
511    {
512     memset(buf,0,4-foo%4);
513     if(write(fd,buf,4-foo%4)<4-foo%4)
514     {
515      puts("failed writing 4 byte ending");
516      return -1;
517     }
518    }
519   }
520  }
521  if(window==3)
522  {
523   for(j=0;j<d3_l->max_y;j++)
524   {
525    for(i=0;i<d3_l->max_x;i++)
526    {
527     if(*(d3_l->status+i+(d3_l->max_y-j-1)*d3_l->max_x+z*d3_l->max_x*d3_l->max_y)&RED) memset(buf,0xff,3);
528     else memset(buf,0,3);
529     if(write(fd,buf,3)<3)
530     {
531      puts("failed writing rgb values to bmp file");
532      return -1;
533     }
534    }
535    if(foo%4)
536    {
537     memset(buf,0,4-foo%4);
538     if(write(fd,buf,4-foo%4)<4-foo%4)
539     {
540      puts("failed writing 4 byte ending");
541      return -1;
542     }
543    }
544   }
545  }
546  close(fd);
547
548  return 1;
549 }
550
551 int save_to_file(char *sf,d3_lattice *d3_l,info *my_inf)
552 {
553  int sf_fd,c;
554
555  if((sf_fd=open(sf,O_WRONLY|O_CREAT))<0)
556  {
557   puts("cannot open save file");
558   return -1;
559  }
560  if(write(sf_fd,d3_l,sizeof(d3_lattice))<sizeof(d3_lattice))
561  {
562   puts("failed saving d3 lattice struct");
563   return -1;
564  }
565  if(write(sf_fd,my_inf,sizeof(info))<sizeof(info))
566  {
567   puts("failed saving info struct");
568   return-1;
569  }
570  c=d3_l->max_x*d3_l->max_y*d3_l->max_z;
571  if(write(sf_fd,d3_l->status,c*sizeof(unsigned char))<c*sizeof(unsigned char))
572  {
573   puts("failed saving status of d3 lattice sites");
574   return -1;
575  }
576  if(write(sf_fd,d3_l->extra,c*sizeof(int))<c*sizeof(int))
577  {
578   puts("failed saving sites concentration");
579   return -1;
580  }
581  close(sf_fd);
582
583  return 1;
584 }
585
586 int load_from_file(char *lf,d3_lattice *d3_l,info *my_inf)
587 {
588  int lf_fd,c;
589
590  if((lf_fd=open(lf,O_RDONLY))<0)
591  {
592   puts("cannot open load file");
593   return -1;
594  }
595  if(read(lf_fd,d3_l,sizeof(d3_lattice))<sizeof(d3_lattice))
596  {
597   puts("failed reading d3 lattice struct");
598   return -1;
599  }
600  if(read(lf_fd,my_inf,sizeof(info))<sizeof(info))
601  {
602   puts("failed reading info struct");
603   return-1;
604  }
605  c=d3_l->max_x*d3_l->max_y*d3_l->max_z;
606  if((d3_l->status=(unsigned char*)malloc(c*sizeof(unsigned char)))==NULL)
607  {
608   puts("cannot allocate status buffer");
609   return -1;
610  }
611  if((d3_l->extra=(int *)malloc(c*sizeof(int)))==NULL)
612  {
613   puts("cannot allocate concentration buffer");
614   return -1;
615  }
616  if(read(lf_fd,d3_l->status,c*sizeof(unsigned char))<c*sizeof(unsigned char))
617  {
618   puts("failed reading status of d3 lattice sites");
619   return -1;
620  }
621  if(read(lf_fd,d3_l->extra,c*sizeof(int))<c*sizeof(int))
622  {
623   puts("failed reading sites concentration");
624   return -1;
625  }
626  close(lf_fd);
627
628  return 1;
629 }
630
631 int convert_file(char *cf,d3_lattice *d3_l)
632 {
633  int x,y,z;
634  int c_fd;
635
636  if((c_fd=open(cf,O_WRONLY|O_CREAT))<0)
637  {
638   puts("cannot open convert file");
639   return -1;
640  }
641  dprintf(c_fd,"# created by nlsop (gnuplot format)\n");
642  for(x=0;x<d3_l->max_x;x++)
643  {
644   for(y=0;y<d3_l->max_y;y++)
645   {
646    for(z=0;z<d3_l->max_z;z++)
647    {
648     if(*(d3_l->status+x+y*d3_l->max_x+z*d3_l->max_x*d3_l->max_y)&AMORPH) dprintf(c_fd,"%d %d %d\n",x,y,z);
649    }
650   }
651  }
652  close(c_fd);
653
654  return 1;
655 }
656
657 int get_c_ratio(double *c_ratio,char *pfile,info *my_info,d3_lattice *d3_l)
658 {
659  double all,a,b,d;
660  int i,k;
661  int p_fd;
662  unsigned char buf[32];
663  char *p;
664  unsigned char c;
665
666  if((p_fd=open(pfile,O_RDONLY))<0)
667  {
668   puts("cannot open profile file");
669   return -1;
670  }
671  k=1;
672  d=0;
673  all=0;
674  while(k)
675  {
676   for(i=0;i<32;i++)
677   {
678    k=read(p_fd,&c,1);
679    buf[i]=c;
680    if(c=='\n') break;
681   }
682   if(k)
683   {
684    p=strtok(buf," ");
685    a=atof(p)/10; /* nm */
686    p=strtok(NULL," ");
687    b=atof(p);
688    if(a>my_info->b_cd*CELL_LENGTH && a<(my_info->b_cd+d3_l->max_z)*CELL_LENGTH) d+=b;
689    all+=b;
690   }
691  }
692  *c_ratio=d/all;
693  close(p_fd);
694
695  return 1;
696 }
697
698 u32 get_reject_graph(info *my_info,d3_lattice *d3_l,char *file,u32 *graph) {
699  double a,b;
700  int i,j,k;
701  int fd;
702  char buf[32],*p;
703  unsigned char *flag;
704  u32 max;
705
706  max=0;
707  if((fd=open(file,O_RDONLY))<0)
708  {
709   puts("cannot open file to calculate rejection graph");
710   return -1;
711  }
712  if((flag=(unsigned char *)malloc(d3_l->max_z))==NULL)
713  {
714   puts("cannot malloc flag memory for rejection graph");
715   return -1;
716  }
717  memset(flag,0,d3_l->max_z);
718  memset(graph,0,d3_l->max_z*sizeof(u32));
719  /* get fixpoints */
720  k=1;
721  while(k)
722  {
723   for(i=0;i<32;i++)
724   {
725    k=read(fd,&buf[i],1);
726    if((buf[i]=='\n')||(k==0)) break;
727   }
728   if(k)
729   {
730    p=strtok(buf," ");
731    a=atof(p)/10; /* nm */
732    p=strtok(NULL," ");
733    b=atof(p);
734    if(a>d3_l->max_z*CELL_LENGTH) k=0;
735    else 
736    {
737     graph[(int)(a/CELL_LENGTH)]=(int)(URAND_MAX*b);
738     flag[(int)(a/CELL_LENGTH)]=1;
739    }
740   }
741  }
742  /* do (linear) interpolation here! */
743  i=0;
744  a=0;
745  while(i<d3_l->max_z)
746  {
747   /* graph[0] is 0! */
748   j=i;
749   i++;
750   while(flag[i]==0&&i<d3_l->max_z) i++;
751   for(k=j+1;k<i;k++) graph[k]=(int)((k-j)*((int)graph[i]-(int)graph[j])/(i-j))+graph[j];
752   if(graph[i]>max) max=graph[i];
753  }
754
755  free(flag);
756
757  // printf("debug: (interpolated c profile)\n");
758  // for(i=0;i<d3_l->max_z;i++) printf("%d %d\n",i,graph[i]);
759
760  return max;
761 }
762
763 int main(int argc,char **argv)
764 {
765  u32 x,y,z,x_c,y_c,z_c;
766  int i,j,quit,escape,switchmode,nowait,bmp,ac_distr;
767  int refresh,resave;
768  int c_step;
769  char s_file[MAX_CHARS];
770  char s_file_tmp[MAX_CHARS];
771  char l_file[MAX_CHARS];
772  char c_file[MAX_CHARS];
773  char p_file[MAX_CHARS];
774  char convert;
775  char r_file[MAX_CHARS];
776 #ifdef USE_DFB_API
777  char xyz_txt[MAX_TXT];
778  char status_txt[MAX_TXT];
779  char conc_txt[MAX_TXT];
780  char steps_txt[MAX_TXT];
781  char cc_txt[MAX_TXT];
782  char a_txt[MAX_TXT];
783  char s_txt[MAX_TXT];
784  char ap_txt[MAX_TXT];
785  char el_txt[MAX_TXT];
786  char cd_txt[MAX_TXT];
787  char r_txt[MAX_TXT];
788  char cp_txt[MAX_TXT];
789  char zdiff_txt[MAX_TXT];
790  char diff_txt[MAX_TXT];
791  char dr_ac_txt[MAX_TXT];
792  char dr_cc_txt[MAX_TXT];
793  char dose_txt[MAX_TXT];
794  char mode_txt[MAX_TXT];
795  char *arg_v[MAX_ARGV];
796 #endif
797  d3_lattice d3_l;
798  info my_info;
799  unsigned char mode;
800  double c_ratio;
801 #ifdef USE_DFB_API
802  int max_extra;
803 #endif
804  u32 *c_profile;
805  u32 *n_e_loss;
806  u32 ne_max,ip_max;
807
808  d3_l.max_x=X;
809  d3_l.max_y=Y;
810  d3_l.max_z=Z;
811  my_info.steps=STEPS;
812  my_info.range=RANGE;
813  refresh=REFRESH;
814  resave=RESAVE;
815  my_info.z_diff=0;
816  my_info.c_diff=1;
817  my_info.a_el=A_EL;
818  my_info.b_el=B_EL;
819  my_info.a_cd=A_CD;
820  my_info.b_cd=B_CD;
821  my_info.a_ap=A_AP;
822  my_info.b_ap=B_AP;
823  my_info.a_cp=A_CP;
824  my_info.cc=CC;
825  my_info.dr_ac=DR_AC;
826  my_info.dr_cc=DR_CC;
827  my_info.diff_rate=DIFF_RATE;
828  my_info.cpi=CPI;
829  nowait=0;
830  quit=0;
831  escape=0;
832  switchmode=0;
833  c_step=0;
834  strcpy(s_file,"");
835  strcpy(l_file,"");
836  strcpy(c_file,"");
837  strcpy(p_file,IMP_PROFILE);
838  convert=0;
839  strcpy(r_file,"");
840  mode=0;
841  ne_max=0;
842  ip_max=0;
843
844  for(i=1;i<argc;i++)
845  {
846   if(argv[i][0]=='-')
847   {
848    switch(argv[i][1])
849    {
850     case 'h':
851      usage();
852      return -1;
853     case 'n':
854      nowait=1;
855      break;
856     case 'a':
857      my_info.a_el=atof(argv[++i]);
858      break;
859     case 'b':
860      my_info.b_el=atof(argv[++i]);
861      break;
862     case 'x':
863      d3_l.max_x=atoi(argv[++i]);
864      break;
865     case 'y':
866      d3_l.max_y=atoi(argv[++i]);
867      break;
868     case 'z':
869      d3_l.max_z=atoi(argv[++i]);
870      break;
871     case 'Z':
872      my_info.z_diff=1;
873      break;
874     case 'i':
875      my_info.c_diff=0;
876      my_info.dr_cc=0;
877      break;
878     case 's':
879      my_info.steps=atoi(argv[++i]);
880      break;
881     case 'd':
882      refresh=atoi(argv[++i]);
883      break;
884     case 'r':
885      my_info.range=atoi(argv[++i]);
886      break;
887     case 'f':
888      my_info.a_ap=atof(argv[++i]);
889      break;
890     case 'p':
891      my_info.b_ap=atof(argv[++i]);
892      break;
893     case 'F':
894      my_info.a_cp=atof(argv[++i]);
895      break;
896     case 'A':
897      my_info.a_cd=atof(argv[++i]);
898      break;
899     case 'B':
900      my_info.b_cd=atof(argv[++i]);
901      break;
902     case 'W':
903      resave=atoi(argv[++i]);
904      break;
905     case 'C':
906      strcpy(l_file,argv[++i]);
907      if(i<argc-1) if(argv[i+1][0]!='-') strcpy(c_file,argv[++i]);
908      convert=1;
909      break;
910     case 'D':
911      my_info.dr_ac=atof(argv[++i]);
912      break;
913     case 'c':
914      my_info.dr_cc=atof(argv[++i]);
915      break;
916     case 'e':
917      my_info.diff_rate=atoi(argv[++i]);
918      break;
919     case 'L':
920      strcpy(l_file,argv[++i]);
921      break;
922     case 'S':
923      strcpy(s_file,argv[++i]);
924      break;
925     case 'R':
926      strcpy(r_file,argv[++i]);
927      break;
928     case 'P':
929      strcpy(p_file,argv[++i]);
930      break;
931     case 'g':
932      strcpy(l_file,argv[++i]);
933      if(i<argc-1) if(argv[i+1][0]!='-') c_step=atoi(argv[++i]);
934      break;
935     case 'H':
936      my_info.cpi=atoi(argv[++i]);
937      break;
938     default:
939      usage();
940      return -1;
941    }
942   } else usage();
943  }
944
945  x=d3_l.max_x/2-1;
946  y=d3_l.max_y/2-1;
947  z=d3_l.max_z/2-1;
948
949 #ifdef NODFB
950  if(!strcmp(s_file,""))
951  {
952   puts("NODFB defined, run with -S option");
953   return -1;
954  }
955 #endif
956
957  if(!strcmp(r_file,"")) rand_init(NULL);
958  else rand_init(r_file);
959
960  if(!strcmp(l_file,""))
961  {
962   i=d3_l.max_x*d3_l.max_y*d3_l.max_z;
963 #ifdef USE_DFB_API
964   d3_lattice_init(&argc,argv,&d3_l);
965 #endif
966   if((d3_l.status=(unsigned char *)malloc(i*sizeof(unsigned char)))==NULL)
967   {
968    puts("failed allocating status buffer");
969    return -1;
970   }
971   memset(d3_l.status,0,i*sizeof(unsigned char));
972   if((d3_l.extra=(int *)malloc(i*sizeof(int)))==NULL)
973   {
974    puts("failed allocating concentration buffer");
975    return -1;
976   }
977   memset(d3_l.extra,0,i*sizeof(int));
978  } else
979  {
980   load_from_file(l_file,&d3_l,&my_info);
981   if(convert) 
982   {   
983    if(!strcmp(c_file,"")) sprintf(c_file,"%s_gnuplot",l_file);
984    printf("converting file %s to %s\n",l_file,c_file);
985    convert_file(c_file,&d3_l);
986    puts("done");
987    return 1;
988   } 
989 #ifdef USE_DFB_API
990   else d3_lattice_init(&argc,argv,&d3_l);
991 #endif
992  }
993
994 #ifdef USE_DFB_API
995  d3_event_init(&d3_l);
996 #endif
997
998 #ifdef USE_DFB_API
999  strcpy(a_txt,"args:");
1000  sprintf(s_txt,"steps: %d",my_info.steps);
1001  sprintf(dose_txt,"dose: %.2fe+17 C/cm²",my_info.steps*1.0/(d3_l.max_x*d3_l.max_y*CELL_LENGTH*CELL_LENGTH*1000));
1002  sprintf(r_txt,"pressure range: %d",my_info.range);
1003  sprintf(ap_txt,"a_ap: %.4f  b_ap: %.3f",my_info.a_ap,my_info.b_ap);
1004  sprintf(el_txt,"a_el: %.3f  b_el: %.3f",my_info.a_el,my_info.b_el);
1005  sprintf(cd_txt,"a_cd: %.3f  b_cd: %.3f",my_info.a_cd,my_info.b_cd);
1006  sprintf(cp_txt,"a_cp: %.5f",my_info.a_cp);
1007  sprintf(dr_ac_txt,"a/c diffusion rate: %.4f",my_info.dr_ac);
1008  if(my_info.c_diff!=0) sprintf(dr_cc_txt,"c/c diffusion rate: %.4f",my_info.dr_cc);
1009  else sprintf(dr_cc_txt,"c/c diffusion rate: none");
1010  sprintf(zdiff_txt,"diffusion in z direction: %c",my_info.z_diff?'y':'n');
1011  sprintf(diff_txt,"diffusion every %d steps",my_info.diff_rate);
1012  strcpy(mode_txt,"view: a/c mode");
1013  arg_v[1]=xyz_txt;
1014  arg_v[2]=NULL;
1015  arg_v[3]=status_txt;
1016  arg_v[4]=conc_txt;
1017  arg_v[5]=NULL;
1018  arg_v[6]=mode_txt;
1019  arg_v[7]=NULL;
1020  arg_v[8]=steps_txt;
1021  arg_v[9]=cc_txt;
1022  arg_v[10]=NULL;
1023  arg_v[11]=diff_txt;
1024  arg_v[12]=zdiff_txt;
1025  arg_v[13]=NULL;
1026  arg_v[14]=a_txt;
1027  arg_v[15]=s_txt;
1028  arg_v[16]=dose_txt;
1029  arg_v[17]=NULL;
1030  arg_v[18]=r_txt;
1031  arg_v[19]=ap_txt;
1032  arg_v[20]=el_txt;
1033  arg_v[21]=cd_txt;
1034  arg_v[22]=cp_txt;
1035  arg_v[23]=NULL;
1036  arg_v[24]=dr_ac_txt;
1037  arg_v[25]=dr_cc_txt;
1038 #endif
1039
1040  if((!strcmp(l_file,""))||(c_step))
1041  {
1042   /* calculate ratio of c_simwindow / c_total */
1043   if(get_c_ratio(&c_ratio,p_file,&my_info,&d3_l)!=1)
1044   {
1045    puts("failed calculating ratio");
1046    return -1;
1047   }
1048   /* compute graphs for random number rejection method */
1049   if((c_profile=(u32 *)malloc(d3_l.max_z*sizeof(unsigned int)))==NULL)
1050   {
1051    puts("failed allocating memory for carbon profile graph");
1052    return -1;
1053   }
1054   if((n_e_loss=(u32 *)malloc(d3_l.max_z*sizeof(unsigned int)))==NULL)
1055   {
1056    puts("failed allocating memory for nuclear energy loss graph");
1057    return -1;
1058   }
1059   ip_max=get_reject_graph(&my_info,&d3_l,p_file,c_profile);
1060
1061 #ifdef DEBUG_RAND
1062  while(1)
1063  {
1064   printf("%d\n",get_rand_reject(d3_l.max_z,ip_max,c_profile));
1065  }
1066 #endif
1067
1068   i=(c_step?c_step:0);
1069   while((i<my_info.steps) && (quit==0) && (escape==0))
1070   {
1071    for(j=0;j<my_info.cpi;j++)
1072    {
1073     x_c=get_rand(d3_l.max_x);
1074     y_c=get_rand(d3_l.max_y);
1075     z_c=get_rand_lgp(d3_l.max_z,my_info.a_el,my_info.b_el);
1076     printf("%d\n",z_c);
1077     process_cell(&d3_l,x_c,y_c,z_c,&my_info);
1078    }
1079    distrib_c(&d3_l,&my_info,i,c_ratio,ip_max,c_profile);
1080 #ifdef USE_DFB_API
1081    if(i%refresh==0)
1082    {
1083     sprintf(xyz_txt,"x: %d  y: %d  z: %d",x+1,y+1,z+1);
1084     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');
1085     sprintf(conc_txt,"conc: %d",*(d3_l.extra+x+y*d3_l.max_x+z*d3_l.max_x*d3_l.max_y));
1086     sprintf(steps_txt,"step: %d",i);
1087     sprintf(cc_txt,"total c: %d",my_info.cc);
1088     d3_lattice_draw(&d3_l,x,y,z,25,arg_v,mode,0);
1089    }
1090 #endif
1091    if(i%resave==0 && strcmp(s_file,"") && resave!=0 && i!=0)
1092    {
1093     sprintf(s_file_tmp,"%s_%d_of_%d",s_file,i,my_info.steps);
1094     save_to_file(s_file_tmp,&d3_l,&my_info);
1095 #ifdef NODFB
1096     printf("saved %s\n",s_file_tmp);
1097 #endif
1098    }
1099    i++;
1100   }
1101  }
1102
1103  if(strcmp(s_file,""))
1104  {
1105    printf("saved %s\n",s_file);
1106    save_to_file(s_file,&d3_l,&my_info);
1107  }
1108
1109 #ifdef USE_DFB_API
1110  /* allocating buffer for pressure values */
1111  if((d3_l.v_ptr=malloc(d3_l.max_x*d3_l.max_y*d3_l.max_z*sizeof(unsigned char)))==NULL)
1112  {
1113   puts("cannot allocate buffer for pressure values");
1114   return -1;
1115  }
1116  /* calc values */
1117  calc_pressure(&d3_l,my_info.range);
1118  max_extra=calc_max_extra(&d3_l);
1119
1120  while((quit==0) && (escape==0) && (nowait==0))
1121  {
1122   /* bahh! */
1123   if(switchmode==0) mode=0;
1124   if(switchmode==1) mode=1;
1125   if(switchmode==2) mode=2;
1126   /* end of bahh! */
1127   sprintf(xyz_txt,"x: %d  y: %d  z: %d",x+1,y+1,z+1);
1128   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');
1129   sprintf(conc_txt,"conc: %d",*(d3_l.extra+x+y*d3_l.max_x+z*d3_l.max_x*d3_l.max_y));
1130   sprintf(steps_txt,"step: end");
1131   sprintf(cc_txt,"total c: %d",my_info.cc);
1132   if(switchmode==0) strcpy(mode_txt,"view: a/c mode");
1133   if(switchmode==1) strcpy(mode_txt,"view: c conc mode");
1134   if(switchmode==2) strcpy(mode_txt,"view: a pressure mode");
1135   d3_lattice_draw(&d3_l,x,y,z,25,arg_v,mode,max_extra);
1136   bmp=0;
1137   ac_distr=0;
1138   scan_event(&d3_l,&x,&y,&z,&quit,&escape,&switchmode,&bmp,&ac_distr);
1139   if(bmp) write_bmp(&d3_l,bmp,x,y,z);
1140   if(ac_distr) write_ac_distr(&d3_l,ac_distr);
1141  }
1142
1143  d3_lattice_release(&d3_l);
1144 #endif
1145
1146  return 1;
1147 }