Trisurf Monte Carlo simulator
mihaf
2014-03-10 152052a93b7e7b5151c42992c79d8e3667471a3e
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){
2870ab 153         fprintf(stderr,"Ooops: tria->neigh_no=%d\n",tria->neigh_no);
a2a676 154         fatal("Reallocation of memory failed during removal of vertex neighbour in triangle_remove_neighbour",100);
SP 155     }
156 /* we repeat the procedure for neighbour */
e19e79 157     j=0;
41a035 158     for(i=0;i<ntria->neigh_no;i++){
SP 159         if(ntria->neigh[i]!=tria){
160             ntria->neigh[j]=ntria->neigh[i];
a2a676 161             j++;
SP 162         } 
163     }
164     if(j==i) {
165         return TS_FAIL; 
166         //fatal("In triangle_remove_neighbour: Specified neighbour does not exist for given triangle",3);
167     }
41a035 168     ntria->neigh_no--;
e19e79 169 //    fprintf(stderr,"*** ntria_number=%d\n",ntria->neigh_no);
41a035 170     ntria->neigh=(ts_triangle **)realloc(ntria->neigh,ntria->neigh_no*sizeof(ts_triangle *));
SP 171     if(ntria->neigh == NULL){
2870ab 172         fprintf(stderr,"Ooops: ntria->neigh_no=%d\n",ntria->neigh_no);
a2a676 173         fatal("Reallocation of memory failed during removal of vertex neighbour in triangle_remove_neighbour",100);
SP 174     }
d7639a 175     return TS_SUCCESS;
SP 176 }
177
bb77ca 178
SP 179 /** @brief Calculates normal vector of the triangle.
180
181   *
182   * Calculate normal vector of the triangle (xnorm, ynorm and znorm) and stores
183   * information in underlying ts_triangle_data data_structure.
184   *
185   * Function receives one argument of type ts_triangle. It should be corectly
186   * initialized with underlying data structure of type ts_triangle_data. the
187   * result is stored in triangle->data->xnorm, triangle->data->ynorm,
188   * triangle->data->znorm. Returns TS_SUCCESS on completion. 
189   *
190   * NOTE: Function uses math.h library. pow function implementation is selected
191   * accordind to the setting in genreal.h
192   *
193   * Example of usage:
194   *        triangle_normal_vector(tlist->tria[3]);
195   *
196   *        Computes normals and stores information into tlist->tria[3]->xnorm,
197   *        tlist->tria[3]->ynorm, tlist->tria[3]->znorm.
198   *        
199   */
d7639a 200 ts_bool triangle_normal_vector(ts_triangle *tria){
SP 201     ts_double x21,x31,y21,y31,z21,z31,xden;
8f6a69 202     x21=tria->vertex[1]->x - tria->vertex[0]->x;
SP 203     x31=tria->vertex[2]->x - tria->vertex[0]->x;
204     y21=tria->vertex[1]->y - tria->vertex[0]->y;
205     y31=tria->vertex[2]->y - tria->vertex[0]->y;
206     z21=tria->vertex[1]->z - tria->vertex[0]->z;
207     z31=tria->vertex[2]->z - tria->vertex[0]->z;
d7639a 208
41a035 209     tria->xnorm=y21*z31 - z21*y31;
SP 210     tria->ynorm=z21*x31 - x21*z31;
211     tria->znorm=x21*y31 - y21*x31;
212     xden=tria->xnorm*tria->xnorm +
213          tria->ynorm*tria->ynorm + 
214          tria->znorm*tria->znorm;
d7639a 215 #ifdef TS_DOUBLE_DOUBLE
SP 216     xden=sqrt(xden);
217 #endif
218 #ifdef TS_DOUBLE_FLOAT
219     xden=sqrtf(xden);
220 #endif
221 #ifdef TS_DOUBLE_LONGDOUBLE
222     xden=sqrtl(xden);
223 #endif
41a035 224     tria->xnorm=tria->xnorm/xden;
SP 225     tria->ynorm=tria->ynorm/xden;
226     tria->znorm=tria->znorm/xden;    
c9d07c 227
SP 228 /*  Here it is an excellent point to recalculate volume of the triangle and
229  *  store it into datastructure. Volume is required at least by constant volume
230  *  calculation of vertex move and bondflip and spherical harmonics. */
231     tria->volume=(tria->vertex[0]->x+ tria->vertex[1]->x + tria->vertex[2]->x) * tria->xnorm + 
232        (tria->vertex[0]->y+ tria->vertex[1]->y + tria->vertex[2]->y) * tria->ynorm + 
233     (tria->vertex[0]->z+ tria->vertex[1]->z + tria->vertex[2]->z) * tria->znorm;
234     tria->volume=-xden*tria->volume/18.0;
235 /*  Also, area can be calculated in each triangle */
236     tria->area=xden/2;
237
238
d7639a 239     return TS_SUCCESS;
SP 240 }
241
242
bb77ca 243
SP 244
245
d7639a 246
bb77ca 247 /** @brief Frees the memory allocated for data structure of triangle list
SP 248  * (ts_triangle_list)
249   *
250   * Function frees the memory of ts_triangle_list previously allocated. It
251   * accepts one argument, the address of data structure. It destroys all
252   * ts_triangle's in the list with underlying data (by calling
253   * triangle_data_free()), and the list itself.
254   *
255   * Should be used eveytime the deletion of triangle list (created by
256   * init_triangle_list() and altered by add_triangle() or remove_triangle()) is desired.
257   *
258   * WARNING: The function doesn't check whether the pointer is NULL or invalid. It is the
259   * job of programmer to make sure the pointer is valid.
260   *
261   * WARNING: Careful when destroying triangle lists. There could be pointers to
262   * that information remaining in structures like vertex_data. This pointers
263   * will be rendered invalid by this operation and should not be used anymore.
264   *
265   * Example of usage:
266   *        triangle_list_free(tlist);
267   *
268   *        Clears all the information on triangles.
269   *        
270   */
d7639a 271 ts_bool triangle_list_free(ts_triangle_list *tlist){
a2a676 272     ts_uint i;
d7639a 273     for(i=0;i<tlist->n;i++){
41a035 274         if(tlist->tria[i]->neigh!=NULL) free(tlist->tria[i]->neigh);
a2a676 275         free(tlist->tria[i]);
d7639a 276     }
a2a676 277     free(tlist->tria);
SP 278     free(tlist);  
d7639a 279     return TS_SUCCESS;
SP 280 }
281