wenn dr_cc 0 -> "none" in gui anzeigen
[physik/nlsop.git] / nlsop.c
1 /*
2  * nlsop.c 
3  *
4  * author: frank zirkelbach (frank@xeen.net)
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 /* test globals - get removed or included in my_info struct later */
52 int amorph_count;
53 int cryst_count;
54 unsigned char c_diff;
55
56 int usage(void)
57 {
58  puts("usage:");
59  puts("-h \t\t help");
60  puts("-n \t\t no user interaction");
61  puts("-Z \t\t cryst -> amorph c diffusion in z direction");
62  puts("-i \t\t no cryst to cryst diffusion");
63  printf("-a <value> \t slope of nuclear energy loss (default %f)\n",A_EL);
64  printf("-b <value> \t nuclear energy loss offset (default %f)\n",B_EL);
65  printf("-x <value> \t # x cells (default %d)\n",X);
66  printf("-y <value> \t # y cells (default %d)\n",Y);
67  printf("-z <value> \t # z cells (default %d)\n",Z);
68  printf("-s <value> \t steps (default %d)\n",STEPS);
69  printf("-d <value> \t refresh display (default %d)\n",REFRESH);
70  printf("-r <value> \t amorphous influence range (default %d)\n",RANGE);
71  printf("-f <value> \t pressure = <value> * 1/distance^2 (default %f)\n",A_AP);
72  printf("-p <value> \t pressure offset (default %f)\n",B_AP);
73  printf("-F <value> \t proportionality constant between c conc and ability to get amorphous (default %f)\n",A_CP);
74  printf("-A <value> \t slope of linear c distribution (default %f)\n",A_CD);
75  printf("-B <value> \t linear c distribution offset (default %f)\n",B_CD);
76  printf("-D <value> \t diffusion rate from cryst to amorph cells (default %f)\n",DR_AC);
77  printf("-c <value> \t diffusion rate in cryst cells (default %f)\n",DR_CC);
78  printf("-e <value> \t do diffusion every <value> steps (default %d)\n",DIFF_RATE);
79  puts("-g <file> <step> continue simulation from file and step (step > 0)!");
80  printf("-W <value> \t write every <value> steps to save file (default %d)\n",RESAVE);
81  puts("-C <file> \t convert file to gnuplot format");
82  puts("-L <file> \t load from file");
83  puts("-S <file> \t save to file");
84  puts("-R <file> \t read from random file");
85  puts("-P <file> \t specify implantation profile file");
86  
87  return 1;
88 }
89
90 int process_cell(d3_lattice *d3_l,u32 x,u32 y,u32 z,info *my_info)
91 {
92  unsigned char *thiz;
93  int *conc;
94  int i,j;
95  int off;
96  double p;
97
98  thiz=d3_l->status+x+y*d3_l->max_x+z*d3_l->max_x*d3_l->max_y;
99  conc=d3_l->extra+x+y*d3_l->max_x+z*d3_l->max_x*d3_l->max_y;
100  p=my_info->b_ap*URAND_MAX;
101  for(i=-(my_info->range);i<=my_info->range;i++)
102  {
103   for(j=-(my_info->range);j<=my_info->range;j++)
104   {
105    if(!(i==0 && j==0))
106    {
107     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;
108     if(*(d3_l->status+off)&AMORPH) p+=my_info->a_ap*(*(d3_l->extra+off))*URAND_MAX/(i*i+j*j);
109    } 
110   }
111  }
112  p+=*conc*my_info->a_cp*URAND_MAX;
113  if(!(*thiz&AMORPH))
114  {
115   if(get_rand(URAND_MAX)<=p)
116   {
117    MAKE_AMORPH(thiz);
118    amorph_count++;
119   }
120  } else
121  {
122   /* assume 1-p probability */
123   if(get_rand(URAND_MAX)>p)
124   {
125    MAKE_CRYST(thiz);
126    cryst_count++;
127   }
128  }
129  
130  return 1;
131 }
132
133 int distrib_c(d3_lattice *d3_l,info *my_info,int step,double c_ratio)
134 {
135  u32 x,y,z;
136  int i,j,k,c;
137  int offset,off;
138  int carry;
139
140  /* put one c ion somewhere in the lattice */
141  if(my_info->cc<c_ratio*step)
142  {
143   x=get_rand(d3_l->max_x);
144   y=get_rand(d3_l->max_y);
145   z=get_rand_lgp(d3_l->max_z,my_info->a_cd,my_info->b_cd);
146   *(d3_l->extra+x+y*d3_l->max_x+z*d3_l->max_x*d3_l->max_y)+=1;
147   (my_info->cc)++;
148  }
149
150  if(step%my_info->diff_rate==0)
151  {
152
153  for(i=0;i<d3_l->max_x;i++)
154  {
155   for(j=0;j<d3_l->max_y;j++)
156   {
157    for(k=0;k<d3_l->max_z;k++)
158    {
159     offset=i+j*d3_l->max_x+k*d3_l->max_x*d3_l->max_y;
160     /* case amorph: amorph <- cryst diffusion */
161     if(*(d3_l->status+offset)&AMORPH)
162     {
163      for(c=-1;c<=1;c++)
164      {
165       if(c!=0)
166       {
167        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;
168        carry=0;
169        if(!(*(d3_l->status+off)&AMORPH)) carry=(int)(my_info->dr_ac*(*(d3_l->extra+off)));
170        if(carry!=0)
171        {
172         *(d3_l->extra+offset)+=carry;
173         *(d3_l->extra+off)-=carry;
174        }
175       }
176      }
177      for(c=-1;c<=1;c++)
178      {
179       if(c!=0)
180       {
181        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;
182        carry=0;
183        if(!(*(d3_l->status+off)&AMORPH)) carry=(int)(my_info->dr_ac*(*(d3_l->extra+off)));                             
184        if(carry!=0)
185        {
186         *(d3_l->extra+offset)+=carry; 
187         *(d3_l->extra+off)-=carry; 
188        }
189       }
190      }
191      if(my_info->z_diff)
192      {
193       for(c=-1;c<=1;c++)
194       {
195        if(c!=0)
196        {
197         off=i+j*d3_l->max_x+((k+c+d3_l->max_z)%d3_l->max_z)*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      }  
208     } else
209     /* case not amorph: cryst <-> cryst diffusion */
210
211     /* test ! */
212     if(c_diff) {
213     /* */
214     {
215      for(c=-1;c<=1;c++) 
216      {
217       if(c!=0)
218       {
219        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;
220        carry=0;
221        if(!(*(d3_l->status+off)&AMORPH))
222        {
223         carry=(int)(my_info->dr_cc*(*(d3_l->extra+off)-*(d3_l->extra+offset))/2);
224         if(carry!=0)
225         {
226          *(d3_l->extra+offset)+=carry;
227          *(d3_l->extra+off)-=carry;
228         }
229        }
230       }
231      }
232      for(c=-1;c<=1;c++)
233      {
234       if(c!=0)
235       {
236        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;
237        carry=0;
238        if(!(*(d3_l->status+off)&AMORPH))
239        {
240         carry=(int)(my_info->dr_cc*(*(d3_l->extra+off)-*(d3_l->extra+offset))/2);
241         if(carry!=0)
242         {
243          *(d3_l->extra+offset)+=carry;
244          *(d3_l->extra+off)-=carry;
245         }
246        }
247       }
248      }
249     }
250     /* end test */
251     }
252     /* */
253    } /* for z */
254   } /* for y */
255  } /* for x */
256
257  } /* if step modulo diff_rate == 0 */
258
259  return 1;
260 }
261
262 int calc_pressure(d3_lattice *d3_l,int range)
263 {
264  int i,j,off;
265  double count,max=0;
266  int x,y,z;
267
268  for(x=0;x<d3_l->max_x;x++)
269  {
270   for(y=0;y<d3_l->max_y;y++)
271   {
272    for(z=0;z<d3_l->max_z;z++)
273    {
274     count=0;
275     for(i=-range;i<=range;i++)
276     {
277      for(j=-range;j<=range;j++)
278      {
279       if(i!=0 && j!=0)
280       {
281        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;
282        if(*(d3_l->status+off)&AMORPH) count+=((double)*(d3_l->extra+off))/(i*i+j*j);
283       }
284      }
285     }
286     if(count>max) max=count;
287    }
288   }
289  }
290
291  for(x=0;x<d3_l->max_x;x++)
292  {
293   for(y=0;y<d3_l->max_y;y++)
294   {
295    for(z=0;z<d3_l->max_z;z++)
296    {
297     count=0;
298     for(i=-range;i<=range;i++)
299     {
300      for(j=-range;j<=range;j++)
301      {
302       if(i!=0 && j!=0)
303       {
304        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;
305        if(*(d3_l->status+off)&AMORPH) count+=((double)*(d3_l->extra+off))/(i*i+j*j);
306       }
307      }
308     }
309     *(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);
310    }
311   }
312  }
313
314  return 1;
315 }
316
317 int calc_max_extra(d3_lattice *d3_l)
318 {
319  int x,y,z;
320  int off,max=0;
321
322  for(x=0;x<d3_l->max_x;x++)
323  {
324   for(y=0;y<d3_l->max_y;y++)
325   {
326    for(z=0;z<d3_l->max_z;z++)
327    {
328     off=x+y*d3_l->max_x+z*d3_l->max_x*d3_l->max_y;
329     if(*(d3_l->extra+off)>max) max=*(d3_l->extra+off);
330    }
331   }
332  }
333
334  return max;
335 }
336
337 int write_bmp(d3_lattice *d3_l,int window,u32 x,u32 y,u32 z)
338 {
339  int fd,i,j,size=0,foo=0;
340  int width=0,height=0;
341  char bmpfile[MAX_CHARS];
342  char buf[128];
343
344  if(window==1)
345  {
346   sprintf(bmpfile,"x-z_%d.bmp",y);
347   foo=3*d3_l->max_x;
348   size=(foo+(4-foo%4))*d3_l->max_z;
349   width=d3_l->max_x;
350   height=d3_l->max_z;
351  }
352  if(window==2)
353  {
354   sprintf(bmpfile,"y-z_%d.bmp",x);
355   foo=3*d3_l->max_y;
356   size=(foo+(4-foo%4))*d3_l->max_z;
357   width=d3_l->max_y;
358   height=d3_l->max_z;
359  }
360  if(window==3)
361  {
362   sprintf(bmpfile,"x-y_%d.bmp",z);
363   foo=3*d3_l->max_x;
364   size=(foo+(4-foo%4))*d3_l->max_y;
365   width=d3_l->max_x;
366   height=d3_l->max_y;
367  }
368
369  if((fd=open(bmpfile,O_WRONLY|O_CREAT))<0)
370  {
371   puts("cannot open bmp file");
372   return -1;
373  }
374
375  /* bmpheader */
376  buf[0]='B'; /* std header start */
377  buf[1]='M';
378  buf[2]=(size+0x36)&0xff; /* file size */
379  buf[3]=(size+0x36)>>8;
380  memset(buf+4,0,6);
381  buf[10]=0x36; /* offset to data */
382  memset(buf+11,0,3);
383  buf[14]=0x28; /* length of bmp info header */
384  memset(buf+15,0,3);
385  buf[18]=width&0xff; /* width and height */
386  buf[19]=width>>8;
387  memset(buf+20,0,2);
388  buf[22]=height&0xff;
389  buf[23]=height>>8;
390  memset(buf+24,0,2);
391  buf[26]=1; /* # planes -> 1 */
392  buf[27]=0;
393  buf[28]=24; /* bits per pixel -> 2^24 (true color) */
394  buf[29]=0;
395  memset(buf+30,0,4); /* compression -> none */
396  buf[34]=size&0xff; /* data size */
397  buf[35]=size>>8;
398  memset(buf+36,0,2);
399  buf[38]=0x12; /* res: pixel/meter */
400  buf[39]=0x0b;
401  memset(buf+40,0,2);
402  buf[42]=0x12;
403  buf[43]=0x0b;
404  memset(buf+44,0,2); 
405  memset(buf+46,0,8); /* no colors, no important colors */
406
407  if(write(fd,buf,54)<54)
408  {
409   puts("failed writing bmp header");
410   return -1;
411  }
412  if(window==1)
413  {
414   for(j=0;j<d3_l->max_z;j++)
415   {
416    for(i=0;i<d3_l->max_x;i++)
417    {
418     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);
419     else memset(buf,0,3);
420     if(write(fd,buf,3)<3)
421     {
422      puts("failed writing rgb values to bmp file");
423      return-1;
424     }
425    }
426    if(foo%4)
427    {
428     memset(buf,0,4-foo%4);
429     if(write(fd,buf,4-foo%4)<4-foo%4)
430     {
431      puts("failed writing 4 byte ending");
432      return -1;
433     }
434    } 
435   }
436  }
437  if(window==2)
438  {
439   for(j=0;j<d3_l->max_z;j++)
440   {
441    for(i=0;i<d3_l->max_y;i++)
442    {
443     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);
444     else memset(buf,0,3);
445     if(write(fd,buf,3)<3)
446     {
447      puts("failed writing rgb values to bmp file");
448      return-1;
449     }
450    }
451    if(foo%4)
452    {
453     memset(buf,0,4-foo%4);
454     if(write(fd,buf,4-foo%4)<4-foo%4)
455     {
456      puts("failed writing 4 byte ending");
457      return -1;
458     }
459    }
460   }
461  }
462  if(window==3)
463  {
464   for(j=0;j<d3_l->max_y;j++)
465   {
466    for(i=0;i<d3_l->max_x;i++)
467    {
468     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);
469     else memset(buf,0,3);
470     if(write(fd,buf,3)<3)
471     {
472      puts("failed writing rgb values to bmp file");
473      return -1;
474     }
475    }
476    if(foo%4)
477    {
478     memset(buf,0,4-foo%4);
479     if(write(fd,buf,4-foo%4)<4-foo%4)
480     {
481      puts("failed writing 4 byte ending");
482      return -1;
483     }
484    }
485   }
486  }
487  close(fd);
488
489  return 1;
490 }
491
492 int save_to_file(char *sf,d3_lattice *d3_l,info *my_inf)
493 {
494  int sf_fd,c;
495
496  if((sf_fd=open(sf,O_WRONLY|O_CREAT))<0)
497  {
498   puts("cannot open save file");
499   return -1;
500  }
501  if(write(sf_fd,d3_l,sizeof(d3_lattice))<sizeof(d3_lattice))
502  {
503   puts("failed saving d3 lattice struct");
504   return -1;
505  }
506  if(write(sf_fd,my_inf,sizeof(info))<sizeof(info))
507  {
508   puts("failed saving info struct");
509   return-1;
510  }
511  c=d3_l->max_x*d3_l->max_y*d3_l->max_z;
512  if(write(sf_fd,d3_l->status,c*sizeof(unsigned char))<c*sizeof(unsigned char))
513  {
514   puts("failed saving status of d3 lattice sites");
515   return -1;
516  }
517  if(write(sf_fd,d3_l->extra,c*sizeof(int))<c*sizeof(int))
518  {
519   puts("failed saving sites concentration");
520   return -1;
521  }
522  close(sf_fd);
523
524  return 1;
525 }
526
527 int load_from_file(char *lf,d3_lattice *d3_l,info *my_inf)
528 {
529  int lf_fd,c;
530
531  if((lf_fd=open(lf,O_RDONLY))<0)
532  {
533   puts("cannot open load file");
534   return -1;
535  }
536  if(read(lf_fd,d3_l,sizeof(d3_lattice))<sizeof(d3_lattice))
537  {
538   puts("failed reading d3 lattice struct");
539   return -1;
540  }
541  if(read(lf_fd,my_inf,sizeof(info))<sizeof(info))
542  {
543   puts("failed reading info struct");
544   return-1;
545  }
546  c=d3_l->max_x*d3_l->max_y*d3_l->max_z;
547  if((d3_l->status=(unsigned char*)malloc(c*sizeof(unsigned char)))==NULL)
548  {
549   puts("cannot allocate status buffer");
550   return -1;
551  }
552  if((d3_l->extra=(int *)malloc(c*sizeof(int)))==NULL)
553  {
554   puts("cannot allocate concentration buffer");
555   return -1;
556  }
557  if(read(lf_fd,d3_l->status,c*sizeof(unsigned char))<c*sizeof(unsigned char))
558  {
559   puts("failed reading status of d3 lattice sites");
560   return -1;
561  }
562  if(read(lf_fd,d3_l->extra,c*sizeof(int))<c*sizeof(int))
563  {
564   puts("failed reading sites concentration");
565   return -1;
566  }
567  close(lf_fd);
568
569  return 1;
570 }
571
572 int convert_file(char *cf,d3_lattice *d3_l)
573 {
574  int x,y,z;
575  int c_fd;
576
577  if((c_fd=open(cf,O_WRONLY|O_CREAT))<0)
578  {
579   puts("cannot open convert file");
580   return -1;
581  }
582  dprintf(c_fd,"# created by nlsop (gnuplot format)\n");
583  for(x=0;x<d3_l->max_x;x++)
584  {
585   for(y=0;y<d3_l->max_y;y++)
586   {
587    for(z=0;z<d3_l->max_z;z++)
588    {
589     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);
590    }
591   }
592  }
593  close(c_fd);
594
595  return 1;
596 }
597
598 int get_c_ratio(double *c_ratio,char *pfile,info *my_info,d3_lattice *d3_l)
599 {
600  double all,a,b,d;
601  int i,k;
602  int p_fd;
603  unsigned char buf[32];
604  char *p;
605  unsigned char c;
606
607  if((p_fd=open(pfile,O_RDONLY))<0)
608  {
609   puts("cannot open profile file");
610   return -1;
611  }
612  k=1;
613  d=0;
614  all=0;
615  while(k)
616  {
617   for(i=0;i<32;i++)
618   {
619    k=read(p_fd,&c,1);
620    buf[i]=c;
621    if(c=='\n') break;
622   }
623   if(k)
624   {
625    p=strtok(buf," ");
626    a=atof(p)/10; /* nm */
627    p=strtok(NULL," ");
628    b=atof(p);
629    if(a>my_info->b_cd*CELL_LENGTH && a<(my_info->b_cd+d3_l->max_z)*CELL_LENGTH) d+=b;
630    all+=b;
631   }
632  }
633  *c_ratio=d/all;
634  close(p_fd);
635
636  return 1;
637 }
638
639 int main(int argc,char **argv)
640 {
641  u32 x,y,z,x_c,y_c,z_c;
642  int i,quit,escape,switchmode,nowait,bmp;
643  int refresh,resave;
644  int c_step;
645  char s_file[MAX_CHARS];
646  char s_file_tmp[MAX_CHARS];
647  char l_file[MAX_CHARS];
648  char c_file[MAX_CHARS];
649  char p_file[MAX_CHARS];
650  char convert;
651  char r_file[MAX_CHARS];
652 #ifdef USE_DFB_API
653  char xyz_txt[MAX_TXT];
654  char status_txt[MAX_TXT];
655  char conc_txt[MAX_TXT];
656  char steps_txt[MAX_TXT];
657  char cc_txt[MAX_TXT];
658  char a_txt[MAX_TXT];
659  char s_txt[MAX_TXT];
660  char ap_txt[MAX_TXT];
661  char el_txt[MAX_TXT];
662  char cd_txt[MAX_TXT];
663  char r_txt[MAX_TXT];
664  char cp_txt[MAX_TXT];
665  char zdiff_txt[MAX_TXT];
666  char diff_txt[MAX_TXT];
667  char dr_ac_txt[MAX_TXT];
668  char dr_cc_txt[MAX_TXT];
669  char dose_txt[MAX_TXT];
670  char mode_txt[MAX_TXT];
671  char *arg_v[MAX_ARGV];
672 #endif
673  d3_lattice d3_l;
674  info my_info;
675  unsigned char mode;
676  double c_ratio;
677 #ifdef USE_DFB_API
678  int max_extra;
679 #endif
680
681  d3_l.max_x=X;
682  d3_l.max_y=Y;
683  d3_l.max_z=Z;
684  my_info.steps=STEPS;
685  my_info.range=RANGE;
686  refresh=REFRESH;
687  resave=RESAVE;
688  my_info.z_diff=0;
689  c_diff=1;
690  my_info.a_el=A_EL;
691  my_info.b_el=B_EL;
692  my_info.a_cd=A_CD;
693  my_info.b_cd=B_CD;
694  my_info.a_ap=A_AP;
695  my_info.b_ap=B_AP;
696  my_info.a_cp=A_CP;
697  my_info.cc=CC;
698  my_info.dr_ac=DR_AC;
699  my_info.dr_cc=DR_CC;
700  my_info.diff_rate=DIFF_RATE;
701  nowait=0;
702  quit=0;
703  escape=0;
704  switchmode=0;
705  c_step=0;
706  strcpy(s_file,"");
707  strcpy(l_file,"");
708  strcpy(c_file,"");
709  strcpy(p_file,IMP_PROFILE);
710  convert=0;
711  strcpy(r_file,"");
712  mode=0;
713
714  amorph_count=0;
715  cryst_count=0;
716
717  for(i=1;i<argc;i++)
718  {
719   if(argv[i][0]=='-')
720   {
721    switch(argv[i][1])
722    {
723     case 'h':
724      usage();
725      return -1;
726     case 'n':
727      nowait=1;
728      break;
729     case 'a':
730      my_info.a_el=atof(argv[++i]);
731      break;
732     case 'b':
733      my_info.b_el=atof(argv[++i]);
734      break;
735     case 'x':
736      d3_l.max_x=atoi(argv[++i]);
737      break;
738     case 'y':
739      d3_l.max_y=atoi(argv[++i]);
740      break;
741     case 'z':
742      d3_l.max_z=atoi(argv[++i]);
743      break;
744     case 'Z':
745      my_info.z_diff=1;
746      break;
747     case 'i':
748      c_diff=0;
749      my_info.dr_cc=0;
750      break;
751     case 's':
752      my_info.steps=atoi(argv[++i]);
753      break;
754     case 'd':
755      refresh=atoi(argv[++i]);
756      break;
757     case 'r':
758      my_info.range=atoi(argv[++i]);
759      break;
760     case 'f':
761      my_info.a_ap=atof(argv[++i]);
762      break;
763     case 'p':
764      my_info.b_ap=atof(argv[++i]);
765      break;
766     case 'F':
767      my_info.a_cp=atof(argv[++i]);
768      break;
769     case 'A':
770      my_info.a_cd=atof(argv[++i]);
771      break;
772     case 'B':
773      my_info.b_cd=atof(argv[++i]);
774      break;
775     case 'W':
776      resave=atoi(argv[++i]);
777      break;
778     case 'C':
779      strcpy(l_file,argv[++i]);
780      if(i<argc-1) if(argv[i+1][0]!='-') strcpy(c_file,argv[++i]);
781      convert=1;
782      break;
783     case 'D':
784      my_info.dr_ac=atof(argv[++i]);
785      break;
786     case 'c':
787      my_info.dr_cc=atof(argv[++i]);
788      break;
789     case 'e':
790      my_info.diff_rate=atoi(argv[++i]);
791      break;
792     case 'L':
793      strcpy(l_file,argv[++i]);
794      break;
795     case 'S':
796      strcpy(s_file,argv[++i]);
797      break;
798     case 'R':
799      strcpy(r_file,argv[++i]);
800      break;
801     case 'P':
802      strcpy(p_file,argv[++i]);
803      break;
804     case 'g':
805      strcpy(l_file,argv[++i]);
806      if(i<argc-1) if(argv[i+1][0]!='-') c_step=atoi(argv[++i]);
807      break;
808     default:
809      usage();
810      return -1;
811    }
812   } else usage();
813  }
814
815  x=d3_l.max_x/2-1;
816  y=d3_l.max_y/2-1;
817  z=d3_l.max_z/2-1;
818
819 #ifdef NODFB
820  if(!strcmp(s_file,""))
821  {
822   puts("NODFB defined, run with -S option");
823   return -1;
824  }
825 #endif
826
827  if(!strcmp(r_file,"")) rand_init(NULL);
828  else rand_init(r_file);
829
830  if(!strcmp(l_file,""))
831  {
832   i=d3_l.max_x*d3_l.max_y*d3_l.max_z;
833 #ifdef USE_DFB_API
834   d3_lattice_init(&argc,argv,&d3_l);
835 #endif
836   if((d3_l.status=(unsigned char *)malloc(i*sizeof(unsigned char)))==NULL)
837   {
838    puts("failed allocating status buffer");
839    return -1;
840   }
841   memset(d3_l.status,0,i*sizeof(unsigned char));
842   if((d3_l.extra=(int *)malloc(i*sizeof(int)))==NULL)
843   {
844    puts("failed allocating concentration buffer");
845    return -1;
846   }
847   memset(d3_l.extra,0,i*sizeof(int));
848  } else
849  {
850   load_from_file(l_file,&d3_l,&my_info);
851   if(convert) 
852   {   
853    if(!strcmp(c_file,"")) sprintf(c_file,"%s_gnuplot",l_file);
854    printf("converting file %s to %s\n",l_file,c_file);
855    convert_file(c_file,&d3_l);
856    puts("done");
857    return 1;
858   } 
859 #ifdef USE_DFB_API
860   else d3_lattice_init(&argc,argv,&d3_l);
861 #endif
862  }
863
864 #ifdef USE_DFB_API
865  d3_event_init(&d3_l);
866 #endif
867
868 #ifdef USE_DFB_API
869  strcpy(a_txt,"args:");
870  sprintf(s_txt,"steps: %d",my_info.steps);
871  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));
872  sprintf(r_txt,"pressure range: %d",my_info.range);
873  sprintf(ap_txt,"a_ap: %.3f  b_ap: %.3f",my_info.a_ap,my_info.b_ap);
874  sprintf(el_txt,"a_el: %.3f  b_el: %.3f",my_info.a_el,my_info.b_el);
875  sprintf(cd_txt,"a_cd: %.3f  b_cd: %.3f",my_info.a_cd,my_info.b_cd);
876  sprintf(cp_txt,"a_cp: %.4f",my_info.a_cp);
877  sprintf(dr_ac_txt,"a/c diffusion rate: %.4f",my_info.dr_ac);
878  if(my_info.dr_cc!=0) sprintf(dr_cc_txt,"c/c diffusion rate: %.4f",my_info.dr_cc);
879  else sprintf(dr_cc_txt,"c/c diffusion rate: none");
880  sprintf(zdiff_txt,"diffusion in z direction: %c",my_info.z_diff?'y':'n');
881  sprintf(diff_txt,"diffusion every %d steps",my_info.diff_rate);
882  strcpy(mode_txt,"view: a/c mode");
883  arg_v[1]=xyz_txt;
884  arg_v[2]=NULL;
885  arg_v[3]=status_txt;
886  arg_v[4]=conc_txt;
887  arg_v[5]=NULL;
888  arg_v[6]=mode_txt;
889  arg_v[7]=NULL;
890  arg_v[8]=steps_txt;
891  arg_v[9]=cc_txt;
892  arg_v[10]=NULL;
893  arg_v[11]=diff_txt;
894  arg_v[12]=zdiff_txt;
895  arg_v[13]=NULL;
896  arg_v[14]=a_txt;
897  arg_v[15]=s_txt;
898  arg_v[16]=dose_txt;
899  arg_v[17]=NULL;
900  arg_v[18]=r_txt;
901  arg_v[19]=ap_txt;
902  arg_v[20]=el_txt;
903  arg_v[21]=cd_txt;
904  arg_v[22]=cp_txt;
905  arg_v[23]=NULL;
906  arg_v[24]=dr_ac_txt;
907  arg_v[25]=dr_cc_txt;
908 #endif
909
910  if((!strcmp(l_file,""))||(c_step))
911  {
912   if(get_c_ratio(&c_ratio,p_file,&my_info,&d3_l)!=1)
913   {
914    puts("failed calculating ratio");
915    return -1;
916   }
917   i=(c_step?c_step:0);
918   while((i<my_info.steps) && (quit==0) && (escape==0))
919   {
920    x_c=get_rand(d3_l.max_x);
921    y_c=get_rand(d3_l.max_y);
922    z_c=get_rand_lgp(d3_l.max_z,my_info.a_el,my_info.b_el);
923    distrib_c(&d3_l,&my_info,i,c_ratio);
924    process_cell(&d3_l,x_c,y_c,z_c,&my_info);
925 #ifdef USE_DFB_API
926    if(i%refresh==0)
927    {
928     sprintf(xyz_txt,"x: %d  y: %d  z: %d",x+1,y+1,z+1);
929     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');
930     sprintf(conc_txt,"conc: %d",*(d3_l.extra+x+y*d3_l.max_x+z*d3_l.max_x*d3_l.max_y));
931     sprintf(steps_txt,"step: %d  a_count: %d",i,amorph_count);
932     sprintf(cc_txt,"total c: %d  c_count: %d",my_info.cc,cryst_count);
933     d3_lattice_draw(&d3_l,x,y,z,25,arg_v,mode,0);
934    }
935 #endif
936    if(i%resave==0 && strcmp(s_file,"") && resave!=0 && i!=0)
937    {
938     sprintf(s_file_tmp,"%s_%d_of_%d",s_file,i,my_info.steps);
939     save_to_file(s_file_tmp,&d3_l,&my_info);
940 #ifdef NODFB
941     printf("saved %s\n",s_file_tmp);
942 #endif
943    }
944    i++;
945   }
946  }
947
948  if(strcmp(s_file,""))
949  {
950    printf("saved %s\n",s_file);
951    save_to_file(s_file,&d3_l,&my_info);
952  }
953
954 #ifdef USE_DFB_API
955  /* allocating buffer for pressure values */
956  if((d3_l.v_ptr=malloc(d3_l.max_x*d3_l.max_y*d3_l.max_z*sizeof(unsigned char)))==NULL)
957  {
958   puts("cannot allocate buffer for pressure values");
959   return -1;
960  }
961  /* calc values */
962  calc_pressure(&d3_l,my_info.range);
963  max_extra=calc_max_extra(&d3_l);
964
965  while((quit==0) && (escape==0) && (nowait==0))
966  {
967   /* bahh! */
968   if(switchmode==0) mode=0;
969   if(switchmode==1) mode=1;
970   if(switchmode==2) mode=2;
971   /* end of bahh! */
972   sprintf(xyz_txt,"x: %d  y: %d  z: %d",x+1,y+1,z+1);
973   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');
974   sprintf(conc_txt,"conc: %d",*(d3_l.extra+x+y*d3_l.max_x+z*d3_l.max_x*d3_l.max_y));
975   sprintf(steps_txt,"step: end");
976   sprintf(cc_txt,"total c: %d",my_info.cc);
977   if(switchmode==0) strcpy(mode_txt,"view: a/c mode");
978   if(switchmode==1) strcpy(mode_txt,"view: c conc mode");
979   if(switchmode==2) strcpy(mode_txt,"view: a pressure mode");
980   d3_lattice_draw(&d3_l,x,y,z,25,arg_v,mode,max_extra);
981   bmp=0;
982   scan_event(&d3_l,&x,&y,&z,&quit,&escape,&switchmode,&bmp);
983   if(bmp) write_bmp(&d3_l,bmp,x,y,z);
984
985  }
986
987  d3_lattice_release(&d3_l);
988 #endif
989
990  return 1;
991 }