added position insertion method + fixed positioning
[physik/posic.git] / mdrun.c
1 /*
2  * mdrun.c - main code to run a md simulation
3  *
4  * author: Frank Zirkelbach <frank.zirkelbach@physik.uni-augsburg.de>
5  *
6  */
7
8 #include "mdrun.h"
9
10 /* potential */
11 #include "potentials/harmonic_oscillator.h"
12 #include "potentials/lennard_jones.h"
13 #include "potentials/albe.h"
14 #ifdef TERSOFF_ORIG
15 #include "potentials/tersoff_orig.h"
16 #else
17 #include "potentials/tersoff.h"
18 #endif
19
20 #define ME      "[mdrun]"
21
22 /*
23  * parse function
24  */
25
26 int mdrun_usage(void) {
27
28         printf("%s usage:\n",ME);
29
30         return 0;
31 }
32
33 int mdrun_parse_argv(t_mdrun *mdrun,int argc,char **argv) {
34
35         int i;
36
37         for(i=1;i<argc;i++) {
38
39                 if(argv[i][0]!='-') {
40                         printf("%s unknown switch: %s\n",ME,argv[i]);
41                         return -1;
42                 }
43
44                 switch(argv[i][1]) {
45                         case 'c':
46                                 strncpy(mdrun->cfile,argv[++i],128);
47                                 break;
48                         case 's':
49                                 strncpy(mdrun->sdir,argv[++i],128);
50                                 break;
51                         case 'h':
52                                 mdrun_usage();
53                                 break;
54                         default:
55                                 printf("%s unknown option: %s\n",ME,argv[i]);
56                                 mdrun_usage();
57                                 return -1;
58                 }
59
60         }
61
62         return 0;
63 }
64
65 int del_stages(t_mdrun *mdrun) {
66
67         t_list *sl;
68         t_stage *stage;
69
70         sl=&(mdrun->stage);
71
72         list_reset_f(sl);
73
74         if(sl->start==NULL)
75                 return 0;
76
77         do {
78                 stage=sl->current->data;
79                 free(stage->params);
80                 free(stage);
81         } while(list_next_f(sl)!=L_NO_NEXT_ELEMENT);
82
83         return 0;
84 }
85
86 int add_stage(t_mdrun *mdrun,u8 type,void *params) {
87
88         int psize;
89
90         t_stage *stage;
91
92         switch(type) {
93                 case STAGE_INSERT_ATOMS:
94                         psize=sizeof(t_insert_atoms_params);
95                         break;
96                 case STAGE_CONTINUE:
97                         psize=sizeof(t_continue_params);
98                         break;
99                 case STAGE_ANNEAL:
100                         psize=sizeof(t_anneal_params);
101                         break;
102                 case STAGE_CHAATTR:
103                         psize=sizeof(t_chaattr_params);
104                         break;
105                 case STAGE_CHSATTR:
106                         psize=sizeof(t_chsattr_params);
107                         break;
108                 default:
109                         printf("%s unknown stage type: %02x\n",ME,type);
110                         return -1;
111         }
112
113         stage=malloc(sizeof(t_stage));
114         if(stage==NULL) {
115                 perror("[mdrun] malloc (add stage)");
116                 return -1;
117         }
118
119         stage->type=type;
120         stage->executed=FALSE;
121
122         stage->params=malloc(psize);
123         if(stage->params==NULL) {
124                 perror("[mdrun] malloc (stage params)");
125                 return -1;
126         }
127
128         memcpy(stage->params,params,psize);
129
130         list_add_immediate_f(&(mdrun->stage),stage);
131
132         return 0;
133 }
134
135 int mdrun_parse_config(t_mdrun *mdrun) {
136
137         int fd,ret;
138         char error[128];
139         char line[128];
140         char *wptr;
141         char word[16][32];
142         int wcnt;
143         int i,o;
144
145         t_insert_atoms_params iap;
146         t_continue_params cp;
147         t_anneal_params ap;
148         t_chaattr_params cap;
149         t_chsattr_params csp;
150
151         /* open config file */
152         fd=open(mdrun->cfile,O_RDONLY);
153         if(fd<0) {
154                 snprintf(error,128,"%s open cfile %s",ME,mdrun->cfile);
155                 perror(error);
156                 return fd;
157         }
158
159         /* read, parse, set */
160         ret=1;
161         while(ret>0) {
162
163                 /* read */
164                 ret=get_line(fd,line,128);
165
166                 /* parse */
167
168                 // ignore # lines and \n
169                 if((line[0]=='#')|(ret==1))
170                         continue;
171
172                 // reset
173                 memset(&iap,0,sizeof(t_insert_atoms_params));
174                 memset(&cp,0,sizeof(t_continue_params));
175                 memset(&ap,0,sizeof(t_anneal_params));
176                 memset(&cap,0,sizeof(t_chaattr_params));
177                 memset(&csp,0,sizeof(t_chsattr_params));
178
179                 // get command + args
180                 wcnt=0;
181                 while(1) {
182                         if(wcnt)
183                                 wptr=strtok(NULL," \t");
184                         else
185                                 wptr=strtok(line," \t");
186                         if(wptr==NULL)
187                                 break;
188                         strncpy(word[wcnt],wptr,32);
189                         wcnt+=1;
190                 }
191
192                 if(!strncmp(word[0],"potential",9)) {
193                         if(!strncmp(word[1],"albe",4))
194                                 mdrun->potential=MOLDYN_POTENTIAL_AM;
195                         if(!strncmp(word[1],"tersoff",7))
196                                 mdrun->potential=MOLDYN_POTENTIAL_TM;
197                         if(!strncmp(word[1],"ho",2))
198                                 mdrun->potential=MOLDYN_POTENTIAL_HO;
199                         if(!strncmp(word[1],"lj",2))
200                                 mdrun->potential=MOLDYN_POTENTIAL_LJ;
201                 }
202                 else if(!strncmp(word[0],"cutoff",6))
203                         mdrun->cutoff=atof(word[1]);
204                 else if(!strncmp(word[0],"nnd",3))
205                         mdrun->nnd=atof(word[1]);
206                 else if(!strncmp(word[0],"intalgo",7)) {
207                         if(!strncmp(word[1],"verlet",5))
208                                 mdrun->intalgo=MOLDYN_INTEGRATE_VERLET;
209                 }
210                 else if(!strncmp(word[0],"timestep",8))
211                         mdrun->timestep=atof(word[1]);
212                 else if(!strncmp(word[0],"volume",6)) {
213                         mdrun->dim.x=atof(word[1]);
214                         mdrun->dim.y=atof(word[2]);
215                         mdrun->dim.z=atof(word[3]);
216                         if(strncmp(word[4],"0",1))
217                                 mdrun->vis=TRUE;
218                 }
219                 else if(!strncmp(word[0],"pbc",3)) {
220                         if(strncmp(word[1],"0",1))
221                                 mdrun->pbcx=TRUE;
222                         else
223                                 mdrun->pbcx=FALSE;
224                         if(strncmp(word[2],"0",1))
225                                 mdrun->pbcy=TRUE;
226                         else
227                                 mdrun->pbcy=FALSE;
228                         if(strncmp(word[3],"0",1))
229                                 mdrun->pbcz=TRUE;
230                         else
231                                 mdrun->pbcz=FALSE;
232                 }
233                 else if(!strncmp(word[0],"temperature",11))
234                         mdrun->temperature=atof(word[1]);
235                 else if(!strncmp(word[0],"pressure",8))
236                         mdrun->pressure=atof(word[1]);
237                 else if(!strncmp(word[0],"lattice",7)) {
238                         if(!strncmp(word[1],"zincblende",10))
239                                 mdrun->lattice=ZINCBLENDE;
240                         if(!strncmp(word[1],"fcc",3))
241                                 mdrun->lattice=FCC;
242                         if(!strncmp(word[1],"diamond",7))
243                                 mdrun->lattice=DIAMOND;
244                 }
245                 else if(!strncmp(word[0],"element1",8)) {
246                         mdrun->element1=atoi(word[1]);
247                         mdrun->m1=pse_mass[mdrun->element1];
248                 }
249                 else if(!strncmp(word[0],"element2",8)) {
250                         mdrun->element2=atoi(word[1]);
251                         mdrun->m2=pse_mass[mdrun->element2];
252                 }
253                 else if(!strncmp(word[0],"fill",6)) {
254                         // only lc mode by now
255                         mdrun->lx=atoi(word[2]);
256                         mdrun->ly=atoi(word[3]);
257                         mdrun->lz=atoi(word[4]);
258                         mdrun->lc=atof(word[5]);
259                 }
260                 else if(!strncmp(word[0],"aattr",5)) {
261                         // for aatrib line we need a special stage
262                         // containing one schedule of 0 loops ...
263                         for(i=0;i<strlen(word[1]);i++) {
264                                 switch(word[1][i]) {
265                                         case 't':
266                                                 cap.type|=CHAATTR_TOTALV;
267                                                 break;
268                                         case 'r':
269                                                 cap.type|=CHAATTR_REGION;
270                                                 break;
271                                         case 'e':
272                                                 cap.type|=CHAATTR_ELEMENT;
273                                                 break;
274                                         default:
275                                                 break;
276                                 }
277                         }
278                         i=2;
279                         if(cap.type&CHAATTR_REGION) {
280                                 cap.x0=atof(word[1]);   
281                                 cap.y0=atof(word[2]);   
282                                 cap.z0=atof(word[3]);   
283                                 cap.x1=atof(word[4]);   
284                                 cap.y1=atof(word[5]);   
285                                 cap.z1=atof(word[6]);
286                                 i+=6;
287                         }
288                         if(cap.type&CHAATTR_ELEMENT) {
289                                 cap.element=atoi(word[i]);
290                                 i+=1;
291                         }
292                         for(o=0;o<strlen(word[i]);o++) {
293                                 switch(word[i][o]) {
294                                         case 'b':
295                                                 cap.attr|=ATOM_ATTR_VB;
296                                                 break;
297                                         case 'h':
298                                                 cap.attr|=ATOM_ATTR_HB;
299                                                 break;
300                                         case 'v':
301                                                 cap.attr|=ATOM_ATTR_VA;
302                                                 break;
303                                         case 'f':
304                                                 cap.attr|=ATOM_ATTR_FP;
305                                                 break;
306                                         case '1':
307                                                 cap.attr|=ATOM_ATTR_1BP;
308                                                 break;
309                                         case '2':
310                                                 cap.attr|=ATOM_ATTR_2BP;
311                                                 break;
312                                         case '3':
313                                                 cap.attr|=ATOM_ATTR_3BP;
314                                                 break;
315                                         default:
316                                                 break;
317                                 }
318                         }
319                         add_stage(mdrun,STAGE_CHAATTR,&cap);
320                 }
321                 else if(!strncmp(word[0],"sattr",5)) {
322                         // for satrib line we need a special stage
323                         // containing one schedule of 0 loops ...
324                         csp.type=0;
325                         for(i=1;i<wcnt;i++) {
326                                 if(!strncmp(word[i],"pctrl",5)) {
327                                         csp.ptau=0.01/(atof(word[++i])*GPA);
328                                         csp.type|=CHSATTR_PCTRL;
329                                 }
330                                 if(!strncmp(word[i],"tctrl",5)) {
331                                         csp.ttau=atof(word[++i]);
332                                         csp.type|=CHSATTR_TCTRL;
333                                 }
334                                 if(!strncmp(word[i],"prelax",6)) {
335                                         csp.dp=atof(word[++i])*BAR;
336                                         csp.type|=CHSATTR_PRELAX;
337                                 }
338                                 if(!strncmp(word[i],"trelax",6)) {
339                                         csp.dt=atof(word[++i]);
340                                         csp.type|=CHSATTR_TRELAX;
341                                 }
342                                 if(!strncmp(word[i],"rsteps",6)) {
343                                         csp.rsteps=atoi(word[++i]);
344                                         csp.type|=CHSATTR_RSTEPS;
345                                 }
346                                 if(!strncmp(word[i],"avgrst",6)) {
347                                         csp.avgrst=atoi(word[++i]);
348                                         csp.type|=CHSATTR_AVGRST;
349                                 }
350                         }
351                         add_stage(mdrun,STAGE_CHSATTR,&csp);
352                 }
353                 else if(!strncmp(word[0],"prerun",6))
354                         mdrun->prerun=atoi(word[1]);
355                 else if(!strncmp(word[0],"avgskip",7))
356                         mdrun->avgskip=atoi(word[1]);
357                 else if(!strncmp(word[0],"elog",4))
358                         mdrun->elog=atoi(word[1]);
359                 else if(!strncmp(word[0],"tlog",4))
360                         mdrun->tlog=atoi(word[1]);
361                 else if(!strncmp(word[0],"plog",4))
362                         mdrun->plog=atoi(word[1]);
363                 else if(!strncmp(word[0],"vlog",4))
364                         mdrun->vlog=atoi(word[1]);
365                 else if(!strncmp(word[0],"save",4))
366                         mdrun->save=atoi(word[1]);
367                 else if(!strncmp(word[0],"visualize",9))
368                         mdrun->visualize=atoi(word[1]);
369                 else if(!strncmp(word[0],"stage",5)) {
370                         // for every stage line, add a stage
371                         if(!strncmp(word[1],"ins_atoms",9)) {
372                                 iap.ins_steps=atoi(word[2]);
373                                 iap.ins_atoms=atoi(word[3]);
374                                 iap.element=atoi(word[4]);
375                                 iap.brand=atoi(word[5]);
376                                 for(i=0;i<strlen(word[6]);i++) {
377                                         switch(word[6][i]) {
378                                                 case 'b':
379                                                         iap.attr|=ATOM_ATTR_VB;
380                                                         break;
381                                                 case 'h':
382                                                         iap.attr|=ATOM_ATTR_HB;
383                                                         break;
384                                                 case 'v':
385                                                         iap.attr|=ATOM_ATTR_VA;
386                                                         break;
387                                                 case 'f':
388                                                         iap.attr|=ATOM_ATTR_FP;
389                                                         break;
390                                                 case '1':
391                                                         iap.attr|=ATOM_ATTR_1BP;
392                                                         break;
393                                                 case '2':
394                                                         iap.attr|=ATOM_ATTR_2BP;
395                                                         break;
396                                                 case '3':
397                                                         iap.attr|=ATOM_ATTR_3BP;
398                                                         break;
399                                                 default:
400                                                         break;
401                                         }
402                                 }
403                                 switch(word[7][0]) {
404                                         // insertion types
405                                         case 'p':
406                                                 iap.type=INS_POS;
407                                                 iap.x0=atof(word[8]);
408                                                 iap.y0=atof(word[9]);
409                                                 iap.z0=atof(word[10]);
410                                                 break;
411                                         case 'r':
412                                                 if(word[8][0]=='t') {
413                                                         iap.type=INS_TOTAL;
414                                                         iap.cr=atof(word[9]);
415                                                 }
416                                                 else {
417                                                         iap.type=INS_REGION;
418                                                         iap.x0=atof(word[8]);
419                                                         iap.y0=atof(word[9]);
420                                                         iap.z0=atof(word[10]);
421                                                         iap.x1=atof(word[11]);
422                                                         iap.y1=atof(word[12]);
423                                                         iap.z1=atof(word[13]);
424                                                         iap.cr=atof(word[14]);
425                                                 }
426                                         default:
427                                                 break;
428                                 }
429                                 add_stage(mdrun,STAGE_INSERT_ATOMS,&iap);
430                         }
431                         else if(!strncmp(word[1],"continue",8)) {
432                                 cp.runs=atoi(word[2]);
433                                 add_stage(mdrun,STAGE_CONTINUE,&cp);
434                         }
435                         else if(!strncmp(word[1],"anneal",6)) {
436                                 ap.count=0;
437                                 ap.runs=atoi(word[2]);
438                                 ap.dt=atof(word[3]);
439                                 add_stage(mdrun,STAGE_ANNEAL,&ap);
440                         }
441                         else {
442                                 printf("%s unknown stage type: %s\n",
443                                        ME,word[1]);
444                                 return -1;
445                         }
446                 }
447                 else {
448                         printf("%s unknown keyword '%s', skipped!\n",
449                                ME,word[0]);
450                         continue;
451                 }
452         }
453
454         /* close file */
455         close(fd);
456
457         return 0;
458 }
459
460 int check_pressure(t_moldyn *moldyn,t_mdrun *mdrun) {
461
462         double delta;
463
464         if(!(mdrun->sattr&SATTR_PRELAX)) {
465                 return TRUE;
466         }
467
468         delta=moldyn->p_avg-moldyn->p_ref;
469
470         if(delta<0)
471                 delta=-delta;
472
473         if(delta>mdrun->dp)
474                 return FALSE;
475
476         return TRUE;
477 }
478
479 int check_temperature(t_moldyn *moldyn,t_mdrun *mdrun) {
480
481         double delta;
482
483         if(!(mdrun->sattr&SATTR_TRELAX))
484                 return TRUE;
485
486         delta=moldyn->t_avg-moldyn->t_ref;
487
488         if(delta<0)
489                 delta=-delta;
490
491         if(delta>mdrun->dt)
492                 return FALSE;
493
494         return TRUE;
495 }
496
497 int insert_atoms(t_moldyn *moldyn,t_mdrun *mdrun) {
498
499         t_insert_atoms_params *iap;
500         t_stage *stage;
501         t_atom *atom;
502         t_3dvec r,v,dist;
503         double d,dmin,o;
504         int cnt,i;
505         double x,y,z;
506         double x0,y0,z0;
507         u8 cr_check,run;
508         
509         stage=mdrun->stage.current->data;
510         iap=stage->params;
511
512         cr_check=FALSE;
513
514         v.x=0.0; v.y=0.0; v.z=0.0;
515         x=0; y=0; z=0;
516         o=0; dmin=0;
517
518         switch(mdrun->lattice) {
519                 case CUBIC:
520                         o=0.5*mdrun->lc;
521                         break;
522                 case FCC:
523                         o=0.25*mdrun->lc;
524                         break;
525                 case DIAMOND:
526                 case ZINCBLENDE:
527                         o=0.125*mdrun->lc;
528                         break;
529                 default:
530                         break;
531         }
532
533         switch(iap->type) {
534                 case INS_TOTAL:
535                         x=moldyn->dim.x;
536                         x0=-x/2.0;
537                         y=moldyn->dim.y;
538                         y0=-y/2.0;
539                         z=moldyn->dim.z;
540                         z0=-z/2.0;
541                         cr_check=TRUE;
542                         break;
543                 case INS_REGION:
544                         x=iap->x1-iap->x0;
545                         x0=iap->x0;
546                         y=iap->y1-iap->y0;
547                         y0=iap->y0;
548                         z=iap->z1-iap->z0;
549                         z0=iap->z0;
550                         cr_check=TRUE;
551                         break;
552                 case INS_POS:
553                         x0=iap->x0;
554                         y0=iap->y0;
555                         z0=iap->z0;
556                         cr_check=FALSE;
557                         break;
558                 default:
559                         printf("%s unknown insertion mode: %02x\n",
560                                ME,iap->type);
561                         return -1;
562         }
563
564         cnt=0;
565         while(cnt<iap->ins_atoms) {
566                 run=1;
567                 while(run) {
568                         if(iap->type!=INS_POS) {
569                                 r.x=rand_get_double(&(moldyn->random))*x;
570                                 r.y=rand_get_double(&(moldyn->random))*y;
571                                 r.z=rand_get_double(&(moldyn->random))*z;
572                         }
573                         else {
574                                 r.x=0.0;
575                                 r.y=0.0;
576                                 r.z=0.0;
577                         }
578                         r.x+=x0;
579                         r.y+=y0;
580                         r.z+=z0;
581                         // offset
582                         if(iap->type!=INS_TOTAL) {
583                                 r.x+=o;
584                                 r.y+=o;
585                                 r.z+=o;
586                         }
587                         run=0;
588                         if(cr_check==TRUE) {
589                                 dmin=1000;      // for sure too high!
590                                 for(i=0;i<moldyn->count;i++) {
591                                         atom=&(moldyn->atom[i]);
592                                         v3_sub(&dist,&(atom->r),&r);
593                                         check_per_bound(moldyn,&dist);
594                                         d=v3_absolute_square(&dist);
595                                         if(d<(iap->cr*iap->cr)) {
596                                                 run=1;
597                                                 break;
598                                         }
599                                         if(d<dmin)
600                                                 dmin=d;
601                                 }
602                         }
603                 }
604                 add_atom(moldyn,iap->element,pse_mass[iap->element],
605                          iap->brand,iap->attr,&r,&v);
606                 printf("%s atom inserted (%d/%d): %f %f %f\n",
607                        ME,(iap->cnt_steps+1)*iap->ins_atoms,
608                        iap->ins_steps*iap->ins_atoms,r.x,r.y,r.z);
609                 printf("  -> d2 = %f/%f\n",dmin,iap->cr*iap->cr);
610                 cnt+=1;
611         }
612
613         return 0;
614 }
615
616 int chaatr(t_moldyn *moldyn,t_mdrun *mdrun) {
617
618         t_stage *stage;
619         t_chaattr_params *cap;
620         t_atom *atom;
621         int i;
622
623         stage=mdrun->stage.current->data;
624         cap=stage->params;
625
626         for(i=0;i<moldyn->count;i++) {
627                 atom=&(moldyn->atom[i]);
628                 if(cap->type&CHAATTR_ELEMENT) {
629                         if(cap->element!=atom->element)
630                                 continue;
631                 }
632                 if(cap->type&CHAATTR_REGION) {
633                         if(cap->x0<atom->r.x)
634                                 continue;
635                         if(cap->y0<atom->r.y)
636                                 continue;
637                         if(cap->z0<atom->r.z)
638                                 continue;
639                         if(cap->x1>atom->r.x)
640                                 continue;
641                         if(cap->y1>atom->r.y)
642                                 continue;
643                         if(cap->z1>atom->r.z)
644                                 continue;
645                 }
646                 atom->attr=cap->attr;
647         }
648
649         return 0;
650 }
651
652 int chsattr(t_moldyn *moldyn,t_mdrun *mdrun) {
653
654         t_stage *stage;
655         t_chsattr_params *csp;
656
657         stage=mdrun->stage.current->data;
658         csp=stage->params;
659
660         if(csp->type&CHSATTR_PCTRL) {
661                 if(csp->ptau>0)
662                         set_p_scale(moldyn,P_SCALE_BERENDSEN,csp->ptau);
663                 else
664                         set_p_scale(moldyn,P_SCALE_BERENDSEN,csp->ptau);
665         }
666         if(csp->type&CHSATTR_TCTRL) {
667                 if(csp->ttau>0)
668                         set_t_scale(moldyn,T_SCALE_BERENDSEN,csp->ttau);
669                 else
670                         set_t_scale(moldyn,T_SCALE_BERENDSEN,csp->ttau);
671         }
672         if(csp->type&CHSATTR_PRELAX) {
673                 if(csp->dp<0)
674                         mdrun->sattr&=(~(SATTR_PRELAX));
675                 else
676                         mdrun->sattr|=SATTR_PRELAX;
677                 mdrun->dp=csp->dp;
678         }
679         if(csp->type&CHSATTR_TRELAX) {
680                 if(csp->dt<0)
681                         mdrun->sattr&=(~(SATTR_TRELAX));
682                 else
683                         mdrun->sattr|=SATTR_TRELAX;
684                 mdrun->dt=csp->dt;
685         }
686         if(csp->type&CHSATTR_AVGRST) {
687                 if(csp->avgrst)
688                         mdrun->sattr|=SATTR_AVGRST;
689                 else
690                         mdrun->sattr&=(~(SATTR_AVGRST));
691         }
692         if(csp->type&CHSATTR_RSTEPS) {
693                 mdrun->relax_steps=csp->rsteps;
694         }
695
696         return 0;
697 }
698
699 #define stage_print(m)  if(!(stage->executed)) \
700                                 printf("%s",m)
701
702 int mdrun_hook(void *ptr1,void *ptr2) {
703
704         t_moldyn *moldyn;
705         t_mdrun *mdrun;
706         t_stage *stage;
707         t_list *sl;
708         int steps;
709         double tau;
710         u8 change_stage;
711
712         t_insert_atoms_params *iap;
713         t_continue_params *cp;
714         t_anneal_params *ap;
715
716         moldyn=ptr1;
717         mdrun=ptr2;
718
719         sl=&(mdrun->stage);
720
721         change_stage=FALSE;
722
723         /* return immediately if there are no more stage */
724         if(sl->current==NULL)
725                 return 0;
726
727         /* get stage description */
728         stage=sl->current->data;
729
730         /* default steps and tau values */
731         steps=mdrun->relax_steps;
732         tau=mdrun->timestep;
733
734         /* check whether relaxation steps are necessary */
735         if((check_pressure(moldyn,mdrun)==TRUE)&\
736            (check_temperature(moldyn,mdrun)==TRUE)) {
737         
738                 /* be verbose */
739                 stage_print("\n###########################\n");
740                 stage_print("# [mdrun] executing stage #\n");
741                 stage_print("###########################\n\n");
742                 
743                 /* stage specific stuff */
744                 switch(stage->type) {
745                         case STAGE_INSERT_ATOMS:
746                                 stage_print("  -> insert atoms\n\n");
747                                 iap=stage->params;
748                                 if(iap->cnt_steps==iap->ins_steps) {
749                                         change_stage=TRUE;
750                                         break;
751                                 }
752                                 insert_atoms(moldyn,mdrun);
753                                 iap->cnt_steps+=1;
754                                         break;
755                         case STAGE_CONTINUE:
756                                 stage_print("  -> continue\n\n");
757                                 if(stage->executed==TRUE) {
758                                         change_stage=TRUE;
759                                         break;
760                                 }
761                                 cp=stage->params;
762                                 steps=cp->runs;
763                                         break;
764                         case STAGE_ANNEAL:
765                                 stage_print("  -> anneal\n\n");
766                                 ap=stage->params;
767                                 if(ap->count==ap->runs) {
768                                         change_stage=TRUE;
769                                         break;
770                                 }
771                                 if(moldyn->t_ref+ap->dt>=0.0)
772                                         set_temperature(moldyn,
773                                                         moldyn->t_ref+ap->dt);
774                                 ap->count+=1;
775                                 break;
776                         case STAGE_CHAATTR:
777                                 stage_print("  -> chaattr\n\n");
778                                 chaatr(moldyn,mdrun);
779                                 change_stage=TRUE;
780                                 break;
781                         case STAGE_CHSATTR:
782                                 stage_print("  -> chsattr\n\n");
783                                 chsattr(moldyn,mdrun);
784                                 change_stage=TRUE;
785                                 break;
786                         default:
787                                 printf("%s unknwon stage type\n",ME);
788                                 break;
789                 }
790         
791                 /* mark as executed */
792                 stage->executed=TRUE;
793         
794                 /* change state */
795                 if(change_stage==TRUE) {
796                         printf("%s finished stage\n",ME);
797                         if(list_next_f(sl)==L_NO_NEXT_ELEMENT) {
798                                 printf("%s no more stages\n",ME);
799                                 return 0;
800                         }
801                         steps=0;
802                         tau=mdrun->timestep;
803                 }
804
805         }
806         else {
807
808                 /* averages */
809                 if(mdrun->sattr&SATTR_AVGRST)
810                         average_reset(moldyn);
811
812         }
813
814         /* continue simulation */
815         moldyn_add_schedule(moldyn,steps,tau);
816
817         return 0;
818 }
819
820 int main(int argc,char **argv) {
821
822         t_mdrun mdrun;
823         t_moldyn moldyn;
824         t_3dvec o;
825
826         /* clear structs */
827         memset(&mdrun,0,sizeof(t_mdrun));
828         memset(&moldyn,0,sizeof(t_moldyn));
829
830         /* parse arguments */
831         if(mdrun_parse_argv(&mdrun,argc,argv)<0)
832                 return -1;
833
834         /* initialize list system */
835         list_init_f(&(mdrun.stage));
836
837         /* parse config file */
838         mdrun_parse_config(&mdrun);
839
840         /* reset the stage list */
841         list_reset_f(&(mdrun.stage));
842
843         /* sanity check! */
844
845         /* prepare simulation */
846         moldyn_init(&moldyn,argc,argv);
847         if(set_int_alg(&moldyn,mdrun.intalgo)<0)
848                 return -1;
849         set_cutoff(&moldyn,mdrun.cutoff);
850         if(set_potential(&moldyn,mdrun.potential)<0)
851                 return -1;
852         switch(mdrun.potential) {
853                 case MOLDYN_POTENTIAL_AM:
854                         albe_mult_set_params(&moldyn,
855                                              mdrun.element1,
856                                              mdrun.element2);
857                         break;
858                 case MOLDYN_POTENTIAL_TM:
859                         tersoff_mult_set_params(&moldyn,
860                                                 mdrun.element1,
861                                                 mdrun.element2);
862                         break;
863                 case MOLDYN_POTENTIAL_HO:
864                         harmonic_oscillator_set_params(&moldyn,mdrun.element1);
865                         break;
866                 case MOLDYN_POTENTIAL_LJ:
867                         lennard_jones_set_params(&moldyn,mdrun.element1);
868                         break;
869                 default:
870                         printf("%s unknown potential: %02x\n",
871                                ME,mdrun.potential);
872                         return -1;
873         }
874         set_dim(&moldyn,mdrun.dim.x,mdrun.dim.y,mdrun.dim.z,mdrun.vis);
875         set_pbc(&moldyn,mdrun.pbcx,mdrun.pbcy,mdrun.pbcz);
876         switch(mdrun.lattice) {
877                 case FCC:
878                         create_lattice(&moldyn,FCC,mdrun.lc,mdrun.element1,
879                                        mdrun.m1,DEFAULT_ATOM_ATTR,0,mdrun.lx,
880                                        mdrun.ly,mdrun.lz,NULL);
881                         break;
882                 case DIAMOND:
883                         create_lattice(&moldyn,DIAMOND,mdrun.lc,mdrun.element1,
884                                        mdrun.m1,DEFAULT_ATOM_ATTR,0,mdrun.lx,
885                                        mdrun.ly,mdrun.lz,NULL);
886                         break;
887                 case ZINCBLENDE:
888                         o.x=0.5*0.25*mdrun.lc; o.y=o.x; o.z=o.x;
889                         create_lattice(&moldyn,FCC,mdrun.lc,mdrun.element1,
890                                        mdrun.m1,DEFAULT_ATOM_ATTR,0,mdrun.lx,
891                                        mdrun.ly,mdrun.lz,&o);
892                         o.x+=0.25*mdrun.lc; o.y=o.x; o.z=o.x;
893                         create_lattice(&moldyn,FCC,mdrun.lc,mdrun.element2,
894                                        mdrun.m2,DEFAULT_ATOM_ATTR,1,mdrun.lx,
895                                        mdrun.ly,mdrun.lz,&o);
896                         break;
897                 default:
898                         printf("%s unknown lattice type: %02x\n",
899                                ME,mdrun.lattice);
900                         return -1;
901         }
902         moldyn_bc_check(&moldyn);
903         set_temperature(&moldyn,mdrun.temperature);
904         set_pressure(&moldyn,mdrun.pressure);
905         thermal_init(&moldyn,TRUE);
906         moldyn_add_schedule(&moldyn,mdrun.prerun,mdrun.timestep);
907         moldyn_set_log_dir(&moldyn,mdrun.sdir);
908         moldyn_set_report(&moldyn,"CHANGE ME","CHANGE ME TOO");
909         if(mdrun.elog)
910                 moldyn_set_log(&moldyn,LOG_TOTAL_ENERGY,mdrun.elog);
911         if(mdrun.tlog)
912                 moldyn_set_log(&moldyn,LOG_TEMPERATURE,mdrun.tlog);
913         if(mdrun.plog)
914                 moldyn_set_log(&moldyn,LOG_PRESSURE,mdrun.plog);
915         if(mdrun.vlog)
916                 moldyn_set_log(&moldyn,LOG_VOLUME,mdrun.vlog);
917         if(mdrun.visualize)
918                 moldyn_set_log(&moldyn,VISUAL_STEP,mdrun.visualize);
919         if(mdrun.save)
920                 moldyn_set_log(&moldyn,SAVE_STEP,mdrun.save);
921         moldyn_set_log(&moldyn,CREATE_REPORT,0);
922         set_avg_skip(&moldyn,mdrun.avgskip);
923
924         /* prepare the hook function */
925         moldyn_set_schedule_hook(&moldyn,&mdrun_hook,&mdrun);
926
927         /* run the simulation */
928         moldyn_integrate(&moldyn);
929
930         /* shutdown */
931         moldyn_shutdown(&moldyn);
932         del_stages(&mdrun);
933         list_destroy_f(&(mdrun.stage));
934
935         return 0;
936 }