From da80c1736d7481436617967eeb5fc32c47cbe83f Mon Sep 17 00:00:00 2001 From: Achim Gsell Date: Mon, 27 Jul 2009 15:12:34 +0000 Subject: [PATCH] binary tree replaced with hash-tables and several fixes --- src/H5Fed_map.c | 9 - src/H5Fed_map.h | 6 - src/h5_core/h5_hsearch.c | 105 +++-- src/h5_core/h5_hsearch_private.h | 49 ++- src/h5_core/h5t_adjacencies.c | 581 +++++++++++--------------- src/h5_core/h5t_adjacencies_private.h | 12 +- src/h5_core/h5t_map.c | 124 ++---- src/h5_core/h5t_map.h | 13 - src/h5_core/h5t_map_private.h | 14 + src/h5_core/h5t_retrieve.c | 9 +- src/h5_core/h5t_storemesh.c | 15 +- src/h5_core/h5t_types_private.h | 67 ++- 12 files changed, 454 insertions(+), 550 deletions(-) diff --git a/src/H5Fed_map.c b/src/H5Fed_map.c index f2d63b7..6045ecb 100644 --- a/src/H5Fed_map.c +++ b/src/H5Fed_map.c @@ -32,15 +32,6 @@ H5FedMapTet2GlobalID ( } -h5_id_t -H5FedMapTriangle2GlobalID ( - h5_file_t * const f, - h5_id_t * const global_vids - ) { - SET_FNAME ( f, __func__ ); - return h5t_get_global_triangle_id ( f, global_vids ); -} - h5_err_t H5FedMapEntity2LocalVids ( h5_file_t * const f, diff --git a/src/H5Fed_map.h b/src/H5Fed_map.h index 775575d..ee5fb70 100644 --- a/src/H5Fed_map.h +++ b/src/H5Fed_map.h @@ -25,12 +25,6 @@ H5FedMapTet2GlobalID ( h5_id_t * const global_vids ); -h5_id_t -H5FedMapTriangle2GlobalID ( - h5_file_t * const f, - h5_id_t * const global_vids - ); - h5_err_t H5FedMapEntity2LocalVids ( h5_file_t * const f, diff --git a/src/h5_core/h5_hsearch.c b/src/h5_core/h5_hsearch.c index be4ded8..3d974c1 100644 --- a/src/h5_core/h5_hsearch.c +++ b/src/h5_core/h5_hsearch.c @@ -33,7 +33,7 @@ which describes the current status. */ typedef struct _ENTRY { unsigned int used; - h5_entry_t entry; + void* entry; } _ENTRY; @@ -59,19 +59,16 @@ isprime (unsigned int number) { indexing as explained in the comment for the hsearch function. The contents of the table is zeroed, especially the field used becomes zero. */ -int -h5_hcreate_r ( +h5_err_t +_h5_hcreate_r ( h5_file_t * const f, size_t nel, - struct hsearch_data *htab + h5_hashtable_t *htab, + int (*compare)(const void*, const void*), + unsigned int (*compute_hash)(const void*) ) { /* Test for correct arguments. */ - if (htab == NULL) { - h5_error_internal ( f, __FILE__, __func__, __LINE__ ); - } - - /* There is still another table active. Return with error. */ - if (htab->table != NULL) { + if (htab == NULL || htab->table != NULL) { h5_error_internal ( f, __FILE__, __func__, __LINE__ ); } /* Change nel to the first prime number not smaller as nel. */ @@ -81,6 +78,8 @@ h5_hcreate_r ( htab->size = nel; htab->filled = 0; + htab->compare = compare; + htab->compute_hash = compute_hash; /* allocate memory and zero out */ TRY ( (htab->table = (_ENTRY *) _h5_calloc ( @@ -90,10 +89,41 @@ h5_hcreate_r ( return H5_SUCCESS; } +h5_err_t +_h5_hresize_r ( + h5_file_t * const f, + size_t nel, + h5_hashtable_t *htab + ) { + if ( htab == NULL || htab->table == NULL ) { + h5_error_internal ( f, __FILE__, __func__, __LINE__ ); + } + h5_hashtable_t __htab; + memset ( &__htab, 0, sizeof ( __htab ) ); + nel += htab->size; + h5_debug ( f, "Resize hash table from %u to %lu elements.", + htab->size, nel ); + TRY ( _h5_hcreate_r ( f, nel, &__htab, htab->compare, htab->compute_hash ) ); + unsigned int idx; + for ( idx = 1; idx <= htab->size; idx++ ) { + if ( htab->table[idx].used ) { + void *ventry; + TRY ( _h5_hsearch_r ( + f, + htab->table[idx].entry, + H5_ENTER, + &ventry, + &__htab ) ); + } + } + TRY ( _h5_hdestroy_r ( f, htab ) ); + *htab = __htab; + return H5_SUCCESS; +} /* After using the hash table it has to be destroyed. The used memory can be freed and the local static variable can be marked as not used. */ -void -h5_hdestroy_r ( +h5_err_t +_h5_hdestroy_r ( h5_file_t * const f, struct hsearch_data *htab ) { @@ -103,10 +133,11 @@ h5_hdestroy_r ( } /* Free used memory. */ - _h5_free ( f, htab->table ); + TRY ( _h5_free ( f, htab->table ) ); /* the sign for an existing table is an value != NULL in htable */ htab->table = NULL; + return H5_SUCCESS; } @@ -124,25 +155,19 @@ h5_hdestroy_r ( means used. The used field can be used as a first fast comparison for equality of the stored and the parameter value. This helps to prevent unnecessary expensive calls of strcmp. */ -int -h5_hsearch_r ( +h5_err_t +_h5_hsearch_r ( h5_file_t * const f, - h5_entry_t item, + void *item, h5_action_t action, - h5_entry_t **retval, + void **retval, struct hsearch_data *htab ) { unsigned int hval; - unsigned int count; unsigned int idx; /* Compute an value for the given string. Perhaps use a better method. */ - hval = item.len; - count = item.len; - while (count-- > 0) { - hval <<= 4; - hval += item.key[count]; - } + hval = (*htab->compute_hash)(item); /* First hash function: simply take the modul but prevent zero. */ idx = hval % htab->size + 1; @@ -151,12 +176,9 @@ h5_hsearch_r ( /* Further action might be required according to the action value. */ if (htab->table[idx].used == hval - && memcmp ( - item.key, - htab->table[idx].entry.key, - item.len ) == 0) { - *retval = &htab->table[idx].entry; - return H5_SUCCESS; + && ((*htab->compare) (item, htab->table[idx].entry) == 0) ) { + *retval = htab->table[idx].entry; + return H5_SUCCESS; } /* Second hash function, as suggested in [Knuth] */ @@ -178,11 +200,8 @@ h5_hsearch_r ( /* If entry is found use it. */ if (htab->table[idx].used == hval - && memcmp ( - item.key, - htab->table[idx].entry.key, - item.len ) == 0) { - *retval = &htab->table[idx].entry; + && ((*htab->compare) (item, htab->table[idx].entry) == 0) ) { + *retval = htab->table[idx].entry; return H5_SUCCESS; } } while (htab->table[idx].used); @@ -203,10 +222,24 @@ h5_hsearch_r ( ++htab->filled; - *retval = &htab->table[idx].entry; + *retval = htab->table[idx].entry; return H5_SUCCESS; } *retval = NULL; return H5_ERR; } + +void +_h5_hwalk_r ( + h5_file_t* f, + struct hsearch_data *htab, + void (*visit)(void *item) + ) { + unsigned int idx = 1; + for ( idx = 1; idx < htab->size; idx++ ) { + if ( htab->table[idx].used ) { + (*visit)( &htab->table[idx].entry ); + } + } +} diff --git a/src/h5_core/h5_hsearch_private.h b/src/h5_core/h5_hsearch_private.h index bee1cff..70aefe4 100644 --- a/src/h5_core/h5_hsearch_private.h +++ b/src/h5_core/h5_hsearch_private.h @@ -8,23 +8,46 @@ typedef enum { } h5_action_t; typedef struct h5_entry { - unsigned int len; - char *key; - void *data; + void *dta; } h5_entry_t; -struct hsearch_data { - struct _ENTRY *table; - unsigned int size; - unsigned int filled; -}; - /* Reentrant versions which can handle multiple hashing tables at the same time. */ -extern int hsearch_r (h5_entry_t __item, h5_action_t __action, h5_entry_t **__retval, - struct hsearch_data *__htab); -extern int hcreate_r (size_t __nel, struct hsearch_data *__htab); -extern void hdestroy_r (struct hsearch_data *__htab); +extern h5_err_t +_h5_hsearch_r ( + h5_file_t * const f, + void *item, + h5_action_t action, + void **retval, + struct hsearch_data *htab + ); +extern h5_err_t +_h5_hcreate_r ( + h5_file_t* const f, + size_t __nel, + struct hsearch_data *__htab, + int (*compare)(const void*, const void*), + unsigned int (*compute_hash)(const void*) + ); +extern h5_err_t +_h5_hresize_r ( + h5_file_t * const f, + size_t nel, + h5_hashtable_t *htab + ); + +extern h5_err_t +_h5_hdestroy_r ( + h5_file_t* f, + struct hsearch_data *__htab + ); + +extern void +_h5_hwalk_r ( + h5_file_t* f, + struct hsearch_data *__htab, + void (*visit)(void *__item) + ); #endif diff --git a/src/h5_core/h5t_adjacencies.c b/src/h5_core/h5t_adjacencies.c index 950dbca..2a6aacb 100644 --- a/src/h5_core/h5t_adjacencies.c +++ b/src/h5_core/h5t_adjacencies.c @@ -14,43 +14,16 @@ #include #include #include +#include #include #include "h5_core/h5_core.h" #include "h5_core/h5_core_private.h" -h5_id_t * -_h5t_get_edge_of_tet ( - const h5_elem_ldta_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_id_t * -_h5t_get_triangle_of_tet ( - const h5_elem_ldta_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; -} - - /* compute T(V) */ static h5_err_t -_calc_tets_of_vertices ( +_compute_tets_of_vertices ( h5_file_t * const f ) { h5t_fdata_t *t = f->t; @@ -75,247 +48,217 @@ _calc_tets_of_vertices ( } static int -_cmp_te_node ( - const void *a, - const void *b +_cmp_te_entries ( + const void *__a, + const void *__b ) { - h5_te_node_key_t *key0 = (h5_te_node_key_t*)a; - h5_te_node_key_t *key1 = (h5_te_node_key_t*)b; - - if ( key0->vids[0] < key1->vids[0] ) - return -1; - if ( key0->vids[0] > key1->vids[0] ) - return 1; - if ( key0->vids[1] < key1->vids[1] ) - return -1; - if ( key0->vids[1] > key1->vids[1] ) - return 1; - return 0; + return memcmp ( __a, __b, sizeof(h5_2id_t) ); } -static h5_err_t -_search_te2 ( +static unsigned int +_compute_te_hashval ( + const void *__item + ) { + h5_te_entry_t *item = (h5_te_entry_t*)__item; + char *key = (char *)item->key.vids; + unsigned int count = 2 * sizeof ( item->key.vids[0] ); + unsigned int hval = count; + while ( count-- > 0 ) { + if ( key[count] ) { + hval <<= 4; + hval += key[count]; + } + } + return hval; +} + +h5_err_t +_h5t_search_te2 ( h5_file_t * const f, - h5_te_node_t **node, h5_id_t face_id, - h5_id_t local_eid + h5_id_t local_eid, + h5_te_entry_t **entry + ) { h5t_fdata_t *t = f->t; h5t_adjacencies_t *a = &t->adjacencies; - void *vnode; - - h5_elem_ldta_t *tet_data = &t->elems_ldta[local_eid]; - h5_id_t vid; - int map[6][2] = { { 0,1 }, {1,2}, {0,2}, {0,3}, {1,3}, {2,3} }; - - if ( *node ==NULL ) { - TRY ( *node = _h5_alloc ( f, NULL, sizeof(**node) ) ); - memset ( *node, 0, sizeof(**node) ); + void *__retval; + if ( *entry == NULL ) { + TRY ( *entry = _h5_calloc ( f, 1, sizeof(**entry) ) ); } - 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 ( + _h5t_get_local_vids_of_edge ( + &t->elems_ldta[local_eid], + face_id, + (*entry)->key.vids ); + TRY ( _h5_hsearch_r ( f, - *node, - (void**)&a->te_tree, - _cmp_te_node ) ); - h5_te_node_t *rnode = *(h5_te_node_t **)vnode; + *entry, + H5_ENTER, + &__retval, + &a->te_hash ) ); + h5_te_entry_t *retval = (h5_te_entry_t *)__retval; TRY ( _h5_append_to_idlist ( f, - &rnode->value, + &retval->value, _h5t_build_edge_id ( face_id, local_eid ) ) ); - if ( rnode->value.num_items == 1 ) { - *node = NULL; + if ( retval->value.num_items == 1 ) { + *entry = NULL; } return H5_SUCCESS; } -h5_err_t -_h5t_find_te ( - h5_file_t * const f, - h5_te_node_t **rnode, - 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; -} - -h5_err_t -_h5t_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_elem_ldta_t *tet_data = &t->elems_ldta[local_eid]; - h5_id_t *edge = node.key.vids; - int map[6][2] = { { 0,1 }, {1,2}, {0,2}, {0,3}, {1,3}, {2,3} }; - - 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] ) { - h5_id_t vid = edge[0]; edge[0] = edge[1]; edge[1] = vid; - } - TRY ( vnode = _h5_tfind ( - f, - vnode, - (void**)&a->te_tree, - _cmp_te_node ) ); - *rnode = *(h5_te_node_t **)vnode; - - return H5_SUCCESS; -} - /* - Sort ID list according their tetrahedra ID. + Find item in the T(E) hash table. - Called by twalk(). + Passing item with type entry type. */ -static void -_sort_telist ( - const void *_node, - const VISIT order, - const int depth +h5_err_t +_h5t_find_te ( + h5_file_t * const f, + h5_te_entry_t *item, + h5_te_entry_t **retval ) { - 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 ); - } + void *__ret; + TRY ( _h5_hsearch_r ( + f, + item, + H5_FIND, + &__ret, + &f->t->adjacencies.te_hash ) ); + *retval = (h5_te_entry_t *)__ret; + return H5_SUCCESS; } +/* + Find item in the T(E) hash table. + + Passing item with face and local element ID. +*/ +h5_err_t +_h5t_find_te2 ( + h5_file_t * const f, + h5_id_t face_id, + h5_id_t local_eid, + h5_te_entry_t **retval + ) { + h5_te_entry_t item; + _h5t_get_local_vids_of_edge ( + &f->t->elems_ldta[local_eid], + face_id, + item.key.vids + ); + return _h5t_find_te ( f, &item, retval ); +} + +static void +_sort_telist ( + const void *_entry + ) { + h5_te_entry_t *entry = *(h5_te_entry_t **)_entry; + h5_idlist_t *list = &entry->value; + qsort ( + list->items, + list->num_items, + sizeof(list->items[0]), + _h5_cmp_ids_by_eid ); +} + +/* + Compute T(E) from current level up to highest levels. + */ static h5_err_t -_calc_tets_of_edges ( +_compute_tets_of_edges ( h5_file_t * const f ) { h5t_fdata_t *t = f->t; h5t_adjacencies_t *a = &t->adjacencies; - h5_id_t local_eid; - h5_size_t num_tets = t->num_elems[t->num_levels-1]; - h5_te_node_t *node = NULL; + h5_te_entry_t *entry = NULL; h5_elem_ldta_t *tet = &t->elems_ldta[0]; - h5_id_t face_id; - - a->te_tree = NULL; - - for ( local_eid = 0; local_eid < num_tets; local_eid++, tet++ ) { + h5_id_t cur_lvl = t->cur_level < 0 ? 0 : t->cur_level; + h5_id_t num_elems = t->num_elems[t->num_levels-1]; + h5_id_t local_eid = (cur_lvl == 0 ) ? 0 : t->num_elems[cur_lvl-1]; + TRY ( _h5_hcreate_r ( + f, + 5*(num_elems - local_eid), + &a->te_hash, + _cmp_te_entries, + _compute_te_hashval ) ); + for ( ; local_eid < num_elems; local_eid++, tet++ ) { + h5_id_t face_id; for ( face_id = 0; face_id < 6; face_id++ ) { - TRY ( - _search_te2 ( - f, - &node, - face_id, - local_eid ) - ); + if ( (a->te_hash.size*6) <= (a->te_hash.filled<<3) ) { + TRY ( _h5_hresize_r ( + f, + 3*(num_elems - local_eid), + &a->te_hash ) ); + } + TRY ( _h5t_search_te2 ( + f, + face_id, + local_eid, + &entry ) ); } } - twalk ( (void*)a->te_tree, _sort_telist ); - if ( node && node->value.items == NULL ) { - _h5_free ( f, node ); + _h5_hwalk_r ( f, &a->te_hash, _sort_telist ); + if ( entry && entry->value.items == NULL ) { + _h5_free ( f, entry ); } return H5_SUCCESS; } static int -_cmp_td_node ( - const void *a, - const void *b +_cmp_td_entries ( + const void *__a, + const void *__b ) { - h5_td_node_key_t *key0 = (h5_td_node_key_t*)a; - h5_td_node_key_t *key1 = (h5_td_node_key_t*)b; - - if ( key0->vids[0] < key1->vids[0] ) - return -1; - if ( key0->vids[0] > key1->vids[0] ) - return 1; - if ( key0->vids[1] < key1->vids[1] ) - return -1; - if ( key0->vids[1] > key1->vids[1] ) - return 1; - if ( key0->vids[2] < key1->vids[2] ) - return -1; - if ( key0->vids[2] > key1->vids[2] ) - return 1; - return 0; + return memcmp ( __a, __b, sizeof(h5_3id_t) ); } -static h5_err_t -_search_td2 ( - h5_file_t * const f, - h5_td_node_t **node, - h5_id_t face_id, - h5_id_t local_eid +static unsigned int +_compute_td_hashval ( + const void *__item ) { - h5t_fdata_t *t = f->t; - h5t_adjacencies_t *a = &t->adjacencies; - void *vnode; - - h5_elem_ldta_t *tet_data = &t->elems_ldta[local_eid]; - h5_id_t vid; - int map[4][3] = { { 1,2,3 }, {0,2,3}, {0,1,3}, {0,1,2} }; - - if ( *node ==NULL ) { - TRY ( *node = _h5_alloc ( f, NULL, sizeof(**node) ) ); - memset ( *node, 0, sizeof(**node) ); + h5_te_entry_t *item = (h5_te_entry_t*)__item; + char *key = (char *)item->key.vids; + unsigned int count = sizeof ( h5_3id_t ); + unsigned int hval = count; + while ( count-- > 0 ) { + if ( key[count] ) { + hval <<= 4; + hval += key[count]; + } } - 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]]; + return hval; +} - if ( triangle[0] > triangle[1] ) { - vid = triangle[0]; triangle[0] = triangle[1]; triangle[1] = vid; +h5_err_t +_h5t_search_td2 ( + h5_file_t * const f, + h5_id_t face_id, + h5_id_t local_eid, + h5_td_entry_t **entry + ) { + void *__retval; + if ( *entry == NULL ) { + TRY ( *entry = _h5_calloc ( f, 1, sizeof(**entry) ) ); } - 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 ( + _h5t_get_local_vids_of_triangle ( + &f->t->elems_ldta[local_eid], + face_id, + (*entry)->key.vids ); + TRY ( _h5_hsearch_r ( f, - *node, - (void**)&a->td_tree, - _cmp_td_node ) ); - h5_td_node_t *rnode = *(h5_td_node_t **)vnode; + *entry, + H5_ENTER, + &__retval, + &f->t->adjacencies.td_hash ) ); + h5_td_entry_t *retval = (h5_td_entry_t *)__retval; TRY ( _h5_append_to_idlist ( f, - &rnode->value, + &retval->value, _h5t_build_triangle_id ( face_id, local_eid ) ) ); - if ( rnode->value.num_items == 1 ) { - *node = NULL; + if ( retval->value.num_items == 1 ) { + *entry = NULL; } return H5_SUCCESS; } @@ -323,78 +266,36 @@ _search_td2 ( h5_err_t _h5t_find_td ( h5_file_t * const f, - h5_td_node_t **rnode, - h5_3id_t tri + h5_td_entry_t *item, + h5_td_entry_t **retval ) { - h5t_fdata_t *t = f->t; - h5t_adjacencies_t *a = &t->adjacencies; - h5_td_node_t node; - void *vnode = &node; - - 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; - } - memcpy ( node.key.vids, tri, 3*sizeof(*tri) ); - vnode = _h5_tfind ( + void *__ret; + _h5_hsearch_r ( f, - vnode, - (void**)&a->td_tree, - _cmp_td_node ); - if ( (h5_err_t)(ptrdiff_t)(vnode) == H5_ERR ) { - return _h5t_error_local_triangle_nexist( f, tri ); + item, + H5_FIND, + &__ret, + &f->t->adjacencies.td_hash ); + if ( __ret == NULL ) { + return _h5t_error_local_triangle_nexist( f, item->key.vids ); } - - *rnode = *(h5_td_node_t **)vnode; - + *retval = (h5_td_entry_t *)__ret; return H5_SUCCESS; } h5_err_t _h5t_find_td2 ( h5_file_t * const f, - h5_td_node_t **rnode, h5_id_t face_id, - h5_id_t local_eid + h5_id_t local_eid, + h5_td_entry_t **retval ) { - h5t_fdata_t *t = f->t; - h5t_adjacencies_t *a = &t->adjacencies; - h5_td_node_t node; - void *vnode = &node; - - h5_elem_ldta_t *tet_data = &t->elems_ldta[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; - } - vnode = _h5_tfind ( - f, - vnode, - (void**)&a->td_tree, - _cmp_td_node ); - if ( (h5_err_t)(ptrdiff_t)(vnode) == H5_ERR ) { - return _h5t_error_local_triangle_nexist( f, tri ); - } - - *rnode = *(h5_td_node_t **)vnode; - - return H5_SUCCESS; + h5_td_entry_t item; + _h5t_get_local_vids_of_triangle ( + &f->t->elems_ldta[local_eid], + face_id, + item.key.vids ); + return _h5t_find_td ( f, &item, retval ); } /* @@ -404,52 +305,57 @@ _h5t_find_td2 ( */ static void _sort_tdlist ( - const void *_node, - const VISIT order, - const int depth + const void *_entry ) { - 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 ); - } + h5_td_entry_t *entry = *(h5_td_entry_t **)_entry; + h5_idlist_t *list = &entry->value; + qsort ( + list->items, + list->num_items, + sizeof(list->items[0]), + _h5_cmp_ids_by_eid ); } static h5_err_t -_calc_tets_of_triangles ( +_compute_tets_of_triangles ( h5_file_t * const f ) { h5t_fdata_t *t = f->t; h5t_adjacencies_t *a = &t->adjacencies; - h5_id_t local_eid; - h5_size_t num_tets = t->num_elems[t->num_levels-1]; - h5_td_node_t *node = NULL; + h5_td_entry_t *entry = NULL; h5_elem_ldta_t *tet = &t->elems_ldta[0]; - h5_id_t face_id; - - a->td_tree = NULL; - - for ( local_eid = 0; local_eid < num_tets; local_eid++, tet++ ) { + h5_id_t cur_lvl = t->cur_level < 0 ? 0 : t->cur_level; + h5_size_t num_elems = t->num_elems[t->num_levels-1]; + h5_id_t local_eid = (cur_lvl == 0 ) ? 0 : t->num_elems[cur_lvl-1]; + TRY ( _h5_hcreate_r ( + f, + 5*(num_elems-local_eid), + &a->td_hash, + _cmp_td_entries, + _compute_td_hashval ) ); + for ( ; local_eid < num_elems; local_eid++, tet++ ) { + h5_id_t face_id; for ( face_id = 0; face_id < 4; face_id++ ) { + if ( (a->td_hash.size*6) <= (a->td_hash.filled<<3) ) { + TRY ( _h5_hresize_r ( + f, + 3*(num_elems-local_eid), + &a->td_hash ) ); + } TRY ( - _search_td2 ( + _h5t_search_td2 ( f, - &node, face_id, - local_eid ) + local_eid, + &entry ) ); } } - twalk ( (void*)a->td_tree, _sort_tdlist ); - if ( node && node->value.items == NULL ) { - _h5_free ( f, node ); + _h5_hwalk_r ( f, &a->td_hash, _sort_tdlist ); + if ( entry && entry->value.items == NULL ) { + _h5_free ( f, entry ); } - return H5_SUCCESS; } @@ -457,9 +363,21 @@ h5_err_t _h5t_rebuild_adj_data ( h5_file_t * const f ) { - TRY ( _calc_tets_of_vertices ( f ) ); - TRY ( _calc_tets_of_edges ( f ) ); - TRY ( _calc_tets_of_triangles ( f ) ); + clock_t t1 = clock(); + TRY ( _compute_tets_of_vertices ( f ) ); + clock_t t2 = clock(); + fprintf ( stderr, "_compute_tets_of_vertices(): %f\n", + (float)(t2-t1)/CLOCKS_PER_SEC ); + t1 = clock(); + TRY ( _compute_tets_of_edges ( f ) ); + t2 = clock(); + fprintf ( stderr, "_compute_tets_of_edge(): %f\n", + (float)(t2-t1)/CLOCKS_PER_SEC ); + t1 = clock(); + TRY ( _compute_tets_of_triangles ( f ) ); + t2 = clock(); + fprintf ( stderr, "_compute_tets_of_triangle(): %f\n", + (float)(t2-t1)/CLOCKS_PER_SEC ); return H5_SUCCESS; } @@ -495,13 +413,13 @@ _compute_children_of_edge ( h5_idlist_t *children ) { h5t_fdata_t *t = f->t; - h5_te_node_t *te; + h5_te_entry_t *te; TRY ( _h5t_find_te2 ( f, - &te, _h5t_get_face_id ( local_kid ), - _h5t_get_elem_id ( local_kid ) ) + _h5t_get_elem_id ( local_kid ), + &te ) ); h5_id_t *edge = te->value.items; h5_id_t *end = te->value.items+te->value.num_items; @@ -539,13 +457,13 @@ _compute_sections_of_edge ( h5_idlist_t *children ) { h5t_fdata_t *t = f->t; - h5_te_node_t *te; + h5_te_entry_t *te; TRY ( _h5t_find_te2 ( f, - &te, _h5t_get_face_id ( local_kid ), - _h5t_get_elem_id ( local_kid ) ) + _h5t_get_elem_id ( local_kid ), + &te ) ); h5_id_t *edge = te->value.items; h5_id_t *end = te->value.items+te->value.num_items; @@ -601,14 +519,14 @@ _compute_children_of_triangle ( ) { h5t_fdata_t *t = f->t; - h5_td_node_t *td; + h5_td_entry_t *td; TRY ( _h5t_find_td2 ( f, - &td, _h5t_get_face_id ( local_did ), - _h5t_get_elem_id ( local_did ) ) - ); + _h5t_get_elem_id ( local_did ), + &td + ) ); h5_id_t *tri = td->value.items; h5_id_t *end = td->value.items+td->value.num_items; for ( ; tri < end; tri++ ) { @@ -646,14 +564,12 @@ _compute_sections_of_triangle ( h5_idlist_t *children ) { h5t_fdata_t *t = f->t; - h5_td_node_t *td; + h5_td_entry_t *td; TRY ( _h5t_find_td2 ( f, - &td, _h5t_get_face_id ( local_did ), - _h5t_get_elem_id ( local_did ) ) - ); + _h5t_get_elem_id ( local_did ), &td ) ); h5_id_t *tri = td->value.items; h5_id_t *end = td->value.items+td->value.num_items; int refined = 0; @@ -696,10 +612,9 @@ _add_edge ( h5_id_t face_id, h5_id_t local_eid ) { - h5_te_node_t *te; - TRY ( _h5t_find_te2 ( f, &te, face_id, local_eid ) ); + h5_te_entry_t *te; + TRY ( _h5t_find_te2 ( f, face_id, local_eid, &te ) ); TRY ( _h5_search_idlist ( f, list, te->value.items[0] ) ); - return H5_SUCCESS; } @@ -740,8 +655,8 @@ _add_triangle ( h5_id_t face_id, h5_id_t local_eid ) { - h5_td_node_t *td; - TRY ( _h5t_find_td2 ( f, &td, face_id, local_eid ) ); + h5_td_entry_t *td; + TRY ( _h5t_find_td2 ( f, face_id, local_eid, &td ) ); TRY ( _h5_search_idlist ( f, list, td->value.items[0] ) ); return H5_SUCCESS; diff --git a/src/h5_core/h5t_adjacencies_private.h b/src/h5_core/h5t_adjacencies_private.h index d37d50b..ad18a78 100644 --- a/src/h5_core/h5t_adjacencies_private.h +++ b/src/h5_core/h5t_adjacencies_private.h @@ -9,23 +9,23 @@ _h5t_rebuild_adj_data ( h5_err_t _h5t_find_te2 ( h5_file_t * const f, - h5_te_node_t **rnode, h5_id_t face_id, - h5_id_t local_eid + h5_id_t local_eid, + h5_te_entry_t **retval ); h5_err_t _h5t_find_td ( h5_file_t * const f, - h5_td_node_t **rnode, - h5_3id_t tri + h5_td_entry_t *item, + h5_td_entry_t **retval ); h5_err_t _h5t_find_td2 ( h5_file_t * const f, - h5_td_node_t **rnode, h5_id_t face_id, - h5_id_t local_eid + h5_id_t local_eid, + h5_td_entry_t **rentry ); #endif diff --git a/src/h5_core/h5t_map.c b/src/h5_core/h5t_map.c index 3b2d775..f378882 100644 --- a/src/h5_core/h5t_map.c +++ b/src/h5_core/h5t_map.c @@ -441,85 +441,6 @@ h5t_get_global_eid ( return h5t_map_local_eid2global ( f, local_eid ); } -/*! - - */ -h5_id_t -h5t_get_global_triangle_id ( - h5_file_t * const f, - h5_id_t * const global_vids - ) { - struct h5t_fdata *t = f->t; - - switch ( t->mesh_type ) { - case H5_OID_TETRAHEDRON: { - h5_id_t local_vids[3]; - TRY ( h5t_map_global_vids2local ( - f, global_vids, 3, local_vids ) ); - h5_id_t local_tid = h5t_get_local_triangle_id ( f, local_vids ); - if ( local_tid < 0 ) - return _h5t_error_global_triangle_id_nexist ( - f, global_vids ); - return h5t_map_local_triangle_id2global ( f, local_tid ); - } - case H5_OID_TRIANGLE: - return h5t_get_global_eid ( f, global_vids ); - default: - return h5_error_internal ( f, __FILE__, __func__, __LINE__ ); - } -} - -/*! - - */ -h5_id_t -h5t_get_local_triangle_id ( - h5_file_t * const f, - h5_id_t * const local_vids - ) { - h5t_fdata_t *t = f->t; - - switch ( t->mesh_type ) { - case H5_OID_TETRAHEDRON: { - h5_td_node_t *td; - TRY ( _h5t_find_td ( - f, - &td, - local_vids ) ); - return td->value.items[0]; - } - case H5_OID_TRIANGLE: - return h5t_get_local_eid ( f, local_vids ); - default: - return h5_error_internal ( f, __FILE__, __func__, __LINE__ ); - } -} - -h5_id_t -h5t_get_local_triangle_id2 ( - h5_file_t * const f, - h5_id_t face_id, - h5_id_t local_eid - ) { - h5t_fdata_t *t = f->t; - - switch ( t->mesh_type ) { - case H5_OID_TETRAHEDRON: { - h5_td_node_t *td; - TRY ( _h5t_find_td2 ( - f, - &td, - face_id, - local_eid) ); - return td->value.items[0]; - } - case H5_OID_TRIANGLE: - return local_eid; - default: - return h5_error_internal ( f, __FILE__, __func__, __LINE__ ); - } -} - /*! Get local element id for an element given by its global id. @@ -643,6 +564,33 @@ _h5t_rebuild_global_2_local_map_of_elems ( return H5_SUCCESS; } +h5_id_t * +_h5t_get_local_vids_of_edge ( + const h5_elem_ldta_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_id_t * +_h5t_get_local_vids_of_triangle ( + const h5_elem_ldta_t *tet, + const h5_id_t face_id, + h5_id_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; +} + /*! \param[in] f file handle \param[in] local_id local ID of entity @@ -662,31 +610,25 @@ h5t_get_local_vids_of_entity ( switch ( _h5t_get_entity_type ( local_id ) ) { case H5T_ELEM_TYPE_VERTEX: { local_vids[0] = tet_dta->local_vids[face_id]; - break; + return H5_SUCCESS; } 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; + _h5t_get_local_vids_of_edge (tet_dta, face_id, local_vids); + return H5_SUCCESS; } 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; + _h5t_get_local_vids_of_triangle (tet_dta, face_id, local_vids); + return H5_SUCCESS; } case 0: case H5T_ELEM_TYPE_TET: { memcpy ( local_vids, tet_dta->local_vids, sizeof(h5_id_t)*4 ); - break; + return H5_SUCCESS; } default: return h5_error_internal ( f, __FILE__, __func__, __LINE__ ); } - return H5_SUCCESS; } h5_id_t diff --git a/src/h5_core/h5t_map.h b/src/h5_core/h5t_map.h index 876965e..4325921 100644 --- a/src/h5_core/h5t_map.h +++ b/src/h5_core/h5t_map.h @@ -63,19 +63,6 @@ h5t_get_global_eid ( const h5_id_t * const global_vids ); -h5_id_t -h5t_get_local_triangle_id ( - h5_file_t * const f, - h5_id_t * const local_vids - ); - -h5_id_t -h5t_get_local_triangle_id2 ( - h5_file_t * const f, - h5_id_t face_id, - h5_id_t local_eid - ); - h5_id_t h5t_get_global_triangle_id ( h5_file_t * const f, diff --git a/src/h5_core/h5t_map_private.h b/src/h5_core/h5t_map_private.h index fa3030f..30640d6 100644 --- a/src/h5_core/h5t_map_private.h +++ b/src/h5_core/h5t_map_private.h @@ -35,4 +35,18 @@ _h5t_rebuild_global_2_local_map_of_elems ( h5_file_t * const f ); +h5_id_t * +_h5t_get_local_vids_of_edge ( + const h5_elem_ldta_t *tet, + const h5_id_t face_id, + h5_2id_t edge + ); + +h5_id_t * +_h5t_get_local_vids_of_triangle ( + const h5_elem_ldta_t *tet, + const h5_id_t face_id, + h5_2id_t tri + ); + #endif diff --git a/src/h5_core/h5t_retrieve.c b/src/h5_core/h5t_retrieve.c index bd28307..6c45fc1 100644 --- a/src/h5_core/h5t_retrieve.c +++ b/src/h5_core/h5t_retrieve.c @@ -113,7 +113,7 @@ h5t_traverse_edges ( ) { h5t_fdata_t *t = f->t; h5t_entity_iterator_t *iter = &t->iters.edge; - h5_te_node_t *te; + h5_te_entry_t *te; h5_size_t i; do { if ( iter->cur_fid >= 5 ) { @@ -128,7 +128,7 @@ h5t_traverse_edges ( iter->cur_fid++; } TRY ( _h5t_find_te2 ( - f, &te, iter->cur_fid, iter->cur_eid ) ); + f, iter->cur_fid, iter->cur_eid, &te ) ); /* skip to first element which is on current level */ i = -1; h5_elem_ldta_t *el_dta; @@ -175,7 +175,7 @@ h5t_traverse_triangles ( ) { h5t_fdata_t *t = f->t; h5t_entity_iterator_t *iter = &t->iters.triangle; - h5_td_node_t *td; + h5_td_entry_t *td; h5_size_t i; do { if ( iter->cur_fid >= 3 ) { @@ -189,8 +189,7 @@ h5t_traverse_triangles ( } else { iter->cur_fid++; } - TRY ( _h5t_find_td2 ( - f, &td, iter->cur_fid, iter->cur_eid ) ); + TRY ( _h5t_find_td2 ( f, iter->cur_fid, iter->cur_eid, &td ) ); /* skip to first element which is on current level */ i = -1; h5_elem_ldta_t *el_dta; diff --git a/src/h5_core/h5t_storemesh.c b/src/h5_core/h5t_storemesh.c index 3837166..5fef0f5 100644 --- a/src/h5_core/h5t_storemesh.c +++ b/src/h5_core/h5t_storemesh.c @@ -231,7 +231,7 @@ _h5t_alloc_num_elems ( h5t_fdata_t *t = f->t; size_t sizeof_elem = _h5t_sizeof_elem[t->mesh_type]; - /* allocl mem for elements */ + /* alloc mem for elements */ TRY ( t->elems.data = _h5_alloc ( f, t->elems.data, @@ -257,7 +257,7 @@ _h5t_alloc_num_elems ( t->elems_lvids, new_num_elems*sizeof(t->elems_lvids[0])*t->mesh_type ) ); memset ( - (void*)t->elems_lvids + cur_num_elems*sizeof(t->elems_lvids[0])*t->mesh_type, + t->elems_lvids + cur_num_elems*sizeof(t->elems_lvids[0])*t->mesh_type, -1, (new_num_elems-cur_num_elems)*sizeof(t->elems_lvids[0])*t->mesh_type ); @@ -359,7 +359,6 @@ _h5t_store_elem ( memcpy ( elem_ldta->local_vids, local_vids, sizeof (*local_vids) * t->mesh_type ); _h5t_sort_local_vids ( f, elem_ldta->local_vids, t->mesh_type ); - return local_eid; } @@ -374,7 +373,6 @@ h5t_end_store_elems ( TRY ( _assign_global_elem_ids ( f ) ); TRY ( _h5t_sort_elems ( f ) ); TRY ( _h5t_rebuild_global_2_local_map_of_elems ( f ) ); - return H5_SUCCESS; } @@ -562,6 +560,15 @@ _h5t_refine_tet ( local_vids[1] = t->elems_ldta[local_eid].local_vids[1]; local_vids[2] = t->elems_ldta[local_eid].local_vids[2]; local_vids[3] = t->elems_ldta[local_eid].local_vids[3]; + + /* + get adjacent tets to the edges we have to refine + if one of the tets have been refined + get vertex id + else + add new vertex + */ + local_vids[4] = _h5t_bisect_edge( f, t->elems_ldta[local_eid].local_vids[0], diff --git a/src/h5_core/h5t_types_private.h b/src/h5_core/h5t_types_private.h index 895847c..50e3663 100644 --- a/src/h5_core/h5t_types_private.h +++ b/src/h5_core/h5t_types_private.h @@ -94,7 +94,7 @@ struct boundary { typedef struct boundary boundary_t; /*** type ids' for compound types ***/ -struct h5_dtypes { +typedef struct h5_dtypes { hid_t h5_id_t; hid_t h5_int64_t; hid_t h5_float64_t; @@ -104,61 +104,60 @@ struct h5_dtypes { hid_t h5_vertex_t; /* vertex structure */ hid_t h5_triangle_t; /* triangle structure */ hid_t h5_tet_t; /* tetrahedron structure */ -}; -typedef struct h5_dtypes h5_dtypes_t; +} h5_dtypes_t; -struct h5_te_node_key { +typedef struct h5_te_entry_key { h5_2id_t vids; -}; -typedef struct h5_te_node_key h5_te_node_key_t; +} h5_te_entry_key_t; -struct h5_te_node { - h5_te_node_key_t key; +typedef struct h5_te_entry { + h5_te_entry_key_t key; h5_idlist_t value; -}; -typedef struct h5_te_node h5_te_node_t; +} h5_te_entry_t; -struct h5_td_node_key { +typedef struct h5_td_entry_key { h5_3id_t vids; -}; -typedef struct h5_td_node_key h5_td_node_key_t; +} h5_td_entry_key_t; -struct h5_td_node { - h5_td_node_key_t key; +typedef struct h5_td_entry { + h5_td_entry_key_t key; h5_idlist_t value; -}; -typedef struct h5_td_node h5_td_node_t; +} h5_td_entry_t; -struct h5t_adjacencies { - void * te_tree; - void * td_tree; +struct hsearch_data { + struct _ENTRY *table; + unsigned int size; + unsigned int filled; + int (*compare)(const void*, const void*); + unsigned int (*compute_hash)(const void*); }; -typedef struct h5t_adjacencies h5t_adjacencies_t; +typedef struct hsearch_data h5_hashtable_t; + +typedef struct h5t_adjacencies { + struct hsearch_data te_hash; + struct hsearch_data td_hash; +} h5t_adjacencies_t; struct h5t_elem_iterator { h5_id_t cur_eid; }; typedef struct h5t_elem_iterator h5t_elem_iterator_t; -struct h5t_vertex_iterator { +typedef struct h5t_vertex_iterator { h5_id_t cur_vid; -}; -typedef struct h5t_vertex_iterator h5t_vertex_iterator_t; +} h5t_vertex_iterator_t; -struct h5t_entity_iterator { +typedef struct h5t_entity_iterator { h5_id_t cur_fid; h5_id_t cur_eid; -}; -typedef struct h5t_entity_iterator h5t_entity_iterator_t; +} h5t_entity_iterator_t; -struct h5t_iterators { +typedef struct h5t_iterators { h5t_vertex_iterator_t vertex; h5t_entity_iterator_t edge; h5t_entity_iterator_t triangle; h5t_elem_iterator_t elem; -}; - -typedef struct h5t_iterators h5t_iterators_t; +} h5t_iterators_t; struct h5t_fdata { /*** book-keeping ***/ @@ -175,15 +174,15 @@ struct h5t_fdata { h5_id_t level_changed; h5_id_t storing_data; - hid_t topo_gid; /* grp id of mesh in current - level */ + hid_t topo_gid; /* grp id of mesh in current + level */ hid_t meshes_gid; hid_t mesh_gid; /*** type ids' for base & compound data types ***/ h5_dtypes_t dtypes; - h5t_iterators_t iters; + h5t_iterators_t iters; /* "build-in" iterators */ /*** vertices ***/ h5_vertex_t *vertices;