MOAB: Mesh Oriented datABase  (version 5.3.1)
convert.cpp File Reference
#include "moab/Core.hpp"
#include "moab/Range.hpp"
#include "MBTagConventions.hpp"
#include "moab/ReaderWriterSet.hpp"
#include "moab/ReorderTool.hpp"
#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <set>
#include <list>
#include <cstdlib>
#include <algorithm>
#include <ctime>
#include <cstdio>
+ Include dependency graph for convert.cpp:

Go to the source code of this file.

Defines

#define WIN32
#define USAGE_ERROR   1
#define READ_ERROR   2
#define WRITE_ERROR   3
#define OTHER_ERROR   4
#define ENT_NOT_FOUND   5

Functions

static void print_usage (const char *name, std::ostream &stream)
static void print_help (const char *name)
static void usage_error (const char *name)
static void list_formats (Interface *)
static bool parse_id_list (const char *string, std::set< int > &)
static void print_id_list (const char *, std::ostream &stream, const std::set< int > &list)
static void reset_times ()
static void write_times (std::ostream &stream)
static void remove_entities_from_sets (Interface *gMB, Range &dead_entities, Range &empty_sets)
static void remove_from_vector (std::vector< EntityHandle > &vect, const Range &ents_to_remove)
static bool make_opts_string (std::vector< std::string > options, std::string &result)
static std::string percent_subst (const std::string &s, int val)
static int process_partition_file (Interface *gMB, std::string &metis_partition_file)
int main (int argc, char *argv[])
static void print_time (int clk_per_sec, const char *prefix, clock_t ticks, std::ostream &stream)

Variables

clock_t usr_time
clock_t sys_time
clock_t abs_time

Define Documentation

#define ENT_NOT_FOUND   5

Definition at line 55 of file convert.cpp.

Referenced by main().

#define OTHER_ERROR   4

Definition at line 54 of file convert.cpp.

Referenced by list_formats().

#define READ_ERROR   2

Definition at line 52 of file convert.cpp.

Referenced by main().

#define USAGE_ERROR   1

Definition at line 51 of file convert.cpp.

Referenced by main(), print_usage(), and usage_error().

#define WIN32

MOAB, a Mesh-Oriented datABase, is a software component for creating, storing and accessing finite element mesh data.

Copyright 2004 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 18 of file convert.cpp.

#define WRITE_ERROR   3

Definition at line 53 of file convert.cpp.

Referenced by main().


Function Documentation

void list_formats ( Interface gMB) [static]

Definition at line 1133 of file convert.cpp.

References ErrorCode, MB_SUCCESS, OTHER_ERROR, moab::Interface::query_interface(), and moab::Interface::release_interface().

Referenced by main().

{
    const char iface_name[] = "ReaderWriterSet";
    ErrorCode err;
    ReaderWriterSet* set = 0;
    ReaderWriterSet::iterator i;
    std::ostream& str = std::cout;

    // get ReaderWriterSet
    err = gMB->query_interface( set );
    if( err != MB_SUCCESS || !set )
    {
        std::cerr << "Internal error:  Interface \"" << iface_name << "\" not available.\n";
        exit( OTHER_ERROR );
    }

    // get field width for format description
    size_t w = 0;
    for( i = set->begin(); i != set->end(); ++i )
        if( i->description().length() > w ) w = i->description().length();

    // write table header
    str << "Format  " << std::setw( w ) << std::left << "Description"
        << "  Read  Write  File Name Suffixes\n"
        << "------  " << std::setw( w ) << std::setfill( '-' ) << "" << std::setfill( ' ' )
        << "  ----  -----  ------------------\n";

    // write table data
    for( i = set->begin(); i != set->end(); ++i )
    {
        std::vector< std::string > ext;
        i->get_extensions( ext );
        str << std::setw( 6 ) << i->name() << "  " << std::setw( w ) << std::left << i->description() << "  "
            << ( i->have_reader() ? " yes" : "  no" ) << "  " << ( i->have_writer() ? "  yes" : "   no" ) << " ";
        for( std::vector< std::string >::iterator j = ext.begin(); j != ext.end(); ++j )
            str << " " << *j;
        str << std::endl;
    }
    str << std::endl;

    gMB->release_interface( set );
    exit( 0 );
}
int main ( int  argc,
char *  argv[] 
)

Definition at line 157 of file convert.cpp.

References moab::Interface::add_entities(), MBMesquite::adj(), moab::Range::all_of_type(), moab::ParallelComm::assign_global_ids(), moab::TempestRemapper::assign_vertex_element_IDs(), moab::Range::begin(), moab::Range::clear(), moab::ParallelComm::comm(), moab::TempestRemapper::ConvertMeshToTempest(), moab::TempestRemapper::ConvertTempestMesh(), moab::TempestRemapper::CS, moab::TempestRemapper::DEFAULT, moab::Interface::delete_entities(), dim, dim_tag, DIRICHLET_SET_TAG_NAME, moab::Range::empty(), moab::Range::end(), ENT_NOT_FOUND, ErrorCode, MBMesquite::faces, moab::TempestRemapper::GenerateMeshMetadata(), geom, GEOM_DIMENSION_TAG_NAME, moab::Interface::get_adjacencies(), moab::Interface::get_entities_by_dimension(), moab::Interface::get_entities_by_type_and_tag(), moab::Interface::get_error_string(), moab::Interface::get_last_error(), moab::TempestRemapper::GetMesh(), moab::TempestRemapper::GetMeshEntities(), moab::TempestRemapper::GetMeshSet(), moab::TempestRemapper::GetMeshVertices(), moab::Interface::globalId_tag(), gMB, moab::ReorderTool::handle_order_from_int_tag(), moab::TempestRemapper::ICO, moab::TempestRemapper::ICOD, id_tag, ierr, moab::TempestRemapper::initialize(), list_formats(), moab::Interface::load_file(), moab::TempestRemapper::LoadMesh(), moab::Remapper::LoadNativeMesh(), make_opts_string(), MATERIAL_SET_TAG_NAME, MB_CHK_ERR, MB_CHK_SET_ERR, MB_SUCCESS, MB_TAG_CREAT, MB_TAG_DENSE, MB_TAG_SPARSE, MB_TYPE_INTEGER, MBENTITYSET, MBQUAD, MBTRI, moab::Range::merge(), mesh, moab::TempestRemapper::meshValidate, MPI_COMM_WORLD, NEUMANN_SET_TAG_NAME, moab::Remapper::OverlapMesh, PARALLEL_PARTITION_TAG_NAME, parse_id_list(), percent_subst(), print_help(), print_id_list(), process_partition_file(), READ_ERROR, read_options, remove_entities_from_sets(), moab::remove_from_vector(), moab::ReorderTool::reorder_entities(), reset_times(), moab::TempestRemapper::RLL, moab::Range::size(), moab::Remapper::SourceMesh, moab::subtract(), moab::Interface::tag_delete(), moab::Interface::tag_get_data(), moab::Interface::tag_get_handle(), moab::Interface::tag_set_data(), moab::Interface::UNION, USAGE_ERROR, usage_error(), verbose, WRITE_ERROR, moab::Interface::write_file(), and write_times().

