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