#include <omp.h>
#endif
+#ifdef PTHREADS
+#include <pthread.h>
+#endif
+
#include "moldyn.h"
#include "report/report.h"
struct timeval t1,t2;
//double tp;
+#ifdef PTHREADS
+ u8 first,change;
+ pthread_t io_thread;
+ int ret;
+ t_moldyn md_copy;
+ t_atom *atom_copy;
+
+ first=1;
+ change=0;
+#endif
+
sched=&(moldyn->schedule);
atom=moldyn->atom;
/* debugging, ignore */
moldyn->debug=0;
+ /* zero & init moldyn copy */
+#ifdef PTHREADS
+ memset(&md_copy,0,sizeof(t_moldyn));
+ atom_copy=malloc(moldyn->count*sizeof(t_atom));
+ if(atom_copy==NULL) {
+ perror("[moldyn] malloc atom copy (init)");
+ return -1;
+ }
+#endif
+
/* tell the world */
printf("[moldyn] integration start, go get a coffee ...\n");
}
if(s) {
if(!(moldyn->total_steps%s)) {
- snprintf(dir,128,"%s/s-%07.f.save",
+ snprintf(dir,128,"%s/s-%08.f.save",
moldyn->vlsdir,moldyn->time);
fd=open(dir,O_WRONLY|O_TRUNC|O_CREAT,
S_IRUSR|S_IWUSR);
}
if(a) {
if(!(moldyn->total_steps%a)) {
+#ifdef PTHREADS
+ /* check whether thread has not terminated yet */
+ if(!first) {
+ ret=pthread_join(io_thread,NULL);
+ }
+ first=0;
+ /* prepare and start thread */
+ if(moldyn->count!=md_copy.count) {
+ free(atom_copy);
+ change=1;
+ }
+ memcpy(&md_copy,moldyn,sizeof(t_moldyn));
+ if(change) {
+ atom_copy=malloc(moldyn->count*sizeof(t_atom));
+ if(atom_copy==NULL) {
+ perror("[moldyn] malloc atom copy (change)");
+ return -1;
+ }
+ }
+ md_copy.atom=atom_copy;
+ memcpy(atom_copy,moldyn->atom,moldyn->count*sizeof(t_atom));
+ change=0;
+ ret=pthread_create(&io_thread,NULL,visual_atoms,&md_copy);
+ if(ret) {
+ perror("[moldyn] create visual atoms thread\n");
+ return -1;
+ }
+#else
visual_atoms(moldyn);
+#endif
}
}
/* display progress */
- //if(!(moldyn->total_steps%10)) {
+ if(!(i%10)) {
/* get current time */
gettimeofday(&t2,NULL);
/* copy over time */
t1=t2;
- //}
+ }
/* increase absolute time */
moldyn->time+=moldyn->tau;
#endif
u8 bc_ij,bc_ik;
int dnlc;
+#ifdef PTHREADS
+ int ret;
+ pthread_t kthread[27];
+ t_kdata kdata[27];
+#endif
count=moldyn->count;
itom=moldyn->atom;
atom=moldyn->atom;
#endif
+#ifdef PTHREADS
+ memset(kdata,0,27*sizeof(t_kdata));
+#endif
+
/* reset energy */
moldyn->energy=0.0;
continue;
/* first loop over atoms k */
+#ifndef PTHREADS
if(moldyn->func3b_k1) {
+#endif
for(k=0;k<27;k++) {
if(ktom==&(itom[i]))
continue;
+#ifdef PTHREADS
+ kdata[k].moldyn=moldyn;
+ kdata[k].ai=&(itom[i]);
+ kdata[k].aj=jtom;
+ kdata[k].ak=ktom;
+ kdata[k].bc=bc_ik;
+ ret=pthread_create(&(kthread[k]),NULL,moldyn->func3b_k1,&(kdata[k]));
+ if(ret) {
+ perror("[moldyn] create k1 thread");
+ return ret;
+ }
+#else
moldyn->func3b_k1(moldyn,
&(itom[i]),
jtom,
ktom,
bc_ik|bc_ij);
+#endif
+
#ifdef STATIC_LISTS
}
#elif LOWMEM_LISTS
}
+#ifndef PTHREADS
}
+#endif
if(moldyn->func3b_j2)
moldyn->func3b_j2(moldyn,
}
+/*
+ * function to find neighboured atoms
+ */
+
+int process_neighbours(t_moldyn *moldyn,void *data,t_atom *atom,
+ int (*process)(t_moldyn *moldyn,t_atom *atom,t_atom *natom,
+ void *data,u8 bc)) {
+
+ t_linkcell *lc;
+#ifdef STATIC_LISTS
+ int *neighbour[27];
+ int p;
+#elif LOWMEM_LISTS
+ int neighbour[27];
+ int p;
+#else
+ t_list neighbour[27];
+ t_list *this;
+#endif
+ u8 bc;
+ t_atom *natom;
+ int j;
+
+ lc=&(moldyn->lc);
+
+ /* neighbour indexing */
+ link_cell_neighbour_index(moldyn,
+ (atom->r.x+moldyn->dim.x/2)/lc->x,
+ (atom->r.y+moldyn->dim.y/2)/lc->x,
+ (atom->r.z+moldyn->dim.z/2)/lc->x,
+ neighbour);
+
+ for(j=0;j<27;j++) {
+
+ bc=(j<lc->dnlc)?0:1;
+
+#ifdef STATIC_LISTS
+ p=0;
+
+ while(neighbour[j][p]!=-1) {
+
+ natom=&(moldyn->atom[neighbour[j][p]]);
+ p++;
+#elif LOWMEM_LISTS
+ p=neighbour[j];
+
+ while(p!=-1) {
+
+ natom=&(moldyn->atom[p]);
+ p=lc->subcell->list[p];
+#else
+ this=&(neighbour[j]);
+ list_reset_f(this);
+
+ if(this->start==NULL)
+ continue;
+
+ do {
+
+ natom=this->current->data;
+#endif
+
+ /* process bond */
+ process(moldyn,atom,natom,data,bc);
+
+#ifdef STATIC_LISTS
+ }
+#elif LOWMEM_LISTS
+ }
+#else
+ } while(list_next_f(this)!=L_NO_NEXT_ELEMENT);
+#endif
+ }
+
+ return 0;
+
+}
+
/*
* post processing functions
*/
return 0;
}
+#ifdef PTHREADS
+void *visual_atoms(void *ptr) {
+#else
int visual_atoms(t_moldyn *moldyn) {
+#endif
int i;
char file[128+64];
t_visual *v;
t_atom *atom;
t_vb vb;
+#ifdef PTHREADS
+ t_moldyn *moldyn;
+
+ moldyn=ptr;
+#endif
v=&(moldyn->vis);
dim.x=v->dim.x;
help=(dim.x+dim.y);
- sprintf(file,"%s/atomic_conf_%07.f.xyz",v->fb,moldyn->time);
+ sprintf(file,"%s/atomic_conf_%08.f.xyz",v->fb,moldyn->time);
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
return -1;
+#endif
}
/* write the actual data file */
// povray header
- dprintf(vb.fd,"# [P] %d %07.f <%f,%f,%f>\n",
+ dprintf(vb.fd,"# [P] %d %08.f <%f,%f,%f>\n",
moldyn->count,moldyn->time,help/40.0,help/40.0,-0.8*help);
// atomic configuration
close(vb.fd);
+#ifdef PTHREADS
+ pthread_exit(NULL);
+
+}
+#else
+
return 0;
}
+#endif
/*
* fpu cntrol functions