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