fixed compile errors, no testing yet!
[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;
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],"intalgo",7)) {
205                         if(!strncmp(word[1],"verlet",5))
206                                 mdrun->intalgo=MOLDYN_INTEGRATE_VERLET;
207                 }
208                 else if(!strncmp(word[0],"timestep",8))
209                         mdrun->timestep=atof(word[1]);
210                 else if(!strncmp(word[0],"volume",6)) {
211                         mdrun->dim.x=atof(word[1]);
212                         mdrun->dim.y=atof(word[2]);
213                         mdrun->dim.z=atof(word[3]);
214                         if(strncmp(word[4],"0",1))
215                                 mdrun->vis=TRUE;
216                 }
217                 else if(!strncmp(word[0],"pbc",3)) {
218                         if(strncmp(word[1],"0",1))
219                                 mdrun->pbcx=TRUE;
220                         else
221                                 mdrun->pbcx=FALSE;
222                         if(strncmp(word[2],"0",1))
223                                 mdrun->pbcy=TRUE;
224                         else
225                                 mdrun->pbcy=FALSE;
226                         if(strncmp(word[3],"0",1))
227                                 mdrun->pbcz=TRUE;
228                         else
229                                 mdrun->pbcz=FALSE;
230                 }
231                 else if(!strncmp(word[0],"temperature",11))
232                         mdrun->temperature=atof(word[1]);
233                 else if(!strncmp(word[0],"pressure",8))
234                         mdrun->pressure=atof(word[1]);
235                 else if(!strncmp(word[0],"lattice",7)) {
236                         if(!strncmp(word[1],"zincblende",10))
237                                 mdrun->lattice=ZINCBLENDE;
238                         if(!strncmp(word[1],"fcc",3))
239                                 mdrun->lattice=FCC;
240                         if(!strncmp(word[1],"diamond",7))
241                                 mdrun->lattice=DIAMOND;
242                 }
243                 else if(!strncmp(word[0],"element1",8)) {
244                         mdrun->element1=atoi(word[1]);
245                         switch(mdrun->element1) {
246                                 case SI:
247                                         mdrun->m1=M_SI;
248                                         break;
249                                 case C:
250                                         mdrun->m1=M_C;
251                                         break;
252                                 default:
253                                         printf("%s unknown element1: %s|%d\n",
254                                                ME,word[1],mdrun->element1);
255                                         return -1;
256                         }
257                 }
258                 else if(!strncmp(word[0],"element2",8)) {
259                         mdrun->element2=atoi(word[1]);
260                         switch(mdrun->element2) {
261                                 case SI:
262                                         mdrun->m2=M_SI;
263                                         break;
264                                 case C:
265                                         mdrun->m2=M_C;
266                                         break;
267                                 default:
268                                         printf("%s unknown element2: %s|%d\n",
269                                                ME,word[1],mdrun->element2);
270                                         return -1;
271                         }
272                 }
273                 else if(!strncmp(word[0],"fill",6)) {
274                         // only lc mode by now
275                         mdrun->lx=atoi(word[2]);
276                         mdrun->ly=atoi(word[3]);
277                         mdrun->lz=atoi(word[4]);
278                 }
279                 else if(!strncmp(word[0],"aattr",5)) {
280                         // for aatrib line we need a special stage
281                         // containing one schedule of 0 loops ...
282                         for(i=0;i<strlen(word[1]);i++) {
283                                 switch(word[1][i]) {
284                                         case 't':
285                                                 cap.type|=CHAATTR_TOTALV;
286                                                 break;
287                                         case 'r':
288                                                 cap.type|=CHAATTR_REGION;
289                                                 break;
290                                         case 'e':
291                                                 cap.type|=CHAATTR_ELEMENT;
292                                                 break;
293                                         default:
294                                                 break;
295                                 }
296                         }
297                         i=1;
298                         if(cap.type&CHAATTR_REGION) {
299                                 cap.x0=atof(word[1]);   
300                                 cap.y0=atof(word[2]);   
301                                 cap.z0=atof(word[3]);   
302                                 cap.x1=atof(word[4]);   
303                                 cap.y1=atof(word[5]);   
304                                 cap.z1=atof(word[6]);
305                                 i+=6;
306                         }
307                         if(cap.type&CHAATTR_ELEMENT) {
308                                 cap.element=atoi(word[i]);
309                                 i+=1;
310                         }
311                         wptr=word[i];
312                         for(i=0;i<strlen(wptr);i++) {
313                                 switch(word[2][i]) {
314                                         case 'b':
315                                                 cap.attr|=ATOM_ATTR_VB;
316                                                 break;
317                                         case 'h':
318                                                 cap.attr|=ATOM_ATTR_HB;
319                                                 break;
320                                         case 'v':
321                                                 cap.attr|=ATOM_ATTR_VA;
322                                                 break;
323                                         case 'f':
324                                                 cap.attr|=ATOM_ATTR_FP;
325                                                 break;
326                                         case '1':
327                                                 cap.attr|=ATOM_ATTR_1BP;
328                                                 break;
329                                         case '2':
330                                                 cap.attr|=ATOM_ATTR_2BP;
331                                                 break;
332                                         case '3':
333                                                 cap.attr|=ATOM_ATTR_3BP;
334                                                 break;
335                                         default:
336                                                 break;
337                                 }
338                         }
339                         add_stage(mdrun,STAGE_CHAATTR,&cap);
340                 }
341                 else if(!strncmp(word[0],"sattr",5)) {
342                         // for satrib line we need a special stage
343                         // containing one schedule of 0 loops ...
344                         for(i=1;i<wcnt;i++) {
345                                 if(!strncmp(word[i],"pctrl",5)) {
346                                         csp.ptau=atof(word[++i]);
347                                 }
348                                 if(!strncmp(word[i],"tctrl",5)) {
349                                         csp.ttau=atof(word[++i]);
350                                 }
351                                 if(!strncmp(word[i],"prelax",6)) {
352                                         csp.dp=atof(word[++i]);
353                                 }
354                                 if(!strncmp(word[i],"trelax",6)) {
355                                         csp.dt=atof(word[++i]);
356                                 }
357                                 if(!strncmp(word[i],"rsteps",6)) {
358                                         csp.rsteps=atoi(word[++i]);
359                                 }
360                                 if(!strncmp(word[i],"avgrst",6)) {
361                                         csp.avgrst=atoi(word[++i]);
362                                 }
363                         }
364                         add_stage(mdrun,STAGE_CHSATTR,&csp);
365                 }
366                 else if(!strncmp(word[0],"prerun",6))
367                         mdrun->prerun=atoi(word[1]);
368                 else if(!strncmp(word[0],"avgskip",7))
369                         mdrun->avgskip=atoi(word[1]);
370                 else if(!strncmp(word[0],"elog",4))
371                         mdrun->elog=atoi(word[1]);
372                 else if(!strncmp(word[0],"tlog",4))
373                         mdrun->tlog=atoi(word[1]);
374                 else if(!strncmp(word[0],"plog",4))
375                         mdrun->plog=atoi(word[1]);
376                 else if(!strncmp(word[0],"vlog",4))
377                         mdrun->vlog=atoi(word[1]);
378                 else if(!strncmp(word[0],"save",4))
379                         mdrun->save=atoi(word[1]);
380                 else if(!strncmp(word[0],"visualize",9))
381                         mdrun->visualize=atoi(word[1]);
382                 else if(!strncmp(word[0],"stage",5)) {
383                         // for every stage line, add a stage
384                         if(!strncmp(word[1],"ins_atoms",9)) {
385                                 iap.ins_steps=atoi(word[2]);
386                                 iap.ins_atoms=atoi(word[3]);
387                                 iap.element=atoi(word[4]);
388                                 iap.element=atoi(word[4]);
389                                 iap.brand=atoi(word[5]);
390                                 for(i=0;i<strlen(word[6]);i++) {
391                                         switch(word[6][i]) {
392                                                 case 'b':
393                                                         iap.attr|=ATOM_ATTR_VB;
394                                                         break;
395                                                 case 'h':
396                                                         iap.attr|=ATOM_ATTR_HB;
397                                                         break;
398                                                 case 'v':
399                                                         iap.attr|=ATOM_ATTR_VA;
400                                                         break;
401                                                 case 'f':
402                                                         iap.attr|=ATOM_ATTR_FP;
403                                                         break;
404                                                 case '1':
405                                                         iap.attr|=ATOM_ATTR_1BP;
406                                                         break;
407                                                 case '2':
408                                                         iap.attr|=ATOM_ATTR_2BP;
409                                                         break;
410                                                 case '3':
411                                                         iap.attr|=ATOM_ATTR_3BP;
412                                                         break;
413                                                 default:
414                                                         break;
415                                         }
416                                 }
417                                 // only rand mode by now
418                                 if(word[8][0]=='t')
419                                         iap.type=INS_TOTAL;
420                                 else {
421                                         iap.type=INS_REGION;
422                                         iap.x0=atof(word[8]);
423                                         iap.y0=atof(word[9]);
424                                         iap.z0=atof(word[10]);
425                                         iap.x1=atof(word[11]);
426                                         iap.y1=atof(word[12]);
427                                         iap.z1=atof(word[13]);
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         delta=moldyn->p_avg-moldyn->p_ref;
468
469         if(delta<0)
470                 delta=-delta;
471
472         if(delta>mdrun->dp)
473                 return FALSE;
474
475         return TRUE;
476 }
477
478 int check_temperature(t_moldyn *moldyn,t_mdrun *mdrun) {
479
480         double delta;
481
482         if(!(mdrun->sattr&SATTR_TRELAX))
483                 return TRUE;
484
485         delta=moldyn->t_avg-moldyn->t_ref;
486
487         if(delta<0)
488                 delta=-delta;
489
490         if(delta>mdrun->dt)
491                 return FALSE;
492
493         return TRUE;
494 }
495
496 int insert_atoms(t_moldyn *moldyn,t_mdrun *mdrun) {
497
498         t_insert_atoms_params *iap;
499         t_stage *stage;
500         t_atom *atom;
501         t_3dvec r,v,dist;
502         double d,dmin;
503         int cnt,i;
504         double x,y,z;
505         double x0,y0,z0;
506         u8 cr_check,run;
507         
508         stage=mdrun->stage.current->data;
509         iap=stage->params;
510
511         cr_check=FALSE;
512
513         v.x=0.0; v.y=0.0; v.z=0.0;
514
515         switch(iap->type) {
516                 case INS_TOTAL:
517                         x=moldyn->dim.x;
518                         x0=0.0;
519                         y=moldyn->dim.y;
520                         y0=0.0;
521                         z=moldyn->dim.z;
522                         z0=0.0;
523                         cr_check=TRUE;
524                         break;
525                 case INS_REGION:
526                         x=iap->x1-iap->x0;
527                         x0=iap->x0;
528                         y=iap->y1-iap->y0;
529                         y0=iap->y0;
530                         z=iap->z1-iap->z0;
531                         z0=iap->z0;
532                         cr_check=TRUE;
533                         break;
534                 default:
535                         printf("%s unknown insertion mode: %02x\n",
536                                ME,iap->type);
537                         return -1;
538         }
539
540         cnt=0;
541         while(cnt<iap->ins_atoms) {
542                 run=1;
543                 while(run) {
544                         r.x=(rand_get_double(&(moldyn->random))-0.5)*x+x0;
545                         r.y=(rand_get_double(&(moldyn->random))-0.5)*y+y0;
546                         r.z=(rand_get_double(&(moldyn->random))-0.5)*z+z0;
547                         run=0;
548                         if(cr_check==TRUE) {
549                                 dmin=1000;      // for sure too high!
550                                 for(i=0;i<moldyn->count;i++) {
551                                         atom=&(moldyn->atom[i]);
552                                         v3_sub(&dist,&(atom->r),&r);
553                                         check_per_bound(moldyn,&dist);
554                                         d=v3_absolute_square(&dist);
555                                         if(d<(iap->cr*iap->cr)) {
556                                                 run=1;
557                                                 break;
558                                         }
559                                         if(d<dmin)
560                                                 dmin=d;
561                                 }
562                         }
563                 }
564                 add_atom(moldyn,iap->element,pse_mass[iap->element],
565                          iap->brand,iap->attr,&r,&v);
566                 printf("%s atom inserted: %f %f %f | d squared = %f\n",
567                        ME,r.x,r.y,r.z,dmin);
568                 cnt+=1;
569         }
570
571         return 0;
572 }
573
574 int chaatr(t_moldyn *moldyn,t_mdrun *mdrun) {
575
576         t_stage *stage;
577         t_chaattr_params *cap;
578         t_atom *atom;
579         int i;
580
581         stage=mdrun->stage.current->data;
582         cap=stage->params;
583
584         for(i=0;i<moldyn->count;i++) {
585                 atom=&(moldyn->atom[i]);
586                 if(cap->type&CHAATTR_ELEMENT) {
587                         if(cap->element!=atom->element)
588                                 continue;
589                 }
590                 if(cap->type&CHAATTR_REGION) {
591                         if(cap->x0<atom->r.x)
592                                 continue;
593                         if(cap->y0<atom->r.y)
594                                 continue;
595                         if(cap->z0<atom->r.z)
596                                 continue;
597                         if(cap->x1>atom->r.x)
598                                 continue;
599                         if(cap->y1>atom->r.y)
600                                 continue;
601                         if(cap->z1>atom->r.z)
602                                 continue;
603                 }
604                 atom->attr=cap->attr;
605         }
606
607         return 0;
608 }
609
610 int chsattr(t_moldyn *moldyn,t_mdrun *mdrun) {
611
612         t_stage *stage;
613         t_chsattr_params *csp;
614
615         stage=mdrun->stage.current->data;
616         csp=stage->params;
617
618         if(csp->type&CHSATTR_PCTRL) {
619                 if(csp->ptau>0)
620                         set_p_scale(moldyn,P_SCALE_BERENDSEN,csp->ptau);
621                 else
622                         set_p_scale(moldyn,P_SCALE_BERENDSEN,csp->ptau);
623         }
624         if(csp->type&CHSATTR_TCTRL) {
625                 if(csp->ttau>0)
626                         set_t_scale(moldyn,T_SCALE_BERENDSEN,csp->ttau);
627                 else
628                         set_t_scale(moldyn,T_SCALE_BERENDSEN,csp->ttau);
629         }
630         if(csp->type&CHSATTR_PRELAX) {
631                 if(csp->dp<0)
632                         mdrun->sattr&=(~(SATTR_PRELAX));
633                 else
634                         mdrun->sattr|=SATTR_PRELAX;
635                 mdrun->dp=csp->dp;
636         }
637         if(csp->type&CHSATTR_TRELAX) {
638                 if(csp->dt<0)
639                         mdrun->sattr&=(~(SATTR_TRELAX));
640                 else
641                         mdrun->sattr|=SATTR_TRELAX;
642                 mdrun->dt=csp->dt;
643         }
644         if(csp->type&CHSATTR_AVGRST) {
645                 if(csp->avgrst)
646                         mdrun->sattr|=CHSATTR_AVGRST;
647                 else
648                         mdrun->sattr&=(~(CHSATTR_AVGRST));
649         }
650         if(csp->type&CHSATTR_RSTEPS) {
651                 mdrun->relax_steps=csp->rsteps;
652         }
653
654         return 0;
655 }
656
657 int mdrun_hook(void *ptr1,void *ptr2) {
658
659         t_moldyn *moldyn;
660         t_mdrun *mdrun;
661         t_stage *stage;
662         t_list *sl;
663         int steps;
664         double tau;
665         u8 change_stage;
666
667         t_insert_atoms_params *iap;
668         t_continue_params *cp;
669         t_anneal_params *ap;
670
671         moldyn=ptr1;
672         mdrun=ptr2;
673
674         sl=&(mdrun->stage);
675
676         change_stage=FALSE;
677
678         /* return immediately if there are no more stage */
679         if(sl->current==NULL)
680                 return 0;
681
682         /* get stage description */
683         stage=sl->current->data;
684
685         /* default steps and tau values */
686         steps=mdrun->relax_steps;
687         tau=mdrun->timestep;
688
689         /* check whether relaxation steps are necessary */
690         if(!((check_pressure(moldyn,mdrun)==FALSE)|\
691              (check_temperature(moldyn,mdrun)==FALSE))) {
692                 
693                 /* stage specific stuff */
694                 switch(stage->type) {
695                         case STAGE_INSERT_ATOMS:
696                                 iap=stage->params;
697                                 if(iap->cnt_steps==iap->ins_steps) {
698                                         change_stage=TRUE;
699                                         break;
700                                 }
701                                 insert_atoms(moldyn,mdrun);
702                                 iap->cnt_steps+=1;
703                                         break;
704                         case STAGE_CONTINUE:
705                                 if(stage->executed==TRUE) {
706                                         change_stage=TRUE;
707                                         break;
708                                 }
709                                 cp=stage->params;
710                                 steps=cp->runs;
711                                         break;
712                         case STAGE_ANNEAL:
713                                 ap=stage->params;
714                                 if(ap->count==ap->runs) {
715                                         change_stage=TRUE;
716                                         break;
717                                 }
718                                 set_temperature(moldyn,moldyn->t_ref+ap->dt);
719                                 ap->count+=1;
720                                 break;
721                         case STAGE_CHAATTR:
722                                 chaatr(moldyn,mdrun);
723                                 change_stage=TRUE;
724                                 break;
725                         case STAGE_CHSATTR:
726                                 chsattr(moldyn,mdrun);
727                                 change_stage=TRUE;
728                                 break;
729                         default:
730                                 printf("%s unknwon stage type\n",ME);
731                                 break;
732                 }
733         
734                 /* mark as executed */
735                 stage->executed=TRUE;
736         
737                 /* change state */
738                 if(change_stage==TRUE) {
739                         printf("%s finished stage\n",ME);
740                         if(list_next_f(sl)==L_NO_NEXT_ELEMENT) {
741                                 printf("%s no more stages\n",ME);
742                                 return 0;
743                         }
744                         steps=0;
745                         tau=mdrun->timestep;
746                 }
747
748         }
749         else {
750
751                 /* averages */
752                 if(mdrun->sattr&SATTR_AVGRST)
753                         average_reset(moldyn);
754
755         }
756
757         /* continue simulation */
758         moldyn_add_schedule(moldyn,steps,tau);
759
760         return 0;
761 }
762
763 int main(int argc,char **argv) {
764
765         t_mdrun mdrun;
766         t_moldyn moldyn;
767         t_3dvec o;
768
769         /* clear mdrun struct */
770         memset(&mdrun,0,sizeof(t_mdrun));
771
772         /* parse arguments */
773         if(mdrun_parse_argv(&mdrun,argc,argv)<0)
774                 return -1;
775
776         /* initialize list system */
777         list_init_f(&(mdrun.stage));
778
779         /* parse config file */
780         mdrun_parse_config(&mdrun);
781
782         /* reset the stage list */
783         list_reset_f(&(mdrun.stage));
784
785         /* sanity check! */
786
787         /* prepare simulation */
788         moldyn_init(&moldyn,argc,argv);
789         if(set_int_alg(&moldyn,mdrun.intalgo)<0)
790                 return -1;
791         set_cutoff(&moldyn,mdrun.cutoff);
792         if(set_potential(&moldyn,mdrun.potential)<0)
793                 return -1;
794         switch(mdrun.potential) {
795                 case MOLDYN_POTENTIAL_AM:
796                         albe_mult_set_params(&moldyn,
797                                              mdrun.element1,
798                                              mdrun.element2);
799                         break;
800                 case MOLDYN_POTENTIAL_TM:
801                         tersoff_mult_set_params(&moldyn,
802                                                 mdrun.element1,
803                                                 mdrun.element2);
804                         break;
805                 case MOLDYN_POTENTIAL_HO:
806                         harmonic_oscillator_set_params(&moldyn,mdrun.element1);
807                         break;
808                 case MOLDYN_POTENTIAL_LJ:
809                         lennard_jones_set_params(&moldyn,mdrun.element1);
810                         break;
811                 default:
812                         printf("%s unknown potential: %02x\n",
813                                ME,mdrun.potential);
814                         return -1;
815         }
816         set_dim(&moldyn,mdrun.dim.x,mdrun.dim.y,mdrun.dim.z,mdrun.vis);
817         set_pbc(&moldyn,mdrun.pbcx,mdrun.pbcy,mdrun.pbcz);
818         switch(mdrun.lattice) {
819                 case FCC:
820                         create_lattice(&moldyn,FCC,mdrun.lc,mdrun.element1,
821                                        mdrun.m1,0,0,mdrun.lx,
822                                        mdrun.ly,mdrun.lz,NULL);
823                         break;
824                 case DIAMOND:
825                         create_lattice(&moldyn,DIAMOND,mdrun.lc,mdrun.element1,
826                                        mdrun.m1,0,0,mdrun.lx,
827                                        mdrun.ly,mdrun.lz,NULL);
828                         break;
829                 case ZINCBLENDE:
830                         o.x=0.5*0.25*mdrun.lc; o.y=o.x; o.z=o.x;
831                         create_lattice(&moldyn,FCC,mdrun.lc,mdrun.element1,
832                                        mdrun.m1,0,0,mdrun.lx,
833                                        mdrun.ly,mdrun.lz,&o);
834                         o.x+=0.25*mdrun.lc; o.y=o.x; o.z=o.x;
835                         create_lattice(&moldyn,FCC,mdrun.lc,mdrun.element2,
836                                        mdrun.m2,0,1,mdrun.lx,
837                                        mdrun.ly,mdrun.lz,&o);
838                         break;
839                 default:
840                         printf("%s unknown lattice type: %02x\n",
841                                ME,mdrun.lattice);
842                         return -1;
843         }
844         moldyn_bc_check(&moldyn);
845         set_temperature(&moldyn,mdrun.temperature);
846         set_pressure(&moldyn,mdrun.pressure);
847         thermal_init(&moldyn,TRUE);
848         moldyn_add_schedule(&moldyn,mdrun.prerun,mdrun.timestep);
849         moldyn_set_log_dir(&moldyn,mdrun.sdir);
850         moldyn_set_report(&moldyn,"CHANGE ME","CHANGE ME TOO");
851         if(mdrun.elog)
852                 moldyn_set_log(&moldyn,LOG_TOTAL_ENERGY,mdrun.elog);
853         if(mdrun.tlog)
854                 moldyn_set_log(&moldyn,LOG_TEMPERATURE,mdrun.tlog);
855         if(mdrun.plog)
856                 moldyn_set_log(&moldyn,LOG_PRESSURE,mdrun.plog);
857         if(mdrun.vlog)
858                 moldyn_set_log(&moldyn,LOG_VOLUME,mdrun.vlog);
859         if(mdrun.visualize)
860                 moldyn_set_log(&moldyn,VISUAL_STEP,mdrun.visualize);
861         if(mdrun.save)
862                 moldyn_set_log(&moldyn,SAVE_STEP,mdrun.save);
863         moldyn_set_log(&moldyn,CREATE_REPORT,0);
864         set_avg_skip(&moldyn,mdrun.avgskip);
865
866         /* prepare the hook function */
867         moldyn_set_schedule_hook(&moldyn,&mdrun_hook,&mdrun);
868
869         /* run the simulation */
870         moldyn_integrate(&moldyn);
871
872         /* shutdown */
873         moldyn_shutdown(&moldyn);
874         del_stages(&mdrun);
875         list_destroy_f(&(mdrun.stage));
876
877         return 0;
878 }