{
    int proc_id = 0;
#ifdef MOAB_HAVE_MPI
    MPI_Init( &argc, &argv );
    MPI_Comm_rank( MPI_COMM_WORLD, &proc_id );
#endif

#ifdef MOAB_HAVE_TEMPESTREMAP
    bool tempestin = false, tempestout = false;
#endif

    Core core;
    Interface* gMB = &core;
    ErrorCode result;
    Range range;

#if( defined( MOAB_HAVE_MPI ) && defined( MOAB_HAVE_TEMPESTREMAP ) )
    moab::ParallelComm* pcomm = new moab::ParallelComm( gMB, MPI_COMM_WORLD, 0 );
#endif

    bool append_rank        = false;
    bool percent_rank_subst = false;
    int i, dim;
    std::list< std::string >::iterator j;
    bool dims[4]       = { false, false, false, false };
    const char* format = NULL;    // output file format
    std::list< std::string > in;  // input file name list
    std::string out;              // output file name
    bool verbose = false;
    std::set< int > geom[4], mesh[4];      // user-specified IDs
    std::vector< EntityHandle > set_list;  // list of user-specified sets to write
    std::vector< std::string > write_opts, read_opts;
    std::string metis_partition_file;
#ifdef MOAB_HAVE_TEMPESTREMAP
    std::string globalid_tag_name;
    int spectral_order = 1;
#endif

    const char* const mesh_tag_names[] = { DIRICHLET_SET_TAG_NAME, NEUMANN_SET_TAG_NAME, MATERIAL_SET_TAG_NAME,
                                           PARALLEL_PARTITION_TAG_NAME };
    const char* const geom_names[]     = { "VERTEX", "CURVE", "SURFACE", "VOLUME" };

    // scan arguments
    bool do_flag     = true;
    bool print_times = false;
    bool generate[]  = { false, false, false };
    bool pval;
    bool parallel = false, resolve_shared = false, exchange_ghosts = false;
    for( i = 1; i < argc; i++ )
    {
        if( !argv[i][0] ) usage_error( argv[0] );

        if( do_flag && argv[i][0] == '-' )
        {
            if( !argv[i][1] || ( argv[i][1] != 'M' && argv[i][2] ) ) usage_error( argv[0] );

            switch( argv[i][1] )
            {
                    // do flag arguments:
                case '-':
                    do_flag = false;
                    break;
                case 'g':
                    verbose = true;
                    break;
                case 't':
                    print_times = true;
                    break;
                case 'A':
                    break;
                case 'h':
                case 'H':
                    print_help( argv[0] );
                    break;
                case 'l':
                    list_formats( gMB );
                    break;
#ifdef MOAB_HAVE_MPI
                case 'P':
                    append_rank = true;
                    break;
                case 'p':
                    percent_rank_subst = true;
                    break;
                case 'M':
                    parallel = true;
                    if( argv[i][2] == '1' || argv[i][2] == '2' ) resolve_shared = true;
                    if( argv[i][2] == '2' ) exchange_ghosts = true;
                    break;
#endif
#ifdef MOAB_HAVE_TEMPESTREMAP
                case 'B':
                    tempestin = true;
                    break;
                case 'b':
                    tempestout = true;
                    break;
#endif
                case '1':
                case '2':
                case '3':
                    dims[argv[i][1] - '0'] = true;
                    break;
                    // do options that require additional args:
                default:
                    ++i;
                    if( i == argc || argv[i][0] == '-' )
                    {
                        std::cerr << "Expected argument following " << argv[i - 1] << std::endl;
                        usage_error( argv[0] );
                    }
                    if( argv[i - 1][1] == 'I' )
                    {
                        dim = atoi( argv[i] );
                        if( dim < 1 || dim > 2 )
                        {
                            std::cerr << "Invalid dimension value following -I" << std::endl;
                            usage_error( argv[0] );
                        }
                        generate[dim] = true;
                        continue;
                    }
                    pval = false;
                    switch( argv[i - 1][1] )
                    {
                        case 'a':
                            read_opts.push_back( std::string( "SAT_FILE=" ) + argv[i] );
                            pval = true;
                            break;
                        case 'f':
                            format = argv[i];
                            pval   = true;
                            break;
                        case 'o':
                            write_opts.push_back( argv[i] );
                            pval = true;
                            break;
                        case 'O':
                            read_opts.push_back( argv[i] );
                            pval = true;
                            break;
#ifdef MOAB_HAVE_TEMPESTREMAP
                        case 'i':
                            globalid_tag_name = std::string( argv[i] );
                            pval              = true;
                            break;
                        case 'r':
                            spectral_order = atoi( argv[i] );
                            pval           = true;
                            break;
#endif
                        case 'v':
                            pval = parse_id_list( argv[i], geom[3] );
                            break;
                        case 's':
                            pval = parse_id_list( argv[i], geom[2] );
                            break;
                        case 'c':
                            pval = parse_id_list( argv[i], geom[1] );
                            break;
                        case 'V':
                            pval = parse_id_list( argv[i], geom[0] );
                            break;
                        case 'D':
                            pval = parse_id_list( argv[i], mesh[3] );
                            break;
                        case 'm':
                            pval = parse_id_list( argv[i], mesh[2] );
                            break;
                        case 'n':
                            pval = parse_id_list( argv[i], mesh[1] );
                            break;
                        case 'd':
                            pval = parse_id_list( argv[i], mesh[0] );
                            break;
                        case 'z':
                            metis_partition_file = argv[i];
                            pval                 = true;
                            break;
                        default:
                            std::cerr << "Invalid option: " << argv[i] << std::endl;
                    }

                    if( !pval )
                    {
                        std::cerr << "Invalid flag or flag value: " << argv[i - 1] << " " << argv[i] << std::endl;
                        usage_error( argv[0] );
                    }
            }
        }
        // do file names
        else
        {
            in.push_back( argv[i] );
        }
    }
    if( in.size() < 2 )
    {
        std::cerr << "No output file name specified." << std::endl;
        usage_error( argv[0] );
    }
    // output file name is the last one specified
    out = in.back();
    in.pop_back();

    if( append_rank )
    {
        std::ostringstream mod;
        mod << out << "." << proc_id;
        out = mod.str();
    }

    if( percent_rank_subst )
    {
        for( j = in.begin(); j != in.end(); ++j )
            *j = percent_subst( *j, proc_id );
        out = percent_subst( out, proc_id );
    }

    // construct options string from individual options
    std::string read_options, write_options;
    if( parallel )
    {
        read_opts.push_back( "PARALLEL=READ_PART" );
        read_opts.push_back( "PARTITION=PARALLEL_PARTITION" );
        if( !append_rank && !percent_rank_subst ) write_opts.push_back( "PARALLEL=WRITE_PART" );
    }
    if( resolve_shared ) read_opts.push_back( "PARALLEL_RESOLVE_SHARED_ENTS" );
    if( exchange_ghosts ) read_opts.push_back( "PARALLEL_GHOSTS=3.0.1" );

    if( !make_opts_string( read_opts, read_options ) || !make_opts_string( write_opts, write_options ) )
    {
#ifdef MOAB_HAVE_MPI
        MPI_Finalize();
#endif
        return USAGE_ERROR;
    }

    if( !metis_partition_file.empty() )
    {
        if( ( in.size() != 1 ) || ( proc_id != 0 ) )
        {
            std::cerr << " mpas partition allows only one input file, in serial conversion\n";
#ifdef MOAB_HAVE_MPI
            MPI_Finalize();
#endif
            return USAGE_ERROR;
        }
    }

    Tag id_tag = gMB->globalId_tag();

    // Read the input file.
#ifdef MOAB_HAVE_TEMPESTREMAP
    if( tempestin && in.size() > 1 )
    {
        std::cerr << " we can read only one tempest files at a time\n";
#ifdef MOAB_HAVE_MPI
        MPI_Finalize();
#endif
        return USAGE_ERROR;
    }

#ifdef MOAB_HAVE_MPI
    TempestRemapper* remapper = new moab::TempestRemapper( gMB, pcomm );
#else
    TempestRemapper* remapper = new moab::TempestRemapper( gMB );
#endif

    bool use_overlap_context = false;
    Tag srcParentTag, tgtParentTag;

#endif
    for( j = in.begin(); j != in.end(); ++j )
    {
        std::string inFileName = *j;

        reset_times();

#ifdef MOAB_HAVE_TEMPESTREMAP

        remapper->meshValidate = false;
        // remapper->constructEdgeMap = true;
        remapper->initialize();

        if( tempestin )
        {
            // convert
            result = remapper->LoadMesh( moab::Remapper::SourceMesh, inFileName, moab::TempestRemapper::DEFAULT );MB_CHK_ERR( result );

            Mesh* tempestMesh = remapper->GetMesh( moab::Remapper::SourceMesh );
            tempestMesh->RemoveZeroEdges();
            tempestMesh->RemoveCoincidentNodes();

            // Load the meshes and validate
            result = remapper->ConvertTempestMesh( moab::Remapper::SourceMesh );

            // Check if we are converting a RLL grid
            NcFile ncInput( inFileName.c_str(), NcFile::ReadOnly );
            bool isRectilinearGrid = false;

            NcError error_temp( NcError::silent_nonfatal );
            // get the attribute
            NcAtt* attRectilinear = ncInput.get_att( "rectilinear" );

            // If rectilinear attribute present, mark it
            std::vector< int > vecDimSizes( 3, 0 );
            Tag rectilinearTag;
            // Tag data contains: guessed mesh type,     mesh size1,     mesh size 2
            //          Example:  CS(0)/ICO(1)/ICOD(2),  num_elements,   num_nodes
            //                 :       RLL(3),           num_lat,        num_lon
            result = gMB->tag_get_handle( "ClimateMetadata", 3, MB_TYPE_INTEGER, rectilinearTag,
                                          MB_TAG_SPARSE | MB_TAG_CREAT, vecDimSizes.data() );MB_CHK_SET_ERR( result, "can't create rectilinear sizes tag" );

            if( attRectilinear != nullptr )
            {
                isRectilinearGrid = true;

                // Obtain rectilinear attributes (dimension sizes)
                NcAtt* attRectilinearDim0Size = ncInput.get_att( "rectilinear_dim0_size" );
                NcAtt* attRectilinearDim1Size = ncInput.get_att( "rectilinear_dim1_size" );

                if( attRectilinearDim0Size == nullptr )
                {
                    _EXCEPTIONT( "Missing attribute \"rectilinear_dim0_size\"" );
                }
                if( attRectilinearDim1Size == nullptr )
                {
                    _EXCEPTIONT( "Missing attribute \"rectilinear_dim1_size\"" );
                }

                int nDim0Size = attRectilinearDim0Size->as_int( 0 );
                int nDim1Size = attRectilinearDim1Size->as_int( 0 );

                // Obtain rectilinear attributes (dimension names)
                NcAtt* attRectilinearDim0Name = ncInput.get_att( "rectilinear_dim0_name" );
                NcAtt* attRectilinearDim1Name = ncInput.get_att( "rectilinear_dim1_name" );

                if( attRectilinearDim0Name == nullptr )
                {
                    _EXCEPTIONT( "Missing attribute \"rectilinear_dim0_name\"" );
                }
                if( attRectilinearDim1Name == nullptr )
                {
                    _EXCEPTIONT( "Missing attribute \"rectilinear_dim1_name\"" );
                }

                std::string strDim0Name = attRectilinearDim0Name->as_string( 0 );
                std::string strDim1Name = attRectilinearDim1Name->as_string( 0 );

                std::map< std::string, int > vecDimNameSizes;
                // Push rectilinear attributes into array
                vecDimNameSizes[strDim0Name] = nDim0Size;
                vecDimNameSizes[strDim1Name] = nDim1Size;
                vecDimSizes[0]               = static_cast< int >( moab::TempestRemapper::RLL );
                vecDimSizes[1]               = vecDimNameSizes["lat"];
                vecDimSizes[2]               = vecDimNameSizes["lon"];

                printf( "Rectilinear RLL mesh size: (lat) %d X (lon) %d\n", vecDimSizes[1], vecDimSizes[2] );

                moab::EntityHandle mSet = 0;
                // mSet   = remapper->GetMeshSet( moab::Remapper::SourceMesh );
                result = gMB->tag_set_data( rectilinearTag, &mSet, 1, vecDimSizes.data() );MB_CHK_ERR( result );
            }
            else
            {
                const Range& elems = remapper->GetMeshEntities( moab::Remapper::SourceMesh );
                bool isQuads       = elems.all_of_type( moab::MBQUAD );
                bool isTris        = elems.all_of_type( moab::MBTRI );
                // vecDimSizes[0] = static_cast< int >( remapper->GetMeshType( moab::Remapper::SourceMesh );
                vecDimSizes[0] = ( isQuads ? static_cast< int >( moab::TempestRemapper::CS )
                                           : ( isTris ? static_cast< int >( moab::TempestRemapper::ICO )
                                                      : static_cast< int >( moab::TempestRemapper::ICOD ) ) );
                vecDimSizes[1] = elems.size();
                vecDimSizes[2] = remapper->GetMeshVertices( moab::Remapper::SourceMesh ).size();

                switch( vecDimSizes[0] )
                {
                    case 0:
                        printf( "Cubed-Sphere mesh: %d (elems), %d (nodes)\n", vecDimSizes[1], vecDimSizes[2] );
                        break;
                    case 2:
                        printf( "Icosahedral (triangular) mesh: %d (elems), %d (nodes)\n", vecDimSizes[1],
                                vecDimSizes[2] );
                        break;
                    case 3:
                    default:
                        printf( "Polygonal mesh: %d (elems), %d (nodes)\n", vecDimSizes[1], vecDimSizes[2] );
                        break;
                }

                moab::EntityHandle mSet = 0;
                // mSet   = remapper->GetMeshSet( moab::Remapper::SourceMesh );
                result = gMB->tag_set_data( rectilinearTag, &mSet, 1, vecDimSizes.data() );MB_CHK_ERR( result );
            }

            ncInput.close();

            const size_t nOverlapFaces = tempestMesh->faces.size();
            if( tempestMesh->vecSourceFaceIx.size() == nOverlapFaces &&
                tempestMesh->vecSourceFaceIx.size() == nOverlapFaces )
            {
                int defaultInt      = -1;
                use_overlap_context = true;
                // Check if our MOAB mesh has RED and BLUE tags; this would indicate we are
                // converting an overlap grid
                result = gMB->tag_get_handle( "TargetParent", 1, MB_TYPE_INTEGER, tgtParentTag,
                                              MB_TAG_DENSE | MB_TAG_CREAT, &defaultInt );MB_CHK_SET_ERR( result, "can't create target parent tag" );

                result = gMB->tag_get_handle( "SourceParent", 1, MB_TYPE_INTEGER, srcParentTag,
                                              MB_TAG_DENSE | MB_TAG_CREAT, &defaultInt );MB_CHK_SET_ERR( result, "can't create source parent tag" );

                const Range& faces = remapper->GetMeshEntities( moab::Remapper::SourceMesh );

                std::vector< int > gids( faces.size() ), srcpar( faces.size() ), tgtpar( faces.size() );
                result = gMB->tag_get_data( id_tag, faces, &gids[0] );MB_CHK_ERR( result );

                for( unsigned ii = 0; ii < faces.size(); ++ii )
                {
                    srcpar[ii] = tempestMesh->vecSourceFaceIx[gids[ii] - 1];
                    tgtpar[ii] = tempestMesh->vecTargetFaceIx[gids[ii] - 1];
                }

                result = gMB->tag_set_data( srcParentTag, faces, &srcpar[0] );MB_CHK_ERR( result );
                result = gMB->tag_set_data( tgtParentTag, faces, &tgtpar[0] );MB_CHK_ERR( result );

                srcpar.clear();
                tgtpar.clear();
                gids.clear();
            }
        }
        else if( tempestout )
        {
            moab::EntityHandle& srcmesh = remapper->GetMeshSet( moab::Remapper::SourceMesh );
            moab::EntityHandle& ovmesh  = remapper->GetMeshSet( moab::Remapper::OverlapMesh );

            // load the mesh in MOAB format
            std::vector< int > metadata;
            result = remapper->LoadNativeMesh( *j, srcmesh, metadata );MB_CHK_ERR( result );

            // Check if our MOAB mesh has RED and BLUE tags; this would indicate we are converting
            // an overlap grid
            ErrorCode rval1 = gMB->tag_get_handle( "SourceParent", srcParentTag );
            ErrorCode rval2 = gMB->tag_get_handle( "TargetParent", tgtParentTag );
            if( rval1 == MB_SUCCESS && rval2 == MB_SUCCESS )
            {
                use_overlap_context = true;
                ovmesh              = srcmesh;

                Tag countTag;
                result = gMB->tag_get_handle( "Counting", countTag );
                // std::vector<int> count_ids()

                // Load the meshes and validate
                Tag order;
                ReorderTool reorder_tool( &core );
                result = reorder_tool.handle_order_from_int_tag( srcParentTag, -1, order );MB_CHK_ERR( result );
                result = reorder_tool.reorder_entities( order );MB_CHK_ERR( result );
                result = gMB->tag_delete( order );MB_CHK_ERR( result );
                result = remapper->ConvertMeshToTempest( moab::Remapper::OverlapMesh );MB_CHK_ERR( result );
            }
            else
            {
                if( metadata[0] == static_cast< int >( moab::TempestRemapper::RLL ) )
                {
                    assert( metadata.size() );
                    std::cout << "Converting a RLL mesh with rectilinear dimension: " << metadata[0] << " X "
                              << metadata[1] << std::endl;
                }

                // Convert the mesh and validate
                result = remapper->ConvertMeshToTempest( moab::Remapper::SourceMesh );MB_CHK_ERR( result );
            }
        }
        else
            result = gMB->load_file( j->c_str(), 0, read_options.c_str() );
#else
        result = gMB->load_file( j->c_str(), 0, read_options.c_str() );
#endif
        if( MB_SUCCESS != result )
        {
            std::cerr << "Failed to load \"" << *j << "\"." << std::endl;
            std::cerr << "Error code: " << gMB->get_error_string( result ) << " (" << result << ")" << std::endl;
            std::string message;
            if( MB_SUCCESS == gMB->get_last_error( message ) && !message.empty() )
                std::cerr << "Error message: " << message << std::endl;
#ifdef MOAB_HAVE_MPI
            MPI_Finalize();
#endif
            return READ_ERROR;
        }
        if( !proc_id ) std::cerr << "Read \"" << *j << "\"" << std::endl;
        if( print_times && !proc_id ) write_times( std::cout );
    }

    // Determine if the user has specified any geometry sets to write
    bool have_geom = false;
    for( dim = 0; dim <= 3; ++dim )
    {
        if( !geom[dim].empty() ) have_geom = true;
        if( verbose ) print_id_list( geom_names[dim], std::cout, geom[dim] );
    }

    // True if the user has specified any sets to write
    bool have_sets = have_geom;

    // Get geometry tags
    Tag dim_tag;
    if( have_geom )
    {
        if( id_tag == 0 )
        {
            std::cerr << "No ID tag defined." << std::endl;
            have_geom = false;
        }
        result = gMB->tag_get_handle( GEOM_DIMENSION_TAG_NAME, 1, MB_TYPE_INTEGER, dim_tag );
        if( MB_SUCCESS != result )
        {
            std::cerr << "No geometry tag defined." << std::endl;
            have_geom = false;
        }
    }

    // Get geometry sets
    if( have_geom )
    {
        int id_val;
        Tag tags[]         = { id_tag, dim_tag };
        const void* vals[] = { &id_val, &dim };
        for( dim = 0; dim <= 3; ++dim )
        {
            int init_count = set_list.size();
            for( std::set< int >::iterator iter = geom[dim].begin(); iter != geom[dim].end(); ++iter )
            {
                id_val = *iter;
                range.clear();
                result = gMB->get_entities_by_type_and_tag( 0, MBENTITYSET, tags, vals, 2, range );
                if( MB_SUCCESS != result || range.empty() )
                {
                    range.clear();
                    std::cerr << geom_names[dim] << " " << id_val << " not found.\n";
                }
                std::copy( range.begin(), range.end(), std::back_inserter( set_list ) );
            }

            if( verbose )
                std::cout << "Found " << ( set_list.size() - init_count ) << ' ' << geom_names[dim] << " sets"
                          << std::endl;
        }
    }

    // Get mesh groupings
    for( i = 0; i < 4; ++i )
    {
        if( verbose ) print_id_list( mesh_tag_names[i], std::cout, mesh[i] );

        if( mesh[i].empty() ) continue;
        have_sets = true;

        // Get tag
        Tag tag;
        result = gMB->tag_get_handle( mesh_tag_names[i], 1, MB_TYPE_INTEGER, tag );
        if( MB_SUCCESS != result )
        {
            std::cerr << "Tag not found: " << mesh_tag_names[i] << std::endl;
            continue;
        }

        // get entity sets
        int init_count = set_list.size();
        for( std::set< int >::iterator iter = mesh[i].begin(); iter != mesh[i].end(); ++iter )
        {
            range.clear();
            const void* vals[] = { &*iter };
            result             = gMB->get_entities_by_type_and_tag( 0, MBENTITYSET, &tag, vals, 1, range );
            if( MB_SUCCESS != result || range.empty() )
            {
                range.clear();
                std::cerr << mesh_tag_names[i] << " " << *iter << " not found.\n";
            }
            std::copy( range.begin(), range.end(), std::back_inserter( set_list ) );
        }

        if( verbose )
            std::cout << "Found " << ( set_list.size() - init_count ) << ' ' << mesh_tag_names[i] << " sets"
                      << std::endl;
    }

    // Check if output is limited to certain dimensions of elements
    bool bydim = false;
    for( dim = 1; dim < 4; ++dim )
        if( dims[dim] ) bydim = true;

    // Check conflicting input
    if( bydim )
    {
        if( generate[1] && !dims[1] )
        {
            std::cerr << "Warning: Request to generate 1D internal entities but not export them." << std::endl;
            generate[1] = false;
        }
        if( generate[2] && !dims[2] )
        {
            std::cerr << "Warning: Request to generate 2D internal entities but not export them." << std::endl;
            generate[2] = false;
        }
    }

    // Generate any internal entities
    if( generate[1] || generate[2] )
    {
        EntityHandle all_mesh    = 0;
        const EntityHandle* sets = &all_mesh;
        int num_sets             = 1;
        if( have_sets )
        {
            num_sets = set_list.size();
            sets     = &set_list[0];
        }
        for( i = 0; i < num_sets; ++i )
        {
            Range dim3, dim2, adj;
            gMB->get_entities_by_dimension( sets[i], 3, dim3, true );
            if( generate[1] )
            {
                gMB->get_entities_by_dimension( sets[i], 2, dim2, true );
                gMB->get_adjacencies( dim3, 1, true, adj, Interface::UNION );
                gMB->get_adjacencies( dim2, 1, true, adj, Interface::UNION );
            }
            if( generate[2] )
            {
                gMB->get_adjacencies( dim3, 2, true, adj, Interface::UNION );
            }
            if( sets[i] ) gMB->add_entities( sets[i], adj );
        }
    }

    // Delete any entities not of the dimensions to be exported
    if( bydim )
    {
        // Get list of dead elements
        Range dead_entities, tmp_range;
        for( dim = 1; dim <= 3; ++dim )
        {
            if( dims[dim] ) continue;
            gMB->get_entities_by_dimension( 0, dim, tmp_range );
            dead_entities.merge( tmp_range );
        }
        // Remove dead entities from all sets, and add all
        // empty sets to list of dead entities.
        Range empty_sets;
        remove_entities_from_sets( gMB, dead_entities, empty_sets );
        while( !empty_sets.empty() )
        {
            if( !set_list.empty() ) remove_from_vector( set_list, empty_sets );
            dead_entities.merge( empty_sets );
            tmp_range.clear();
            remove_entities_from_sets( gMB, empty_sets, tmp_range );
            empty_sets = subtract( tmp_range, dead_entities );
        }
        // Destroy dead entities
        gMB->delete_entities( dead_entities );
    }

    // If user specified sets to write, but none were found, exit.
    if( have_sets && set_list.empty() )
    {
        std::cerr << "Nothing to write." << std::endl;
#ifdef MOAB_HAVE_MPI
        MPI_Finalize();
#endif
        return ENT_NOT_FOUND;
    }

    // interpret the mpas partition file created by gpmetis
    if( !metis_partition_file.empty() )
    {
        int err = process_partition_file( gMB, metis_partition_file );
        if( err )
        {
            std::cerr << "Failed to process partition file \"" << metis_partition_file << "\"." << std::endl;
#ifdef MOAB_HAVE_MPI
            MPI_Finalize();
#endif
            return WRITE_ERROR;
        }
    }
    if( verbose )
    {
        if( have_sets )
            std::cout << "Found " << set_list.size() << " specified sets to write (total)." << std::endl;
        else
            std::cout << "No sets specifed.  Writing entire mesh." << std::endl;
    }

    // Write the output file
    reset_times();
#ifdef MOAB_HAVE_TEMPESTREMAP
    Range faces;
    Mesh* tempestMesh =
        remapper->GetMesh( ( use_overlap_context ? moab::Remapper::OverlapMesh : moab::Remapper::SourceMesh ) );
    moab::EntityHandle& srcmesh =
        remapper->GetMeshSet( ( use_overlap_context ? moab::Remapper::OverlapMesh : moab::Remapper::SourceMesh ) );
    result = gMB->get_entities_by_dimension( srcmesh, 2, faces );MB_CHK_ERR( result );
    int ntot_elements = 0, nelements = faces.size();
#ifdef MOAB_HAVE_MPI
    int ierr = MPI_Allreduce( &nelements, &ntot_elements, 1, MPI_INT, MPI_SUM, pcomm->comm() );
    if( ierr != 0 ) MB_CHK_SET_ERR( MB_FAILURE, "MPI_Allreduce failed to get total source elements" );
#else
    ntot_elements             = nelements;
#endif

    Tag gidTag = gMB->globalId_tag();
    std::vector< int > gids( faces.size() );
    result = gMB->tag_get_data( gidTag, faces, &gids[0] );MB_CHK_ERR( result );

    if( faces.size() > 1 && gids[0] == gids[1] && !use_overlap_context )
    {
#ifdef MOAB_HAVE_MPI
        result = pcomm->assign_global_ids( srcmesh, 2, 1, false );MB_CHK_ERR( result );
#else
        result = remapper->assign_vertex_element_IDs( gidTag, srcmesh, 2, 1 );MB_CHK_ERR( result );
        result = remapper->assign_vertex_element_IDs( gidTag, srcmesh, 0, 1 );MB_CHK_ERR( result );
#endif
    }

    // VSM: If user requested explicitly for some metadata, we need to generate the DoF ID tag
    // and set the appropriate numbering based on specified discretization order
    // Useful only for SE meshes with GLL DoFs
    if( spectral_order > 1 && globalid_tag_name.size() > 1 )
    {
        result = remapper->GenerateMeshMetadata( *tempestMesh, ntot_elements, faces, NULL, globalid_tag_name,
                                                 spectral_order );MB_CHK_ERR( result );
    }

    if( tempestout )
    {
        // Check if our MOAB mesh has RED and BLUE tags; this would indicate we are converting an
        // overlap grid
        if( use_overlap_context && false )
        {
            const int nOverlapFaces = faces.size();
            // Overlap mesh: resize the source and target connection arrays
            tempestMesh->vecSourceFaceIx.resize( nOverlapFaces );  // 0-based indices corresponding to source mesh
            tempestMesh->vecTargetFaceIx.resize( nOverlapFaces );  // 0-based indices corresponding to target mesh
            result = gMB->tag_get_data( srcParentTag, faces, &tempestMesh->vecSourceFaceIx[0] );MB_CHK_ERR( result );
            result = gMB->tag_get_data( tgtParentTag, faces, &tempestMesh->vecTargetFaceIx[0] );MB_CHK_ERR( result );
        }
        // Write out the mesh using TempestRemap
        tempestMesh->Write( out, NcFile::Netcdf4 );
    }
    else
    {
#endif

        if( have_sets )
            result = gMB->write_file( out.c_str(), format, write_options.c_str(), &set_list[0], set_list.size() );
        else
            result = gMB->write_file( out.c_str(), format, write_options.c_str() );
        if( MB_SUCCESS != result )
        {
            std::cerr << "Failed to write \"" << out << "\"." << std::endl;
            std::cerr << "Error code: " << gMB->get_error_string( result ) << " (" << result << ")" << std::endl;
            std::string message;
            if( MB_SUCCESS == gMB->get_last_error( message ) && !message.empty() )
                std::cerr << "Error message: " << message << std::endl;
#ifdef MOAB_HAVE_MPI
            MPI_Finalize();
#endif
            return WRITE_ERROR;
        }
#ifdef MOAB_HAVE_TEMPESTREMAP
    }
    delete remapper;
#endif

    if( !proc_id ) std::cerr << "Wrote \"" << out << "\"" << std::endl;
    if( print_times && !proc_id ) write_times( std::cout );

#ifdef MOAB_HAVE_MPI
    MPI_Finalize();
#endif
    return 0;
}
bool make_opts_string ( std::vector< std::string >  options,
std::string &  result 
) [static]

