diff --git a/src/C/H5Fed_store.c b/src/C/H5Fed_store.c index 26a19cc..937044b 100644 --- a/src/C/H5Fed_store.c +++ b/src/C/H5Fed_store.c @@ -146,11 +146,10 @@ H5FedEndStoreElements ( h5_err_t H5FedBeginRefineElements ( - h5_file_t * const f, - const h5_size_t num + h5_file_t * const f ) { SET_FNAME ( f, __func__ ); - return h5t_begin_refine_elems ( f, num ); + return h5t_begin_refine_elems ( f ); } h5_id_t diff --git a/src/h5core/h5t_openclose.c b/src/h5core/h5t_openclose.c index 51480d5..4156384 100644 --- a/src/h5core/h5t_openclose.c +++ b/src/h5core/h5t_openclose.c @@ -237,7 +237,6 @@ _init_fdata ( t->topo_gid = -1; t->meshes_gid = -1; t->mesh_gid = -1; - t->num_boundaries = -1; /* vertices */ strcpy( t->dsinfo_vertices.name, "Vertices" ); diff --git a/src/h5core/h5t_storemesh.c b/src/h5core/h5t_storemesh.c index c3ea1af..c42db95 100644 --- a/src/h5core/h5t_storemesh.c +++ b/src/h5core/h5t_storemesh.c @@ -314,63 +314,127 @@ h5t_end_store_elems ( return H5_SUCCESS; } - +/* + Mark entity for further processing (e.g. refinement). + */ h5_err_t -h5t_begin_refine_elems ( - h5_file_t * const f, - const h5_size_t num_elems_to_refine +h5t_mark_entity ( + h5_file_t* const f, + const h5_id_t entity_id ) { - h5_size_t num_elems_to_add = 0; - h5_size_t num_vertices_to_add = 0; + h5t_fdata_t* t = f->t; + return h5priv_append_to_idlist (f, &t->marked_entities, entity_id); +} - f->t->storing_data = 1; - /* - Now we have to guess the number of vertices ... - If we are going to refine one tetrahedron, we have 8 new tetrahedra - and 6 new vertices. Thus the numbers below are definitely upper - limits! - */ - switch ( f->t->mesh_type ) { +/* + When calling this function, we know the number of elements to refine. But + we don't now the number of new vertices we will get. We have to compute + this number or just to guess it. + + Let n be the number of elements to refine and l the number of disconnected + areas to be refined. + + For triangle grids the upper limit of new vertices is 3n and the lower limit + 2n + 1. The exact number is 2n + l. + + For tetrahedral grids the upper limit is 6n and the lower limit is 3n+3. + The exact number is 3n + 3l. + + To get the real number of vertices to add, we either have to compute the + number of disconnected areas (which is quiet expensive), try to guess it + (which is impossible) or just set a limit. In most cases the number of + disconnected areas will be "small". + + For the time being we set the maximum number of disconnected areas to 64. + */ +h5_err_t +h5t_pre_refine ( + h5_file_t* const f + ) { + h5t_fdata_t* t = f->t; + unsigned int num_elems_to_refine = t->marked_entities.num_items; + unsigned int num_elems_to_add = 0; + unsigned int num_vertices_to_add = 0; + + switch (t->mesh_type) { case H5_OID_TETRAHEDRON: - num_vertices_to_add = num_elems_to_refine*6; + num_vertices_to_add = num_elems_to_refine*3 + 192; num_elems_to_add = num_elems_to_refine*8; break; case H5_OID_TRIANGLE: - num_vertices_to_add = num_elems_to_refine*3; + num_vertices_to_add = num_elems_to_refine*2 + 64; num_elems_to_add = num_elems_to_refine*4; break; default: - return h5_error_internal ( f, __FILE__, __func__, __LINE__ ); + return h5_error_internal (f, __FILE__, __func__, __LINE__); } - TRY ( h5t_begin_store_vertices ( f, num_vertices_to_add ) ); - TRY ( h5t_begin_store_elems ( f, num_elems_to_add ) ); + t->storing_data = 1; + TRY( h5t_begin_store_vertices (f, num_vertices_to_add) ); + TRY( h5t_begin_store_elems (f, num_elems_to_add) ); return H5_SUCCESS; } +/* + Refine previously marked elements. +*/ +h5_err_t +h5t_refine ( + h5_file_t* const f + ) { + h5t_fdata_t* t = f->t; + t->storing_data = 1; + int i; + for (i = 0; i < t->marked_entities.num_items; i++) { + TRY( h5t_refine_elem (f, t->marked_entities.items[i]) ); + } + return H5_SUCCESS; +} + +h5_err_t +h5t_post_refine ( + h5_file_t* const f + ) { + h5t_fdata_t* t = f->t; + return h5priv_free_idlist_items (f, &t->marked_entities); +} + + +h5_err_t +h5t_begin_refine_elems ( + h5_file_t* const f + ) { + h5t_fdata_t* const t = f->t; + + /* + Pre-allocate space for items to avoid allocating small pieces of + memory. + */ + TRY( h5priv_alloc_idlist_items (f, &t->marked_entities, 2048) ); + return H5_SUCCESS; +} + /*! - Refine element \c local_eid + Refine element \c elem_id. Actually we set a mark only ... \return local id of first new element or \c -1 */ h5_id_t h5t_refine_elem ( - h5_file_t * const f, - const h5_id_t local_eid + h5_file_t* const f, + const h5_id_t elem_id ) { - return (*f->t->methods.store->refine_elem)( f, local_eid ); + return h5t_mark_entity (f, elem_id); } h5_err_t h5t_end_refine_elems ( - h5_file_t * const f + h5_file_t* const f ) { - h5t_fdata_t *t = f->t; - t->storing_data = 0; - - TRY ( h5t_end_store_vertices ( f ) ); - TRY ( h5t_end_store_elems ( f ) ); + TRY( h5t_pre_refine (f) ); + TRY( h5t_refine (f) ); + TRY( h5t_post_refine (f) ); return H5_SUCCESS; } diff --git a/src/h5core/h5t_types_private.h b/src/h5core/h5t_types_private.h index 2e1cf26..69c5aff 100644 --- a/src/h5core/h5t_types_private.h +++ b/src/h5core/h5t_types_private.h @@ -187,11 +187,16 @@ typedef struct h5t_fdata { h5_dsinfo_t dsinfo_num_elems; h5_dsinfo_t dsinfo_num_elems_on_level; + h5_idlist_t marked_entities; + +#if 0 /*** Boundary Meshes ***/ h5_id_t num_boundaries; /* number of boundaries */ h5_id_t boundaries_gid; /* hdf5 grp id container group */ boundary_t boundary; +#endif + /*** Adjacencies ***/ h5t_adjacencies_t adjacencies; /*** Tags ***/ diff --git a/src/include/H5Fed_store.h b/src/include/H5Fed_store.h index 5a0a0ac..1a33bf3 100644 --- a/src/include/H5Fed_store.h +++ b/src/include/H5Fed_store.h @@ -68,8 +68,7 @@ H5FedEndStoreElements ( h5_err_t H5FedBeginRefineElements ( - h5_file_t * const f, - const h5_size_t num + h5_file_t * const f ); h5_id_t diff --git a/src/include/h5core/h5t_storemesh.h b/src/include/h5core/h5t_storemesh.h index dc1e274..ecc6f2a 100644 --- a/src/include/h5core/h5t_storemesh.h +++ b/src/include/h5core/h5t_storemesh.h @@ -50,8 +50,7 @@ h5t_end_store_elems ( h5_err_t h5t_begin_refine_elems ( - h5_file_t * const f, - const h5_size_t num_elems_to_refine + h5_file_t * const f ); h5_id_t diff --git a/test/H5Fed/tetmesh_write.c b/test/H5Fed/tetmesh_write.c index 277945a..d05dc82 100644 --- a/test/H5Fed/tetmesh_write.c +++ b/test/H5Fed/tetmesh_write.c @@ -68,13 +68,13 @@ main ( /* add 1. Level */ H5FedAddLevel(f); - H5FedBeginRefineElements (f, 1); + H5FedBeginRefineElements (f); H5FedRefineElement (f, 0); H5FedEndRefineElements (f); /* add 2. Level */ H5FedAddLevel(f); - H5FedBeginRefineElements (f, 1); + H5FedBeginRefineElements (f); H5FedRefineElement (f, 2); H5FedEndRefineElements (f); diff --git a/test/H5Fed/tetmesh_write2.c b/test/H5Fed/tetmesh_write2.c index fd7ad5d..bba5386 100644 --- a/test/H5Fed/tetmesh_write2.c +++ b/test/H5Fed/tetmesh_write2.c @@ -82,7 +82,7 @@ main ( /* add 1. Level */ H5FedAddLevel(f); - H5FedBeginRefineElements (f, 1); + H5FedBeginRefineElements (f); H5FedRefineElement (f, 0); H5FedEndRefineElements (f); @@ -94,7 +94,7 @@ main ( /* refine 4 to the power of level_id-1 elems */ h5_id_t level_id = H5FedAddLevel(f); h5_int32_t num_elems2refine = power (4, level_id-1); - H5FedBeginRefineElements (f, num_elems2refine); + H5FedBeginRefineElements (f); for (i = num_elems_last_level; i < num_elems_last_level+num_elems2refine; i++) { diff --git a/test/H5Fed/trimesh_write.c b/test/H5Fed/trimesh_write.c index 6a96748..1aaf058 100644 --- a/test/H5Fed/trimesh_write.c +++ b/test/H5Fed/trimesh_write.c @@ -63,7 +63,7 @@ main ( /* add 1. Level */ H5FedAddLevel(f); - H5FedBeginRefineElements (f, 1); + H5FedBeginRefineElements (f); H5FedRefineElement (f, 0); H5FedEndRefineElements (f);