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