Changeset 8568
- Timestamp:
- Sep 9, 2012, 9:02:28 PM (13 years ago)
- Location:
- trunk/anuga_core/source/anuga/abstract_2d_finite_volumes
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/anuga_core/source/anuga/abstract_2d_finite_volumes/pmesh2domain.py
r8567 r8568 160 160 161 161 162 def pmesh_dict_to_tag_dict (mesh_dict):162 def pmesh_dict_to_tag_dict_old(mesh_dict): 163 163 """ Convert the pmesh dictionary (mesh_dict) description of boundary tags 164 164 to a dictionary of tags, indexed with volume id and face number. … … 166 166 167 167 triangles = mesh_dict['triangles'] 168 sides = calc_sides(triangles) 168 169 triangles = num.array(triangles,num.int) 170 171 sides = {} 172 for id, triangle in enumerate(triangles): 173 a = triangle[0] 174 b = triangle[1] 175 c = triangle[2] 176 177 sides[a,b] = 3*id+2 #(id, face) 178 sides[b,c] = 3*id+0 #(id, face) 179 sides[c,a] = 3*id+1 #(id, face) 180 169 181 tag_dict = {} 170 182 for seg, tag in map(None, mesh_dict['segments'], mesh_dict['segment_tags']): … … 182 194 return tag_dict 183 195 196 def pmesh_dict_to_tag_dict(mesh_dict): 197 """ Convert the pmesh dictionary (mesh_dict) description of boundary tags 198 to a dictionary of tags, indexed with volume id and face number. 199 """ 200 201 triangles = mesh_dict['triangles'] 202 segments = mesh_dict['segments'] 203 segment_tags = mesh_dict['segment_tags'] 204 205 triangles = num.array(triangles,num.int) 206 segments = num.array(segments,num.int) 207 tag_dict = {} 208 209 #print triangles 210 #print segments 211 #print segment_tags 212 213 from pmesh2domain_ext import build_boundary_dictionary 214 215 tag_dict = build_boundary_dictionary(triangles, segments, segment_tags, tag_dict) 216 217 return tag_dict 218 184 219 185 220 def calc_sides_old(triangles): … … 201 236 return sides 202 237 203 def calc_sides_old2(triangles): 204 '''Build dictionary mapping from sides (2-tuple of points) 205 to left hand side neighbouring triangle 206 ''' 207 208 sides = {} 209 210 for id, triangle in enumerate(triangles): 211 a = int(triangle[0]) 212 b = int(triangle[1]) 213 c = int(triangle[2]) 214 215 sides[a,b] = (id, 2) #(id, face) 216 sides[b,c] = (id, 0) #(id, face) 217 sides[c,a] = (id, 1) #(id, face) 218 219 return sides 238 220 239 221 240 def calc_sides_zip(triangles): … … 242 261 return sides 243 262 244 def calc_sides (triangles):263 def calc_sides_c(triangles): 245 264 '''Build dictionary mapping from sides (2-tuple of points) 246 265 to left hand side neighbouring triangle -
trunk/anuga_core/source/anuga/abstract_2d_finite_volumes/pmesh2domain_ext.c
r8567 r8568 1 #include <stdio.h> /* gets */ 2 #include <stdlib.h> /* atoi, malloc */ 3 #include <string.h> /* strcpy */ 4 5 6 1 7 #include "Python.h" 2 8 #include "numpy/arrayobject.h" 3 #include <stdio.h> 4 #include "util_ext.h" 9 #include "math.h" 10 11 //Shared code snippets 12 13 #include "util_ext.h" /* in utilities */ 14 #include "uthash.h" /* in utilities */ 15 16 5 17 6 18 #define DDATA(p) ((double*)(((PyArrayObject *)p)->data)) 7 19 #define IDATA(p) ((long*)(((PyArrayObject *)p)->data)) 20 #define CDATA(p) ((char*)(((PyArrayObject *)p)->data)) 8 21 #define LENDATA(p) ((long)(((PyArrayObject *)p)->dimensions[0])) 9 22 10 11 12 static PyObject *SidesDictionaryConstruct( PyObject *self, PyObject *args ) 13 { 14 int i, ok, numTriangle; 15 long a,b,c; 16 long *triangles; 17 PyObject *pyobj_key; 18 PyObject *pyobj_sides; 19 PyArrayObject *pyobj_triangles; 20 21 22 ok = PyArg_ParseTuple( args, "OO", &pyobj_triangles, &pyobj_sides ); 23 if( !ok ){ 24 report_python_error(AT, "could not parse input arguments"); 25 return NULL; 26 } 27 28 29 numTriangle = LENDATA( pyobj_triangles ); 30 triangles = IDATA( pyobj_triangles ); 31 32 /* 33 for id, triangle in enumerate(triangles): 34 a = int(triangle[0]) 35 b = int(triangle[1]) 36 c = int(triangle[2]) 37 38 sides[a,b] = 3*id+2 #(id, face) 39 sides[b,c] = 3*id+0 #(id, face) 40 sides[c,a] = 3*id+1 #(id, face) 41 */ 42 43 //printf("numTriangle %d\n",numTriangle); 44 45 for(i=0; i<numTriangle; i++){ 46 a = triangles[i*3+0]; 47 b = triangles[i*3+1]; 48 c = triangles[i*3+2]; 49 50 // sides[a,b] = (id, 2) #(id, face) 51 pyobj_key = PyTuple_New( 2 ); 52 PyTuple_SetItem( pyobj_key, 0, PyInt_FromLong( a ) ); 53 PyTuple_SetItem( pyobj_key, 1, PyInt_FromLong( b ) ); 54 55 PyDict_SetItem( pyobj_sides, pyobj_key, PyInt_FromLong( 3*i+2 ) ); 56 57 Py_DECREF(pyobj_key); 58 59 // sides[b,c] = (id, 0) #(id, face) 60 pyobj_key = PyTuple_New( 2 ); 61 PyTuple_SetItem( pyobj_key, 0, PyInt_FromLong( b ) ); 62 PyTuple_SetItem( pyobj_key, 1, PyInt_FromLong( c ) ); 63 64 PyDict_SetItem( pyobj_sides, pyobj_key, PyInt_FromLong( 3*i+0 ) ); 65 66 Py_DECREF(pyobj_key); 67 68 69 // sides[c,a] = (id, 1) #(id, face) 70 pyobj_key = PyTuple_New( 2 ); 71 PyTuple_SetItem( pyobj_key, 0, PyInt_FromLong( c ) ); 72 PyTuple_SetItem( pyobj_key, 1, PyInt_FromLong( a ) ); 73 74 PyDict_SetItem( pyobj_sides, pyobj_key, PyInt_FromLong( 3*i+1 ) ); 75 76 Py_DECREF(pyobj_key); 77 78 79 } 80 81 return Py_BuildValue("O", pyobj_sides); 82 } 23 //============================================================================== 24 // hashtable code from uthash. Look at copyright info in "uthash.h in the 25 // utilities directory 26 //============================================================================== 27 28 typedef struct { 29 int i; 30 int j; 31 } segment_key_t; 32 33 typedef struct { 34 segment_key_t key; /* key of form i , j */ 35 int vol_id; /* id of vol containing this segement */ 36 int edge_id; /* edge_id of segement in this vol */ 37 UT_hash_handle hh; /* makes this structure hashable */ 38 } segment_t; 39 40 segment_t *segment_table = NULL; 41 42 void add_segment(segment_key_t key, int vol_id, int edge_id) { 43 segment_t *s; 44 45 s = (segment_t*) malloc(sizeof (segment_t)); 46 memset(s, 0, sizeof (segment_t)); 47 s->key.i = key.i; 48 s->key.j = key.j; 49 s->vol_id = vol_id; 50 s->edge_id = edge_id; 51 HASH_ADD(hh, segment_table, key, sizeof (segment_key_t), s); /* key: name of key field */ 52 } 53 54 segment_t *find_segment(segment_key_t key) { 55 segment_t *s=0; 56 57 HASH_FIND(hh, segment_table, &key, sizeof (segment_key_t), s); /* s: output pointer */ 58 return s; 59 } 60 61 void delete_segment(segment_t *segment) { 62 HASH_DEL(segment_table, segment); /* user: pointer to deletee */ 63 free(segment); 64 } 65 66 void delete_all() { 67 segment_t *current_segment, *tmp; 68 69 HASH_ITER(hh, segment_table, current_segment, tmp) { 70 HASH_DEL(segment_table, current_segment); /* delete it (segment_table advances to next) */ 71 free(current_segment); /* free it */ 72 } 73 } 74 75 void print_segments() { 76 segment_t *s; 77 78 for (s = segment_table; s != NULL; s = (segment_t*) (s->hh.next)) { 79 printf("segment key i %d j %d vol_id %d edge_id %d\n", 80 s->key.i, s->key.j, s->vol_id, s->edge_id); 81 } 82 } 83 84 int vol_id_sort(segment_t *a, segment_t *b) { 85 return (a->vol_id - b->vol_id); 86 } 87 88 int key_sort(segment_t *a, segment_t *b) { 89 return (a->key.i - b->key.i); 90 } 91 92 void sort_by_vol_id() { 93 HASH_SORT(segment_table, vol_id_sort); 94 } 95 96 void sort_by_key() { 97 HASH_SORT(segment_table, key_sort); 98 } 99 100 101 //============================================================================== 102 // Python method Wrapper 103 //============================================================================== 104 105 PyObject *build_boundary_dictionary(PyObject *self, PyObject *args) { 106 107 /* 108 * Update neighbours array using triangles array 109 * 110 * N is number of nodes (vertices) 111 * triangle nodes defining triangles 112 * neighbour across edge_id 113 * neighbour_segments edge_id of segment in neighbouring triangle 114 * number_of_boundaries 115 */ 116 117 PyArrayObject *pyobj_segments; 118 PyArrayObject *pyobj_triangles; 119 120 PyObject *pyobj_segment_tags; // List of strings 121 PyObject *pyobj_tag_dict; 122 PyObject *pyobj_key; 123 PyObject *pyobj_tag; 124 125 long *triangles; 126 long *segments; 127 128 int M; // Number of triangles (calculated from triangle array) 129 int N; // Number of segments (calculated from segments array) 130 int err = 0; 131 132 int k; 133 int k3; 134 int k2; 135 int a,b,c; 136 int vol_id; 137 int edge_id; 138 int len_tag; 139 char *string; 140 segment_t *s; 141 segment_key_t key; 142 143 // Convert Python arguments to C 144 if (!PyArg_ParseTuple(args, "OOOO", 145 &pyobj_triangles, 146 &pyobj_segments, 147 &pyobj_segment_tags, 148 &pyobj_tag_dict 149 )) { 150 PyErr_SetString(PyExc_RuntimeError, 151 "pmesh2domain.c: build_boundary_dictionary could not parse input"); 152 return NULL; 153 } 154 155 M = LENDATA(pyobj_triangles); 156 N = LENDATA(pyobj_segments); 157 158 triangles = IDATA(pyobj_triangles); 159 segments = IDATA(pyobj_segments); 160 161 //-------------------------------------------------------------------------- 162 // Step 1: 163 // Populate hashtable. We use a key based on the node_ids of the 164 // two nodes defining the segment 165 //-------------------------------------------------------------------------- 166 for (k = 0; k < M; k++) { 167 168 // Run through triangles 169 k3 = 3 * k; 170 171 a = triangles[k3 + 0]; 172 b = triangles[k3 + 1]; 173 c = triangles[k3 + 2]; 174 175 176 177 // Add segments to hashtable 178 179 //---------------------------------------------------------------------- 180 // Segment a,b 181 //---------------------------------------------------------------------- 182 key.i = a; 183 key.j = b; 184 vol_id = k; 185 edge_id = 2; 186 187 // Error if duplicates 188 s = find_segment(key); 189 190 //printf("k = %d segment %d %d \n",k,a,b); 191 if (s) { 192 err = 1; 193 break; 194 } 195 // Otherwise add segment 196 add_segment(key, vol_id, edge_id); 197 198 //---------------------------------------------------------------------- 199 // segment b,c 200 //---------------------------------------------------------------------- 201 key.i = b; 202 key.j = c; 203 vol_id = k; 204 edge_id = 0; 205 206 // Error if duplicates 207 s = find_segment(key); 208 //printf("k = %d segment %d %d \n",k,b,c); 209 if (s) { 210 err = 1; 211 break; 212 } 213 // Otherwise add segment 214 add_segment(key, vol_id, edge_id); 215 216 //---------------------------------------------------------------------- 217 // segment c,a 218 //---------------------------------------------------------------------- 219 key.i = c; 220 key.j = a; 221 vol_id = k; 222 edge_id = 1; 223 224 // Error if duplicates 225 s = find_segment(key); 226 227 //printf("k = %d segment %d %d \n",k,c,a); 228 if (s) { 229 err = 1; 230 break; 231 } 232 // Otherwise add segment 233 add_segment(key, vol_id, edge_id); 234 235 } 236 237 //printf("err %d \n",err); 238 //-------------------------------------------------------------------------- 239 // return with an error code if duplicate key found 240 // Clean up hashtable 241 //-------------------------------------------------------------------------- 242 if (err) { 243 //printf("Duplicate Keys:\n"); 244 //printf("key.i %d key.j %d vol_id %d edge_id %d \n", 245 // s->key.i, s->key.j,s->vol_id,s->edge_id); 246 //printf("key.i %d key.j %d vol_id %d edge_id %d \n", 247 // key.i,key.j,vol_id,edge_id); 248 delete_all(); 249 PyErr_SetString(PyExc_RuntimeError, 250 "pmesh2domain.c: build_boundary_dictionary Duplicate segments"); 251 return NULL; 252 } 253 254 255 //-------------------------------------------------------------------------- 256 //Step 2: 257 //Go through segments. Those with null tags are added to pyobj_tag_dict 258 //-------------------------------------------------------------------------- 259 260 261 for (k = 0; k < N; k++) { 262 263 k2 = 2*k; 264 a = segments[k2+0]; 265 b = segments[k2+1]; 266 267 // pyobj_tag should be a string 268 pyobj_tag = PyList_GetItem(pyobj_segment_tags, (Py_ssize_t) k ); 269 270 string = PyString_AsString(pyobj_tag); 271 272 len_tag = strlen(string); 273 274 //printf("segment %d %d len %d, tag %s \n",a,b,len_tag, string); 275 276 key.i = a; 277 key.j = b; 278 s = find_segment(key); 279 if ( s && len_tag>0 ) { 280 vol_id = s->vol_id; 281 edge_id = s->edge_id; 282 283 pyobj_key = PyTuple_New(2); 284 PyTuple_SetItem(pyobj_key, 0, PyInt_FromLong( vol_id )); 285 PyTuple_SetItem(pyobj_key, 1, PyInt_FromLong( edge_id )); 286 287 PyDict_SetItem(pyobj_tag_dict, pyobj_key, pyobj_tag ); 288 } 289 290 key.i = b; 291 key.j = a; 292 s = find_segment(key); 293 if ( s && len_tag>0 ) { 294 vol_id = s->vol_id; 295 edge_id = s->edge_id; 296 297 pyobj_key = PyTuple_New(2); 298 PyTuple_SetItem(pyobj_key, 0, PyInt_FromLong( vol_id )); 299 PyTuple_SetItem(pyobj_key, 1, PyInt_FromLong( edge_id )); 300 301 PyDict_SetItem(pyobj_tag_dict, pyobj_key, pyobj_tag ); 302 } 303 304 } 305 306 delete_all(); /* free any structures */ 307 308 return Py_BuildValue("O", pyobj_tag_dict); 309 } 310 311 312 //============================================================================== 313 // Structures to allow calling from python 314 //============================================================================== 315 316 static PyObject *build_sides_dictionary(PyObject *self, PyObject *args) { 317 long i, numTriangle; 318 int ok; 319 long a, b, c; 320 long *triangles; 321 PyObject *pyobj_key; 322 PyObject *pyobj_sides; 323 PyArrayObject *pyobj_triangles; 324 325 326 ok = PyArg_ParseTuple(args, "OO", &pyobj_triangles, &pyobj_sides); 327 if (!ok) { 328 report_python_error(AT, "could not parse input arguments"); 329 return NULL; 330 } 331 332 333 numTriangle = LENDATA(pyobj_triangles); 334 triangles = IDATA(pyobj_triangles); 335 336 337 338 for (i = 0; i < numTriangle; i++) { 339 a = triangles[i * 3 + 0]; 340 b = triangles[i * 3 + 1]; 341 c = triangles[i * 3 + 2]; 342 343 // sides[a,b] = (id, 2) #(id, face) 344 pyobj_key = PyTuple_New(2); 345 PyTuple_SetItem(pyobj_key, 0, PyInt_FromLong(a)); 346 PyTuple_SetItem(pyobj_key, 1, PyInt_FromLong(b)); 347 348 PyDict_SetItem(pyobj_sides, pyobj_key, PyInt_FromLong(3 * i + 2)); 349 350 Py_DECREF(pyobj_key); 351 352 // sides[b,c] = (id, 0) #(id, face) 353 pyobj_key = PyTuple_New(2); 354 PyTuple_SetItem(pyobj_key, 0, PyInt_FromLong(b)); 355 PyTuple_SetItem(pyobj_key, 1, PyInt_FromLong(c)); 356 357 PyDict_SetItem(pyobj_sides, pyobj_key, PyInt_FromLong(3 * i + 0)); 358 359 Py_DECREF(pyobj_key); 360 361 362 // sides[c,a] = (id, 1) #(id, face) 363 pyobj_key = PyTuple_New(2); 364 PyTuple_SetItem(pyobj_key, 0, PyInt_FromLong(c)); 365 PyTuple_SetItem(pyobj_key, 1, PyInt_FromLong(a)); 366 367 PyDict_SetItem(pyobj_sides, pyobj_key, PyInt_FromLong(3 * i + 1)); 368 369 Py_DECREF(pyobj_key); 370 371 372 } 373 374 return Py_BuildValue("O", pyobj_sides); 375 } 376 83 377 84 378 static PyMethodDef MF_module_methods[] = { 85 {"sides_dictionary_construct", SidesDictionaryConstruct, METH_VARARGS},86 {NULL, NULL} //sentinel 87 }; 88 89 void initpmesh2domain_ext( ) 90 {91 92 93 94 } 379 {"build_boundary_dictionary", build_boundary_dictionary, METH_VARARGS}, 380 {"build_sides_dictionary", build_sides_dictionary, METH_VARARGS}, 381 {NULL, NULL} //sentinel 382 }; 383 384 void initpmesh2domain_ext() { 385 (void) Py_InitModule("pmesh2domain_ext", MF_module_methods); 386 387 import_array(); 388 }
Note: See TracChangeset
for help on using the changeset viewer.