increased line size (parse config) + zero defect subtype
[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 /* pse */
21 #define PSE_MASS
22 #include "pse.h"
23 #undef PSE_MASS
24
25 #define ME      "[mdrun]"
26
27 /*
28  * parse function
29  */
30
31 int mdrun_usage(void) {
32
33         printf("%s usage:\n",ME);
34
35         return 0;
36 }
37
38 int mdrun_parse_argv(t_mdrun *mdrun,int argc,char **argv) {
39
40         int i;
41
42         for(i=1;i<argc;i++) {
43
44                 if(argv[i][0]!='-') {
45                         printf("%s unknown switch: %s\n",ME,argv[i]);
46                         return -1;
47                 }
48
49                 switch(argv[i][1]) {
50                         case 'c':
51                                 strncpy(mdrun->cfile,argv[++i],128);
52                                 break;
53                         case 's':
54                                 strncpy(mdrun->sdir,argv[++i],128);
55                                 break;
56                         case 'h':
57                                 mdrun_usage();
58                                 break;
59                         default:
60                                 printf("%s unknown option: %s\n",ME,argv[i]);
61                                 mdrun_usage();
62                                 return -1;
63                 }
64
65         }
66
67         return 0;
68 }
69
70 int del_stages(t_mdrun *mdrun) {
71
72         t_list *sl;
73         t_stage *stage;
74
75         sl=&(mdrun->stage);
76
77         list_reset_f(sl);
78
79         if(sl->start==NULL)
80                 return 0;
81
82         do {
83                 stage=sl->current->data;
84                 free(stage->params);
85                 free(stage);
86         } while(list_next_f(sl)!=L_NO_NEXT_ELEMENT);
87
88         return 0;
89 }
90
91 int add_stage(t_mdrun *mdrun,u8 type,void *params) {
92
93         int psize;
94
95         t_stage *stage;
96
97         switch(type) {
98                 case STAGE_DISPLACE_ATOM:
99                         psize=sizeof(t_displace_atom_params);
100                         break;
101                 case STAGE_INSERT_ATOMS:
102                         psize=sizeof(t_insert_atoms_params);
103                         break;
104                 case STAGE_INSERT_MIXED_ATOMS:
105                         psize=sizeof(t_insert_mixed_atoms_params);
106                         break;
107                 case STAGE_CONTINUE:
108                         psize=sizeof(t_continue_params);
109                         break;
110                 case STAGE_ANNEAL:
111                         psize=sizeof(t_anneal_params);
112                         break;
113                 case STAGE_CHAATTR:
114                         psize=sizeof(t_chaattr_params);
115                         break;
116                 case STAGE_CHSATTR:
117                         psize=sizeof(t_chsattr_params);
118                         break;
119                 case STAGE_SET_TEMP:
120                         psize=sizeof(t_set_temp_params);
121                         break;
122                 case STAGE_SET_TIMESTEP:
123                         psize=sizeof(t_set_timestep_params);
124                         break;
125                 case STAGE_FILL:
126                         psize=sizeof(t_fill_params);
127                         break;
128                 case STAGE_THERMAL_INIT:
129                         psize=0;
130                         break;
131                 default:
132                         printf("%s unknown stage type: %02x\n",ME,type);
133                         return -1;
134         }
135
136         stage=malloc(sizeof(t_stage));
137         if(stage==NULL) {
138                 perror("[mdrun] malloc (add stage)");
139                 return -1;
140         }
141
142         stage->type=type;
143         stage->executed=FALSE;
144
145         stage->params=malloc(psize);
146         if(stage->params==NULL) {
147                 perror("[mdrun] malloc (stage params)");
148                 return -1;
149         }
150
151         memcpy(stage->params,params,psize);
152
153         list_add_immediate_f(&(mdrun->stage),stage);
154
155         return 0;
156 }
157
158 int mdrun_parse_config(t_mdrun *mdrun) {
159
160         int fd,ret;
161         char error[128];
162         char line[128];
163         char *wptr;
164         char word[32][64];
165         int wcnt;
166         int i,o;
167
168         t_displace_atom_params dap;
169         t_insert_atoms_params iap;
170         t_insert_mixed_atoms_params imp;
171         t_continue_params cp;
172         t_anneal_params ap;
173         t_chaattr_params cap;
174         t_chsattr_params csp;
175         t_set_temp_params stp;
176         t_set_timestep_params stsp;
177         t_fill_params fp;
178
179         /* open config file */
180         fd=open(mdrun->cfile,O_RDONLY);
181         if(fd<0) {
182                 snprintf(error,128,"%s open cfile %s",ME,mdrun->cfile);
183                 perror(error);
184                 return fd;
185         }
186
187         /* read, parse, set */
188         ret=1;
189         while(ret>0) {
190
191                 /* read */
192                 ret=get_line(fd,line,128);
193
194                 /* parse */
195
196                 // ignore # lines and \n
197                 if((line[0]=='#')|(ret==1))
198                         continue;
199
200                 // reset
201                 memset(&iap,0,sizeof(t_insert_atoms_params));
202                 memset(&imp,0,sizeof(t_insert_mixed_atoms_params));
203                 memset(&cp,0,sizeof(t_continue_params));
204                 memset(&ap,0,sizeof(t_anneal_params));
205                 memset(&cap,0,sizeof(t_chaattr_params));
206                 memset(&csp,0,sizeof(t_chsattr_params));
207                 memset(&stp,0,sizeof(t_set_temp_params));
208                 memset(&stsp,0,sizeof(t_set_timestep_params));
209                 memset(&fp,0,sizeof(t_fill_params));
210
211                 // get command + args
212                 wcnt=0;
213                 while(1) {
214                         if(wcnt)
215                                 wptr=strtok(NULL," \t");
216                         else
217                                 wptr=strtok(line," \t");
218                         if(wptr==NULL)
219                                 break;
220                         strncpy(word[wcnt],wptr,64);
221                         wcnt+=1;
222                 }
223
224                 if(!strncmp(word[0],"potential",9)) {
225                         if(!strncmp(word[1],"albe",4))
226                                 mdrun->potential=MOLDYN_POTENTIAL_AM;
227                         if(!strncmp(word[1],"tersoff",7))
228                                 mdrun->potential=MOLDYN_POTENTIAL_TM;
229                         if(!strncmp(word[1],"ho",2))
230                                 mdrun->potential=MOLDYN_POTENTIAL_HO;
231                         if(!strncmp(word[1],"lj",2))
232                                 mdrun->potential=MOLDYN_POTENTIAL_LJ;
233                 }
234                 else if(!strncmp(word[0],"continue",8))
235                         strncpy(mdrun->continue_file,word[1],128);
236                 else if(!strncmp(word[0],"cutoff",6))
237                         mdrun->cutoff=atof(word[1]);
238                 else if(!strncmp(word[0],"nnd",3))
239                         mdrun->nnd=atof(word[1]);
240                 else if(!strncmp(word[0],"intalgo",7)) {
241                         if(!strncmp(word[1],"verlet",5))
242                                 mdrun->intalgo=MOLDYN_INTEGRATE_VERLET;
243                 }
244                 else if(!strncmp(word[0],"timestep",8))
245                         mdrun->timestep=atof(word[1]);
246                 else if(!strncmp(word[0],"volume",6)) {
247                         mdrun->dim.x=atof(word[1]);
248                         mdrun->dim.y=atof(word[2]);
249                         mdrun->dim.z=atof(word[3]);
250                         if(strncmp(word[4],"0",1))
251                                 mdrun->vis=TRUE;
252                 }
253                 else if(!strncmp(word[0],"pbc",3)) {
254                         if(strncmp(word[1],"0",1))
255                                 mdrun->pbcx=TRUE;
256                         else
257                                 mdrun->pbcx=FALSE;
258                         if(strncmp(word[2],"0",1))
259                                 mdrun->pbcy=TRUE;
260                         else
261                                 mdrun->pbcy=FALSE;
262                         if(strncmp(word[3],"0",1))
263                                 mdrun->pbcz=TRUE;
264                         else
265                                 mdrun->pbcz=FALSE;
266                 }
267                 else if(!strncmp(word[0],"temperature",11))
268                         mdrun->temperature=atof(word[1]);
269                 else if(!strncmp(word[0],"pressure",8))
270                         mdrun->pressure=atof(word[1]);
271                 else if(!strncmp(word[0],"lattice",7)) {
272                         if(!strncmp(word[1],"zincblende",10))
273                                 mdrun->lattice=ZINCBLENDE;
274                         if(!strncmp(word[1],"fcc",3))
275                                 mdrun->lattice=FCC;
276                         if(!strncmp(word[1],"diamond",7))
277                                 mdrun->lattice=DIAMOND;
278                         if(!strncmp(word[1],"none",4))
279                                 mdrun->lattice=NONE;
280                         if(wcnt==3)
281                                 mdrun->lc=atof(word[2]);
282                 }
283                 else if(!strncmp(word[0],"element1",8)) {
284                         mdrun->element1=atoi(word[1]);
285                 }
286                 else if(!strncmp(word[0],"element2",8)) {
287                         mdrun->element2=atoi(word[1]);
288                 }
289                 else if(!strncmp(word[0],"fill",6)) {
290                         // default values
291                         fp.fill_element=mdrun->element1;
292                         fp.fill_brand=0;
293                         fp.lattice=mdrun->lattice;
294                         fp.p_params.type=0;
295                         fp.d_params.type=0;
296                         fp.d_params.stype=0;
297                         // parse fill command
298                         i=1;
299                         while(i<wcnt) {
300                                 if(!strncmp(word[i],"lc",2)) {
301                                         fp.lx=atoi(word[++i]);
302                                         fp.ly=atoi(word[++i]);
303                                         fp.lz=atoi(word[++i]);
304                                         fp.lc=atof(word[++i]);
305                                         mdrun->lc=fp.lc;
306                                 }
307                                 if(!strncmp(word[i],"eb",2)) {
308                                         fp.fill_element=atoi(word[++i]);
309                                         fp.fill_brand=atoi(word[++i]);
310                                 }
311                                 if(word[i][0]=='p') {
312                                         i+=1;
313                                         switch(word[i][0]) {
314                                         case 'i':
315                                                 if(word[i][1]=='r')
316                                                 fp.p_params.type=PART_INSIDE_R;
317                                                 else
318                                                 fp.p_params.type=PART_INSIDE_D;
319                                                 break;
320                                         case 'o':
321                                                 if(word[i][1]=='r')
322                                                 fp.p_params.type=PART_OUTSIDE_R;
323                                                 else
324                                                 fp.p_params.type=PART_OUTSIDE_D;
325                                                 break;
326                                         default:
327                                                 break;
328                                         }
329                                         if((fp.p_params.type==PART_INSIDE_R)||
330                                           (fp.p_params.type==PART_OUTSIDE_R)) {
331                                                 fp.p_params.r=atof(word[++i]);  
332                                                 fp.p_params.p.x=atof(word[++i]);
333                                                 fp.p_params.p.y=atof(word[++i]);
334                                                 fp.p_params.p.z=atof(word[++i]);
335                                         }
336                                         if((fp.p_params.type==PART_INSIDE_D)||
337                                            (fp.p_params.type==PART_OUTSIDE_D)) {
338                                                 fp.p_params.p.x=atof(word[++i]);
339                                                 fp.p_params.p.y=atof(word[++i]);
340                                                 fp.p_params.p.z=atof(word[++i]);
341                                                 fp.p_params.d.x=atof(word[++i]);
342                                                 fp.p_params.d.y=atof(word[++i]);
343                                                 fp.p_params.d.z=atof(word[++i]);
344                                         }
345                                 }
346                                 if(word[i][0]=='d') {
347                                         switch(word[++i][0]) {
348                                                 case '0':
349
350                                 fp.d_params.type=DEFECT_TYPE_0D;
351                                 if(!strncmp(word[i+1],"dbx",3)) {
352                                         fp.d_params.stype=DEFECT_STYPE_DB_X;
353                                 }
354                                 if(!strncmp(word[i+1],"dby",3)) {
355                                         fp.d_params.stype=DEFECT_STYPE_DB_Y;
356                                 }
357                                 if(!strncmp(word[i+1],"dbz",3)) {
358                                         fp.d_params.stype=DEFECT_STYPE_DB_Z;
359                                 }
360                                 if(!strncmp(word[i+1],"dbr",3)) {
361                                         fp.d_params.stype=DEFECT_STYPE_DB_R;
362                                 }
363                                 i+=1;
364                                 fp.d_params.od=atof(word[++i]);
365                                 fp.d_params.dd=atof(word[++i]);
366                                 fp.d_params.element=atoi(word[++i]);
367                                 fp.d_params.brand=atoi(word[++i]);
368                                 // parsed in future
369                 fp.d_params.attr=ATOM_ATTR_HB|ATOM_ATTR_VA;
370                 fp.d_params.attr|=ATOM_ATTR_1BP|ATOM_ATTR_2BP|ATOM_ATTR_3BP;
371                                 break;
372
373                                                 case '1':
374                                 fp.d_params.type=DEFECT_TYPE_1D;
375                                 break;
376                                                 case '2':
377                                 fp.d_params.type=DEFECT_TYPE_2D;
378                                 break;
379                                                 case '3':
380                                 fp.d_params.type=DEFECT_TYPE_3D;
381                                 break;
382                                                 default:
383                                                         break;
384                                         }
385
386                                 }
387                                 i+=1;
388                         }
389                         add_stage(mdrun,STAGE_FILL,&fp);
390                 }
391                 else if(!strncmp(word[0],"thermal_init",12)) {
392                         add_stage(mdrun,STAGE_THERMAL_INIT,NULL);
393                 }
394                 else if(!strncmp(word[0],"aattr",5)) {
395                         // for aatrib line we need a special stage
396                         // containing one schedule of 0 loops ...
397                         for(i=0;i<strlen(word[1]);i++) {
398                                 switch(word[1][i]) {
399                                         case 't':
400                                                 cap.type|=CHAATTR_TOTALV;
401                                                 break;
402                                         case 'r':
403                                                 cap.type|=CHAATTR_REGION;
404                                                 break;
405                                         case 'e':
406                                                 cap.type|=CHAATTR_ELEMENT;
407                                                 break;
408                                         default:
409                                                 break;
410                                 }
411                         }
412                         i=2;
413                         if(cap.type&CHAATTR_REGION) {
414                                 cap.x0=atof(word[1]);   
415                                 cap.y0=atof(word[2]);   
416                                 cap.z0=atof(word[3]);   
417                                 cap.x1=atof(word[4]);   
418                                 cap.y1=atof(word[5]);   
419                                 cap.z1=atof(word[6]);
420                                 i+=6;
421                         }
422                         if(cap.type&CHAATTR_ELEMENT) {
423                                 cap.element=atoi(word[i]);
424                                 i+=1;
425                         }
426                         for(o=0;o<strlen(word[i]);o++) {
427                                 switch(word[i][o]) {
428                                         case 'b':
429                                                 cap.attr|=ATOM_ATTR_VB;
430                                                 break;
431                                         case 'h':
432                                                 cap.attr|=ATOM_ATTR_HB;
433                                                 break;
434                                         case 'v':
435                                                 cap.attr|=ATOM_ATTR_VA;
436                                                 break;
437                                         case 'f':
438                                                 cap.attr|=ATOM_ATTR_FP;
439                                                 break;
440                                         case '1':
441                                                 cap.attr|=ATOM_ATTR_1BP;
442                                                 break;
443                                         case '2':
444                                                 cap.attr|=ATOM_ATTR_2BP;
445                                                 break;
446                                         case '3':
447                                                 cap.attr|=ATOM_ATTR_3BP;
448                                                 break;
449                                         default:
450                                                 break;
451                                 }
452                         }
453                         add_stage(mdrun,STAGE_CHAATTR,&cap);
454                 }
455                 else if(!strncmp(word[0],"sattr",5)) {
456                         // for satrib line we need a special stage
457                         // containing one schedule of 0 loops ...
458                         csp.type=0;
459                         for(i=1;i<wcnt;i++) {
460                                 if(!strncmp(word[i],"pctrl",5)) {
461                                         csp.ptau=0.01/(atof(word[++i])*GPA);
462                                         csp.type|=CHSATTR_PCTRL;
463                                 }
464                                 if(!strncmp(word[i],"tctrl",5)) {
465                                         csp.ttau=atof(word[++i]);
466                                         csp.type|=CHSATTR_TCTRL;
467                                 }
468                                 if(!strncmp(word[i],"prelax",6)) {
469                                         csp.dp=atof(word[++i])*BAR;
470                                         csp.type|=CHSATTR_PRELAX;
471                                 }
472                                 if(!strncmp(word[i],"trelax",6)) {
473                                         csp.dt=atof(word[++i]);
474                                         csp.type|=CHSATTR_TRELAX;
475                                 }
476                                 if(!strncmp(word[i],"rsteps",6)) {
477                                         csp.rsteps=atoi(word[++i]);
478                                         csp.type|=CHSATTR_RSTEPS;
479                                 }
480                                 if(!strncmp(word[i],"avgrst",6)) {
481                                         csp.avgrst=atoi(word[++i]);
482                                         csp.type|=CHSATTR_AVGRST;
483                                 }
484                         }
485                         add_stage(mdrun,STAGE_CHSATTR,&csp);
486                 }
487                 else if(!strncmp(word[0],"prerun",6))
488                         mdrun->prerun=atoi(word[1]);
489                 else if(!strncmp(word[0],"avgskip",7))
490                         mdrun->avgskip=atoi(word[1]);
491                 else if(!strncmp(word[0],"elog",4))
492                         mdrun->elog=atoi(word[1]);
493                 else if(!strncmp(word[0],"tlog",4))
494                         mdrun->tlog=atoi(word[1]);
495                 else if(!strncmp(word[0],"plog",4))
496                         mdrun->plog=atoi(word[1]);
497                 else if(!strncmp(word[0],"vlog",4))
498                         mdrun->vlog=atoi(word[1]);
499                 else if(!strncmp(word[0],"save",4))
500                         mdrun->save=atoi(word[1]);
501                 else if(!strncmp(word[0],"visualize",9))
502                         mdrun->visualize=atoi(word[1]);
503                 else if(!strncmp(word[0],"stage",5)) {
504                         // for every stage line, add a stage
505                         if(!strncmp(word[1],"displace",8)) {
506                                 dap.nr=atoi(word[2]);   
507                                 dap.dx=atof(word[3]);
508                                 dap.dy=atof(word[4]);
509                                 dap.dz=atof(word[5]);
510                                 add_stage(mdrun,STAGE_DISPLACE_ATOM,&dap);
511                         }
512                         else if(!strncmp(word[1],"ins_atoms",9)) {
513                                 iap.ins_steps=atoi(word[2]);
514                                 iap.ins_atoms=atoi(word[3]);
515                                 iap.element=atoi(word[4]);
516                                 iap.brand=atoi(word[5]);
517                                 for(i=0;i<strlen(word[6]);i++) {
518                                         switch(word[6][i]) {
519                                                 case 'b':
520                                                         iap.attr|=ATOM_ATTR_VB;
521                                                         break;
522                                                 case 'h':
523                                                         iap.attr|=ATOM_ATTR_HB;
524                                                         break;
525                                                 case 'v':
526                                                         iap.attr|=ATOM_ATTR_VA;
527                                                         break;
528                                                 case 'f':
529                                                         iap.attr|=ATOM_ATTR_FP;
530                                                         break;
531                                                 case '1':
532                                                         iap.attr|=ATOM_ATTR_1BP;
533                                                         break;
534                                                 case '2':
535                                                         iap.attr|=ATOM_ATTR_2BP;
536                                                         break;
537                                                 case '3':
538                                                         iap.attr|=ATOM_ATTR_3BP;
539                                                         break;
540                                                 default:
541                                                         break;
542                                         }
543                                 }
544                                 switch(word[7][0]) {
545                                         // insertion types
546                                         case 'p':
547                                                 iap.type=INS_POS;
548                                                 iap.x0=atof(word[8]);
549                                                 iap.y0=atof(word[9]);
550                                                 iap.z0=atof(word[10]);
551                                                 break;
552                                         case 'r':
553                                                 if(word[8][0]=='t') {
554                                                         iap.type=INS_TOTAL;
555                                                         iap.cr=atof(word[9]);
556                                                 }
557                                                 else {
558                                                         iap.type=INS_REGION;
559                                                         iap.x0=atof(word[8]);
560                                                         iap.y0=atof(word[9]);
561                                                         iap.z0=atof(word[10]);
562                                                         iap.x1=atof(word[11]);
563                                                         iap.y1=atof(word[12]);
564                                                         iap.z1=atof(word[13]);
565                                                         iap.cr=atof(word[14]);
566                                                 }
567                                         default:
568                                                 break;
569                                 }
570                                 add_stage(mdrun,STAGE_INSERT_ATOMS,&iap);
571                         }
572
573
574                         // HERE WE GO ...
575
576                         else if(!strncmp(word[1],"ins_m_atoms",11)) {
577                                 imp.element1=atoi(word[2]);
578                                 imp.element2=atoi(word[3]);
579                                 imp.amount1=atoi(word[4]);
580                                 imp.amount2=atoi(word[5]);
581                                 imp.brand1=atoi(word[6]);
582                                 imp.brand2=atoi(word[7]);
583                                 imp.crmin=atof(word[8]);
584                                 imp.crmax=atof(word[9]);
585                                 /* do this later ...
586                                 for(i=0;i<strlen(word[8]);i++) {
587                                         switch(word[8][i]) {
588                                                 case 'b':
589                                                         imp.attr|=ATOM_ATTR_VB;
590                                                         break;
591                                                 case 'h':
592                                                         imp.attr|=ATOM_ATTR_HB;
593                                                         break;
594                                                 case 'v':
595                                                         imp.attr|=ATOM_ATTR_VA;
596                                                         break;
597                                                 case 'f':
598                                                         imp.attr|=ATOM_ATTR_FP;
599                                                         break;
600                                                 case '1':
601                                                         imp.attr|=ATOM_ATTR_1BP;
602                                                         break;
603                                                 case '2':
604                                                         imp.attr|=ATOM_ATTR_2BP;
605                                                         break;
606                                                 case '3':
607                                                         imp.attr|=ATOM_ATTR_3BP;
608                                                         break;
609                                                 default:
610                                                         break;
611                                         }
612                                 }
613                                 */
614                                 imp.attr1=ATOM_ATTR_HB|ATOM_ATTR_VA|ATOM_ATTR_1BP|ATOM_ATTR_2BP|ATOM_ATTR_3BP|ATOM_ATTR_FP;
615                                 imp.attr2=ATOM_ATTR_HB|ATOM_ATTR_VA|ATOM_ATTR_1BP|ATOM_ATTR_2BP|ATOM_ATTR_3BP|ATOM_ATTR_FP;
616                                 add_stage(mdrun,STAGE_INSERT_MIXED_ATOMS,&imp);
617                         }
618
619
620
621
622
623                         else if(!strncmp(word[1],"continue",8)) {
624                                 cp.runs=atoi(word[2]);
625                                 add_stage(mdrun,STAGE_CONTINUE,&cp);
626                         }
627                         else if(!strncmp(word[1],"anneal",6)) {
628                                 ap.count=0;
629                                 ap.runs=atoi(word[2]);
630                                 ap.dt=atof(word[3]);
631                                 ap.interval=atoi(word[4]);
632                                 add_stage(mdrun,STAGE_ANNEAL,&ap);
633                         }
634                         else if(!strncmp(word[1],"set_temp",8)) {
635                                 if(word[2][0]=='c') {
636                                         stp.type=SET_TEMP_CURRENT;
637                                         stp.val=0.0;
638                                 }
639                                 else {
640                                         stp.type=SET_TEMP_VALUE;
641                                         stp.val=atof(word[2]);
642                                 }
643                                 add_stage(mdrun,STAGE_SET_TEMP,&stp);
644                         }
645                         else if(!strncmp(word[1],"set_timestep",12)) {
646                                 stsp.tau=atof(word[2]);
647                                 add_stage(mdrun,STAGE_SET_TIMESTEP,&stsp);
648                         }
649                         else {
650                                 printf("%s unknown stage type: %s\n",
651                                        ME,word[1]);
652                                 return -1;
653                         }
654                 }
655                 else {
656                         printf("%s unknown keyword '%s', skipped!\n",
657                                ME,word[0]);
658                         continue;
659                 }
660         }
661
662         /* close file */
663         close(fd);
664
665         return 0;
666 }
667
668 int check_pressure(t_moldyn *moldyn,t_mdrun *mdrun) {
669
670         double delta;
671
672         if(!(mdrun->sattr&SATTR_PRELAX)) {
673                 return TRUE;
674         }
675
676         delta=moldyn->p_avg-moldyn->p_ref;
677
678         if(delta<0)
679                 delta=-delta;
680
681         if(delta>mdrun->dp)
682                 return FALSE;
683
684         return TRUE;
685 }
686
687 int check_temperature(t_moldyn *moldyn,t_mdrun *mdrun) {
688
689         double delta;
690
691         if(!(mdrun->sattr&SATTR_TRELAX))
692                 return TRUE;
693
694         delta=moldyn->t_avg-moldyn->t_ref;
695
696         if(delta<0)
697                 delta=-delta;
698
699         if(delta>mdrun->dt)
700                 return FALSE;
701
702         return TRUE;
703 }
704
705 int displace_atom(t_moldyn *moldyn,t_mdrun *mdrun) {
706
707         t_displace_atom_params *dap;
708         t_stage *stage;
709         t_atom *atom;
710
711         stage=mdrun->stage.current->data;
712         dap=stage->params;
713
714         atom=&(moldyn->atom[dap->nr]);
715         atom->r.x+=dap->dx;
716         atom->r.y+=dap->dy;
717         atom->r.z+=dap->dz;
718
719         return 0;
720 }
721
722 int insert_atoms(t_moldyn *moldyn,t_mdrun *mdrun) {
723
724         t_insert_atoms_params *iap;
725         t_stage *stage;
726         t_atom *atom;
727         t_3dvec r,v,dist;
728         double d,dmin,o;
729         int cnt,i;
730         double x,y,z;
731         double x0,y0,z0;
732         u8 cr_check,run;
733         
734         stage=mdrun->stage.current->data;
735         iap=stage->params;
736
737         cr_check=FALSE;
738
739         v.x=0.0; v.y=0.0; v.z=0.0;
740         x=0; y=0; z=0;
741         o=0; dmin=0;
742
743         switch(mdrun->lattice) {
744                 case CUBIC:
745                         o=0.5*mdrun->lc;
746                         break;
747                 case FCC:
748                         o=0.25*mdrun->lc;
749                         break;
750                 case DIAMOND:
751                 case ZINCBLENDE:
752                         o=0.125*mdrun->lc;
753                         break;
754                 default:
755                         break;
756         }
757
758         switch(iap->type) {
759                 case INS_TOTAL:
760                         x=moldyn->dim.x;
761                         x0=-x/2.0;
762                         y=moldyn->dim.y;
763                         y0=-y/2.0;
764                         z=moldyn->dim.z;
765                         z0=-z/2.0;
766                         cr_check=TRUE;
767                         break;
768                 case INS_REGION:
769                         x=iap->x1-iap->x0;
770                         x0=iap->x0;
771                         y=iap->y1-iap->y0;
772                         y0=iap->y0;
773                         z=iap->z1-iap->z0;
774                         z0=iap->z0;
775                         cr_check=TRUE;
776                         break;
777                 case INS_POS:
778                         x0=iap->x0;
779                         y0=iap->y0;
780                         z0=iap->z0;
781                         cr_check=FALSE;
782                         break;
783                 default:
784                         printf("%s unknown insertion mode: %02x\n",
785                                ME,iap->type);
786                         return -1;
787         }
788
789         cnt=0;
790         while(cnt<iap->ins_atoms) {
791                 run=1;
792                 while(run) {
793                         if(iap->type!=INS_POS) {
794                                 r.x=rand_get_double(&(moldyn->random))*x;
795                                 r.y=rand_get_double(&(moldyn->random))*y;
796                                 r.z=rand_get_double(&(moldyn->random))*z;
797                         }
798                         else {
799                                 r.x=0.0;
800                                 r.y=0.0;
801                                 r.z=0.0;
802                         }
803                         r.x+=x0;
804                         r.y+=y0;
805                         r.z+=z0;
806                         // offset
807                         if(iap->type!=INS_TOTAL) {
808                                 r.x+=o;
809                                 r.y+=o;
810                                 r.z+=o;
811                         }
812                         run=0;
813                         if(cr_check==TRUE) {
814                                 dmin=1000;      // for sure too high!
815                                 for(i=0;i<moldyn->count;i++) {
816                                         atom=&(moldyn->atom[i]);
817                                         v3_sub(&dist,&(atom->r),&r);
818                                         check_per_bound(moldyn,&dist);
819                                         d=v3_absolute_square(&dist);
820                                         if(d<(iap->cr*iap->cr)) {
821                                                 run=1;
822                                                 break;
823                                         }
824                                         if(d<dmin)
825                                                 dmin=d;
826                                 }
827                         }
828                 }
829                 add_atom(moldyn,iap->element,
830                          iap->brand,iap->attr,&r,&v);
831                 printf("%s atom inserted (%d/%d): %f %f %f\n",
832                        ME,(iap->cnt_steps+1)*iap->ins_atoms,
833                        iap->ins_steps*iap->ins_atoms,r.x,r.y,r.z);
834                 printf("  -> d2 = %f/%f\n",dmin,iap->cr*iap->cr);
835                 cnt+=1;
836         }
837
838         return 0;
839 }
840
841 int insert_mixed_atoms(t_moldyn *moldyn,t_mdrun *mdrun) {
842
843         t_stage *stage;
844         t_insert_mixed_atoms_params *imp;
845         t_atom *atom;
846         double x,x0,y,y0,z,z0;
847         double dmin,d,cmin,cmax;
848         u8 retry;
849         t_3dvec r,v,dist;
850         int i;
851         
852
853         stage=mdrun->stage.current->data;
854         imp=stage->params;
855
856         x=moldyn->dim.x;
857         x0=-x/2.0;
858         y=moldyn->dim.y;
859         y0=-y/2.0;
860         z=moldyn->dim.z;
861         z0=-z/2.0;
862
863         v.x=0.0;
864         v.y=0.0;
865         v.z=0.0;
866
867         cmin=imp->crmin*imp->crmin;
868         cmax=imp->crmax*imp->crmax;
869
870         while(imp->amount1|imp->amount2) {
871                 if(imp->amount1) {
872                         retry=1;
873                         while(retry) {
874                                 retry=0;
875                                 r.x=rand_get_double(&(moldyn->random))*x;
876                                 r.y=rand_get_double(&(moldyn->random))*y;
877                                 r.z=rand_get_double(&(moldyn->random))*z;
878                                 r.x+=x0;
879                                 r.y+=y0;
880                                 r.z+=z0;
881                                 dmin=1000.0;    // for sure too high!
882                                 for(i=0;i<moldyn->count;i++) {
883                                         atom=&(moldyn->atom[i]);
884                                         v3_sub(&dist,&(atom->r),&r);
885                                         check_per_bound(moldyn,&dist);
886                                         d=v3_absolute_square(&dist);
887                                         if(d<cmin) {
888                                                 retry=1;
889                                                 break;
890                                         }
891                                         if(d<dmin)
892                                                 dmin=d;
893                                 }
894                                 if(dmin!=1000.0)
895                                         if(dmin>cmax)
896                                                 retry=1;
897                         }
898                         add_atom(moldyn,imp->element1,
899                                  imp->brand1,imp->attr1,&r,&v);
900                         printf("%s (mixed) atom inserted (%d): %f %f %f\n",
901                                ME,imp->amount1,r.x,r.y,r.z);
902                         printf("  -> d2 = %f/%f/%f\n",dmin,cmin,cmax);
903                         imp->amount1-=1;
904                 }
905                 if(imp->amount2) {
906                         retry=1;
907                         while(retry) {
908                                 retry=0;
909                                 r.x=rand_get_double(&(moldyn->random))*x;
910                                 r.y=rand_get_double(&(moldyn->random))*y;
911                                 r.z=rand_get_double(&(moldyn->random))*z;
912                                 r.x+=x0;
913                                 r.y+=y0;
914                                 r.z+=z0;
915                                 dmin=1000.0;    // for sure too high!
916                                 for(i=0;i<moldyn->count;i++) {
917                                         atom=&(moldyn->atom[i]);
918                                         v3_sub(&dist,&(atom->r),&r);
919                                         check_per_bound(moldyn,&dist);
920                                         d=v3_absolute_square(&dist);
921                                         if(d<cmin) {
922                                                 retry=1;
923                                                 break;
924                                         }
925                                         if(d<dmin)
926                                                 dmin=d;
927                                 }
928                                 if(dmin!=1000.0)
929                                         if(dmin>cmax)
930                                                 retry=1;
931                         }
932                         add_atom(moldyn,imp->element2,
933                                  imp->brand2,imp->attr2,&r,&v);
934                         printf("%s (mixed) atom inserted (%d): %f %f %f\n",
935                                ME,imp->amount2,r.x,r.y,r.z);
936                         printf("  -> d2 = %f/%f/%f\n",dmin,cmin,cmax);
937                         imp->amount2-=1;
938                 }
939         }
940
941         return 0;
942 }
943
944 int chaatr(t_moldyn *moldyn,t_mdrun *mdrun) {
945
946         t_stage *stage;
947         t_chaattr_params *cap;
948         t_atom *atom;
949         int i;
950
951         stage=mdrun->stage.current->data;
952         cap=stage->params;
953
954         for(i=0;i<moldyn->count;i++) {
955                 atom=&(moldyn->atom[i]);
956                 if(cap->type&CHAATTR_ELEMENT) {
957                         if(cap->element!=atom->element)
958                                 continue;
959                 }
960                 if(cap->type&CHAATTR_REGION) {
961                         if(cap->x0<atom->r.x)
962                                 continue;
963                         if(cap->y0<atom->r.y)
964                                 continue;
965                         if(cap->z0<atom->r.z)
966                                 continue;
967                         if(cap->x1>atom->r.x)
968                                 continue;
969                         if(cap->y1>atom->r.y)
970                                 continue;
971                         if(cap->z1>atom->r.z)
972                                 continue;
973                 }
974                 atom->attr=cap->attr;
975         }
976
977         return 0;
978 }
979
980 int chsattr(t_moldyn *moldyn,t_mdrun *mdrun) {
981
982         t_stage *stage;
983         t_chsattr_params *csp;
984
985         stage=mdrun->stage.current->data;
986         csp=stage->params;
987
988         if(csp->type&CHSATTR_PCTRL) {
989                 if(csp->ptau>0)
990                         set_p_scale(moldyn,P_SCALE_BERENDSEN,csp->ptau);
991                 else
992                         set_p_scale(moldyn,P_SCALE_BERENDSEN,csp->ptau);
993         }
994         if(csp->type&CHSATTR_TCTRL) {
995                 if(csp->ttau>0)
996                         set_t_scale(moldyn,T_SCALE_BERENDSEN,csp->ttau);
997                 else
998                         set_t_scale(moldyn,T_SCALE_BERENDSEN,csp->ttau);
999         }
1000         if(csp->type&CHSATTR_PRELAX) {
1001                 if(csp->dp<0)
1002                         mdrun->sattr&=(~(SATTR_PRELAX));
1003                 else
1004                         mdrun->sattr|=SATTR_PRELAX;
1005                 mdrun->dp=csp->dp;
1006         }
1007         if(csp->type&CHSATTR_TRELAX) {
1008                 if(csp->dt<0)
1009                         mdrun->sattr&=(~(SATTR_TRELAX));
1010                 else
1011                         mdrun->sattr|=SATTR_TRELAX;
1012                 mdrun->dt=csp->dt;
1013         }
1014         if(csp->type&CHSATTR_AVGRST) {
1015                 if(csp->avgrst)
1016                         mdrun->sattr|=SATTR_AVGRST;
1017                 else
1018                         mdrun->sattr&=(~(SATTR_AVGRST));
1019         }
1020         if(csp->type&CHSATTR_RSTEPS) {
1021                 mdrun->relax_steps=csp->rsteps;
1022         }
1023
1024         return 0;
1025 }
1026
1027 #define stage_print(m)  if(!(stage->executed)) \
1028                                 printf("%s",m)
1029
1030 int mdrun_hook(void *ptr1,void *ptr2) {
1031
1032         t_moldyn *moldyn;
1033         t_mdrun *mdrun;
1034         t_stage *stage;
1035         t_list *sl;
1036         int steps;
1037         u8 change_stage;
1038         t_3dvec o;
1039
1040         t_insert_atoms_params *iap;
1041         t_insert_mixed_atoms_params *imp;
1042         t_continue_params *cp;
1043         t_anneal_params *ap;
1044         t_set_temp_params *stp;
1045         t_set_timestep_params *stsp;
1046         t_fill_params *fp;
1047
1048         moldyn=ptr1;
1049         mdrun=ptr2;
1050
1051         sl=&(mdrun->stage);
1052
1053         change_stage=FALSE;
1054
1055         /* return immediately if there are no more stage */
1056         if(sl->current==NULL)
1057                 return 0;
1058
1059         /* get stage description */
1060         stage=sl->current->data;
1061
1062         /* steps in next schedule */
1063         steps=mdrun->relax_steps;
1064
1065         /* check whether relaxation steps are necessary */
1066         if((check_pressure(moldyn,mdrun)==TRUE)&\
1067            (check_temperature(moldyn,mdrun)==TRUE)) {
1068         
1069                 /* be verbose */
1070                 stage_print("\n###########################\n");
1071                 stage_print("# [mdrun] executing stage #\n");
1072                 stage_print("###########################\n\n");
1073                 
1074                 /* stage specific stuff */
1075                 switch(stage->type) {
1076                         case STAGE_DISPLACE_ATOM:
1077                                 stage_print("  -> displace atom\n\n");
1078                                 displace_atom(moldyn,mdrun);
1079                                 change_stage=TRUE;
1080                                 break;
1081                         case STAGE_INSERT_ATOMS:
1082                                 stage_print("  -> insert atoms\n\n");
1083                                 iap=stage->params;
1084                                 if(iap->cnt_steps==iap->ins_steps) {
1085                                         change_stage=TRUE;
1086                                         break;
1087                                 }
1088                                 insert_atoms(moldyn,mdrun);
1089                                 iap->cnt_steps+=1;
1090                                 break;
1091
1092
1093
1094                         case STAGE_INSERT_MIXED_ATOMS:
1095                                 stage_print("  -> insert mixed atoms\n\n");
1096                                 imp=stage->params;
1097                                 insert_mixed_atoms(moldyn,mdrun);
1098                                 change_stage=TRUE;
1099                                 break;
1100
1101
1102
1103                         case STAGE_CONTINUE:
1104                                 stage_print("  -> continue\n\n");
1105                                 if(stage->executed==TRUE) {
1106                                         change_stage=TRUE;
1107                                         break;
1108                                 }
1109                                 cp=stage->params;
1110                                 steps=cp->runs;
1111                                 break;
1112                         case STAGE_ANNEAL:
1113                                 stage_print("  -> anneal\n\n");
1114                                 ap=stage->params;
1115                                 if(ap->count==ap->runs) {
1116                                         change_stage=TRUE;
1117                                         break;
1118                                 }
1119                                 if(moldyn->t_ref+ap->dt>=0.0)
1120                                         set_temperature(moldyn,
1121                                                         moldyn->t_ref+ap->dt);
1122                                 ap->count+=1;
1123                                 steps=ap->interval;
1124                                 break;
1125                         case STAGE_CHAATTR:
1126                                 stage_print("  -> change atom attributes\n\n");
1127                                 chaatr(moldyn,mdrun);
1128                                 change_stage=TRUE;
1129                                 break;
1130                         case STAGE_CHSATTR:
1131                                 stage_print("  -> change sys attributes\n\n");
1132                                 chsattr(moldyn,mdrun);
1133                                 change_stage=TRUE;
1134                                 break;
1135                         case STAGE_SET_TEMP:
1136                                 stage_print("  -> set temperature\n\n");
1137                                 stp=stage->params;
1138                                 if(stp->type&SET_TEMP_CURRENT) {
1139                                         set_temperature(moldyn,moldyn->t_avg);
1140                                 }
1141                                 else {
1142                                         set_temperature(moldyn,stp->val);
1143                                 }
1144                                 change_stage=TRUE;
1145                                 break;
1146                         case STAGE_SET_TIMESTEP:
1147                                 stage_print("  -> set timestep\n\n");
1148                                 stsp=stage->params;
1149                                 mdrun->timestep=stsp->tau;
1150                                 change_stage=TRUE;
1151                                 break;
1152                         case STAGE_FILL:
1153                                 stage_print("  -> fill lattice\n\n");
1154                                 fp=stage->params;
1155                                 switch(fp->lattice) {
1156                                         case ZINCBLENDE:
1157
1158                                         o.x=0.5*0.25*fp->lc;
1159                                         o.y=o.x;
1160                                         o.z=o.x;
1161                                         create_lattice(moldyn,
1162                                                        FCC,fp->lc,
1163                                                        mdrun->element1,
1164                                                        DEFAULT_ATOM_ATTR,0,
1165                                                        fp->lx,fp->ly,fp->lz,
1166                                                        &o,
1167                                                        &(fp->p_params),
1168                                                        &(fp->d_params));
1169                                         o.x+=0.25*fp->lc;
1170                                         o.y=o.x;
1171                                         o.z=o.x;
1172                                         create_lattice(moldyn,
1173                                                        FCC,fp->lc,
1174                                                        mdrun->element2,
1175                                                        DEFAULT_ATOM_ATTR,1,
1176                                                        fp->lx,fp->ly,fp->lz,
1177                                                        &o,
1178                                                        &(fp->p_params),
1179                                                        &(fp->d_params));
1180                                         break;
1181
1182                                         default:
1183
1184                                         create_lattice(moldyn,
1185                                                        fp->lattice,fp->lc,
1186                                                        mdrun->element1,
1187                                                        DEFAULT_ATOM_ATTR,0,
1188                                                        fp->lx,fp->ly,fp->lz,
1189                                                        NULL,
1190                                                        &(fp->p_params),
1191                                                        &(fp->d_params));
1192                                         break;
1193                                 }
1194                                 moldyn_bc_check(moldyn);
1195                                 change_stage=TRUE;
1196                                 break;
1197                         case STAGE_THERMAL_INIT:
1198                                 stage_print("  -> thermal init\n\n");
1199                                 thermal_init(moldyn,TRUE);
1200                                 change_stage=TRUE;
1201                                 break;
1202                         default:
1203                                 printf("%s unknwon stage type\n",ME);
1204                                 break;
1205                 }
1206         
1207                 /* mark as executed */
1208                 stage->executed=TRUE;
1209         
1210                 /* change state */
1211                 if(change_stage==TRUE) {
1212                         printf("%s finished stage\n",ME);
1213                         if(list_next_f(sl)==L_NO_NEXT_ELEMENT) {
1214                                 printf("%s no more stages\n",ME);
1215                                 return 0;
1216                         }
1217                         steps=0;
1218                 }
1219
1220         }
1221         else {
1222
1223                 /* averages */
1224                 if(mdrun->sattr&SATTR_AVGRST)
1225                         average_reset(moldyn);
1226
1227         }
1228
1229         /* continue simulation */
1230         moldyn_add_schedule(moldyn,steps,mdrun->timestep);
1231
1232         return 0;
1233 }
1234
1235 int main(int argc,char **argv) {
1236
1237         t_mdrun mdrun;
1238         t_moldyn moldyn;
1239         //t_3dvec o;
1240
1241         /* clear structs */
1242         memset(&mdrun,0,sizeof(t_mdrun));
1243         memset(&moldyn,0,sizeof(t_moldyn));
1244
1245         /* parse arguments */
1246         if(mdrun_parse_argv(&mdrun,argc,argv)<0)
1247                 return -1;
1248
1249         /* initialize list system */
1250         list_init_f(&(mdrun.stage));
1251
1252         /* parse config file */
1253         mdrun_parse_config(&mdrun);
1254
1255         /* reset the stage list */
1256         list_reset_f(&(mdrun.stage));
1257
1258         /* sanity check! */
1259
1260         /* prepare simulation */
1261
1262         if(mdrun.continue_file[0]) {
1263                 // read the save file
1264                 moldyn_read_save_file(&moldyn,mdrun.continue_file);
1265                 // manualaadjusting some stuff
1266                 moldyn.argc=argc;
1267                 moldyn.args=argv;
1268                 rand_init(&(moldyn.random),NULL,1);
1269                 moldyn.random.status|=RAND_STAT_VERBOSE;
1270         }
1271         else {
1272                 moldyn_init(&moldyn,argc,argv);
1273         }
1274         
1275         if(set_int_alg(&moldyn,mdrun.intalgo)<0)
1276                 return -1;
1277
1278         /* potential */
1279         set_cutoff(&moldyn,mdrun.cutoff);
1280         if(set_potential(&moldyn,mdrun.potential)<0)
1281                 return -1;
1282         switch(mdrun.potential) {
1283                 case MOLDYN_POTENTIAL_AM:
1284                         albe_mult_set_params(&moldyn,
1285                                              mdrun.element1,
1286                                              mdrun.element2);
1287                         break;
1288                 case MOLDYN_POTENTIAL_TM:
1289                         tersoff_mult_set_params(&moldyn,
1290                                                 mdrun.element1,
1291                                                 mdrun.element2);
1292                         break;
1293                 case MOLDYN_POTENTIAL_HO:
1294                         harmonic_oscillator_set_params(&moldyn,mdrun.element1);
1295                         break;
1296                 case MOLDYN_POTENTIAL_LJ:
1297                         lennard_jones_set_params(&moldyn,mdrun.element1);
1298                         break;
1299                 default:
1300                         printf("%s unknown potential: %02x\n",
1301                                ME,mdrun.potential);
1302                         return -1;
1303         }
1304
1305         /* if it is a continue run, reset schedule and skip lattice init */
1306         if(mdrun.continue_file[0]) {
1307                 memset(&(moldyn.schedule),0,sizeof(t_moldyn_schedule));
1308                 goto addsched;
1309         }
1310
1311         /* initial lattice and dimensions */
1312         set_dim(&moldyn,mdrun.dim.x,mdrun.dim.y,mdrun.dim.z,mdrun.vis);
1313         set_pbc(&moldyn,mdrun.pbcx,mdrun.pbcy,mdrun.pbcz);
1314         /* replaced by fill stage !! 
1315         switch(mdrun.lattice) {
1316                 case FCC:
1317                         create_lattice(&moldyn,FCC,mdrun.lc,mdrun.fill_element,
1318                                        mdrun.m1,DEFAULT_ATOM_ATTR,
1319                                        mdrun.fill_brand,mdrun.lx,
1320                                        mdrun.ly,mdrun.lz,NULL,0,NULL);
1321                         break;
1322                 case DIAMOND:
1323                         create_lattice(&moldyn,DIAMOND,mdrun.lc,
1324                                        mdrun.fill_element,
1325                                        mdrun.m1,DEFAULT_ATOM_ATTR,
1326                                        mdrun.fill_brand,mdrun.lx,
1327                                        mdrun.ly,mdrun.lz,NULL,0,NULL);
1328                         break;
1329                 case ZINCBLENDE:
1330                         o.x=0.5*0.25*mdrun.lc; o.y=o.x; o.z=o.x;
1331                         create_lattice(&moldyn,FCC,mdrun.lc,mdrun.element1,
1332                                        mdrun.m1,DEFAULT_ATOM_ATTR,0,mdrun.lx,
1333                                        mdrun.ly,mdrun.lz,&o,0,NULL);
1334                         o.x+=0.25*mdrun.lc; o.y=o.x; o.z=o.x;
1335                         create_lattice(&moldyn,FCC,mdrun.lc,mdrun.element2,
1336                                        mdrun.m2,DEFAULT_ATOM_ATTR,1,mdrun.lx,
1337                                        mdrun.ly,mdrun.lz,&o,0,NULL);
1338                         break;
1339                 case NONE:
1340                         set_nn_dist(&moldyn,mdrun.nnd);
1341                         break;
1342                 default:
1343                         printf("%s unknown lattice type: %02x\n",
1344                                ME,mdrun.lattice);
1345                         return -1;
1346         }
1347         moldyn_bc_check(&moldyn);
1348         replaced by fill stage !! */
1349
1350         /* temperature and pressure */
1351         set_temperature(&moldyn,mdrun.temperature);
1352         set_pressure(&moldyn,mdrun.pressure);
1353         /* replaced thermal_init stage
1354         thermal_init(&moldyn,TRUE);
1355         */
1356
1357 addsched:
1358         /* first schedule */
1359         moldyn_add_schedule(&moldyn,mdrun.prerun,mdrun.timestep);
1360
1361         /* log */
1362         moldyn_set_log_dir(&moldyn,mdrun.sdir);
1363         moldyn_set_report(&moldyn,"CHANGE ME","CHANGE ME TOO");
1364         if(mdrun.elog)
1365                 moldyn_set_log(&moldyn,LOG_TOTAL_ENERGY,mdrun.elog);
1366         if(mdrun.tlog)
1367                 moldyn_set_log(&moldyn,LOG_TEMPERATURE,mdrun.tlog);
1368         if(mdrun.plog)
1369                 moldyn_set_log(&moldyn,LOG_PRESSURE,mdrun.plog);
1370         if(mdrun.vlog)
1371                 moldyn_set_log(&moldyn,LOG_VOLUME,mdrun.vlog);
1372         if(mdrun.visualize)
1373                 moldyn_set_log(&moldyn,VISUAL_STEP,mdrun.visualize);
1374         if(mdrun.save)
1375                 moldyn_set_log(&moldyn,SAVE_STEP,mdrun.save);
1376         moldyn_set_log(&moldyn,CREATE_REPORT,0);
1377         set_avg_skip(&moldyn,mdrun.avgskip);
1378
1379         /* prepare the hook function */
1380         moldyn_set_schedule_hook(&moldyn,&mdrun_hook,&mdrun);
1381
1382         /* run the simulation */
1383         moldyn_integrate(&moldyn);
1384
1385         /* shutdown */
1386         moldyn_shutdown(&moldyn);
1387         del_stages(&mdrun);
1388         list_destroy_f(&(mdrun.stage));
1389
1390         return 0;
1391 }