nearly finished gui code. adaptions / bugfixes.
[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. Habil.Schrift, 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("-x <value> \t # x cells (default %d)\n",X);
59  printf("-y <value> \t # y cells (default %d)\n",Y);
60  printf("-z <value> \t # z cells (default %d)\n",Z);
61  printf("-s <value> \t steps (default %d)\n",STEPS);
62  printf("-d <value> \t refresh display (default %d)\n",REFRESH);
63  printf("-r <value> \t amorphous influence range (default %d)\n",RANGE);
64  printf("-f <value> \t stress induced amorphization influence (default %f)\n",S_D);
65  printf("-p <value> \t ballistic amorphization influence (default %f)\n",B_D);
66  printf("-F <value> \t carbon induced amorphization influence (default %f)\n",C_D);
67  printf("-D <value> \t diffusion rate from cryst to amorph cells (default %f)\n",DR_AC);
68  printf("-c <value> \t diffusion rate in cryst cells (default %f)\n",DR_CC);
69  printf("-e <value> \t do diffusion every <value> steps (default %d)\n",DIFF_RATE);
70  puts("-g <file> <step> continue simulation from file and step (step > 0)!");
71  printf("-W <value> \t write every <value> steps to save file (default %d)\n",RESAVE);
72  puts("-C <file> \t convert file to gnuplot format");
73  puts("-L <file> \t load from file");
74  puts("-S <file> \t save to file");
75  puts("-R <file> \t read from random file");
76  puts("-P <file> \t specify implantation profile file");
77  puts("-N <file> \t specify nuclear energy loss profile file");
78  printf("-H <value> \t collisions per ion in simulation window (default %d)\n",CPI);
79  printf("-m <value> \t number of ion hits sputtering 3nm (default %d)\n",S_RATE);
80  
81  return 1;
82 }
83
84 int sputter(d3_lattice *d3_l)
85 {
86  int i,size;
87  int offh,offl;
88
89  size=d3_l->max_x*d3_l->max_y;
90  offl=0;
91  offh=size;
92
93  for(i=0;i<d3_l->max_z-1;i++)
94  {
95   memcpy(d3_l->status+offl,d3_l->status+offh,size);
96   memcpy(d3_l->extra+offl,d3_l->extra+offh,size*sizeof(int));
97   offl=offh;
98   offh+=size;
99  }
100  memset(d3_l->status+offl,0,size);
101  memset(d3_l->extra+offl,0,size);
102
103  return 1;
104 }
105
106 int process_cell(d3_lattice *d3_l,u32 x,u32 y,u32 z,info *my_info,u32 nel_z)
107 {
108  unsigned char *thiz;
109  int *conc;
110  int i,j;
111  int off;
112  double p,q;
113
114  thiz=d3_l->status+x+y*d3_l->max_x+z*d3_l->max_x*d3_l->max_y;
115  conc=d3_l->extra+x+y*d3_l->max_x+z*d3_l->max_x*d3_l->max_y;
116  p=my_info->b*nel_z;
117  for(i=-(my_info->range);i<=my_info->range;i++)
118  {
119   for(j=-(my_info->range);j<=my_info->range;j++)
120   {
121    if(!(i==0 && j==0))
122    {
123     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;
124     if(*(d3_l->status+off)&AMORPH) p+=my_info->s*(*(d3_l->extra+off))*URAND_MAX/(i*i+j*j);
125    } 
126   }
127  }
128  p+=*conc*my_info->c*URAND_MAX;
129  if(!(*thiz&AMORPH))
130  {
131   if(get_rand(URAND_MAX)<=p) MAKE_AMORPH(thiz);
132  } else
133  {
134   /* assume 1-p probability */
135   /* also look for neighbours ! */
136   q=(URAND_MAX-p)>0?URAND_MAX-p:0;
137   j=0;
138   j+=(*(d3_l->status+((x+d3_l->max_x+1)%d3_l->max_x)+y*d3_l->max_x+z*d3_l->max_x*d3_l->max_y)&AMORPH)?1:0;
139   j+=(*(d3_l->status+((x+d3_l->max_x-1)%d3_l->max_x)+y*d3_l->max_x+z*d3_l->max_x*d3_l->max_y)&AMORPH)?1:0;
140   j+=(*(d3_l->status+x+((y+1+d3_l->max_y)%d3_l->max_y)*d3_l->max_x+z*d3_l->max_x*d3_l->max_y)&AMORPH)?1:0;
141   j+=(*(d3_l->status+x+((y-1+d3_l->max_y)%d3_l->max_y)*d3_l->max_x+z*d3_l->max_x*d3_l->max_y)&AMORPH)?1:0;
142   j+=(*(d3_l->status+x+y*d3_l->max_x+((z+1+d3_l->max_z)%d3_l->max_z)*d3_l->max_x*d3_l->max_y)&AMORPH)?1:0;
143   j+=(*(d3_l->status+x+y*d3_l->max_x+((z-1+d3_l->max_z)%d3_l->max_z)*d3_l->max_x*d3_l->max_y)&AMORPH)?1:0;
144
145   p+=((q/6)*j);
146   if(get_rand(URAND_MAX)>p) MAKE_CRYST(thiz);
147  }
148  
149  return 1;
150 }
151
152 int distrib_c(d3_lattice *d3_l,info *my_info,int step,u32 rj_m,u32 *rj_g)
153 {
154  u32 x,y,z;
155  int i,j,k,c;
156  int offset,off;
157  int carry;
158
159  /* put one c ion somewhere in the lattice */
160  x=get_rand(d3_l->max_x);
161  y=get_rand(d3_l->max_y);
162  z=get_rand_reject(d3_l->max_z,rj_m,rj_g);
163  *(d3_l->extra+x+y*d3_l->max_x+z*d3_l->max_x*d3_l->max_y)+=1;
164  (my_info->cc)++;
165
166  if(step%my_info->diff_rate==0)
167  {
168
169  for(i=0;i<d3_l->max_x;i++)
170  {
171   for(j=0;j<d3_l->max_y;j++)
172   {
173    for(k=0;k<d3_l->max_z;k++)
174    {
175     offset=i+j*d3_l->max_x+k*d3_l->max_x*d3_l->max_y;
176     /* case amorph: amorph <- cryst diffusion */
177     if(*(d3_l->status+offset)&AMORPH)
178     {
179      for(c=-1;c<=1;c++)
180      {
181       if(c!=0)
182       {
183        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;
184        carry=0;
185        if(!(*(d3_l->status+off)&AMORPH)) carry=(int)(my_info->dr_ac*(*(d3_l->extra+off)));
186        if(carry!=0)
187        {
188         *(d3_l->extra+offset)+=carry;
189         *(d3_l->extra+off)-=carry;
190        }
191       }
192      }
193      for(c=-1;c<=1;c++)
194      {
195       if(c!=0)
196       {
197        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;
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+offset)+=carry; 
203         *(d3_l->extra+off)-=carry; 
204        }
205       }
206      }
207      if(my_info->z_diff)
208      {
209       if(k!=0)
210       {
211        off=i+j*d3_l->max_x+(k-1)*d3_l->max_x*d3_l->max_y;
212        carry=0;
213        if(!*(d3_l->status+off)&AMORPH) carry=(int)(my_info->dr_ac*(*(d3_l->extra+off)));
214        if(carry!=0)
215        {
216         *(d3_l->extra+off)-=carry;
217         *(d3_l->extra+offset)+=carry;
218        }
219       }
220       if(k!=d3_l->max_z-1)
221       {
222        off=i+j*d3_l->max_x+(k+1)*d3_l->max_x*d3_l->max_y;
223        carry=0;
224        if(!*(d3_l->status+off)&AMORPH) carry=(int)(my_info->dr_ac*(*(d3_l->extra+off)));
225        if(carry!=0)
226        {
227         *(d3_l->extra+off)-=carry;
228         *(d3_l->extra+offset)+=carry;
229        }
230       }
231      }  
232     } else
233     /* case not amorph: cryst <-> cryst diffusion */
234     if(my_info->c_diff) {
235     /* if there is c diff, no diff in z-direction */
236     {
237      for(c=-1;c<=1;c++) 
238      {
239       if(c!=0)
240       {
241        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;
242        carry=0;
243        if(!(*(d3_l->status+off)&AMORPH))
244        {
245         carry=(int)(my_info->dr_cc*(*(d3_l->extra+off)-*(d3_l->extra+offset))/2);
246         if(carry!=0)
247         {
248          *(d3_l->extra+offset)+=carry;
249          *(d3_l->extra+off)-=carry;
250         }
251        }
252       }
253      }
254      for(c=-1;c<=1;c++)
255      {
256       if(c!=0)
257       {
258        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;
259        carry=0;
260        if(!(*(d3_l->status+off)&AMORPH))
261        {
262         carry=(int)(my_info->dr_cc*(*(d3_l->extra+off)-*(d3_l->extra+offset))/2);
263         if(carry!=0)
264         {
265          *(d3_l->extra+offset)+=carry;
266          *(d3_l->extra+off)-=carry;
267         }
268        }
269       }
270      }
271     }
272     /* end test */
273     }
274     /* */
275    } /* for z */
276   } /* for y */
277  } /* for x */
278
279  } /* if step modulo diff_rate == 0 */
280
281  return 1;
282 }
283
284 int calc_pressure(d3_lattice *d3_l,int range)
285 {
286  int i,j,off;
287  double count,max=0;
288  int x,y,z;
289
290  for(x=0;x<d3_l->max_x;x++)
291  {
292   for(y=0;y<d3_l->max_y;y++)
293   {
294    for(z=0;z<d3_l->max_z;z++)
295    {
296     count=0;
297     for(i=-range;i<=range;i++)
298     {
299      for(j=-range;j<=range;j++)
300      {
301       if(i!=0 && j!=0)
302       {
303        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;
304        if(*(d3_l->status+off)&AMORPH) count+=((double)*(d3_l->extra+off))/(i*i+j*j);
305       }
306      }
307     }
308     if(count>max) max=count;
309    }
310   }
311  }
312
313  for(x=0;x<d3_l->max_x;x++)
314  {
315   for(y=0;y<d3_l->max_y;y++)
316   {
317    for(z=0;z<d3_l->max_z;z++)
318    {
319     count=0;
320     for(i=-range;i<=range;i++)
321     {
322      for(j=-range;j<=range;j++)
323      {
324       if(i!=0 && j!=0)
325       {
326        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;
327        if(*(d3_l->status+off)&AMORPH) count+=((double)*(d3_l->extra+off))/(i*i+j*j);
328       }
329      }
330     }
331     *(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);
332    }
333   }
334  }
335
336  return 1;
337 }
338
339 int calc_max_extra(d3_lattice *d3_l)
340 {
341  int x,y,z;
342  int off,max=0;
343
344  for(x=0;x<d3_l->max_x;x++)
345  {
346   for(y=0;y<d3_l->max_y;y++)
347   {
348    for(z=0;z<d3_l->max_z;z++)
349    {
350     off=x+y*d3_l->max_x+z*d3_l->max_x*d3_l->max_y;
351     if(*(d3_l->extra+off)>max) max=*(d3_l->extra+off);
352    }
353   }
354  }
355
356  return max;
357 }
358
359 int write_ac_distr(d3_lattice *d3_l,int ac_distr)
360 {
361  int fd,x,y,z;
362  int count,offset;
363  char file[32];
364  int si_count;
365  
366  si_count=d3_l->max_x*d3_l->max_y*SI_PER_VOLUME;
367  if(ac_distr==1) strcpy(file,"carbon_in_av.plot");
368  if(ac_distr==2) strcpy(file,"carbon_in_cv.plot");
369  if(ac_distr==3) strcpy(file,"carbon.plot");
370  if(ac_distr==4) strcpy(file,"amorphous_volumes.plot");
371
372  if((fd=open(file,O_WRONLY|O_CREAT))<0)
373  {
374   puts("cannot open plot file");
375   return -1;
376  }
377
378  for(z=0;z<d3_l->max_z;z++)
379  {
380   count=0;
381   for(x=0;x<d3_l->max_x;x++)
382   {
383    for(y=0;y<d3_l->max_y;y++)
384    {
385     offset=x+y*d3_l->max_x+z*d3_l->max_x*d3_l->max_y;
386     if(ac_distr==1)
387      if(*(d3_l->status+offset)&AMORPH) count+=*(d3_l->extra+offset);
388     if(ac_distr==2)
389      if(!(*(d3_l->status+offset)&AMORPH)) count+=*(d3_l->extra+offset);
390     if(ac_distr==3) count+=*(d3_l->extra+offset);
391     if(ac_distr==4)
392      if(*(d3_l->status+offset)&AMORPH) count+=1;
393    }
394   }
395 #ifndef MAC
396   if(ac_distr==4) dprintf(fd,"%d %d\n",z*CELL_LENGTH,count);
397   else dprintf(fd,"%d %f\n",z*CELL_LENGTH,100.0*count/si_count);
398 #endif
399  }
400  close(fd);
401  
402  return 1;
403 }
404
405 int write_bmp(d3_lattice *d3_l,int window,u32 x,u32 y,u32 z,int max)
406 {
407  int fd,i,j,size=0,foo=0,k,sum;
408  int width=0,height=0;
409  char bmpfile[MAX_CHARS];
410  char buf[128];
411
412  if(window==1)
413  {
414   sprintf(bmpfile,"x-z_%d.bmp",y);
415   foo=3*d3_l->max_x;
416   size=(foo+(4-foo%4))*d3_l->max_z;
417   height=d3_l->max_z;
418   width=d3_l->max_x;
419  }
420  if(window==2)
421  {
422   sprintf(bmpfile,"y-z_%d.bmp",x);
423   foo=3*d3_l->max_y;
424   size=(foo+(4-foo%4))*d3_l->max_z;
425   height=d3_l->max_z;
426   width=d3_l->max_y;
427  }
428  if(window==3)
429  {
430   sprintf(bmpfile,"x-y_%d.bmp",z);
431   foo=3*d3_l->max_x;
432   size=(foo+(4-foo%4))*d3_l->max_y;
433   width=d3_l->max_x;
434   height=d3_l->max_y;
435  }
436  if(window==4)
437  {
438   sprintf(bmpfile,"x-z_cdistr_%d.bmp",y);
439   foo=3*d3_l->max_x;
440   size=(foo+(4-foo%4))*d3_l->max_z;
441   height=d3_l->max_z;
442   width=d3_l->max_x;
443  }
444  if(window==5)
445  {
446   sprintf(bmpfile,"y-z_cdistr_%d.bmp",x);
447   foo=3*d3_l->max_y;
448   size=(foo+(4-foo%4))*d3_l->max_z;
449   height=d3_l->max_z;
450   width=d3_l->max_y;
451  }
452  if(window==6)
453  {
454   sprintf(bmpfile,"x-y_cdistr_%d.bmp",z);
455   foo=3*d3_l->max_x;
456   size=(foo+(4-foo%4))*d3_l->max_y;
457   width=d3_l->max_x;
458   height=d3_l->max_y;
459  }
460  if(window==7)
461  {
462   sprintf(bmpfile,"x-z_a_cdistr_%d.bmp",y);
463   foo=3*d3_l->max_x;
464   size=(foo+(4-foo%4))*d3_l->max_z;
465   height=d3_l->max_z;
466   width=d3_l->max_x;
467  }
468  if(window==8)
469  {
470   sprintf(bmpfile,"y-z_a_cdistr_%d.bmp",x);
471   foo=3*d3_l->max_y;
472   size=(foo+(4-foo%4))*d3_l->max_z;
473   height=d3_l->max_z;
474   width=d3_l->max_y;
475  }
476  if(window==9)
477  {
478   sprintf(bmpfile,"x-y_a_cdistr_%d.bmp",z);
479   foo=3*d3_l->max_x;
480   size=(foo+(4-foo%4))*d3_l->max_y;
481   height=d3_l->max_y;
482   width=d3_l->max_x;
483  }
484  if(window==10)
485  {
486   sprintf(bmpfile,"x-z_c_cdistr_%d.bmp",y);
487   foo=3*d3_l->max_x;
488   size=(foo+(4-foo%4))*d3_l->max_z;
489   height=d3_l->max_z;
490   width=d3_l->max_x;
491  }
492  if(window==11)
493  {
494   sprintf(bmpfile,"y-z_c_cdistr_%d.bmp",x);
495   foo=3*d3_l->max_y;
496   size=(foo+(4-foo%4))*d3_l->max_z;
497   height=d3_l->max_z;
498   width=d3_l->max_y;
499  }
500  if(window==12)
501  {
502   sprintf(bmpfile,"x-y_c_cdistr_%d.bmp",z);
503   foo=3*d3_l->max_x;
504   size=(foo+(4-foo%4))*d3_l->max_y;
505   height=d3_l->max_y;
506   width=d3_l->max_x;
507  }
508  if((fd=open(bmpfile,O_WRONLY|O_CREAT))<0)
509  {
510   puts("cannot open bmp file");
511   return -1;
512  }
513
514  /* bmpheader */
515  buf[0]='B'; /* std header start */
516  buf[1]='M';
517  buf[2]=(size+0x36)&0xff; /* file size */
518  buf[3]=(size+0x36)>>8;
519  memset(buf+4,0,6);
520  buf[10]=0x36; /* offset to data */
521  memset(buf+11,0,3);
522  buf[14]=0x28; /* length of bmp info header */
523  memset(buf+15,0,3);
524  buf[18]=width&0xff; /* width and height */
525  buf[19]=width>>8;
526  memset(buf+20,0,2);
527  buf[22]=height&0xff;
528  buf[23]=height>>8;
529  memset(buf+24,0,2);
530  buf[26]=1; /* # planes -> 1 */
531  buf[27]=0;
532  buf[28]=24; /* bits per pixel -> 2^24 (true color) */
533  buf[29]=0;
534  memset(buf+30,0,4); /* compression -> none */
535  buf[34]=size&0xff; /* data size */
536  buf[35]=size>>8;
537  memset(buf+36,0,2);
538  buf[38]=0x12; /* res: pixel/meter */
539  buf[39]=0x0b;
540  memset(buf+40,0,2);
541  buf[42]=0x12;
542  buf[43]=0x0b;
543  memset(buf+44,0,2); 
544  memset(buf+46,0,8); /* no colors, no important colors */
545
546  if(write(fd,buf,54)<54)
547  {
548   puts("failed writing bmp header");
549   return -1;
550  }
551  if(window==1)
552  {
553   for(j=0;j<d3_l->max_z;j++)
554   {
555    for(i=0;i<d3_l->max_x;i++)
556    {
557     sum=0;
558     for(k=-2;k<=2;k++)
559      if(*(d3_l->status+i+(((y+k+d3_l->max_y)%d3_l->max_y)*d3_l->max_x)+(d3_l->max_z-j-1)*d3_l->max_x*d3_l->max_y)&RED) sum+=0xff;
560     sum/=5;
561     memset(buf,(unsigned char)sum,3);
562     if(write(fd,buf,3)<3)
563     {
564      puts("failed writing rgb values to bmp file");
565      return-1;
566     }
567    }
568    if(foo%4)
569    {
570     memset(buf,0,4-foo%4);
571     if(write(fd,buf,4-foo%4)<4-foo%4)
572     {
573      puts("failed writing 4 byte ending");
574      return -1;
575     }
576    } 
577   }
578  }
579  if(window==2)
580  {
581   for(j=0;j<d3_l->max_z;j++)
582   {
583    for(i=0;i<d3_l->max_y;i++)
584    {
585     sum=0;
586     for(k=-2;k<=2;k++)
587      if(*(d3_l->status+((x+k+d3_l->max_x)%d3_l->max_x)+i*d3_l->max_x+(d3_l->max_z-j-1)*d3_l->max_x*d3_l->max_y)&RED) sum+=0xff;
588     sum/=5;
589     memset(buf,(unsigned char)sum,3);
590     if(write(fd,buf,3)<3)
591     {
592      puts("failed writing rgb values to bmp file");
593      return-1;
594     }
595    }
596    if(foo%4)
597    {
598     memset(buf,0,4-foo%4);
599     if(write(fd,buf,4-foo%4)<4-foo%4)
600     {
601      puts("failed writing 4 byte ending");
602      return -1;
603     }
604    }
605   }
606  }
607  if(window==3)
608  {
609   for(j=0;j<d3_l->max_y;j++)
610   {
611    for(i=0;i<d3_l->max_x;i++)
612    {
613     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);
614     else memset(buf,0,3);
615     if(write(fd,buf,3)<3)
616     {
617      puts("failed writing rgb values to bmp file");
618      return -1;
619     }
620    }
621    if(foo%4)
622    {
623     memset(buf,0,4-foo%4);
624     if(write(fd,buf,4-foo%4)<4-foo%4)
625     {
626      puts("failed writing 4 byte ending");
627      return -1;
628     }
629    }
630   }
631  }
632  if(window==4)
633  {
634   for(j=0;j<d3_l->max_z;j++)
635   {
636    for(i=0;i<d3_l->max_x;i++)
637    {
638     sum=*(d3_l->extra+i+y*d3_l->max_x+(d3_l->max_z-j-1)*d3_l->max_x*d3_l->max_y);
639     sum=sum*255/max;
640     memset(buf,(unsigned char)sum,3);
641     if(write(fd,buf,3)<3)
642     {
643      puts("failed writing rgb values to bmp file");
644      return-1;
645     }
646    }
647    if(foo%4)
648    {
649     memset(buf,0,4-foo%4);
650     if(write(fd,buf,4-foo%4)<4-foo%4)
651     {
652      puts("failed writing 4 byte ending");
653      return -1;
654     }
655    }
656   }
657  }
658  if(window==5)
659  { 
660   for(j=0;j<d3_l->max_z;j++) 
661   {                     
662    for(i=0;i<d3_l->max_x;i++)
663    {
664     sum=*(d3_l->extra+x+i*d3_l->max_x+(d3_l->max_z-j-1)*d3_l->max_x*d3_l->max_y);
665     sum=sum*255/max;
666     memset(buf,(unsigned char)sum,3);
667     if(write(fd,buf,3)<3)
668     {
669      puts("failed writing rgb values to bmp file");
670      return-1;  
671     }
672    }
673    if(foo%4)
674    {
675     memset(buf,0,4-foo%4);
676     if(write(fd,buf,4-foo%4)<4-foo%4)
677     {
678      puts("failed writing 4 byte ending");
679      return -1;
680     }
681    }
682   }
683  }
684  if(window==6)
685  {   
686   for(j=0;j<d3_l->max_y;j++)
687   {  
688    for(i=0;i<d3_l->max_x;i++)
689    { 
690     sum=*(d3_l->extra+i+(d3_l->max_y-j-1)*d3_l->max_x+z*d3_l->max_x*d3_l->max_y);
691     sum=sum*255/max;
692     memset(buf,(unsigned char)sum,3);
693     if(write(fd,buf,3)<3)
694     {
695      puts("failed writing rgb values to bmp file");
696      return-1;
697     }
698    } 
699    if(foo%4)
700    { 
701     memset(buf,0,4-foo%4);
702     if(write(fd,buf,4-foo%4)<4-foo%4)
703     {
704      puts("failed writing 4 byte ending");
705      return -1;
706     }
707    } 
708   }
709  }
710  if(window==7)
711  {
712   for(j=0;j<d3_l->max_z;j++)
713   {
714    for(i=0;i<d3_l->max_x;i++)
715    {
716     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) sum=*(d3_l->extra+i+y*d3_l->max_x+(d3_l->max_z-j-1)*d3_l->max_x*d3_l->max_y);
717     else sum=0;
718     sum=sum*255/max;
719     memset(buf,(unsigned char)sum,3);
720     if(write(fd,buf,3)<3)
721     {
722      puts("failed writing rgb values to bmp file");
723      return-1;
724     }
725    }
726    if(foo%4)
727    {
728     memset(buf,0,4-foo%4);
729     if(write(fd,buf,4-foo%4)<4-foo%4)
730     {
731      puts("failed writing 4 byte ending");
732      return -1;
733     }
734    }
735   }
736  }
737  if(window==8)
738  { 
739   for(j=0;j<d3_l->max_z;j++) 
740   {                     
741    for(i=0;i<d3_l->max_x;i++)
742    {
743     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) sum=*(d3_l->extra+x+i*d3_l->max_x+(d3_l->max_z-j-1)*d3_l->max_x*d3_l->max_y);
744     else sum=0;
745     sum=sum*255/max;
746     memset(buf,(unsigned char)sum,3);
747     if(write(fd,buf,3)<3)
748     {
749      puts("failed writing rgb values to bmp file");
750      return-1;  
751     }
752    }
753    if(foo%4)
754    {
755     memset(buf,0,4-foo%4);
756     if(write(fd,buf,4-foo%4)<4-foo%4)
757     {
758      puts("failed writing 4 byte ending");
759      return -1;
760     }
761    }
762   }
763  }
764  if(window==9)
765  {   
766   for(j=0;j<d3_l->max_y;j++)
767   {  
768    for(i=0;i<d3_l->max_x;i++)
769    {
770     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) sum=*(d3_l->extra+i+(d3_l->max_y-j-1)*d3_l->max_x+z*d3_l->max_x*d3_l->max_y);
771     else sum=0;
772     sum=sum*255/max;
773     memset(buf,(unsigned char)sum,3);
774     if(write(fd,buf,3)<3)
775     {
776      puts("failed writing rgb values to bmp file");
777      return-1;
778     }
779    } 
780    if(foo%4)
781    { 
782     memset(buf,0,4-foo%4);
783     if(write(fd,buf,4-foo%4)<4-foo%4)
784     {
785      puts("failed writing 4 byte ending");
786      return -1;
787     }
788    } 
789   }
790  }
791  if(window==10)
792  {
793   for(j=0;j<d3_l->max_z;j++)
794   {
795    for(i=0;i<d3_l->max_x;i++)
796    {
797     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)) sum=*(d3_l->extra+i+y*d3_l->max_x+(d3_l->max_z-j-1)*d3_l->max_x*d3_l->max_y);
798     else sum=0;
799     sum=sum*255/max;
800     memset(buf,(unsigned char)sum,3);
801     if(write(fd,buf,3)<3)
802     {
803      puts("failed writing rgb values to bmp file");
804      return-1;
805     }
806    }
807    if(foo%4)
808    {
809     memset(buf,0,4-foo%4);
810     if(write(fd,buf,4-foo%4)<4-foo%4)
811     {
812      puts("failed writing 4 byte ending");
813      return -1;
814     }
815    }
816   }
817  }
818  if(window==11)
819  { 
820   for(j=0;j<d3_l->max_z;j++) 
821   {                     
822    for(i=0;i<d3_l->max_x;i++)
823    {
824     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)) sum=*(d3_l->extra+x+i*d3_l->max_x+(d3_l->max_z-j-1)*d3_l->max_x*d3_l->max_y);
825     else sum=0;
826     sum=sum*255/max;
827     memset(buf,(unsigned char)sum,3);
828     if(write(fd,buf,3)<3)
829     {
830      puts("failed writing rgb values to bmp file");
831      return-1;  
832     }
833    }
834    if(foo%4)
835    {
836     memset(buf,0,4-foo%4);
837     if(write(fd,buf,4-foo%4)<4-foo%4)
838     {
839      puts("failed writing 4 byte ending");
840      return -1;
841     }
842    }
843   }
844  }
845  if(window==12)
846  {   
847   for(j=0;j<d3_l->max_y;j++)
848   {  
849    for(i=0;i<d3_l->max_x;i++)
850    {
851     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)) sum=*(d3_l->extra+i+(d3_l->max_y-j-1)*d3_l->max_x+z*d3_l->max_x*d3_l->max_y);
852     else sum=0;
853     sum=sum*255/max;
854     memset(buf,(unsigned char)sum,3);
855     if(write(fd,buf,3)<3)
856     {
857      puts("failed writing rgb values to bmp file");
858      return-1;
859     }
860    } 
861    if(foo%4)
862    { 
863     memset(buf,0,4-foo%4);
864     if(write(fd,buf,4-foo%4)<4-foo%4)
865     {
866      puts("failed writing 4 byte ending");
867      return -1;
868     }
869    }
870   }
871  }
872  close(fd);
873
874  return 1;
875 }
876
877 int save_to_file(char *sf,d3_lattice *d3_l,info *my_inf)
878 {
879  int sf_fd,c;
880
881  if((sf_fd=open(sf,O_WRONLY|O_CREAT))<0)
882  {
883   puts("cannot open save file");
884   return -1;
885  }
886  if(write(sf_fd,d3_l,sizeof(d3_lattice))<sizeof(d3_lattice))
887  {
888   puts("failed saving d3 lattice struct");
889   return -1;
890  }
891  if(write(sf_fd,my_inf,sizeof(info))<sizeof(info))
892  {
893   puts("failed saving info struct");
894   return-1;
895  }
896  c=d3_l->max_x*d3_l->max_y*d3_l->max_z;
897  if(write(sf_fd,d3_l->status,c*sizeof(unsigned char))<c*sizeof(unsigned char))
898  {
899   puts("failed saving status of d3 lattice sites");
900   return -1;
901  }
902  if(write(sf_fd,d3_l->extra,c*sizeof(int))<c*sizeof(int))
903  {
904   puts("failed saving sites concentration");
905   return -1;
906  }
907  close(sf_fd);
908
909  return 1;
910 }
911
912 int load_from_file(char *lf,d3_lattice *d3_l,info *my_inf)
913 {
914
915  int lf_fd,c,pos,end,data,data_len,strip;
916
917  if((lf_fd=open(lf,O_RDONLY))<0)
918  {
919   puts("cannot open load file");
920   return -1;
921  }
922  if(read(lf_fd,d3_l,sizeof(d3_lattice))<sizeof(d3_lattice))
923  {
924   puts("failed reading d3 lattice struct");
925   return -1;
926  }
927  pos=lseek(lf_fd,0,SEEK_CUR);
928  printf("psition: %d (%d)\n",pos,sizeof(d3_lattice));
929  data=d3_l->max_x*d3_l->max_y*d3_l->max_z;
930  data_len=data*(sizeof(int)+sizeof(unsigned char));
931  printf("there are %d volumes so we need %d of bytes\n",data,data_len);
932  end=lseek(lf_fd,0,SEEK_END);
933  c=end-pos-data_len;
934  printf("end: %d => length: %d => guessed info size: %d bytes\n",end,end-pos,c);
935  strip=sizeof(info)-c;
936  printf("as real programs info size is %d, we strip %d bytes\n",sizeof(info),strip);
937  lseek(lf_fd,pos,SEEK_SET);
938  c=sizeof(info);
939  if(strip>0) c-=strip;
940  if(c<0)
941  {
942   puts("info smaller then strip size");
943   return -1;
944  }
945  if(read(lf_fd,my_inf,c)<c)
946  {
947   puts("failed reading info struct");
948   return-1;
949  }
950  if(strip>0) memset(my_inf+c,0,strip);
951  if(strip<0) lseek(lf_fd,(-1*strip),SEEK_CUR);
952  c=d3_l->max_x*d3_l->max_y*d3_l->max_z;
953  if((d3_l->status=(unsigned char*)malloc(c*sizeof(unsigned char)))==NULL)
954  {
955   puts("cannot allocate status buffer");
956   return -1;
957  }
958  if((d3_l->extra=(int *)malloc(c*sizeof(int)))==NULL)
959  {
960   puts("cannot allocate concentration buffer");
961   return -1;
962  }
963  if(read(lf_fd,d3_l->status,c*sizeof(unsigned char))<c*sizeof(unsigned char))
964  {
965   puts("failed reading status of d3 lattice sites");
966   return -1;
967  }
968  if(read(lf_fd,d3_l->extra,c*sizeof(int))<c*sizeof(int))
969  {
970   puts("failed reading sites concentration");
971   return -1;
972  }
973  close(lf_fd);
974
975  return 1;
976 }
977
978 int convert_file(char *cf,d3_lattice *d3_l)
979 {
980 #ifndef MAC
981  int x,y,z;
982  int c_fd;
983
984  if((c_fd=open(cf,O_WRONLY|O_CREAT))<0)
985  {
986   puts("cannot open convert file");
987   return -1;
988  }
989  dprintf(c_fd,"# created by nlsop (gnuplot format)\n");
990  for(x=0;x<d3_l->max_x;x++)
991  {
992   for(y=0;y<d3_l->max_y;y++)
993   {
994    for(z=0;z<d3_l->max_z;z++)
995    {
996     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);
997    }
998   }
999  }
1000  close(c_fd);
1001 #endif
1002
1003  return 1;
1004 }
1005
1006 int get_c_ratio(double *c_ratio,char *pfile,info *my_info,d3_lattice *d3_l)
1007 {
1008  double all,a,b,d;
1009  int i,k;
1010  int p_fd;
1011  unsigned char buf[32];
1012  char *p;
1013  unsigned char c;
1014
1015  if((p_fd=open(pfile,O_RDONLY))<0)
1016  {
1017   puts("cannot open profile file");
1018   return -1;
1019  }
1020  k=1;
1021  d=0;
1022  all=0;
1023  while(k)
1024  {
1025   for(i=0;i<32;i++)
1026   {
1027    k=read(p_fd,&c,1);
1028    buf[i]=c;
1029    if(c=='\n') break;
1030   }
1031   if(k)
1032   {
1033    p=strtok(buf," ");
1034    a=atof(p)/10; /* nm */
1035    p=strtok(NULL," ");
1036    b=atof(p);
1037    if(a<=d3_l->max_z*CELL_LENGTH) d+=b;
1038    all+=b;
1039   }
1040  }
1041  *c_ratio=d/all;
1042  close(p_fd);
1043
1044  return 1;
1045 }
1046
1047 u32 get_reject_graph(info *my_info,d3_lattice *d3_l,char *file,u32 *graph) {
1048  double a,b;
1049  int i,j,k;
1050  int fd;
1051  char buf[32],*p;
1052  unsigned char *flag;
1053  u32 max;
1054
1055  max=0;
1056  if((fd=open(file,O_RDONLY))<0)
1057  {
1058   puts("cannot open file to calculate rejection graph");
1059   return -1;
1060  }
1061  if((flag=(unsigned char *)malloc(d3_l->max_z))==NULL)
1062  {
1063   puts("cannot malloc flag memory for rejection graph");
1064   return -1;
1065  }
1066  memset(flag,0,d3_l->max_z);
1067  memset(graph,0,d3_l->max_z*sizeof(u32));
1068  /* get fixpoints */
1069  k=1;
1070  while(k)
1071  {
1072   for(i=0;i<32;i++)
1073   {
1074    k=read(fd,&buf[i],1);
1075    if((buf[i]=='\n')||(k==0)) break;
1076   }
1077   if(k)
1078   {
1079    p=strtok(buf," ");
1080    a=atof(p)/10; /* nm */
1081    p=strtok(NULL," ");
1082    b=atof(p);
1083    if(a>d3_l->max_z*CELL_LENGTH) k=0;
1084    else 
1085    {
1086     graph[(int)(a/CELL_LENGTH)]=(int)(URAND_MAX/100*b);
1087     flag[(int)(a/CELL_LENGTH)]=1;
1088    }
1089   }
1090  }
1091  /* do (linear) interpolation here! */
1092  i=0;
1093  a=0;
1094  while(i<d3_l->max_z)
1095  {
1096   /* graph[0] is 0! */
1097   j=i;
1098   i++;
1099   while(flag[i]==0&&i<d3_l->max_z) i++;
1100   for(k=j+1;k<i;k++) graph[k]=(int)((k-j)*((int)graph[i]-(int)graph[j])/(i-j))+graph[j];
1101   if(graph[i]>max) max=graph[i];
1102  }
1103
1104  free(flag);
1105
1106 #ifdef DEBUG_INTERPOL_PROFILE
1107  printf("debug: %s (interpolated profile)\n",file);
1108  for(i=0;i<d3_l->max_z;i++) printf("%d %d\n",i,graph[i]);
1109 #endif
1110
1111  return max;
1112 }
1113
1114 int main(int argc,char **argv)
1115 {
1116  u32 x,y,z,x_c,y_c,z_c;
1117  int i,j,quit,escape,switchmode,nowait,bmp,ac_distr;
1118  int refresh,resave;
1119  int c_step;
1120  char s_file[MAX_CHARS];
1121  char s_file_tmp[MAX_CHARS];
1122  char l_file[MAX_CHARS];
1123  char c_file[MAX_CHARS];
1124  char p_file[MAX_CHARS];
1125  char n_e_file[MAX_CHARS];
1126  char convert;
1127  char r_file[MAX_CHARS];
1128 #ifdef USE_DFB_API
1129  char xyz_txt[MAX_TXT];
1130  char status_txt[MAX_TXT];
1131  char conc_txt[MAX_TXT];
1132  char steps_txt[MAX_TXT];
1133  char cc_txt[MAX_TXT];
1134  char a_txt[MAX_TXT];
1135  char s_txt[MAX_TXT];
1136  char ballistic_txt[MAX_TXT];
1137  char carbon_txt[MAX_TXT];
1138  char stress_txt[MAX_TXT];
1139  char r_txt[MAX_TXT];
1140  char zdiff_txt[MAX_TXT];
1141  char diff_txt[MAX_TXT];
1142  char dr_ac_txt[MAX_TXT];
1143  char dr_cc_txt[MAX_TXT];
1144  char dose_txt[MAX_TXT];
1145  char mode_txt[MAX_TXT];
1146  char hpi_txt[MAX_TXT];
1147  char csat_txt[MAX_TXT];
1148  char *arg_v[MAX_ARGV];
1149 #endif
1150  d3_lattice d3_l;
1151  info my_info;
1152  unsigned char mode;
1153  //double c_ratio;
1154 #ifdef USE_DFB_API
1155  int max_extra;
1156 #endif
1157  u32 *c_profile;
1158  u32 *n_e_loss;
1159  u32 ne_max,ip_max;
1160  u32 nel_z;
1161
1162  d3_l.max_x=X;
1163  d3_l.max_y=Y;
1164  d3_l.max_z=Z;
1165  my_info.steps=STEPS;
1166  my_info.range=RANGE;
1167  refresh=REFRESH;
1168  resave=RESAVE;
1169  my_info.z_diff=0;
1170  my_info.c_diff=1;
1171  my_info.s=S_D;
1172  my_info.b=B_D;
1173  my_info.c=C_D;
1174  my_info.cc=CC;
1175  my_info.dr_ac=DR_AC;
1176  my_info.dr_cc=DR_CC;
1177  my_info.diff_rate=DIFF_RATE;
1178  my_info.cpi=CPI;
1179  my_info.s_rate=S_RATE;
1180  nowait=0;
1181  quit=0;
1182  escape=0;
1183  switchmode=0;
1184  c_step=0;
1185  strcpy(s_file,"");
1186  strcpy(l_file,"");
1187  strcpy(c_file,"");
1188  strcpy(p_file,IMP_PROFILE);
1189  strcpy(n_e_file,NEL_PROFILE);
1190  convert=0;
1191  strcpy(r_file,"");
1192  mode=0;
1193  ne_max=0;
1194  ip_max=0;
1195
1196 #ifdef MORE_PRINTF
1197  printf("reading argv ...");
1198 #endif
1199
1200  for(i=1;i<argc;i++)
1201  {
1202   if(argv[i][0]=='-')
1203   {
1204    switch(argv[i][1])
1205    {
1206     case 'h':
1207      usage();
1208      return -1;
1209     case 'n':
1210      nowait=1;
1211      break;
1212     case 'x':
1213      d3_l.max_x=atoi(argv[++i]);
1214      break;
1215     case 'y':
1216      d3_l.max_y=atoi(argv[++i]);
1217      break;
1218     case 'z':
1219      d3_l.max_z=atoi(argv[++i]);
1220      break;
1221     case 'Z':
1222      my_info.z_diff=1;
1223      break;
1224     case 'i':
1225      my_info.c_diff=0;
1226      my_info.dr_cc=0;
1227      break;
1228     case 's':
1229      my_info.steps=atoi(argv[++i]);
1230      break;
1231     case 'd':
1232      refresh=atoi(argv[++i]);
1233      break;
1234     case 'r':
1235      my_info.range=atoi(argv[++i]);
1236      break;
1237     case 'f':
1238      my_info.s=atof(argv[++i]);
1239      break;
1240     case 'p':
1241      my_info.b=atof(argv[++i]);
1242      break;
1243     case 'F':
1244      my_info.c=atof(argv[++i]);
1245      break;
1246     case 'W':
1247      resave=atoi(argv[++i]);
1248      break;
1249     case 'C':
1250      strcpy(l_file,argv[++i]);
1251      if(i<argc-1) if(argv[i+1][0]!='-') strcpy(c_file,argv[++i]);
1252      convert=1;
1253      break;
1254     case 'D':
1255      my_info.dr_ac=atof(argv[++i]);
1256      break;
1257     case 'c':
1258      my_info.dr_cc=atof(argv[++i]);
1259      break;
1260     case 'e':
1261      my_info.diff_rate=atoi(argv[++i]);
1262      break;
1263     case 'L':
1264      strcpy(l_file,argv[++i]);
1265      break;
1266     case 'S':
1267      strcpy(s_file,argv[++i]);
1268      break;
1269     case 'R':
1270      strcpy(r_file,argv[++i]);
1271      break;
1272     case 'P':
1273      strcpy(p_file,argv[++i]);
1274      break;
1275     case 'N':
1276      strcpy(n_e_file,argv[++i]);
1277      break;
1278     case 'g':
1279      strcpy(l_file,argv[++i]);
1280      if(i<argc-1) if(argv[i+1][0]!='-') c_step=atoi(argv[++i]);
1281      break;
1282     case 'H':
1283      my_info.cpi=atoi(argv[++i]);
1284      break;
1285     case 'm':
1286      my_info.s_rate=atoi(argv[++i]);
1287      break;
1288     default:
1289      usage();
1290      return -1;
1291    }
1292   } else usage();
1293  }
1294
1295 #ifdef MORE_PRINTF
1296  printf(" done\n");
1297 #endif
1298
1299  x=d3_l.max_x/2-1;
1300  y=d3_l.max_y/2-1;
1301  z=d3_l.max_z/2-1;
1302
1303 #ifdef NODFB
1304  if(!strcmp(s_file,""))
1305  {
1306   puts("NODFB defined, run with -S option");
1307   return -1;
1308  }
1309 #endif
1310
1311 #ifdef MORE_PRINTF
1312  printf("rand init ...");
1313 #endif
1314
1315  if(!strcmp(r_file,"")) rand_init(NULL);
1316  else rand_init(r_file);
1317
1318 #ifdef MORE_PRINTF
1319  printf(" done\n");
1320  printf("allocating data ...");
1321 #endif
1322
1323  if(!strcmp(l_file,""))
1324  {
1325   i=d3_l.max_x*d3_l.max_y*d3_l.max_z;
1326 #ifdef USE_DFB_API
1327   d3_lattice_init(&argc,argv,&d3_l);
1328 #endif
1329   if((d3_l.status=(unsigned char *)malloc(i*sizeof(unsigned char)))==NULL)
1330   {
1331    puts("failed allocating status buffer");
1332    return -1;
1333   }
1334   memset(d3_l.status,0,i*sizeof(unsigned char));
1335   if((d3_l.extra=(int *)malloc(i*sizeof(int)))==NULL)
1336   {
1337    puts("failed allocating concentration buffer");
1338    return -1;
1339   }
1340   memset(d3_l.extra,0,i*sizeof(int));
1341  } else
1342  {
1343   load_from_file(l_file,&d3_l,&my_info);
1344   if(convert) 
1345   {   
1346    if(!strcmp(c_file,"")) sprintf(c_file,"%s_gnuplot",l_file);
1347    printf("converting file %s to %s\n",l_file,c_file);
1348    convert_file(c_file,&d3_l);
1349    puts("done");
1350    return 1;
1351   }
1352 #ifdef USE_DFB_API
1353   else d3_lattice_init(&argc,argv,&d3_l);
1354 #endif
1355  }
1356
1357 #ifdef MORE_PRINTF
1358  printf(" done\n");
1359 #endif
1360
1361 #ifdef USE_DFB_API
1362  d3_event_init(&d3_l);
1363 #endif
1364
1365 #ifdef USE_DFB_API
1366  strcpy(a_txt,"args:");
1367  sprintf(s_txt,"steps: %d",my_info.steps);
1368  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));
1369  sprintf(r_txt,"pressure range: %d",my_info.range);
1370  sprintf(stress_txt,"stress term: %f",my_info.s);
1371  sprintf(ballistic_txt,"ballistic term: %f",my_info.b);
1372  sprintf(carbon_txt,"carbon term: %f",my_info.c);
1373  sprintf(dr_ac_txt,"a/c diffusion rate: %f",my_info.dr_ac);
1374  if(my_info.c_diff!=0) sprintf(dr_cc_txt,"c/c diffusion rate: %f",my_info.dr_cc);
1375  else sprintf(dr_cc_txt,"c/c diffusion rate: none");
1376  sprintf(zdiff_txt,"diffusion in z direction: %c",my_info.z_diff?'y':'n');
1377  sprintf(diff_txt,"diffusion every %d steps",my_info.diff_rate);
1378  strcpy(mode_txt,"view: a/c mode");
1379  sprintf(hpi_txt,"hits per ion: %d",my_info.cpi);
1380  sprintf(csat_txt,"sputter rate (3nm/#c): %d",my_info.s_rate);
1381  arg_v[1]=mode_txt;
1382  arg_v[2]=xyz_txt;
1383  arg_v[3]=status_txt;
1384  arg_v[4]=conc_txt;
1385  arg_v[5]=NULL;
1386  arg_v[6]=steps_txt;
1387  arg_v[7]=cc_txt;
1388  arg_v[8]=NULL;
1389  arg_v[9]=a_txt;
1390  arg_v[10]=s_txt;
1391  arg_v[11]=dose_txt;
1392  arg_v[12]=diff_txt;
1393  arg_v[13]=zdiff_txt;
1394  arg_v[14]=r_txt;
1395  arg_v[15]=ballistic_txt;
1396  arg_v[16]=carbon_txt;
1397  arg_v[17]=stress_txt;
1398  arg_v[18]=dr_ac_txt;
1399  arg_v[19]=dr_cc_txt;
1400  arg_v[20]=hpi_txt;
1401  arg_v[21]=csat_txt;
1402  arg_v[22]=NULL;
1403  arg_v[23]=NULL;
1404  arg_v[24]=NULL;
1405  arg_v[25]=NULL;
1406 #endif
1407
1408 #ifdef MORE_PRINTF
1409  printf("random rejection graphs ...");
1410 #endif
1411
1412  /* compute graphs for random number rejection method */
1413  if((c_profile=(u32 *)malloc(d3_l.max_z*sizeof(unsigned int)))==NULL)
1414  {
1415   puts("failed allocating memory for carbon profile graph");
1416   return -1;
1417  }
1418  if((n_e_loss=(u32 *)malloc(d3_l.max_z*sizeof(unsigned int)))==NULL)
1419  {
1420   puts("failed allocating memory for nuclear energy loss graph");
1421   return -1;
1422  }
1423  ip_max=get_reject_graph(&my_info,&d3_l,p_file,c_profile);
1424  ne_max=get_reject_graph(&my_info,&d3_l,n_e_file,n_e_loss);
1425
1426 #ifdef MORE_PRINTF
1427  printf(" done\n");
1428 #endif
1429
1430
1431  if((!strcmp(l_file,""))||(c_step))
1432  {
1433
1434   /* this should be obsolete - z is high enough - we check now! */
1435   if(c_profile[d3_l.max_z-1]!=0)
1436   {
1437    printf("max_z (%d) too small - sputtering not possible\n",d3_l.max_z);
1438    return -1;
1439   }
1440   /* calculate ratio of c_simwindow / c_total */
1441   //if(get_c_ratio(&c_ratio,p_file,&my_info,&d3_l)!=1)
1442   //{
1443   // puts("failed calculating ratio");
1444   // return -1;
1445   //}
1446
1447   /* sputtering realy possible ?*/
1448   if(n_e_loss[d3_l.max_z-1]!=0)
1449    printf("warning: max_z (%d) too small - there may be amorphous volumes\n",d3_l.max_z);
1450
1451 #ifdef DEBUG_RAND
1452  i=0;
1453  while(1)
1454  {
1455 #ifdef DEBUG_CP
1456   printf("%d\n",get_rand_reject(d3_l.max_z,ip_max,c_profile));
1457 #endif
1458 #ifdef DEBUG_NEL
1459   printf("%d\n",get_rand_reject(d3_l.max_z,ne_max,n_e_loss));
1460 #endif
1461 #ifdef DEBUG_NORM
1462   printf("%d\n",get_rand(d3_l.max_z));
1463 #endif
1464  if(i==10000000) return 1;
1465  i++;
1466  }
1467 #endif
1468
1469 #ifdef MORE_PRINTF
1470   printf("starting simulation ... now! :)\n");
1471 #endif
1472
1473   i=(c_step?c_step:0);
1474   while((i<my_info.steps) && (quit==0) && (escape==0))
1475   {
1476 #ifdef MORE_PRINTF
1477    if(i%refresh==0) printf("step: %d\n",i);
1478 #endif
1479    for(j=0;j<my_info.cpi;j++)
1480    {
1481     x_c=get_rand(d3_l.max_x);
1482     y_c=get_rand(d3_l.max_y);
1483     // z_c=get_rand_reject(d3_l.max_z,ne_max,n_e_loss);
1484     z_c=get_rand(d3_l.max_z);
1485     nel_z=URAND_MAX*(1.0*n_e_loss[z_c]/ne_max);
1486     process_cell(&d3_l,x_c,y_c,z_c,&my_info,nel_z);
1487    }
1488    distrib_c(&d3_l,&my_info,i,ip_max,c_profile);
1489 #ifdef USE_DFB_API
1490    if(i%refresh==0)
1491    {
1492     sprintf(xyz_txt,"x: %d  y: %d  z: %d",x+1,y+1,z+1);
1493     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');
1494     sprintf(conc_txt,"conc: %d",*(d3_l.extra+x+y*d3_l.max_x+z*d3_l.max_x*d3_l.max_y));
1495     sprintf(steps_txt,"step: %d",i);
1496     sprintf(cc_txt,"total c: %d",my_info.cc);
1497     d3_lattice_draw(&d3_l,x,y,z,25,arg_v,mode,0,NULL,0,NULL,0);
1498    }
1499 #endif
1500    if(i%resave==0 && strcmp(s_file,"") && resave!=0 && i!=0)
1501    {
1502     sprintf(s_file_tmp,"%s_%d_of_%d",s_file,i,my_info.steps);
1503     save_to_file(s_file_tmp,&d3_l,&my_info);
1504 #ifdef NODFB
1505     printf("saved %s\n",s_file_tmp);
1506 #endif
1507    }
1508    i++;
1509    if(i%my_info.s_rate==0) sputter(&d3_l);
1510   }
1511  }
1512
1513  if(strcmp(s_file,""))
1514  {
1515    printf("saved %s\n",s_file);
1516    save_to_file(s_file,&d3_l,&my_info);
1517  }
1518
1519 #ifdef USE_DFB_API
1520  /* allocating buffer for pressure values */
1521  if((d3_l.v_ptr=malloc(d3_l.max_x*d3_l.max_y*d3_l.max_z*sizeof(unsigned char)))==NULL)
1522  {
1523   puts("cannot allocate buffer for pressure values");
1524   return -1;
1525  }
1526  /* calc values */
1527  calc_pressure(&d3_l,my_info.range);
1528  max_extra=calc_max_extra(&d3_l);
1529
1530  while((quit==0) && (escape==0) && (nowait==0))
1531  {
1532   /* bahh! */
1533   if(switchmode==0) mode=0;
1534   if(switchmode==1) mode=1;
1535   if(switchmode==2) mode=2;
1536   if(switchmode==3) mode=3;
1537   /* end of bahh! */
1538   sprintf(xyz_txt,"x: %d  y: %d  z: %d",x+1,y+1,z+1);
1539   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');
1540   sprintf(conc_txt,"conc: %d",*(d3_l.extra+x+y*d3_l.max_x+z*d3_l.max_x*d3_l.max_y));
1541   sprintf(steps_txt,"step: end");
1542   sprintf(cc_txt,"total c: %d",my_info.cc);
1543   if(switchmode==0) strcpy(mode_txt,"view: a/c mode");
1544   if(switchmode==1) strcpy(mode_txt,"view: c conc mode");
1545   if(switchmode==2) strcpy(mode_txt,"view: a pressure mode");
1546   if(switchmode==3) strcpy(mode_txt,"view: a/c + profiles mode");
1547   d3_lattice_draw(&d3_l,x,y,z,25,arg_v,mode,max_extra,c_profile,ip_max,n_e_loss,ne_max);
1548   bmp=0;
1549   ac_distr=0;
1550   scan_event(&d3_l,&x,&y,&z,&quit,&escape,&switchmode,&bmp,&ac_distr);
1551   if(bmp) write_bmp(&d3_l,bmp,x,y,z,max_extra);
1552   if(ac_distr) write_ac_distr(&d3_l,ac_distr);
1553  }
1554
1555  d3_lattice_release(&d3_l);
1556 #endif
1557
1558  return 1;
1559 }