X-Git-Url: https://hackdaworld.org/gitweb/?a=blobdiff_plain;f=moldyn.c;h=aebd6049de10d66fa2b3cea4b8893eeb13dbff23;hb=75f0a0576d76e3d49bd8c6e62ab0a6f5c1ce72ab;hp=705a28ca43be21b0839c4937e8fe22294c62c309;hpb=57847266c05bc38218bf162efdb08e8dd40894d7;p=physik%2Fposic.git diff --git a/moldyn.c b/moldyn.c index 705a28c..aebd604 100644 --- a/moldyn.c +++ b/moldyn.c @@ -421,11 +421,11 @@ int moldyn_log_shutdown(t_moldyn *moldyn) { */ int create_lattice(t_moldyn *moldyn,u8 type,double lc,int element,double mass, - u8 attr,u8 brand,int a,int b,int c) { + u8 attr,u8 brand,int a,int b,int c,t_3dvec *origin) { int new,count; int ret; - t_3dvec origin; + t_3dvec orig; void *ptr; t_atom *atom; @@ -447,24 +447,33 @@ int create_lattice(t_moldyn *moldyn,u8 type,double lc,int element,double mass, atom=&(moldyn->atom[count]); /* no atoms on the boundaries (only reason: it looks better!) */ - origin.x=0.5*lc; - origin.y=0.5*lc; - origin.z=0.5*lc; + if(!origin) { + orig.x=0.5*lc; + orig.y=0.5*lc; + orig.z=0.5*lc; + } + else { + orig.x=origin->x; + orig.y=origin->y; + orig.z=origin->z; + } switch(type) { case CUBIC: set_nn_dist(moldyn,lc); - ret=cubic_init(a,b,c,lc,atom,&origin); + ret=cubic_init(a,b,c,lc,atom,&orig); break; case FCC: - v3_scale(&origin,&origin,0.5); + if(!origin) + v3_scale(&orig,&orig,0.5); set_nn_dist(moldyn,0.5*sqrt(2.0)*lc); - ret=fcc_init(a,b,c,lc,atom,&origin); + ret=fcc_init(a,b,c,lc,atom,&orig); break; case DIAMOND: - v3_scale(&origin,&origin,0.25); + if(!origin) + v3_scale(&orig,&orig,0.25); set_nn_dist(moldyn,0.25*sqrt(3.0)*lc); - ret=diamond_init(a,b,c,lc,atom,&origin); + ret=diamond_init(a,b,c,lc,atom,&orig); break; default: printf("unknown lattice type (%02x)\n",type); @@ -794,8 +803,12 @@ double pressure_calc(t_moldyn *moldyn) { v+=(virial->xx+virial->yy+virial->zz); } + /* virial sum and mean virial */ + moldyn->virial_sum+=v; + moldyn->mean_v=moldyn->virial_sum/moldyn->total_steps; + /* assume up to date kinetic energy */ - moldyn->p=2.0*moldyn->ekin+v; + moldyn->p=2.0*moldyn->ekin+moldyn->mean_v; moldyn->p/=(3.0*moldyn->volume); moldyn->p_sum+=moldyn->p; moldyn->mean_p=moldyn->p_sum/moldyn->total_steps; @@ -814,8 +827,8 @@ double pressure_calc(t_moldyn *moldyn) { double thermodynamic_pressure_calc(t_moldyn *moldyn) { t_3dvec dim,*tp; - double u,p; - double scale,dv; + double u_up,u_down,dv; + double scale,p; t_atom *store; /* @@ -823,13 +836,11 @@ double thermodynamic_pressure_calc(t_moldyn *moldyn) { * * => p = - dU/dV * - * dV: dx,y,z = 0.001 x,y,z */ - scale=1.00000000000001; -printf("\n\nP-DEBUG:\n"); + scale=0.00001; + dv=8*scale*scale*scale*moldyn->volume; - tp=&(moldyn->tp); store=malloc(moldyn->count*sizeof(t_atom)); if(store==NULL) { printf("[moldyn] allocating store mem failed\n"); @@ -837,59 +848,44 @@ printf("\n\nP-DEBUG:\n"); } /* save unscaled potential energy + atom/dim configuration */ - u=moldyn->energy; memcpy(store,moldyn->atom,moldyn->count*sizeof(t_atom)); dim=moldyn->dim; - /* derivative with respect to x direction */ - scale_dim(moldyn,scale,TRUE,0,0); - scale_atoms(moldyn,scale,TRUE,0,0); - dv=0.00000000000001*moldyn->dim.x*moldyn->dim.y*moldyn->dim.z; - link_cell_shutdown(moldyn); - link_cell_init(moldyn,QUIET); - potential_force_calc(moldyn); - tp->x=(moldyn->energy-u)/dv; - p=tp->x*tp->x; - - /* restore atomic configuration + dim */ - memcpy(moldyn->atom,store,moldyn->count*sizeof(t_atom)); - moldyn->dim=dim; - - /* derivative with respect to y direction */ - scale_dim(moldyn,scale,0,TRUE,0); - scale_atoms(moldyn,scale,0,TRUE,0); - dv=0.00000000000001*moldyn->dim.y*moldyn->dim.x*moldyn->dim.z; + /* scale up dimension and atom positions */ + scale_dim(moldyn,SCALE_UP,scale,TRUE,TRUE,TRUE); + scale_atoms(moldyn,SCALE_UP,scale,TRUE,TRUE,TRUE); link_cell_shutdown(moldyn); link_cell_init(moldyn,QUIET); potential_force_calc(moldyn); - tp->y=(moldyn->energy-u)/dv; - p+=tp->y*tp->y; + u_up=moldyn->energy; /* restore atomic configuration + dim */ memcpy(moldyn->atom,store,moldyn->count*sizeof(t_atom)); moldyn->dim=dim; - /* derivative with respect to z direction */ - scale_dim(moldyn,scale,0,0,TRUE); - scale_atoms(moldyn,scale,0,0,TRUE); - dv=0.00000000000001*moldyn->dim.z*moldyn->dim.x*moldyn->dim.y; + /* scale down dimension and atom positions */ + scale_dim(moldyn,SCALE_DOWN,scale,TRUE,TRUE,TRUE); + scale_atoms(moldyn,SCALE_DOWN,scale,TRUE,TRUE,TRUE); link_cell_shutdown(moldyn); link_cell_init(moldyn,QUIET); potential_force_calc(moldyn); - tp->z=(moldyn->energy-u)/dv; - p+=tp->z*tp->z; + u_down=moldyn->energy; + + /* calculate pressure */ + p=-(u_up-u_down)/dv; +printf("-------> %.10f %.10f %f\n",u_up/EV/moldyn->count,u_down/EV/moldyn->count,p/BAR); /* restore atomic configuration + dim */ memcpy(moldyn->atom,store,moldyn->count*sizeof(t_atom)); moldyn->dim=dim; /* restore energy */ - moldyn->energy=u; + potential_force_calc(moldyn); link_cell_shutdown(moldyn); link_cell_init(moldyn,QUIET); - return sqrt(p); + return p; } double get_pressure(t_moldyn *moldyn) { @@ -898,12 +894,18 @@ double get_pressure(t_moldyn *moldyn) { } -int scale_dim(t_moldyn *moldyn,double scale,u8 x,u8 y,u8 z) { +int scale_dim(t_moldyn *moldyn,u8 dir,double scale,u8 x,u8 y,u8 z) { t_3dvec *dim; dim=&(moldyn->dim); + if(dir==SCALE_UP) + scale=1.0+scale; + + if(dir==SCALE_DOWN) + scale=1.0-scale; + if(x) dim->x*=scale; if(y) dim->y*=scale; if(z) dim->z*=scale; @@ -911,11 +913,17 @@ int scale_dim(t_moldyn *moldyn,double scale,u8 x,u8 y,u8 z) { return 0; } -int scale_atoms(t_moldyn *moldyn,double scale,u8 x,u8 y,u8 z) { +int scale_atoms(t_moldyn *moldyn,u8 dir,double scale,u8 x,u8 y,u8 z) { int i; t_3dvec *r; + if(dir==SCALE_UP) + scale=1.0+scale; + + if(dir==SCALE_DOWN) + scale=1.0-scale; + for(i=0;icount;i++) { r=&(moldyn->atom[i].r); if(x) r->x*=scale; @@ -947,8 +955,8 @@ int scale_volume(t_moldyn *moldyn) { moldyn->debug=scale; /* scale the atoms and dimensions */ - scale_atoms(moldyn,scale,TRUE,TRUE,TRUE); - scale_dim(moldyn,scale,TRUE,TRUE,TRUE); + scale_atoms(moldyn,SCALE_DIRECT,scale,TRUE,TRUE,TRUE); + scale_dim(moldyn,SCALE_DIRECT,scale,TRUE,TRUE,TRUE); /* visualize dimensions */ if(vdim->x!=0) { @@ -1252,6 +1260,9 @@ int moldyn_integrate(t_moldyn *moldyn) { /* calculate initial forces */ potential_force_calc(moldyn); +#ifdef DEBUG +return 0; +#endif /* some stupid checks before we actually start calculating bullshit */ if(moldyn->cutoff>0.5*moldyn->dim.x) @@ -1294,7 +1305,7 @@ int moldyn_integrate(t_moldyn *moldyn) { temperature_calc(moldyn); pressure_calc(moldyn); //tp=thermodynamic_pressure_calc(moldyn); -//printf("thermodynamic p: %f %f %f - %f\n",moldyn->tp.x/BAR,moldyn->tp.y/BAR,moldyn->tp.z/BAR,tp/BAR); +//printf("thermodynamic p: %f\n",thermodynamic_pressure_calc(moldyn)/BAR); /* p/t scaling */ if(moldyn->pt_scale&(T_SCALE_BERENDSEN|T_SCALE_DIRECT)) @@ -1486,7 +1497,8 @@ int potential_force_calc(t_moldyn *moldyn) { /* single particle potential/force */ if(itom[i].attr&ATOM_ATTR_1BP) - moldyn->func1b(moldyn,&(itom[i])); + if(moldyn->func1b) + moldyn->func1b(moldyn,&(itom[i])); if(!(itom[i].attr&(ATOM_ATTR_2BP|ATOM_ATTR_3BP))) continue; @@ -1793,3 +1805,102 @@ int moldyn_bc_check(t_moldyn *moldyn) { return 0; } + +/* + * postprocessing functions + */ +#define LINE_MAX 128 +int read_line(int fd,char *line) { + + int count,ret; + + count=0; + + while(1) { + if(count==LINE_MAX) return count; + ret=read(fd,line+count,1); + if(ret<0) return ret; + if(line[count]=='\n') { + line[count]='\0'; + return count+1; + } + count+=1; + } +} + +int calc_fluctuations(double start,double end,char *file) { + + int fd; + int count,ret; + double time,pot,kin,tot; + double p_m,k_m,t_m; + double p2_m,k2_m,t2_m; + double p_sum,k_sum,t_sum; + char buf[LINE_MAX]; + + fd=open(file,O_RDONLY); + if(fd<0) { + perror("[moldyn] post proc open"); + return fd; + } + + /* first calc the averages */ + p_sum=0.0; + k_sum=0.0; + t_sum=0.0; + count=0; + while(1) { + ret=read_line(fd,buf); + if(ret<0) break; +printf("%d\n",ret); + if(buf[0]=='#') continue; + sscanf(buf,"%lf %lf %lf %lf",&time,&kin,&pot,&tot); +printf("%f %f %f %f\n",time,pot,kin,tot); + //if(time>end) break; + if((time>=start)&(time<=end)) { + p_sum+=pot; + k_sum+=kin; + t_sum+=tot; + count+=1; + } + } + + p_m=p_sum/count; + k_m=k_sum/count; + t_m=t_sum/count; + + /* mean square fluctuations */ + if(lseek(fd,SEEK_SET,0)<0) { + perror("[moldyn] lseek"); + return -1; + } + count=0; + p_sum=0.0; + k_sum=0.0; + t_sum=0.0; + while(1) { + ret=read_line(fd,buf); + if(ret<0) break; + if(buf[0]=='#') continue; + sscanf(buf,"%lf %lf %lf %lf",&time,&kin,&pot,&tot); + if(time>end) break; + if((time>=start)&(time<=end)) { + p_sum+=((pot-p_m)*(pot-p_m)); + k_sum+=((kin-k_m)*(kin-k_m)); + t_sum+=((tot-t_m)*(tot-t_m)); + count+=1; + } + } + + p2_m=p_sum/count; + k2_m=k_sum/count; + t2_m=t_sum/count; + + printf("[moldyn] fluctuations (%f - %f):\n",start,end); + printf(" - averages : %f %f %f\n",k_m,p_m,t_m); + printf(" - mean square: %f %f %f\n",k2_m,p2_m,t2_m); + + close(fd); + + return 0; +}