Merge branch 'leadoff'
[physik/posic.git] / mdrun.c
diff --git a/mdrun.c b/mdrun.c
index 062224b..26fbc87 100644 (file)
--- a/mdrun.c
+++ b/mdrun.c
@@ -11,6 +11,7 @@
 #include "potentials/harmonic_oscillator.h"
 #include "potentials/lennard_jones.h"
 #include "potentials/albe.h"
+#include "potentials/albe_orig.h"
 #ifdef TERSOFF_ORIG
 #include "potentials/tersoff_orig.h"
 #else
@@ -129,6 +130,9 @@ int add_stage(t_mdrun *mdrun,u8 type,void *params) {
                case STAGE_THERMAL_INIT:
                        psize=0;
                        break;
+               case STAGE_CRT:
+                       psize=sizeof(t_crt_params);
+                       break;
                default:
                        printf("%s unknown stage type: %02x\n",ME,type);
                        return -1;
@@ -178,6 +182,7 @@ int mdrun_parse_config(t_mdrun *mdrun) {
        t_set_timestep_params stsp;
        t_fill_params fp;
        t_del_atoms_params delp;
+       t_crt_params crtp;
 
        /* open config file */
        fd=open(mdrun->cfile,O_RDONLY);
@@ -212,6 +217,7 @@ int mdrun_parse_config(t_mdrun *mdrun) {
                memset(&stsp,0,sizeof(t_set_timestep_params));
                memset(&fp,0,sizeof(t_fill_params));
                memset(&delp,0,sizeof(t_del_atoms_params));
+               memset(&crtp,0,sizeof(t_crt_params));
 
                // get command + args
                wcnt=0;
@@ -229,6 +235,8 @@ int mdrun_parse_config(t_mdrun *mdrun) {
                if(!strncmp(word[0],"potential",9)) {
                        if(!strncmp(word[1],"albe",4))
                                mdrun->potential=MOLDYN_POTENTIAL_AM;
+                       if(!strncmp(word[1],"albe_o",6))
+                               mdrun->potential=MOLDYN_POTENTIAL_AO;
                        if(!strncmp(word[1],"tersoff",7))
                                mdrun->potential=MOLDYN_POTENTIAL_TM;
                        if(!strncmp(word[1],"ho",2))
@@ -422,6 +430,8 @@ int mdrun_parse_config(t_mdrun *mdrun) {
                                        case 'e':
                                                cap.type|=CHAATTR_ELEMENT;
                                                break;
+                                       case 'n':
+                                               cap.type|=CHAATTR_NUMBER;
                                        default:
                                                break;
                                }
@@ -440,6 +450,10 @@ int mdrun_parse_config(t_mdrun *mdrun) {
                                cap.element=atoi(word[i]);
                                i+=1;
                        }
+                       if(cap.type&CHAATTR_NUMBER) {
+                               cap.element=atoi(word[i]);
+                               i+=1;
+                       }
                        for(o=0;o<strlen(word[i]);o++) {
                                switch(word[i][o]) {
                                        case 'b':
@@ -591,6 +605,12 @@ int mdrun_parse_config(t_mdrun *mdrun) {
                                                iap.y0=atof(word[9]);
                                                iap.z0=atof(word[10]);
                                                break;
+                                       case 'P':
+                                               iap.type=INS_RELPOS;
+                                               iap.x0=atof(word[8]);
+                                               iap.y0=atof(word[9]);
+                                               iap.z0=atof(word[10]);
+                                               break;
                                        case 'r':
                                                switch(word[8][0]) {
 
@@ -701,6 +721,12 @@ int mdrun_parse_config(t_mdrun *mdrun) {
                                stsp.tau=atof(word[2]);
                                add_stage(mdrun,STAGE_SET_TIMESTEP,&stsp);
                        }
+                       else if(!strncmp(word[1],"crt",3)) {
+                               crtp.type=atoi(word[2]);
+                               crtp.steps=atoi(word[3]);
+                               strncpy(crtp.file,word[4],127);
+                               add_stage(mdrun,STAGE_CRT,&crtp);
+                       }
                        else {
                                printf("%s unknown stage type: %s\n",
                                       ME,word[1]);
@@ -780,18 +806,35 @@ int del_atoms(t_moldyn *moldyn,t_mdrun *mdrun) {
        t_del_atoms_params *delp;
        int i;
        t_3dvec dist;
-       
+       u8 outer;
+
+       outer=0;        
        stage=mdrun->stage.current->data;
        delp=stage->params;
 
+       if(delp->r<0)
+               outer=1;
+
        for(i=0;i<moldyn->count;i++) {
                v3_sub(&dist,&(delp->o),&(moldyn->atom[i].r));
 //printf("%d ----> %f %f %f = %f | %f\n",i,dist.x,dist.y,dist.z,v3_absolute_square(&dist),delp->r*delp->r);
                if(v3_absolute_square(&dist)<=(delp->r*delp->r)) {
-                       del_atom(moldyn,moldyn->atom[i].tag);
-                       printf("%s atom deleted: %d %d %d\n",ME,
-                               moldyn->atom[i].tag,moldyn->atom[i].element,
-                              moldyn->atom[i].brand);
+                       if(!outer) {
+                               del_atom(moldyn,moldyn->atom[i].tag);
+                               printf("%s atom deleted: %d %d %d\n",ME,
+                                      moldyn->atom[i].tag,
+                                      moldyn->atom[i].element,
+                                      moldyn->atom[i].brand);
+                       }
+               }
+               else {
+                       if(outer) {
+                               del_atom(moldyn,moldyn->atom[i].tag);
+                               printf("%s atom deleted: %d %d %d\n",ME,
+                                      moldyn->atom[i].tag,
+                                      moldyn->atom[i].element,
+                                      moldyn->atom[i].brand);
+                       }
                }
        }
 
@@ -896,6 +939,7 @@ int insert_atoms(t_moldyn *moldyn,t_mdrun *mdrun) {
                        cr_check=TRUE;
                        break;
                case INS_POS:
+               case INS_RELPOS:
                        x0=iap->x0;
                        y0=iap->y0;
                        z0=iap->z0;
@@ -911,7 +955,7 @@ int insert_atoms(t_moldyn *moldyn,t_mdrun *mdrun) {
        while(cnt<iap->ins_atoms) {
                run=1;
                while(run) {
-                       if(iap->type!=INS_POS) {
+                       if((iap->type!=INS_POS)&&(iap->type!=INS_RELPOS)) {
                                r.x=rand_get_double(&(moldyn->random))*x;
                                r.y=rand_get_double(&(moldyn->random))*y;
                                r.z=rand_get_double(&(moldyn->random))*z;
@@ -921,9 +965,16 @@ int insert_atoms(t_moldyn *moldyn,t_mdrun *mdrun) {
                                r.y=0.0;
                                r.z=0.0;
                        }
-                       r.x+=x0;
-                       r.y+=y0;
-                       r.z+=z0;
+                       if(iap->type==INS_RELPOS) {
+                               r.x+=x0*mdrun->lc;
+                               r.y+=y0*mdrun->lc;
+                               r.z+=z0*mdrun->lc;
+                       }
+                       else {
+                               r.x+=x0;
+                               r.y+=y0;
+                               r.z+=z0;
+                       }
                        // offset
                        if(iap->type!=INS_TOTAL) {
                                r.x+=o;
@@ -1102,6 +1153,10 @@ int chaatr(t_moldyn *moldyn,t_mdrun *mdrun) {
                        if(cap->element!=atom->element)
                                continue;
                }
+               if(cap->type&CHAATTR_NUMBER) {
+                       if(cap->element!=atom->tag)
+                               continue;
+               }
                if(cap->type&CHAATTR_REGION) {
                        if(cap->x0>atom->r.x)
                                continue;
@@ -1174,6 +1229,138 @@ int chsattr(t_moldyn *moldyn,t_mdrun *mdrun) {
        return 0;
 }
 
+int crt(t_moldyn *moldyn,t_mdrun *mdrun) {
+
+       t_stage *stage;
+       t_crt_params *crtp;
+
+       int fd;
+       char line[128];
+       char *wptr;
+       int acount;
+       int ret;
+       void *ptr;
+
+       t_atom *atom;
+       t_3dvec disp;
+       double frac;
+       int i;
+       
+       stage=mdrun->stage.current->data;
+       crtp=stage->params;
+
+       acount=0;
+
+       /* initial stuff */
+
+       if(crtp->count==0) {
+               printf("  crt init\n");
+               // read final positions, constraints and do the alloc
+               fd=open(crtp->file,O_RDONLY);
+               if(fd<0) {
+                       perror("[mdrun] FATAL reading constraints file");
+                       return fd;
+               }
+               while(1) {
+                       ret=get_line(fd,line,128);
+                       // check for end of file
+                       if(ret<=0) {
+                               printf("  read %d atom positions\n",acount);
+                               if(acount!=moldyn->count)
+                                       printf("  atom count mismatch!!!\n");
+                               printf("\n");
+                               break;
+                       }
+                       // ignore # lines and \n
+                       if((line[0]=='#')|(ret==1))
+                               continue;
+                       // allocate new memory
+                       ptr=realloc(crtp->r_fin,(acount+1)*sizeof(t_3dvec));
+                       if(ptr==NULL) {
+                               perror("[mdrun] FATAL realloc crt positions");
+                               return -1;
+                       }
+                       crtp->r_fin=ptr;
+                       ptr=realloc(constraints,(acount+1)*3*sizeof(u8));
+                       if(ptr==NULL) {
+                               perror("[mdrun] FATAL realloc crt constraints");
+                               return -1;
+                       }
+                       constraints=ptr;
+                       // ignore type
+                       wptr=strtok(line," \t");
+                       // read x y z
+                       wptr=strtok(NULL," \t");
+                       crtp->r_fin[acount].x=atof(wptr);
+                       wptr=strtok(NULL," \t");
+                       crtp->r_fin[acount].y=atof(wptr);
+                       wptr=strtok(NULL," \t");
+                       crtp->r_fin[acount].z=atof(wptr);
+                       // read constraints
+                       wptr=strtok(NULL," \t");
+                       constraints[3*acount]=atoi(wptr);
+                       wptr=strtok(NULL," \t");
+                       constraints[3*acount+1]=atoi(wptr);
+                       wptr=strtok(NULL," \t");
+                       constraints[3*acount+2]=atoi(wptr);
+                       // done reading
+                       acount+=1;
+               }
+               close(fd);
+               // allocate trafo angles
+               trafo_angle=malloc(acount*2*sizeof(double));
+               if(trafo_angle==NULL) {
+                       perror("[mdrun] FATAL alloc trafo angles");
+                       return -1;
+               }
+               // set crt mode
+               crtt=crtp->type;
+       }
+
+       /* write a save file s-crt_xofy.save */
+       snprintf(line,128,"%s/s-crt_%03dof%03d.save",
+                moldyn->vlsdir,crtp->count,crtp->steps);
+       fd=open(line,O_WRONLY|O_TRUNC|O_CREAT,S_IRUSR|S_IWUSR);
+       if(fd<0) perror("[mdrun] crt save fd open");
+       else {
+               write(fd,moldyn,sizeof(t_moldyn));
+               write(fd,moldyn->atom,
+                     moldyn->count*sizeof(t_atom));
+       }
+       close(fd);
+       /* visualize atoms */
+       visual_atoms(moldyn);
+
+       /* output energy */
+       printf("  crt energy: %d - %f\n\n",
+              crtp->count,(moldyn->ekin+moldyn->energy)/EV);
+
+       /* crt routines: calculate displacement + set individual constraints */
+
+       printf("  crt step %d of %d in total\n\n",crtp->count+1,crtp->steps);
+
+       if((crtp->type==1)|(crtp->count==0))
+               printf("  crt angle update\n\n");
+               
+       for(i=0;i<moldyn->count;i++) {
+               // calc displacements
+               atom=moldyn->atom;
+               v3_sub(&disp,&(crtp->r_fin[i]),&(atom[i].r));
+               // angles
+               if((crtp->type==1)|(crtp->count==0)) {
+                       trafo_angle[2*i]=atan2(disp.x,disp.y);
+                       trafo_angle[2*i+1]=-atan2(disp.z,
+                                          sqrt(disp.x*disp.x+disp.y*disp.y));
+               }
+               // move atoms
+               frac=1.0/(crtp->steps-crtp->count);
+               v3_scale(&disp,&disp,frac);
+               v3_add(&(atom[i].r),&(atom[i].r),&disp);
+       }
+
+       return 0;
+}
+
 #define stage_print(m) if(!(stage->executed)) \
                                printf("%s",m)
 
@@ -1194,6 +1381,7 @@ int mdrun_hook(void *ptr1,void *ptr2) {
        t_set_temp_params *stp;
        t_set_timestep_params *stsp;
        t_fill_params *fp;
+       t_crt_params *crtp;
 
        moldyn=ptr1;
        mdrun=ptr2;
@@ -1363,6 +1551,20 @@ int mdrun_hook(void *ptr1,void *ptr2) {
                                thermal_init(moldyn,TRUE);
                                change_stage=TRUE;
                                break;
+                       case STAGE_CRT:
+                               stage_print("  -> constraint relaxation");
+                               stage_print(" technique\n\n");
+                               crtp=stage->params;
+                               if(crtp->count==crtp->steps) {
+                                       free(constraints);
+                                       free(trafo_angle);
+                                       free(crtp->r_fin);
+                                       change_stage=TRUE;
+                                       break;
+                               }
+                               crt(moldyn,mdrun);
+                               crtp->count+=1;
+                               break;
                        default:
                                printf("%s unknwon stage type\n",ME);
                                break;
@@ -1406,6 +1608,11 @@ int main(int argc,char **argv) {
        memset(&mdrun,0,sizeof(t_mdrun));
        memset(&moldyn,0,sizeof(t_moldyn));
 
+       /* init crt variables */
+       crtt=0;
+       constraints=NULL;
+       trafo_angle=NULL;
+
        /* parse arguments */
        if(mdrun_parse_argv(&mdrun,argc,argv)<0)
                return -1;
@@ -1449,6 +1656,11 @@ int main(int argc,char **argv) {
                                             mdrun.element1,
                                             mdrun.element2);
                        break;
+               case MOLDYN_POTENTIAL_AO:
+                       albe_orig_mult_set_params(&moldyn,
+                                                 mdrun.element1,
+                                                 mdrun.element2);
+                       break;
                case MOLDYN_POTENTIAL_TM:
                        tersoff_mult_set_params(&moldyn,
                                                mdrun.element1,