Trisurf Monte Carlo simulator
Samo Penic
2013-11-24 84af719f37b54185ddd7daf0627421143874905c
src/timestep.c
@@ -2,7 +2,7 @@
#include<stdio.h>
#include<math.h>
#include<pthread.h>
#include<unistd.h> //usleep requires it
//#include<unistd.h> //usleep requires it
//#include "io.h"
#include "general.h"
#include "timestep.h"
@@ -13,42 +13,34 @@
#include "io.h"
ts_bool run_simulation(ts_vesicle *vesicle, ts_uint mcsweeps, ts_uint inititer, ts_uint iterations){
   ts_uint i, j;
   ts_uint i, j,k ;
   centermass(vesicle);
   cell_occupation(vesicle);
   ts_fprintf(stdout, "Starting simulation (first %d x %d MC sweeps will not be recorded on disk)\n", inititer, mcsweeps);
   pthread_t tid1,tid2, tid3, tid4;
   thdata data1, data2, data3, data4;
   pthread_mutex_t mutex;
   data1.thread_no=0;
   data2.thread_no=1;
   data1.vesicle=vesicle;
   data2.vesicle=vesicle;
          data3.thread_no=2;
   data4.thread_no=3;
   data3.vesicle=vesicle;
   data4.vesicle=vesicle;
   ts_fprintf(stdout, "Starting %d threads\n",vesicle->threads);
   data1.vtx_tainting_lock=&mutex;
   data2.vtx_tainting_lock=&mutex;
   data3.vtx_tainting_lock=&mutex;
   data4.vtx_tainting_lock=&mutex;
   pthread_t *tid=(pthread_t *)malloc(sizeof(pthread_t)*vesicle->threads);
   thdata *data=(thdata *)malloc(sizeof(thdata)*vesicle->threads);
   pthread_mutex_init(&(vesicle->mutex->vtx_taint),NULL);
   pthread_mutex_init(&(vesicle->mutex->vtx_untaint),NULL);
   pthread_mutex_init(&(vesicle->mutex->cell_modify),NULL);
   pthread_mutex_init(&mutex,NULL);
   for(i=0;i<vesicle->threads;i++){
      data[i].thread_no=i;
      data[i].vesicle=vesicle;
      data[i].threads=vesicle->threads;
   }
    for(i=0;i<inititer+iterations;i++){
      for(j=0;j<mcsweeps;j++){
         pthread_create(&tid1,NULL,single_timestep,(void *)&data1);
              pthread_create(&tid2,NULL,single_timestep,(void *)&data2);
              pthread_create(&tid3,NULL,single_timestep,(void *)&data3);
              pthread_create(&tid4,NULL,single_timestep,(void *)&data4);
              pthread_join(tid1,NULL);
              pthread_join(tid2,NULL);
              pthread_join(tid3,NULL);
              pthread_join(tid4,NULL);
//   single_timestep(vesicle);
         for(k=0;k<vesicle->threads;k++){
            pthread_create(&tid[k], NULL, single_timestep, (void *)&data[k]);
         }
         for(k=0;k<vesicle->threads;k++){
                 pthread_join(tid[k],NULL);
         }
      //   single_timestep(vesicle);
      }
      centermass(vesicle);
      cell_occupation(vesicle);
@@ -57,7 +49,8 @@
      }
   }
   pthread_mutex_destroy(&mutex);
   pthread_mutex_destroy(&(vesicle->mutex->vtx_taint));
   pthread_mutex_destroy(&(vesicle->mutex->vtx_untaint));
   pthread_exit(NULL);
   return TS_SUCCESS;
}
@@ -67,32 +60,45 @@
   data=(thdata *)thread_data;
   ts_vesicle *vesicle=data->vesicle;
   ts_uint thID=data->thread_no;
   ts_uint partition_size=(ts_uint)(vesicle->vlist->n/4);
   ts_uint partition_size=(ts_uint)(vesicle->vlist->n/data->threads);
   ts_uint end;
   if(thID==3){
   if(thID==data->threads-1){
      end=vesicle->vlist->n;
   } else {
      end=(thID+1)*partition_size;
   }
    ts_double rnvec[3];
    ts_uint i; //b;
    ts_uint i,j; //b;
//   ts_fprintf(stdout,"Thread thID=%d report for duty. My vtxes are in range from %d to %d.\n",thID,thID*partition_size, end-1);
    for(i=thID*partition_size;i<end;i++){
        rnvec[0]=drand48();
        rnvec[1]=drand48();
        rnvec[2]=drand48();
//TODO: you only need to taint (lock) vertices, that could be shared with another partition. You can leave out the rest. How can you test for that? Well, if any of vtx neighbours are in other partition, then you need to lock vertex and that neighbor. Otherwise not!
   /**** THREAD IS POTENTIALLY LOCKED ******/
   pthread_mutex_lock(data->vtx_tainting_lock); //taint if no other process is tainting or wait until you can taint
   pthread_mutex_lock(&vesicle->mutex->vtx_taint); //taint if no other process is tainting or wait until you can taint
   //   ts_fprintf(stdout, "thID=%d:: Tainting vertex %d, level=%d. Waiting....\n",thID, i, vesicle->vlist->vtx[i]->locked);
   while(vertex_tainted(vesicle->vlist->vtx[i],1,1)){
      ts_fprintf(stdout, "thID=%d:: Vertex %d is tainted, so I cannot try vertexmove. Level=%d. WAITING!\n",thID, i, vesicle->vlist->vtx[i]->locked);
      ts_fprintf(stdout, "thID=%d:: Vertex %d is tainted, so I cannot try vertexmove. Amount=%d. BU(H)TELJ!\n       neigh. vtxs: ",thID, i, vesicle->vlist->vtx[i]->locked);
      for(j=0; j<vesicle->vlist->vtx[i]->neigh_no; j++){
         ts_fprintf(stdout, "%d(a=%d) ", vesicle->vlist->vtx[i]->neigh[j]->idx,  vesicle->vlist->vtx[i]->neigh[j]->locked);
      }
      ts_fprintf(stdout, ".\n");
   }
   pthread_mutex_lock(&vesicle->mutex->vtx_untaint);
   vertex_taint(vesicle->vlist->vtx[i],1);
   pthread_mutex_unlock(data->vtx_tainting_lock);
   pthread_mutex_unlock(&vesicle->mutex->vtx_untaint);
   pthread_mutex_unlock(&vesicle->mutex->vtx_taint);
   /**** THREAD IS RELEASING MUTEX RESOURCES ******/
        single_verticle_timestep(vesicle,vesicle->vlist->vtx[i],rnvec);
   pthread_mutex_lock(&vesicle->mutex->vtx_untaint);
   vertex_untaint(vesicle->vlist->vtx[i],1);
   pthread_mutex_unlock(&vesicle->mutex->vtx_untaint);
//      ts_fprintf(stdout, "Vertex %d should be untainted, level=%d.\n", i, vesicle->vlist->vtx[i]->locked);
    }