Definition at line 1086 of file convert.cpp.

Referenced by main().

{
    opts.clear();
    if( options.empty() ) return true;

    // choose a separator character
    std::vector< std::string >::const_iterator i;
    char separator             = '\0';
    const char* alt_separators = ";+,:\t\n";
    for( const char* sep_ptr = alt_separators; *sep_ptr; ++sep_ptr )
    {
        bool seen = false;
        for( i = options.begin(); i != options.end(); ++i )
            if( i->find( *sep_ptr, 0 ) != std::string::npos )
            {
                seen = true;
                break;
            }
        if( !seen )
        {
            separator = *sep_ptr;
            break;
        }
    }
    if( !separator )
    {
        std::cerr << "Error: cannot find separator character for options string" << std::endl;
        return false;
    }
    if( separator != ';' )
    {
        opts = ";";
        opts += separator;
    }

    // concatenate options
    i = options.begin();
    opts += *i;
    for( ++i; i != options.end(); ++i )
    {
        opts += separator;
        opts += *i;
    }

    return true;
}
bool parse_id_list ( const char *  string,
std::set< int > &  results 
) [static]

Definition at line 943 of file convert.cpp.

Referenced by main().

{
    bool okay   = true;
    char* mystr = strdup( string );
    for( const char* ptr = strtok( mystr, "," ); ptr; ptr = strtok( 0, "," ) )
    {
        char* endptr;
        long val = strtol( ptr, &endptr, 0 );
        if( endptr == ptr || val <= 0 )
        {
            std::cerr << "Not a valid id: " << ptr << std::endl;
            okay = false;
            break;
        }

        long val2 = val;
        if( *endptr == '-' )
        {
            const char* sptr = endptr + 1;
            val2             = strtol( sptr, &endptr, 0 );
            if( endptr == sptr || val2 <= 0 )
            {
                std::cerr << "Not a valid id: " << sptr << std::endl;
                okay = false;
                break;
            }
            if( val2 < val )
            {
                std::cerr << "Invalid id range: " << ptr << std::endl;
                okay = false;
                break;
            }
        }

        if( *endptr )
        {
            std::cerr << "Unexpected character: " << *endptr << std::endl;
            okay = false;
            break;
        }

        for( ; val <= val2; ++val )
            if( !results.insert( (int)val ).second ) std::cerr << "Warning: duplicate Id: " << val << std::endl;
    }

    free( mystr );
    return okay;
}
std::string percent_subst ( const std::string &  s,
int  val 
) [static]

