#include <omp.h>
#endif
-#ifdef PTHREADS
+#if defined PTHREADS || defined VISUAL_THREAD
#include <pthread.h>
#endif
#undef PSE_NAME
#undef PSE_COL
+#ifdef PTHREADS
+/* global mutexes */
+pthread_mutex_t *amutex;
+pthread_mutex_t emutex;
+#endif
+
/*
* the moldyn functions
*/
rand_init(&(moldyn->random),NULL,1);
moldyn->random.status|=RAND_STAT_VERBOSE;
+#ifdef PTHREADS
+ pthread_mutex_init(&emutex,NULL);
+#endif
+
return 0;
}
int moldyn_shutdown(t_moldyn *moldyn) {
+#ifdef PTHREADS
+ int i;
+#endif
+
printf("[moldyn] shutdown\n");
+#ifdef PTHREADS
+ for(i=0;i<moldyn->count;i++)
+ pthread_mutex_destroy(&(amutex[i]));
+ free(amutex);
+ pthread_mutex_destroy(&emutex);
+#endif
+
moldyn_log_shutdown(moldyn);
link_cell_shutdown(moldyn);
rand_close(&(moldyn->random));
*/
int create_lattice(t_moldyn *moldyn,u8 type,double lc,int element,double mass,
- u8 attr,u8 brand,int a,int b,int c,t_3dvec *origin) {
+ u8 attr,u8 brand,int a,int b,int c,t_3dvec *origin,
+ u8 p_type,t_part_vals *p_vals) {
int new,count;
int ret;
void *ptr;
t_atom *atom;
char name[16];
+#ifdef PTHREADS
+ pthread_mutex_t *mutex;
+#endif
new=a*b*c;
count=moldyn->count;
moldyn->atom=ptr;
atom=&(moldyn->atom[count]);
+#ifdef PTHREADS
+ ptr=realloc(amutex,(count+new)*sizeof(pthread_mutex_t));
+ if(!ptr) {
+ perror("[moldyn] mutex realloc (add atom)");
+ return -1;
+ }
+ amutex=ptr;
+ mutex=&(amutex[count]);
+#endif
+
/* no atoms on the boundaries (only reason: it looks better!) */
if(!origin) {
orig.x=0.5*lc;
switch(type) {
case CUBIC:
set_nn_dist(moldyn,lc);
- ret=cubic_init(a,b,c,lc,atom,&orig);
+ ret=cubic_init(a,b,c,lc,atom,&orig,p_type,p_vals);
strcpy(name,"cubic");
break;
case FCC:
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,&orig);
+ ret=fcc_init(a,b,c,lc,atom,&orig,p_type,p_vals);
strcpy(name,"fcc");
break;
case DIAMOND:
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,&orig);
+ ret=diamond_init(a,b,c,lc,atom,&orig,p_type,p_vals);
strcpy(name,"diamond");
break;
default:
/* debug */
if(ret!=new) {
- printf("[moldyn] creating lattice failed\n");
+ printf("[moldyn] creating %s lattice (lc=%f) incomplete\n",
+ name,lc);
+ printf(" (ignore in case of partial lattice creation)\n");
printf(" amount of atoms\n");
printf(" - expected: %d\n",new);
printf(" - created: %d\n",ret);
- return -1;
}
- moldyn->count+=new;
- printf("[moldyn] created %s lattice with %d atoms\n",name,new);
+ moldyn->count+=ret;
+ if(ret==new)
+ printf("[moldyn] created %s lattice with %d atoms\n",name,ret);
- 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));
- atom[ret].r_0=atom[ret].r;
+ for(new=0;new<ret;new++) {
+ atom[new].element=element;
+ atom[new].mass=mass;
+ atom[new].attr=attr;
+ atom[new].brand=brand;
+ atom[new].tag=count+new;
+ check_per_bound(moldyn,&(atom[new].r));
+ atom[new].r_0=atom[new].r;
+#ifdef PTHREADS
+ pthread_mutex_init(&(mutex[new]),NULL);
+#endif
+ }
+
+ /* fix allocation */
+ ptr=realloc(moldyn->atom,moldyn->count*sizeof(t_atom));
+ if(!ptr) {
+ perror("[moldyn] realloc (create lattice - alloc fix)");
+ return -1;
}
+ moldyn->atom=ptr;
+
+#ifdef LOWMEM_LISTS
+ ptr=realloc(moldyn->lc.subcell->list,moldyn->count*sizeof(int));
+ if(!ptr) {
+ perror("[moldyn] list realloc (create lattice)");
+ return -1;
+ }
+ moldyn->lc.subcell->list=ptr;
+#endif
/* update total system mass */
total_mass_calc(moldyn);
moldyn->lc.subcell->list=ptr;
#endif
+#ifdef PTHREADS
+ ptr=realloc(amutex,(count+1)*sizeof(pthread_mutex_t));
+ if(!ptr) {
+ perror("[moldyn] mutex realloc (add atom)");
+ return -1;
+ }
+ amutex=ptr;
+ pthread_mutex_init(&(amutex[count]),NULL);
+#endif
+
atom=moldyn->atom;
/* initialize new atom */
}
/* cubic init */
-int cubic_init(int a,int b,int c,double lc,t_atom *atom,t_3dvec *origin) {
+int cubic_init(int a,int b,int c,double lc,t_atom *atom,t_3dvec *origin,
+ u8 p_type,t_part_vals *p_vals) {
int count;
t_3dvec r;
int i,j,k;
t_3dvec o;
+ t_3dvec dist;
+ t_3dvec p;
+
+ p.x=0; p.y=0; p.z=0;
count=0;
if(origin)
else
v3_zero(&o);
+ /* shift partition values */
+ if(p_type) {
+ p.x=p_vals->p.x+(a*lc)/2.0;
+ p.y=p_vals->p.y+(b*lc)/2.0;
+ p.z=p_vals->p.z+(c*lc)/2.0;
+ }
+
r.x=o.x;
for(i=0;i<a;i++) {
r.y=o.y;
for(j=0;j<b;j++) {
r.z=o.z;
for(k=0;k<c;k++) {
+ switch(p_type) {
+ case PART_INSIDE_R:
+ v3_sub(&dist,&r,&p);
+ if(v3_absolute_square(&dist)<(p_vals->r*p_vals->r)) {
v3_copy(&(atom[count].r),&r);
count+=1;
+ }
+ break;
+ case PART_OUTSIDE_R:
+ v3_sub(&dist,&r,&p);
+ if(v3_absolute_square(&dist)>=(p_vals->r*p_vals->r)) {
+ v3_copy(&(atom[count].r),&r);
+ count+=1;
+ }
+ break;
+ case PART_INSIDE_D:
+ v3_sub(&dist,&r,&p);
+ if((fabs(dist.x)<p_vals->d.x)&&
+ (fabs(dist.y)<p_vals->d.y)&&
+ (fabs(dist.z)<p_vals->d.z)) {
+ v3_copy(&(atom[count].r),&r);
+ count+=1;
+ }
+ break;
+ case PART_OUTSIDE_D:
+ v3_sub(&dist,&r,&p);
+ if((fabs(dist.x)>=p_vals->d.x)||
+ (fabs(dist.y)>=p_vals->d.y)||
+ (fabs(dist.z)>=p_vals->d.z)) {
+ v3_copy(&(atom[count].r),&r);
+ count+=1;
+ }
+ break;
+ default:
+ v3_copy(&(atom[count].r),&r);
+ count+=1;
+ break;
+ }
r.z+=lc;
}
r.y+=lc;
}
/* fcc lattice init */
-int fcc_init(int a,int b,int c,double lc,t_atom *atom,t_3dvec *origin) {
+int fcc_init(int a,int b,int c,double lc,t_atom *atom,t_3dvec *origin,
+ u8 p_type,t_part_vals *p_vals) {
int count;
int i,j,k,l;
t_3dvec o,r,n;
t_3dvec basis[3];
+ t_3dvec dist;
+ t_3dvec p;
+
+ p.x=0; p.y=0; p.z=0;
count=0;
if(origin)
basis[2].y=0.5*lc;
basis[2].z=0.5*lc;
+ /* shift partition values */
+ if(p_type) {
+ p.x=p_vals->p.x+(a*lc)/2.0;
+ p.y=p_vals->p.y+(b*lc)/2.0;
+ p.z=p_vals->p.z+(c*lc)/2.0;
+ }
+
/* fill up the room */
r.x=o.x;
for(i=0;i<a;i++) {
r.z=o.z;
for(k=0;k<c;k++) {
/* first atom */
+ switch(p_type) {
+ case PART_INSIDE_R:
+ v3_sub(&dist,&r,&p);
+ if(v3_absolute_square(&dist)<(p_vals->r*p_vals->r)) {
v3_copy(&(atom[count].r),&r);
count+=1;
- r.z+=lc;
+ }
+ break;
+ case PART_OUTSIDE_R:
+ v3_sub(&dist,&r,&p);
+ if(v3_absolute_square(&dist)>=(p_vals->r*p_vals->r)) {
+ v3_copy(&(atom[count].r),&r);
+ count+=1;
+ }
+ break;
+ case PART_INSIDE_D:
+ v3_sub(&dist,&r,&p);
+ if((fabs(dist.x)<p_vals->d.x)&&
+ (fabs(dist.y)<p_vals->d.y)&&
+ (fabs(dist.z)<p_vals->d.z)) {
+ v3_copy(&(atom[count].r),&r);
+ count+=1;
+ }
+ break;
+ case PART_OUTSIDE_D:
+ v3_sub(&dist,&r,&p);
+ if((fabs(dist.x)>=p_vals->d.x)||
+ (fabs(dist.y)>=p_vals->d.y)||
+ (fabs(dist.z)>=p_vals->d.z)) {
+ v3_copy(&(atom[count].r),&r);
+ count+=1;
+ }
+ break;
+ default:
+ v3_copy(&(atom[count].r),&r);
+ count+=1;
+ break;
+ }
/* the three face centered atoms */
for(l=0;l<3;l++) {
v3_add(&n,&r,&basis[l]);
+ switch(p_type) {
+ case PART_INSIDE_R:
+ v3_sub(&dist,&n,&p);
+ if(v3_absolute_square(&dist)<(p_vals->r*p_vals->r)) {
+ v3_copy(&(atom[count].r),&n);
+ count+=1;
+ }
+ break;
+ case PART_OUTSIDE_R:
+ v3_sub(&dist,&n,&p);
+ if(v3_absolute_square(&dist)>=(p_vals->r*p_vals->r)) {
+ v3_copy(&(atom[count].r),&n);
+ count+=1;
+ }
+ break;
+ case PART_INSIDE_D:
+ v3_sub(&dist,&n,&p);
+ if((fabs(dist.x)<p_vals->d.x)&&
+ (fabs(dist.y)<p_vals->d.y)&&
+ (fabs(dist.z)<p_vals->d.z)) {
+ v3_copy(&(atom[count].r),&n);
+ count+=1;
+ }
+ break;
+ case PART_OUTSIDE_D:
+ v3_sub(&dist,&n,&p);
+ if((fabs(dist.x)>=p_vals->d.x)||
+ (fabs(dist.y)>=p_vals->d.y)||
+ (fabs(dist.z)>=p_vals->d.z)) {
+ v3_copy(&(atom[count].r),&n);
+ count+=1;
+ }
+ break;
+ default:
v3_copy(&(atom[count].r),&n);
count+=1;
+ break;
+ }
}
+ r.z+=lc;
}
r.y+=lc;
}
return count;
}
-int diamond_init(int a,int b,int c,double lc,t_atom *atom,t_3dvec *origin) {
+int diamond_init(int a,int b,int c,double lc,t_atom *atom,t_3dvec *origin,
+ u8 p_type,t_part_vals *p_vals) {
int count;
t_3dvec o;
- count=fcc_init(a,b,c,lc,atom,origin);
+ count=fcc_init(a,b,c,lc,atom,origin,p_type,p_vals);
o.x=0.25*lc;
o.y=0.25*lc;
if(origin) v3_add(&o,&o,origin);
- count+=fcc_init(a,b,c,lc,&atom[count],&o);
+ count+=fcc_init(a,b,c,lc,&atom[count],&o,p_type,p_vals);
return count;
}
/* assume up to date kinetic energy, which is 3/2 N k_B T */
- moldyn->t=(2.0*moldyn->ekin)/(3.0*K_BOLTZMANN*moldyn->count);
+ if(moldyn->count)
+ moldyn->t=(2.0*moldyn->ekin)/(3.0*K_BOLTZMANN*moldyn->count);
+ else moldyn->t=0.0;
return moldyn->t;
}
}
/* global virial (absolute coordinates) */
- virial=&(moldyn->gvir);
- moldyn->gv=virial->xx+virial->yy+virial->zz;
+ //virial=&(moldyn->gvir);
+ //moldyn->gv=virial->xx+virial->yy+virial->zz;
return moldyn->virial;
}
moldyn->p=2.0*moldyn->ekin+moldyn->virial;
moldyn->p/=(3.0*moldyn->volume);
+ moldyn->px=2.0*moldyn->ekinx+moldyn->vir.xx;
+ moldyn->px/=moldyn->volume;
+ moldyn->py=2.0*moldyn->ekiny+moldyn->vir.yy;
+ moldyn->py/=moldyn->volume;
+ moldyn->pz=2.0*moldyn->ekinz+moldyn->vir.zz;
+ moldyn->pz/=moldyn->volume;
+
/* pressure (absolute coordinates) */
- moldyn->gp=2.0*moldyn->ekin+moldyn->gv;
- moldyn->gp/=(3.0*moldyn->volume);
+ //moldyn->gp=2.0*moldyn->ekin+moldyn->gv;
+ //moldyn->gp/=(3.0*moldyn->volume);
return moldyn->p;
}
/* virial */
moldyn->virial_sum=0.0;
- moldyn->gv_sum=0.0;
+ //moldyn->gv_sum=0.0;
/* pressure */
moldyn->p_sum=0.0;
- moldyn->gp_sum=0.0;
+ //moldyn->gp_sum=0.0;
moldyn->tp_sum=0.0;
return 0;
/* virial */
moldyn->virial_sum+=moldyn->virial;
moldyn->virial_avg=moldyn->virial_sum/denom;
- moldyn->gv_sum+=moldyn->gv;
- moldyn->gv_avg=moldyn->gv_sum/denom;
+ //moldyn->gv_sum+=moldyn->gv;
+ //moldyn->gv_avg=moldyn->gv_sum/denom;
/* pressure */
moldyn->p_sum+=moldyn->p;
moldyn->p_avg=moldyn->p_sum/denom;
- moldyn->gp_sum+=moldyn->gp;
- moldyn->gp_avg=moldyn->gp_sum/denom;
+ //moldyn->gp_sum+=moldyn->gp;
+ //moldyn->gp_avg=moldyn->gp_sum/denom;
moldyn->tp_sum+=moldyn->tp;
moldyn->tp_avg=moldyn->tp_sum/denom;
return 0;
}
+int scale_atoms_ind(t_moldyn *moldyn,double x,double y,double z) {
+
+ int i;
+ t_3dvec *r;
+
+ for(i=0;i<moldyn->count;i++) {
+ r=&(moldyn->atom[i].r);
+ r->x*=x;
+ r->y*=y;
+ r->z*=z;
+ }
+
+ return 0;
+}
+
+int scale_dim_ind(t_moldyn *moldyn,double x,double y,double z) {
+
+ t_3dvec *dim;
+
+ dim=&(moldyn->dim);
+
+ dim->x*=x;
+ dim->y*=y;
+ dim->z*=z;
+
+ return 0;
+}
+
int scale_volume(t_moldyn *moldyn) {
t_3dvec *dim,*vdim;
- double scale;
+ //double scale;
t_linkcell *lc;
+ double sx,sy,sz;
vdim=&(moldyn->vis.dim);
dim=&(moldyn->dim);
lc=&(moldyn->lc);
/* scaling factor */
+ /*
if(moldyn->pt_scale&P_SCALE_BERENDSEN) {
scale=1.0-(moldyn->p_ref-moldyn->p)*moldyn->p_tc*moldyn->tau;
scale=pow(scale,ONE_THIRD);
else {
scale=pow(moldyn->p/moldyn->p_ref,ONE_THIRD);
}
+ */
+
+ sx=1.0-(moldyn->p_ref-moldyn->px)*moldyn->p_tc*moldyn->tau;
+ sy=1.0-(moldyn->p_ref-moldyn->py)*moldyn->p_tc*moldyn->tau;
+ sz=1.0-(moldyn->p_ref-moldyn->pz)*moldyn->p_tc*moldyn->tau;
+ sx=pow(sx,ONE_THIRD);
+ sy=pow(sy,ONE_THIRD);
+ sz=pow(sz,ONE_THIRD);
/* scale the atoms and dimensions */
- scale_atoms(moldyn,SCALE_DIRECT,scale,TRUE,TRUE,TRUE);
- scale_dim(moldyn,SCALE_DIRECT,scale,TRUE,TRUE,TRUE);
+ //scale_atoms(moldyn,SCALE_DIRECT,scale,TRUE,TRUE,TRUE);
+ //scale_dim(moldyn,SCALE_DIRECT,scale,TRUE,TRUE,TRUE);
+ scale_atoms_ind(moldyn,sx,sy,sz);
+ scale_dim_ind(moldyn,sx,sy,sz);
/* visualize dimensions */
if(vdim->x!=0) {
link_cell_shutdown(moldyn);
link_cell_init(moldyn,QUIET);
} else {
- lc->x*=scale;
- lc->y*=scale;
- lc->z*=scale;
+ //lc->x*=scale;
+ //lc->y*=scale;
+ //lc->z*=scale;
+ lc->x*=sx;
+ lc->y*=sx;
+ lc->z*=sy;
}
return 0;
atom=moldyn->atom;
moldyn->ekin=0.0;
+ moldyn->ekinx=0.0;
+ moldyn->ekiny=0.0;
+ moldyn->ekinz=0.0;
for(i=0;i<moldyn->count;i++) {
atom[i].ekin=0.5*atom[i].mass*v3_absolute_square(&(atom[i].v));
moldyn->ekin+=atom[i].ekin;
+ moldyn->ekinx+=0.5*atom[i].mass*atom[i].v.x*atom[i].v.x;
+ moldyn->ekiny+=0.5*atom[i].mass*atom[i].v.y*atom[i].v.y;
+ moldyn->ekinz+=0.5*atom[i].mass*atom[i].v.z*atom[i].v.z;
}
return moldyn->ekin;
struct timeval t1,t2;
//double tp;
-#ifdef PTHREADS
+#ifdef VISUAL_THREAD
u8 first,change;
pthread_t io_thread;
int ret;
moldyn->debug=0;
/* zero & init moldyn copy */
-#ifdef PTHREADS
+#ifdef VISUAL_THREAD
memset(&md_copy,0,sizeof(t_moldyn));
atom_copy=malloc(moldyn->count*sizeof(t_atom));
if(atom_copy==NULL) {
}
#endif
+#ifdef PTHREADS
+ printf("##################\n");
+ printf("# USING PTHREADS #\n");
+ printf("##################\n");
+#endif
/* tell the world */
printf("[moldyn] integration start, go get a coffee ...\n");
dprintf(moldyn->pfd,
"%f %f %f %f %f %f %f\n",moldyn->time,
moldyn->p/BAR,moldyn->p_avg/BAR,
- moldyn->gp/BAR,moldyn->gp_avg/BAR,
+ moldyn->p/BAR,moldyn->p_avg/BAR,
moldyn->tp/BAR,moldyn->tp_avg/BAR);
}
}
if(v) {
if(!(moldyn->total_steps%v)) {
dprintf(moldyn->vfd,
- "%f %f\n",moldyn->time,moldyn->volume);
+ "%f %f %f %f %f\n",moldyn->time,
+ moldyn->volume,
+ moldyn->dim.x,
+ moldyn->dim.y,
+ moldyn->dim.z);
}
}
if(s) {
}
if(a) {
if(!(moldyn->total_steps%a)) {
-#ifdef PTHREADS
+#ifdef VISUAL_THREAD
/* check whether thread has not terminated yet */
if(!first) {
ret=pthread_join(io_thread,NULL);
/* get current time */
gettimeofday(&t2,NULL);
-printf("\rsched:%d, steps:%d/%d, T:%4.1f/%4.1f P:%4.1f/%4.1f V:%6.1f (%d)",
+printf("sched:%d, steps:%d/%d, T:%4.1f/%4.1f P:%4.1f/%4.1f V:%6.1f (%d)\n",
sched->count,i,moldyn->total_steps,
moldyn->t,moldyn->t_avg,
moldyn->p/BAR,moldyn->p_avg/BAR,
jtom,
ktom,
bc_ik|bc_ij);
+
#ifdef STATIC_LISTS
}
#elif LOWMEM_LISTS
size-=cnt;
}
+#ifdef PTHREADS
+ amutex=malloc(moldyn->count*sizeof(pthread_mutex_t));
+ if(amutex==NULL) {
+ perror("[moldyn] load save file (mutexes)");
+ return -1;
+ }
+ for(cnt=0;cnt<moldyn->count;cnt++)
+ pthread_mutex_init(&(amutex[cnt]),NULL);
+#endif
+
// hooks etc ...
return 0;
return 0;
}
-#ifdef PTHREADS
+#ifdef VISUAL_THREAD
void *visual_atoms(void *ptr) {
#else
int visual_atoms(t_moldyn *moldyn) {
t_visual *v;
t_atom *atom;
t_vb vb;
-#ifdef PTHREADS
+#ifdef VISUAL_THREAD
t_moldyn *moldyn;
moldyn=ptr;
vb.fd=open(file,O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR);
if(vb.fd<0) {
perror("open visual save file fd");
-#ifndef PTHREADS
+#ifndef VISUAL_THREAD
return -1;
#endif
}
atom[i].ekin);
// bonds between atoms
+#ifndef VISUAL_THREAD
process_2b_bonds(moldyn,&vb,visual_bonds_process);
+#endif
// boundaries
if(dim.x) {
close(vb.fd);
-#ifdef PTHREADS
+#ifdef VISUAL_THREAD
pthread_exit(NULL);
}