Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include "mhdf.h"
#include <H5Tpublic.h>
Go to the source code of this file.
Defines | |
#define | CHK_ERR(A) |
Functions | |
int | main (int argc, char *argv[]) |
#define CHK_ERR | ( | A | ) |
do \ { \ if( mhdf_isError( A ) ) \ { \ fprintf( stderr, "Error: %s\n", mhdf_message( A ) ); \ exit( 2 ); \ } \ } while( 0 )
MOAB, a Mesh-Oriented datABase, is a software component for creating, storing and accessing finite element mesh data.
Copyright 2006 Sandia Corporation. Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains certain rights in this software.
This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.
Definition at line 56 of file hexes_to_gmsh.c.
Referenced by main().
int main | ( | int | argc, |
char * | argv[] | ||
) |
Definition at line 66 of file hexes_to_gmsh.c.
References CHK_ERR, mdhf_HEX_TYPE_NAME, mhdf_closeData(), mhdf_closeFile(), mhdf_getElemHandles(), mhdf_getElemTypeName(), mhdf_getTagInfo(), mhdf_haveDenseTag(), mhdf_INTEGER, mhdf_isError(), mhdf_node_type_handle(), mhdf_openConnectivity(), mhdf_openDenseTagData(), mhdf_openFile(), mhdf_openNodeCoords(), mhdf_openSparseTagData(), mhdf_readConnectivity(), mhdf_readNodeCoords(), and mhdf_readSparseTagEntities().
{ /* 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; }