regular checkin of logfile
[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                                                 switch(word[8][0]) {
554
555                                                 case 't':
556                                                         iap.type=INS_TOTAL;
557                                                         iap.cr=atof(word[9]);
558                                                         break;
559                                                 case 'r':
560                                                         iap.type=INS_RECT;
561                                                         iap.x0=atof(word[9]);
562                                                         iap.y0=atof(word[10]);
563                                                         iap.z0=atof(word[11]);
564                                                         iap.x1=atof(word[12]);
565                                                         iap.y1=atof(word[13]);
566                                                         iap.z1=atof(word[14]);
567                                                         iap.cr=atof(word[15]);
568                                                         break;
569                                                 case 's':
570                                                         iap.type=INS_SPHERE;
571                                                         iap.x0=atof(word[9]);
572                                                         iap.y0=atof(word[10]);
573                                                         iap.z0=atof(word[11]);
574                                                         iap.x1=atof(word[12]);
575                                                         iap.cr=atof(word[13]);
576                                                         break;
577                                                 default:
578                                                         break;
579                                                 }
580                                         default:
581                                                 break;
582                                 }
583                                 add_stage(mdrun,STAGE_INSERT_ATOMS,&iap);
584                         }
585
586
587                         // HERE WE GO ...
588
589                         else if(!strncmp(word[1],"ins_m_atoms",11)) {
590                                 imp.element1=atoi(word[2]);
591                                 imp.element2=atoi(word[3]);
592                                 imp.amount1=atoi(word[4]);
593                                 imp.amount2=atoi(word[5]);
594                                 imp.brand1=atoi(word[6]);
595                                 imp.brand2=atoi(word[7]);
596                                 imp.crmin=atof(word[8]);
597                                 imp.crmax=atof(word[9]);
598                                 /* do this later ...
599                                 for(i=0;i<strlen(word[8]);i++) {
600                                         switch(word[8][i]) {
601                                                 case 'b':
602                                                         imp.attr|=ATOM_ATTR_VB;
603                                                         break;
604                                                 case 'h':
605                                                         imp.attr|=ATOM_ATTR_HB;
606                                                         break;
607                                                 case 'v':
608                                                         imp.attr|=ATOM_ATTR_VA;
609                                                         break;
610                                                 case 'f':
611                                                         imp.attr|=ATOM_ATTR_FP;
612                                                         break;
613                                                 case '1':
614                                                         imp.attr|=ATOM_ATTR_1BP;
615                                                         break;
616                                                 case '2':
617                                                         imp.attr|=ATOM_ATTR_2BP;
618                                                         break;
619                                                 case '3':
620                                                         imp.attr|=ATOM_ATTR_3BP;
621                                                         break;
622                                                 default:
623                                                         break;
624                                         }
625                                 }
626                                 */
627                                 imp.attr1=ATOM_ATTR_HB|ATOM_ATTR_VA|ATOM_ATTR_1BP|ATOM_ATTR_2BP|ATOM_ATTR_3BP|ATOM_ATTR_FP;
628                                 imp.attr2=ATOM_ATTR_HB|ATOM_ATTR_VA|ATOM_ATTR_1BP|ATOM_ATTR_2BP|ATOM_ATTR_3BP|ATOM_ATTR_FP;
629                                 add_stage(mdrun,STAGE_INSERT_MIXED_ATOMS,&imp);
630                         }
631
632
633
634
635
636                         else if(!strncmp(word[1],"continue",8)) {
637                                 cp.runs=atoi(word[2]);
638                                 add_stage(mdrun,STAGE_CONTINUE,&cp);
639                         }
640                         else if(!strncmp(word[1],"anneal",6)) {
641                                 ap.count=0;
642                                 ap.runs=atoi(word[2]);
643                                 ap.dt=atof(word[3]);
644                                 ap.interval=atoi(word[4]);
645                                 add_stage(mdrun,STAGE_ANNEAL,&ap);
646                         }
647                         else if(!strncmp(word[1],"set_temp",8)) {
648                                 if(word[2][0]=='c') {
649                                         stp.type=SET_TEMP_CURRENT;
650                                         stp.val=0.0;
651                                 }
652                                 else {
653                                         stp.type=SET_TEMP_VALUE;
654                                         stp.val=atof(word[2]);
655                                 }
656                                 add_stage(mdrun,STAGE_SET_TEMP,&stp);
657                         }
658                         else if(!strncmp(word[1],"set_timestep",12)) {
659                                 stsp.tau=atof(word[2]);
660                                 add_stage(mdrun,STAGE_SET_TIMESTEP,&stsp);
661                         }
662                         else {
663                                 printf("%s unknown stage type: %s\n",
664                                        ME,word[1]);
665                                 return -1;
666                         }
667                 }
668                 else {
669                         printf("%s unknown keyword '%s', skipped!\n",
670                                ME,word[0]);
671                         continue;
672                 }
673         }
674
675         /* close file */
676         close(fd);
677
678         return 0;
679 }
680
681 int check_pressure(t_moldyn *moldyn,t_mdrun *mdrun) {
682
683         double delta;
684
685         if(!(mdrun->sattr&SATTR_PRELAX)) {
686                 return TRUE;
687         }
688
689         delta=moldyn->p_avg-moldyn->p_ref;
690
691         if(delta<0)
692                 delta=-delta;
693
694         if(delta>mdrun->dp)
695                 return FALSE;
696
697         return TRUE;
698 }
699
700 int check_temperature(t_moldyn *moldyn,t_mdrun *mdrun) {
701
702         double delta;
703
704         if(!(mdrun->sattr&SATTR_TRELAX))
705                 return TRUE;
706
707         delta=moldyn->t_avg-moldyn->t_ref;
708
709         if(delta<0)
710                 delta=-delta;
711
712         if(delta>mdrun->dt)
713                 return FALSE;
714
715         return TRUE;
716 }
717
718 int displace_atom(t_moldyn *moldyn,t_mdrun *mdrun) {
719
720         t_displace_atom_params *dap;
721         t_stage *stage;
722         t_atom *atom;
723
724         stage=mdrun->stage.current->data;
725         dap=stage->params;
726
727         atom=&(moldyn->atom[dap->nr]);
728         atom->r.x+=dap->dx;
729         atom->r.y+=dap->dy;
730         atom->r.z+=dap->dz;
731
732         return 0;
733 }
734
735 int insert_atoms(t_moldyn *moldyn,t_mdrun *mdrun) {
736
737         t_insert_atoms_params *iap;
738         t_stage *stage;
739         t_atom *atom;
740         t_3dvec r,v,dist;
741         double d,dmin,o;
742         int cnt,i;
743         double x,y,z;
744         double x0,y0,z0;
745         u8 cr_check,run;
746         
747         stage=mdrun->stage.current->data;
748         iap=stage->params;
749
750         cr_check=FALSE;
751
752         v.x=0.0; v.y=0.0; v.z=0.0;
753         x=0; y=0; z=0;
754         o=0; dmin=0;
755
756         switch(mdrun->lattice) {
757                 case CUBIC:
758                         o=0.5*mdrun->lc;
759                         break;
760                 case FCC:
761                         o=0.25*mdrun->lc;
762                         break;
763                 case DIAMOND:
764                 case ZINCBLENDE:
765                         o=0.125*mdrun->lc;
766                         break;
767                 default:
768                         break;
769         }
770
771         switch(iap->type) {
772                 case INS_TOTAL:
773                         x=moldyn->dim.x;
774                         x0=-x/2.0;
775                         y=moldyn->dim.y;
776                         y0=-y/2.0;
777                         z=moldyn->dim.z;
778                         z0=-z/2.0;
779                         cr_check=TRUE;
780                         break;
781                 case INS_RECT:
782                         x=iap->x1-iap->x0;
783                         x0=iap->x0;
784                         y=iap->y1-iap->y0;
785                         y0=iap->y0;
786                         z=iap->z1-iap->z0;
787                         z0=iap->z0;
788                         cr_check=TRUE;
789                         break;
790                 case INS_SPHERE:
791                         x=2.0*iap->x1;
792                         x0=iap->x0-iap->x1;
793                         y=x;
794                         y0=iap->y0-iap->x1;
795                         z=x;
796                         z0=iap->z0-iap->x1;
797                         cr_check=TRUE;
798                         break;
799                 case INS_POS:
800                         x0=iap->x0;
801                         y0=iap->y0;
802                         z0=iap->z0;
803                         cr_check=FALSE;
804                         break;
805                 default:
806                         printf("%s unknown insertion mode: %02x\n",
807                                ME,iap->type);
808                         return -1;
809         }
810
811         cnt=0;
812         while(cnt<iap->ins_atoms) {
813                 run=1;
814                 while(run) {
815                         if(iap->type!=INS_POS) {
816                                 r.x=rand_get_double(&(moldyn->random))*x;
817                                 r.y=rand_get_double(&(moldyn->random))*y;
818                                 r.z=rand_get_double(&(moldyn->random))*z;
819                         }
820                         else {
821                                 r.x=0.0;
822                                 r.y=0.0;
823                                 r.z=0.0;
824                         }
825                         r.x+=x0;
826                         r.y+=y0;
827                         r.z+=z0;
828                         // offset
829                         if(iap->type!=INS_TOTAL) {
830                                 r.x+=o;
831                                 r.y+=o;
832                                 r.z+=o;
833                         }
834                         run=0;
835                         if(cr_check==TRUE) {
836                                 dmin=1000;      // for sure too high!
837                                 for(i=0;i<moldyn->count;i++) {
838                                         atom=&(moldyn->atom[i]);
839                                         v3_sub(&dist,&(atom->r),&r);
840                                         check_per_bound(moldyn,&dist);
841                                         d=v3_absolute_square(&dist);
842                                         if(d<(iap->cr*iap->cr)) {
843                                                 run=1;
844                                                 break;
845                                         }
846                                         if(d<dmin)
847                                                 dmin=d;
848                                 }
849                         }
850                         if(iap->type==INS_SPHERE) {
851                                 if((r.x-iap->x0)*(r.x-iap->x0)+
852                                    (r.y-iap->y0)*(r.y-iap->y0)+
853                                    (r.z-iap->z0)*(r.z-iap->z0)>
854                                    (iap->x1*iap->x1)) {
855                                         run=1;
856                                 }
857                         }
858                 }
859                 add_atom(moldyn,iap->element,
860                          iap->brand,iap->attr,&r,&v);
861                 printf("%s atom inserted (%d/%d): %f %f %f\n",
862                        ME,(iap->cnt_steps+1)*iap->ins_atoms,
863                        iap->ins_steps*iap->ins_atoms,r.x,r.y,r.z);
864                 printf("  -> d2 = %f/%f\n",dmin,iap->cr*iap->cr);
865                 cnt+=1;
866         }
867
868         return 0;
869 }
870
871 int insert_mixed_atoms(t_moldyn *moldyn,t_mdrun *mdrun) {
872
873         t_stage *stage;
874         t_insert_mixed_atoms_params *imp;
875         t_atom *atom;
876         double x,x0,y,y0,z,z0;
877         double dmin,d,cmin,cmax;
878         u8 retry;
879         t_3dvec r,v,dist;
880         int i;
881         
882
883         stage=mdrun->stage.current->data;
884         imp=stage->params;
885
886         x=moldyn->dim.x;
887         x0=-x/2.0;
888         y=moldyn->dim.y;
889         y0=-y/2.0;
890         z=moldyn->dim.z;
891         z0=-z/2.0;
892
893         v.x=0.0;
894         v.y=0.0;
895         v.z=0.0;
896
897         cmin=imp->crmin*imp->crmin;
898         cmax=imp->crmax*imp->crmax;
899
900         while(imp->amount1|imp->amount2) {
901                 if(imp->amount1) {
902                         retry=1;
903                         while(retry) {
904                                 retry=0;
905                                 r.x=rand_get_double(&(moldyn->random))*x;
906                                 r.y=rand_get_double(&(moldyn->random))*y;
907                                 r.z=rand_get_double(&(moldyn->random))*z;
908                                 r.x+=x0;
909                                 r.y+=y0;
910                                 r.z+=z0;
911                                 dmin=1000.0;    // for sure too high!
912                                 for(i=0;i<moldyn->count;i++) {
913                                         atom=&(moldyn->atom[i]);
914                                         v3_sub(&dist,&(atom->r),&r);
915                                         check_per_bound(moldyn,&dist);
916                                         d=v3_absolute_square(&dist);
917                                         if(d<cmin) {
918                                                 retry=1;
919                                                 break;
920                                         }
921                                         if(d<dmin)
922                                                 dmin=d;
923                                 }
924                                 if(dmin!=1000.0)
925                                         if(dmin>cmax)
926                                                 retry=1;
927                         }
928                         add_atom(moldyn,imp->element1,
929                                  imp->brand1,imp->attr1,&r,&v);
930                         printf("%s (mixed) atom inserted (%d): %f %f %f\n",
931                                ME,imp->amount1,r.x,r.y,r.z);
932                         printf("  -> d2 = %f/%f/%f\n",dmin,cmin,cmax);
933                         imp->amount1-=1;
934                 }
935                 if(imp->amount2) {
936                         retry=1;
937                         while(retry) {
938                                 retry=0;
939                                 r.x=rand_get_double(&(moldyn->random))*x;
940                                 r.y=rand_get_double(&(moldyn->random))*y;
941                                 r.z=rand_get_double(&(moldyn->random))*z;
942                                 r.x+=x0;
943                                 r.y+=y0;
944                                 r.z+=z0;
945                                 dmin=1000.0;    // for sure too high!
946                                 for(i=0;i<moldyn->count;i++) {
947                                         atom=&(moldyn->atom[i]);
948                                         v3_sub(&dist,&(atom->r),&r);
949                                         check_per_bound(moldyn,&dist);
950                                         d=v3_absolute_square(&dist);
951                                         if(d<cmin) {
952                                                 retry=1;
953                                                 break;
954                                         }
955                                         if(d<dmin)
956                                                 dmin=d;
957                                 }
958                                 if(dmin!=1000.0)
959                                         if(dmin>cmax)
960                                                 retry=1;
961                         }
962                         add_atom(moldyn,imp->element2,
963                                  imp->brand2,imp->attr2,&r,&v);
964                         printf("%s (mixed) atom inserted (%d): %f %f %f\n",
965                                ME,imp->amount2,r.x,r.y,r.z);
966                         printf("  -> d2 = %f/%f/%f\n",dmin,cmin,cmax);
967                         imp->amount2-=1;
968                 }
969         }
970
971         return 0;
972 }
973
974 int chaatr(t_moldyn *moldyn,t_mdrun *mdrun) {
975
976         t_stage *stage;
977         t_chaattr_params *cap;
978         t_atom *atom;
979         int i;
980
981         stage=mdrun->stage.current->data;
982         cap=stage->params;
983
984         for(i=0;i<moldyn->count;i++) {
985                 atom=&(moldyn->atom[i]);
986                 if(cap->type&CHAATTR_ELEMENT) {
987                         if(cap->element!=atom->element)
988                                 continue;
989                 }
990                 if(cap->type&CHAATTR_REGION) {
991                         if(cap->x0<atom->r.x)
992                                 continue;
993                         if(cap->y0<atom->r.y)
994                                 continue;
995                         if(cap->z0<atom->r.z)
996                                 continue;
997                         if(cap->x1>atom->r.x)
998                                 continue;
999                         if(cap->y1>atom->r.y)
1000                                 continue;
1001                         if(cap->z1>atom->r.z)
1002                                 continue;
1003                 }
1004                 atom->attr=cap->attr;
1005         }
1006
1007         return 0;
1008 }
1009
1010 int chsattr(t_moldyn *moldyn,t_mdrun *mdrun) {
1011
1012         t_stage *stage;
1013         t_chsattr_params *csp;
1014
1015         stage=mdrun->stage.current->data;
1016         csp=stage->params;
1017
1018         if(csp->type&CHSATTR_PCTRL) {
1019                 if(csp->ptau>0)
1020                         set_p_scale(moldyn,P_SCALE_BERENDSEN,csp->ptau);
1021                 else
1022                         set_p_scale(moldyn,P_SCALE_BERENDSEN,csp->ptau);
1023         }
1024         if(csp->type&CHSATTR_TCTRL) {
1025                 if(csp->ttau>0)
1026                         set_t_scale(moldyn,T_SCALE_BERENDSEN,csp->ttau);
1027                 else
1028                         set_t_scale(moldyn,T_SCALE_BERENDSEN,csp->ttau);
1029         }
1030         if(csp->type&CHSATTR_PRELAX) {
1031                 if(csp->dp<0)
1032                         mdrun->sattr&=(~(SATTR_PRELAX));
1033                 else
1034                         mdrun->sattr|=SATTR_PRELAX;
1035                 mdrun->dp=csp->dp;
1036         }
1037         if(csp->type&CHSATTR_TRELAX) {
1038                 if(csp->dt<0)
1039                         mdrun->sattr&=(~(SATTR_TRELAX));
1040                 else
1041                         mdrun->sattr|=SATTR_TRELAX;
1042                 mdrun->dt=csp->dt;
1043         }
1044         if(csp->type&CHSATTR_AVGRST) {
1045                 if(csp->avgrst)
1046                         mdrun->sattr|=SATTR_AVGRST;
1047                 else
1048                         mdrun->sattr&=(~(SATTR_AVGRST));
1049         }
1050         if(csp->type&CHSATTR_RSTEPS) {
1051                 mdrun->relax_steps=csp->rsteps;
1052         }
1053
1054         return 0;
1055 }
1056
1057 #define stage_print(m)  if(!(stage->executed)) \
1058                                 printf("%s",m)
1059
1060 int mdrun_hook(void *ptr1,void *ptr2) {
1061
1062         t_moldyn *moldyn;
1063         t_mdrun *mdrun;
1064         t_stage *stage;
1065         t_list *sl;
1066         int steps;
1067         u8 change_stage;
1068         t_3dvec o;
1069
1070         t_insert_atoms_params *iap;
1071         t_insert_mixed_atoms_params *imp;
1072         t_continue_params *cp;
1073         t_anneal_params *ap;
1074         t_set_temp_params *stp;
1075         t_set_timestep_params *stsp;
1076         t_fill_params *fp;
1077
1078         moldyn=ptr1;
1079         mdrun=ptr2;
1080
1081         sl=&(mdrun->stage);
1082
1083         change_stage=FALSE;
1084
1085         /* return immediately if there are no more stage */
1086         if(sl->current==NULL)
1087                 return 0;
1088
1089         /* get stage description */
1090         stage=sl->current->data;
1091
1092         /* steps in next schedule */
1093         steps=mdrun->relax_steps;
1094
1095         /* check whether relaxation steps are necessary */
1096         if((check_pressure(moldyn,mdrun)==TRUE)&\
1097            (check_temperature(moldyn,mdrun)==TRUE)) {
1098         
1099                 /* be verbose */
1100                 stage_print("\n###########################\n");
1101                 stage_print("# [mdrun] executing stage #\n");
1102                 stage_print("###########################\n\n");
1103                 
1104                 /* stage specific stuff */
1105                 switch(stage->type) {
1106                         case STAGE_DISPLACE_ATOM:
1107                                 stage_print("  -> displace atom\n\n");
1108                                 displace_atom(moldyn,mdrun);
1109                                 change_stage=TRUE;
1110                                 break;
1111                         case STAGE_INSERT_ATOMS:
1112                                 stage_print("  -> insert atoms\n\n");
1113                                 iap=stage->params;
1114                                 if(iap->cnt_steps==iap->ins_steps) {
1115                                         change_stage=TRUE;
1116                                         break;
1117                                 }
1118                                 insert_atoms(moldyn,mdrun);
1119                                 iap->cnt_steps+=1;
1120                                 break;
1121
1122
1123
1124                         case STAGE_INSERT_MIXED_ATOMS:
1125                                 stage_print("  -> insert mixed atoms\n\n");
1126                                 imp=stage->params;
1127                                 insert_mixed_atoms(moldyn,mdrun);
1128                                 change_stage=TRUE;
1129                                 break;
1130
1131
1132
1133                         case STAGE_CONTINUE:
1134                                 stage_print("  -> continue\n\n");
1135                                 if(stage->executed==TRUE) {
1136                                         change_stage=TRUE;
1137                                         break;
1138                                 }
1139                                 cp=stage->params;
1140                                 steps=cp->runs;
1141                                 break;
1142                         case STAGE_ANNEAL:
1143                                 stage_print("  -> anneal\n\n");
1144                                 ap=stage->params;
1145                                 if(ap->count==ap->runs) {
1146                                         change_stage=TRUE;
1147                                         break;
1148                                 }
1149                                 if(moldyn->t_ref+ap->dt>=0.0)
1150                                         set_temperature(moldyn,
1151                                                         moldyn->t_ref+ap->dt);
1152                                 ap->count+=1;
1153                                 steps=ap->interval;
1154                                 break;
1155                         case STAGE_CHAATTR:
1156                                 stage_print("  -> change atom attributes\n\n");
1157                                 chaatr(moldyn,mdrun);
1158                                 change_stage=TRUE;
1159                                 break;
1160                         case STAGE_CHSATTR:
1161                                 stage_print("  -> change sys attributes\n\n");
1162                                 chsattr(moldyn,mdrun);
1163                                 change_stage=TRUE;
1164                                 break;
1165                         case STAGE_SET_TEMP:
1166                                 stage_print("  -> set temperature\n\n");
1167                                 stp=stage->params;
1168                                 if(stp->type&SET_TEMP_CURRENT) {
1169                                         set_temperature(moldyn,moldyn->t_avg);
1170                                 }
1171                                 else {
1172                                         set_temperature(moldyn,stp->val);
1173                                 }
1174                                 change_stage=TRUE;
1175                                 break;
1176                         case STAGE_SET_TIMESTEP:
1177                                 stage_print("  -> set timestep\n\n");
1178                                 stsp=stage->params;
1179                                 mdrun->timestep=stsp->tau;
1180                                 change_stage=TRUE;
1181                                 break;
1182                         case STAGE_FILL:
1183                                 stage_print("  -> fill lattice\n\n");
1184                                 fp=stage->params;
1185                                 switch(fp->lattice) {
1186                                         case ZINCBLENDE:
1187
1188                                         o.x=0.5*0.25*fp->lc;
1189                                         o.y=o.x;
1190                                         o.z=o.x;
1191                                         create_lattice(moldyn,
1192                                                        FCC,fp->lc,
1193                                                        mdrun->element1,
1194                                                        DEFAULT_ATOM_ATTR,0,
1195                                                        fp->lx,fp->ly,fp->lz,
1196                                                        &o,
1197                                                        &(fp->p_params),
1198                                                        &(fp->d_params));
1199                                         o.x+=0.25*fp->lc;
1200                                         o.y=o.x;
1201                                         o.z=o.x;
1202                                         create_lattice(moldyn,
1203                                                        FCC,fp->lc,
1204                                                        mdrun->element2,
1205                                                        DEFAULT_ATOM_ATTR,1,
1206                                                        fp->lx,fp->ly,fp->lz,
1207                                                        &o,
1208                                                        &(fp->p_params),
1209                                                        &(fp->d_params));
1210                                         break;
1211
1212                                         default:
1213
1214                                         create_lattice(moldyn,
1215                                                        fp->lattice,fp->lc,
1216                                                        mdrun->element1,
1217                                                        DEFAULT_ATOM_ATTR,0,
1218                                                        fp->lx,fp->ly,fp->lz,
1219                                                        NULL,
1220                                                        &(fp->p_params),
1221                                                        &(fp->d_params));
1222                                         break;
1223                                 }
1224                                 moldyn_bc_check(moldyn);
1225                                 change_stage=TRUE;
1226                                 break;
1227                         case STAGE_THERMAL_INIT:
1228                                 stage_print("  -> thermal init\n\n");
1229                                 thermal_init(moldyn,TRUE);
1230                                 change_stage=TRUE;
1231                                 break;
1232                         default:
1233                                 printf("%s unknwon stage type\n",ME);
1234                                 break;
1235                 }
1236         
1237                 /* mark as executed */
1238                 stage->executed=TRUE;
1239         
1240                 /* change state */
1241                 if(change_stage==TRUE) {
1242                         printf("%s finished stage\n",ME);
1243                         if(list_next_f(sl)==L_NO_NEXT_ELEMENT) {
1244                                 printf("%s no more stages\n",ME);
1245                                 return 0;
1246                         }
1247                         steps=0;
1248                 }
1249
1250         }
1251         else {
1252
1253                 /* averages */
1254                 if(mdrun->sattr&SATTR_AVGRST)
1255                         average_reset(moldyn);
1256
1257         }
1258
1259         /* continue simulation */
1260         moldyn_add_schedule(moldyn,steps,mdrun->timestep);
1261
1262         return 0;
1263 }
1264
1265 int main(int argc,char **argv) {
1266
1267         t_mdrun mdrun;
1268         t_moldyn moldyn;
1269         //t_3dvec o;
1270
1271         /* clear structs */
1272         memset(&mdrun,0,sizeof(t_mdrun));
1273         memset(&moldyn,0,sizeof(t_moldyn));
1274
1275         /* parse arguments */
1276         if(mdrun_parse_argv(&mdrun,argc,argv)<0)
1277                 return -1;
1278
1279         /* initialize list system */
1280         list_init_f(&(mdrun.stage));
1281
1282         /* parse config file */
1283         mdrun_parse_config(&mdrun);
1284
1285         /* reset the stage list */
1286         list_reset_f(&(mdrun.stage));
1287
1288         /* sanity check! */
1289
1290         /* prepare simulation */
1291
1292         if(mdrun.continue_file[0]) {
1293                 // read the save file
1294                 moldyn_read_save_file(&moldyn,mdrun.continue_file);
1295                 // manualaadjusting some stuff
1296                 moldyn.argc=argc;
1297                 moldyn.args=argv;
1298                 rand_init(&(moldyn.random),NULL,1);
1299                 moldyn.random.status|=RAND_STAT_VERBOSE;
1300         }
1301         else {
1302                 moldyn_init(&moldyn,argc,argv);
1303         }
1304         
1305         if(set_int_alg(&moldyn,mdrun.intalgo)<0)
1306                 return -1;
1307
1308         /* potential */
1309         set_cutoff(&moldyn,mdrun.cutoff);
1310         if(set_potential(&moldyn,mdrun.potential)<0)
1311                 return -1;
1312         switch(mdrun.potential) {
1313                 case MOLDYN_POTENTIAL_AM:
1314                         albe_mult_set_params(&moldyn,
1315                                              mdrun.element1,
1316                                              mdrun.element2);
1317                         break;
1318                 case MOLDYN_POTENTIAL_TM:
1319                         tersoff_mult_set_params(&moldyn,
1320                                                 mdrun.element1,
1321                                                 mdrun.element2);
1322                         break;
1323                 case MOLDYN_POTENTIAL_HO:
1324                         harmonic_oscillator_set_params(&moldyn,mdrun.element1);
1325                         break;
1326                 case MOLDYN_POTENTIAL_LJ:
1327                         lennard_jones_set_params(&moldyn,mdrun.element1);
1328                         break;
1329                 default:
1330                         printf("%s unknown potential: %02x\n",
1331                                ME,mdrun.potential);
1332                         return -1;
1333         }
1334
1335         /* if it is a continue run, reset schedule and skip lattice init */
1336         if(mdrun.continue_file[0]) {
1337                 memset(&(moldyn.schedule),0,sizeof(t_moldyn_schedule));
1338                 goto addsched;
1339         }
1340
1341         /* initial lattice and dimensions */
1342         set_dim(&moldyn,mdrun.dim.x,mdrun.dim.y,mdrun.dim.z,mdrun.vis);
1343         set_pbc(&moldyn,mdrun.pbcx,mdrun.pbcy,mdrun.pbcz);
1344         /* replaced by fill stage !! 
1345         switch(mdrun.lattice) {
1346                 case FCC:
1347                         create_lattice(&moldyn,FCC,mdrun.lc,mdrun.fill_element,
1348                                        mdrun.m1,DEFAULT_ATOM_ATTR,
1349                                        mdrun.fill_brand,mdrun.lx,
1350                                        mdrun.ly,mdrun.lz,NULL,0,NULL);
1351                         break;
1352                 case DIAMOND:
1353                         create_lattice(&moldyn,DIAMOND,mdrun.lc,
1354                                        mdrun.fill_element,
1355                                        mdrun.m1,DEFAULT_ATOM_ATTR,
1356                                        mdrun.fill_brand,mdrun.lx,
1357                                        mdrun.ly,mdrun.lz,NULL,0,NULL);
1358                         break;
1359                 case ZINCBLENDE:
1360                         o.x=0.5*0.25*mdrun.lc; o.y=o.x; o.z=o.x;
1361                         create_lattice(&moldyn,FCC,mdrun.lc,mdrun.element1,
1362                                        mdrun.m1,DEFAULT_ATOM_ATTR,0,mdrun.lx,
1363                                        mdrun.ly,mdrun.lz,&o,0,NULL);
1364                         o.x+=0.25*mdrun.lc; o.y=o.x; o.z=o.x;
1365                         create_lattice(&moldyn,FCC,mdrun.lc,mdrun.element2,
1366                                        mdrun.m2,DEFAULT_ATOM_ATTR,1,mdrun.lx,
1367                                        mdrun.ly,mdrun.lz,&o,0,NULL);
1368                         break;
1369                 case NONE:
1370                         set_nn_dist(&moldyn,mdrun.nnd);
1371                         break;
1372                 default:
1373                         printf("%s unknown lattice type: %02x\n",
1374                                ME,mdrun.lattice);
1375                         return -1;
1376         }
1377         moldyn_bc_check(&moldyn);
1378         replaced by fill stage !! */
1379
1380         /* temperature and pressure */
1381         set_temperature(&moldyn,mdrun.temperature);
1382         set_pressure(&moldyn,mdrun.pressure);
1383         /* replaced thermal_init stage
1384         thermal_init(&moldyn,TRUE);
1385         */
1386
1387 addsched:
1388         /* first schedule */
1389         moldyn_add_schedule(&moldyn,mdrun.prerun,mdrun.timestep);
1390
1391         /* log */
1392         moldyn_set_log_dir(&moldyn,mdrun.sdir);
1393         moldyn_set_report(&moldyn,"CHANGE ME","CHANGE ME TOO");
1394         if(mdrun.elog)
1395                 moldyn_set_log(&moldyn,LOG_TOTAL_ENERGY,mdrun.elog);
1396         if(mdrun.tlog)
1397                 moldyn_set_log(&moldyn,LOG_TEMPERATURE,mdrun.tlog);
1398         if(mdrun.plog)
1399                 moldyn_set_log(&moldyn,LOG_PRESSURE,mdrun.plog);
1400         if(mdrun.vlog)
1401                 moldyn_set_log(&moldyn,LOG_VOLUME,mdrun.vlog);
1402         if(mdrun.visualize)
1403                 moldyn_set_log(&moldyn,VISUAL_STEP,mdrun.visualize);
1404         if(mdrun.save)
1405                 moldyn_set_log(&moldyn,SAVE_STEP,mdrun.save);
1406         moldyn_set_log(&moldyn,CREATE_REPORT,0);
1407         set_avg_skip(&moldyn,mdrun.avgskip);
1408
1409         /* prepare the hook function */
1410         moldyn_set_schedule_hook(&moldyn,&mdrun_hook,&mdrun);
1411
1412         /* run the simulation */
1413         moldyn_integrate(&moldyn);
1414
1415         /* shutdown */
1416         moldyn_shutdown(&moldyn);
1417         del_stages(&mdrun);
1418         list_destroy_f(&(mdrun.stage));
1419
1420         return 0;
1421 }