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