Definition at line 1205 of file convert.cpp.

Referenced by main().

{
    if( s.empty() ) return s;

    size_t j = s.find( '%' );
    if( j == std::string::npos ) return s;

    std::ostringstream st;
    st << s.substr( 0, j );
    st << val;

    size_t i;
    while( ( i = s.find( '%', j + 1 ) ) != std::string::npos )
    {
        st << s.substr( j, i - j );
        st << val;
        j = i;
    }
    st << s.substr( j + 1 );
    return st.str();
}
static void print_help ( const char *  name) [static]

Definition at line 117 of file convert.cpp.

References print_usage().

Referenced by main().

{
    std::cout << " This program can be used to convert between mesh file\n"
                 " formats, extract a subset of a mesh file to a separate\n"
                 " file, or both.  The type of file to write is determined\n"
                 " from the file extension (e.g. \".vtk\") portion of the\n"
                 " output file name.\n"
                 " \n"
                 " While MOAB strives to export and import all data from\n"
                 " each supported file format, most file formats do\n"
                 " not support MOAB's entire data model.  Thus MOAB cannot\n"
                 " guarantee lossless conversion for any file formats\n"
                 " other than the native HDF5 representation.\n"
                 "\n";

    print_usage( name, std::cout );
    exit( 0 );
}
void print_id_list ( const char *  head,
std::ostream &  stream,
const std::set< int > &  list 
) [static]

