Trisurf Monte Carlo simulator
Samo Penic
2014-03-08 7efbb1dbd7c2c1368c429858a32fbeb9467420a8
commit | author | age
7958e9 1 #include<stdlib.h>
SP 2 #include<math.h>
3 #include<stdio.h>
4 #include "general.h"
5 #include "vertex.h"
6 #include "bond.h"
7 #include "vesicle.h"
8 #include "vertex.h"
9 #include "triangle.h"
10 #include "initial_distribution.h"
f74313 11 #include "energy.h"
7958e9 12
SP 13 ts_vesicle *initial_distribution_dipyramid(ts_uint nshell, ts_uint ncmax1, ts_uint ncmax2, ts_uint ncmax3, ts_double stepsize){
14     ts_fprintf(stderr,"Starting initial_distribution on vesicle with %u shells!...\n",nshell);
15     ts_bool retval;
16     ts_uint no_vertices=5*nshell*nshell+2;
314f2d 17
SP 18
7958e9 19     
SP 20     ts_vesicle *vesicle=init_vesicle(no_vertices,ncmax1,ncmax2,ncmax3,stepsize);
314f2d 21
7958e9 22     vesicle->nshell=nshell;
SP 23     retval = vtx_set_global_values(vesicle);
24     retval = pentagonal_dipyramid_vertex_distribution(vesicle->vlist);
25     retval = init_vertex_neighbours(vesicle->vlist);
b01cc1 26     vesicle->vlist = init_sort_neighbours(vesicle->blist,vesicle->vlist);
SP 27    // retval = init_vesicle_bonds(vesicle); // bonds are created in sort_neigh
7958e9 28     retval = init_triangles(vesicle);
SP 29     retval = init_triangle_neighbours(vesicle);
30     retval = init_common_vertex_triangle_neighbours(vesicle);
dac2e5 31     retval = init_normal_vectors(vesicle->tlist);
f74313 32     retval = mean_curvature_and_energy(vesicle);
7958e9 33  ts_fprintf(stderr,"initial_distribution finished!\n");
41a035 34     if(retval);
7958e9 35     return vesicle;
SP 36
37
38
39 ts_bool pentagonal_dipyramid_vertex_distribution(ts_vertex_list *vlist){
40     /* Some often used relations */
41     const ts_double s1= sin(2.0*M_PI/5.0);
42     const ts_double s2= sin(4.0*M_PI/5.0);
43     const ts_double c1= cos(2.0*M_PI/5.0);
44     const ts_double c2= cos(4.0*M_PI/5.0);
45
46     /* Calculates projection lenght of an edge bond to pentagram plane */
47     const ts_double xl0=A0/(2.0*sin(M_PI/5.0));
48 #ifdef TS_DOUBLE_DOUBLE
49     const ts_double z0=sqrt(pow(A0,2)-pow(xl0,2));
50 #endif
51 #ifdef TS_DOUBLE_FLOAT
52     const ts_double z0=sqrtf(powf(A0,2)-powf(xl0,2));
53 #endif
54 #ifdef TS_DOUBLE_LONGDOUBLE
55     const ts_double z0=sqrtl(powl(A0,2)-powl(xl0,2));
56 #endif
57 //    const z0=sqrt(A0*A0 -xl0*xl0); /* I could use pow function but if pow is used make a check on the float type. If float then powf, if long double use powl */
58
59 /*placeholder for the pointer to vertex datastructure list... DIRTY: actual pointer points towards invalid address, one position before actual beginning of the list... This is to solve the difference between 1 based indexing in original program in fortran and 0 based indexing in C. All algorithms remain unchanged because of this!*/
60     ts_vertex **vtx=vlist->vtx -1 ; 
61
62
63     ts_uint nshell=(ts_uint)( sqrt((ts_double)(vlist->n-2)/5));
64 //    printf("nshell=%u\n",nshell);
65     ts_uint i,n0; // some for loop prereq
66     ts_int j,k;
67     ts_double dx,dy; // end loop prereq
68
69     /* topmost vertex */
8f6a69 70     vtx[1]->x=0.0;
SP 71     vtx[1]->y=0.0;
72     vtx[1]->z=z0*(ts_double)nshell;
7958e9 73     
SP 74     /* starting from to in circular order on pentagrams */    
75     for(i=1;i<=nshell;i++){
76         n0=2+5*i*(i-1)/2; //-1 would be for the reason that C index starts from 0 
8f6a69 77         vtx[n0]->x=0.0;
SP 78         vtx[n0]->y=(ts_double)i*xl0;
79         vtx[n0+i]->x=vtx[n0]->y*s1;
80         vtx[n0+i]->y=vtx[n0]->y*c1;
81         vtx[n0+2*i]->x=vtx[n0]->y*s2;
82         vtx[n0+2*i]->y=vtx[n0]->y*c2;
83         vtx[n0+3*i]->x=-vtx[n0+2*i]->x;
84         vtx[n0+3*i]->y=vtx[n0+2*i]->y;
85         vtx[n0+4*i]->x=-vtx[n0+i]->x;
86         vtx[n0+4*i]->y=vtx[n0+i]->y;
7958e9 87     }
SP 88
89     /* vertexes on the faces of the dipyramid */
90     for(i=1;i<=nshell;i++){
91         n0=2+5*i*(i-1)/2; // -1 would be because of C!
92         for(j=1;j<=i-1;j++){
8f6a69 93             dx=(vtx[n0]->x-vtx[n0+4*i]->x)/(ts_double)i;
SP 94             dy=(vtx[n0]->y-vtx[n0+4*i]->y)/(ts_double)i;
95             vtx[n0+4*i+j]->x=(ts_double)j*dx+vtx[n0+4*i]->x;
96             vtx[n0+4*i+j]->y=(ts_double)j*dy+vtx[n0+4*i]->y;
7958e9 97         }
SP 98         for(k=0;k<=3;k++){ // I would be worried about zero starting of for
8f6a69 99             dx=(vtx[n0+(k+1)*i]->x - vtx[n0+k*i]->x)/(ts_double) i;
SP 100             dy=(vtx[n0+(k+1)*i]->y - vtx[n0+k*i]->y)/(ts_double) i;
7958e9 101             for(j=1; j<=i-1;j++){
8f6a69 102                 vtx[n0+k*i+j]->x= (ts_double)j*dx+vtx[n0+k*i]->x;
SP 103                 vtx[n0+k*i+j]->y= (ts_double)j*dy+vtx[n0+k*i]->y;
7958e9 104             } 
SP 105         } 
106     }
107
108     for(i=1;i<=nshell;i++){
109         n0= 2+ 5*i*(i-1)/2;
110         for(j=0;j<=5*i-1;j++){
8f6a69 111         vtx[n0+j]->z= z0*(ts_double)(nshell-i);   // I would be worried about zero starting of for
7958e9 112         }
SP 113     }
114
115 /* for botom part of dipyramide we calculate the positions of vertices */
116     for(i=2+5*nshell*(nshell+1)/2;i<=vlist->n;i++){
8f6a69 117         vtx[i]->x=vtx[vlist->n - i +1]->x;
SP 118         vtx[i]->y=vtx[vlist->n - i +1]->y;
119         vtx[i]->z=-vtx[vlist->n - i +1]->z;
7958e9 120     }
SP 121
122     for(i=1;i<=vlist->n;i++){
123         for(j=1;j<=vlist->n;j++){
124             if(i!=j && vtx_distance_sq(vtx[i],vtx[j])<0.001){
125                 printf("Vertices %u and %u are the same!\n",i,j);
126             }
127         }
128     }
129     return TS_SUCCESS;
130 }
131
132
133
134 ts_bool init_vertex_neighbours(ts_vertex_list *vlist){
135     ts_vertex **vtx=vlist->vtx -1; // take a look at dipyramid function for comment.
136     const ts_double eps=0.001; //TODO: find out if you can use EPS from math.h
137     ts_uint i,j;
138     ts_double dist2; // Square of distance of neighbours
139     /*this is not required if we zero all data in vertex structure at initialization */
140     /*if we force zeroing at initialization this for loop can safely be deleted */
141     //for(i=1;i<=vlist->n;i++){
142     //    vtx[i].neigh_no=0;
143     //}
144     for(i=1;i<=vlist->n;i++){
145         for(j=1;j<=vlist->n;j++){
146             dist2=vtx_distance_sq(vtx[i],vtx[j]);
147             if( (dist2>eps) && (dist2<(A0*A0+eps))){ 
148     //if it is close enough, but not too much close (solves problem of comparing when i==j)
149                 vtx_add_neighbour(vtx[i],vtx[j]);
150             }
151         }
152     //        printf ("vertex %u ima %u sosedov!\n",i,vtx[i]->data->neigh_no);
153     }
154
155     return TS_SUCCESS;
156 }
157
b01cc1 158 // TODO: with new datastructure can be rewritten. Partially it is done, but it is complicated.
SP 159 ts_vertex_list *init_sort_neighbours(ts_bond_list *blist,ts_vertex_list *vlist){
7958e9 160     ts_vertex **vtx=vlist->vtx -1; // take a look at dipyramid function for comment.
SP 161     ts_uint i,l,j,jj,jjj,k=0;   
162     ts_double eps=0.001; // Take a look if EPS from math.h can be used
163
164 /*lets initialize memory for temporary vertex_list. Should we write a function instead */
b01cc1 165     ts_vertex_list *tvlist=vertex_list_copy(vlist);
7958e9 166     ts_vertex **tvtx=tvlist->vtx -1;  /* again to compensate for 0-indexing */
SP 167
168     ts_double dist2; // Square of distance of neighbours
169     ts_double direct; // Something, dont know what, but could be normal of some kind
170     for(i=1;i<=vlist->n;i++){
171         k++; // WHY i IS NOT GOOD??
8f6a69 172            vtx_add_cneighbour(blist,tvtx[k], tvtx[vtx[i]->neigh[0]->idx+1]); //always add 1st
7958e9 173            jjj=1;
SP 174            jj=1;
8f6a69 175            for(l=2;l<=vtx[i]->neigh_no;l++){
SP 176                for(j=2;j<=vtx[i]->neigh_no;j++){
177                    dist2=vtx_distance_sq(vtx[i]->neigh[j-1],vtx[i]->neigh[jj-1]);
178                    direct=vtx_direct(vtx[i],vtx[i]->neigh[j-1],vtx[i]->neigh[jj-1]);
179 // TODO: check if fabs can be used with all floating point types!!
7958e9 180                    if( (fabs(dist2-A0*A0)<=eps) && (direct>0.0) && (j!=jjj) ){
8f6a69 181                        vtx_add_cneighbour(blist,tvtx[k],tvtx[vtx[i]->neigh[j-1]->idx+1]);
7958e9 182                        jjj=jj;
SP 183                        jj=j;
184                        break;
185                    }
186                }
187            }    
188     }
b01cc1 189 /* We use the temporary vertex for our main vertices and we abandon main
SP 190  * vertices, because their neighbours are not correctly ordered */
191    // tvtx=vlist->vtx;
192    // vlist->vtx=tvtx;
193    // tvlist->vtx=vtx;
194     vtx_list_free(vlist);
195 /* Let's make a check if the number of bonds is correct */
196     if((blist->n)!=3*(tvlist->n-2)){
197         ts_fprintf(stderr,"Number of bonds is %u should be %u!\n", blist->n, 3*(tvlist->n-2));
198         fatal("Number of bonds is not 3*(no_vertex-2).",4);
7958e9 199     }
SP 200
b01cc1 201     return tvlist;
7958e9 202 }
SP 203
204
205 ts_bool init_vesicle_bonds(ts_vesicle *vesicle){
206     ts_vertex_list *vlist=vesicle->vlist;
207     ts_bond_list *blist=vesicle->blist;
208     ts_vertex **vtx=vesicle->vlist->vtx - 1; // Because of 0 indexing
209 /* lets make correct clockwise ordering of in nearest neighbour list */
210     ts_uint i,j,k;
211     for(i=1;i<=vlist->n;i++){
212         for(j=i+1;j<=vlist->n;j++){
8f6a69 213             for(k=0;k<vtx[i]->neigh_no;k++){ // has changed 0 to < instead of 1 and <=
SP 214                 if(vtx[i]->neigh[k]==vtx[j]){  //if addresses matches it is the same
7958e9 215                     bond_add(blist,vtx[i],vtx[j]);
SP 216                     break;
217                 }
218             }
219         }
220     } 
221 /* Let's make a check if the number of bonds is correct */
222     if((blist->n)!=3*(vlist->n-2)){
223         ts_fprintf(stderr,"Number of bonds is %u should be %u!\n", blist->n, 3*(vlist->n-2));
224         fatal("Number of bonds is not 3*(no_vertex-2).",4);
225     }
226     return TS_SUCCESS;
227 }
228
229
230
231 ts_bool init_triangles(ts_vesicle *vesicle){
232     ts_uint i,j,jj,k;
233     ts_vertex **vtx=vesicle->vlist->vtx -1; // difference between 0 indexing and 1 indexing
234     ts_triangle_list *tlist=vesicle->tlist;
235     ts_double dist, direct;
236     ts_double eps=0.001; // can we use EPS from math.h?
237     k=0;
238     for(i=1;i<=vesicle->vlist->n;i++){
8f6a69 239         for(j=1;j<=vtx[i]->neigh_no;j++){
SP 240             for(jj=1;jj<=vtx[i]->neigh_no;jj++){
7958e9 241         //        ts_fprintf(stderr,"%u: (%u,%u) neigh_no=%u ",i,j,jj,vtx[i].neigh_no);
SP 242         //      ts_fprintf(stderr,"%e, %e",vtx[i].neigh[j-1]->x,vtx[i].neigh[jj-1]->x);
8f6a69 243                 dist=vtx_distance_sq(vtx[i]->neigh[j-1],vtx[i]->neigh[jj-1]);
SP 244                 direct=vtx_direct(vtx[i],vtx[i]->neigh[j-1],vtx[i]->neigh[jj-1]);                
245 // TODO: same as above                
246                 if(fabs(dist-A0*A0)<=eps && direct < 0.0 && vtx[i]->neigh[j-1]->idx+1 > i && vtx[i]->neigh[jj-1]->idx+1 >i){
247                     triangle_add(tlist,vtx[i],vtx[i]->neigh[j-1],vtx[i]->neigh[jj-1]);
7958e9 248                 }    
SP 249             }    
250         }
251     }
252 /* We check if all triangles have 3 vertices and if the number of triangles
253  * matches the theoretical value.
254  */
255     for(i=0;i<tlist->n;i++){
256         k=0;
257         for(j=0;j<3;j++){
41a035 258             if(tlist->tria[i]->vertex[j]!=NULL)
7958e9 259             k++;
SP 260         }
261             if(k!=3){
8f6a69 262                 fatal("Some triangles have less than 3 vertices..",4);
7958e9 263             }   
SP 264     } 
265     if(tlist->n!=2*(vesicle->vlist->n -2)){
266         ts_fprintf(stderr,"The number of triangles is %u but should be %u!\n",tlist->n,2*(vesicle->vlist->n -2));
267         fatal("The number of triangles doesn't match 2*(no_vertex -2).",4);
268     }
269     return TS_SUCCESS;
270 }
271
272
273
274 ts_bool init_triangle_neighbours(ts_vesicle *vesicle){
275     ts_uint i,j,nobo;
276     ts_vertex *i1,*i2,*i3,*j1,*j2,*j3;
277 //    ts_vertex **vtx=vesicle->vlist->vtx -1; // difference between 0 indexing and 1 indexing
278     ts_triangle_list *tlist=vesicle->tlist;
279     ts_triangle **tria=tlist->tria -1;
280     nobo=0;
281     for(i=1;i<=tlist->n;i++){
41a035 282         i1=tria[i]->vertex[0]; 
SP 283         i2=tria[i]->vertex[1]; 
284         i3=tria[i]->vertex[2]; 
7958e9 285         for(j=1;j<=tlist->n;j++){
SP 286             if(j==i) continue;
41a035 287             j1=tria[j]->vertex[0]; 
SP 288             j2=tria[j]->vertex[1]; 
289             j3=tria[j]->vertex[2]; 
7958e9 290             if((i1==j1 && i3==j2) || (i1==j2 && i3==j3) || (i1==j3 && i3==j1)){
SP 291                     triangle_add_neighbour(tria[i],tria[j]);
292                     nobo++;
293             }
294         }
295     }
296     for(i=1;i<=tlist->n;i++){
41a035 297         i1=tria[i]->vertex[0]; 
SP 298         i2=tria[i]->vertex[1]; 
299         i3=tria[i]->vertex[2]; 
7958e9 300         for(j=1;j<=tlist->n;j++){
SP 301             if(j==i) continue;
41a035 302             j1=tria[j]->vertex[0]; 
SP 303             j2=tria[j]->vertex[1]; 
304             j3=tria[j]->vertex[2]; 
7958e9 305             if((i1==j1 && i2==j3) || (i1==j3 && i2==j2) || (i1==j2 && i2==j1)){
SP 306                 triangle_add_neighbour(tria[i],tria[j]);
307                 nobo++;
308             }
309         }
310     }
311     for(i=1;i<=tlist->n;i++){
41a035 312         i1=tria[i]->vertex[0]; 
SP 313         i2=tria[i]->vertex[1]; 
314         i3=tria[i]->vertex[2]; 
7958e9 315         for(j=1;j<=tlist->n;j++){
SP 316             if(j==i) continue;
41a035 317             j1=tria[j]->vertex[0]; 
SP 318             j2=tria[j]->vertex[1]; 
319             j3=tria[j]->vertex[2]; 
7958e9 320             if((i2==j1 && i3==j3) || (i2==j3 && i3==j2) || (i2==j2 && i3==j1)){
SP 321                 triangle_add_neighbour(tria[i],tria[j]);
322                 nobo++;
323             }
324         }
325     }
326     if(nobo != vesicle->blist->n*2) {
327             ts_fprintf(stderr,"Number of triangles= %u, number of bonds= %u\n",nobo/2, vesicle->blist->n);
328             fatal("Number of triangle neighbour pairs differs from double the number of bonds!",4);
329     }
330     return TS_SUCCESS;
331 }
332
333
334 ts_bool init_common_vertex_triangle_neighbours(ts_vesicle *vesicle){
335     ts_uint i,j,jp,k;
336     ts_vertex *k1,*k2,*k3,*k4,*k5;
337     ts_vertex **vtx=vesicle->vlist->vtx -1; // difference between 0 indexing and 1 indexing
338     ts_triangle_list *tlist=vesicle->tlist;
339     ts_triangle **tria=tlist->tria -1;
340
341     for(i=1;i<=vesicle->vlist->n;i++){
8f6a69 342         for(j=1;j<=vtx[i]->neigh_no;j++){
SP 343             k1=vtx[i]->neigh[j-1];
7958e9 344             jp=j+1;
8f6a69 345             if(j == vtx[i]->neigh_no) jp=1;
SP 346             k2=vtx[i]->neigh[jp-1];
7958e9 347             for(k=1;k<=tlist->n;k++){        // VERY NON-OPTIMAL!!! too many loops (vlist.n * vtx.neigh * tlist.n )!
41a035 348                 k3=tria[k]->vertex[0];
SP 349                 k4=tria[k]->vertex[1];
350                 k5=tria[k]->vertex[2];
7958e9 351 //                ts_fprintf(stderr,"%u %u: k=(%u %u %u)\n",k1,k2,k3,k4,k5);
SP 352                 if((vtx[i]==k3 && k1==k4 && k2==k5) ||
353                 (vtx[i]==k4 && k1==k5 && k2==k3) ||
354                 (vtx[i]==k5 && k1==k3 && k2==k4)){
b01cc1 355
SP 356 //TODO: probably something wrong with neighbour distribution.
357 //                if(vtx[i]==k3 || vtx[i]==k4 || vtx[i]==k5){
dac2e5 358     //                    if(i==6) ts_fprintf(stdout, "Vtx[%u] > Added to tristar!\n",i);
7958e9 359                     vertex_add_tristar(vtx[i],tria[k]);
SP 360                 }
361             }
362         }
363 /*        ts_fprintf(stderr,"TRISTAR for %u (%u):",i-1,vtx[i].tristar_no);
364         for(j=0;j<vtx[i].tristar_no;j++){
365             ts_fprintf(stderr," %u,",vtx[i].tristar[j]->idx);
366         }
367         ts_fprintf(stderr,"\n"); */
368     }
369     return TS_SUCCESS;
370 }
371
372
373 ts_bool init_normal_vectors(ts_triangle_list *tlist){
374     /* Normals point INSIDE vesicle */
375     ts_uint k;
376     ts_triangle **tria=tlist->tria -1; //for 0 indexing
377     for(k=1;k<=tlist->n;k++){
378         triangle_normal_vector(tria[k]);    
379     }
380     return TS_SUCCESS;
381 }