added 2 newview modes: c conc & a pressure
[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 implantation at temperatures
6  * below 400 degree celsius.
7  * hopefully the program will simulate the stabilization of the
8  * selforganizing lamella structure in the observed behaviour.
9  *
10  * refs: 
11  *  - J. K. N. Lindner. Habilationsschrift, Universitaet Augsburg.
12  *  - Maik Haeberlen. Diplomarbeit, Universitaet Augsburg.
13  */
14
15 #define _GNU_SOURCE
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <sys/types.h>
20 #include <sys/stat.h>
21 #include <fcntl.h>
22 #include <unistd.h>
23
24 #include "nlsop.h"
25
26 #include "dfbapi.h"
27 #include "random.h"
28
29 #define MAKE_AMORPH(N) *(N)|=AMORPH
30 #define MAKE_CRYST(N) *(N)&=~AMORPH
31
32 int usage(void)
33 {
34  puts("usage:");
35  puts("-h \t\t help");
36  puts("-n \t\t no user interaction");
37  puts("-Z \t\t cryst -> amorph c diffusion in z direction");
38  printf("-a <value> \t slope of nuclear energy loss (default %f)\n",A_EL);
39  printf("-b <value> \t nuclear energy loss offset (default %f)\n",B_EL);
40  printf("-x <value> \t # x cells (default %d)\n",X);
41  printf("-y <value> \t # y cells (default %d)\n",Y);
42  printf("-z <value> \t # z cells (default %d)\n",Z);
43  /*
44  printf("-X <value> \t display x (default %d)\n",X/2-1);
45  printf("-Y <value> \t display y (default %d)\n",Y/2-1);
46  printf("-Z <value> \t display z (default %d)\n",Z/2-1);
47  */
48  printf("-s <value> \t steps (default %d)\n",STEPS);
49  printf("-d <value> \t refresh display (default %d)\n",REFRESH);
50  printf("-r <value> \t amorphous influence range (default %d)\n",RANGE);
51  printf("-f <value> \t pressure = <value> * 1/distance^2 (default %f)\n",A_AP);
52  printf("-p <value> \t pressure offset (default %f)\n",B_AP);
53  printf("-A <value> \t slope of linear c distribution (default %f)\n",A_CD);
54  printf("-B <value> \t linear c distribution offset (default %f)\n",B_CD);
55  /*
56  printf("-C <value> \t initial c concentration (default %d)\n",CC);
57  */
58  printf("-D <value> \t diffusion rate from cryst to amorph cells (default %f)\n",D_R);
59  printf("-W <value> \t write every <value> steps to save file (default %d)\n",RESAVE);
60  puts("-C <file> \t convert file to gnuplot format");
61  puts("-L <file> \t load from file");
62  puts("-S <file> \t save to file");
63  puts("-R <file> \t read from random file");
64  
65  return 1;
66 }
67
68 int process_cell(d3_lattice *d3_l,u32 x,u32 y,u32 z,int r,double a,double b,int *t_c)
69 {
70  unsigned char *thiz;
71  int *conc;
72  int i,j;
73  int off;
74  double p;
75
76  thiz=d3_l->status+x+y*d3_l->max_x+z*d3_l->max_x*d3_l->max_y;
77  conc=d3_l->extra+x+y*d3_l->max_x+z*d3_l->max_x*d3_l->max_y;
78  p=b*URAND_MAX;
79  for(i=-r;i<=r;i++)
80  {
81   for(j=-r;j<=r;j++)
82   {
83    if(!(i==0 && j==0))
84    {
85     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;
86     if(*(d3_l->status+off)&AMORPH) p+=a*(*(d3_l->extra+off))*URAND_MAX/(i*i+j*j);
87    } 
88   }
89  }
90  printf("debug: p = %f\n",p);
91  if(!(*thiz&AMORPH))
92  {
93   if(get_rand(URAND_MAX)<=p) MAKE_AMORPH(thiz);
94  } else
95  {
96   /* assume 1-p probability */
97   if(get_rand(URAND_MAX)>p) MAKE_CRYST(thiz);
98  }
99  
100  *t_c+=1;
101
102  return 1;
103 }
104
105 int distrib_c(d3_lattice *d3_l,double d_r,double a,double b,char z_diff)
106 {
107  u32 x,y,z;
108  int i,j,k,c;
109  int offset,off;
110  int carry;
111
112  /* put one c ion somewhere in the lattice */
113  x=get_rand(d3_l->max_x);
114  y=get_rand(d3_l->max_y);
115  z=get_rand_lgp(d3_l->max_z,a,b);
116  *(d3_l->extra+x+y*d3_l->max_x+z*d3_l->max_x*d3_l->max_y)+=1;
117
118  /* diffusion in layer */
119  for(i=0;i<d3_l->max_x;i++)
120  {
121   for(j=0;j<d3_l->max_y;j++)
122   {
123    for(k=0;k<d3_l->max_z;k++)
124    {
125     offset=i+j*d3_l->max_x+k*d3_l->max_x*d3_l->max_y;
126     /* case amorph */
127     if(*(d3_l->status+offset)&AMORPH)
128     {
129      /* look at neighbours and move c ions */
130      for(c=-1;c<=1;c++)
131      {
132       if(c!=0)
133       {
134        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;
135        carry=0;
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        /*
140         * no diffusion between amorphous cells
141         *
142        else carry=(*(d3_l->extra+off)-*(d3_l->extra+offset))/2;
143         */
144        if(carry!=0)
145        {
146         *(d3_l->extra+offset)+=carry;
147         *(d3_l->extra+off)-=carry;
148        }
149       }
150      }
151      for(c=-1;c<=1;c++)
152      {
153       if(c!=0)
154       {
155        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;
156        carry=0;
157        /* case neighbour not amorph */  
158        if(!(*(d3_l->status+off)&AMORPH)) carry=(int)(d_r*(*(d3_l->extra+off)));                             
159        /* case neighbour amorph */
160        /*
161         *
162         * no diffusion between amorphous cells
163         *
164        else carry=(*(d3_l->extra+off)-*(d3_l->extra+offset))/2;
165         */
166        if(carry!=0)
167        {
168         *(d3_l->extra+offset)+=carry; 
169         *(d3_l->extra+off)-=carry; 
170        }
171       }
172      }
173     } else
174     /* case not amorph */
175     {
176      /* look at neighbours and move c ions */     
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        /* case neighbour not amorph */
184        if(!(*(d3_l->status+off)&AMORPH))
185        {
186         carry=(*(d3_l->extra+off)-*(d3_l->extra+offset))/2;
187         if(carry!=0)
188         {
189          *(d3_l->extra+offset)+=carry;
190          *(d3_l->extra+off)-=carry;
191         }
192        }
193       }
194      }
195      for(c=-1;c<=1;c++)
196      {
197       if(c!=0)
198       {
199        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;
200        carry=0;
201        /* case neighbour not amorph */
202        if(!(*(d3_l->status+off)&AMORPH))
203        {
204         carry=(*(d3_l->extra+off)-*(d3_l->extra+offset))/2;
205         if(carry!=0)
206         {
207          *(d3_l->extra+offset)+=carry;
208          *(d3_l->extra+off)-=carry;
209         }
210        }
211       }
212      }
213      /* cryst -> amorph diffusion in z direction */
214      if(z_diff)
215      {
216       for(c=1;c>=-1;c--)
217       {
218        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;
219        carry=0;
220        if(*(d3_l->status+off)&AMORPH) carry=(int)(d_r*(*(d3_l->extra+offset)));
221        if(carry!=0)
222        {
223         *(d3_l->extra+offset)-=carry;
224         *(d3_l->extra+off)+=carry;
225        }
226       }
227      } /* if z_diff */
228     }
229    } /* for z */
230   } /* for y */
231  } /* for x */
232
233  return 1;
234 }
235
236 int calc_pressure(d3_lattice *d3_l,int range)
237 {
238  int i,j,off;
239  double count;
240  int x,y,z;
241
242  for(x=0;x<d3_l->max_x;x++)
243  {
244   for(y=0;y<d3_l->max_y;y++)
245   {
246    for(z=0;z<d3_l->max_z;z++)
247    {
248     count=0;
249     for(i=-range;i<=range;i++)
250     {
251      for(j=-range;j<=range;j++)
252      {
253       if(i!=0 && j!=0)
254       {
255        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;
256        if(*(d3_l->status+off)&AMORPH) count+=((double)*(d3_l->extra+off))/(i*i+j*j);
257       }
258      }
259     }
260     *(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_VPTR);
261    }
262   }
263  }
264
265  return 1;
266 }
267
268 int distrib_c_old(d3_lattice *d3_l,int t_c,double a,double b)
269 {
270  int i,j,k,total,area;
271  double sum;
272  int temp,left;
273  int *area_h;
274  u32 x,y,z;
275
276  area=d3_l->max_x*d3_l->max_y;
277  area_h=(int *)malloc(d3_l->max_z*sizeof(int));
278
279  total=0;
280  sum=b*d3_l->max_z+a*d3_l->max_z*(d3_l->max_z+1)/2;
281  for(i=0;i<d3_l->max_z;i++)
282  {
283   area_h[i]=0;
284   for(j=0;j<area;j++)
285   {
286    if(!(*(d3_l->status+(i*area)+j)&AMORPH))
287    {
288     area_h[i]+=1;
289    }
290   }
291   temp=(int)((i+1)*a+b)*t_c/(sum*area_h[i]);
292   for(j=0;j<area;j++)
293   {
294    if(!(*(d3_l->status+(i*area)+j)&AMORPH))
295    {
296     *(d3_l->extra+(i*area)+j)=temp;
297     total+=temp;
298    }
299   }
300   left=(int)(((i+1)*a+b)*t_c/sum)%area_h[i];
301   while(left)
302   {
303    x=get_rand(d3_l->max_x);
304    y=get_rand(d3_l->max_y);
305    if(!(*(d3_l->status+(i*area)+x+y*d3_l->max_x)&AMORPH))
306    {
307     *(d3_l->extra+(i*area)+x+y*d3_l->max_x)+=1;
308     total+=1;
309     left-=1;
310    }
311   }
312  }
313  left=t_c-total;
314  while(left)
315  {
316   x=get_rand(d3_l->max_x);
317   y=get_rand(d3_l->max_y);
318   z=get_rand_lgp(d3_l->max_z,a,b);
319   if(!(*(d3_l->status+x+y*d3_l->max_x+z*area)&AMORPH))
320   {
321    *(d3_l->extra+x+y*d3_l->max_x+z*area)+=1;
322    left-=1;
323   }
324  }
325  free(area_h);
326
327  return 1;
328 }
329
330 int save_to_file(char *sf,d3_lattice *d3_l,info *my_inf)
331 {
332  int sf_fd,c;
333
334  if((sf_fd=open(sf,O_WRONLY|O_CREAT))<0)
335  {
336   puts("cannot open save file");
337   return -1;
338  }
339  if(write(sf_fd,d3_l,sizeof(d3_lattice))<sizeof(d3_lattice))
340  {
341   puts("failed saving d3 lattice struct");
342   return -1;
343  }
344  if(write(sf_fd,my_inf,sizeof(info))<sizeof(info))
345  {
346   puts("failed saving info struct");
347   return-1;
348  }
349  c=d3_l->max_x*d3_l->max_y*d3_l->max_z;
350  if(write(sf_fd,d3_l->status,c*sizeof(unsigned char))<c*sizeof(unsigned char))
351  {
352   puts("failed saving status of d3 lattice sites");
353   return -1;
354  }
355  if(write(sf_fd,d3_l->extra,c*sizeof(int))<c*sizeof(int))
356  {
357   puts("failed saving sites concentration");
358   return -1;
359  }
360  close(sf_fd);
361
362  return 1;
363 }
364
365 int load_from_file(char *lf,d3_lattice *d3_l,info *my_inf)
366 {
367  int lf_fd,c;
368
369  if((lf_fd=open(lf,O_RDONLY))<0)
370  {
371   puts("cannot open load file");
372   return -1;
373  }
374  if(read(lf_fd,d3_l,sizeof(d3_lattice))<sizeof(d3_lattice))
375  {
376   puts("failed reading d3 lattice struct");
377   return -1;
378  }
379  if(read(lf_fd,my_inf,sizeof(info))<sizeof(info))
380  {
381   puts("failed reading info struct");
382   return-1;
383  }
384  c=d3_l->max_x*d3_l->max_y*d3_l->max_z;
385  if((d3_l->status=(unsigned char*)malloc(c*sizeof(unsigned char)))==NULL)
386  {
387   puts("cannot allocate status buffer");
388   return -1;
389  }
390  if((d3_l->extra=(int *)malloc(c*sizeof(int)))==NULL)
391  {
392   puts("cannot allocate concentration buffer");
393   return -1;
394  }
395  if(read(lf_fd,d3_l->status,c*sizeof(unsigned char))<c*sizeof(unsigned char))
396  {
397   puts("failed reading status of d3 lattice sites");
398   return -1;
399  }
400  if(read(lf_fd,d3_l->extra,c*sizeof(int))<c*sizeof(int))
401  {
402   puts("failed reading sites concentration");
403   return -1;
404  }
405  close(lf_fd);
406
407  return 1;
408 }
409
410 int convert_file(char *cf,d3_lattice *d3_l)
411 {
412  int x,y,z;
413  int c_fd;
414
415  if((c_fd=open(cf,O_WRONLY|O_CREAT))<0)
416  {
417   puts("cannot open convert file");
418   return -1;
419  }
420  dprintf(c_fd,"# created by nlsop (gnuplot format)\n");
421  for(x=0;x<d3_l->max_x;x++)
422  {
423   for(y=0;y<d3_l->max_y;y++)
424   {
425    for(z=0;z<d3_l->max_z;z++)
426    {
427     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);
428    }
429   }
430  }
431  close(c_fd);
432
433  return 1;
434 }
435
436 int main(int argc,char **argv)
437 {
438  u32 x,y,z,x_c,y_c,z_c;
439  int i,quit,escape,switchmode,nowait;
440  int refresh,resave;
441  char z_diff;
442  char s_file[MAX_CHARS];
443  char s_file_tmp[MAX_CHARS];
444  char l_file[MAX_CHARS];
445  char c_file[MAX_CHARS];
446  char convert;
447  char r_file[MAX_CHARS];
448 #ifdef USE_DFB_API
449  char x_txt[MAX_TXT];
450  char y_txt[MAX_TXT];
451  char z_txt[MAX_TXT];
452  char status_txt[MAX_TXT];
453  char conc_txt[MAX_TXT];
454  char steps_txt[MAX_TXT];
455  char cc_txt[MAX_TXT];
456  char a_txt[MAX_TXT];
457  char s_txt[MAX_TXT];
458  char ap_txt[MAX_TXT];
459  char el_txt[MAX_TXT];
460  char cd_txt[MAX_TXT];
461  char r_txt[MAX_TXT];
462  char ap2_txt[MAX_TXT];
463  char cd2_txt[MAX_TXT];
464  char el2_txt[MAX_TXT];
465  char dr_txt[MAX_TXT];
466  char mode_txt[MAX_TXT];
467  char *arg_v[MAX_ARGV];
468 #endif
469  d3_lattice d3_l;
470  info my_info;
471  unsigned char mode;
472
473  d3_l.max_x=X;
474  d3_l.max_y=Y;
475  d3_l.max_z=Z;
476  my_info.steps=STEPS;
477  my_info.range=RANGE;
478  refresh=REFRESH;
479  resave=RESAVE;
480  z_diff=0;
481  my_info.a_el=A_EL;
482  my_info.b_el=B_EL;
483  my_info.a_cd=A_CD;
484  my_info.b_cd=B_CD;
485  my_info.a_ap=A_AP;
486  my_info.b_ap=B_AP;
487  my_info.cc=CC;
488  my_info.d_r=D_R;
489  nowait=0;
490  quit=0;
491  escape=0;
492  switchmode=0;
493  strcpy(s_file,"");
494  strcpy(l_file,"");
495  strcpy(c_file,"");
496  convert=0;
497  strcpy(r_file,"");
498  mode=0;
499
500  for(i=1;i<argc;i++)
501  {
502   if(argv[i][0]=='-')
503   {
504    switch(argv[i][1])
505    {
506     case 'h':
507      usage();
508      return -1;
509     case 'n':
510      nowait=1;
511      break;
512     case 'a':
513      my_info.a_el=atof(argv[++i]);
514      break;
515     case 'b':
516      my_info.b_el=atof(argv[++i]);
517      break;
518     case 'x':
519      d3_l.max_x=atoi(argv[++i]);
520      break;
521     case 'y':
522      d3_l.max_y=atoi(argv[++i]);
523      break;
524     case 'z':
525      d3_l.max_z=atoi(argv[++i]);
526      break;
527     /*
528     case 'X':
529      x=atoi(argv[++i]);
530      break;
531     case 'Y':
532      y=atoi(argv[++i]);
533      break;
534     */
535     case 'Z':
536      z_diff=1;
537      break;
538     /* */
539     case 's':
540      my_info.steps=atoi(argv[++i]);
541      break;
542     case 'd':
543      refresh=atoi(argv[++i]);
544      break;
545     case 'r':
546      my_info.range=atoi(argv[++i]);
547      break;
548     case 'f':
549      my_info.a_ap=atof(argv[++i]);
550      break;
551     case 'p':
552      my_info.b_ap=atof(argv[++i]);
553      break;
554     case 'A':
555      my_info.a_cd=atof(argv[++i]);
556      break;
557     case 'B':
558      my_info.b_cd=atof(argv[++i]);
559      break;
560     /*
561     case 'C':
562      my_info.cc=atoi(argv[++i]);
563      break;
564     */
565     case 'W':
566      resave=atoi(argv[++i]);
567      break;
568     case 'C':
569      strcpy(l_file,argv[++i]);
570      if(i<argc-1) if(argv[i+1][0]!='-') strcpy(c_file,argv[++i]);
571      convert=1;
572      break;
573     case 'D':
574      my_info.d_r=atof(argv[++i]);
575      break;
576     case 'L':
577      strcpy(l_file,argv[++i]);
578      break;
579     case 'S':
580      strcpy(s_file,argv[++i]);
581      break;
582     case 'R':
583      strcpy(r_file,argv[++i]);
584      break;
585     default:
586      usage();
587      return -1;
588    }
589   } else usage();
590  }
591
592  x=d3_l.max_x/2-1;
593  y=d3_l.max_y/2-1;
594  z=d3_l.max_z/2-1;
595
596 #ifdef NODFB
597  if(!strcmp(s_file,""))
598  {
599   puts("NODFB defined, run with -S option");
600   return -1;
601  }
602 #endif
603
604  if(!strcmp(r_file,"")) rand_init(NULL);
605  else rand_init(r_file);
606
607  if(!strcmp(l_file,""))
608  {
609   i=d3_l.max_x*d3_l.max_y*d3_l.max_z;
610 #ifdef USE_DFB_API
611   d3_lattice_init(&argc,argv,&d3_l);
612 #endif
613   if((d3_l.status=(unsigned char *)malloc(i*sizeof(unsigned char)))==NULL)
614   {
615    puts("failed allocating status buffer");
616    return -1;
617   }
618   memset(d3_l.status,0,i*sizeof(unsigned char));
619   if((d3_l.extra=(int *)malloc(i*sizeof(int)))==NULL)
620   {
621    puts("failed allocating concentration buffer");
622    return -1;
623   }
624   memset(d3_l.extra,0,i*sizeof(int));
625  } else
626  {
627   load_from_file(l_file,&d3_l,&my_info);
628   if(convert) 
629   {   
630    if(!strcmp(c_file,"")) sprintf(c_file,"%s_gnuplot",l_file);
631    printf("converting file %s to %s\n",l_file,c_file);
632    convert_file(c_file,&d3_l);
633    puts("done");
634    return 1;
635   } 
636 #ifdef USE_DFB_API
637     else d3_lattice_init(&argc,argv,&d3_l);
638 #endif
639  }
640
641 #ifdef USE_DFB_API
642  d3_event_init(&d3_l);
643 #endif
644
645 #ifdef USE_DFB_API
646  strcpy(a_txt,"args:");
647  sprintf(s_txt,"steps: %d",my_info.steps);
648  sprintf(r_txt,"pressure range: %d",my_info.range);
649  sprintf(ap_txt,"pressure faktor: %.2f",my_info.a_ap);
650  sprintf(ap2_txt,"pressure offset: %.2f",my_info.b_ap);
651  sprintf(el_txt,"energy loss slope: %.2f",my_info.a_el);
652  sprintf(el2_txt,"energy loss offset: %.2f",my_info.b_el);
653  sprintf(cd_txt,"c distrib slope: %.2f",my_info.a_cd);
654  sprintf(cd2_txt,"c distrib offset: %.2f",my_info.b_cd);
655  sprintf(dr_txt,"diffusion rate: %.2f",my_info.d_r);
656  strcpy(mode_txt,"view: a/c mode");
657  arg_v[1]=x_txt;
658  arg_v[2]=y_txt;
659  arg_v[3]=z_txt;
660  arg_v[4]=NULL;
661  arg_v[5]=status_txt;
662  arg_v[6]=conc_txt;
663  arg_v[7]=NULL;
664  arg_v[8]=mode_txt;
665  arg_v[9]=NULL;
666  arg_v[10]=steps_txt;;
667  arg_v[11]=cc_txt;
668  arg_v[12]=NULL;
669  arg_v[13]=NULL;
670  arg_v[14]=a_txt;
671  arg_v[15]=NULL;
672  arg_v[16]=s_txt;
673  arg_v[17]=r_txt;
674  arg_v[18]=ap_txt;
675  arg_v[19]=ap2_txt;
676  arg_v[20]=el_txt;
677  arg_v[21]=el2_txt;
678  arg_v[22]=cd_txt;
679  arg_v[23]=cd2_txt;
680  arg_v[24]=dr_txt;
681 #endif
682
683  if(!strcmp(l_file,""))
684  {
685   i=0;
686   while((i<my_info.steps) && (quit==0) && (escape==0))
687   {
688    x_c=get_rand(d3_l.max_x);
689    y_c=get_rand(d3_l.max_y);
690    z_c=get_rand_lgp(d3_l.max_z,my_info.a_el,my_info.b_el);
691    distrib_c(&d3_l,my_info.d_r,my_info.a_cd,my_info.b_cd,z_diff);
692    process_cell(&d3_l,x_c,y_c,z_c,my_info.range,my_info.a_ap,my_info.b_ap,&(my_info.cc));
693 #ifdef USE_DFB_API
694    if(i%refresh==0)
695    {
696     sprintf(x_txt,"x: %d",x+1);
697     sprintf(y_txt,"y: %d",y+1);
698     sprintf(z_txt,"z: %d",z+1);
699     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');
700     sprintf(conc_txt,"conc: %d",*(d3_l.extra+x+y*d3_l.max_x+z*d3_l.max_x*d3_l.max_y));
701     sprintf(steps_txt,"step: %d",i);
702     sprintf(cc_txt,"total c: %d",my_info.cc);
703     d3_lattice_draw(&d3_l,x,y,z,24,arg_v,mode);
704    }
705 #endif
706    if(i%resave==0 && strcmp(s_file,"") && resave!=0)
707    {
708     sprintf(s_file_tmp,"%s_%d_of_%d",s_file,i,my_info.steps);
709     save_to_file(s_file_tmp,&d3_l,&my_info);
710 #ifdef NODFB
711     printf("saved %s\n",s_file_tmp);
712 #endif
713    }
714    i++;
715   }
716  }
717
718  if(strcmp(s_file,""))
719  {
720    printf("saved %s\n",s_file);
721    save_to_file(s_file,&d3_l,&my_info);
722  }
723
724 #ifdef USE_DFB_API
725  /* allocating buffer for pressure values */
726  if((d3_l.v_ptr=malloc(d3_l.max_x*d3_l.max_y*d3_l.max_z*sizeof(unsigned char)))==NULL)
727  {
728   puts("cannot allocate buffer for pressure values");
729   return -1;
730  }
731  /* calc values */
732  calc_pressure(&d3_l,my_info.range);
733
734  while((quit==0) && (escape==0) && (nowait==0))
735  {
736   /* bahh! */
737   if(switchmode==0) mode=0;
738   if(switchmode==1) mode=1;
739   if(switchmode==2) mode=2;
740   /* end of bahh! */
741   sprintf(x_txt,"x: %d",x+1);
742   sprintf(y_txt,"y: %d",y+1);
743   sprintf(z_txt,"z: %d",z+1);
744   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');
745   sprintf(conc_txt,"conc: %d",*(d3_l.extra+x+y*d3_l.max_x+z*d3_l.max_x*d3_l.max_y));
746   strcpy(steps_txt,"step: end!");
747   sprintf(cc_txt,"total c: %d",my_info.cc);
748   if(switchmode==0) strcpy(mode_txt,"view: a/c mode");
749   if(switchmode==1) strcpy(mode_txt,"view: c conc mode");
750   if(switchmode==2) strcpy(mode_txt,"view: a pressure mode");
751   d3_lattice_draw(&d3_l,x,y,z,24,arg_v,mode);
752   scan_event(&d3_l,&x,&y,&z,&quit,&escape,&switchmode);
753  }
754
755  d3_lattice_release(&d3_l);
756 #endif
757
758  return 1;
759 }