actually just bullshit ... (added unique tag -> maybe symmetry)
[physik/posic.git] / moldyn.c
index b6fa8d3..f8bfd3f 100644 (file)
--- a/moldyn.c
+++ b/moldyn.c
 
 #include "moldyn.h"
 
-#include "math/math.h"
-#include "init/init.h"
-#include "random/random.h"
-#include "visual/visual.h"
-#include "list/list.h"
-
-
 int moldyn_init(t_moldyn *moldyn,int argc,char **argv) {
 
-       //int ret;
-
-       //ret=moldyn_parse_argv(moldyn,argc,argv);
-       //if(ret<0) return ret;
-
        memset(moldyn,0,sizeof(t_moldyn));
 
        rand_init(&(moldyn->random),NULL,1);
@@ -108,7 +96,7 @@ int set_dim(t_moldyn *moldyn,double x,double y,double z,u8 visualize) {
                moldyn->vis.dim.z=z;
        }
 
-       printf("[moldyn] dimensions in A and A^2 respectively:\n");
+       printf("[moldyn] dimensions in A and A^3 respectively:\n");
        printf("  x: %f\n",moldyn->dim.x);
        printf("  y: %f\n",moldyn->dim.y);
        printf("  z: %f\n",moldyn->dim.z);
@@ -237,34 +225,43 @@ int moldyn_log_shutdown(t_moldyn *moldyn) {
        return 0;
 }
 
+/*
+ * creating lattice functions
+ */
+
 int create_lattice(t_moldyn *moldyn,u8 type,double lc,int element,double mass,
-                   u8 attr,u8 bnum,int a,int b,int c) {
+                   u8 attr,u8 brand,int a,int b,int c) {
 
-       int count;
+       int new,count;
        int ret;
        t_3dvec origin;
+       void *ptr;
+       t_atom *atom;
 
-       count=a*b*c;
+       new=a*b*c;
+       count=moldyn->count;
 
        /* how many atoms do we expect */
-       if(type==FCC) count*=4;
-       if(type==DIAMOND) count*=8;
+       if(type==FCC) new*=4;
+       if(type==DIAMOND) new*=8;
 
        /* allocate space for atoms */
-       moldyn->atom=malloc(count*sizeof(t_atom));
-       if(moldyn->atom==NULL) {
-               perror("malloc (atoms)");
+       ptr=realloc(moldyn->atom,(count+new)*sizeof(t_atom));
+       if(!ptr) {
+               perror("[moldyn] realloc (create lattice)");
                return -1;
        }
-
+       moldyn->atom=ptr;
+       atom=&(moldyn->atom[count]);
+               
        v3_zero(&origin);
 
        switch(type) {
                case FCC:
-                       ret=fcc_init(a,b,c,lc,moldyn->atom,&origin);
+                       ret=fcc_init(a,b,c,lc,atom,&origin);
                        break;
                case DIAMOND:
-                       ret=diamond_init(a,b,c,lc,moldyn->atom,&origin);
+                       ret=diamond_init(a,b,c,lc,atom,&origin);
                        break;
                default:
                        printf("unknown lattice type (%02x)\n",type);
@@ -272,30 +269,114 @@ int create_lattice(t_moldyn *moldyn,u8 type,double lc,int element,double mass,
        }
 
        /* debug */
-       if(ret!=count) {
+       if(ret!=new) {
                printf("[moldyn] creating lattice failed\n");
                printf("  amount of atoms\n");
-               printf("  - expected: %d\n",count);
+               printf("  - expected: %d\n",new);
                printf("  - created: %d\n",ret);
                return -1;
        }
 
-       moldyn->count=count;
-       printf("[moldyn] created lattice with %d atoms\n",count);
+       moldyn->count+=new;
+       printf("[moldyn] created lattice with %d atoms\n",new);
 
-       while(count) {
-               count-=1;
-               moldyn->atom[count].element=element;
-               moldyn->atom[count].mass=mass;
-               moldyn->atom[count].attr=attr;
-               moldyn->atom[count].bnum=bnum;
-               check_per_bound(moldyn,&(moldyn->atom[count].r));
+       for(ret=0;ret<new;ret++) {
+               atom[ret].element=element;
+               atom[ret].mass=mass;
+               atom[ret].attr=attr;
+               atom[ret].brand=brand;
+               atom[ret].tag=count+ret;
+               check_per_bound(moldyn,&(atom[ret].r));
        }
 
        return ret;
 }
 
-int add_atom(t_moldyn *moldyn,int element,double mass,u8 bnum,u8 attr,
+/* fcc lattice init */
+int fcc_init(int a,int b,int c,double lc,t_atom *atom,t_3dvec *origin) {
+
+       int count;
+       int i,j;
+       t_3dvec o,r,n;
+       t_3dvec basis[3];
+       double help[3];
+       double x,y,z;
+
+       x=a*lc;
+       y=b*lc;
+       z=c*lc;
+
+       if(origin) v3_copy(&o,origin);
+       else v3_zero(&o);
+
+       /* construct the basis */
+       for(i=0;i<3;i++) {
+               for(j=0;j<3;j++) {
+                       if(i!=j) help[j]=0.5*lc;
+                       else help[j]=.0;
+               }
+               v3_set(&basis[i],help);
+       }
+
+       v3_zero(&r);
+       count=0;
+       
+       /* fill up the room */
+       r.x=o.x;
+       while(r.x<x) {
+               r.y=o.y;
+               while(r.y<y) {
+                       r.z=o.z;
+                       while(r.z<z) {
+                               v3_copy(&(atom[count].r),&r);
+                               atom[count].element=1;
+                               count+=1;
+                               for(i=0;i<3;i++) {
+                                       v3_add(&n,&r,&basis[i]);
+                                       if((n.x<x+o.x)&&
+                                          (n.y<y+o.y)&&
+                                          (n.z<z+o.z)) {
+                                               v3_copy(&(atom[count].r),&n);
+                                               count+=1;
+                                       }
+                               }
+                               r.z+=lc;        
+                       }
+                       r.y+=lc;
+               }
+               r.x+=lc;
+       }
+
+       /* coordinate transformation */
+       help[0]=x/2.0;
+       help[1]=y/2.0;
+       help[2]=z/2.0;
+       v3_set(&n,help);
+       for(i=0;i<count;i++)
+               v3_sub(&(atom[i].r),&(atom[i].r),&n);
+               
+       return count;
+}
+
+int diamond_init(int a,int b,int c,double lc,t_atom *atom,t_3dvec *origin) {
+
+       int count;
+       t_3dvec o;
+
+       count=fcc_init(a,b,c,lc,atom,origin);
+
+       o.x=0.25*lc;
+       o.y=0.25*lc;
+       o.z=0.25*lc;
+
+       if(origin) v3_add(&o,&o,origin);
+
+       count+=fcc_init(a,b,c,lc,&atom[count],&o);
+
+       return count;
+}
+
+int add_atom(t_moldyn *moldyn,int element,double mass,u8 brand,u8 attr,
              t_3dvec *r,t_3dvec *v) {
 
        t_atom *atom;
@@ -303,9 +384,9 @@ int add_atom(t_moldyn *moldyn,int element,double mass,u8 bnum,u8 attr,
        int count;
        
        atom=moldyn->atom;
-       count=++(moldyn->count);
+       count=(moldyn->count)++;
 
-       ptr=realloc(atom,count*sizeof(t_atom));
+       ptr=realloc(atom,(count+1)*sizeof(t_atom));
        if(!ptr) {
                perror("[moldyn] realloc (add atom)");
                return -1;
@@ -313,12 +394,13 @@ int add_atom(t_moldyn *moldyn,int element,double mass,u8 bnum,u8 attr,
        moldyn->atom=ptr;
 
        atom=moldyn->atom;
-       atom[count-1].r=*r;
-       atom[count-1].v=*v;
-       atom[count-1].element=element;
-       atom[count-1].mass=mass;
-       atom[count-1].bnum=bnum;
-       atom[count-1].attr=attr;
+       atom[count].r=*r;
+       atom[count].v=*v;
+       atom[count].element=element;
+       atom[count].mass=mass;
+       atom[count].brand=brand;
+       atom[count].tag=count;
+       atom[count].attr=attr;
 
        return 0;
 }
@@ -551,9 +633,6 @@ int link_cell_init(t_moldyn *moldyn) {
 
        t_linkcell *lc;
        int i;
-       int fd;
-
-       fd=open("/dev/null",O_WRONLY);
 
        lc=&(moldyn->lc);
 
@@ -571,8 +650,7 @@ int link_cell_init(t_moldyn *moldyn) {
        printf("[moldyn] initializing linked cells (%d)\n",lc->cells);
 
        for(i=0;i<lc->cells;i++)
-               //list_init(&(lc->subcell[i]),1);
-               list_init(&(lc->subcell[i]),fd);
+               list_init_f(&(lc->subcell[i]));
 
        link_cell_update(moldyn);
        
@@ -582,26 +660,30 @@ int link_cell_init(t_moldyn *moldyn) {
 int link_cell_update(t_moldyn *moldyn) {
 
        int count,i,j,k;
-       int nx,ny,nz;
+       int nx,ny;
        t_atom *atom;
        t_linkcell *lc;
+       double x,y,z;
 
        atom=moldyn->atom;
        lc=&(moldyn->lc);
 
        nx=lc->nx;
        ny=lc->ny;
-       nz=lc->nz;
+
+       x=moldyn->dim.x/2;
+       y=moldyn->dim.y/2;
+       z=moldyn->dim.z/2;
 
        for(i=0;i<lc->cells;i++)
-               list_destroy(&(moldyn->lc.subcell[i]));
+               list_destroy_f(&(lc->subcell[i]));
        
        for(count=0;count<moldyn->count;count++) {
-               i=(atom[count].r.x+(moldyn->dim.x/2))/lc->x;
-               j=(atom[count].r.y+(moldyn->dim.y/2))/lc->y;
-               k=(atom[count].r.z+(moldyn->dim.z/2))/lc->z;
-               list_add_immediate_ptr(&(moldyn->lc.subcell[i+j*nx+k*nx*ny]),
-                                      &(atom[count]));
+               i=((atom[count].r.x+(moldyn->dim.x/2))/lc->x);
+               j=((atom[count].r.y+(moldyn->dim.y/2))/lc->y);
+               k=((atom[count].r.z+(moldyn->dim.z/2))/lc->z);
+               list_add_immediate_f(&(moldyn->lc.subcell[i+j*nx+k*nx*ny]),
+                                    &(atom[count]));
        }
 
        return 0;
@@ -671,7 +753,9 @@ int link_cell_shutdown(t_moldyn *moldyn) {
        lc=&(moldyn->lc);
 
        for(i=0;i<lc->nx*lc->ny*lc->nz;i++)
-               list_shutdown(&(moldyn->lc.subcell[i]));
+               list_destroy_f(&(moldyn->lc.subcell[i]));
+
+       free(lc->subcell);
 
        return 0;
 }
@@ -786,11 +870,7 @@ int moldyn_integrate(t_moldyn *moldyn) {
                if(moldyn->pt_scale&(T_SCALE_BERENDSEN|T_SCALE_DIRECT))
                        scale_velocity(moldyn,FALSE);
                if(moldyn->pt_scale&(P_SCALE_BERENDSEN|P_SCALE_DIRECT))
-{
-printf("going to do p scale ...\n");
                        scale_volume(moldyn);
-printf("done\n");
-}
 
                /* check for log & visualization */
                if(e) {
@@ -869,16 +949,13 @@ int velocity_verlet(t_moldyn *moldyn) {
                v3_add(&(atom[i].r),&(atom[i].r),&delta);
                v3_scale(&delta,&(atom[i].f),0.5*tau_square/atom[i].mass);
                v3_add(&(atom[i].r),&(atom[i].r),&delta);
-//if(i==5) printf("v: %f %f %f\n",atom[i].r.x,(atom[i].r.x+moldyn->dim.x/2)/moldyn->lc.x,2*atom[i].r.x/moldyn->dim.x);
                check_per_bound(moldyn,&(atom[i].r));
-//if(i==5) printf("n: %f %f %f\n",atom[i].r.x,(atom[i].r.x+moldyn->dim.x/2)/moldyn->lc.x,2*atom[i].r.x/moldyn->dim.x);
 
                /* velocities */
                v3_scale(&delta,&(atom[i].f),0.5*tau/atom[i].mass);
                v3_add(&(atom[i].v),&(atom[i].v),&delta);
        }
 
-//moldyn_bc_check(moldyn);
        /* neighbour list update */
        link_cell_update(moldyn);
 
@@ -930,6 +1007,9 @@ int potential_force_calc(t_moldyn *moldyn) {
                /* reset viral of atom i */
                v3_zero(&(itom[i].virial));
 
+               /* reset site energy */
+               itom[i].e=0.0;
+
                /* single particle potential/force */
                if(itom[i].attr&ATOM_ATTR_1BP)
                        moldyn->func1b(moldyn,&(itom[i]));
@@ -950,7 +1030,7 @@ int potential_force_calc(t_moldyn *moldyn) {
                for(j=0;j<27;j++) {
 
                        this=&(neighbour_i[j]);
-                       list_reset(this);
+                       list_reset_f(this);
 
                        if(this->start==NULL)
                                continue;
@@ -985,7 +1065,7 @@ int potential_force_calc(t_moldyn *moldyn) {
                                for(k=0;k<27;k++) {
 
                                        that=&(neighbour_i2[k]);
-                                       list_reset(that);
+                                       list_reset_f(that);
                                        
                                        if(that->start==NULL)
                                                continue;
@@ -1011,7 +1091,7 @@ int potential_force_calc(t_moldyn *moldyn) {
                                                               ktom,
                                                               bc_ik|bc_ij);
 
-                                       } while(list_next(that)!=\
+                                       } while(list_next_f(that)!=\
                                                L_NO_NEXT_ELEMENT);
 
                                }
@@ -1023,7 +1103,7 @@ int potential_force_calc(t_moldyn *moldyn) {
                                                            jtom,bc_ij);
                                }
                                        
-                       } while(list_next(this)!=L_NO_NEXT_ELEMENT);
+                       } while(list_next_f(this)!=L_NO_NEXT_ELEMENT);
                
                }
 
@@ -1036,7 +1116,7 @@ int potential_force_calc(t_moldyn *moldyn) {
  * periodic boundayr checking
  */
 
-int check_per_bound(t_moldyn *moldyn,t_3dvec *a) {
+inline int check_per_bound(t_moldyn *moldyn,t_3dvec *a) {
        
        double x,y,z;
        t_3dvec *dim;
@@ -1169,11 +1249,11 @@ int tersoff_mult_complete_params(t_tersoff_mult_params *p) {
 /* tersoff 1 body part */
 int tersoff_mult_1bp(t_moldyn *moldyn,t_atom *ai) {
 
-       int num;
+       int brand;
        t_tersoff_mult_params *params;
        t_tersoff_exchange *exchange;
        
-       num=ai->bnum;
+       brand=ai->brand;
        params=moldyn->pot1b_params;
        exchange=&(params->exchange);
 
@@ -1182,15 +1262,15 @@ int tersoff_mult_1bp(t_moldyn *moldyn,t_atom *ai) {
         *         their right values
         */
 
-       exchange->beta_i=&(params->beta[num]);
-       exchange->n_i=&(params->n[num]);
-       exchange->c_i=&(params->c[num]);
-       exchange->d_i=&(params->d[num]);
-       exchange->h_i=&(params->h[num]);
+       exchange->beta_i=&(params->beta[brand]);
+       exchange->n_i=&(params->n[brand]);
+       exchange->c_i=&(params->c[brand]);
+       exchange->d_i=&(params->d[brand]);
+       exchange->h_i=&(params->h[brand]);
 
        exchange->betaini=pow(*(exchange->beta_i),*(exchange->n_i));
-       exchange->ci2=params->c[num]*params->c[num];
-       exchange->di2=params->d[num]*params->d[num];
+       exchange->ci2=params->c[brand]*params->c[brand];
+       exchange->di2=params->d[brand]*params->d[brand];
        exchange->ci2di2=exchange->ci2/exchange->di2;
 
        return 0;
@@ -1206,12 +1286,12 @@ int tersoff_mult_2bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) {
        double A,B,R,S,lambda,mu;
        double f_r,df_r;
        double f_c,df_c;
-       int num;
+       int brand;
        double s_r;
        double arg;
 
        params=moldyn->pot2b_params;
-       num=aj->bnum;
+       brand=aj->brand;
        exchange=&(params->exchange);
 
        /* clear 3bp and 2bp post run */
@@ -1244,13 +1324,13 @@ int tersoff_mult_2bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) {
        exchange->dist_ij=dist_ij;
 
        /* constants */
-       if(num==ai->bnum) {
-               S=params->S[num];
-               R=params->R[num];
-               A=params->A[num];
-               B=params->B[num];
-               lambda=params->lambda[num];
-               mu=params->mu[num];
+       if(brand==ai->brand) {
+               S=params->S[brand];
+               R=params->R[brand];
+               A=params->A[brand];
+               B=params->B[brand];
+               lambda=params->lambda[brand];
+               mu=params->mu[brand];
                exchange->chi=1.0;
        }
        else {
@@ -1268,12 +1348,12 @@ int tersoff_mult_2bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) {
                return 0;
 
        /* more constants */
-       exchange->beta_j=&(params->beta[num]);
-       exchange->n_j=&(params->n[num]);
-       exchange->c_j=&(params->c[num]);
-       exchange->d_j=&(params->d[num]);
-       exchange->h_j=&(params->h[num]);
-       if(num==ai->bnum) {
+       exchange->beta_j=&(params->beta[brand]);
+       exchange->n_j=&(params->n[brand]);
+       exchange->c_j=&(params->c[brand]);
+       exchange->d_j=&(params->d[brand]);
+       exchange->h_j=&(params->h[brand]);
+       if(brand==ai->brand) {
                exchange->betajnj=exchange->betaini;
                exchange->cj2=exchange->ci2;
                exchange->dj2=exchange->di2;
@@ -1281,8 +1361,8 @@ int tersoff_mult_2bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,u8 bc) {
        }
        else {
                exchange->betajnj=pow(*(exchange->beta_j),*(exchange->n_j));
-               exchange->cj2=params->c[num]*params->c[num];
-               exchange->dj2=params->d[num]*params->d[num];
+               exchange->cj2=params->c[brand]*params->c[brand];
+               exchange->dj2=params->d[brand]*params->d[brand];
                exchange->cj2dj2=exchange->cj2/exchange->dj2;
        }
 
@@ -1462,7 +1542,7 @@ int tersoff_mult_3bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,t_atom *ak,u8 bc) {
        double h_cos,d2_h_cos2;
        double frac,g,zeta,chi;
        double tmp;
-       int num;
+       int brand;
 
        params=moldyn->pot3b_params;
        exchange=&(params->exchange);
@@ -1514,10 +1594,10 @@ int tersoff_mult_3bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,t_atom *ak,u8 bc) {
        d_ik=v3_norm(&dist_ik);
 
        /* ik constants */
-       num=ai->bnum;
-       if(num==ak->bnum) {
-               R=params->R[num];
-               S=params->S[num];
+       brand=ai->brand;
+       if(brand==ak->brand) {
+               R=params->R[brand];
+               S=params->S[brand];
        }
        else {
                R=params->Rmixed;
@@ -1600,12 +1680,12 @@ int tersoff_mult_3bp(t_moldyn *moldyn,t_atom *ai,t_atom *aj,t_atom *ak,u8 bc) {
        d_jk=v3_norm(&dist_jk);
 
        /* jk constants */
-       num=aj->bnum;
-       if(num==ak->bnum) {
-               R=params->R[num];
-               S=params->S[num];
-               B=params->B[num];
-               mu=params->mu[num];
+       brand=aj->brand;
+       if(brand==ak->brand) {
+               R=params->R[brand];
+               S=params->S[brand];
+               B=params->B[brand];
+               mu=params->mu[brand];
                chi=1.0;
        }
        else {
@@ -1713,13 +1793,13 @@ int moldyn_bc_check(t_moldyn *moldyn) {
        t_atom *atom;
        t_3dvec *dim;
        int i;
-double x;
-u8 byte;
-int j,k;
+       double x;
+       u8 byte;
+       int j,k;
 
        atom=moldyn->atom;
        dim=&(moldyn->dim);
-x=dim->x/2;
+       x=dim->x/2;
 
        for(i=0;i<moldyn->count;i++) {
                if(atom[i].r.x>=dim->x/2||-atom[i].r.x>dim->x/2) {
@@ -1755,4 +1835,3 @@ x=dim->x/2;
 
        return 0;
 }
-