Mesh Oriented datABase  (version 5.4.1)
Array-based unstructured mesh datastructure
hexes_to_gmsh.c File Reference
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include "mhdf.h"
#include <H5Tpublic.h>
+ Include dependency graph for hexes_to_gmsh.c:

Go to the source code of this file.

Defines

#define CHK_ERR(A)

Functions

int main (int argc, char *argv[])

Define Documentation

#define CHK_ERR (   A)
Value:
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().


Function Documentation

int main ( int  argc,
char *  argv[] 
)
Examples:
addPCdata.cpp, ComputeTriDual.cpp, copyPartition.cpp, CrystalRouterExample.cpp, DeformMeshRemap.cpp, DirectAccessNoHoles.cpp, DirectAccessWithHoles.cpp, ErrorHandlingSimulation.cpp, ExtractLand.cpp, ExtrudePoly.cpp, GenLargeMesh.cpp, GetEntities.cpp, HelloMOAB.cpp, HelloParMOAB.cpp, LaplacianSmoother.cpp, LloydRelaxation.cpp, LoadPartial.cpp, QuadTriConv.cpp, ReadPartFile.cpp, ReadWriteTest.cpp, ReduceExchangeTags.cpp, SetsNTags.cpp, StructuredMeshSimple.cpp, TestErrorHandling.cpp, TestErrorHandlingPar.cpp, TestExodusII.cpp, and VisTags.cpp.

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;
}
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines