Trisurf Monte Carlo simulator
Samo Penic
2013-11-27 0652ee2715994b48a9bbfd1132bf0b65ad206289
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#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 "vertexmove.h"
#include "bondflip.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,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);
    ts_fprintf(stdout, "Starting %d threads\n",vesicle->threads);
 
    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);
 
    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++){
            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);
        if(i>inititer){
            write_vertex_xml_file(vesicle,i-inititer);
        }
    }
 
    pthread_mutex_destroy(&(vesicle->mutex->vtx_taint));
    pthread_mutex_destroy(&(vesicle->mutex->vtx_untaint));
    pthread_exit(NULL);
    return TS_SUCCESS;
}
 
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/data->threads);
    ts_uint end;
    if(thID==data->threads-1){
        end=vesicle->vlist->n;
    } else {
        end=(thID+1)*partition_size;
    }
    ts_double rnvec[3];
    ts_uint i,j,b;
    ts_vertex *vtx;
    //ts_bool retval;    
//    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(&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. 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(&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_int cnt=0;
    
    for(i=0;i<(ts_uint)((ts_double)(vesicle->vlist->n)/(ts_double)vesicle->threads);i++){
    b=rand() % vesicle->blist->n;
        //find a bond and return a pointer to a bond...
        //call single_bondflip_timestep...
    vtx=vesicle->blist->bond[b]->vtx1;
 
    /**** THREAD IS POTENTIALLY LOCKED ******/
    pthread_mutex_lock(&vesicle->mutex->vtx_taint);
            while(vertex_tainted(vtx,2,1)){
        ts_fprintf(stdout, "BF:: thID=%d Vertex %d is tainted. 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(vtx,2);
    pthread_mutex_unlock(&vesicle->mutex->vtx_untaint);
 
    pthread_mutex_unlock(&vesicle->mutex->vtx_taint);
    /**** THREAD IS RELEASING MUTEX RESOURCES ******/
 
    //retval=
    single_bondflip_timestep(vesicle,vesicle->blist->bond[b],rnvec);
    
    pthread_mutex_lock(&vesicle->mutex->vtx_untaint);
    vertex_untaint(vtx,2);
    pthread_mutex_unlock(&vesicle->mutex->vtx_untaint);
 
 
//    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);
    return TS_SUCCESS;
*/
     pthread_exit(0); /* exit */
}