Files
src_old/src/h5core/h5t_map.c
T
2010-12-15 10:14:31 +00:00

329 lines
8.4 KiB
C

#include "h5core/h5_core.h"
#include "h5_core_private.h"
/*
Mapping of global to local id's:
Before adding a new level or closing the mesh, we must define global id's
for the vertices and elements. This we have to do only for the last stored
level.
*/
/*!
Compare to vertices given by their 3-dimensional coordinates
*/
static int
cmp_vertices (
h5_float64_t P0[3],
h5_float64_t P1[3]
) {
int i;
for (i = 0; i < 3; i++) {
h5_int64_t diff = h5priv_fcmp (P0[i], P1[i], 10);
if (diff < 0) return -1;
else if (diff > 0) return 1;
}
return 0;
}
/*!
Sort (small) array of local vertex indices geometrically.
*/
h5_err_t
h5tpriv_sort_local_vertex_indices (
h5_file_t* const f,
h5_loc_idx_t* const indices, /* IN/OUT: local vertex indices */
const h5_size_t size /* size of array */
) {
h5t_fdata_t* t = f->t;
h5_size_t i;
for (i = 1; i < size; ++i) {
h5_loc_idx_t idx = indices[i];
h5_size_t j = i;
while ((j >= 1 ) && cmp_vertices (
t->vertices[idx].P,
t->vertices[indices[j-1]].P
) < 0 ) {
indices[j] = indices[j-1];
--j;
}
indices[j] = idx;
}
return H5_SUCCESS;
}
/*!
Map a global vertex index to corresponding local index.
*/
h5_loc_idx_t
h5t_map_global_vertex_idx2local (
h5_file_t* const f,
const h5_glb_idx_t glb_idx
) {
if (glb_idx < 0) return -1;
h5_loc_idx_t loc_idx = h5priv_search_idxmap (&f->t->map_vertex_g2l, glb_idx);
if (loc_idx < 0)
return h5tpriv_error_global_id_nexist (f, "vertex", glb_idx);
return loc_idx;
}
h5_err_t
h5t_map_global_vertex_indices2local (
h5_file_t* const f,
const h5_glb_idx_t* const glb_indices,
const h5_size_t size,
h5_loc_idx_t* const loc_indices
) {
h5_size_t i;
for (i = 0; i < size; i++) {
TRY( (loc_indices[i] =
h5t_map_global_vertex_idx2local (f, glb_indices[i])) );
}
return H5_SUCCESS;
}
/*!
Get local element idx of element given by its global idx.
\param[in] f File handle
\param[in] glb_idx Global element index
\return Local element index or error code.
*/
h5_loc_idx_t
h5t_map_glb_elem_idx2loc (
h5_file_t* const f,
const h5_glb_idx_t glb_idx
) {
if (glb_idx < 0) return -1;
h5_loc_idx_t loc_idx = h5priv_search_idxmap (&f->t->map_elem_g2l, glb_idx);
if (loc_idx < 0)
return h5tpriv_error_global_id_nexist (f, "elem", glb_idx);
return loc_idx;
}
h5_err_t
h5t_map_glb_elem_indices2loc (
h5_file_t* const f,
const h5_glb_idx_t* glb_indices,
const h5_size_t size,
h5_loc_idx_t* loc_indices
) {
const h5_glb_idx_t* end = glb_indices+size;
while (glb_indices < end) {
TRY( (*loc_indices =
h5t_map_glb_elem_idx2loc (f, *glb_indices)) );
loc_indices++;
glb_indices++;
}
return H5_SUCCESS;
}
/*
rebuild mapping of global vertex indices to their local indices
*/
h5_err_t
h5tpriv_rebuild_vertex_indices_mapping (
h5_file_t* const f
) {
h5_debug (f, "%s()", __func__);
h5t_fdata_t* t = f->t;
if (t->num_levels <= 0) return H5_SUCCESS;
h5_loc_idx_t loc_idx = t->cur_level > 0 ? t->num_vertices[t->cur_level-1] : 0;
h5_loc_idx_t num_loc_vertices = t->num_vertices[t->num_levels-1];
h5_idxmap_el_t *item = &t->map_vertex_g2l.items[loc_idx];
for (; loc_idx < num_loc_vertices; loc_idx++, item++) {
item->glb_idx = t->vertices[loc_idx].idx;
item->loc_idx = loc_idx;
t->map_vertex_g2l.num_items++;
}
h5priv_sort_idxmap (&t->map_vertex_g2l);
return H5_SUCCESS;
}
/*
Rebuild mapping of global element indices to their local indices.
*/
h5_err_t
h5tpriv_rebuild_elem_indices_mapping (
h5_file_t* const f
) {
h5_debug (f, "%s()", __func__);
h5t_fdata_t* t = f->t;
if (t->num_levels <= 0) return H5_SUCCESS;
h5_loc_idx_t loc_idx = t->cur_level > 0 ? t->num_elems[t->cur_level-1] : 0;
h5_loc_idx_t num_loc_elems = t->num_elems[t->num_levels-1];
h5_idxmap_el_t *item = &t->map_elem_g2l.items[loc_idx];
for (; loc_idx < num_loc_elems; loc_idx++, item++) {
item->glb_idx = h5tpriv_get_glb_elem_idx (f, loc_idx);
item->loc_idx = loc_idx;
t->map_elem_g2l.num_items++;
}
h5priv_sort_idxmap (&t->map_elem_g2l);
return H5_SUCCESS;
}
h5_err_t
h5t_get_vertex_indices_of_entity (
h5_file_t* const f, // in
const h5_loc_id_t entity_id, // in
h5_loc_idx_t* vertex_indices // out
) {
static int map_entity_type_to_dimension[] = {
-1,
[H5_OID_VERTEX] = 0,
[H5_OID_EDGE] = 1,
[H5_OID_TRIANGLE] = 2,
[H5_OID_TETRAHEDRON] = 3
};
h5_loc_id_t entity_type = h5tpriv_get_entity_type (entity_id);
h5_loc_idx_t face_idx = h5tpriv_get_face_idx (entity_id);
h5_loc_idx_t elem_idx = h5tpriv_get_elem_idx (entity_id);
int dim = map_entity_type_to_dimension[entity_type];
return h5t_get_vertex_indices_of_entity2 (f, dim, face_idx, elem_idx, vertex_indices);
}
h5_err_t
h5t_get_vertex_indices_of_entity2 (
h5_file_t* const f, // [in]
const int dim, // [in] dimension
const h5_loc_idx_t face_idx, // [in] vertex index according ref. element
const h5_loc_idx_t elem_idx, // [in] local element index
h5_loc_idx_t* vertex_indices // [out]
) {
h5_loc_idx_t* indices = h5tpriv_get_loc_elem_vertex_indices (f, elem_idx);
const h5t_ref_elem_t* ref_elem = f->t->ref_elem;
int num_vertices = ref_elem->num_vertices_of_face[dim][face_idx];
int i;
for (i = 0; i < num_vertices; i++) {
int idx = ref_elem->map[dim][face_idx][i];
vertex_indices[i] = indices[idx];
}
return H5_SUCCESS;
}
h5_err_t
h5t_get_vertex_index_of_vertex (
h5_file_t* const f,
const h5_loc_id_t entity_id,
h5_loc_idx_t* vertex_index
) {
h5_loc_idx_t face_idx = h5tpriv_get_face_idx (entity_id);
h5_loc_idx_t elem_idx = h5tpriv_get_elem_idx (entity_id);
return h5t_get_vertex_index_of_vertex2 (
f, face_idx, elem_idx, vertex_index);
}
h5_err_t
h5t_get_vertex_index_of_vertex2 (
h5_file_t* const f,
const h5_loc_idx_t face_idx, // vertex index according ref. element
const h5_loc_idx_t elem_idx, // local element index
h5_loc_idx_t* vertex_indices // OUT: vertex ID's
) {
vertex_indices[0] = h5tpriv_get_loc_elem_vertex_idx (f, elem_idx, face_idx);
return H5_SUCCESS;
}
/*
Get the local ID of the vertices of an elemet.
*/
h5_err_t
h5t_get_vertex_indices_of_edge (
h5_file_t* const f,
const h5_loc_id_t entity_id,
h5_loc_idx_t* vertex_indices
) {
h5_loc_idx_t face_idx = h5tpriv_get_face_idx (entity_id);
h5_loc_idx_t elem_idx = h5tpriv_get_elem_idx (entity_id);
return h5t_get_vertex_indices_of_edge2 (
f, face_idx, elem_idx, vertex_indices);
}
/*!
Get local vertex indices of an edge. The edge is specified by the local
element index and the face number of the edge according the reference
element.
This function can be used with tetrahedral and triangle meshes.
*/
h5_err_t
h5t_get_vertex_indices_of_edge2 (
h5_file_t* const f,
const h5_loc_idx_t face_idx, // edge index according ref. element
const h5_loc_idx_t elem_idx, // local element index
h5_loc_idx_t* vertex_indices // OUT: vertex indices
) {
const h5_loc_idx_t* indices = h5tpriv_get_loc_elem_vertex_indices (f, elem_idx);
const h5t_ref_elem_t* ref_elem = f->t->ref_elem;
vertex_indices[0] = indices[ ref_elem->map[1][face_idx][0] ];
vertex_indices[1] = indices[ ref_elem->map[1][face_idx][1] ];
return H5_SUCCESS;
}
h5_err_t
h5t_get_vertex_indices_of_triangle (
h5_file_t* const f,
const h5_loc_id_t entity_id,
h5_loc_idx_t* vertex_indices
) {
h5_loc_idx_t face_idx = h5tpriv_get_face_idx (entity_id);
h5_loc_idx_t elem_idx = h5tpriv_get_elem_idx (entity_id);
return h5t_get_vertex_indices_of_triangle2 (
f, face_idx, elem_idx, vertex_indices);
}
h5_err_t
h5t_get_vertex_indices_of_triangle2 (
h5_file_t* const f,
const h5_loc_idx_t face_idx,
const h5_loc_idx_t elem_idx,
h5_loc_idx_t* vertex_indices
) {
const h5_loc_idx_t* indices = h5tpriv_get_loc_elem_vertex_indices (
f, elem_idx);
const h5t_ref_elem_t* ref_elem = f->t->ref_elem;
vertex_indices[0] = indices[ ref_elem->map[2][face_idx][0] ];
vertex_indices[1] = indices[ ref_elem->map[2][face_idx][1] ];
vertex_indices[2] = indices[ ref_elem->map[2][face_idx][2] ];
return H5_SUCCESS;
}
h5_err_t
h5t_get_vertex_indices_of_tet (
h5_file_t* const f,
const h5_loc_id_t entity_id,
h5_loc_idx_t* vertex_indices
) {
const h5_loc_idx_t elem_idx = h5tpriv_get_elem_idx (entity_id);
const h5_loc_idx_t* indices = h5tpriv_get_loc_elem_vertex_indices (
f, elem_idx);
const h5t_ref_elem_t* ref_elem = f->t->ref_elem;
vertex_indices[0] = indices[ ref_elem->map[3][0][0] ];
vertex_indices[1] = indices[ ref_elem->map[3][0][1] ];
vertex_indices[2] = indices[ ref_elem->map[3][0][2] ];
vertex_indices[3] = indices[ ref_elem->map[3][0][3] ];
return H5_SUCCESS;
}