Definition at line 992 of file convert.cpp.

Referenced by main().

{
    stream << head << ": ";

    if( list.empty() )
    {
        stream << "(none)" << std::endl;
        return;
    }

    int start, prev;
    std::set< int >::const_iterator iter = list.begin();
    start = prev = *( iter++ );
    for( ;; )
    {
        if( iter == list.end() || *iter != 1 + prev )
        {
            stream << start;
            if( prev != start ) stream << '-' << prev;
            if( iter == list.end() ) break;
            stream << ", ";
            start = *iter;
        }
        prev = *( iter++ );
    }

    stream << std::endl;
}
static void print_time ( int  clk_per_sec,
const char *  prefix,
clock_t  ticks,
std::ostream &  stream 
) [static]

Definition at line 1021 of file convert.cpp.

Referenced by build_coords(), main(), testA(), testB(), testC(), testD(), testE(), and write_times().

{
    ticks *= clk_per_sec / 100;
    clock_t centi   = ticks % 100;
    clock_t seconds = ticks / 100;
    stream << prefix;
    if( seconds < 120 )
    {
        stream << ( ticks / 100 ) << "." << centi << "s" << std::endl;
    }
    else
    {
        clock_t minutes = ( seconds / 60 ) % 60;
        clock_t hours   = ( seconds / 3600 );
        seconds %= 60;
        if( hours ) stream << hours << "h";
        if( minutes ) stream << minutes << "m";
        if( seconds || centi ) stream << seconds << "." << centi << "s";
        stream << " (" << ( ticks / 100 ) << "." << centi << "s)" << std::endl;
    }
}
static void print_usage ( const char *  name,
std::ostream &  stream 
) [static]

