MOAB: Mesh Oriented datABase  (version 5.4.1)
moab::TempestRemapper Class Reference

#include <TempestRemapper.hpp>

+ Inheritance diagram for moab::TempestRemapper:
+ Collaboration diagram for moab::TempestRemapper:

Public Types

enum  TempestMeshType {
  DEFAULT = -1, CS = 0, RLL = 1, ICO = 2,
  ICOD = 3, OVERLAP_FILES = 4, OVERLAP_MEMORY = 5, OVERLAP_MOAB = 6
}

Public Member Functions

 TempestRemapper (moab::Interface *mbInt)
virtual ~TempestRemapper ()
virtual ErrorCode initialize (bool initialize_fsets=true)
 Initialize the TempestRemapper object internal datastructures including the mesh sets and TempestRemap mesh references.
virtual ErrorCode clear ()
 Deallocate and clear any memory initialized in the TempestRemapper object.
moab::ErrorCode GenerateMesh (Remapper::IntersectionContext ctx, TempestMeshType type)
 Generate a mesh in memory of given type (CS/RLL/ICO/MPAS(structured)) and store it under the context specified by the user.
moab::ErrorCode LoadMesh (Remapper::IntersectionContext ctx, std::string inputFilename, TempestMeshType type)
 Load a mesh from disk of given type and store it under the context specified by the user.
moab::ErrorCode ConstructCoveringSet (double tolerance=1e-8, double radius_src=1.0, double radius_tgt=1.0, double boxeps=0.1, bool regional_mesh=false)
 Construct a source covering mesh such that it completely encompasses the target grid in parallel. This operation is critical to ensure that the parallel advancing-front intersection algorithm can the intersection mesh only locally without any process communication.
moab::ErrorCode ComputeOverlapMesh (bool kdtree_search=true, bool use_tempest=false)
 Compute the intersection mesh between the source and target grids that have been instantiated in the Remapper. This function invokes the parallel advancing-front intersection algorithm internally for spherical meshes and can handle arbitrary unstructured grids (CS, RLL, ICO, MPAS) with and without holes.
moab::ErrorCode ConvertTempestMesh (Remapper::IntersectionContext ctx)
 Convert the TempestRemap mesh object to a corresponding MOAB mesh representation according to the intersection context.
moab::ErrorCode ConvertMeshToTempest (Remapper::IntersectionContext ctx)
 Convert the MOAB mesh representation to a corresponding TempestRemap mesh object according to the intersection context.
Mesh * GetMesh (Remapper::IntersectionContext ctx)
 Get the TempestRemap mesh object according to the intersection context.
void SetMesh (Remapper::IntersectionContext ctx, Mesh *mesh, bool overwrite=true)
 Set the TempestRemap mesh object according to the intersection context.
void SetMeshSet (Remapper::IntersectionContext ctx, moab::EntityHandle mset, moab::Range &entities)
Mesh * GetCoveringMesh ()
 Get the covering mesh (TempestRemap) object.
moab::EntityHandleGetMeshSet (Remapper::IntersectionContext ctx)
 Get the MOAB mesh set corresponding to the intersection context.
moab::EntityHandle GetMeshSet (Remapper::IntersectionContext ctx) const
 Const overload. Get the MOAB mesh set corresponding to the intersection context.
moab::RangeGetMeshEntities (Remapper::IntersectionContext ctx)
 Get the mesh element entities corresponding to the intersection context.
const moab::RangeGetMeshEntities (Remapper::IntersectionContext ctx) const
 Const overload. Get the mesh element entities corresponding to the intersection context.
moab::RangeGetMeshVertices (Remapper::IntersectionContext ctx)
 Get the mesh vertices corresponding to the intersection context. Useful for point-cloud meshes.
const moab::RangeGetMeshVertices (Remapper::IntersectionContext ctx) const
 Const overload. Get the mesh vertices corresponding to the intersection context. Useful for point-cloud meshes.
moab::EntityHandleGetCoveringSet ()
 Get access to the underlying source covering set if available. Else return the source set.
void SetMeshType (Remapper::IntersectionContext ctx, TempestMeshType type, const std::vector< int > *metadata=nullptr)
 Set the mesh type corresponding to the intersection context.
TempestMeshType GetMeshType (Remapper::IntersectionContext ctx) const
 Get the mesh type corresponding to the intersection context.
int GetGlobalID (Remapper::IntersectionContext ctx, int localID)
 Get the global ID corresponding to the local entity ID according to the context (source, target, intersection)
int GetLocalID (Remapper::IntersectionContext ctx, int globalID)
 Get the local ID corresponding to the global entity ID according to the context (source, target, intersection)
moab::ErrorCode WriteTempestIntersectionMesh (std::string strOutputFileName, const bool fAllParallel, const bool fInputConcave, const bool fOutputConcave)
 Gather the overlap mesh and asssociated source/target data and write it out to disk using the TempestRemap output interface. This information can then be used with the "GenerateOfflineMap" tool in TempestRemap as needed.
moab::ErrorCode GenerateCSMeshMetadata (const int ntot_elements, moab::Range &entities, moab::Range *secondary_entities, const std::string &dofTagName, int nP)
 Generate the necessary metadata and specifically the GLL node numbering for DoFs for a CS mesh. This negates the need for running external code like HOMME to output the numbering needed for computing maps. The functionality is used through the `mbconvert` tool to compute processor-invariant Global DoF IDs at GLL nodes.
moab::ErrorCode GenerateMeshMetadata (Mesh &mesh, const int ntot_elements, moab::Range &entities, moab::Range *secondary_entities, const std::string dofTagName, int nP)
 Generate the necessary metadata for DoF node numbering in a given mesh. Currently, only the functionality to generate numbering on CS grids is supported.
moab::ErrorCode ComputeGlobalLocalMaps ()
 Compute the local and global IDs for elements in source/target/coverage meshes.
moab::ErrorCode GetOverlapAugmentedEntities (moab::Range &sharedGhostEntities)
 Get all the ghosted overlap entities that were accumulated to enable conservation in parallel.
moab::ErrorCode assign_vertex_element_IDs (Tag idtag, EntityHandle this_set, const int dimension=2, const int start_id=1)
 Internal method to assign vertex and element global IDs if one does not exist already.
ErrorCode GetIMasks (Remapper::IntersectionContext ctx, std::vector< int > &masks)

Public Attributes

bool meshValidate
bool constructEdgeMap

Static Public Attributes

static const bool verbose = true

Private Member Functions

moab::ErrorCode convert_overlap_mesh_sorted_by_source ()
moab::ErrorCode load_tempest_mesh_private (std::string inputFilename, Mesh **tempest_mesh)
moab::ErrorCode convert_mesh_to_tempest_private (Mesh *mesh, moab::EntityHandle meshset, moab::Range &entities, moab::Range *pverts)
moab::ErrorCode convert_tempest_mesh_private (TempestMeshType type, Mesh *mesh, moab::EntityHandle &meshset, moab::Range &entities, moab::Range *vertices)
moab::ErrorCode augment_overlap_set ()

Private Attributes

Mesh * m_source
TempestMeshType m_source_type
moab::Range m_source_entities
moab::Range m_source_vertices
moab::EntityHandle m_source_set
int max_source_edges
bool point_cloud_source
std::vector< int > m_source_metadata
Mesh * m_target
TempestMeshType m_target_type
moab::Range m_target_entities
moab::Range m_target_vertices
moab::EntityHandle m_target_set
int max_target_edges
bool point_cloud_target
std::vector< int > m_target_metadata
Mesh * m_overlap
TempestMeshType m_overlap_type
moab::Range m_overlap_entities
moab::EntityHandle m_overlap_set
std::vector< std::pair< int,
int > > 
m_sorted_overlap_order
moab::Intx2MeshOnSpherembintx
Mesh * m_covering_source
moab::EntityHandle m_covering_source_set
moab::Range m_covering_source_entities
moab::Range m_covering_source_vertices
std::map< int, int > gid_to_lid_src
std::map< int, int > gid_to_lid_covsrc
std::map< int, int > gid_to_lid_tgt
std::map< int, int > lid_to_gid_src
std::map< int, int > lid_to_gid_covsrc
std::map< int, int > lid_to_gid_tgt
IntxAreaUtils::AreaMethod m_area_method
bool rrmgrids
bool is_parallel
bool is_root
int rank
int size

Friends

class TempestOnlineMap

Detailed Description

Definition at line 36 of file TempestRemapper.hpp.


Member Enumeration Documentation

Enumerator:
DEFAULT 
CS 
RLL 
ICO 
ICOD 
OVERLAP_FILES 
OVERLAP_MEMORY 
OVERLAP_MOAB 

Definition at line 53 of file TempestRemapper.hpp.

    {
        DEFAULT        = -1,
        CS             = 0,
        RLL            = 1,
        ICO            = 2,
        ICOD           = 3,
        OVERLAP_FILES  = 4,
        OVERLAP_MEMORY = 5,
        OVERLAP_MOAB   = 6
    };

Constructor & Destructor Documentation

Definition at line 43 of file TempestRemapper.hpp.

        : Remapper( mbInt ),
#endif
          meshValidate( false ), constructEdgeMap( false ), m_source_type( DEFAULT ), m_target_type( DEFAULT )
    {
    }

Definition at line 90 of file TempestRemapper.cpp.

References clear().

{
    this->clear();
}

Member Function Documentation

ErrorCode moab::TempestRemapper::assign_vertex_element_IDs ( Tag  idtag,
EntityHandle  this_set,
const int  dimension = 2,
const int  start_id = 1 
)

Internal method to assign vertex and element global IDs if one does not exist already.

Definition at line 844 of file TempestRemapper.cpp.

References entities, ErrorCode, moab::Interface::get_entities_by_dimension(), moab::Remapper::m_interface, MB_CHK_ERR, MB_CHK_SET_ERR, MB_SUCCESS, moab::Range::size(), and moab::Interface::tag_set_data().

Referenced by ComputeOverlapMesh(), and main().

