| | |
| | | #include<stdlib.h> |
| | | #include<stdio.h> |
| | | #include<math.h> |
| | | #include<pthread.h> |
| | | #include<unistd.h> //usleep requires it |
| | | //#include "io.h" |
| | | #include "general.h" |
| | | #include "timestep.h" |
| | |
| | | #include "frame.h" |
| | | #include "vertex.h" |
| | | #include "io.h" |
| | | |
| | | ts_bool run_simulation(ts_vesicle *vesicle, ts_uint mcsweeps, ts_uint inititer, ts_uint iterations){ |
| | | ts_uint i, j; |
| | | |
| | | 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); |
| | | for(i=0;i<inititer+iterations;i++){ |
| | | 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; |
| | | |
| | | data1.vtx_tainting_lock=&mutex; |
| | | data2.vtx_tainting_lock=&mutex; |
| | | data3.vtx_tainting_lock=&mutex; |
| | | data4.vtx_tainting_lock=&mutex; |
| | | |
| | | pthread_mutex_init(&mutex,NULL); |
| | | |
| | | for(i=0;i<inititer+iterations;i++){ |
| | | for(j=0;j<mcsweeps;j++){ |
| | | single_timestep(vesicle); |
| | | 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); |
| | | } |
| | | centermass(vesicle); |
| | | cell_occupation(vesicle); |
| | |
| | | write_vertex_xml_file(vesicle,i-inititer); |
| | | } |
| | | } |
| | | |
| | | pthread_mutex_destroy(&mutex); |
| | | pthread_exit(NULL); |
| | | return TS_SUCCESS; |
| | | } |
| | | |
| | | ts_bool single_timestep(ts_vesicle *vesicle){ |
| | | ts_bool retval; |
| | | void * single_timestep(void *thread_data){ |
| | | thdata *data; |
| | | 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 end; |
| | | if(thID==3){ |
| | | end=vesicle->vlist->n; |
| | | } else { |
| | | end=(thID+1)*partition_size; |
| | | } |
| | | ts_double rnvec[3]; |
| | | ts_uint i, b; |
| | | for(i=0;i<vesicle->vlist->n;i++){ |
| | | ts_uint i; //b; |
| | | for(i=thID*partition_size;i<end;i++){ |
| | | rnvec[0]=drand48(); |
| | | rnvec[1]=drand48(); |
| | | rnvec[2]=drand48(); |
| | | vertex_taint(vesicle->vlist->vtx[i],1); |
| | | // ts_fprintf(stdout, "Vertex %d should be tainted, level=%d.\n", i, vesicle->vlist->vtx[i]->locked); |
| | | if(vertex_tainted(vesicle->vlist->vtx[i],1,1)){ |
| | | ts_fprintf(stdout, "Vertex %d tainted, level=%d. Waiting....\n", i, vesicle->vlist->vtx[i]->locked); |
| | | while(vertex_tainted(vesicle->vlist->vtx[i],1,1)); |
| | | |
| | | /**** THREAD IS POTENTIALLY LOCKED ******/ |
| | | pthread_mutex_lock(data->vtx_tainting_lock); //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); |
| | | } |
| | | retval=single_verticle_timestep(vesicle,vesicle->vlist->vtx[i],rnvec); |
| | | vertex_taint(vesicle->vlist->vtx[i],1); |
| | | pthread_mutex_unlock(data->vtx_tainting_lock); |
| | | /**** THREAD IS RELEASING MUTEX RESOURCES ******/ |
| | | |
| | | single_verticle_timestep(vesicle,vesicle->vlist->vtx[i],rnvec); |
| | | vertex_untaint(vesicle->vlist->vtx[i],1); |
| | | // ts_fprintf(stdout, "Vertex %d should be untainted, level=%d.\n", i, vesicle->vlist->vtx[i]->locked); |
| | | } |
| | | |
| | | // ts_int cnt=0; |
| | | /* |
| | | for(i=0;i<vesicle->vlist->n;i++){ |
| | | //why is rnvec needed in bondflip? |
| | | /* rnvec[0]=drand48(); |
| | | rnvec[1]=drand48(); |
| | | rnvec[2]=drand48(); |
| | | */ |
| | | b=rand() % vesicle->blist->n; |
| | | //find a bond and return a pointer to a bond... |
| | | //call single_bondflip_timestep... |
| | |
| | | // if(retval==TS_SUCCESS) cnt++; |
| | | } |
| | | // printf("Bondflip success rate in one sweep: %d/%d=%e\n", cnt,vesicle->blist->n,(double)cnt/(double)vesicle->blist->n); |
| | | if(retval); |
| | | */ |
| | | /* if(retval); |
| | | return TS_SUCCESS; |
| | | */ |
| | | pthread_exit(0); /* exit */ |
| | | } |
| | | |
| | | |