Definition at line 59 of file convert.cpp.

Referenced by main(), print_help(), and usage_error().

{
    stream << "Usage: " << name
           << " [-a <sat_file>|-A] [-t] [subset options] [-f format] <input_file> [<input_file2> "
              "...] <output_file>"
           << std::endl
           << "\t-f <format>    - Specify output file format" << std::endl
           << "\t-a <acis_file> - ACIS SAT file dumped by .cub reader (same as \"-o "
              "SAT_FILE=acis_file\""
           << std::endl
           << "\t-A             - .cub file reader should not dump a SAT file (depricated default)" << std::endl
           << "\t-o option      - Specify write option." << std::endl
           << "\t-O option      - Specify read option." << std::endl
           << "\t-t             - Time read and write of files." << std::endl
           << "\t-g             - Enable verbose/debug output." << std::endl
           << "\t-h             - Print this help text and exit." << std::endl
           << "\t-l             - List available file formats and exit." << std::endl
           << "\t-I <dim>       - Generate internal entities of specified dimension." << std::endl
#ifdef MOAB_HAVE_MPI
           << "\t-P             - Append processor ID to output file name" << std::endl
           << "\t-p             - Replace '%' with processor ID in input and output file name" << std::endl
           << "\t-M[0|1|2]      - Read/write in parallel, optionally also doing "
              "resolve_shared_ents (1) and exchange_ghosts (2)"
           << std::endl
           << "\t-z <file>      - Read metis partition information corresponding to an MPAS grid "
              "file and create h5m partition file"
           << std::endl
#endif

#ifdef MOAB_HAVE_TEMPESTREMAP
           << "\t-B             - Use TempestRemap exodus file reader and convert to MOAB format" << std::endl
           << "\t-b             - Convert MOAB mesh to TempestRemap exodus file writer" << std::endl
           << "\t-i             - Name of the global DoF tag to use with mbtempest" << std::endl
           << "\t-r             - Order of field DoF (discretization) data; FV=1,SE=[1,N]" << std::endl
#endif
           << "\t--             - treat all subsequent options as file names" << std::endl
           << "\t                 (allows file names beginning with '-')" << std::endl
           << "  subset options: " << std::endl
           << "\tEach of the following options should be followed by " << std::endl
           << "\ta list of ids.  IDs may be separated with commas.  " << std::endl
           << "\tRanges of IDs may be specified with a '-' between " << std::endl
           << "\ttwo values.  The list may not contain spaces." << std::endl
           << "\t-v  - Volume" << std::endl
           << "\t-s  - Surface" << std::endl
           << "\t-c  - Curve" << std::endl
           << "\t-V  - Vertex" << std::endl
           << "\t-m  - Material set (block)" << std::endl
           << "\t-d  - Dirichlet set (nodeset)" << std::endl
           << "\t-n  - Neumann set (sideset)" << std::endl
           << "\t-D  - Parallel partitioning set (PARALLEL_PARTITION)" << std::endl
           << "\tThe presence of one or more of the following flags limits " << std::endl
           << "\tthe exported mesh to only elements of the corresponding " << std::endl
           << "\tdimension.  Vertices are always exported." << std::endl
           << "\t-1  - Edges " << std::endl
           << "\t-2  - Tri, Quad, Polygon " << std::endl
           << "\t-3  - Tet, Hex, Prism, etc. " << std::endl;
}
int process_partition_file ( Interface gMB,
std::string &  metis_partition_file 
) [static]

Definition at line 1227 of file convert.cpp.

References moab::Interface::add_entities(), moab::Interface::clear_meshset(), moab::Interface::create_meshset(), moab::Range::empty(), ErrorCode, MBMesquite::faces, moab::Interface::get_entities_by_dimension(), moab::Interface::get_entities_by_type_and_tag(), moab::Range::insert(), MB_CHK_ERR, MB_TAG_CREAT, MB_TAG_SPARSE, MB_TYPE_INTEGER, MBENTITYSET, MESHSET_SET, moab::Range::size(), moab::Interface::tag_delete_data(), moab::Interface::tag_get_data(), moab::Interface::tag_get_handle(), moab::Interface::tag_set_data(), and moab::Interface::UNION.

Referenced by main().

{
    // how many faces in the file ? how do we make sure it is an mpas file?
    // mpas atmosphere files can be downloaded from here
    // https://mpas-dev.github.io/atmosphere/atmosphere_meshes.html
    Range faces;
    ErrorCode rval = mb->get_entities_by_dimension( 0, 2, faces );MB_CHK_ERR( rval );
    std::cout << " MPAS model has " << faces.size() << " polygons\n";

    // read the partition file
    std::ifstream partfile;
    partfile.open( metis_partition_file.c_str() );
    std::string line;
    std::vector< int > parts;
    parts.resize( faces.size(), -1 );
    int i = 0;
    if( partfile.is_open() )
    {
        while( getline( partfile, line ) )
        {
            // cout << line << '\n';
            parts[i++] = atoi( line.c_str() );
            if( i > (int)faces.size() )
            {
                std::cerr << " too many lines in partition file \n. bail out \n";
                return 1;
            }
        }
        partfile.close();
    }
    std::vector< int >::iterator pmax = max_element( parts.begin(), parts.end() );
    std::vector< int >::iterator pmin = min_element( parts.begin(), parts.end() );
    if( *pmin <= -1 )
    {
        std::cerr << " partition file is incomplete, *pmin is -1 !! \n";
        return 1;
    }
    std::cout << " partitions range: " << *pmin << " " << *pmax << "\n";
    Tag part_set_tag;
    int dum_id = -1;
    rval = mb->tag_get_handle( "PARALLEL_PARTITION", 1, MB_TYPE_INTEGER, part_set_tag, MB_TAG_SPARSE | MB_TAG_CREAT,
                               &dum_id );MB_CHK_ERR( rval );

    // get any sets already with this tag, and clear them
    // remove the parallel partition sets if they exist
    Range tagged_sets;
    rval = mb->get_entities_by_type_and_tag( 0, MBENTITYSET, &part_set_tag, NULL, 1, tagged_sets, Interface::UNION );MB_CHK_ERR( rval );
    if( !tagged_sets.empty() )
    {
        rval = mb->clear_meshset( tagged_sets );MB_CHK_ERR( rval );
        rval = mb->tag_delete_data( part_set_tag, tagged_sets );MB_CHK_ERR( rval );
    }
    Tag gid;
    rval = mb->tag_get_handle( "GLOBAL_ID", gid );MB_CHK_ERR( rval );
    int num_sets = *pmax + 1;
    if( *pmin != 0 )
    {
        std::cout << " problem reading parts; min is not 0 \n";
        return 1;
    }
    for( i = 0; i < num_sets; i++ )
    {
        EntityHandle new_set;
        rval = mb->create_meshset( MESHSET_SET, new_set );MB_CHK_ERR( rval );
        tagged_sets.insert( new_set );
    }
    int* dum_ids = new int[num_sets];
    for( i = 0; i < num_sets; i++ )
        dum_ids[i] = i;

    rval = mb->tag_set_data( part_set_tag, tagged_sets, dum_ids );MB_CHK_ERR( rval );
    delete[] dum_ids;

    std::vector< int > gids;
    int num_faces = (int)faces.size();
    gids.resize( num_faces );
    rval = mb->tag_get_data( gid, faces, &gids[0] );MB_CHK_ERR( rval );

    for( int j = 0; j < num_faces; j++ )
    {
        int eid         = gids[j];
        EntityHandle eh = faces[j];
        int partition   = parts[eid - 1];
        if( partition < 0 || partition >= num_sets )
        {
            std::cout << " wrong partition number \n";
            return 1;
        }
        rval = mb->add_entities( tagged_sets[partition], &eh, 1 );MB_CHK_ERR( rval );
    }
    return 0;
}
void remove_entities_from_sets ( Interface gMB,
Range dead_entities,
Range empty_sets 
) [static]

Definition at line 1177 of file convert.cpp.

References moab::Range::begin(), moab::Range::clear(), moab::Range::empty(), moab::Range::end(), moab::Interface::get_entities_by_handle(), moab::Interface::get_entities_by_type(), moab::Range::insert(), moab::intersect(), MBENTITYSET, and moab::Interface::remove_entities().

Referenced by main().

{
    empty_sets.clear();
    Range sets;
    gMB->get_entities_by_type( 0, MBENTITYSET, sets );
    for( Range::iterator i = sets.begin(); i != sets.end(); ++i )
    {
        Range set_contents;
        gMB->get_entities_by_handle( *i, set_contents, false );
        set_contents = intersect( set_contents, dead_entities );
        gMB->remove_entities( *i, set_contents );
        set_contents.clear();
        gMB->get_entities_by_handle( *i, set_contents, false );
        if( set_contents.empty() ) empty_sets.insert( *i );
    }
}
void remove_from_vector ( std::vector< EntityHandle > &  vect,
const Range ents_to_remove 
) [static]

Definition at line 1194 of file convert.cpp.

References moab::Range::begin(), and moab::Range::end().

{
    Range::const_iterator i;
    std::vector< EntityHandle >::iterator j;
    for( i = ents_to_remove.begin(); i != ents_to_remove.end(); ++i )
    {
        j = std::find( vect.begin(), vect.end(), *i );
        if( j != vect.end() ) vect.erase( j );
    }
}
void reset_times ( ) [static]

Definition at line 1047 of file convert.cpp.

References abs_time.

Referenced by main().

{
    abs_time = clock();
}
static void usage_error ( const char *  name) [static]

Definition at line 136 of file convert.cpp.

References print_usage(), and USAGE_ERROR.

Referenced by main().

{
    print_usage( name, std::cerr );
#ifdef MOAB_HAVE_MPI
    MPI_Finalize();
#endif
    exit( USAGE_ERROR );
}
void write_times ( std::ostream &  stream) [static]

Definition at line 1052 of file convert.cpp.

References abs_time, and print_time().

Referenced by main().

{
    clock_t abs_tm = clock();
    print_time( CLOCKS_PER_SEC, "  ", abs_tm - abs_time, stream );
    abs_time = abs_tm;
}

Variable Documentation

clock_t abs_time

Definition at line 1043 of file convert.cpp.

Referenced by reset_times(), and write_times().

clock_t sys_time

Definition at line 1043 of file convert.cpp.

Referenced by reset_times(), and write_times().

clock_t usr_time

Definition at line 1043 of file convert.cpp.

Referenced by reset_times(), and write_times().

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines