bugfixes, implementation of adjacency functions

This commit is contained in:
2009-06-11 23:09:47 +00:00
parent 48618f0028
commit 5bd0617f59
14 changed files with 757 additions and 195 deletions
+34 -12
View File
@@ -37,30 +37,52 @@
/*
ID's: 64bit
Tets:
00000000 tttttttt tttttttt tttttttt tttttttt tttttttt tttttttt tttttttt
00 TT TT TT TT TT TT
Trinagles:
000100dd tttttttt tttttttt tttttttt tttttttt tttttttt tttttttt tttttttt
1D TT TT TT TT TT TT
Vertices:
000100vv tttttttt tttttttt tttttttt tttttttt tttttttt tttttttt tttttttt
3V TT TT TT TT TT TT
Edges:
00100eee tttttttt tttttttt tttttttt tttttttt tttttttt tttttttt tttttttt
2E TT TT TT TT TT TT
Trinagles:
001100dd tttttttt tttttttt tttttttt tttttttt tttttttt tttttttt tttttttt
1D TT TT TT TT TT TT
Tets:
01000000 tttttttt tttttttt tttttttt tttttttt tttttttt tttttttt tttttttt
00 TT TT TT TT TT TT
*/
#define H5T_ELEM_MASK ( (h5_id_t) (ULLONG_MAX >> 8) )
#define H5T_ETYPE_MASK ( 7ull << (sizeof(h5_id_t)*8-4) )
#define H5T_ELEM_TYPE_MASK ( 7ull << (sizeof(h5_id_t)*8-4) )
#define H5T_FACE_MASK (15ull << (sizeof(h5_id_t)*7) )
#define _h5t_build_triangle_id( face_id, elem_id ) \
( ((h5_id_t)1 << (sizeof(elem_id)*8-4)) | \
((h5_id_t)(face_id) << (sizeof(elem_id)*7)) | \
#define H5T_ELEM_TYPE_VERTEX ((h5_id_t)1 << (sizeof(h5_id_t)*8-4))
#define H5T_ELEM_TYPE_EDGE ((h5_id_t)2 << (sizeof(h5_id_t)*8-4))
#define H5T_ELEM_TYPE_TRIANGLE ((h5_id_t)3 << (sizeof(h5_id_t)*8-4))
#define H5T_ELEM_TYPE_TET ((h5_id_t)4 << (sizeof(h5_id_t)*8-4))
#define _h5t_build_vertex_id( face_id, elem_id ) \
( H5T_ELEM_TYPE_VERTEX | \
((h5_id_t)(face_id) << (sizeof(h5_id_t)*7)) | \
((elem_id) & H5T_ELEM_MASK))
#define _h5t_build_edge_id( face_id, elem_id ) \
( ((h5_id_t)1 << (sizeof(elem_id)*8-3)) | \
((h5_id_t)(face_id) << (sizeof(elem_id)*7)) | \
( H5T_ELEM_TYPE_EDGE | \
((h5_id_t)(face_id) << (sizeof(h5_id_t)*7)) | \
((elem_id) & H5T_ELEM_MASK))
#define _h5t_build_triangle_id( face_id, elem_id ) \
( H5T_ELEM_TYPE_TRIANGLE | \
((h5_id_t)(face_id) << (sizeof(h5_id_t)*7)) | \
((elem_id) & H5T_ELEM_MASK))
#define _h5t_get_entity_type( entity_id ) \
( entity_id & H5T_ELEM_TYPE_MASK )
#define _h5t_get_face_id( entity_id ) \
( (entity_id & H5T_FACE_MASK) >> (sizeof(h5_id_t)*7) )
+158 -12
View File
@@ -7,9 +7,9 @@
#include "h5_core_private.h"
h5_err_t
_h5_alloc_idlist (
_h5_alloc_idlist_items (
h5_file_t * const f,
h5_idlist_t *list,
h5_idlist_t *list,
const h5_size_t size
) {
int new = ( list->items == NULL );
@@ -20,12 +20,131 @@ _h5_alloc_idlist (
return H5_SUCCESS;
}
h5_err_t
_h5_free_idlist_items (
h5_file_t * const f,
h5_idlist_t *list
) {
if ( list->items != NULL ) free ( list->items );
list->items = NULL;
list->size = 0;
list->num_items = 0;
return H5_SUCCESS;
}
h5_err_t
_h5_alloc_idlist (
h5_file_t * const f,
h5_idlist_t **list,
const h5_size_t size
) {
TRY ( ( *list = _h5_alloc ( f, NULL, sizeof (**list) ) ) );
memset ( *list, 0, sizeof(**list) );
size_t size_in_bytes = size * sizeof ( (*list)->items[0] );
TRY ( (*list)->items = _h5_alloc ( f, (*list)->items, size_in_bytes ) );
(*list)->size = size;
return H5_SUCCESS;
}
h5_err_t
_h5_free_idlist (
h5_file_t * const f,
h5_idlist_t **list
) {
if ( *list == NULL ) return H5_SUCCESS;
TRY ( _h5_free_idlist_items ( f, *list ) );
TRY ( _h5_free( f, *list ) );
*list = NULL;
return H5_SUCCESS;
}
h5_err_t
_h5_append_to_idlist (
h5_file_t * const f,
h5_idlist_t *list,
h5_id_t id
) {
if ( list->num_items == list->size ) {
h5_size_t size = list->size;
if ( size == 0 ) {
size = 2;
} else {
size *= 2;
}
TRY ( _h5_alloc_idlist_items ( f, list, size ) );
}
list->items[list->num_items++] = id;
return H5_SUCCESS;
}
int
_h5_cmp_ids_by_eid (
const void *_id1,
const void *_id2
) {
h5_id_t id1 = _h5t_get_elem_id ( *(h5_id_t*)_id1 );
h5_id_t id2 = _h5t_get_elem_id ( *(h5_id_t*)_id2 );
if ( id1 < id2 ) return -1;
if ( id1 > id2 ) return 1;
return 0;
}
int
_h5_cmp_ids (
const void *_id1,
const void *_id2
) {
h5_id_t *id1 = (h5_id_t*)_id1;
h5_id_t *id2 = (h5_id_t*)_id2;
if ( *id1 < *id2 ) return -1;
if ( *id1 > *id2 ) return 1;
return 0;
}
h5_err_t
_h5_sort_idlist_by_eid (
h5_file_t * const f,
h5_idlist_t *list
) {
qsort (
list->items,
list->num_items,
sizeof(list->items[0]),
_h5_cmp_ids_by_eid );
return H5_SUCCESS;
}
h5_id_t
_h5_find_idlist (
h5_file_t * const f,
h5_idlist_t *list,
h5_id_t item
) {
register h5_id_t low = 0;
register h5_id_t high = list->num_items - 1;
while (low <= high) {
register h5_id_t mid = (low + high) / 2;
register h5_id_t diff = list->items[mid] - item;
if ( diff > 0 )
high = mid - 1;
else if ( diff < 0 )
low = mid + 1;
else
return mid; // found
}
return -(low+1); // not found
}
h5_id_t
_h5_insert_idlist (
h5_file_t * const f,
h5_idlist_t *list,
h5_id_t item,
h5_id_t idx
) {
if ( list->num_items == list->size ) {
h5_size_t size = list->size;
if ( size == 0 ) {
@@ -33,10 +152,29 @@ _h5_append_to_idlist (
} else {
size *= 2;
}
TRY ( _h5_alloc_idlist ( f, list, size ) );
TRY ( _h5_alloc_idlist_items ( f, list, size ) );
}
list->items[list->num_items++] = id;
return H5_SUCCESS;
memmove (
&list->items[idx+1],
&list->items[idx],
(list->num_items - idx) * sizeof(list->items[0]) );
list->items[idx] = item;
list->num_items++;
return idx;
}
h5_id_t
_h5_search_idlist (
h5_file_t * const f,
h5_idlist_t *list,
h5_id_t item
) {
h5_id_t idx = _h5_find_idlist ( f, list, item );
if ( idx < 0 ) {
idx = -(idx+1);
idx = _h5_insert_idlist ( f, list, item, idx );
}
return idx;
}
h5_err_t
@@ -53,7 +191,6 @@ _h5_alloc_idmap (
return H5_SUCCESS;
}
h5_err_t
_h5_insert_idmap (
h5_file_t * const f,
@@ -74,7 +211,7 @@ _h5_insert_idmap (
memmove (
&map->items[i+1],
&map->items[i],
map->num_items - i );
(map->num_items - i) * sizeof(map->items[0]) );
map->items[i].global_id = global_id;
map->items[i].local_id = local_id;
map->num_items++;
@@ -114,18 +251,27 @@ _h5_search_idmap (
}
int
_cmp_idmap (
const void *id1,
const void *id2
_cmp_idmap_items (
const void *_item1,
const void *_item2
) {
h5_idmap_el_t *item1 = (h5_idmap_el_t*)_item1;
h5_idmap_el_t *item2 = (h5_idmap_el_t*)_item2;
if ( item1->global_id < item2->global_id ) return -1;
if ( item1->global_id > item2->global_id ) return 1;
return *(h5_id_t*)id1 - *(h5_id_t*)id2;
return 0;
}
h5_err_t
_h5_sort_idmap (
h5_idmap_t *map
) {
qsort ( map->items, map->num_items, sizeof(map->items[0]), _cmp_idmap );
qsort (
map->items,
map->num_items,
sizeof(map->items[0]),
_cmp_idmap_items );
return H5_SUCCESS;
}
+59
View File
@@ -3,11 +3,30 @@
h5_err_t
_h5_alloc_idlist (
h5_file_t * const f,
h5_idlist_t **list,
const h5_size_t size
);
h5_err_t
_h5_free_idlist (
h5_file_t * const f,
h5_idlist_t **list
);
h5_err_t
_h5_alloc_idlist_items (
h5_file_t * const f,
h5_idlist_t *list,
const h5_size_t size
);
h5_err_t
_h5_free_idlist_items (
h5_file_t * const f,
h5_idlist_t *list
);
h5_err_t
_h5_append_to_idlist (
h5_file_t * const f,
@@ -15,6 +34,46 @@ _h5_append_to_idlist (
h5_id_t id
);
int
_h5_cmp_ids_by_eid (
const void *_id1,
const void *_id2
);
int
_h5_cmp_ids (
const void *_id1,
const void *_id2
);
h5_err_t
_h5_sort_idlist_by_eid (
h5_file_t * const f,
h5_idlist_t *list
);
h5_id_t
_h5_find_idlist (
h5_file_t * const f,
h5_idlist_t *list,
h5_id_t item
);
h5_id_t
_h5_insert_idlist (
h5_file_t * const f,
h5_idlist_t *list,
h5_id_t item,
h5_id_t idx
);
h5_id_t
_h5_search_idlist (
h5_file_t * const f,
h5_idlist_t *list,
h5_id_t item
);
h5_err_t
_h5_alloc_idmap (
h5_file_t * const f,
+2 -1
View File
@@ -21,12 +21,13 @@ _h5_alloc (
return ptr;
}
void
h5_err_t
_h5_free (
h5_file_t * const f,
void *ptr
) {
if ( ptr ) free ( ptr );
return H5_SUCCESS;
}
void *
+1 -1
View File
@@ -8,7 +8,7 @@ _h5_alloc (
const size_t size
);
void
h5_err_t
_h5_free (
h5_file_t * const f,
void *ptr
+5 -1
View File
@@ -54,7 +54,11 @@ typedef h5_err_t (*h5_errorhandler_t)(
typedef unsigned long MPI_Comm;
#endif
struct h5_idlist;
struct h5_idlist {
h5_size_t size; /* allocated space in number of items */
h5_size_t num_items; /* stored items */
h5_id_t *items;
};
typedef struct h5_idlist h5_idlist_t;
struct h5_idmap;
typedef struct h5_idmap h5_idmap_t;
-5
View File
@@ -1,11 +1,6 @@
#ifndef __H5_TYPES_PRIVATE_H
#define __H5_TYPES_PRIVATE_H
struct h5_idlist {
h5_size_t size; /* allocated space in number of items */
h5_size_t num_items; /* stored items */
h5_id_t *items;
};
struct h5_idmap_el {
h5_id_t global_id;
+412 -155
View File
@@ -13,17 +13,21 @@
#include <stdlib.h>
#include <string.h>
#include <search.h>
#include <hdf5.h>
#include "h5_core/h5_core.h"
#include "h5_core/h5_core_private.h"
h5_err_t
static h5_err_t
_compute_children_of_edge (
h5_file_t * const f,
h5_id_t local_kid,
h5_idlist_t *children
);
/*
compute T(V)
*/
static h5_err_t
_calc_tets_of_vertices (
h5_file_t * const f
@@ -38,12 +42,12 @@ _calc_tets_of_vertices (
for ( local_tid = 0, tet = &t->elems_data.tets[0];
local_tid < t->num_elems[t->num_levels-1];
local_tid++, tet++ ) {
for ( i = 0; i < 3; i++ ) {
for ( i = 0; i < 4; i++ ) {
local_vid = tet->local_vids[i];
TRY ( _h5_append_to_idlist (
f,
&t->vertices_data[local_vid].tv,
local_tid ) );
_h5t_build_vertex_id( i, local_tid ) ) );
}
}
return H5_SUCCESS;
@@ -69,33 +73,32 @@ _cmp_te_node (
}
static h5_err_t
_search_te (
_search_te2 (
h5_file_t * const f,
h5_te_node_t **node,
h5_id_t local_kid
h5_id_t face_id,
h5_id_t local_eid
) {
h5t_fdata_t *t = f->t;
h5t_adjacencies_t *a = &t->adjacencies;
void *vnode;
h5_id_t local_eid = _h5t_get_elem_id ( local_kid );
h5_id_t face_id = _h5t_get_face_id ( local_kid );
h5_tet_data_t *tet_data = &t->elems_data.tets[local_eid];
h5_id_t *vids = (*node)->key.vids;
h5_id_t vid;
int map[6][2] = { { 0,1 }, {1,2}, {0,2}, {0,3}, {1,3}, {2,3} };
vids[0] = tet_data->local_vids[map[face_id][0]];
vids[1] = tet_data->local_vids[map[face_id][1]];
if ( vids[0] > vids[1] ) {
vid = vids[0]; vids[0] = vids[1]; vids[1] = vid;
}
if ( *node ==NULL ) {
TRY ( *node = _h5_alloc ( f, NULL, sizeof(**node) ) );
memset ( *node, 0, sizeof(**node) );
}
h5_id_t *edge = (*node)->key.vids;
edge[0] = tet_data->local_vids[map[face_id][0]];
edge[1] = tet_data->local_vids[map[face_id][1]];
if ( edge[0] > edge[1] ) {
vid = edge[0]; edge[0] = edge[1]; edge[1] = vid;
}
TRY ( vnode = _h5_tsearch (
f,
*node,
@@ -105,7 +108,7 @@ _search_te (
TRY ( _h5_append_to_idlist (
f,
&rnode->value,
local_eid ) );
_h5t_build_edge_id ( face_id, local_eid ) ) );
if ( rnode->value.num_items == 1 ) {
*node = NULL;
}
@@ -116,25 +119,57 @@ static h5_err_t
_find_te (
h5_file_t * const f,
h5_te_node_t **rnode,
h5_id_t local_kid
h5_2id_t edge
) {
h5t_fdata_t *t = f->t;
h5t_adjacencies_t *a = &t->adjacencies;
h5_te_node_t node;
void *vnode = &node;
if ( edge[0] > edge[1] ) {
h5_id_t vid = edge[0]; edge[0] = edge[1]; edge[1] = vid;
}
memcpy ( node.key.vids, edge, 2*sizeof(*edge) );
TRY ( vnode = _h5_tfind (
f,
vnode,
(void**)&a->te_tree,
_cmp_te_node ) );
*rnode = *(h5_te_node_t **)vnode;
return H5_SUCCESS;
}
/*
pass edge by:
edge ID
vertices
face and element ID
*/
static h5_err_t
_find_te2 (
h5_file_t * const f,
h5_te_node_t **rnode,
h5_id_t face_id,
h5_id_t local_eid
) {
h5t_fdata_t *t = f->t;
h5t_adjacencies_t *a = &t->adjacencies;
h5_te_node_t node;
void *vnode = &node;
h5_id_t local_eid = _h5t_get_elem_id ( local_kid );
h5_id_t face_id = _h5t_get_face_id ( local_kid );
h5_tet_data_t *tet_data = &t->elems_data.tets[local_eid];
h5_id_t *vids = node.key.vids;
h5_id_t vid;
h5_id_t *edge = node.key.vids;
int map[6][2] = { { 0,1 }, {1,2}, {0,2}, {0,3}, {1,3}, {2,3} };
vids[0] = tet_data->local_vids[map[face_id][0]];
vids[1] = tet_data->local_vids[map[face_id][1]];
edge[0] = tet_data->local_vids[map[face_id][0]];
edge[1] = tet_data->local_vids[map[face_id][1]];
if ( vids[0] > vids[1] ) {
vid = vids[0]; vids[0] = vids[1]; vids[1] = vid;
if ( edge[0] > edge[1] ) {
h5_id_t vid = edge[0]; edge[0] = edge[1]; edge[1] = vid;
}
TRY ( vnode = _h5_tfind (
f,
@@ -146,61 +181,57 @@ _find_te (
return H5_SUCCESS;
}
/*
Sort ID list according their tetrahedra ID.
Called by twalk().
*/
static void
_sort_telist (
const void *_node,
const VISIT order,
const int depth
) {
if ( order == postorder || order == leaf ) {
h5_te_node_t *node = *(h5_te_node_t **)_node;
h5_idlist_t *list = &node->value;
qsort (
list->items,
list->num_items,
sizeof(list->items[0]),
_h5_cmp_ids_by_eid );
}
}
static h5_err_t
_calc_tets_of_edges (
h5_file_t * const f
) {
h5t_fdata_t *t = f->t;
h5t_adjacencies_t *a = &t->adjacencies;
h5_id_t local_tid;
h5_id_t local_eid;
h5_size_t num_tets = t->num_elems[t->num_levels-1];
h5_te_node_t *node = NULL;
h5_tet_data_t *tet = &t->elems_data.tets[0];
h5_id_t edge_id;
h5_id_t face_id;
a->te_tree = NULL;
for ( local_tid = 0; local_tid < num_tets; local_tid++, tet++ ) {
for ( edge_id = 0; edge_id < 6; edge_id++ ) {
for ( local_eid = 0; local_eid < num_tets; local_eid++, tet++ ) {
for ( face_id = 0; face_id < 6; face_id++ ) {
TRY (
_search_te (
_search_te2 (
f,
&node,
_h5t_build_edge_id (
edge_id,
local_tid ) )
face_id,
local_eid )
);
}
}
twalk ( (void*)a->te_tree, _sort_telist );
if ( node && node->value.items == NULL ) {
_h5_free ( f, node );
}
#undef DEBUG
#ifdef DEBUG
node = NULL;
tet = &t->elems_data.tets[0];
for ( local_tid = 0; local_tid < num_tets; local_tid++, tet++ ) {
/* for each edge of tet */
for ( i = 1; i <= 3; i++ ) {
for ( j = 0; j < i; j++ ) {
TRY ( _find_te (
f,
&node,
tet->local_vids[i],
tet->local_vids[j] ) );
h5_debug ( f, "Edge (%lld,%lld):",
node->key.vid0,
node->key.vid1 );
h5_size_t k;
for ( k = 0; k < node->value.num_items; k++ ) {
h5_debug ( f, " %lld",
node->value.items[k] );
}
}
}
}
#endif
return H5_SUCCESS;
}
@@ -228,39 +259,38 @@ _cmp_td_node (
}
static h5_err_t
_search_td (
_search_td2 (
h5_file_t * const f,
h5_td_node_t **node,
h5_id_t local_did
h5_id_t face_id,
h5_id_t local_eid
) {
h5t_fdata_t *t = f->t;
h5t_adjacencies_t *a = &t->adjacencies;
void *vnode;
h5_id_t local_eid = _h5t_get_elem_id ( local_did );
h5_id_t face_id = _h5t_get_face_id ( local_did );
h5_tet_data_t *tet_data = &t->elems_data.tets[local_eid];
h5_id_t *vids = (*node)->key.vids;
h5_id_t vid;
int map[4][3] = { { 1,2,3 }, {0,2,3}, {0,1,3}, {0,1,2} };
vids[0] = tet_data->local_vids[map[face_id][0]];
vids[1] = tet_data->local_vids[map[face_id][1]];
vids[2] = tet_data->local_vids[map[face_id][2]];
if ( vids[0] > vids[1] ) {
vid = vids[0]; vids[0] = vids[1]; vids[1] = vid;
}
if ( vids[1] > vids[2] ) {
vid = vids[1]; vids[1] = vids[2]; vids[2] = vid;
}
if ( vids[0] > vids[1] ) {
vid = vids[0]; vids[0] = vids[1]; vids[1] = vid;
}
if ( *node ==NULL ) {
TRY ( *node = _h5_alloc ( f, NULL, sizeof(**node) ) );
memset ( *node, 0, sizeof(**node) );
}
h5_id_t *triangle = (*node)->key.vids;
triangle[0] = tet_data->local_vids[map[face_id][0]];
triangle[1] = tet_data->local_vids[map[face_id][1]];
triangle[2] = tet_data->local_vids[map[face_id][2]];
if ( triangle[0] > triangle[1] ) {
vid = triangle[0]; triangle[0] = triangle[1]; triangle[1] = vid;
}
if ( triangle[1] > triangle[2] ) {
vid = triangle[1]; triangle[1] = triangle[2]; triangle[2] = vid;
}
if ( triangle[0] > triangle[1] ) {
vid = triangle[0]; triangle[0] = triangle[1]; triangle[1] = vid;
}
TRY ( vnode = _h5_tsearch (
f,
@@ -271,44 +301,49 @@ _search_td (
TRY ( _h5_append_to_idlist (
f,
&rnode->value,
local_eid ) );
_h5t_build_triangle_id ( face_id, local_eid ) ) );
if ( rnode->value.num_items == 1 ) {
*node = NULL;
}
return H5_SUCCESS;
}
h5_id_t *
_h5t_get_triangle_of_tet (
const h5_tet_data_t *tet,
const h5_id_t face_id,
h5_2id_t tri
) {
int map[4][3] = { { 1, 2, 3 }, { 0, 2, 3 }, { 0, 1, 3 }, { 0, 1, 2} };
tri[0] = tet->local_vids[map[face_id][0]];
tri[1] = tet->local_vids[map[face_id][1]];
tri[2] = tet->local_vids[map[face_id][2]];
return tri;
}
static h5_err_t
_find_td (
h5_file_t * const f,
h5_td_node_t **rnode,
h5_id_t local_did
h5_3id_t tri
) {
h5t_fdata_t *t = f->t;
h5t_adjacencies_t *a = &t->adjacencies;
h5_td_node_t node;
void *vnode = &node;
h5_id_t local_eid = _h5t_get_elem_id ( local_did );
h5_id_t face_id = _h5t_get_face_id ( local_did );
h5_tet_data_t *tet_data = &t->elems_data.tets[local_eid];
h5_id_t *vids = node.key.vids;
h5_id_t vid;
int map[4][3] = { { 1,2,3 }, {0,2,3}, {0,1,3}, {0,1,2} };
vids[0] = tet_data->local_vids[map[face_id][0]];
vids[1] = tet_data->local_vids[map[face_id][1]];
vids[2] = tet_data->local_vids[map[face_id][2]];
if ( vids[0] > vids[1] ) {
vid = vids[0]; vids[0] = vids[1]; vids[1] = vid;
if ( tri[0] > tri[1] ) {
vid = tri[0]; tri[0] = tri[1]; tri[1] = vid;
}
if ( vids[1] > vids[2] ) {
vid = vids[1]; vids[1] = vids[2]; vids[2] = vid;
if ( tri[1] > tri[2] ) {
vid = tri[1]; tri[1] = tri[2]; tri[2] = vid;
}
if ( vids[0] > vids[1] ) {
vid = vids[0]; vids[0] = vids[1]; vids[1] = vid;
if ( tri[0] > tri[1] ) {
vid = tri[0]; tri[0] = tri[1]; tri[1] = vid;
}
memcpy ( node.key.vids, tri, 3*sizeof(*tri) );
TRY ( vnode = _h5_tfind (
f,
vnode,
@@ -319,13 +354,73 @@ _find_td (
return H5_SUCCESS;
}
static h5_err_t
_find_td2 (
h5_file_t * const f,
h5_td_node_t **rnode,
h5_id_t face_id,
h5_id_t local_eid
) {
h5t_fdata_t *t = f->t;
h5t_adjacencies_t *a = &t->adjacencies;
h5_td_node_t node;
void *vnode = &node;
h5_tet_data_t *tet_data = &t->elems_data.tets[local_eid];
h5_id_t *tri = node.key.vids;
_h5t_get_triangle_of_tet ( tet_data, face_id, tri );
h5_id_t vid;
if ( tri[0] > tri[1] ) {
vid = tri[0]; tri[0] = tri[1]; tri[1] = vid;
}
if ( tri[1] > tri[2] ) {
vid = tri[1]; tri[1] = tri[2]; tri[2] = vid;
}
if ( tri[0] > tri[1] ) {
vid = tri[0]; tri[0] = tri[1]; tri[1] = vid;
}
TRY ( vnode = _h5_tfind (
f,
vnode,
(void**)&a->td_tree,
_cmp_td_node ) );
*rnode = *(h5_td_node_t **)vnode;
return H5_SUCCESS;
}
/*
Sort ID list according their tetrahedra ID.
Called by twalk().
*/
static void
_sort_tdlist (
const void *_node,
const VISIT order,
const int depth
) {
if ( order == postorder || order == leaf ) {
h5_td_node_t *node = *(h5_td_node_t **)_node;
h5_idlist_t *list = &node->value;
qsort (
list->items,
list->num_items,
sizeof(list->items[0]),
_h5_cmp_ids_by_eid );
}
}
static h5_err_t
_calc_tets_of_triangles (
h5_file_t * const f
) {
h5t_fdata_t *t = f->t;
h5t_adjacencies_t *a = &t->adjacencies;
h5_id_t local_tid;
h5_id_t local_eid;
h5_size_t num_tets = t->num_elems[t->num_levels-1];
h5_td_node_t *node = NULL;
h5_tet_data_t *tet = &t->elems_data.tets[0];
@@ -333,18 +428,18 @@ _calc_tets_of_triangles (
a->td_tree = NULL;
for ( local_tid = 0; local_tid < num_tets; local_tid++, tet++ ) {
for ( local_eid = 0; local_eid < num_tets; local_eid++, tet++ ) {
for ( face_id = 0; face_id < 4; face_id++ ) {
TRY (
_search_td (
_search_td2 (
f,
&node,
_h5t_build_triangle_id (
face_id,
local_tid) )
face_id,
local_eid )
);
}
}
twalk ( (void*)a->td_tree, _sort_tdlist );
if ( node && node->value.items == NULL ) {
_h5_free ( f, node );
}
@@ -360,47 +455,43 @@ _h5t_rebuild_adj_data (
TRY ( _calc_tets_of_edges ( f ) );
TRY ( _calc_tets_of_triangles ( f ) );
h5_id_t local_kid = _h5t_build_edge_id ( 0, 0 );
h5_idlist_t children;
f->t->cur_level = 2;
memset ( &children, 0, sizeof(children) );
_compute_children_of_edge (
f,
local_kid,
&children
);
f->t->cur_level = 0;
return H5_SUCCESS;
}
/*!
\param[in] f file handle
\param[in] local_kid local edge ID we search children of
\param[in] local_eid local element ID of first children
\param[out] kids direct children
*/
h5_err_t
_compute_direct_children_of_edge (
h5_file_t * const f,
h5_id_t local_kid,
h5_id_t kids[4]
h5_id_t local_eid,
h5_id_t kids[2]
) {
h5_id_t local_eid = _h5t_get_elem_id ( local_kid );
h5_id_t face_id = _h5t_get_face_id ( local_kid );
if ( face_id == 0 ) {
kids[0] = _h5t_build_edge_id ( 3, local_eid+0 );
kids[1] = _h5t_build_edge_id ( 3, local_eid+1 );
kids[0] = _h5t_build_edge_id ( 0, local_eid+0 );
kids[1] = _h5t_build_edge_id ( 0, local_eid+1 );
} else if ( face_id == 1 ) {
kids[0] = _h5t_build_edge_id ( 5, local_eid+1 );
kids[1] = _h5t_build_edge_id ( 5, local_eid+2 );
kids[0] = _h5t_build_edge_id ( 1, local_eid+1 );
kids[1] = _h5t_build_edge_id ( 1, local_eid+2 );
} else if ( face_id == 2 ) {
kids[0] = _h5t_build_edge_id ( 2, local_eid+0 );
kids[1] = _h5t_build_edge_id ( 2, local_eid+2 );
} else if ( face_id == 3 ) {
kids[0] = _h5t_build_edge_id ( 0, local_eid+0 );
kids[1] = _h5t_build_edge_id ( 0, local_eid+3 );
kids[0] = _h5t_build_edge_id ( 3, local_eid+0 );
kids[1] = _h5t_build_edge_id ( 3, local_eid+3 );
} else if ( face_id == 4 ) {
kids[0] = _h5t_build_edge_id ( 4, local_eid+1 );
kids[1] = _h5t_build_edge_id ( 4, local_eid+3 );
} else if ( face_id == 5 ) {
kids[0] = _h5t_build_edge_id ( 1, local_eid+2 );
kids[1] = _h5t_build_edge_id ( 1, local_eid+3 );
kids[0] = _h5t_build_edge_id ( 5, local_eid+2 );
kids[1] = _h5t_build_edge_id ( 5, local_eid+3 );
} else {
return h5_error_internal ( f, __FILE__, __func__, __LINE__ );
}
@@ -430,7 +521,12 @@ _compute_children_of_edge (
h5_te_node_t *te;
int i,k;
TRY ( _find_te ( f, &te, local_kid ) );
TRY ( _find_te2 (
f,
&te,
_h5t_get_face_id ( local_kid ),
_h5t_get_elem_id ( local_kid ) )
);
for ( k = 0; k < te->value.num_items; k++ ) {
h5_id_t local_eid = _h5t_get_elem_id ( te->value.items[k] );
h5_tet_data_t *tet = &t->elems_data.tets[local_eid];
@@ -440,30 +536,26 @@ _compute_children_of_edge (
continue;
/* no children on current level? */
h5_tet_data_t *child_tet = &t->elems_data.tets[tet->local_child_eid];
if ( (tet->local_child_eid >= 0) &&
(child_tet->level_id > t->cur_level) )
if ( child_tet->level_id > t->cur_level )
continue;
h5_id_t local_kids[2];
TRY ( _compute_direct_children_of_edge (
f,
te->value.items[k], /* parent triangle */
te->value.items[k], /* parent edge */
tet->local_child_eid, /* first children of element */
local_kids ) ); /* result */
for ( i = 0; i < 4; i++ ) {
for ( i = 0; i < 2; i++ ) {
local_eid = _h5t_get_elem_id ( local_kids[i] );
tet = &t->elems_data.tets[local_eid];
/* no children? */
if ( tet->local_child_eid < 0 ) {
h5_id_t l_chld_eid = tet->local_child_eid;
if ( ( l_chld_eid < 0 ) ||
( t->elems_data.tets[l_chld_eid].level_id > t->cur_level)) {
TRY ( _h5_append_to_idlist (
f, children, local_kids[i] )
);
}
/* no children on current level? */
child_tet = &t->elems_data.tets[tet->local_child_eid];
if ( child_tet->level_id > t->cur_level) {
TRY ( _h5_append_to_idlist (
f, children, local_kids[i] ) );
} else {
TRY ( _compute_children_of_edge (
f, local_kids[i], children ) );
@@ -489,20 +581,20 @@ _compute_direct_children_of_triangle (
children_dids[2] = _h5t_build_triangle_id ( 0, local_eid+3 );
children_dids[3] = _h5t_build_triangle_id ( 0, local_eid+7 );
} else if ( face_id == 1 ) {
children_dids[0] = _h5t_build_triangle_id ( 3, local_eid+0 );
children_dids[1] = _h5t_build_triangle_id ( 3, local_eid+2 );
children_dids[2] = _h5t_build_triangle_id ( 3, local_eid+3 );
children_dids[3] = _h5t_build_triangle_id ( 3, local_eid+6 );
children_dids[0] = _h5t_build_triangle_id ( 1, local_eid+0 );
children_dids[1] = _h5t_build_triangle_id ( 1, local_eid+2 );
children_dids[2] = _h5t_build_triangle_id ( 1, local_eid+3 );
children_dids[3] = _h5t_build_triangle_id ( 1, local_eid+6 );
} else if ( face_id == 2 ) {
children_dids[0] = _h5t_build_triangle_id ( 2, local_eid+0 );
children_dids[1] = _h5t_build_triangle_id ( 2, local_eid+1 );
children_dids[2] = _h5t_build_triangle_id ( 2, local_eid+3 );
children_dids[3] = _h5t_build_triangle_id ( 1, local_eid+4 );
children_dids[3] = _h5t_build_triangle_id ( 2, local_eid+4 );
} else if ( face_id == 3 ) {
children_dids[0] = _h5t_build_triangle_id ( 1, local_eid+0 );
children_dids[1] = _h5t_build_triangle_id ( 1, local_eid+1 );
children_dids[2] = _h5t_build_triangle_id ( 1, local_eid+2 );
children_dids[3] = _h5t_build_triangle_id ( 2, local_eid+5 );
children_dids[0] = _h5t_build_triangle_id ( 3, local_eid+0 );
children_dids[1] = _h5t_build_triangle_id ( 3, local_eid+1 );
children_dids[2] = _h5t_build_triangle_id ( 3, local_eid+2 );
children_dids[3] = _h5t_build_triangle_id ( 3, local_eid+5 );
} else {
return h5_error_internal ( f, __FILE__, __func__, __LINE__ );
}
@@ -533,7 +625,12 @@ _compute_children_of_triangle (
h5_td_node_t *td;
int i, k;
TRY ( _find_td ( f, &td, local_did ) );
TRY ( _find_td2 (
f,
&td,
_h5t_get_face_id ( local_did ),
_h5t_get_elem_id ( local_did ) )
);
for ( k = 0; k < td->value.num_items; k++ ) {
h5_id_t local_eid = _h5t_get_elem_id ( td->value.items[k] );
h5_tet_data_t *tet = &t->elems_data.tets[local_eid];
@@ -542,9 +639,8 @@ _compute_children_of_triangle (
if ( tet->local_child_eid < 0 )
continue;
/* no children on current level? */
h5_tet_data_t *child_tet = &t->elems_data.tets[tet->local_child_eid];
if ( (tet->local_child_eid >= 0) &&
(child_tet->level_id > t->cur_level) )
h5_tet_data_t *child = &t->elems_data.tets[tet->local_child_eid];
if ( child->level_id > t->cur_level )
continue;
h5_id_t local_dids[4];
@@ -555,18 +651,13 @@ _compute_children_of_triangle (
for ( i = 0; i < 4; i++ ) {
local_eid = _h5t_get_elem_id ( local_dids[i] );
tet = &t->elems_data.tets[local_eid];
/* no children? */
if ( tet->local_child_eid < 0 ) {
h5_id_t l_chld_eid = tet->local_child_eid;
if ( ( l_chld_eid < 0 ) ||
( t->elems_data.tets[l_chld_eid].level_id > t->cur_level)) {
TRY ( _h5_append_to_idlist (
f, children, local_dids[i] )
);
}
/* no children on current level? */
child_tet = &t->elems_data.tets[tet->local_child_eid];
if ( child_tet->level_id > t->cur_level) {
TRY ( _h5_append_to_idlist (
f, children, local_dids[i] ) );
} else {
TRY ( _compute_children_of_triangle (
f, local_dids[i], children ) );
@@ -576,3 +667,169 @@ _compute_children_of_triangle (
return H5_SUCCESS;
}
/*
map edge ID to unique ID
if unique ID not in list: add
*/
static h5_err_t
_add_edge (
h5_file_t * const f,
h5_idlist_t *list,
h5_2id_t edge
) {
h5_te_node_t *te;
TRY ( _find_te ( f, &te, edge ) );
/* search/add unique ID */
_h5_search_idlist ( f, list, te->value.items[0] );
return H5_SUCCESS;
}
h5_err_t
_h5t_tet_is_on_level (
h5_file_t * const f,
h5_tet_data_t *tet_dta
) {
h5t_fdata_t *t = f->t;
if ( tet_dta->level_id > t->cur_level ) {
/* No. Tetrahedron has been defined on higher level */
return H5_ERR;
}
h5_id_t local_child_eid = tet_dta->local_child_eid;
if ( ( local_child_eid >= 0 ) &&
( t->elems_data.tets[local_child_eid].level_id <= t->cur_level ) ) {
/* No. Tetrahedron has children an a level <= current level */
return H5_ERR;
}
return H5_SUCCESS;
}
h5_id_t *
_h5t_get_edge_of_tet (
const h5_tet_data_t *tet,
const h5_id_t face_id,
h5_2id_t edge
) {
int map[6][2] = { { 0,1 }, {1,2}, {0,2}, {0,3}, {1,3}, {2,3} };
edge[0] = tet->local_vids[map[face_id][0]];
edge[1] = tet->local_vids[map[face_id][1]];
return edge;
}
h5_err_t
h5t_get_edges_upadjacent_to_vertex (
h5_file_t * const f,
const h5_id_t local_vid,
h5_idlist_t **list
) {
TRY ( _h5_alloc_idlist ( f, list, 8 ) );
h5t_fdata_t *t = f->t;
h5_idlist_t *tv = &t->vertices_data[local_vid].tv;
h5_size_t i;
for ( i = 0; i < tv->num_items; i++ ) {
h5_id_t local_eid = _h5t_get_elem_id ( tv->items[i] );
h5_id_t vertex_id = _h5t_get_face_id ( tv->items[i] );
h5_tet_data_t *tet = &t->elems_data.tets[local_eid];
if ( _h5t_tet_is_on_level ( f, tet ) == H5_ERR ) {
continue;
}
int map[4][3] = { { 0, 2, 3 }, { 0, 1, 4 }, { 2, 1, 5 }, { 3, 4, 5} };
h5_2id_t edge;
TRY ( _add_edge ( f, *list,
_h5t_get_edge_of_tet(tet, map[vertex_id][0], edge) ) );
TRY ( _add_edge ( f, *list,
_h5t_get_edge_of_tet(tet, map[vertex_id][1], edge) ) );
TRY ( _add_edge ( f, *list,
_h5t_get_edge_of_tet(tet, map[vertex_id][2], edge) ) );
}
return H5_SUCCESS;
}
static h5_err_t
_add_triangle (
h5_file_t * const f,
h5_idlist_t *list,
h5_3id_t tri
) {
h5_td_node_t *td;
TRY ( _find_td ( f, &td, tri ) );
TRY ( _h5_search_idlist ( f, list, td->value.items[0] ) );
return H5_SUCCESS;
}
h5_err_t
h5t_get_triangles_upadjacent_to_vertex (
h5_file_t * const f,
const h5_id_t local_vid,
h5_idlist_t **list
) {
TRY ( _h5_alloc_idlist ( f, list, 8 ) );
h5t_fdata_t *t = f->t;
h5_idlist_t *tv = &t->vertices_data[local_vid].tv;
h5_size_t i;
for ( i = 0; i < tv->num_items; i++ ) {
h5_id_t local_eid = _h5t_get_elem_id ( tv->items[i] );
h5_id_t vertex_id = _h5t_get_face_id ( tv->items[i] );
h5_tet_data_t *tet = &t->elems_data.tets[local_eid];
if ( _h5t_tet_is_on_level ( f, tet ) == H5_ERR ) {
continue;
}
int map[4][3] = { { 1, 2, 3 }, { 0, 2, 3 }, { 0, 1, 3 }, { 0, 1, 2} };
h5_3id_t tri;
TRY ( _add_triangle (
f, *list,
_h5t_get_triangle_of_tet(tet, map[vertex_id][0], tri) ) );
TRY ( _add_triangle (
f, *list,
_h5t_get_triangle_of_tet(tet, map[vertex_id][1], tri) ) );
TRY ( _add_triangle (
f, *list,
_h5t_get_triangle_of_tet(tet, map[vertex_id][2], tri) ) );
}
return H5_SUCCESS;
}
h5_err_t
h5t_get_tets_upadjacent_to_vertex (
h5_file_t * const f,
const h5_id_t local_vid,
h5_idlist_t **list
) {
TRY ( _h5_alloc_idlist ( f, list, 8 ) );
h5t_fdata_t *t = f->t;
h5_idlist_t *tv = &t->vertices_data[local_vid].tv;
h5_size_t i;
for ( i = 0; i < tv->num_items; i++ ) {
h5_id_t local_eid = _h5t_get_elem_id ( tv->items[i] );
h5_tet_data_t *tet = &t->elems_data.tets[local_eid];
if ( _h5t_tet_is_on_level ( f, tet ) == H5_ERR ) {
continue;
}
TRY ( _h5_search_idlist ( f, *list, local_eid ) );
}
return H5_SUCCESS;
}
h5_err_t
h5t_release_list_of_adjacencies (
h5_file_t * const f,
h5_idlist_t **list
) {
TRY ( _h5_free_idlist ( f, list ) );
return H5_SUCCESS;
}
+26
View File
@@ -1,4 +1,30 @@
#ifndef __H5T_ADJACENCIES_H
#define __H5T_ADJACENCIES_H
h5_err_t
h5t_get_edges_upadjacent_to_vertex (
h5_file_t * const f,
const h5_id_t local_vid,
h5_idlist_t **list
);
h5_err_t
h5t_get_triangles_upadjacent_to_vertex (
h5_file_t * const f,
const h5_id_t local_vid,
h5_idlist_t **list
);
h5_err_t
h5t_get_tets_upadjacent_to_vertex (
h5_file_t * const f,
const h5_id_t local_vid,
h5_idlist_t **list
);
h5_err_t
h5t_release_list_of_adjacencies (
h5_file_t * const f,
h5_idlist_t **list
);
#endif
+50 -4
View File
@@ -1,3 +1,4 @@
#include <string.h>
#include <hdf5.h>
#include "h5_core/h5_core.h"
@@ -46,8 +47,7 @@ _qsort_cmp_vertices (
/*!
Sort vertices. Store local id's in a sorted array so we can run a
binary search.
Sort vertices. Store local id's in a sorted array for binary search.
*/
h5_err_t
_h5t_sort_vertices (
@@ -297,7 +297,7 @@ _h5t_sort_elems (
int k;
h5_id_t i;
for ( k = 0; k < 2; k++ ) {
TRY( _h5_alloc_idlist ( f, &t->sorted_elems[k], num_elems ) );
TRY( _h5_alloc_idlist_items ( f, &t->sorted_elems[k], num_elems ) );
for ( i = local_eid; i < num_elems; i++ ) {
t->sorted_elems[k].items[i] = i;
}
@@ -887,7 +887,7 @@ _h5t_rebuild_elems_data (
f,
el->global_child_eid ) );
if ( local_eid > t->num_elems_on_level[level_id] ) {
if ( local_eid >= t->num_elems[level_id] ) {
level_id++;
}
el_data->level_id = level_id;
@@ -927,3 +927,49 @@ _h5t_rebuild_elems_data (
return H5_SUCCESS;
}
/*!
\param[in] f file handle
\param[in] local_id local ID of entity
\param[out] local_vids array of local vertex IDs of entity
*/
h5_err_t
h5t_get_local_vids_of_entity (
h5_file_t * const f,
h5_id_t local_id,
h5_id_t *local_vids
) {
h5t_fdata_t *t = f->t;
h5_id_t face_id = _h5t_get_face_id ( local_id );
h5_id_t local_eid = _h5t_get_elem_id ( local_id );
h5_tet_data_t *tet_dta = &t->elems_data.tets[local_eid];
switch ( _h5t_get_entity_type ( local_id ) ) {
case H5T_ELEM_TYPE_VERTEX: {
local_vids[0] = tet_dta->local_vids[face_id];
break;
}
case H5T_ELEM_TYPE_EDGE: {
int map[6][2] = { { 0,1 }, {1,2}, {0,2}, {0,3}, {1,3}, {2,3} };
local_vids[0] = tet_dta->local_vids[map[face_id][0]];
local_vids[1] = tet_dta->local_vids[map[face_id][1]];
break;
}
case H5T_ELEM_TYPE_TRIANGLE: {
int map[4][3] = { { 1,2,3 }, {0,2,3}, {0,1,3}, {0,1,2} };
local_vids[0] = tet_dta->local_vids[map[face_id][0]];
local_vids[1] = tet_dta->local_vids[map[face_id][1]];
local_vids[2] = tet_dta->local_vids[map[face_id][2]];
break;
}
case 0:
case H5T_ELEM_TYPE_TET: {
memcpy ( local_vids, tet_dta->local_vids, sizeof(h5_id_t)*4 );
break;
}
default:
return h5_error_internal (
f, __FILE__, __func__, __LINE__ );
}
return H5_SUCCESS;
}
+6
View File
@@ -75,4 +75,10 @@ h5t_get_global_triangle_id (
h5_id_t * const global_vids
);
h5_err_t
h5t_get_local_vids_of_entity (
h5_file_t * const f,
h5_id_t local_id,
h5_id_t *local_vids
);
#endif
+1 -1
View File
@@ -341,7 +341,7 @@ h5t_traverse_elems (
elem_data = (h5_element_data_t*)
&t->elems_data.tets[t->last_retrieved_eid];
local_child_eid = elem_data->local_child_eid;
refined_on_level = ( elem_data->local_child_eid >= 0 ) ?
refined_on_level = ( local_child_eid >= 0 ) ?
t->elems_data.tets[local_child_eid].level_id :
t->cur_level+1; /* this means "not refined" */
break;
+1 -1
View File
@@ -118,7 +118,7 @@ _h5t_alloc_num_vertices (
size = num_vertices * sizeof ( t->vertices_data[0] );
TRY ( t->vertices_data = _h5_alloc ( f, t->vertices_data, size ) );
TRY( _h5_alloc_idmap ( f, &t->map_vertex_g2l, num_vertices ) );
TRY( _h5_alloc_idlist ( f, &t->sorted_lvertices, num_vertices ) );
TRY( _h5_alloc_idlist_items ( f, &t->sorted_lvertices, num_vertices ) );
return H5_SUCCESS;
}
+2 -2
View File
@@ -130,7 +130,7 @@ struct h5_dtypes {
typedef struct h5_dtypes h5_dtypes_t;
struct h5_te_node_key {
h5_id_t vids[2];
h5_2id_t vids;
};
typedef struct h5_te_node_key h5_te_node_key_t;
@@ -141,7 +141,7 @@ struct h5_te_node {
typedef struct h5_te_node h5_te_node_t;
struct h5_td_node_key {
h5_id_t vids[3];
h5_3id_t vids;
};
typedef struct h5_td_node_key h5_td_node_key_t;