{
    assert( idtag );

    ErrorCode rval;
    Range entities;
    rval = m_interface->get_entities_by_dimension( this_set, dimension, entities );MB_CHK_SET_ERR( rval, "Failed to get entities" );

    if( entities.size() == 0 ) return moab::MB_SUCCESS;

    int idoffset = start_id;
    std::vector< int > gid( entities.size() );
    for( unsigned i = 0; i < entities.size(); ++i )
        gid[i] = idoffset++;

    rval = m_interface->tag_set_data( idtag, entities, &gid[0] );MB_CHK_ERR( rval );

    return moab::MB_SUCCESS;
}

Compute the local and global IDs for elements in source/target/coverage meshes.

Definition at line 704 of file TempestRemapper.cpp.

References convert_mesh_to_tempest_private(), ErrorCode, gid_to_lid_covsrc, gid_to_lid_src, gid_to_lid_tgt, moab::Interface::globalId_tag(), ie, lid_to_gid_covsrc, lid_to_gid_src, lid_to_gid_tgt, m_covering_source, m_covering_source_entities, m_covering_source_set, m_covering_source_vertices, moab::Remapper::m_interface, m_source_entities, m_source_vertices, m_target_entities, m_target_vertices, MB_CHK_ERR, MB_CHK_SET_ERR, MB_SUCCESS, point_cloud_source, point_cloud_target, moab::Range::size(), and moab::Interface::tag_get_data().

Referenced by ComputeOverlapMesh().

{
    ErrorCode rval;

    if( 0 == m_covering_source )
    {
        m_covering_source = new Mesh();
        rval = convert_mesh_to_tempest_private( m_covering_source, m_covering_source_set, m_covering_source_entities,
                                                &m_covering_source_vertices );MB_CHK_SET_ERR( rval, "Can't convert source Tempest mesh" );
        // std::cout << "ComputeGlobalLocalMaps: " << rank << ", " << " covering entities = [" <<
        // m_covering_source_vertices.size() << ", " << m_covering_source_entities.size() << "]\n";
    }
    gid_to_lid_src.clear();
    lid_to_gid_src.clear();
    gid_to_lid_covsrc.clear();
    lid_to_gid_covsrc.clear();
    gid_to_lid_tgt.clear();
    lid_to_gid_tgt.clear();
    {
        Tag gidtag = m_interface->globalId_tag();

        std::vector< int > gids;
        if( point_cloud_source )
        {
            gids.resize( m_covering_source_vertices.size(), -1 );
            rval = m_interface->tag_get_data( gidtag, m_covering_source_vertices, &gids[0] );MB_CHK_ERR( rval );
        }
        else
        {
            gids.resize( m_covering_source_entities.size(), -1 );
            rval = m_interface->tag_get_data( gidtag, m_covering_source_entities, &gids[0] );MB_CHK_ERR( rval );
        }
        for( unsigned ie = 0; ie < gids.size(); ++ie )
        {
            gid_to_lid_covsrc[gids[ie]] = ie;
            lid_to_gid_covsrc[ie]       = gids[ie];
        }

        if( point_cloud_source )
        {
            gids.resize( m_source_vertices.size(), -1 );
            rval = m_interface->tag_get_data( gidtag, m_source_vertices, &gids[0] );MB_CHK_ERR( rval );
        }
        else
        {
            gids.resize( m_source_entities.size(), -1 );
            rval = m_interface->tag_get_data( gidtag, m_source_entities, &gids[0] );MB_CHK_ERR( rval );
        }
        for( unsigned ie = 0; ie < gids.size(); ++ie )
        {
            gid_to_lid_src[gids[ie]] = ie;
            lid_to_gid_src[ie]       = gids[ie];
        }

        if( point_cloud_target )
        {
            gids.resize( m_target_vertices.size(), -1 );
            rval = m_interface->tag_get_data( gidtag, m_target_vertices, &gids[0] );MB_CHK_ERR( rval );
        }
        else
        {
            gids.resize( m_target_entities.size(), -1 );
            rval = m_interface->tag_get_data( gidtag, m_target_entities, &gids[0] );MB_CHK_ERR( rval );
        }
        for( unsigned ie = 0; ie < gids.size(); ++ie )
        {
            gid_to_lid_tgt[gids[ie]] = ie;
            lid_to_gid_tgt[ie]       = gids[ie];
        }
    }

    return MB_SUCCESS;
}
ErrorCode moab::TempestRemapper::ComputeOverlapMesh ( bool  kdtree_search = true,
bool  use_tempest = false 
)

Compute the intersection mesh between the source and target grids that have been instantiated in the Remapper. This function invokes the parallel advancing-front intersection algorithm internally for spherical meshes and can handle arbitrary unstructured grids (CS, RLL, ICO, MPAS) with and without holes.

Definition at line 1196 of file TempestRemapper.cpp.

References assign_vertex_element_IDs(), augment_overlap_set(), moab::Range::begin(), ComputeGlobalLocalMaps(), convert_overlap_mesh_sorted_by_source(), dbgprint, moab::Range::end(), ErrorCode, moab::IntxUtils::fix_degenerate_quads(), moab::Interface::get_entities_by_dimension(), moab::Interface::globalId_tag(), ie, moab::Range::insert(), moab::Intx2Mesh::intersect_meshes(), moab::Intx2Mesh::intersect_meshes_kdtree(), is_parallel, m_covering_source, m_covering_source_set, moab::Remapper::m_interface, m_overlap, m_overlap_set, m_source, m_source_entities, m_source_set, m_target, m_target_entities, m_target_set, MB_CHK_ERR, MB_CHK_SET_ERR, MB_SUCCESS, mbintx, point_cloud_target, moab::IntxAreaUtils::positive_orientation(), moab::DebugOutput::printf(), rank, moab::Interface::remove_entities(), rrmgrids, moab::DebugOutput::set_prefix(), moab::Range::size(), size, moab::subtract(), moab::Interface::tag_get_data(), moab::Interface::tag_get_handle(), and moab::Interface::write_mesh().

Referenced by main().

{
    ErrorCode rval;
    const bool outputEnabled = ( this->rank == 0 );
    moab::DebugOutput dbgprint( std::cout, this->rank, 0 );
    dbgprint.set_prefix( "[ComputeOverlapMesh]: " );

    // const double radius = 1.0 /*2.0*acos(-1.0)*/;
    // const double boxeps = 0.1;
    // Create the intersection on the sphere object and set up necessary parameters

    // First, split based on whether to use Tempest or MOAB
    // If Tempest
    //   1) Check for valid Mesh and pointers to objects for source/target
    //   2) Invoke GenerateOverlapWithMeshes routine from Tempest library
    // If MOAB
    //   1) Check for valid source and target meshsets (and entities)
    //   2) Build processor bounding boxes and construct a covering set
    //   3) Perform intersection between the source (covering) and target entities
    if( use_tempest )
    {
        // Now let us construct the overlap mesh, by calling TempestRemap interface directly
        // For the overlap method, choose between: "fuzzy", "exact" or "mixed"
        assert( m_source != NULL );
        assert( m_target != NULL );
        if( m_overlap != NULL ) delete m_overlap;
        m_overlap         = new Mesh();
        bool concaveMeshA = false, concaveMeshB = false;
        int err = GenerateOverlapWithMeshes( *m_covering_source, *m_target, *m_overlap, "" /*outFilename*/, "Netcdf4",
                                             "exact", concaveMeshA, concaveMeshB, false );
        if( err )
        {
            MB_CHK_SET_ERR( MB_FAILURE, "TempestRemap: Can't compute the intersection of meshes on the sphere" );
        }
    }
    else
    {
        Tag gidtag = m_interface->globalId_tag();
        moab::EntityHandle subrange[2];
        int gid[2];
        if( m_source_entities.size() > 1 )
        {  // Let us do some sanity checking to fix ID if they have are setup incorrectly
            subrange[0] = m_source_entities[0];
            subrange[1] = m_source_entities[1];
            rval        = m_interface->tag_get_data( gidtag, subrange, 2, gid );MB_CHK_ERR( rval );

            // Check if we need to impose Global ID numbering for vertices and elements. This may be
            // needed if we load the meshes from exodus or some other formats that may not have a
            // numbering forced.
            if( gid[0] + gid[1] == 0 )  // this implies first two elements have GID = 0
            {
#ifdef MOAB_HAVE_MPI
                rval = m_pcomm->assign_global_ids( m_source_set, 2, 1, false, true, false );MB_CHK_ERR( rval );
#else
                rval = this->assign_vertex_element_IDs( gidtag, m_source_set, 2, 1 );MB_CHK_ERR( rval );
#endif
            }
        }
        if( m_target_entities.size() > 1 )
        {
            subrange[0] = m_target_entities[0];
            subrange[1] = m_target_entities[1];
            rval        = m_interface->tag_get_data( gidtag, subrange, 2, gid );MB_CHK_ERR( rval );

            // Check if we need to impose Global ID numbering for vertices and elements. This may be
            // needed if we load the meshes from exodus or some other formats that may not have a
            // numbering forced.
            if( gid[0] + gid[1] == 0 )  // this implies first two elements have GID = 0
            {
#ifdef MOAB_HAVE_MPI
                rval = m_pcomm->assign_global_ids( m_target_set, 2, 1, false, true, false );MB_CHK_ERR( rval );
#else
                rval = this->assign_vertex_element_IDs( gidtag, m_target_set, 2, 1 );MB_CHK_ERR( rval );
#endif
            }
        }

        // Now perform the actual parallel intersection between the source and the target meshes
        if( kdtree_search )
        {
            if( outputEnabled ) dbgprint.printf( 0, "Computing intersection mesh with the Kd-tree search algorithm" );
            rval = mbintx->intersect_meshes_kdtree( m_covering_source_set, m_target_set, m_overlap_set );MB_CHK_SET_ERR( rval, "Can't compute the intersection of meshes on the sphere with brute-force" );
        }
        else
        {
            if( outputEnabled )
                dbgprint.printf( 0, "Computing intersection mesh with the advancing-front propagation algorithm" );
            rval = mbintx->intersect_meshes( m_covering_source_set, m_target_set, m_overlap_set );MB_CHK_SET_ERR( rval, "Can't compute the intersection of meshes on the sphere" );
        }

#ifdef MOAB_HAVE_MPI
        if( is_parallel || rrmgrids )
        {
#ifdef VERBOSE
            std::stringstream ffc, fft, ffo;
            ffc << "cover_" << rank << ".h5m";
            fft << "target_" << rank << ".h5m";
            ffo << "intx_" << rank << ".h5m";
            rval = m_interface->write_mesh( ffc.str().c_str(), &m_covering_source_set, 1 );MB_CHK_ERR( rval );
            rval = m_interface->write_mesh( fft.str().c_str(), &m_target_set, 1 );MB_CHK_ERR( rval );
            rval = m_interface->write_mesh( ffo.str().c_str(), &m_overlap_set, 1 );MB_CHK_ERR( rval );
#endif
            // because we do not want to work with elements in coverage set that do not participate
            // in intersection, remove them from the coverage set we will not delete them yet, just
            // remove from the set !
            if( !point_cloud_target )
            {
                Range covEnts;
                rval = m_interface->get_entities_by_dimension( m_covering_source_set, 2, covEnts );MB_CHK_ERR( rval );
                Tag gidtag = m_interface->globalId_tag();

                std::map< int, int > loc_gid_to_lid_covsrc;
                std::vector< int > gids( covEnts.size(), -1 );
                rval = m_interface->tag_get_data( gidtag, covEnts, &gids[0] );MB_CHK_ERR( rval );
                for( unsigned ie = 0; ie < gids.size(); ++ie )
                {
                    loc_gid_to_lid_covsrc[gids[ie]] = ie;
                }

                Range intxCov;
                Range intxCells;
                Tag srcParentTag;
                rval = m_interface->tag_get_handle( "SourceParent", srcParentTag );MB_CHK_ERR( rval );
                rval = m_interface->get_entities_by_dimension( m_overlap_set, 2, intxCells );MB_CHK_ERR( rval );
                for( Range::iterator it = intxCells.begin(); it != intxCells.end(); it++ )
                {
                    EntityHandle intxCell = *it;
                    int blueParent        = -1;
                    rval                  = m_interface->tag_get_data( srcParentTag, &intxCell, 1, &blueParent );MB_CHK_ERR( rval );
                    // if (is_root) std::cout << "Found intersecting element: " << blueParent << ",
                    // " << gid_to_lid_covsrc[blueParent] << "\n";
                    assert( blueParent >= 0 );
                    intxCov.insert( covEnts[loc_gid_to_lid_covsrc[blueParent]] );
                }

                Range notNeededCovCells = moab::subtract( covEnts, intxCov );
                // remove now from coverage set the cells that are not needed
                rval = m_interface->remove_entities( m_covering_source_set, notNeededCovCells );MB_CHK_ERR( rval );
                covEnts = moab::subtract( covEnts, notNeededCovCells );
#ifdef VERBOSE
                std::cout << " total participating elements in the covering set: " << intxCov.size() << "\n";
                std::cout << " remove from coverage set elements that are not intersected: " << notNeededCovCells.size()
                          << "\n";
#endif
                if( size > 1 )
                {
                    // some source elements cover multiple target partitions; the conservation logic
                    // requires to know all overlap elements for a source element; they need to be
                    // communicated from the other target partitions
                    //
                    // so first we have to identify source (coverage) elements that cover multiple
                    // target partitions

                    // we will then mark the source, we will need to migrate the overlap elements
                    // that cover this to the original source for the source element; then
                    // distribute the overlap elements to all processors that have the coverage mesh
                    // used

                    rval = augment_overlap_set();MB_CHK_ERR( rval );
                }
            }

            // m_covering_source = new Mesh();
            // rval = convert_mesh_to_tempest_private ( m_covering_source, m_covering_source_set,
            // m_covering_source_entities, &m_covering_source_vertices ); MB_CHK_SET_ERR ( rval,
            // "Can't convert source Tempest mesh" );
        }
#endif

        // Fix any inconsistencies in the overlap mesh
        {
            IntxAreaUtils areaAdaptor;
            rval = IntxUtils::fix_degenerate_quads( m_interface, m_overlap_set );MB_CHK_ERR( rval );
            rval = areaAdaptor.positive_orientation( m_interface, m_overlap_set, 1.0 /*radius*/ );MB_CHK_ERR( rval );
        }

        // Now let us re-convert the MOAB mesh back to Tempest representation
        rval = this->ComputeGlobalLocalMaps();MB_CHK_ERR( rval );

        rval = this->convert_overlap_mesh_sorted_by_source();MB_CHK_ERR( rval );

        // free the memory
        delete mbintx;
    }

    return MB_SUCCESS;
}
ErrorCode moab::TempestRemapper::ConstructCoveringSet ( double  tolerance = 1e-8,
double  radius_src = 1.0,
double  radius_tgt = 1.0,
double  boxeps = 0.1,
bool  regional_mesh = false 
)

Construct a source covering mesh such that it completely encompasses the target grid in parallel. This operation is critical to ensure that the parallel advancing-front intersection algorithm can the intersection mesh only locally without any process communication.

Definition at line 1059 of file TempestRemapper.cpp.

References moab::Interface::add_entities(), moab::AdaptiveKDTree::build_tree(), moab::Interface::create_meshset(), ErrorCode, moab::Intx2Mesh::FindMaxEdges(), moab::Interface::get_connectivity(), moab::Interface::get_coords(), moab::Interface::get_entities_by_dimension(), ie, moab::Range::insert(), is_parallel, leaf, m_covering_source, m_covering_source_entities, m_covering_source_set, m_covering_source_vertices, moab::Remapper::m_interface, m_source, m_source_entities, m_source_set, m_source_vertices, m_target_entities, m_target_set, moab::Intx2Mesh::max_edges_1, moab::Intx2Mesh::max_edges_2, max_source_edges, max_target_edges, MB_CHK_ERR, MB_CHK_SET_ERR, mbintx, MESHSET_SET, moab::AdaptiveKDTree::point_search(), rrmgrids, moab::Intx2Mesh::set_box_error(), moab::Intx2Mesh::set_error_tolerance(), moab::Intx2MeshOnSphere::set_radius_destination_mesh(), moab::Intx2MeshOnSphere::set_radius_source_mesh(), moab::Range::size(), and tree.

Referenced by main().

{
    ErrorCode rval;

    rrmgrids = regional_mesh;
    moab::Range local_verts;

    // Initialize intersection context
    mbintx = new moab::Intx2MeshOnSphere( m_interface );

    mbintx->set_error_tolerance( tolerance );
    mbintx->set_radius_source_mesh( radius_src );
    mbintx->set_radius_destination_mesh( radius_tgt );
    mbintx->set_box_error( boxeps );
#ifdef MOAB_HAVE_MPI
    mbintx->set_parallel_comm( m_pcomm );
#endif

    // compute the maxiumum edges in elements comprising source and target mesh
    rval = mbintx->FindMaxEdges( m_source_set, m_target_set );MB_CHK_ERR( rval );

    this->max_source_edges = mbintx->max_edges_1;
    this->max_target_edges = mbintx->max_edges_2;

    // Note: lots of communication possible, if mesh is distributed very differently
#ifdef MOAB_HAVE_MPI
    if( is_parallel )
    {
        rval = mbintx->build_processor_euler_boxes( m_target_set, local_verts );MB_CHK_ERR( rval );

        rval = m_interface->create_meshset( moab::MESHSET_SET, m_covering_source_set );MB_CHK_SET_ERR( rval, "Can't create new set" );

        rval = mbintx->construct_covering_set( m_source_set, m_covering_source_set );MB_CHK_ERR( rval );
        // if (rank == 1)
        // {
        //     moab::Range ents;
        //     m_interface->get_entities_by_dimension(m_covering_source_set, 2, ents);
        //     m_interface->remove_entities(m_covering_source_set, ents);
        // }
    }
    else
    {
#endif
        if( rrmgrids )
        {
            rval = m_interface->create_meshset( moab::MESHSET_SET, m_covering_source_set );MB_CHK_SET_ERR( rval, "Can't create new set" );

            double tolerance = 1e-6, btolerance = 1e-3;
            moab::AdaptiveKDTree tree( m_interface );
            moab::Range targetVerts;

            rval = m_interface->get_connectivity( m_target_entities, targetVerts, true );MB_CHK_ERR( rval );

            rval = tree.build_tree( m_source_entities, &m_source_set );MB_CHK_ERR( rval );

            for( unsigned ie = 0; ie < targetVerts.size(); ++ie )
            {
                EntityHandle el = targetVerts[ie], leaf;
                double point[3];

                // Get the element centroid to be queried
                rval = m_interface->get_coords( &el, 1, point );MB_CHK_ERR( rval );

                // Search for the closest source element in the master mesh corresponding
                // to the target element centroid in the slave mesh
                rval = tree.point_search( point, leaf, tolerance, btolerance );MB_CHK_ERR( rval );

                if( leaf == 0 )
                {
                    leaf = m_source_set;  // no hint
                }

                std::vector< moab::EntityHandle > leaf_elems;
                // We only care about the dimension that the user specified.
                // MOAB partitions are ordered by elements anyway.
                rval = m_interface->get_entities_by_dimension( leaf, 2, leaf_elems );MB_CHK_ERR( rval );

                if( !leaf_elems.size() )
                {
                    // std::cout << ie << ": " << " No leaf elements found." << std::endl;
                    continue;
                }

                // Now get the master element centroids so that we can compute
                // the minimum distance to the target point
                std::vector< double > centroids( leaf_elems.size() * 3 );
                rval = m_interface->get_coords( &leaf_elems[0], leaf_elems.size(), &centroids[0] );MB_CHK_ERR( rval );

                double dist = 1e5;
                int pinelem = -1;
                for( size_t il = 0; il < leaf_elems.size(); ++il )
                {
                    const double* centroid = &centroids[il * 3];
                    const double locdist   = std::pow( point[0] - centroid[0], 2 ) +
                                           std::pow( point[1] - centroid[1], 2 ) +
                                           std::pow( point[2] - centroid[2], 2 );

                    if( locdist < dist )
                    {
                        dist    = locdist;
                        pinelem = il;
                        m_covering_source_entities.insert( leaf_elems[il] );
                    }
                }

                if( pinelem < 0 )
                {
                    std::cout << ie
                              << ": [Error] - Could not find a minimum distance within the leaf "
                                 "nodes. Dist = "
                              << dist << std::endl;
                }
            }
            // rval = tree.reset_tree();MB_CHK_ERR(rval);
            std::cout << "[INFO] - Total covering source entities = " << m_covering_source_entities.size() << std::endl;
            rval = m_interface->add_entities( m_covering_source_set, m_covering_source_entities );MB_CHK_ERR( rval );
        }
        else
        {
            m_covering_source_set      = m_source_set;
            m_covering_source          = m_source;
            m_covering_source_entities = m_source_entities;  // this is a tempest mesh object; careful about
                                                             // incrementing the reference?
            m_covering_source_vertices = m_source_vertices;  // this is a tempest mesh object; careful about
                                                             // incrementing the reference?
        }
#ifdef MOAB_HAVE_MPI
    }
#endif

    return rval;
}
ErrorCode moab::TempestRemapper::convert_mesh_to_tempest_private ( Mesh *  mesh,
moab::EntityHandle  meshset,
moab::Range entities,
moab::Range pverts 
) [private]

Definition at line 437 of file TempestRemapper.cpp.

References moab::Range::begin(), moab::Range::clear(), moab::Range::compactness(), constructEdgeMap, moab::Range::end(), ErrorCode, moab::Interface::get_connectivity(), moab::Interface::get_coords(), moab::Interface::get_entities_by_dimension(), iface, moab::Range::index(), moab::Remapper::m_interface, MB_CHK_ERR, MB_SUCCESS, and moab::Range::size().

Referenced by ComputeGlobalLocalMaps(), and ConvertMeshToTempest().

{
    ErrorCode rval;
    Range verts;

    NodeVector& nodes = mesh->nodes;
    FaceVector& faces = mesh->faces;

    elems.clear();
    rval = m_interface->get_entities_by_dimension( mesh_set, 2, elems );MB_CHK_ERR( rval );

    // resize the number of elements in Tempest mesh
    faces.resize( elems.size() );

    // let us now get the vertices from all the elements
    rval = m_interface->get_connectivity( elems, verts );MB_CHK_ERR( rval );
    if( verts.size() == 0 )
    {
        rval = m_interface->get_entities_by_dimension( mesh_set, 0, verts );MB_CHK_ERR( rval );
    }
    // assert(verts.size() > 0); // If not, this may be an invalid mesh ! possible for unbalanced
    // loads

    std::map< EntityHandle, int > indxMap;
    bool useRange = true;
    if( verts.compactness() > 0.01 )
    {
        int j = 0;
        for( Range::iterator it = verts.begin(); it != verts.end(); it++ )
            indxMap[*it] = j++;
        useRange = false;
    }

    for( unsigned iface = 0; iface < elems.size(); ++iface )
    {
        Face& face           = faces[iface];
        EntityHandle ehandle = elems[iface];

        // get the connectivity for each edge
        const EntityHandle* connectface;
        int nnodesf;
        rval = m_interface->get_connectivity( ehandle, connectface, nnodesf );MB_CHK_ERR( rval );

        face.edges.resize( nnodesf );
        for( int iverts = 0; iverts < nnodesf; ++iverts )
        {
            int indx = ( useRange ? verts.index( connectface[iverts] ) : indxMap[connectface[iverts]] );
            assert( indx >= 0 );
            face.SetNode( iverts, indx );
        }
    }

    unsigned nnodes = verts.size();
    nodes.resize( nnodes );

    // Set the data for the vertices
    std::vector< double > coordx( nnodes ), coordy( nnodes ), coordz( nnodes );
    rval = m_interface->get_coords( verts, &coordx[0], &coordy[0], &coordz[0] );MB_CHK_ERR( rval );
    for( unsigned inode = 0; inode < nnodes; ++inode )
    {
        Node& node = nodes[inode];
        node.x     = coordx[inode];
        node.y     = coordy[inode];
        node.z     = coordz[inode];
    }
    coordx.clear();
    coordy.clear();
    coordz.clear();

    mesh->RemoveZeroEdges();
    mesh->RemoveCoincidentNodes();

    // Generate reverse node array and edge map
    if( constructEdgeMap ) mesh->ConstructEdgeMap( false );
    // mesh->ConstructReverseNodeArray();

    // mesh->Validate();

    if( pverts )
    {
        pverts->clear();
        *pverts = verts;
    }
    verts.clear();

    return MB_SUCCESS;
}

Definition at line 578 of file TempestRemapper.cpp.

References moab::Range::begin(), moab::Range::clear(), moab::Range::compactness(), moab::Range::end(), ErrorCode, moab::Interface::get_connectivity(), moab::Interface::get_coords(), moab::Interface::get_entities_by_dimension(), gid_to_lid_covsrc, gid_to_lid_tgt, ie, iface, moab::Range::index(), moab::IntPairComparator(), is_parallel, moab::Remapper::m_interface, m_overlap, m_overlap_entities, m_overlap_set, MB_CHK_ERR, MB_SUCCESS, moab::Range::size(), size, moab::Interface::tag_get_data(), and moab::Interface::tag_get_handle().

Referenced by ComputeOverlapMesh(), and ConvertMeshToTempest().

{
    ErrorCode rval;

    m_overlap_entities.clear();
    rval = m_interface->get_entities_by_dimension( m_overlap_set, 2, m_overlap_entities );MB_CHK_ERR( rval );

    // Allocate for the overlap mesh
    if( !m_overlap ) m_overlap = new Mesh();

    size_t n_overlap_entitites = m_overlap_entities.size();

    std::vector< std::pair< int, int > > sorted_overlap_order( n_overlap_entitites );
    {
        Tag srcParentTag, tgtParentTag;
        rval = m_interface->tag_get_handle( "SourceParent", srcParentTag );MB_CHK_ERR( rval );
        rval = m_interface->tag_get_handle( "TargetParent", tgtParentTag );MB_CHK_ERR( rval );
        // Overlap mesh: resize the source and target connection arrays
        m_overlap->vecTargetFaceIx.resize( n_overlap_entitites );
        m_overlap->vecSourceFaceIx.resize( n_overlap_entitites );

        // Overlap mesh: resize the source and target connection arrays
        std::vector< int > rbids_src( n_overlap_entitites ), rbids_tgt( n_overlap_entitites );
        rval = m_interface->tag_get_data( srcParentTag, m_overlap_entities, &rbids_src[0] );MB_CHK_ERR( rval );
        rval = m_interface->tag_get_data( tgtParentTag, m_overlap_entities, &rbids_tgt[0] );MB_CHK_ERR( rval );
        for( size_t ix = 0; ix < n_overlap_entitites; ++ix )
        {
            sorted_overlap_order[ix].first =
                ( gid_to_lid_covsrc.size() ? gid_to_lid_covsrc[rbids_src[ix]] : rbids_src[ix] );
            sorted_overlap_order[ix].second = ix;
        }
        std::sort( sorted_overlap_order.begin(), sorted_overlap_order.end(), IntPairComparator );
        // sorted_overlap_order[ie].second , ie=0,nOverlap-1 is the order such that overlap elems
        // are ordered by source parent

        std::vector< int > ghFlags;
        if( is_parallel && size > 1 )
        {
            Tag ghostTag;
            ghFlags.resize( n_overlap_entitites );
            rval = m_interface->tag_get_handle( "ORIG_PROC", ghostTag );MB_CHK_ERR( rval );
            rval = m_interface->tag_get_data( ghostTag, m_overlap_entities, &ghFlags[0] );MB_CHK_ERR( rval );
        }
        for( unsigned ie = 0; ie < n_overlap_entitites; ++ie )
        {
            int ix = sorted_overlap_order[ie].second;  // original index of the element
            m_overlap->vecSourceFaceIx[ie] =
                ( gid_to_lid_covsrc.size() ? gid_to_lid_covsrc[rbids_src[ix]] : rbids_src[ix] - 1 );
            if( is_parallel && size > 1 && ghFlags[ix] >= 0 )  // it means it is a ghost overlap element
                m_overlap->vecTargetFaceIx[ie] = -1;           // this should not participate in smat!
            else
                m_overlap->vecTargetFaceIx[ie] =
                    ( gid_to_lid_tgt.size() ? gid_to_lid_tgt[rbids_tgt[ix]] : rbids_tgt[ix] - 1 );
        }
    }

    FaceVector& faces = m_overlap->faces;
    faces.resize( n_overlap_entitites );

    Range verts;
    // let us now get the vertices from all the elements
    rval = m_interface->get_connectivity( m_overlap_entities, verts );MB_CHK_ERR( rval );
    // std::cout << "Vertices size = " << verts.size() << " , psize = " << verts.psize() << ",
    // compactness = " << verts.compactness() << std::endl;

    std::map< EntityHandle, int > indxMap;
    bool useRange = true;
    if( verts.compactness() > 0.01 )
    {
        int j = 0;
        for( Range::iterator it = verts.begin(); it != verts.end(); ++it )
            indxMap[*it] = j++;
        useRange = false;
    }

    for( unsigned ifac = 0; ifac < m_overlap_entities.size(); ++ifac )
    {
        const unsigned iface = sorted_overlap_order[ifac].second;
        Face& face           = faces[ifac];
        EntityHandle ehandle = m_overlap_entities[iface];

        // get the connectivity for each edge
        const EntityHandle* connectface;
        int nnodesf;
        rval = m_interface->get_connectivity( ehandle, connectface, nnodesf );MB_CHK_ERR( rval );

        face.edges.resize( nnodesf );
        for( int iverts = 0; iverts < nnodesf; ++iverts )
        {
            int indx = ( useRange ? verts.index( connectface[iverts] ) : indxMap[connectface[iverts]] );
            assert( indx >= 0 );
            face.SetNode( iverts, indx );
        }
    }

    unsigned nnodes   = verts.size();
    NodeVector& nodes = m_overlap->nodes;
    nodes.resize( nnodes );

    // Set the data for the vertices
    std::vector< double > coordx( nnodes ), coordy( nnodes ), coordz( nnodes );
    rval = m_interface->get_coords( verts, &coordx[0], &coordy[0], &coordz[0] );MB_CHK_ERR( rval );
    for( unsigned inode = 0; inode < nnodes; ++inode )
    {
        Node& node = nodes[inode];
        node.x     = coordx[inode];
        node.y     = coordy[inode];
        node.z     = coordz[inode];
    }
    coordx.clear();
    coordy.clear();
    coordz.clear();
    verts.clear();

    m_overlap->RemoveZeroEdges();
    m_overlap->RemoveCoincidentNodes( false );

    // Generate reverse node array and edge map
    // if ( constructEdgeMap ) m_overlap->ConstructEdgeMap(false);
    // m_overlap->ConstructReverseNodeArray();

    // m_overlap->Validate();
    return MB_SUCCESS;
}
ErrorCode moab::TempestRemapper::convert_tempest_mesh_private ( TempestMeshType  type,
Mesh *  mesh,
moab::EntityHandle meshset,
moab::Range entities,
moab::Range vertices 
) [private]

Definition at line 241 of file TempestRemapper.cpp.

References moab::Interface::add_entities(), moab::Range::clear(), dbgprint, ErrorCode, moab::Interface::get_adjacencies(), moab::ReadUtilIface::get_element_connect(), moab::ReadUtilIface::get_node_coords(), moab::Interface::globalId_tag(), iface, is_root, moab::Remapper::m_interface, MB_CHK_SET_ERR, MB_SUCCESS, MB_TAG_CREAT, MB_TAG_DENSE, MB_TYPE_INTEGER, MBPOLYGON, MBQUAD, MBTRI, moab::Range::merge(), OVERLAP_FILES, moab::DebugOutput::printf(), moab::Interface::query_interface(), rank, moab::DebugOutput::set_prefix(), moab::Range::size(), size, moab::Interface::tag_get_handle(), moab::Interface::tag_set_data(), moab::Interface::UNION, moab::ReadUtilIface::update_adjacencies(), and verbose.

Referenced by ConvertTempestMesh().

{
    ErrorCode rval;

    const bool outputEnabled = ( TempestRemapper::verbose && is_root );
    const NodeVector& nodes  = mesh->nodes;
    const FaceVector& faces  = mesh->faces;

    moab::DebugOutput dbgprint( std::cout, this->rank, 0 );
    dbgprint.set_prefix( "[TempestToMOAB]: " );

    ReadUtilIface* iface;
    rval = m_interface->query_interface( iface );MB_CHK_SET_ERR( rval, "Can't get reader interface" );

    Tag gidTag = m_interface->globalId_tag();

    // Set the data for the vertices
    std::vector< double* > arrays;
    std::vector< int > gidsv( nodes.size() );
    EntityHandle startv;
    rval = iface->get_node_coords( 3, nodes.size(), 0, startv, arrays );MB_CHK_SET_ERR( rval, "Can't get node coords" );
    for( unsigned iverts = 0; iverts < nodes.size(); ++iverts )
    {
        const Node& node  = nodes[iverts];
        arrays[0][iverts] = node.x;
        arrays[1][iverts] = node.y;
        arrays[2][iverts] = node.z;
        gidsv[iverts]     = iverts + 1;
    }
    Range mbverts( startv, startv + nodes.size() - 1 );
    rval = m_interface->add_entities( mesh_set, mbverts );MB_CHK_SET_ERR( rval, "Can't add entities" );
    rval = m_interface->tag_set_data( gidTag, mbverts, &gidsv[0] );MB_CHK_SET_ERR( rval, "Can't set global_id tag" );

    gidsv.clear();
    entities.clear();

    Tag srcParentTag, tgtParentTag;
    std::vector< int > srcParent, tgtParent;
    bool storeParentInfo = ( mesh->vecSourceFaceIx.size() > 0 );

    if( storeParentInfo )
    {
        int defaultInt = -1;
        rval           = m_interface->tag_get_handle( "TargetParent", 1, MB_TYPE_INTEGER, tgtParentTag,
                                                      MB_TAG_DENSE | MB_TAG_CREAT, &defaultInt );MB_CHK_SET_ERR( rval, "can't create positive tag" );

        rval = m_interface->tag_get_handle( "SourceParent", 1, MB_TYPE_INTEGER, srcParentTag,
                                            MB_TAG_DENSE | MB_TAG_CREAT, &defaultInt );MB_CHK_SET_ERR( rval, "can't create negative tag" );
    }

    // Let us first perform a full pass assuming arbitrary polygons. This is especially true for
    // overlap meshes.
    //   1. We do a first pass over faces, decipher edge size and group into categories based on
    //   element type
    //   2. Next we loop over type, and add blocks of elements into MOAB
    //   3. For each block within the loop, also update the connectivity of elements.
    {
        if( outputEnabled )
            dbgprint.printf( 0, "..Mesh size: Nodes [%zu]  Elements [%zu].\n", nodes.size(), faces.size() );
        const int NMAXPOLYEDGES = 15;
        std::vector< unsigned > nPolys( NMAXPOLYEDGES, 0 );
        std::vector< std::vector< int > > typeNSeqs( NMAXPOLYEDGES );
        for( unsigned ifaces = 0; ifaces < faces.size(); ++ifaces )
        {
            const int iType = faces[ifaces].edges.size();
            nPolys[iType]++;
            typeNSeqs[iType].push_back( ifaces );
        }
        int iBlock = 0;
        for( unsigned iType = 0; iType < NMAXPOLYEDGES; ++iType )
        {
            if( !nPolys[iType] ) continue;  // Nothing to do

            const unsigned num_v_per_elem = iType;
            EntityHandle starte;  // Connectivity
            EntityHandle* conn;

            // Allocate the connectivity array, depending on the element type
            switch( num_v_per_elem )
            {
                case 3:
                    if( outputEnabled )
                        dbgprint.printf( 0, "....Block %d: Triangular Elements [%u].\n", iBlock++, nPolys[iType] );
                    rval = iface->get_element_connect( nPolys[iType], num_v_per_elem, MBTRI, 0, starte, conn );MB_CHK_SET_ERR( rval, "Can't get element connectivity" );
                    break;
                case 4:
                    if( outputEnabled )
                        dbgprint.printf( 0, "....Block %d: Quadrilateral Elements [%u].\n", iBlock++, nPolys[iType] );
                    rval = iface->get_element_connect( nPolys[iType], num_v_per_elem, MBQUAD, 0, starte, conn );MB_CHK_SET_ERR( rval, "Can't get element connectivity" );
                    break;
                default:
                    if( outputEnabled )
                        dbgprint.printf( 0, "....Block %d: Polygonal [%u] Elements [%u].\n", iBlock++, iType,
                                         nPolys[iType] );
                    rval = iface->get_element_connect( nPolys[iType], num_v_per_elem, MBPOLYGON, 0, starte, conn );MB_CHK_SET_ERR( rval, "Can't get element connectivity" );
                    break;
            }

            Range mbcells( starte, starte + nPolys[iType] - 1 );
            m_interface->add_entities( mesh_set, mbcells );

            if( storeParentInfo )
            {
                srcParent.resize( mbcells.size(), -1 );
                tgtParent.resize( mbcells.size(), -1 );
            }

            std::vector< int > gids( typeNSeqs[iType].size() );
            for( unsigned ifaces = 0, offset = 0; ifaces < typeNSeqs[iType].size(); ++ifaces )
            {
                const int fIndex = typeNSeqs[iType][ifaces];
                const Face& face = faces[fIndex];
                // conn[offset++] = startv + face.edges[0].node[0];
                for( unsigned iedges = 0; iedges < face.edges.size(); ++iedges )
                {
                    conn[offset++] = startv + face.edges[iedges].node[0];
                }

                if( storeParentInfo )
                {
                    srcParent[ifaces] = mesh->vecSourceFaceIx[fIndex] + 1;
                    tgtParent[ifaces] = mesh->vecTargetFaceIx[fIndex] + 1;
                }

                gids[ifaces] = typeNSeqs[iType][ifaces] + 1;
            }
            rval = m_interface->tag_set_data( gidTag, mbcells, &gids[0] );MB_CHK_SET_ERR( rval, "Can't set global_id tag" );

            if( meshType == OVERLAP_FILES )
            {
                // Now let us update the adjacency data, because some elements are new
                rval = iface->update_adjacencies( starte, nPolys[iType], num_v_per_elem, conn );MB_CHK_SET_ERR( rval, "Can't update adjacencies" );
                // Generate all adj entities dimension 1 and 2 (edges and faces/ tri or qua)
                Range edges;
                rval = m_interface->get_adjacencies( mbcells, 1, true, edges, Interface::UNION );MB_CHK_SET_ERR( rval, "Can't get edges" );
            }

            if( storeParentInfo )
            {
                rval = m_interface->tag_set_data( srcParentTag, mbcells, &srcParent[0] );MB_CHK_SET_ERR( rval, "Can't set tag data" );
                rval = m_interface->tag_set_data( tgtParentTag, mbcells, &tgtParent[0] );MB_CHK_SET_ERR( rval, "Can't set tag data" );
            }
            entities.merge( mbcells );
        }
    }

    if( vertices ) *vertices = mbverts;

    return MB_SUCCESS;
}

Convert the MOAB mesh representation to a corresponding TempestRemap mesh object according to the intersection context.

Definition at line 398 of file TempestRemapper.cpp.

References convert_mesh_to_tempest_private(), convert_overlap_mesh_sorted_by_source(), dbgprint, ErrorCode, is_root, m_overlap, m_source, m_source_entities, m_source_set, m_source_vertices, m_target, m_target_entities, m_target_set, m_target_vertices, MB_CHK_SET_ERR, moab::Remapper::OverlapMesh, point_cloud_source, point_cloud_target, moab::DebugOutput::printf(), rank, moab::DebugOutput::set_prefix(), moab::Range::size(), moab::Remapper::SourceMesh, moab::Remapper::TargetMesh, and verbose.

Referenced by CreateTempestMesh(), main(), and test_tempest_to_moab_convert().

