static int check_valid_tag( int tag_idx, mhdf_FileHandle file, struct mhdf_FileDesc* desc ) { long *ids = 0, count, junk; long *ranges; int nranges; hid_t handles[3]; mhdf_Status status; const struct mhdf_TagDesc* tag = &(desc->tags[tag_idx]); int i, result = 0; long srange[2]; const char* name; struct mhdf_EntDesc* group; hid_t h5type; hsize_t size; if (tag->have_sparse) { mhdf_openSparseTagData( file, tag->name, &count, &junk, handles, &status ); if (mhdf_isError(&status)) { fprintf(stderr,"Internal error opening sparse data for tag \"%s\": %s\n", tag->name, mhdf_message(&status)); return 1; } ids = malloc( sizeof(long) * count ); mhdf_readSparseTagEntities( handles[0], 0, count, H5T_NATIVE_LONG, ids, &status ); if (mhdf_isError(&status)) { fprintf(stderr,"Internal error reading sparse entities for tag \"%s\": %s\n", tag->name, mhdf_message(&status)); mhdf_closeData( file, handles[0], &status ); mhdf_closeData( file, handles[1], &status ); free(ids); return 1; } mhdf_closeData( file, handles[0], &status ); ranges = all_id_ranges( desc, 0, &nranges ); if (!ids_contained( ids, count, ranges, nranges )) { ++result; printf("Sparse data for tag \"%s\" has values for invalid IDs\n", tag->name ); } else if (contains_duplicates( ids, count )) { ++result; printf("Sparse data for tag \"%s\" has duplicate values for one or more entities\n", tag->name ); } free(ranges); for (i = 0; i < tag->num_dense_indices; ++i) { if (tag->dense_elem_indices[i] == -2) { name = mhdf_set_type_handle(); group = &desc->sets; } else if (tag->dense_elem_indices[i] == -1) { name = mhdf_node_type_handle(); group = &desc->nodes; } else { name = desc->elems[ tag->dense_elem_indices[i] ].handle; group = &desc->elems[ tag->dense_elem_indices[i] ].desc; } srange[0] = group->start_id; srange[1] = group->count; if (ids_contained( ids, count, srange, 2 )) { ++result; printf("Tag \"%s\" has both sparse values and dense values for one or more entities in \"%s\"\n", tag->name, name ); } } free(ids); } if (tag->type != mhdf_ENTITY_ID) { if (tag->have_sparse) mhdf_closeData( file, handles[1], &status ); return result; } ranges = all_id_ranges( desc, 1, &nranges ); if (tag->default_value && !ids_contained( tag->default_value, tag->size, ranges, nranges )) { ++result; printf("Handle tag \"%s\" has invalid ID(s) in its default value.\n", tag->name ); } if (tag->global_value && !ids_contained( tag->global_value, tag->size, ranges, nranges )) { ++result; printf("Handle tag \"%s\" has invalid ID(s) in its global/mesh value.\n", tag->name ); } h5type = H5T_NATIVE_LONG; if (tag->size > 1) { size = tag->size; #if defined(H5Tarray_create_vers) && H5Tarray_create_vers > 1 h5type = H5Tarray_create( H5T_NATIVE_LONG, 1, &size ); #else h5type = H5Tarray_create( H5T_NATIVE_LONG, 1, &size, NULL ); #endif } if (tag->have_sparse) { ids = malloc( tag->size * count * sizeof(long) ); mhdf_readTagValues( handles[1], 0, count, h5type, ids, &status ); if (mhdf_isError(&status)) { fprintf(stderr,"Internal error reading sparse values for handle tag \"%s\": %s\n", tag->name, mhdf_message(&status)); mhdf_closeData( file, handles[1], &status ); free(ids); free(ranges); if (tag->size > 1) H5Tclose( h5type ); return 1; } mhdf_closeData( file, handles[1], &status ); if (!ids_contained( ids, tag->size * count, ranges, nranges )) { ++result; printf("Sparse data for one or more entities with handle tag \"%s\" has invalid ID(s).\n", tag->name ); } free(ids); } for (i = 0; i < tag->num_dense_indices; ++i) { if (tag->dense_elem_indices[i] == -2) { name = mhdf_set_type_handle(); /*group = &desc->sets;*/ } else if (tag->dense_elem_indices[i] == -1) { name = mhdf_node_type_handle(); /*group = &desc->nodes;*/ } else { name = desc->elems[ tag->dense_elem_indices[i] ].handle; /*group = &desc->elems[ tag->dense_elem_indices[i] ].desc;*/ } handles[0] = mhdf_openDenseTagData( file, tag->name, name, &count, &status ); if (mhdf_isError(&status)) { fprintf(stderr,"Internal dense values for handle tag \"%s\" on \"%s\": %s\n", tag->name, name, mhdf_message(&status)); ++result; continue; } ids = malloc( tag->size * count * sizeof(long) ); mhdf_readTagValues( handles[0], 0, count, h5type, ids, &status ); if (mhdf_isError(&status)) { fprintf(stderr,"Internal error reading dense values for handle tag \"%s\" on \"%s\": %s\n", tag->name, name, mhdf_message(&status)); mhdf_closeData( file, handles[0], &status ); free(ids); ++result; continue; } mhdf_closeData( file, handles[1], &status ); if (!ids_contained( ids, count, ranges, nranges )) { ++result; printf("Dense data on \"%s\" for handle tag \"%s\" has invalid ID(s) for one or more entities.\n", name, tag->name ); } free(ids); } if (tag->size > 1) H5Tclose( h5type ); return result; }
int main( int argc, char* argv[] ) { /* input file */ const char* filename; mhdf_FileHandle file; mhdf_Status status; mhdf_Status *const sptr = &status; hid_t handle; /* generic handle used to refer to any data block in file */ /* output file */ const char* gmsh_filename; FILE* gmsh; unsigned gmsh_type; /* hexahedral element type number */ double x, y, z; /* temp storage of node coordinates */ unsigned node_offset, node_id; /* temporary values */ unsigned* connectivity; /* temporary value */ /* node data */ long numnode; /* total number of nodes */ long nodestart; /* file id of first node in list */ int dimension; /* coordinate values per node */ double* nodecoords; /* interleaved node coordinates */ unsigned* nodeids; /* GLOBAL_ID value for nodes */ int have_nodeids = 0; /* hex data */ char* hexgroup = NULL; /* name of element group containing hexes */ long numhex; /* total number of hexahedral elements */ long hexstart; /* file id of first hex in group */ int nodes_per_hex; /* length of connectivity list for a hex */ unsigned* hexconnectivity; /* hex connectivity data */ unsigned* hexids; /* GLOBAL_ID value for hexes */ int have_hexids = 0; /* list of element groups in file */ char** elem_groups; unsigned num_elem_groups; char namebuffer[64]; /* tag data for accessing GLOBAL_ID */ int tagsize; /* number of values for each entity */ int ts, td, tg; /* unused tag properties */ int havesparse, havedense; /* Boolean values */ enum mhdf_TagDataType tagtype; /* base data type of tag */ hid_t sparse_handle[2]; /* handle pair for sparse tag data */ unsigned* sparse_entities; /* temp storage of sparse tag file ids */ unsigned* sparse_ids; /* temp storage of GLOBAL_ID values in spasre tag */ long junk, numtag; /* number of entities for which tag data is available */ long fileid, globalid; /* temporary values */ long ncount = 0, hcount = 0; /* temporary count of number of tag values */ /* iteration */ long i; int j; unsigned k; /* process CL args (expect input .h5m file and output .gmsh file name) */ if (argc != 3) { fprintf(stderr, "Usage: %s <input_file> <output_file>\n", argv[0] ); return 1; } filename = argv[1]; gmsh_filename = argv[2]; /* Open the file */ file = mhdf_openFile( filename, 0, 0, sptr ); CHK_ERR(sptr); /* Read node coordinates. */ handle = mhdf_openNodeCoords( file, &numnode, &dimension, &nodestart, sptr ); CHK_ERR(sptr); nodecoords = (double*)malloc( dimension * numnode * sizeof(double) ); mhdf_readNodeCoords( handle, 0, numnode, nodecoords, sptr ); CHK_ERR(sptr); mhdf_closeData( file, handle, sptr ); CHK_ERR(sptr); /* Find first element group containing hexahedra */ elem_groups = mhdf_getElemHandles( file, &num_elem_groups, sptr ); CHK_ERR(sptr); for (k = 0; k < num_elem_groups; ++k) { mhdf_getElemTypeName( file, elem_groups[k], namebuffer, sizeof(namebuffer), sptr ); CHK_ERR(sptr); if (!hexgroup && !strcmp(mdhf_HEX_TYPE_NAME, namebuffer)) hexgroup = strdup(elem_groups[k]); else printf( "Skipping element group '%s' containing element of type '%s'\n", elem_groups[k], namebuffer ); } free( elem_groups ); if (!hexgroup) { fprintf( stderr, "No Hexahedra defined in file\n" ); return 4; } /* Read Hexahedron connectivity */ handle = mhdf_openConnectivity( file, hexgroup, &nodes_per_hex, &numhex, &hexstart, sptr ); CHK_ERR(sptr); hexconnectivity = (unsigned*)malloc(numhex * nodes_per_hex * sizeof(unsigned)); mhdf_readConnectivity( handle, 0, numhex, H5T_NATIVE_UINT, hexconnectivity, sptr ); CHK_ERR(sptr); mhdf_closeData( file, handle, sptr ); CHK_ERR(sptr); /* Note: hex connectivity list contains file-space node IDs, which are the nodes in the sequence they are read from the file, with the first node having an ID of 'nodestart' */ /* Check for "GLOBAL_ID" tag */ nodeids = (unsigned*)malloc( numnode * sizeof(unsigned) ); hexids = (unsigned*)malloc( numhex * sizeof(unsigned) ); mhdf_getTagInfo( file, "GLOBAL_ID", &tagtype, &tagsize, &ts, &td, &tg, &havesparse, sptr ); /* If have GLOBAL_ID tag, try to read values for nodes and hexes */ if (!mhdf_isError(sptr)) { /* Check that the tag contains what we expect */ if (tagtype != mhdf_INTEGER || tagsize != 1) { fprintf(stderr, "ERROR: Invalid data type for 'GLOBAL_ID' tag.\n"); exit(3); } /* Check for and read dense-format tag data for nodes */ havedense = mhdf_haveDenseTag( file, "GLOBAL_ID", mhdf_node_type_handle(), sptr ); CHK_ERR(sptr); if (havedense) { handle = mhdf_openDenseTagData( file, "GLOBAL_ID", mhdf_node_type_handle(), &numtag, sptr ); CHK_ERR(sptr); assert( numtag == numnode ); mhdf_readDenseTag( handle, 0, numtag, H5T_NATIVE_UINT, nodeids, sptr ); CHK_ERR(sptr); mhdf_closeData( file, handle, sptr ); CHK_ERR(sptr); have_nodeids = 1; } /* Check for and read dense-format tag data for hexes */ havedense = mhdf_haveDenseTag( file, "GLOBAL_ID", hexgroup, sptr ); CHK_ERR(sptr); if (havedense) { handle = mhdf_openDenseTagData( file, "GLOBAL_ID", hexgroup, &numtag, sptr ); CHK_ERR(sptr); assert( numtag == numhex ); mhdf_readDenseTag( handle, 0, numtag, H5T_NATIVE_UINT, hexids, sptr ); CHK_ERR(sptr); mhdf_closeData( file, handle, sptr ); CHK_ERR(sptr); have_hexids = 1; } /* Check for and read sparse-format tag data */ if (havesparse) { mhdf_openSparseTagData( file, "GLOBAL_ID", &numtag, &junk, sparse_handle, sptr ); CHK_ERR(sptr); sparse_entities = (unsigned*)malloc(numtag * sizeof(unsigned)); mhdf_readSparseTagEntities( sparse_handle[0], 0, numtag, H5T_NATIVE_UINT, sparse_entities, sptr ); CHK_ERR(sptr); sparse_ids = (unsigned*)malloc(numtag * sizeof(unsigned)); mhdf_readSparseTagValues( sparse_handle[1], 0, numtag, H5T_NATIVE_UINT, sparse_ids, sptr ); CHK_ERR(sptr); mhdf_closeData( file, sparse_handle[0], sptr ); CHK_ERR(sptr); mhdf_closeData( file, sparse_handle[1], sptr ); CHK_ERR(sptr); /* Set hex and node ids from sparse tag data */ for (i = 0; i < numtag; ++i) { fileid = sparse_entities[i]; globalid = sparse_ids[i]; if (fileid >= nodestart && fileid - nodestart < numnode) { nodeids[fileid - nodestart] = globalid; ++ncount; } else if (fileid >= hexstart && fileid - hexstart < numhex) { hexids[fileid - hexstart] = globalid; ++hcount; } } free( sparse_ids ); free( sparse_entities ); /* make sure there was an ID for each node and each hex */ if (ncount == numnode) have_nodeids = 1; if (hcount == numhex) have_hexids = 1; } /* end have sparse tag for GLOBAL_ID */ } /* end have GLOBAL_ID tag */ /* done with input file */ free( hexgroup ); mhdf_closeFile( file, sptr ); CHK_ERR(sptr); /* if no GLOBAL_ID, just use incrementing values */ if (!have_nodeids) for (i = 0; i < numnode; ++i) nodeids[i] = i+1; if (!have_hexids) for (i = 0; i < numhex; ++i) hexids[i] = i+1; /* write out as gmesh file version 1.0 */ /* get gmsh type for hexahedrons */ if (nodes_per_hex == 8) gmsh_type = 5; else if (nodes_per_hex == 27) gmsh_type = 12; else { fprintf(stderr, "Cannot store %d node hex in gmsh file.\n", nodes_per_hex); exit(4); } /* open file */ gmsh = fopen( gmsh_filename, "w" ); /* Write node data. If dimension is less than 3, write zero for other coordinate values. In the (highly unlikely) case that dimension is greater than three, disregard higher-dimension coordinate values. */ fprintf(gmsh, "$NOD\n" ); fprintf(gmsh, "%lu\n", numnode ); for (i = 0; i < numnode; ++i) { x = nodecoords[dimension*i]; y = z = 0.0; if (dimension > 1) { y = nodecoords[dimension*i+1]; if (dimension > 2) { z = nodecoords[dimension*i+2]; } } fprintf(gmsh, "%u %f %f %f\n", nodeids[i], x, y, z ); } /* Write element connectivity data */ fprintf(gmsh, "$ENDNOD\n$ELM\n" ); fprintf(gmsh, "%lu\n", numhex ); for (i = 0; i < numhex; ++i) { fprintf( gmsh, "%u %u 1 1 %d", hexids[i], gmsh_type, nodes_per_hex ); /* connectivity list for this hex */ connectivity = hexconnectivity + i*nodes_per_hex; for (j = 0; j < nodes_per_hex; ++j) { /* get offset in node list from file id */ node_offset = connectivity[j] - nodestart; /* get node id from ID list */ node_id = nodeids[node_offset]; fprintf( gmsh, " %u", node_id ); } fprintf( gmsh, "\n" ); } fprintf( gmsh, "$ENDELM\n" ); fclose( gmsh ); return 0; }