X-Git-Url: https://hackdaworld.org/gitweb/?a=blobdiff_plain;f=moldyn.c;h=ad0f9a383ea7ae3e01a5a7c3ebc67de518756dc6;hb=e763f6e3072fbbbc5ecf7345b989d7d29929a38f;hp=4b580890f3eaab417494fa497130f53570130ce4;hpb=e6f456c0fa807b86e1b25996e70efcdcfe390ea5;p=physik%2Fposic.git diff --git a/moldyn.c b/moldyn.c index 4b58089..ad0f9a3 100644 --- a/moldyn.c +++ b/moldyn.c @@ -35,6 +35,7 @@ int moldyn_usage(char **argv) { printf("--- physics options ---\n"); printf("-T [K] (%f)\n",MOLDYN_TEMP); printf("-t [s] (%.15f)\n",MOLDYN_TAU); + printf("-C [m] (%.15f)\n",MOLDYN_CUTOFF); printf("-R (%d)\n",MOLDYN_RUNS); printf(" -- integration algo --\n"); printf(" -I (%d)\n",MOLDYN_INTEGRATE_DEFAULT); @@ -98,6 +99,9 @@ int moldyn_parse_argv(t_moldyn *moldyn,int argc,char **argv) { case 't': moldyn->tau=atof(argv[++i]); break; + case 'C': + moldyn->cutoff=atof(argv[++i]); + break; case 'R': moldyn->time_steps=atoi(argv[++i]); break; @@ -153,12 +157,12 @@ int moldyn_parse_argv(t_moldyn *moldyn,int argc,char **argv) { return 0; } -int moldyn_log_init(t_moldyn *moldyn,void *v) { +int moldyn_log_init(t_moldyn *moldyn) { moldyn->lvstat=0; t_visual *vis; - vis=v; + vis=&(moldyn->vis); if(moldyn->ewrite) { moldyn->efd=open(moldyn->efb,O_WRONLY|O_CREAT|O_TRUNC); @@ -204,7 +208,7 @@ int moldyn_log_init(t_moldyn *moldyn,void *v) { return 0; } -int moldyn_shutdown(t_moldyn *moldyn) { +int moldyn_log_shutdown(t_moldyn *moldyn) { if(moldyn->efd) close(moldyn->efd); if(moldyn->mfd) close(moldyn->efd); @@ -214,6 +218,33 @@ int moldyn_shutdown(t_moldyn *moldyn) { return 0; } +int moldyn_init(t_moldyn *moldyn,int argc,char **argv) { + + int ret; + + ret=moldyn_parse_argv(moldyn,argc,argv); + if(ret<0) return ret; + + ret=moldyn_log_init(moldyn); + if(ret<0) return ret; + + rand_init(&(moldyn->random),NULL,1); + moldyn->random.status|=RAND_STAT_VERBOSE; + + moldyn->status=0; + + return 0; +} + +int moldyn_shutdown(t_moldyn *moldyn) { + + moldyn_log_shutdown(moldyn); + rand_close(&(moldyn->random)); + free(moldyn->atom); + + return 0; +} + int create_lattice(unsigned char type,int element,double mass,double lc, int a,int b,int c,t_atom **atom) { @@ -270,7 +301,7 @@ int destroy_lattice(t_atom *atom) { return 0; } -int thermal_init(t_moldyn *moldyn,t_random *random) { +int thermal_init(t_moldyn *moldyn) { /* * - gaussian distribution of velocities @@ -282,8 +313,10 @@ int thermal_init(t_moldyn *moldyn,t_random *random) { double v,sigma; t_3dvec p_total,delta; t_atom *atom; + t_random *random; atom=moldyn->atom; + random=&(moldyn->random); /* gaussian distribution of velocities */ v3_zero(&p_total); @@ -402,9 +435,13 @@ double estimate_time_step(t_moldyn *moldyn,double nn_dist,double t) { int link_cell_init(t_moldyn *moldyn) { t_linkcell *lc; + int i; lc=&(moldyn->lc); + /* list log fd */ + lc->listfd=open("/dev/null",O_WRONLY); + /* partitioning the md cell */ lc->nx=moldyn->dim.x/moldyn->cutoff; lc->x=moldyn->dim.x/lc->nx; @@ -413,7 +450,14 @@ int link_cell_init(t_moldyn *moldyn) { lc->nz=moldyn->dim.z/moldyn->cutoff; lc->z=moldyn->dim.z/lc->nz; - lc->subcell=malloc(lc->nx*lc->ny*lc->nz*sizeof(t_list)); + lc->cells=lc->nx*lc->ny*lc->nz; + lc->subcell=malloc(lc->cells*sizeof(t_list)); + + printf("initializing linked cells (%d)\n",lc->cells); + + for(i=0;icells;i++) + //list_init(&(lc->subcell[i]),1); + list_init(&(lc->subcell[i])); link_cell_update(moldyn); @@ -434,13 +478,13 @@ int link_cell_update(t_moldyn *moldyn) { ny=lc->ny; nz=lc->nz; - for(i=0;icells;i++) list_destroy(&(moldyn->lc.subcell[i])); for(count=0;countcount;count++) { - i=atom[count].r.x/lc->x; - j=atom[count].r.y/lc->y; - k=atom[count].r.z/lc->z; + 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])); } @@ -461,11 +505,12 @@ int link_cell_neighbour_index(t_moldyn *moldyn,int i,int j,int k,t_list *cell) { lc=&(moldyn->lc); nx=lc->nx; ny=lc->ny; - nx=lc->nz; + nz=lc->nz; count1=1; count2=27; a=nx*ny; + cell[0]=lc->subcell[i+j*nx+k*a]; for(ci=-1;ci<=1;ci++) { bx=0; @@ -488,7 +533,7 @@ int link_cell_neighbour_index(t_moldyn *moldyn,int i,int j,int k,t_list *cell) { z=(z+nz)%nz; bz=1; } - if(!(x|y|z)) continue; + if(!(ci|cj|ck)) continue; if(bx|by|bz) { cell[--count2]=lc->subcell[x+y*nx+z*a]; } @@ -512,6 +557,8 @@ int link_cell_shutdown(t_moldyn *moldyn) { for(i=0;inx*lc->ny*lc->nz;i++) list_shutdown(&(moldyn->lc.subcell[i])); + if(lc->listfd) close(lc->listfd); + return 0; } @@ -532,6 +579,9 @@ int moldyn_integrate(t_moldyn *moldyn) { int fd; char fb[128]; + /* initialize linked cell method */ + link_cell_init(moldyn); + /* logging & visualization */ e=moldyn->ewrite; m=moldyn->mwrite; @@ -548,18 +598,10 @@ int moldyn_integrate(t_moldyn *moldyn) { moldyn->tau_square=moldyn->tau*moldyn->tau; moldyn->cutoff_square=moldyn->cutoff*moldyn->cutoff; - /* create the neighbour list */ - link_cell_update(moldyn); - /* calculate initial forces */ moldyn->potential_force_function(moldyn); for(i=0;itime_steps;i++) { - /* show runs */ - printf("."); - - /* neighbour list update */ - link_cell_update(moldyn); /* integration step */ moldyn->integrate(moldyn); @@ -599,9 +641,12 @@ int moldyn_integrate(t_moldyn *moldyn) { } if(v) { - if(!(i%v)) + if(!(i%v)) { visual_atoms(moldyn->visual,i*moldyn->tau, moldyn->atom,moldyn->count); + printf("\rsteps: %d",i); + fflush(stdout); + } } } @@ -635,8 +680,15 @@ int velocity_verlet(t_moldyn *moldyn) { v3_add(&(atom[i].v),&(atom[i].v),&delta); } + /* neighbour list update */ +printf("list update ...\n"); + link_cell_update(moldyn); +printf("done\n"); + /* forces depending on chosen potential */ +printf("calc potential/force ...\n"); moldyn->potential_force_function(moldyn); +printf("done\n"); for(i=0;iequilibrium_distance; count=moldyn->count; + /* reset energy counter */ u=0.0; + for(i=0;ix; - nj=atom[i].r.y/lc->y; - nk=atom[i].r.z/lc->z; + ni=(atom[i].r.x+(moldyn->dim.x/2))/lc->x; + nj=(atom[i].r.y+(moldyn->dim.y/2))/lc->y; + nk=(atom[i].r.z+(moldyn->dim.z/2))/lc->z; c=link_cell_neighbour_index(moldyn,ni,nj,nk,neighbour); - /* processing cell of atom i */ + /* + * processing cell of atom i + * => no need to check for empty list (1 element at minimum) + */ this=&(neighbour[0]); - list_reset(this); /* list has 1 element at minimum */ + list_reset(this); do { btom=this->current->data; if(btom==&(atom[i])) continue; v3_sub(&distance,&(atom[i].r),&(btom->r)); d=v3_norm(&distance); - u+=(0.5*sc*(d-equi_dist)*(d-equi_dist)); - v3_scale(&force,&distance,-sc*(1.0-(equi_dist/d))); - v3_add(&(atom[i].f),&(atom[i].f),&force); + if(d<=moldyn->cutoff) { + u+=(0.5*sc*(d-equi_dist)*(d-equi_dist)); + v3_scale(&force,&distance, + -sc*(1.0-(equi_dist/d))); + v3_add(&(atom[i].f),&(atom[i].f),&force); + } } while(list_next(this)!=L_NO_NEXT_ELEMENT); - /* neighbours not doing boundary condition overflow */ + /* + * direct neighbour cells + * => no boundary condition check necessary + */ for(j=1;j check boundary conditions + */ for(j=c;j<27;j++) { this=&(neighbour[j]); list_reset(this); /* check boundary conditions */ @@ -744,7 +813,7 @@ int harmonic_oscillator(t_moldyn *moldyn) { } } - moldyn->energy=u; + moldyn->energy=0.5*u; return 0; } @@ -772,12 +841,17 @@ int lennard_jones(t_moldyn *moldyn) { sig6=params->sigma6; sig12=params->sigma12; + /* reset energy counter */ u=0.0; + for(i=0;ix; - nj=atom[i].r.y/lc->y; - nk=atom[i].r.z/lc->z; + ni=(atom[i].r.x+(moldyn->dim.x/2))/lc->x; + nj=(atom[i].r.y+(moldyn->dim.y/2))/lc->y; + nk=(atom[i].r.z+(moldyn->dim.z/2))/lc->z; c=link_cell_neighbour_index(moldyn,ni,nj,nk,neighbour); /* processing cell of atom i */ @@ -788,19 +862,22 @@ int lennard_jones(t_moldyn *moldyn) { if(btom==&(atom[i])) continue; v3_sub(&distance,&(atom[i].r),&(btom->r)); - d=1.0/v3_absolute_square(&distance); /* 1/r^2 */ - h1=d*d; /* 1/r^4 */ - h2*=d; /* 1/r^6 */ - h1=h2*h2; /* 1/r^12 */ - u+=eps*(sig12*h1-sig6*h2); - h2*=d; /* 1/r^8 */ - h1*=d; /* 1/r^14 */ - h2*=6*sig6; - h1*=12*sig12; - d=-h1+h2; - d*=eps; - v3_scale(&force,&distance,d); - v3_add(&(atom[i].f),&(atom[i].f),&force); + d=v3_absolute_square(&distance); /* 1/r^2 */ + if(d<=moldyn->cutoff_square) { + d=1.0/d; /* 1/r^2 */ + h2=d*d; /* 1/r^4 */ + h2*=d; /* 1/r^6 */ + h1=h2*h2; /* 1/r^12 */ + u+=eps*(sig12*h1-sig6*h2); + h2*=d; /* 1/r^8 */ + h1*=d; /* 1/r^14 */ + h2*=6*sig6; + h1*=12*sig12; + d=+h1-h2; + d*=eps; + v3_scale(&force,&distance,d); + v3_add(&(atom[i].f),&(atom[i].f),&force); + } } while(list_next(this)!=L_NO_NEXT_ELEMENT); /* neighbours not doing boundary condition overflow */ @@ -815,7 +892,7 @@ int lennard_jones(t_moldyn *moldyn) { d=v3_absolute_square(&distance); /* r^2 */ if(d<=moldyn->cutoff_square) { d=1.0/d; /* 1/r^2 */ - h1=d*d; /* 1/r^4 */ + h2=d*d; /* 1/r^4 */ h2*=d; /* 1/r^6 */ h1=h2*h2; /* 1/r^12 */ u+=eps*(sig12*h1-sig6*h2); @@ -823,7 +900,7 @@ int lennard_jones(t_moldyn *moldyn) { h1*=d; /* 1/r^14 */ h2*=6*sig6; h1*=12*sig12; - d=-h1+h2; + d=+h1-h2; d*=eps; v3_scale(&force,&distance,d); v3_add(&(atom[i].f),&(atom[i].f), @@ -847,7 +924,7 @@ int lennard_jones(t_moldyn *moldyn) { d=v3_absolute_square(&distance); /* r^2 */ if(d<=moldyn->cutoff_square) { d=1.0/d; /* 1/r^2 */ - h1=d*d; /* 1/r^4 */ + h2=d*d; /* 1/r^4 */ h2*=d; /* 1/r^6 */ h1=h2*h2; /* 1/r^12 */ u+=eps*(sig12*h1-sig6*h2); @@ -855,7 +932,7 @@ int lennard_jones(t_moldyn *moldyn) { h1*=d; /* 1/r^14 */ h2*=6*sig6; h1*=12*sig12; - d=-h1+h2; + d=+h1-h2; d*=eps; v3_scale(&force,&distance,d); v3_add(&(atom[i].f),&(atom[i].f), @@ -867,8 +944,355 @@ int lennard_jones(t_moldyn *moldyn) { } } - moldyn->energy=u; + moldyn->energy=0.5*u; return 0; } +/* tersoff potential & force for 2 sorts of atoms */ + +int tersoff(t_moldyn *moldyn) { + + t_tersoff_params *params; + t_atom *atom,*btom,*ktom; + t_linkcell *lc; + t_list *this,*thisk,neighbour[27],neighbourk[27]; + int i,j,k,c,ck; + int count; + double u; + int ni,nj,nk; + int ki,kj,kk; + + + params=moldyn->pot_params; + atom=moldyn->atom; + lc=&(moldyn->lc); + count=moldyn->count; + + /* reset energy counter */ + u=0.0; + + for(i=0;idim.x/2))/lc->x; + nj=(atom[i].r.y+(moldyn->dim.y/2))/lc->y; + nk=(atom[i].r.z+(moldyn->dim.z/2))/lc->z; + c=link_cell_neighbour_index(moldyn,ni,nj,nk,neighbour); + + /* + * processing cell of atom i + * => no need to check for empty list (1 element at minimum) + */ + this=&(neighbour[0]); + list_reset(this); + do { + btom=this->current->data; + if(btom==&(atom[i])) + continue; + + /* 2 body stuff */ + + v3_sub(&dist_ij,btom,&(atom[i])); + d_ij=v3_norm(&dist_ij); + if(d_ij<=S) { + + S=; + R=; + A=; + lambda=; + B=; + mu=; + chi=; + beta=; + betaN=; + + if(d_ij<=R) { + f_c=1.0; + df_c=0.0; + } + else { + s_r=S-R; + arg1=PI*(d_ij-R)/s_r; + f_c=0.5+0.5*cos(arg1); + df_c=-0.5*sin(arg1)*(PI/(s_r*d_ij)); + f_r=A*exp(-lambda*d_ij); + f_a=-B*exp(-mu*d_ij); + } + } + else + continue; + + + /* end 2 body stuff */ + + /* determine cell neighbours of btom */ + ki=(btom->r.x+(moldyn->dim.x/2))/lc->x; + kj=(btom->r.y+(moldyn->dim.y/2))/lc->y; + kk=(btom->r.z+(moldyn->dim.z/2))/lc->z; + ck=link_cell_neighbour_index(moldyn,ki,kj,kk, + neighbourk); + + /* go for zeta - 3 body stuff! */ + zeta=0.0; + d_ij2=d_ij*d_ij; + + /* cell of btom */ + thisk=&(neighbourk[0]); + list_reset(thisk); + do { + ktom=thisk->current->data; + if(ktom==btom) + continue; + if(ktom==&(atom[i])) + continue; + + /* 3 body stuff (1) */ + + v3_sub(&dist_ik,ktom,&(atom[i])); + d_ik=v3_norm(&dist_ik); + if(d_ik<=Sik) { + + Rik=; + Sik=; + Aik=; + lambda_ik=; + Bik=; + mu_ik=; + omega_ik=; + c_i=; + d_i=; + h_i=; + + + if(d_ik<=Rik) { + f_cik=1.0; + df_cik=0.0; + } + else { + sik_rik=Sik-Rik; + arg1ik=PI*(d_ik-Rik)/sik_rik; + f_cik=0.5+0.5*cos(arg1ik); + df_cik=-0.5*sin(arg1ik)* \ + (PI/(sik_rik*d_ik)); + f_rik=Aik*exp(-lambda_ik*d_ik); + f_aik=-Bik*exp(-mu_ik*d_ik); + } + + v3_sub(&distance_jk,ktom,btom); + cos_theta=(d_ij2+d_ik*d_ik-d_jk*d_jk)/\ + (2*d_ij*d_ik); + theta=arccos(cos_theta); + + + } + else + continue; + + /* end 3 body stuff (1) */ + + + } while(list_next(thisk)!=L_NO_NEXT_ELEMENT); + + /* direct neighbours of btom cell */ + for(k=1;kstart!=NULL) { + + do { + ktom=thisk->current->data; + if(ktom==&(atom[i])) + continue; + + /* 3 body stuff (2) */ + + } while(list_next(thisk)!=L_NO_NEXT_ELEMENT); + + } + } + + /* indirect neighbours of btom cell */ + for(k=ck;k<27;k++) { + thisk=&(neighbourk[k]); + list_reset(thisk); + if(thisk->start!=NULL) { + + do { + ktom=thisk->current->data; + if(ktom==&(atom[i])) + continue; + + /* 3 body stuff */ + + } while(list_next(thisk)!=L_NO_NEXT_ELEMENT); + + } + } + + + } while(list_next(this)!=L_NO_NEXT_ELEMENT); + + /* + * direct neighbour cells of atom i + */ + for(j=1;jstart!=NULL) { + + do { + btom=this->current->data; + + /* 2 body stuff */ + + + /* determine cell neighbours of btom */ + ki=(btom->r.x+(moldyn->dim.x/2))/lc->x; + kj=(btom->r.y+(moldyn->dim.y/2))/lc->y; + kk=(btom->r.z+(moldyn->dim.z/2))/lc->z; + ck=link_cell_neighbour_index(moldyn,ki,kj,kk, + neighbourk); + + /* cell of btom */ + thisk=&(neighbourk[0]); + list_reset(thisk); + do { + ktom=thisk->current->data; + if(ktom==btom) + continue; + if(ktom==&(atom[i])) + continue; + + /* 3 body stuff (1) */ + + } while(list_next(thisk)!=L_NO_NEXT_ELEMENT); + + /* direct neighbours of btom cell */ + for(k=1;kstart!=NULL) { + + do { + ktom=thisk->current->data; + if(ktom==&(atom[i])) + continue; + + /* 3 body stuff (2) */ + + } while(list_next(thisk)!=L_NO_NEXT_ELEMENT); + + } + } + + /* indirect neighbours of btom cell */ + for(k=ck;k<27;k++) { + thisk=&(neighbourk[k]); + list_reset(thisk); + if(thisk->start!=NULL) { + + do { + ktom=thisk->current->data; + if(ktom==&(atom[i])) + continue; + + /* 3 body stuff (3) */ + + } while(list_next(thisk)!=L_NO_NEXT_ELEMENT); + + } + } + + + } while(list_next(this)!=L_NO_NEXT_ELEMENT); + + } + } + + /* + * indirect neighbour cells of atom i + */ + for(j=c;j<27;j++) { + this=&(neighbour[j]); + list_reset(this); + if(this->start!=NULL) { + + do { + btom=this->current->data; + + /* 2 body stuff */ + + + /* determine cell neighbours of btom */ + ki=(btom->r.x+(moldyn->dim.x/2))/lc->x; + kj=(btom->r.y+(moldyn->dim.y/2))/lc->y; + kk=(btom->r.z+(moldyn->dim.z/2))/lc->z; + ck=link_cell_neighbour_index(moldyn,ki,kj,kk, + neighbourk); + + /* cell of btom */ + thisk=&(neighbourk[0]); + list_reset(thisk); + do { + ktom=thisk->current->data; + if(ktom==btom) + continue; + if(ktom==&(atom[i])) + continue; + + /* 3 body stuff (1) */ + + } while(list_next(thisk)!=L_NO_NEXT_ELEMENT); + + /* direct neighbours of btom cell */ + for(k=1;kstart!=NULL) { + + do { + ktom=thisk->current->data; + if(ktom==&(atom[i])) + continue; + + /* 3 body stuff (2) */ + + } while(list_next(thisk)!=L_NO_NEXT_ELEMENT); + + } + } + + /* indirect neighbours of btom cell */ + for(k=ck;k<27;k++) { + thisk=&(neighbourk[k]); + list_reset(thisk); + if(thisk->start!=NULL) { + + do { + ktom=thisk->current->data; + if(ktom==&(atom[i])) + continue; + + /* 3 body stuff (3) */ + + } while(list_next(thisk)!=L_NO_NEXT_ELEMENT); + + } + } + + + } while(list_next(this)!=L_NO_NEXT_ELEMENT); + + } + } + + } + + moldyn->energy=0.5*u; + + return 0; +} +