Trisurf Monte Carlo simulator
Samo Penic
2014-03-08 2870ab279d5dce60c24e7a3e35d8a5e421003548
commit | author | age
aec47d 1 #include<stdlib.h>
SP 2 #include<math.h>
3 #include "general.h"
4 #include "vertex.h"
5 #include "bond.h"
6 #include "triangle.h"
7 #include "vesicle.h"
8 #include "energy.h"
9 #include "timestep.h"
10 #include "cell.h"
30ee9c 11 #include "bondflip.h"
aec47d 12 //#include "io.h"
SP 13 #include<stdio.h>
2870ab 14 #include<string.h>
aec47d 15
SP 16 ts_bool single_bondflip_timestep(ts_vesicle *vesicle, ts_bond *bond, ts_double *rn){
17 /*c  Vertex and triangle (lm and lp) indexing for bond flip:
18 c      +----- k-------+              +----- k ------+
19 c      |lm1 / | \ lp1 |              |lm1 /   \ lp1 |
20 c      |  /   |   \   |              |  /       \   |
21 c      |/     |     \ |     FLIP     |/    lm     \ |
22 c     km  lm  | lp   kp    --->      km ---------- kp  
23 c      |\     |     / |              |\    lp     / |  
24 c      |  \   |   /   |              |  \       /   |
25 c      |lm2 \ | / lp2 |              |lm2 \   / lp2 |
26 c      +------it------+              +----- it -----+
27 c
28 */
29     ts_vertex *it=bond->vtx1;
30     ts_vertex *k=bond->vtx2;
31     ts_uint nei,neip,neim;
b866cf 32     ts_uint i,j;
414b8a 33     ts_double oldenergy, delta_energy, dvol=0.0;
b866cf 34     ts_triangle *lm=NULL,*lp=NULL, *lp1=NULL, *lm2=NULL;
aec47d 35
SP 36     ts_vertex *kp,*km;
37
38     if(it->neigh_no< 3) return TS_FAIL;
39     if(k->neigh_no< 3) return TS_FAIL;
40     if(k==NULL || it==NULL){
41         fatal("In bondflip, number of neighbours of k or it is less than 3!",999);
42     }
43
30ee9c 44     nei=0;
aec47d 45     for(i=0;i<it->neigh_no;i++){ // Finds the nn of it, that is k 
SP 46         if(it->neigh[i]==k){
47             nei=i;
48             break;
49         }
50     }
51     neip=nei+1;  // I don't like it.. Smells like I must have it in correct order
52     neim=nei-1;
53     if(neip>=it->neigh_no) neip=0;
54     if((ts_int)neim<0) neim=it->neigh_no-1; /* casting is essential... If not
55 there the neim is never <0 !!! */
56   //  fprintf(stderr,"The numbers are: %u %u\n",neip, neim);
57     km=it->neigh[neim];  // We located km and kp
58     kp=it->neigh[neip];
59
60     if(km==NULL || kp==NULL){
61         fatal("In bondflip, cannot determine km and kp!",999);
62     }
63
64   //  fprintf(stderr,"I WAS HERE! after the 4 vertices are known!\n");
65
66 /* test if the membrane is wrapped too much, so that kp is nearest neighbour of
67  * km. If it is true, then don't flip! */
68     for(i=0;i<km->neigh_no;i++){
69         if(km->neigh[i] == kp) return TS_FAIL;
70     }
71  //   fprintf(stderr,"Membrane didn't wrap too much.. Continue.\n");
72 /* if bond would be too long, return... */
30ee9c 73     if(vtx_distance_sq(km,kp) > vesicle->dmax ) return TS_FAIL;
aec47d 74  //   fprintf(stderr,"Bond will not be too long.. Continue.\n");
SP 75
76 /* we make a bond flip. this is different than in original fortran */
b866cf 77 // find lm, lp
aec47d 78 // 1. step. We find lm and lp from k->tristar !
SP 79     for(i=0;i<it->tristar_no;i++){
80         for(j=0;j<k->tristar_no;j++){
81             if((it->tristar[i] == k->tristar[j])){ //ce gre za skupen trikotnik
82                 if((it->tristar[i]->vertex[0] == km || it->tristar[i]->vertex[1]
83 == km || it->tristar[i]->vertex[2]== km )){
84                 lm=it->tristar[i];
85          //       lmidx=i;
86                 }
87                 else
88                 {
89                 lp=it->tristar[i];
90          //       lpidx=i;
91                 }
92
93             }
94         }
95     }
96 if(lm==NULL || lp==NULL) fatal("ts_flip_bond: Cannot find triangles lm and lp!",999);
97
98 //we look for important triangles lp1 and lm2.
99
100  for(i=0;i<k->tristar_no;i++){
101         for(j=0;j<kp->tristar_no;j++){
102                 if((k->tristar[i] == kp->tristar[j]) && k->tristar[i]!=lp){ //ce gre za skupen trikotnik
103                     lp1=k->tristar[i];
104             }
105         }
106 }
107
108  for(i=0;i<it->tristar_no;i++){
109         for(j=0;j<km->tristar_no;j++){
110             if((it->tristar[i] == km->tristar[j]) && it->tristar[i]!=lm){ //ce gre za skupen trikotnik
111                     lm2=it->tristar[i];
112             } 
113         }
114     }
115
116 if(lm2==NULL || lp1==NULL) fatal("ts_flip_bond: Cannot find triangles lm2 and lp1!",999);
2870ab 117
SP 118
119 /* backup old structure */
120 /* need to backup:
121  * vertices k, kp, km, it
122  * triangles lm, lp, lm2, lp1
123  * bond
124  */
125 ts_vertex *bck_vtx[4];
126 ts_triangle *bck_tria[4];
127 ts_bond *bck_bond;
128 ts_vertex *orig_vtx[]={k,it,kp,km};
129 ts_triangle *orig_tria[]={lm,lp, lm2,lp1};
130
131 fprintf(stderr,"Backuping!!!\n");
132 for(i=0;i<4;i++){
133     bck_vtx[i]=(ts_vertex *)malloc(sizeof(ts_vertex));
134     bck_tria[i]=(ts_triangle *)malloc(sizeof(ts_triangle));
135     bck_bond=(ts_bond *)malloc(sizeof(ts_bond));
136     /* level 2 pointers */
137     bck_vtx[i]->neigh=(ts_vertex **)malloc(orig_vtx[i]->neigh_no*sizeof(ts_vertex *));
138     bck_vtx[i]->tristar=(ts_triangle **)malloc(orig_vtx[i]->tristar_no*sizeof(ts_triangle *));
139     bck_vtx[i]->bond=(ts_bond **)malloc(orig_vtx[i]->bond_no*sizeof(ts_bond *));
140     bck_tria[i]->neigh=(ts_triangle **)malloc(orig_tria[i]->neigh_no*sizeof(ts_triangle *));
141
142     bck_vtx[i]=memcpy(bck_vtx[i],orig_vtx[i],sizeof(ts_vertex));
143     bck_vtx[i]->neigh=memcpy(bck_vtx[i]->neigh,orig_vtx[i]->neigh,orig_vtx[i]->neigh_no*sizeof(ts_vertex *));
144     bck_vtx[i]->tristar=memcpy(bck_vtx[i]->tristar,orig_vtx[i]->tristar,orig_vtx[i]->tristar_no*sizeof(ts_triangle *));
145     bck_vtx[i]->bond=memcpy(bck_vtx[i]->bond,orig_vtx[i]->bond,orig_vtx[i]->bond_no*sizeof(ts_bond *));
146
147         
148     bck_tria[i]=memcpy(bck_tria[i],orig_tria[i],sizeof(ts_triangle));
149     bck_tria[i]->neigh=memcpy(bck_tria[i]->neigh,orig_tria[i]->neigh,orig_tria[i]->neigh_no*sizeof(ts_triangle *));    
150 }
151     bck_bond=memcpy(bck_bond,bond,sizeof(ts_bond));
152 fprintf(stderr,"Backup complete!!!\n");
153 /* end backup vertex */
b866cf 154     
414b8a 155 /* Save old energy */
b866cf 156   oldenergy=0;
M 157   oldenergy+=k->xk* k->energy;
158   oldenergy+=kp->xk* kp->energy;
159   oldenergy+=km->xk* km->energy;
160   oldenergy+=it->xk* it->energy;
414b8a 161   //Neigbours of k, it, km, kp don't change its energy.
aec47d 162
414b8a 163     if(vesicle->pswitch == 1){dvol = -lm->volume - lp->volume;}
M 164
165 /* fix data structure for flipped bond */
166     ts_flip_bond(k,it,km,kp, bond,lm, lp, lm2, lp1);
aec47d 167
SP 168
b866cf 169 /* Calculating the new energy */
M 170   delta_energy=0;
171   delta_energy+=k->xk* k->energy;
172   delta_energy+=kp->xk* kp->energy;
173   delta_energy+=km->xk* km->energy;
174   delta_energy+=it->xk* it->energy;
414b8a 175   //Neigbours of k, it, km, kp don't change its energy.
M 176
b866cf 177   delta_energy-=oldenergy;
414b8a 178     if(vesicle->pswitch == 1){
M 179         dvol = dvol + lm->volume + lp->volume;
180         delta_energy-= vesicle->pressure*dvol;
181     }
182
b866cf 183 /* MONTE CARLO */
M 184     if(delta_energy>=0){
185 #ifdef TS_DOUBLE_DOUBLE
186         if(exp(-delta_energy)< drand48() )
187 #endif
188 #ifdef TS_DOUBLE_FLOAT
189         if(expf(-delta_energy)< (ts_float)drand48())
190 #endif
191 #ifdef TS_DOUBLE_LONGDOUBLE
192         if(expl(-delta_energy)< (ts_ldouble)drand48())
193 #endif
194         {
195             //not accepted, reverting changes
196 //            fprintf(stderr,"Failed to move, due to MC\n");
aec47d 197
2870ab 198       //      ts_flip_bond(kp,km,k,it, bond, lm,lp,lm2,lp1);
b866cf 199 //    fprintf(stderr,"%e, %e, %e\n", lp->xnorm, lp->ynorm, lp->znorm);
2870ab 200
SP 201     //restore all backups
202             fprintf(stderr,"Restoring!!!\n");
203
204 for(i=0;i<4;i++){
205     /* level 2 pointers */
206     orig_vtx[i]=memcpy(orig_vtx[i],bck_vtx[i],sizeof(ts_vertex));
207     orig_vtx[i]->neigh=memcpy(orig_vtx[i]->neigh,bck_vtx[i]->neigh,bck_vtx[i]->neigh_no*sizeof(ts_vertex *));
208     orig_vtx[i]->tristar=memcpy(orig_vtx[i]->tristar,bck_vtx[i]->tristar,bck_vtx[i]->tristar_no*sizeof(ts_triangle *));
209     orig_vtx[i]->bond=memcpy(orig_vtx[i]->bond,bck_vtx[i]->bond,bck_vtx[i]->bond_no*sizeof(ts_bond *));
210
211         
212     orig_tria[i]=memcpy(orig_tria[i],bck_tria[i],sizeof(ts_triangle));
213     orig_tria[i]->neigh=memcpy(orig_tria[i]->neigh,bck_tria[i]->neigh,bck_tria[i]->neigh_no*sizeof(ts_triangle *));    
214 }
215     bond=memcpy(bond,bck_bond,sizeof(ts_bond));
216
217
218     for(i=0;i<4;i++){
219         vtx_free(bck_vtx[i]);
220
221      free(bck_tria[i]->neigh);
222         free(bck_tria[i]);
223         
224     }
225         free(bck_bond);
226
227             fprintf(stderr,"Restoration complete!!!\n");
228
b866cf 229             return TS_FAIL;
M 230         }
231     }
232      /* IF BONDFLIP ACCEPTED, THEN RETURN SUCCESS! */
2870ab 233             fprintf(stderr,"SUCCESS!!!\n");
SP 234
235     // delete all backups
236     for(i=0;i<4;i++){
237         vtx_free(bck_vtx[i]);
238
239      free(bck_tria[i]->neigh);
240         free(bck_tria[i]);
241         
242     }
243         free(bck_bond);
b866cf 244     return TS_SUCCESS;
aec47d 245 }
SP 246
247
b866cf 248 ts_bool ts_flip_bond(ts_vertex *k,ts_vertex *it,ts_vertex *km, ts_vertex *kp,
M 249 ts_bond *bond, ts_triangle *lm, ts_triangle *lp, ts_triangle *lm2, ts_triangle *lp1){
250
251     ts_uint i; //lmidx, lpidx;
252 if(k==NULL || it==NULL || km==NULL || kp==NULL){
253     fatal("ts_flip_bond: You called me with invalid pointers to vertices",999);
254 }
aec47d 255 // 2. step. We change the triangle vertices... (actual bond flip)
SP 256     for(i=0;i<3;i++) if(lm->vertex[i]== it) lm->vertex[i]= kp;
257     for(i=0;i<3;i++) if(lp->vertex[i]== k) lp->vertex[i]= km;
e19e79 258 //fprintf(stderr,"2. step: actual bondflip made\n");
aec47d 259 // 2a. step. If any changes in triangle calculations must be done, do it here!
SP 260 //   * normals are recalculated here
261     triangle_normal_vector(lp);
262     triangle_normal_vector(lm);
e19e79 263 //fprintf(stderr,"2a. step: triangle normals recalculated\n");
aec47d 264 // 3. step. Correct neighbours in vertex_list
SP 265
266
30ee9c 267             vtx_remove_neighbour(k,it);
306559 268 //            vtx_remove_neighbour(it,k);
e19e79 269 //fprintf(stderr,"3. step (PROGRESS): removed k and it neighbours\n");
306559 270     
aec47d 271             //Tukaj pa nastopi tezava... Kam dodati soseda?
30ee9c 272             vtx_insert_neighbour(km,kp,k);
SP 273             vtx_insert_neighbour(kp,km,it);
aec47d 274 //            vertex_add_neighbour(km,kp); //pazi na vrstni red.
SP 275 //            vertex_add_neighbour(kp,km);
e19e79 276 //fprintf(stderr,"3. step: vertex neighbours corrected\n");
aec47d 277
SP 278 // 3a. step. If any changes to ts_vertex, do it here!
279 //   bond_length calculatons not required for it is done in energy.c
280
281 // 4. step. Correct bond_list (don't know why I still have it!)
282             bond->vtx1=km;
283             bond->vtx2=kp;
284 //fprintf(stderr,"4. step: bondlist corrected\n");
285
286
287 // 5. step. Correct neighbouring triangles 
288    
289     triangle_remove_neighbour(lp,lp1);
e19e79 290   //  fprintf(stderr,".\n");
aec47d 291     triangle_remove_neighbour(lp1,lp);
SP 292   //  fprintf(stderr,".\n");
293     triangle_remove_neighbour(lm,lm2);
294   //  fprintf(stderr,".\n");
295     triangle_remove_neighbour(lm2,lm);
296    
297     triangle_add_neighbour(lm,lp1);    
298     triangle_add_neighbour(lp1,lm);
299     triangle_add_neighbour(lp,lm2);  //Vrstni red?!
300     triangle_add_neighbour(lm2,lp);
301
302 //fprintf(stderr,"5. step: triangle neigbours corrected\n");
303
304
305 // 6. step. Correct tristar for vertices km, kp, k and it
306             vertex_add_tristar(km,lp);  // Preveri vrstni red!
307             vertex_add_tristar(kp,lm);
30ee9c 308             vtx_remove_tristar(it,lm);
SP 309             vtx_remove_tristar(k,lp);
aec47d 310 //fprintf(stderr,"6. step: tristar corrected\n");
SP 311   energy_vertex(k);
312   energy_vertex(kp);
313   energy_vertex(km);
314   energy_vertex(it);
315 // END modifications to data structure!
316     return TS_SUCCESS;
317 }