Trisurf Monte Carlo simulator
Samo Penic
2016-07-11 80f2a33e4b55c7259bdb4bff66a0ce12b96edd80
commit | author | age
7f6076 1 /* vim: set ts=4 sts=4 sw=4 noet : */
d7639a 2 #include<stdlib.h>
SP 3 #include<stdio.h>
4 #include "general.h"
5 #include "triangle.h"
6 #include<math.h>
7
bb77ca 8 /** @brief Prepares the list for triangles.
632960 9   * @returns pointer to empty data structure for maintaining triangle list.
bb77ca 10   *
SP 11   * Create empty list for holding the information on triangles. Triangles are
12   * added later on with triangle_add().
13   * Returns pointer to the tlist datastructure it has created. This pointer must
14   * be assigned to some variable or it will be lost.
15   *
16   *
17   * Example of usage:
18   *     ts_triangle_list *tlist;
19   *        tlist=triangle_data_free();
20   *
21   *        Initalized data structure for holding the information on triangles.
22   *        
23   */
a2a676 24 ts_triangle_list *init_triangle_list(){
SP 25     ts_triangle_list *tlist=(ts_triangle_list *)malloc(sizeof(ts_triangle_list));
d7639a 26     tlist->n = 0;
a2a676 27     tlist->tria=NULL;
SP 28     return tlist;
d7639a 29 }
SP 30
bb77ca 31 /** @brief Add the triangle to the triangle list and create necessary data
632960 32   * structures.
SP 33   * @param *tlist is a pointer to triangle list where triangle should be created
34   * @param *vtx1, *vtx2, *vtx3 are the three vertices defining the triangle
35   * @returns pointer to the newly created triangle on success and NULL if
36   * triangle could not be created. It breaks program execution if memory
37   * allocation of triangle list can't be done.
bb77ca 38   *
632960 39   * Add the triangle ts_triangle to the ts_triangle_list.
bb77ca 40   * The triangle list is resized, the ts_triangle is allocated and
632960 41   * triangle data is zeroed. Returned pointer to newly
SP 42   * created triangle doesn't need assigning, since it is
bb77ca 43   * referenced by triangle list.
SP 44   *
45   * WARNING: Function can be accelerated a bit by removing the NULL checks.
46   * However the time gained by removal doesn't justify the time spent by
47   * debugging stupid NULL pointers.
48   *
49   * Example of usage:
50   *        triangle_add(tlist, vlist->vtx[1], vlist->vtx[2], vlist->vtx[3]);
51   *
52   *        Creates a triangle with given vertices and puts it into the list.
53   *        
54   */
a2a676 55 ts_triangle *triangle_add(ts_triangle_list *tlist, ts_vertex *vtx1, ts_vertex *vtx2, ts_vertex *vtx3){
SP 56         if(vtx1==NULL || vtx2==NULL || vtx3==NULL){
57             return NULL;
58         }
d7639a 59         tlist->n++;
a2a676 60         tlist->tria=(ts_triangle **)realloc(tlist->tria,tlist->n*sizeof(ts_triangle *));
SP 61         if(tlist->tria==NULL) fatal("Cannot reallocate memory for additional ts_triangle.",5);
62
63         tlist->tria[tlist->n-1]=(ts_triangle *)calloc(1,sizeof(ts_triangle));
64         if(tlist->tria[tlist->n-1]==NULL) fatal("Cannot reallocate memory for additional ts_triangle.",5);
65
d7639a 66         //NOW insert vertices!
a2a676 67         tlist->tria[tlist->n - 1]->idx=tlist->n-1;
41a035 68         tlist->tria[tlist->n - 1]->vertex[0]=vtx1;
SP 69         tlist->tria[tlist->n - 1]->vertex[1]=vtx2;
70         tlist->tria[tlist->n - 1]->vertex[2]=vtx3;
a2a676 71         return tlist->tria[tlist->n-1];
d7639a 72 }
SP 73
bb77ca 74 /** @brief Add the neigbour to triangles.
632960 75   * @param *tria is a first triangle.
SP 76   * @param *ntria is a second triangle.
77   * @returns TS_SUCCES on sucessful adition to the list, TS_FAIL if triangles
78   * are NULL and breaks execution FATALY if memory allocation error occurs.
bb77ca 79   *
SP 80   * Add the neigbour to the list of neighbouring triangles. The
632960 81   * neighbouring triangles are those, who share two vertices and corresponding
SP 82   * bond. Function resizes
bb77ca 83   * the list and adds the pointer to neighbour. It receives two arguments of
dac2e5 84   * ts_triangle type. It then adds second triangle to the list of first
SP 85   * triangle, but not the opposite. Upon
bb77ca 86   * success it returns TS_SUCCESS, upon detecting NULL pointers 
SP 87   * returns TS_FAIL and it FATALY ends when the data structure
88   * cannot be resized.
89   *
90   *
91   * WARNING: Function can be accelerated a bit by removing the NULL checks.
92   * However the time gained by removal doesn't justify the time spent by
93   * debugging stupid NULL pointers.
94   *
95   * Example of usage:
632960 96   *        triangle_add_neighbour(tlist->tria[3], tlist->tria[4]);
bb77ca 97   *
632960 98   *        Triangle 4 is a neighbour of triangle 3, but (strangely) not the
SP 99   *        oposite. The function should be called again with the changed order of
100   *        triangles to make neighbourship mutual.
bb77ca 101   *        
SP 102   */
d7639a 103
SP 104 ts_bool triangle_add_neighbour(ts_triangle *tria, ts_triangle *ntria){
a2a676 105     if(tria==NULL || ntria==NULL) return TS_FAIL;
41a035 106     tria->neigh_no++;
SP 107     tria->neigh=realloc(tria->neigh,tria->neigh_no*sizeof(ts_triangle *));
108     if(tria->neigh == NULL)
d7639a 109             fatal("Reallocation of memory failed during insertion of triangle neighbour in triangle_add_neighbour",3);
632960 110     tria->neigh[tria->neigh_no-1]=ntria; 
d7639a 111     return TS_SUCCESS;
SP 112 }
113
bb77ca 114 /** @brief Remove the neigbours from triangle.
632960 115   * @param *tria is a first triangle.
SP 116   * @param *ntria is neighbouring triangle.
117   * @returns TS_SUCCESS on successful removal, TS_FAIL if triangles are not
118   * neighbours and it breaks program execution FATALY if memory allocation
119   * problem occurs.
bb77ca 120   *
SP 121   * Removes the neigbour from the list of neighbouring triangles. The
632960 122   * neighbouring triangles are those, who share two vertices and corresponding
SP 123   * bond. Function resizes
bb77ca 124   * the list and deletes the pointer to neighbour. It receives two arguments of
632960 125   * ts_triangle type. It then mutually removes triangles from eachouther
SP 126   * neighbour list. Upon
bb77ca 127   * success it returns TS_SUCCESS, upon failure to find the triangle in the
632960 128   * neighbour list returns TS_FAIL. It FATALY breaks program execution when the datastructure
SP 129   * cannot be resized due to memory constrain problems.
bb77ca 130   *
SP 131   * WARNING: The function doesn't check whether the pointer is NULL or invalid. It is the
132   * job of programmer to make sure the pointer is valid.
133   *
134   * WARNING: Function is slow. Do not use it often!
135   *
136   * Example of usage:
137   *        triangle_remove_neighbour(tlist->tria[3], tlist->tria[4]);
138   *
139   *        Triangles 3 and 4 are not neighbours anymore.
140   *        
141   */
d7639a 142 ts_bool triangle_remove_neighbour(ts_triangle *tria, ts_triangle *ntria){
a2a676 143     ts_uint i,j=0; 
SP 144     if(tria==NULL || ntria==NULL) return TS_FAIL;
145
41a035 146     for(i=0;i<tria->neigh_no;i++){
SP 147         if(tria->neigh[i]!=ntria){
148             tria->neigh[j]=tria->neigh[i];
d7639a 149             j++;
SP 150         } 
151     }
a2a676 152     if(j==i) {
SP 153         return TS_FAIL; 
154     }
41a035 155     tria->neigh_no--;
SP 156     tria->neigh=(ts_triangle **)realloc(tria->neigh,tria->neigh_no*sizeof(ts_triangle *));
157     if(tria->neigh == NULL){
2870ab 158         fprintf(stderr,"Ooops: tria->neigh_no=%d\n",tria->neigh_no);
a2a676 159         fatal("Reallocation of memory failed during removal of vertex neighbour in triangle_remove_neighbour",100);
SP 160     }
161 /* we repeat the procedure for neighbour */
e19e79 162     j=0;
41a035 163     for(i=0;i<ntria->neigh_no;i++){
SP 164         if(ntria->neigh[i]!=tria){
165             ntria->neigh[j]=ntria->neigh[i];
a2a676 166             j++;
SP 167         } 
168     }
169     if(j==i) {
170         return TS_FAIL; 
171     }
41a035 172     ntria->neigh_no--;
SP 173     ntria->neigh=(ts_triangle **)realloc(ntria->neigh,ntria->neigh_no*sizeof(ts_triangle *));
174     if(ntria->neigh == NULL){
2870ab 175         fprintf(stderr,"Ooops: ntria->neigh_no=%d\n",ntria->neigh_no);
a2a676 176         fatal("Reallocation of memory failed during removal of vertex neighbour in triangle_remove_neighbour",100);
SP 177     }
d7639a 178     return TS_SUCCESS;
SP 179 }
180
bb77ca 181
632960 182 /** @brief Calculates normal vector of the triangle, its corresponding area and volume.
SP 183   * @param *tria is a triangle pointer for which normal, area and volume is
184   * to be calculated.
185   * @returns TS_SUCCESS on success. (always)
bb77ca 186   *
SP 187   * Calculate normal vector of the triangle (xnorm, ynorm and znorm) and stores
632960 188   * information. At the same time
SP 189   * triangle area is determined, since we already have the normal and volume of
190   * triangular pyramid with given triangle as a base and vesicle centroid as a
191   * tip. 
bb77ca 192   *
SP 193   * Function receives one argument of type ts_triangle. It should be corectly
632960 194   * initialized. The
SP 195   * result is stored in triangle->xnorm, triangle->ynorm, triangle->znorm.
196   * Area and volume are stored into triangle->area and triangle->volume.
197   * Returns TS_SUCCESS on completion. 
bb77ca 198   *
632960 199   * NOTE: Function uses math.h library. Function pow implementation is selected
SP 200   * accordind to the used TS_DOUBLE_* definition set in general.h, so it should
201   * be compatible with any type of floating point precision.
bb77ca 202   *
SP 203   * Example of usage:
204   *        triangle_normal_vector(tlist->tria[3]);
205   *
206   *        Computes normals and stores information into tlist->tria[3]->xnorm,
632960 207   *        tlist->tria[3]->ynorm, tlist->tria[3]->znorm tlist->tria[3]->area and
SP 208   *        tlist->tria[3]->volume.
bb77ca 209   *        
SP 210   */
d7639a 211 ts_bool triangle_normal_vector(ts_triangle *tria){
SP 212     ts_double x21,x31,y21,y31,z21,z31,xden;
8f6a69 213     x21=tria->vertex[1]->x - tria->vertex[0]->x;
SP 214     x31=tria->vertex[2]->x - tria->vertex[0]->x;
215     y21=tria->vertex[1]->y - tria->vertex[0]->y;
216     y31=tria->vertex[2]->y - tria->vertex[0]->y;
217     z21=tria->vertex[1]->z - tria->vertex[0]->z;
218     z31=tria->vertex[2]->z - tria->vertex[0]->z;
d7639a 219
41a035 220     tria->xnorm=y21*z31 - z21*y31;
SP 221     tria->ynorm=z21*x31 - x21*z31;
222     tria->znorm=x21*y31 - y21*x31;
223     xden=tria->xnorm*tria->xnorm +
224          tria->ynorm*tria->ynorm + 
225          tria->znorm*tria->znorm;
d7639a 226 #ifdef TS_DOUBLE_DOUBLE
SP 227     xden=sqrt(xden);
228 #endif
229 #ifdef TS_DOUBLE_FLOAT
230     xden=sqrtf(xden);
231 #endif
232 #ifdef TS_DOUBLE_LONGDOUBLE
233     xden=sqrtl(xden);
234 #endif
41a035 235     tria->xnorm=tria->xnorm/xden;
SP 236     tria->ynorm=tria->ynorm/xden;
237     tria->znorm=tria->znorm/xden;    
c9d07c 238
SP 239 /*  Here it is an excellent point to recalculate volume of the triangle and
240  *  store it into datastructure. Volume is required at least by constant volume
241  *  calculation of vertex move and bondflip and spherical harmonics. */
242     tria->volume=(tria->vertex[0]->x+ tria->vertex[1]->x + tria->vertex[2]->x) * tria->xnorm + 
243        (tria->vertex[0]->y+ tria->vertex[1]->y + tria->vertex[2]->y) * tria->ynorm + 
244     (tria->vertex[0]->z+ tria->vertex[1]->z + tria->vertex[2]->z) * tria->znorm;
245     tria->volume=-xden*tria->volume/18.0;
246 /*  Also, area can be calculated in each triangle */
247     tria->area=xden/2;
248
249
d7639a 250     return TS_SUCCESS;
SP 251 }
252
bb77ca 253 /** @brief Frees the memory allocated for data structure of triangle list
632960 254   * @param *tlist is a pointer to datastructure triangle list to be freed.
SP 255   * @returns TS_SUCCESS on success (always).
bb77ca 256   *
SP 257   * Function frees the memory of ts_triangle_list previously allocated. It
258   * accepts one argument, the address of data structure. It destroys all
259   * ts_triangle's in the list with underlying data (by calling
260   * triangle_data_free()), and the list itself.
261   *
262   * Should be used eveytime the deletion of triangle list (created by
263   * init_triangle_list() and altered by add_triangle() or remove_triangle()) is desired.
264   *
265   * WARNING: The function doesn't check whether the pointer is NULL or invalid. It is the
266   * job of programmer to make sure the pointer is valid.
267   *
268   * WARNING: Careful when destroying triangle lists. There could be pointers to
269   * that information remaining in structures like vertex_data. This pointers
270   * will be rendered invalid by this operation and should not be used anymore.
271   *
272   * Example of usage:
273   *        triangle_list_free(tlist);
274   *
275   *        Clears all the information on triangles.
276   *        
277   */
d7639a 278 ts_bool triangle_list_free(ts_triangle_list *tlist){
a2a676 279     ts_uint i;
d7639a 280     for(i=0;i<tlist->n;i++){
41a035 281         if(tlist->tria[i]->neigh!=NULL) free(tlist->tria[i]->neigh);
a2a676 282         free(tlist->tria[i]);
d7639a 283     }
a2a676 284     free(tlist->tria);
SP 285     free(tlist);  
d7639a 286     return TS_SUCCESS;
SP 287 }
288