{
    ErrorCode rval;
    const bool outputEnabled = ( TempestRemapper::verbose && is_root );

    moab::DebugOutput dbgprint( std::cout, this->rank, 0 );
    dbgprint.set_prefix( "[MOABToTempest]: " );

    if( ctx == Remapper::SourceMesh )
    {
        if( !m_source ) m_source = new Mesh();
        if( outputEnabled ) dbgprint.printf( 0, "Converting (source) MOAB to TempestRemap Mesh representation ...\n" );
        rval = convert_mesh_to_tempest_private( m_source, m_source_set, m_source_entities, &m_source_vertices );MB_CHK_SET_ERR( rval, "Can't convert source mesh to Tempest" );
        if( m_source_entities.size() == 0 && m_source_vertices.size() != 0 )
        {
            this->point_cloud_source = true;
        }
    }
    else if( ctx == Remapper::TargetMesh )
    {
        if( !m_target ) m_target = new Mesh();
        if( outputEnabled ) dbgprint.printf( 0, "Converting (target) MOAB to TempestRemap Mesh representation ...\n" );
        rval = convert_mesh_to_tempest_private( m_target, m_target_set, m_target_entities, &m_target_vertices );MB_CHK_SET_ERR( rval, "Can't convert target mesh to Tempest" );
        if( m_target_entities.size() == 0 && m_target_vertices.size() != 0 ) this->point_cloud_target = true;
    }
    else if( ctx == Remapper::OverlapMesh )  // Overlap mesh
    {
        if( !m_overlap ) m_overlap = new Mesh();
        if( outputEnabled ) dbgprint.printf( 0, "Converting (overlap) MOAB to TempestRemap Mesh representation ...\n" );
        rval = convert_overlap_mesh_sorted_by_source();MB_CHK_SET_ERR( rval, "Can't convert overlap mesh to Tempest" );
    }
    else
    {
        MB_CHK_SET_ERR( MB_FAILURE, "Invalid IntersectionContext context provided" );
    }

    return rval;
}

Convert the TempestRemap mesh object to a corresponding MOAB mesh representation according to the intersection context.

Definition at line 215 of file TempestRemapper.cpp.

References convert_tempest_mesh_private(), moab::Remapper::DEFAULT, is_root, m_overlap, m_overlap_entities, m_overlap_set, m_overlap_type, m_source, m_source_entities, m_source_set, m_source_type, m_source_vertices, m_target, m_target_entities, m_target_set, m_target_type, m_target_vertices, MB_CHK_SET_ERR, moab::Remapper::SourceMesh, moab::Remapper::TargetMesh, and verbose.

Referenced by main(), and test_tempest_to_moab_convert().

{
    const bool outputEnabled = ( TempestRemapper::verbose && is_root );
    if( ctx == Remapper::SourceMesh )
    {
        if( outputEnabled ) std::cout << "Converting (source) TempestRemap Mesh object to MOAB representation ...\n";
        return convert_tempest_mesh_private( m_source_type, m_source, m_source_set, m_source_entities,
                                             &m_source_vertices );
    }
    else if( ctx == Remapper::TargetMesh )
    {
        if( outputEnabled ) std::cout << "Converting (target) TempestRemap Mesh object to MOAB representation ...\n";
        return convert_tempest_mesh_private( m_target_type, m_target, m_target_set, m_target_entities,
                                             &m_target_vertices );
    }
    else if( ctx != Remapper::DEFAULT )
    {
        if( outputEnabled ) std::cout << "Converting (overlap) TempestRemap Mesh object to MOAB representation ...\n";
        return convert_tempest_mesh_private( m_overlap_type, m_overlap, m_overlap_set, m_overlap_entities, NULL );
    }
    else
    {
        MB_CHK_SET_ERR( MB_FAILURE, "Invalid IntersectionContext context provided" );
    }
}
ErrorCode moab::TempestRemapper::GenerateCSMeshMetadata ( const int  ntot_elements,
moab::Range entities,
moab::Range secondary_entities,
const std::string &  dofTagName,
int  nP 
)

Generate the necessary metadata and specifically the GLL node numbering for DoFs for a CS mesh. This negates the need for running external code like HOMME to output the numbering needed for computing maps. The functionality is used through the `mbconvert` tool to compute processor-invariant Global DoF IDs at GLL nodes.

Definition at line 876 of file TempestRemapper.cpp.

References ErrorCode, GenerateMeshMetadata(), MB_CHK_SET_ERR, and MB_SUCCESS.

{
    Mesh csMesh;
    int err;
    moab::ErrorCode rval;

    const int res = std::sqrt( ntot_elements / 6 );

    // create a temporary CS mesh
    // NOTE: This will not work for RRM grids. Need to run HOMME for that case anyway
    err = GenerateCSMesh( csMesh, res, "", "NetCDF4" );
    if( err )
    {
        MB_CHK_SET_ERR( MB_FAILURE, "Failed to generate CS mesh through TempestRemap" );
        ;
    }

    rval = this->GenerateMeshMetadata( csMesh, ntot_elements, ents, secondary_ents, dofTagName, nP );MB_CHK_SET_ERR( rval, "Failed in call to GenerateMeshMetadata" );

    return moab::MB_SUCCESS;
}

Generate a mesh in memory of given type (CS/RLL/ICO/MPAS(structured)) and store it under the context specified by the user.

ErrorCode moab::TempestRemapper::GenerateMeshMetadata ( Mesh &  mesh,
const int  ntot_elements,
moab::Range entities,
moab::Range secondary_entities,
const std::string  dofTagName,
int  nP 
)

Generate the necessary metadata for DoF node numbering in a given mesh. Currently, only the functionality to generate numbering on CS grids is supported.

Definition at line 902 of file TempestRemapper.cpp.

References moab::Range::begin(), moab::Range::end(), entities, ErrorCode, moab::Interface::get_coords(), moab::Range::insert(), moab::Remapper::m_interface, MB_CHK_SET_ERR, MB_SUCCESS, MB_TAG_CREAT, MB_TAG_DENSE, MB_TYPE_INTEGER, moab::Range::size(), moab::Interface::tag_get_handle(), and moab::Interface::tag_set_data().

Referenced by GenerateCSMeshMetadata(), and main().

{
    moab::ErrorCode rval;

    Tag dofTag;
    bool created = false;
    rval         = m_interface->tag_get_handle( dofTagName.c_str(), nP * nP, MB_TYPE_INTEGER, dofTag,
                                                MB_TAG_DENSE | MB_TAG_CREAT, 0, &created );MB_CHK_SET_ERR( rval, "Failed creating DoF tag" );

    // Number of Faces
    int nElements = static_cast< int >( csMesh.faces.size() );

    assert( nElements == ntot_elements );

    // Initialize data structures
    DataArray3D< int > dataGLLnodes;
    dataGLLnodes.Allocate( nP, nP, nElements );

    std::map< Node, int > mapNodes;
    std::map< Node, moab::EntityHandle > mapLocalMBNodes;

    // GLL Quadrature nodes
    DataArray1D< double > dG;
    DataArray1D< double > dW;
    GaussLobattoQuadrature::GetPoints( nP, 0.0, 1.0, dG, dW );

    moab::Range entities( ents );
    if( secondary_ents ) entities.insert( secondary_ents->begin(), secondary_ents->end() );
    double elcoords[3];
    for( unsigned iel = 0; iel < entities.size(); ++iel )
    {
        EntityHandle eh = entities[iel];
        rval            = m_interface->get_coords( &eh, 1, elcoords );
        Node elCentroid( elcoords[0], elcoords[1], elcoords[2] );
        mapLocalMBNodes.insert( std::pair< Node, moab::EntityHandle >( elCentroid, eh ) );
    }

    // Build a Kd-tree for local mesh (nearest neighbor searches)
    // Loop over all elements in CS-Mesh
    // Then find if current centroid is in an element
    //     If yes - then let us compute the DoF numbering and set to tag data
    //     If no - then compute DoF numbering BUT DO NOT SET to tag data
    // continue
    int* dofIDs = new int[nP * nP];

    // Write metadata
    for( int k = 0; k < nElements; k++ )
    {
        const Face& face        = csMesh.faces[k];
        const NodeVector& nodes = csMesh.nodes;

        if( face.edges.size() != 4 )
        {
            _EXCEPTIONT( "Mesh must only contain quadrilateral elements" );
        }

        Node centroid;
        centroid.x = centroid.y = centroid.z = 0.0;
        for( unsigned l = 0; l < face.edges.size(); ++l )
        {
            centroid.x += nodes[face[l]].x;
            centroid.y += nodes[face[l]].y;
            centroid.z += nodes[face[l]].z;
        }
        const double factor = 1.0 / face.edges.size();
        centroid.x *= factor;
        centroid.y *= factor;
        centroid.z *= factor;

        bool locElem = false;
        EntityHandle current_eh;
        if( mapLocalMBNodes.find( centroid ) != mapLocalMBNodes.end() )
        {
            locElem    = true;
            current_eh = mapLocalMBNodes[centroid];
        }

        for( int j = 0; j < nP; j++ )
        {
            for( int i = 0; i < nP; i++ )
            {

                // Get local map vectors
                Node nodeGLL;
                Node dDx1G;
                Node dDx2G;

                // ApplyLocalMap(
                //     face,
                //     nodevec,
                //     dG[i],
                //     dG[j],
                //     nodeGLL,
                //     dDx1G,
                //     dDx2G);
                const double& dAlpha = dG[i];
                const double& dBeta  = dG[j];

                // Calculate nodal locations on the plane
                double dXc = nodes[face[0]].x * ( 1.0 - dAlpha ) * ( 1.0 - dBeta ) +
                             nodes[face[1]].x * dAlpha * ( 1.0 - dBeta ) + nodes[face[2]].x * dAlpha * dBeta +
                             nodes[face[3]].x * ( 1.0 - dAlpha ) * dBeta;

                double dYc = nodes[face[0]].y * ( 1.0 - dAlpha ) * ( 1.0 - dBeta ) +
                             nodes[face[1]].y * dAlpha * ( 1.0 - dBeta ) + nodes[face[2]].y * dAlpha * dBeta +
                             nodes[face[3]].y * ( 1.0 - dAlpha ) * dBeta;

                double dZc = nodes[face[0]].z * ( 1.0 - dAlpha ) * ( 1.0 - dBeta ) +
                             nodes[face[1]].z * dAlpha * ( 1.0 - dBeta ) + nodes[face[2]].z * dAlpha * dBeta +
                             nodes[face[3]].z * ( 1.0 - dAlpha ) * dBeta;

                double dR = sqrt( dXc * dXc + dYc * dYc + dZc * dZc );

                // Mapped node location
                nodeGLL.x = dXc / dR;
                nodeGLL.y = dYc / dR;
                nodeGLL.z = dZc / dR;

                // Determine if this is a unique Node
                std::map< Node, int >::const_iterator iter = mapNodes.find( nodeGLL );
                if( iter == mapNodes.end() )
                {
                    // Insert new unique node into map
                    int ixNode = static_cast< int >( mapNodes.size() );
                    mapNodes.insert( std::pair< Node, int >( nodeGLL, ixNode ) );
                    dataGLLnodes[j][i][k] = ixNode + 1;
                }
                else
                {
                    dataGLLnodes[j][i][k] = iter->second + 1;
                }

                dofIDs[j * nP + i] = dataGLLnodes[j][i][k];
            }
        }

        if( locElem )
        {
            rval = m_interface->tag_set_data( dofTag, &current_eh, 1, dofIDs );MB_CHK_SET_ERR( rval, "Failed to tag_set_data for DoFs" );
        }
    }

    // clear memory
    delete[] dofIDs;
    mapLocalMBNodes.clear();
    mapNodes.clear();

    return moab::MB_SUCCESS;
}

