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