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