Get the covering mesh (TempestRemap) object.

Definition at line 536 of file TempestRemapper.hpp.

References m_covering_source.

Referenced by moab::TempestOnlineMap::TempestOnlineMap().

{
    return m_covering_source;
}

Get access to the underlying source covering set if available. Else return the source set.

Definition at line 541 of file TempestRemapper.hpp.

References m_covering_source_set.

int moab::TempestRemapper::GetGlobalID ( Remapper::IntersectionContext  ctx,
int  localID 
) [inline]

Get the global ID corresponding to the local entity ID according to the context (source, target, intersection)

Definition at line 546 of file TempestRemapper.hpp.

References moab::Remapper::CoveringMesh, moab::Remapper::DEFAULT, lid_to_gid_covsrc, lid_to_gid_src, lid_to_gid_tgt, moab::Remapper::OverlapMesh, moab::Remapper::SourceMesh, and moab::Remapper::TargetMesh.

{
    switch( ctx )
    {
        case Remapper::SourceMesh:
            return lid_to_gid_src[localID];
        case Remapper::TargetMesh:
            return lid_to_gid_tgt[localID];
        case Remapper::CoveringMesh:
            return lid_to_gid_covsrc[localID];
        case Remapper::OverlapMesh:
        case Remapper::DEFAULT:
        default:
            return -1;
    }
}

Get the masks that could have been defined

Definition at line 1994 of file TempestRemapper.cpp.

References moab::Remapper::CoveringMesh, ErrorCode, moab::Remapper::m_interface, m_source_entities, m_source_vertices, m_target_entities, m_target_vertices, MB_CHK_SET_ERR, MB_SUCCESS, MB_TAG_CREAT, MB_TAG_DENSE, MB_TYPE_INTEGER, moab::Remapper::OverlapMesh, point_cloud_source, point_cloud_target, moab::Range::size(), moab::Remapper::SourceMesh, moab::Interface::tag_get_data(), moab::Interface::tag_get_handle(), and moab::Remapper::TargetMesh.

{
    Tag maskTag;
    // it should have been created already, if not, we might have a problem
    int def_val = 1;
    ErrorCode rval =
        m_interface->tag_get_handle( "GRID_IMASK", 1, MB_TYPE_INTEGER, maskTag, MB_TAG_DENSE | MB_TAG_CREAT, &def_val );MB_CHK_SET_ERR( rval, "Trouble creating GRID_IMASK tag" );

    switch( ctx )
    {
        case Remapper::SourceMesh: {
            if( point_cloud_source )
            {
                masks.resize( m_source_vertices.size() );
                rval = m_interface->tag_get_data( maskTag, m_source_vertices, &masks[0] );MB_CHK_SET_ERR( rval, "Trouble getting GRID_IMASK tag" );
            }
            else
            {
                masks.resize( m_source_entities.size() );
                rval = m_interface->tag_get_data( maskTag, m_source_entities, &masks[0] );MB_CHK_SET_ERR( rval, "Trouble getting GRID_IMASK tag" );
            }
            return MB_SUCCESS;
        }
        case Remapper::TargetMesh: {
            if( point_cloud_target )
            {
                masks.resize( m_target_vertices.size() );
                rval = m_interface->tag_get_data( maskTag, m_target_vertices, &masks[0] );MB_CHK_SET_ERR( rval, "Trouble getting GRID_IMASK tag" );
            }
            else
            {
                masks.resize( m_target_entities.size() );
                rval = m_interface->tag_get_data( maskTag, m_target_entities, &masks[0] );MB_CHK_SET_ERR( rval, "Trouble getting GRID_IMASK tag" );
            }
            return MB_SUCCESS;
        }
        case Remapper::CoveringMesh:
        case Remapper::OverlapMesh:
        default:
            return MB_SUCCESS;
    }
}
int moab::TempestRemapper::GetLocalID ( Remapper::IntersectionContext  ctx,
int  globalID 
) [inline]

Get the local ID corresponding to the global entity ID according to the context (source, target, intersection)

Definition at line 563 of file TempestRemapper.hpp.

References moab::Remapper::CoveringMesh, moab::Remapper::DEFAULT, gid_to_lid_covsrc, gid_to_lid_src, gid_to_lid_tgt, moab::Remapper::OverlapMesh, moab::Remapper::SourceMesh, and moab::Remapper::TargetMesh.

{
    switch( ctx )
    {
        case Remapper::SourceMesh:
            return gid_to_lid_src[globalID];
        case Remapper::TargetMesh:
            return gid_to_lid_tgt[globalID];
        case Remapper::CoveringMesh:
            return gid_to_lid_covsrc[globalID];
        case Remapper::DEFAULT:
        case Remapper::OverlapMesh:
        default:
            return -1;
    }
}

Get the mesh vertices corresponding to the intersection context. Useful for point-cloud meshes.

Definition at line 457 of file TempestRemapper.hpp.

References moab::Remapper::CoveringMesh, moab::Remapper::DEFAULT, m_covering_source_vertices, m_source_vertices, m_target_vertices, MB_SET_ERR_RET_VAL, moab::Remapper::SourceMesh, and moab::Remapper::TargetMesh.

Referenced by main().

{
    switch( ctx )
    {
        case Remapper::SourceMesh:
            return m_source_vertices;
        case Remapper::TargetMesh:
            return m_target_vertices;
        case Remapper::CoveringMesh:
            return m_covering_source_vertices;
        case Remapper::DEFAULT:
        default:
            MB_SET_ERR_RET_VAL( "Invalid context passed to GetMeshSet", m_source_vertices );
    }
}

Const overload. Get the mesh vertices corresponding to the intersection context. Useful for point-cloud meshes.

Definition at line 473 of file TempestRemapper.hpp.

References moab::Remapper::CoveringMesh, moab::Remapper::DEFAULT, m_covering_source_vertices, m_source_vertices, m_target_vertices, MB_SET_ERR_RET_VAL, moab::Remapper::SourceMesh, and moab::Remapper::TargetMesh.

{
    switch( ctx )
    {
        case Remapper::SourceMesh:
            return m_source_vertices;
        case Remapper::TargetMesh:
            return m_target_vertices;
        case Remapper::CoveringMesh:
            return m_covering_source_vertices;
        case Remapper::DEFAULT:
        default:
            MB_SET_ERR_RET_VAL( "Invalid context passed to GetMeshSet", m_source_vertices );
    }
}

Get all the ghosted overlap entities that were accumulated to enable conservation in parallel.

Definition at line 538 of file TempestRemapper.cpp.

References moab::Range::clear(), ErrorCode, moab::Range::insert(), MB_CHK_ERR, MB_CHK_SET_ERR, MB_SUCCESS, moab::Range::merge(), size, moab::Range::size(), and moab::subtract().

Referenced by main().

{
    sharedGhostEntities.clear();
#ifdef MOAB_HAVE_MPI
    moab::ErrorCode rval;

    // Remove entities in the intersection mesh that are part of the ghosted overlap
    if( is_parallel && size > 1 )
    {
        moab::Range allents;
        rval = m_interface->get_entities_by_dimension( m_overlap_set, 2, allents );MB_CHK_SET_ERR( rval, "Getting entities dim 2 failed" );

        moab::Range sharedents;
        moab::Tag ghostTag;
        std::vector< int > ghFlags( allents.size() );
        rval = m_interface->tag_get_handle( "ORIG_PROC", ghostTag );MB_CHK_ERR( rval );
        rval = m_interface->tag_get_data( ghostTag, allents, &ghFlags[0] );MB_CHK_ERR( rval );
        for( unsigned i = 0; i < allents.size(); ++i )
            if( ghFlags[i] >= 0 )                 // it means it is a ghost overlap element
                sharedents.insert( allents[i] );  // this should not participate in smat!

        allents = subtract( allents, sharedents );

        // Get connectivity from all ghosted elements and filter out
        // the vertices that are not owned
        moab::Range ownedverts, sharedverts;
        rval = m_interface->get_connectivity( allents, ownedverts );MB_CHK_SET_ERR( rval, "Deleting entities dim 0 failed" );
        rval = m_interface->get_connectivity( sharedents, sharedverts );MB_CHK_SET_ERR( rval, "Deleting entities dim 0 failed" );
        sharedverts = subtract( sharedverts, ownedverts );
        // rval = m_interface->remove_entities(m_overlap_set, sharedents);MB_CHK_SET_ERR(rval,
        // "Deleting entities dim 2 failed"); rval = m_interface->remove_entities(m_overlap_set,
        // sharedverts);MB_CHK_SET_ERR(rval, "Deleting entities dim 0 failed");

        sharedGhostEntities.merge( sharedents );
        // sharedGhostEntities.merge(sharedverts);
    }
#endif
    return moab::MB_SUCCESS;
}
ErrorCode moab::TempestRemapper::initialize ( bool  initialize_fsets = true) [virtual]

Initialize the TempestRemapper object internal datastructures including the mesh sets and TempestRemap mesh references.

Definition at line 44 of file TempestRemapper.cpp.

References moab::Interface::create_meshset(), ErrorCode, is_parallel, is_root, m_covering_source, moab::Remapper::m_interface, m_overlap, m_overlap_set, m_source, m_source_set, m_target, m_target_set, MB_CHK_SET_ERR, MB_SUCCESS, MESHSET_SET, point_cloud_source, point_cloud_target, rank, and size.

Referenced by main(), read_map_from_disk(), and test_tempest_to_moab_convert().

{
    ErrorCode rval;
    if( initialize_fsets )
    {
        rval = m_interface->create_meshset( moab::MESHSET_SET, m_source_set );MB_CHK_SET_ERR( rval, "Can't create new set" );
        rval = m_interface->create_meshset( moab::MESHSET_SET, m_target_set );MB_CHK_SET_ERR( rval, "Can't create new set" );
        rval = m_interface->create_meshset( moab::MESHSET_SET, m_overlap_set );MB_CHK_SET_ERR( rval, "Can't create new set" );
    }
    else
    {
        m_source_set  = 0;
        m_target_set  = 0;
        m_overlap_set = 0;
    }

    is_parallel = false;
    is_root     = true;
    rank        = 0;
    size        = 1;
#ifdef MOAB_HAVE_MPI
    int flagInit;
    MPI_Initialized( &flagInit );
    if( flagInit )
    {
        is_parallel = true;
        assert( m_pcomm != NULL );
        rank    = m_pcomm->rank();
        size    = m_pcomm->size();
        is_root = ( rank == 0 );
    }
#endif

    m_source          = NULL;
    m_target          = NULL;
    m_overlap         = NULL;
    m_covering_source = NULL;

    point_cloud_source = false;
    point_cloud_target = false;

    return MB_SUCCESS;
}
ErrorCode moab::TempestRemapper::load_tempest_mesh_private ( std::string  inputFilename,
Mesh **  tempest_mesh 
) [private]

Definition at line 166 of file TempestRemapper.cpp.

References constructEdgeMap, moab::error(), is_root, MB_SUCCESS, mesh, meshValidate, and verbose.

Referenced by LoadMesh().

{
    const bool outputEnabled = ( TempestRemapper::verbose && is_root );
    if( outputEnabled ) std::cout << "\nLoading TempestRemap Mesh object from file = " << inputFilename << " ...\n";

    {
        NcError error( NcError::silent_nonfatal );

        try
        {
            // Load input mesh
            if( outputEnabled ) std::cout << "Loading mesh ...\n";
            Mesh* mesh = new Mesh( inputFilename );
            mesh->RemoveZeroEdges();
            if( outputEnabled ) std::cout << "----------------\n";

            // Validate mesh
            if( meshValidate )
            {
                if( outputEnabled ) std::cout << "Validating mesh ...\n";
                mesh->Validate();
                if( outputEnabled ) std::cout << "-------------------\n";
            }

            // Construct the edge map on the mesh
            if( constructEdgeMap )
            {
                if( outputEnabled ) std::cout << "Constructing edge map on mesh ...\n";
                mesh->ConstructEdgeMap( false );
                if( outputEnabled ) std::cout << "---------------------------------\n";
            }

            if( tempest_mesh ) *tempest_mesh = mesh;
        }
        catch( Exception& e )
        {
            std::cout << "TempestRemap ERROR: " << e.ToString() << "\n";
            return MB_FAILURE;
        }
        catch( ... )
        {
            return MB_FAILURE;
        }
    }
    return MB_SUCCESS;
}

Load a mesh from disk of given type and store it under the context specified by the user.

Definition at line 141 of file TempestRemapper.cpp.

References moab::Remapper::DEFAULT, load_tempest_mesh_private(), m_overlap, m_overlap_type, m_source, m_source_type, m_target, m_target_type, MB_CHK_SET_ERR, moab::Remapper::SourceMesh, and moab::Remapper::TargetMesh.

Referenced by CreateTempestMesh(), main(), and test_tempest_to_moab_convert().

{
    if( ctx == Remapper::SourceMesh )
    {
        m_source_type = type;
        return load_tempest_mesh_private( inputFilename, &m_source );
    }
    else if( ctx == Remapper::TargetMesh )
    {
        m_target_type = type;
        return load_tempest_mesh_private( inputFilename, &m_target );
    }
    else if( ctx != Remapper::DEFAULT )
    {
        m_overlap_type = type;
        return load_tempest_mesh_private( inputFilename, &m_overlap );
    }
    else
    {
        MB_CHK_SET_ERR( MB_FAILURE, "Invalid IntersectionContext context provided" );
    }
}
void moab::TempestRemapper::SetMesh ( Remapper::IntersectionContext  ctx,
Mesh *  mesh,
bool  overwrite = true 
) [inline]

Set the TempestRemap mesh object according to the intersection context.

Definition at line 355 of file TempestRemapper.hpp.

References moab::Remapper::CoveringMesh, moab::Remapper::DEFAULT, m_covering_source, m_overlap, m_source, m_target, mesh, moab::Remapper::OverlapMesh, moab::Remapper::SourceMesh, and moab::Remapper::TargetMesh.

Referenced by CreateTempestMesh().

{
    switch( ctx )
    {
        case Remapper::SourceMesh:
            if( !overwrite && m_source ) return;
            if( overwrite && m_source ) delete m_source;
            m_source = mesh;
            break;
        case Remapper::TargetMesh:
            if( !overwrite && m_target ) return;
            if( overwrite && m_target ) delete m_target;
            m_target = mesh;
            break;
        case Remapper::OverlapMesh:
            if( !overwrite && m_overlap ) return;
            if( overwrite && m_overlap ) delete m_overlap;
            m_overlap = mesh;
            break;
        case Remapper::CoveringMesh:
            if( !overwrite && m_covering_source ) return;
            if( overwrite && m_covering_source ) delete m_covering_source;
            m_covering_source = mesh;
            break;
        case Remapper::DEFAULT:
        default:
            break;
    }
}
void moab::TempestRemapper::SetMeshType ( Remapper::IntersectionContext  ctx,
TempestRemapper::TempestMeshType  type,
const std::vector< int > *  metadata = nullptr 
) [inline]

Set the mesh type corresponding to the intersection context.

Definition at line 489 of file TempestRemapper.hpp.

References moab::Remapper::DEFAULT, m_overlap_type, m_source_metadata, m_source_type, m_target_metadata, m_target_type, moab::Remapper::OverlapMesh, moab::Remapper::SourceMesh, and moab::Remapper::TargetMesh.

Referenced by CreateTempestMesh(), and main().

{
    switch( ctx )
    {
        case Remapper::SourceMesh:
            m_source_type = type;
            if( metadata )
            {
                m_source_metadata.resize( metadata->size() );
                std::copy( metadata->begin(), metadata->end(), m_source_metadata.begin() );
            }
            break;
        case Remapper::TargetMesh:
            m_target_type = type;
            if( metadata )
            {
                m_target_metadata.resize( metadata->size() );
                std::copy( metadata->begin(), metadata->end(), m_target_metadata.begin() );
            }
            break;
        case Remapper::OverlapMesh:
            m_overlap_type = type;
            break;
        case Remapper::DEFAULT:
        default:
            break;
    }
}
moab::ErrorCode moab::TempestRemapper::WriteTempestIntersectionMesh ( std::string  strOutputFileName,
const bool  fAllParallel,
const bool  fInputConcave,
const bool  fOutputConcave 
)

Gather the overlap mesh and asssociated source/target data and write it out to disk using the TempestRemap output interface. This information can then be used with the "GenerateOfflineMap" tool in TempestRemap as needed.

Definition at line 780 of file TempestRemapper.cpp.

References MB_SUCCESS, and size.

{
    // Let us alos write out the TempestRemap equivalent so that we can do some verification checks
    if( fAllParallel )
    {
        if( is_root && size == 1 )
        {
            this->m_source->CalculateFaceAreas( fInputConcave );
            this->m_target->CalculateFaceAreas( fOutputConcave );
            this->m_overlap->Write( strOutputFileName.c_str(), NcFile::Netcdf4 );
        }
        else
        {
            // Perform reduction and write from root processor
            // if ( is_root )
            //     std::cout << "--- PARALLEL IMPLEMENTATION is NOT AVAILABLE yet ---\n";

            this->m_source->CalculateFaceAreas( fInputConcave );
            this->m_covering_source->CalculateFaceAreas( fInputConcave );
            this->m_target->CalculateFaceAreas( fOutputConcave );
            this->m_overlap->Write( strOutputFileName.c_str(), NcFile::Netcdf4 );
        }
    }
    else
    {
        this->m_source->CalculateFaceAreas( fInputConcave );
        this->m_target->CalculateFaceAreas( fOutputConcave );
        this->m_overlap->Write( strOutputFileName.c_str(), NcFile::Netcdf4 );
    }

    return moab::MB_SUCCESS;
}

Friends And Related Function Documentation

friend class TempestOnlineMap [friend]

Definition at line 65 of file TempestRemapper.hpp.


Member Data Documentation

std::map< int, int > moab::TempestRemapper::gid_to_lid_src [private]

Definition at line 326 of file TempestRemapper.hpp.

Referenced by clear(), ComputeGlobalLocalMaps(), and GetLocalID().

std::map< int, int > moab::TempestRemapper::lid_to_gid_covsrc [private]

Definition at line 327 of file TempestRemapper.hpp.

Referenced by clear(), ComputeGlobalLocalMaps(), and GetGlobalID().

std::map< int, int > moab::TempestRemapper::lid_to_gid_src [private]

Definition at line 327 of file TempestRemapper.hpp.

Referenced by clear(), ComputeGlobalLocalMaps(), and GetGlobalID().

std::map< int, int > moab::TempestRemapper::lid_to_gid_tgt [private]

Definition at line 327 of file TempestRemapper.hpp.

Referenced by clear(), ComputeGlobalLocalMaps(), and GetGlobalID().

std::vector< std::pair< int, int > > moab::TempestRemapper::m_sorted_overlap_order [private]

Definition at line 314 of file TempestRemapper.hpp.

std::vector< int > moab::TempestRemapper::m_source_metadata [private]

Definition at line 297 of file TempestRemapper.hpp.

Referenced by SetMeshType().

std::vector< int > moab::TempestRemapper::m_target_metadata [private]

Definition at line 307 of file TempestRemapper.hpp.

Referenced by SetMeshType().

Definition at line 295 of file TempestRemapper.hpp.

Referenced by ConstructCoveringSet().

Definition at line 305 of file TempestRemapper.hpp.

Referenced by ConstructCoveringSet().

Definition at line 331 of file TempestRemapper.hpp.

Referenced by ComputeOverlapMesh(), and ConstructCoveringSet().

List of all members.


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines