*/
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;
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);
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;
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;
/*
*
* => 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");
}
/* 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;
+ /* 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->x=(moldyn->energy-u)/dv;
- p=tp->x*tp->x;
+ u_up=moldyn->energy;
/* 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 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->y=(moldyn->energy-u)/dv;
- p+=tp->y*tp->y;
-
- /* 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;
- 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) {
}
-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;
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;i<moldyn->count;i++) {
r=&(moldyn->atom[i].r);
if(x) r->x*=scale;
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) {
/* 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)
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))
/* 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;