Mesh Oriented datABase  (version 5.6.0)
An array-based unstructured mesh library
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 Types inherited from moab::Remapper
enum  IntersectionContext {
  DEFAULT = -1 , SourceMesh = 0 , TargetMesh = 1 , OverlapMesh = 2 ,
  CoveringMesh = 3
}
 

Public Member Functions

 TempestRemapper (moab::Interface *mbInt, bool offlineMode=false)
 
virtual ~TempestRemapper ()
 
virtual ErrorCode initialize (bool initialize_fsets=true)
 Initialize the TempestRemapper object internal data structures including the mesh sets and TempestRemap mesh references. More...
 
virtual ErrorCode clear ()
 Deallocate and clear any memory initialized in the TempestRemapper object. More...
 
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. More...
 
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, bool gnomonic=true, int nb_ghost_layers=0)
 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 compute the intersection mesh only locally without any process communication. More...
 
void SetAreaMethod (IntxAreaUtils::AreaMethod method)
 Validate the GLOBAL_ID tags on the source and target meshes. More...
 
IntxAreaUtils::AreaMethod GetAreaMethod () const
 Formula currently used for spherical area computations. More...
 
void SetRegionalMesh (bool regional)
 Declare that the source and/or target mesh is regionally refined, so their domains need not coincide. More...
 
bool IsRegionalMesh () const
 Whether the meshes have been declared regionally refined; see SetRegionalMesh(). More...
 
moab::ErrorCode ValidateGlobalIds (bool throw_error=true)
 
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. More...
 
moab::ErrorCode ConvertTempestMesh (Remapper::IntersectionContext ctx)
 Convert the TempestRemap mesh object to a corresponding MOAB mesh representation according to the intersection context. More...
 
moab::ErrorCode ConvertMeshToTempest (Remapper::IntersectionContext ctx)
 Convert the MOAB mesh representation to a corresponding TempestRemap mesh object according to the intersection context. More...
 
Mesh * GetMesh (Remapper::IntersectionContext ctx)
 Get the TempestRemap mesh object according to the intersection context. More...
 
void SetMesh (Remapper::IntersectionContext ctx, Mesh *mesh, bool overwrite=true)
 Set the TempestRemap mesh object according to the intersection context. More...
 
void SetMeshSet (Remapper::IntersectionContext ctx, moab::EntityHandle mset, moab::Range *entities=nullptr)
 Set the mesh set according to the intersection context. More...
 
Mesh * GetCoveringMesh ()
 Get the covering mesh (TempestRemap) object. More...
 
moab::EntityHandle & GetMeshSet (Remapper::IntersectionContext ctx)
 Get the MOAB mesh set corresponding to the intersection context. More...
 
moab::EntityHandle GetMeshSet (Remapper::IntersectionContext ctx) const
 Const overload. Get the MOAB mesh set corresponding to the intersection context. More...
 
moab::Range & GetMeshEntities (Remapper::IntersectionContext ctx)
 Get the mesh element entities corresponding to the intersection context. More...
 
const moab::Range & GetMeshEntities (Remapper::IntersectionContext ctx) const
 Const overload. Get the mesh element entities corresponding to the intersection context. More...
 
moab::Range & GetMeshVertices (Remapper::IntersectionContext ctx)
 Get the mesh vertices corresponding to the intersection context. Useful for point-cloud meshes. More...
 
const moab::Range & GetMeshVertices (Remapper::IntersectionContext ctx) const
 Const overload. Get the mesh vertices corresponding to the intersection context. Useful for point-cloud meshes. More...
 
moab::EntityHandle & GetCoveringSet ()
 Get access to the underlying source covering set if available. Else return the source set. More...
 
void SetMeshType (Remapper::IntersectionContext ctx, const std::vector< int > &metadata)
 Set the mesh type corresponding to the intersection context. More...
 
void ResetMeshSet (Remapper::IntersectionContext ctx, moab::EntityHandle meshSet)
 Reconstruct mesh, used now only for IO; need a better solution maybe. More...
 
TempestMeshType GetMeshType (Remapper::IntersectionContext ctx) const
 Get the mesh type corresponding to the intersection context. More...
 
moab::ErrorCode WriteTempestIntersectionMesh (std::string strOutputFileName, const bool fAllParallel, const bool fInputConcave, const bool fOutputConcave)
 Gather the overlap mesh and associated 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. More...
 
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. More...
 
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. More...
 
moab::ErrorCode GetOverlapAugmentedEntities (moab::Range &sharedGhostEntities)
 Get all the ghosted overlap entities that were accumulated to enable conservation in parallel. More...
 
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. More...
 
ErrorCode GetIMasks (Remapper::IntersectionContext ctx, std::vector< int > &masks)
 Get the masks that could have been defined. More...
 
- Public Member Functions inherited from moab::Remapper
 Remapper (moab::Interface *mbInt)
 
virtual ~Remapper ()
 
moab::Interface * get_interface ()
 
ErrorCode LoadNativeMesh (std::string filename, moab::EntityHandle &meshset, std::vector< int > &metadata, const char *readopts=0)
 

Public Attributes

const bool offlineWorkflow
 Flag indicating whether the workflow is in offline mode. More...
 
bool meshValidate
 Flag to enable mesh validation after loading from file. More...
 
bool constructEdgeMap
 Flag to construct the edge map within the TempestRemap data structures. More...
 

Static Public Attributes

static const bool verbose = true
 Global verbosity flag. More...
 

Private Member Functions

moab::ErrorCode validate_global_ids_private (moab::EntityHandle mesh_set, int dimension, const char *mesh_name, std::string &error_message)
 Helper for ValidateGlobalIds: check one mesh set at one dimension. More...
 
ErrorCode ConvertAllMeshesToTempest ()
 Convert all MOAB meshes to TempestRemap format. More...
 
moab::ErrorCode ConvertOverlapMeshSourceOrdered ()
 Convert overlap mesh to source-ordered format. More...
 
moab::ErrorCode convert_mesh_to_tempest_private (Mesh *mesh, moab::EntityHandle meshset, moab::Range &entities, moab::Range *pverts)
 Convert a MOAB mesh to TempestRemap format. More...
 
moab::ErrorCode convert_tempest_mesh_private (TempestMeshType type, Mesh *mesh, moab::EntityHandle &meshset, moab::Range &entities, moab::Range *vertices)
 Convert a TempestRemap mesh to MOAB format. More...
 
moab::ErrorCode AugmentOverlapSet ()
 Augment overlap mesh with ghosted entities. More...
 

Private Attributes

Mesh * m_source = nullptr
 
TempestMeshType m_source_type
 
moab::Range m_source_entities
 
moab::Range m_source_vertices
 
moab::EntityHandle m_source_set = 0
 
int max_source_edges = 0
 
bool point_cloud_source = false
 
std::vector< int > m_source_metadata
 
Mesh * m_target = nullptr
 
TempestMeshType m_target_type
 
moab::Range m_target_entities
 
moab::Range m_target_vertices
 
moab::EntityHandle m_target_set = 0
 
int max_target_edges = 0
 
bool point_cloud_target = false
 
std::vector< int > m_target_metadata
 
Mesh * m_overlap = nullptr
 
TempestMeshType m_overlap_type = DEFAULT
 
moab::Range m_overlap_entities
 
moab::EntityHandle m_overlap_set = 0
 
std::vector< std::pair< int, int > > m_sorted_overlap_order
 
moab::Intx2MeshOnSphere * mbintx = nullptr
 
Mesh * m_covering_source = nullptr
 
moab::EntityHandle m_covering_source_set = 0
 
moab::Range m_covering_source_entities
 
moab::Range m_covering_source_vertices
 
IntxAreaUtils::AreaMethod m_area_method = IntxAreaUtils::DEFAULT_AREA_METHOD
 
bool rrmgrids = false
 
bool is_parallel = false
 
bool is_root = false
 
int rank = 0
 
int size = 0
 

Friends

class TempestOnlineMap
 

Additional Inherited Members

- Protected Attributes inherited from moab::Remapper
Interface * m_interface
 

Detailed Description

Definition at line 43 of file TempestRemapper.hpp.

Member Enumeration Documentation

◆ TempestMeshType

Enumerator
DEFAULT 
CS 
RLL 
ICO 
ICOD 
OVERLAP_FILES 
OVERLAP_MEMORY 
OVERLAP_MOAB 

Definition at line 64 of file TempestRemapper.hpp.

65  {
66  DEFAULT = -1,
67  CS = 0,
68  RLL = 1,
69  ICO = 2,
70  ICOD = 3,
71  OVERLAP_FILES = 4,
72  OVERLAP_MEMORY = 5,
73  OVERLAP_MOAB = 6
74  };

Constructor & Destructor Documentation

◆ TempestRemapper()

moab::TempestRemapper::TempestRemapper ( moab::Interface *  mbInt,
bool  offlineMode = false 
)
inline

Definition at line 50 of file TempestRemapper.hpp.

51  : Remapper( mbInt ),
52 #endif
53  offlineWorkflow( offlineMode ), meshValidate( false ), constructEdgeMap( false ), m_source_type( DEFAULT ),
55  {
56 #ifdef MOAB_HAVE_MPI
57  AnnounceOnlyOutputOnRankZero();
58 #endif
59  }

◆ ~TempestRemapper()

moab::TempestRemapper::~TempestRemapper ( )
virtual

Definition at line 101 of file TempestRemapper.cpp.

102 {
103  this->clear();
104 }

References clear().

Member Function Documentation

◆ assign_vertex_element_IDs()

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.

Parameters
idtagTag for the global IDs
this_setMOAB entity handle of the mesh set
dimensionDimension of the mesh (default: 2)
start_idStarting ID (default: 1)
Returns
ErrorCode indicating the status of the assignment

Definition at line 1038 of file TempestRemapper.cpp.

1042 {
1043  assert( idtag );
1044 
1045  ErrorCode rval;
1046  Range entities;
1047  MB_CHK_SET_ERR( m_interface->get_entities_by_dimension( this_set, dimension, entities ), "Failed to get entities" );
1048 
1049  if( entities.size() == 0 ) return moab::MB_SUCCESS;
1050 
1051  int idoffset = start_id;
1052  std::vector< int > gid( entities.size() );
1053  for( unsigned i = 0; i < entities.size(); ++i )
1054  gid[i] = idoffset++;
1055 
1056  MB_CHK_ERR( m_interface->tag_set_data( idtag, entities, &gid[0] ) );
1057 
1058  return moab::MB_SUCCESS;
1059 }

References 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 main().

◆ AugmentOverlapSet()

moab::ErrorCode moab::TempestRemapper::AugmentOverlapSet ( )
private

Augment overlap mesh with ghosted entities.

Adds ghosted entities to the overlap mesh to ensure conservation in parallel operations.

Returns
moab::ErrorCode Status of the augmentation

Referenced by ComputeOverlapMesh().

◆ clear()

ErrorCode moab::TempestRemapper::clear ( )
virtual

Deallocate and clear any memory initialized in the TempestRemapper object.

Returns
ErrorCode indicating the status of the clear operation

Definition at line 106 of file TempestRemapper.cpp.

107 {
108  // destroy all meshes
109  if( m_source )
110  {
111  delete m_source;
112  m_source = nullptr;
113  }
114  if( m_target )
115  {
116  delete m_target;
117  m_target = nullptr;
118  }
119  if( m_overlap )
120  {
121  delete m_overlap;
122  m_overlap = nullptr;
123  }
124  if( m_covering_source && size > 1 )
125  {
126  delete m_covering_source;
127  m_covering_source = nullptr;
128  }
129 
130  point_cloud_source = false;
131  point_cloud_target = false;
132 
140 
141  return MB_SUCCESS;
142 }

References moab::Range::clear(), m_covering_source, m_covering_source_entities, m_covering_source_vertices, m_overlap, m_overlap_entities, m_source, m_source_entities, m_source_vertices, m_target, m_target_entities, m_target_vertices, MB_SUCCESS, point_cloud_source, point_cloud_target, and size.

Referenced by main(), and ~TempestRemapper().

◆ ComputeOverlapMesh()

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.

Parameters
kdtree_searchFlag to enable k-d tree search (default: true)
use_tempestFlag to use TempestRemap (default: false)
Returns
ErrorCode indicating the status of the intersection mesh computation

Definition at line 1445 of file TempestRemapper.cpp.

1446 {
1447  const bool outputEnabled = ( this->rank == 0 );
1448  moab::DebugOutput dbgprint( std::cout, this->rank, 0 );
1449  dbgprint.set_prefix( "[ComputeOverlapMesh]: " );
1450 
1451  //
1452  // Create the intersection on the sphere object and set up necessary parameters
1453  //
1454  // First, split based on whether to use TempestRemap or MOAB for intersection
1455  // If TempestRemap,
1456  // 1) Check for valid Mesh and pointers to objects for source/target
1457  // 2) Invoke GenerateOverlapWithMeshes routine from Tempest library
1458  // If MOAB,
1459  // 1) Check for valid source and target meshsets (and entities)
1460  // 2) Build processor bounding boxes and construct a covering set
1461  // 3) Perform intersection between the source (covering) and target entities
1462  if( use_tempest )
1463  {
1464  // Now let us construct the overlap mesh, by calling TempestRemap interface directly
1465  // For the overlap method, choose between: "fuzzy", "exact" or "mixed"
1466  assert( m_covering_source != nullptr );
1467  assert( m_target != nullptr );
1468  if( m_overlap != nullptr ) delete m_overlap;
1469  bool concaveMeshA = false, concaveMeshB = false;
1470  // we have reset the overlap mesh - allocate now
1471  m_overlap = new Mesh();
1472  // Generate the overlap mesh using TempestRemap
1473  if( GenerateOverlapWithMeshes( *m_covering_source, *m_target, *m_overlap, "" /*outFilename*/, "Netcdf4",
1474  "exact", concaveMeshA, concaveMeshB, true, false ) )
1475  MB_CHK_SET_ERR( MB_FAILURE, "TempestRemap: cannot compute the intersection of meshes on the sphere" );
1476  }
1477  else
1478  {
1479  // Now perform the actual parallel intersection between the source and the target meshes
1480  if( kdtree_search )
1481  {
1482  if( outputEnabled ) dbgprint.printf( 0, "Computing intersection mesh with the Kd-tree search algorithm" );
1484  "Can't compute the intersection of meshes on the sphere with kd-tree" );
1485  }
1486  else
1487  {
1488  if( outputEnabled )
1489  dbgprint.printf( 0, "Computing intersection mesh with the advancing-front propagation algorithm" );
1491  "Can't compute the intersection of meshes on the sphere" );
1492  }
1493 
1494 #ifdef MOAB_HAVE_MPI
1495  if( is_parallel )
1496  {
1497 #ifdef VERBOSE
1498  std::stringstream ffc, fft, ffo;
1499  ffc << "cover_" << rank << ".h5m";
1500  fft << "target_" << rank << ".h5m";
1501  ffo << "intx_" << rank << ".h5m";
1502  MB_CHK_ERR( m_interface->write_mesh( ffc.str().c_str(), &m_covering_source_set, 1 ) );
1503  MB_CHK_ERR( m_interface->write_mesh( fft.str().c_str(), &m_target_set, 1 ) );
1504  MB_CHK_ERR( m_interface->write_mesh( ffo.str().c_str(), &m_overlap_set, 1 ) );
1505 #endif
1506  // because we do not want to work with elements in coverage set that do not participate
1507  // in intersection, remove them from the coverage set we will not delete them yet, just
1508  // remove from the set !
1509  if( !point_cloud_target )
1510  {
1511  Range covEnts;
1513 
1514  std::map< int, int > loc_gid_to_lid_covsrc;
1515  std::vector< int > gids( covEnts.size(), -1 );
1516 
1517  Tag gidtag = m_interface->globalId_tag();
1518  MB_CHK_ERR( m_interface->tag_get_data( gidtag, covEnts, gids.data() ) );
1519 
1520  for( unsigned ie = 0; ie < gids.size(); ++ie )
1521  {
1522  assert( gids[ie] > 0 );
1523  loc_gid_to_lid_covsrc[gids[ie]] = ie;
1524  }
1525 
1526  Range intxCov, intxCells;
1527  Tag srcParentTag;
1528  MB_CHK_ERR( m_interface->tag_get_handle( "SourceParent", srcParentTag ) );
1530  for( Range::iterator it = intxCells.begin(); it != intxCells.end(); ++it )
1531  {
1532  EntityHandle intxCell = *it;
1533  int srcParent = -1;
1534  MB_CHK_ERR( m_interface->tag_get_data( srcParentTag, &intxCell, 1, &srcParent ) );
1535 
1536  assert( srcParent >= 0 );
1537  intxCov.insert( covEnts[loc_gid_to_lid_covsrc[srcParent]] );
1538  }
1539 
1540  Range notNeededCovCells = moab::subtract( covEnts, intxCov );
1541 
1542  // now let us get only the covering entities that participate in intersection mesh
1543  covEnts = moab::subtract( covEnts, notNeededCovCells );
1544 
1545  // in order for getting 1-ring neighborhood, we need to be sure that the adjacencies are updated (created)
1546  if( false )
1547  {
1548  // update all adjacency list
1549  Core* mb = dynamic_cast< Core* >( m_interface );
1550  AEntityFactory* adj_fact = mb->a_entity_factory();
1551  if( !adj_fact->vert_elem_adjacencies() )
1552  adj_fact->create_vert_elem_adjacencies();
1553  else
1554  {
1555  for( Range::iterator it = covEnts.begin(); it != covEnts.end(); ++it )
1556  {
1557  EntityHandle eh = *it;
1558  const EntityHandle* conn = nullptr;
1559  int num_nodes = 0;
1560  MB_CHK_ERR( mb->get_connectivity( eh, conn, num_nodes ) );
1561  adj_fact->notify_create_entity( eh, conn, num_nodes );
1562  }
1563  }
1564 
1565  // next, for elements on the edge of the partition, get one ring adjacencies
1566  Skinner skinner( mb );
1567  Range skin;
1568  MB_CHK_SET_ERR( skinner.find_skin( m_covering_source_set, covEnts, false, skin ),
1569  "Unable to find skin" );
1570  for( Range::iterator it = skin.begin(); it != skin.end(); ++it )
1571  {
1572  const EntityHandle* conn = nullptr;
1573  int len = 0;
1574  MB_CHK_ERR( mb->get_connectivity( *it, conn, len, false ) );
1575  for( int ie = 0; ie < len; ++ie )
1576  {
1577  std::vector< EntityHandle > adjacent_entities;
1578  MB_CHK_ERR( adj_fact->get_adjacencies( conn[ie], 2, false, adjacent_entities ) );
1579  for( auto ent : adjacent_entities )
1580  notNeededCovCells.erase( ent ); // ent is part of the 1-ring neighborhood
1581  }
1582  }
1583 
1585  std::string( "sourcecoveragemesh_p" + std::to_string( rank ) + ".h5m" ).c_str(),
1586  &m_covering_source_set, 1 ) );
1587  }
1588 
1589  // remove now from coverage set the cells that are not needed
1590  // MB_CHK_ERR( m_interface->remove_entities( m_covering_source_set, notNeededCovCells ) );
1591 
1592  // Need to loop over covEnts now and ensure at least N-rings are available dependign on whether bilinear (1) or
1593  // high order FV (p) methods are being used for map generation. For bilinear/FV(1): need 1 ring, and for FV(p)
1594  // need p=ring neighborhood to recover exact conservation and consistency wrt serial/parallel.
1595 #ifdef VERBOSE
1596  std::cout << " total participating elements in the covering set: " << intxCov.size() << "\n";
1597  std::cout << " remove from coverage set elements that are not intersected: " << notNeededCovCells.size()
1598  << "\n";
1599 #endif
1600  if( size > 1 )
1601  {
1602  // some source elements cover multiple target partitions; the conservation logic
1603  // requires to know all overlap elements for a source element; they need to be
1604  // communicated from the other target partitions
1605  //
1606  // so first we have to identify source (coverage) elements that cover multiple
1607  // target partitions
1608  //
1609  // we will then mark the source, we will need to migrate the overlap elements
1610  // that cover this to the original source for the source element; then
1611  // distribute the overlap elements to all processors that have the coverage mesh
1612  // used
1614  }
1615  }
1616  }
1617 #endif
1618 
1619  // Fix any inconsistencies in the overlap mesh
1620  {
1621  IntxAreaUtils areaAdaptor( m_area_method );
1623  MB_CHK_ERR( areaAdaptor.positive_orientation( m_interface, m_overlap_set, 1.0 /*radius*/ ) );
1624  }
1625 
1626  // free the memory
1627  delete mbintx;
1628  }
1629 
1630  // Now, let us convert the overlap mesh to MOAB format so that we have a consistent interface
1631  MB_CHK_SET_ERR( ConvertOverlapMeshSourceOrdered(), "Can't convert overlap TempestRemap mesh to MOAB format" );
1632 
1633  return MB_SUCCESS;
1634 }

References AugmentOverlapSet(), moab::Range::begin(), ConvertOverlapMeshSourceOrdered(), moab::AEntityFactory::create_vert_elem_adjacencies(), dbgprint, moab::Range::end(), moab::Range::erase(), moab::Skinner::find_skin(), moab::IntxUtils::fix_degenerate_quads(), moab::AEntityFactory::get_adjacencies(), moab::Interface::get_entities_by_dimension(), moab::Interface::globalId_tag(), moab::Range::insert(), moab::Intx2Mesh::intersect_meshes(), moab::Intx2Mesh::intersect_meshes_kdtree(), is_parallel, m_area_method, m_covering_source, m_covering_source_set, moab::Remapper::m_interface, m_overlap, m_overlap_set, m_target, m_target_set, mb, MB_CHK_ERR, MB_CHK_SET_ERR, MB_SUCCESS, mbintx, moab::AEntityFactory::notify_create_entity(), point_cloud_target, moab::IntxAreaUtils::positive_orientation(), rank, moab::DebugOutput::set_prefix(), moab::Range::size(), size, moab::subtract(), moab::Interface::tag_get_data(), moab::Interface::tag_get_handle(), moab::AEntityFactory::vert_elem_adjacencies(), and moab::Interface::write_mesh().

Referenced by main().

◆ ConstructCoveringSet()

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,
bool  gnomonic = true,
int  nb_ghost_layers = 0 
)

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 compute the intersection mesh only locally without any process communication.

Parameters
toleranceTolerance for the covering mesh construction (default: 1e-8)
radius_srcRadius of the source mesh (default: 1.0)
radius_tgtRadius of the target mesh (default: 1.0)
boxepsBox epsilon value (default: 0.1)
regional_meshFlag to indicate if the mesh is regional (default: false)
gnomonicFlag to indicate if the mesh is gnomonic (default: true)
nb_ghost_layersNumber of ghost layers (default: 0)
Returns
ErrorCode indicating the status of the covering mesh construction

Definition at line 1362 of file TempestRemapper.cpp.

1369 {
1370  if( nb_ghost_layers >= 1 ) gnomonic = false;
1371  rrmgrids = regional_mesh;
1372  moab::Range local_verts;
1373 
1374  // Fail fast on meshes whose GLOBAL_IDs cannot support the coverage migration or
1375  // the map assembly. Doing this before any expensive work turns what used to be a
1376  // silent corruption (collapsed cells, bogus map rows) into an immediate diagnosis.
1378 
1379  // Initialize intersection context
1380  // Use the remapper-wide area formula rather than a hardcoded one, so that a single
1381  // choice (see SetAreaMethod) governs intersection, coverage and orientation fixups.
1383 
1385  mbintx->set_radius_source_mesh( radius_src );
1386  mbintx->set_radius_destination_mesh( radius_tgt );
1387  mbintx->set_box_error( boxeps );
1388 #ifdef MOAB_HAVE_MPI
1389  mbintx->set_parallel_comm( m_pcomm );
1390 #endif
1391 
1392  // compute the maxiumum edges in elements comprising source and target mesh
1394 
1397 
1398  // Note: lots of communication possible, if mesh is distributed very differently
1399 #ifdef MOAB_HAVE_MPI
1400  if( is_parallel )
1401  {
1402  MB_CHK_ERR( mbintx->build_processor_euler_boxes( m_target_set, local_verts, gnomonic ) );
1403 
1405  "Can't create new set" );
1406 
1407  MB_CHK_ERR( mbintx->construct_covering_set( m_source_set, m_covering_source_set, gnomonic, nb_ghost_layers ) );
1408 #ifdef MOAB_DBG
1409  std::stringstream filename;
1410  filename << "covering" << rank << ".h5m";
1411  MB_CHK_ERR( m_interface->write_file( filename.str().c_str(), 0, 0, &m_covering_source_set, 1 ) );
1412  std::stringstream targetFile;
1413  targetFile << "target" << rank << ".h5m";
1414  MB_CHK_ERR( m_interface->write_file( targetFile.str().c_str(), 0, 0, &m_target_set, 1 ) );
1415 #endif
1416  }
1417  else
1418  {
1419 #endif
1420  // Serial: every source cell is trivially in the coverage set.
1421  //
1422  // A "regional mesh" shortcut used to live here, picking for each target vertex
1423  // the source cell with the nearest centroid. Nearest centroid is not the same
1424  // relation as overlaps, so it dropped most of the covering set and produced a
1425  // silently wrong map (row sums down to 0.004). Holes are handled where they
1426  // belong instead -- in the overlap-based area correction; see IsRegionalMesh().
1429  m_covering_source_entities = m_source_entities; // this is a tempest mesh object; careful about
1430  // incrementing the reference?
1431  m_covering_source_vertices = m_source_vertices; // this is a tempest mesh object; careful about
1432  // incrementing the reference?
1433 #ifdef MOAB_HAVE_MPI
1434  }
1435 #endif
1436 
1437  // Convert the source, target and coverage meshes to TempestRemap format
1439 
1440  return moab::MB_SUCCESS;
1441 }

References ConvertAllMeshesToTempest(), moab::Interface::create_meshset(), moab::Intx2Mesh::FindMaxEdges(), is_parallel, m_area_method, 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_set, moab::Intx2Mesh::max_edges_1, moab::Intx2Mesh::max_edges_2, max_source_edges, max_target_edges, MB_CHK_ERR, MB_CHK_SET_ERR, MB_SUCCESS, mbintx, MESHSET_SET, rank, rrmgrids, moab::Intx2Mesh::set_box_error(), moab::Intx2Mesh::set_error_tolerance(), moab::Intx2MeshOnSphere::set_radius_destination_mesh(), moab::Intx2MeshOnSphere::set_radius_source_mesh(), moab::tolerance, ValidateGlobalIds(), and moab::Interface::write_file().

Referenced by main().

◆ convert_mesh_to_tempest_private()

ErrorCode moab::TempestRemapper::convert_mesh_to_tempest_private ( Mesh *  mesh,
moab::EntityHandle  meshset,
moab::Range &  entities,
moab::Range *  pverts 
)
private

Convert a MOAB mesh to TempestRemap format.

Parameters
meshTarget TempestRemap mesh pointer
meshsetMOAB mesh set to convert
entitiesRange of entities to convert
pvertsOptional pointer to vertex range
Returns
moab::ErrorCode Status of the conversion

Definition at line 642 of file TempestRemapper.cpp.

646 {
647  NodeVector& nodes = mesh->nodes;
648  FaceVector& faces = mesh->faces;
649 
650  elems.clear();
651  MB_CHK_ERR( m_interface->get_entities_by_dimension( mesh_set, 2, elems ) );
652 
653  const size_t nelems = elems.size();
654 
655  // resize the number of elements in Tempest mesh
656  faces.resize( nelems );
657 
658  // let us now get the vertices from all the elements
659  Range verts;
660  MB_CHK_ERR( m_interface->get_connectivity( elems, verts ) );
661  if( verts.size() == 0 )
662  {
663  MB_CHK_ERR( m_interface->get_entities_by_dimension( mesh_set, 0, verts ) );
664  }
665  // assert(verts.size() > 0); // If not, this may be an invalid mesh ! possible for unbalanced loads
666 
667  std::map< EntityHandle, int > indxMap;
668  bool useRange = true;
669  if( verts.compactness() > 0.01 )
670  {
671  int j = 0;
672  for( Range::iterator it = verts.begin(); it != verts.end(); ++it )
673  indxMap[*it] = j++;
674  useRange = false;
675  }
676 
677  std::vector< int > globIds( nelems );
679  MB_CHK_ERR( m_interface->tag_get_data( gid, elems, &globIds[0] ) );
680  std::vector< size_t > sortedIdx;
681  if( offlineWorkflow )
682  {
683  sortedIdx.resize( nelems );
684  // initialize original index locations
685  std::iota( sortedIdx.begin(), sortedIdx.end(), 0 );
686  // sort indexes based on comparing values in v, using std::stable_sort instead of std::sort
687  // to avoid unnecessary index re-orderings when v contains elements of equal values
688  std::sort( sortedIdx.begin(), sortedIdx.end(),
689  [&globIds]( size_t i1, size_t i2 ) { return globIds[i1] < globIds[i2]; } );
690  }
691 
692  for( unsigned iface = 0; iface < nelems; ++iface )
693  {
694  Face& face = faces[iface];
695  EntityHandle ehandle = ( offlineWorkflow ? elems[sortedIdx[iface]] : elems[iface] );
696 
697  // get the connectivity for each edge
698  const EntityHandle* connectface;
699  int nnodesf;
700  MB_CHK_ERR( m_interface->get_connectivity( ehandle, connectface, nnodesf ) );
701  // account for padded polygons
702  while( connectface[nnodesf - 2] == connectface[nnodesf - 1] && nnodesf > 3 )
703  nnodesf--;
704 
705  face.edges.resize( nnodesf );
706  for( int iverts = 0; iverts < nnodesf; ++iverts )
707  {
708  int indx = ( useRange ? verts.index( connectface[iverts] ) : indxMap[connectface[iverts]] );
709  assert( indx >= 0 );
710  face.SetNode( iverts, indx );
711  }
712  }
713 
714  unsigned nnodes = verts.size();
715  nodes.resize( nnodes );
716 
717  // Set the data for the vertices
718  std::vector< double > coordx( nnodes ), coordy( nnodes ), coordz( nnodes );
719  MB_CHK_ERR( m_interface->get_coords( verts, &coordx[0], &coordy[0], &coordz[0] ) );
720  for( unsigned inode = 0; inode < nnodes; ++inode )
721  {
722  Node& node = nodes[inode];
723  node.x = coordx[inode];
724  node.y = coordy[inode];
725  node.z = coordz[inode];
726  }
727  coordx.clear();
728  coordy.clear();
729  coordz.clear();
730 
731  mesh->RemoveCoincidentNodes();
732  mesh->RemoveZeroEdges();
733 
734  // Generate reverse node array and edge map
735  if( constructEdgeMap ) mesh->ConstructEdgeMap( false );
736  // mesh->ConstructReverseNodeArray();
737 
738  // mesh->Validate();
739 
740  if( pverts )
741  {
742  pverts->clear();
743  *pverts = verts;
744  }
745  verts.clear();
746 
747  return MB_SUCCESS;
748 }

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

Referenced by ConvertMeshToTempest(), and ResetMeshSet().

◆ convert_tempest_mesh_private()

ErrorCode moab::TempestRemapper::convert_tempest_mesh_private ( TempestMeshType  type,
Mesh *  mesh,
moab::EntityHandle &  meshset,
moab::Range &  entities,
moab::Range *  vertices 
)
private

Convert a TempestRemap mesh to MOAB format.

Parameters
typeType of the TempestRemap mesh
meshSource TempestRemap mesh
meshsetTarget MOAB mesh set
entitiesRange to store converted entities
verticesOptional range to store vertices
Returns
moab::ErrorCode Status of the conversion

Definition at line 252 of file TempestRemapper.cpp.

257 {
258  const bool outputEnabled = ( TempestRemapper::verbose && is_root );
259  const NodeVector& nodes = mesh->nodes;
260  const FaceVector& faces = mesh->faces;
261 
262  moab::DebugOutput dbgprint( std::cout, this->rank, 0 );
263  dbgprint.set_prefix( "[TempestToMOAB]: " );
264 
265  ReadUtilIface* iface;
266  MB_CHK_SET_ERR( m_interface->query_interface( iface ), "Can't get reader interface" );
267 
268  Tag gidTag = m_interface->globalId_tag();
269 
270  // Set the data for the vertices
271  std::vector< double* > arrays;
272  std::vector< int > gidsv( nodes.size() );
273  EntityHandle startv;
274  MB_CHK_SET_ERR( iface->get_node_coords( 3, nodes.size(), 0, startv, arrays ), "Can't get node coords" );
275  for( unsigned iverts = 0; iverts < nodes.size(); ++iverts )
276  {
277  const Node& node = nodes[iverts];
278  arrays[0][iverts] = node.x;
279  arrays[1][iverts] = node.y;
280  arrays[2][iverts] = node.z;
281  gidsv[iverts] = iverts + 1;
282  }
283  Range mbverts( startv, startv + nodes.size() - 1 );
284  MB_CHK_SET_ERR( m_interface->add_entities( mesh_set, mbverts ), "Can't add entities" );
285  MB_CHK_SET_ERR( m_interface->tag_set_data( gidTag, mbverts, &gidsv[0] ), "Can't set global_id tag" );
286 
287  gidsv.clear();
288  entities.clear();
289 
290  Tag srcParentTag, tgtParentTag;
291  std::vector< int > srcParent( faces.size(), -1 ), tgtParent( faces.size(), -1 );
292  std::vector< int > gidse( faces.size(), -1 );
293  bool storeParentInfo = ( mesh->vecSourceFaceIx.size() > 0 );
294 
295  if( storeParentInfo )
296  {
297  int defaultInt = -1;
298  MB_CHK_SET_ERR( m_interface->tag_get_handle( "TargetParent", 1, MB_TYPE_INTEGER, tgtParentTag,
299  MB_TAG_DENSE | MB_TAG_CREAT, &defaultInt ),
300  "can't create positive tag" );
301 
302  MB_CHK_SET_ERR( m_interface->tag_get_handle( "SourceParent", 1, MB_TYPE_INTEGER, srcParentTag,
303  MB_TAG_DENSE | MB_TAG_CREAT, &defaultInt ),
304  "can't create negative tag" );
305  }
306 
307  // Let us first perform a full pass assuming arbitrary polygons. This is especially true for
308  // overlap meshes.
309  // 1. We do a first pass over faces, decipher edge size and group into categories based on
310  // element type
311  // 2. Next we loop over type, and add blocks of elements into MOAB
312  // 3. For each block within the loop, also update the connectivity of elements.
313  {
314  if( outputEnabled )
315  dbgprint.printf( 0, "..Mesh size: Nodes [%zu] Elements [%zu].\n", nodes.size(), faces.size() );
316  std::vector< EntityHandle > mbcells( faces.size() );
317  unsigned ntris = 0, nquads = 0, npolys = 0;
318  std::vector< EntityHandle > conn( 16 );
319 
320  for( unsigned ifaces = 0; ifaces < faces.size(); ++ifaces )
321  {
322  const Face& face = faces[ifaces];
323  const unsigned num_v_per_elem = face.edges.size();
324 
325  for( unsigned iedges = 0; iedges < num_v_per_elem; ++iedges )
326  {
327  conn[iedges] = startv + face.edges[iedges].node[0];
328  }
329 
330  switch( num_v_per_elem )
331  {
332  case 3:
333  // if( outputEnabled )
334  // dbgprint.printf( 0, "....Block %d: Triangular Elements [%u].\n", iBlock++, nPolys[iType] );
335  MB_CHK_SET_ERR( m_interface->create_element( MBTRI, &conn[0], num_v_per_elem, mbcells[ifaces] ),
336  "Can't get element connectivity" );
337  ntris++;
338  break;
339  case 4:
340  // if( outputEnabled )
341  // dbgprint.printf( 0, "....Block %d: Quadrilateral Elements [%u].\n", iBlock++, nPolys[iType] );
342  MB_CHK_SET_ERR( m_interface->create_element( MBQUAD, &conn[0], num_v_per_elem, mbcells[ifaces] ),
343  "Can't get element connectivity" );
344  nquads++;
345  break;
346  default:
347  // if( outputEnabled )
348  // dbgprint.printf( 0, "....Block %d: Polygonal [%u] Elements [%u].\n", iBlock++, iType,
349  // nPolys[iType] );
350  MB_CHK_SET_ERR( m_interface->create_element( MBPOLYGON, &conn[0], num_v_per_elem, mbcells[ifaces] ),
351  "Can't get element connectivity" );
352  npolys++;
353  break;
354  }
355 
356  gidse[ifaces] = ifaces + 1;
357 
358  if( storeParentInfo )
359  {
360  srcParent[ifaces] = mesh->vecSourceFaceIx[ifaces] + 1;
361  tgtParent[ifaces] = mesh->vecTargetFaceIx[ifaces] + 1;
362  }
363  }
364 
365  if( ntris ) dbgprint.printf( 0, "....Triangular Elements [%u].\n", ntris );
366  if( nquads ) dbgprint.printf( 0, "....Quadrangular Elements [%u].\n", nquads );
367  if( npolys ) dbgprint.printf( 0, "....Polygonal Elements [%u].\n", npolys );
368 
369  MB_CHK_SET_ERR( m_interface->add_entities( mesh_set, &mbcells[0], mbcells.size() ), "Could not add entities" );
370 
371  MB_CHK_SET_ERR( m_interface->tag_set_data( gidTag, &mbcells[0], mbcells.size(), &gidse[0] ),
372  "Can't set global_id tag" );
373 #ifdef MOAB_HAVE_MPI
374  MB_CHK_SET_ERR( m_pcomm->assign_global_ids(mesh_set, 2, 1, false, true, false ), "Unable to set global IDs" );
375 #endif
376 
377  if( storeParentInfo )
378  {
379  MB_CHK_SET_ERR( m_interface->tag_set_data( srcParentTag, &mbcells[0], mbcells.size(), &srcParent[0] ),
380  "Can't set tag data" );
381  MB_CHK_SET_ERR( m_interface->tag_set_data( tgtParentTag, &mbcells[0], mbcells.size(), &tgtParent[0] ),
382  "Can't set tag data" );
383  }
384 
385  // insert from mbcells to entities to preserve ordering
386  std::copy( mbcells.begin(), mbcells.end(), range_inserter( entities ) );
387  }
388 
389  if( vertices ) *vertices = mbverts;
390 
391  return MB_SUCCESS;
392 }

References moab::Interface::add_entities(), moab::Range::clear(), moab::Interface::create_element(), dbgprint, 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::Interface::query_interface(), rank, moab::DebugOutput::set_prefix(), moab::Interface::tag_get_handle(), moab::Interface::tag_set_data(), and verbose.

Referenced by ConvertTempestMesh().

◆ ConvertAllMeshesToTempest()

ErrorCode moab::TempestRemapper::ConvertAllMeshesToTempest ( )
private

Convert all MOAB meshes to TempestRemap format.

Utility method primarily used in online workflows to convert all meshes to TempestRemap format.

Returns
ErrorCode Status of the conversion

Definition at line 564 of file TempestRemapper.cpp.

565 {
566  // now, let us ensure we have a valid source and target mesh objects
567  // if not, convert the source and target meshes to TempestRemap format
568  if( this->m_source == nullptr )
569  {
570  // Convert the covering mesh to TempestRemap format
572  "Can't convert source mesh to TempestRemap format" );
573  }
574  if( this->m_covering_source == nullptr )
575  {
576  // Convert the covering mesh to TempestRemap format
578  "Can't convert source coverage mesh to TempestRemap format" );
579  }
580  if( this->m_target == nullptr )
581  {
582  // Convert the covering mesh to TempestRemap format
584  "Can't convert target mesh to TempestRemap format" );
585  }
586 
587  return moab::MB_SUCCESS;
588 }

References ConvertMeshToTempest(), moab::Remapper::CoveringMesh, m_covering_source, m_source, m_target, MB_CHK_SET_ERR, MB_SUCCESS, moab::Remapper::SourceMesh, and moab::Remapper::TargetMesh.

Referenced by ConstructCoveringSet().

◆ ConvertMeshToTempest()

ErrorCode moab::TempestRemapper::ConvertMeshToTempest ( Remapper::IntersectionContext  ctx)

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

Parameters
ctxIntersection context
Returns
ErrorCode indicating the status of the mesh conversion

Definition at line 590 of file TempestRemapper.cpp.

591 {
592  const bool outputEnabled = ( TempestRemapper::verbose && is_root );
593 
594  // create a debug output object and set a prefix
595  moab::DebugOutput dbgprint( std::cout, this->rank, 0 );
596  dbgprint.set_prefix( "[MOABToTempest]: " );
597 
598  if( ctx == Remapper::SourceMesh )
599  {
600  if( !m_source ) m_source = new Mesh();
601  if( outputEnabled ) dbgprint.printf( 0, "Converting (source) MOAB to TempestRemap Mesh representation ...\n" );
604  "Can't convert source mesh to Tempest" );
605  if( m_source_entities.size() == 0 && m_source_vertices.size() != 0 )
606  {
607  this->point_cloud_source = true;
608  }
609  }
610  else if( ctx == Remapper::CoveringMesh )
611  {
612  if( !m_covering_source ) m_covering_source = new Mesh();
613  if( outputEnabled )
614  dbgprint.printf( 0, "Converting (covering source) MOAB to TempestRemap Mesh representation ...\n" );
617  "Can't convert convering source mesh to TempestRemap format" );
618  }
619  else if( ctx == Remapper::TargetMesh )
620  {
621  if( !m_target ) m_target = new Mesh();
622  if( outputEnabled ) dbgprint.printf( 0, "Converting (target) MOAB to TempestRemap Mesh representation ...\n" );
625  "Can't convert target mesh to Tempest" );
626  if( m_target_entities.size() == 0 && m_target_vertices.size() != 0 ) this->point_cloud_target = true;
627  }
628  else if( ctx == Remapper::OverlapMesh ) // Overlap mesh
629  {
630  if( !m_overlap ) m_overlap = new Mesh();
631  if( outputEnabled ) dbgprint.printf( 0, "Converting (overlap) MOAB to TempestRemap Mesh representation ...\n" );
632  MB_CHK_SET_ERR( ConvertOverlapMeshSourceOrdered(), "Can't convert overlap mesh to Tempest" );
633  }
634  else
635  {
636  MB_CHK_SET_ERR( MB_FAILURE, "Invalid IntersectionContext context provided" );
637  }
638 
639  return moab::MB_SUCCESS;
640 }

References convert_mesh_to_tempest_private(), ConvertOverlapMeshSourceOrdered(), moab::Remapper::CoveringMesh, dbgprint, is_root, m_covering_source, m_covering_source_entities, m_covering_source_set, m_covering_source_vertices, 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, MB_SUCCESS, moab::Remapper::OverlapMesh, point_cloud_source, point_cloud_target, rank, moab::DebugOutput::set_prefix(), moab::Range::size(), moab::Remapper::SourceMesh, moab::Remapper::TargetMesh, and verbose.

Referenced by ConvertAllMeshesToTempest(), anonymous_namespace{mbtempest.cpp}::handleOverlapMOAB(), and main().

◆ ConvertOverlapMeshSourceOrdered()

ErrorCode moab::TempestRemapper::ConvertOverlapMeshSourceOrdered ( )
private

Convert overlap mesh to source-ordered format.

Transforms the overlap mesh into a source-ordered format compatible with TempestRemap.

Returns
moab::ErrorCode Status of the conversion

Definition at line 799 of file TempestRemapper.cpp.

800 {
803  size_t n_overlap_entitites = m_overlap_entities.size();
804 
805  // Allocate for the overlap mesh
806  if( !m_overlap ) m_overlap = new Mesh();
807 
808  std::vector< std::array< int, 3 > > sorted_overlap_order( n_overlap_entitites,
809  std::array< int, 3 >( { -1, -1, -1 } ) );
810  {
811  Tag srcParentTag, tgtParentTag;
812  MB_CHK_ERR( m_interface->tag_get_handle( "SourceParent", srcParentTag ) );
813  MB_CHK_ERR( m_interface->tag_get_handle( "TargetParent", tgtParentTag ) );
814  // Overlap mesh: resize the source and target connection arrays
815  m_overlap->vecTargetFaceIx.resize( n_overlap_entitites );
816  m_overlap->vecSourceFaceIx.resize( n_overlap_entitites );
817 
818  // We need a global to local numbering
819  Tag gidtag = m_interface->globalId_tag();
820  std::vector< int > gids_src( m_covering_source_entities.size(), -1 ), gids_tgt( m_target_entities.size(), -1 );
821  MB_CHK_ERR( m_interface->tag_get_data( gidtag, m_covering_source_entities, gids_src.data() ) );
822  MB_CHK_ERR( m_interface->tag_get_data( gidtag, m_target_entities, gids_tgt.data() ) );
823 
824  // Global-id -> local-index lookup.
825  //
826  // This used to be a std::find() over the whole gid vector for every overlap
827  // element, making the loop below O(n_overlap * n_source). On a 288k-cell RLL
828  // source that single std::find accounted for 68% of total runtime (13029 of
829  // 19243 samples). Build the index once instead, so each lookup is O(1) and
830  // the loop becomes O(n_overlap + n_source).
831  //
832  // Insert with first-occurrence-wins so the result matches what std::find
833  // returned when a global id appears more than once.
834  auto build_index = []( const std::vector< int >& gids ) {
835  std::unordered_map< int, int > index;
836  index.reserve( gids.size() * 2 );
837  for( size_t i = 0; i < gids.size(); i++ )
838  index.emplace( gids[i], static_cast< int >( i ) );
839  return index;
840  };
841 
842  std::unordered_map< int, int > index_src, index_tgt;
843  if( !offlineWorkflow )
844  {
845  index_src = build_index( gids_src );
846  index_tgt = build_index( gids_tgt );
847  }
848 
849  auto find_lid = [this]( const std::unordered_map< int, int >& index, int gid ) -> int {
850  if( offlineWorkflow ) return gid - 1;
851  auto it = index.find( gid );
852  return ( it != index.end() ? it->second : -1 );
853  };
854 
855  std::vector< int > ghFlags;
856  if( is_parallel )
857  {
858  Tag ghostTag;
859  ghFlags.resize( n_overlap_entitites );
860  MB_CHK_SET_ERR( m_interface->tag_get_handle( "ORIG_PROC", ghostTag ), "Could not find ORIG_PROC tag" );
861  MB_CHK_ERR( m_interface->tag_get_data( ghostTag, m_overlap_entities, ghFlags.data() ) );
862  }
863 
864  // Overlap mesh: resize the source and target connection arrays
865  std::vector< int > rbids_src( n_overlap_entitites ), rbids_tgt( n_overlap_entitites );
866  MB_CHK_ERR( m_interface->tag_get_data( srcParentTag, m_overlap_entities, rbids_src.data() ) );
867  MB_CHK_ERR( m_interface->tag_get_data( tgtParentTag, m_overlap_entities, rbids_tgt.data() ) );
868 
869  for( size_t ix = 0; ix < n_overlap_entitites; ++ix )
870  {
871  std::get< 0 >( sorted_overlap_order[ix] ) = ix;
872  std::get< 1 >( sorted_overlap_order[ix] ) = find_lid( index_src, rbids_src[ix] );
873  assert( std::get< 1 >( sorted_overlap_order[ix] ) >= 0 );
874  if( is_parallel && ghFlags[ix] >= 0 )
875  {
876  // Ghost overlap element: its target cell lives on the rank that owns this element.
877  // Weight contributions for this element are computed on that owning rank (where the
878  // element has ORIG_PROC=-1 and a valid local target face index). Using -1 here
879  // ensures the element is skipped on this rank to avoid double-counting.
880  std::get< 2 >( sorted_overlap_order[ix] ) = -1;
881  }
882  else
883  std::get< 2 >( sorted_overlap_order[ix] ) = find_lid( index_tgt, rbids_tgt[ix] );
884  }
885  // now sort the overlap elements such that they are ordered by source parent first
886  // and then target parent next
887  std::sort( sorted_overlap_order.begin(), sorted_overlap_order.end(), IntPairComparator );
888 
889  for( unsigned ie = 0; ie < n_overlap_entitites; ++ie )
890  {
891  m_overlap->vecSourceFaceIx[ie] = std::get< 1 >( sorted_overlap_order[ie] );
892  m_overlap->vecTargetFaceIx[ie] = std::get< 2 >( sorted_overlap_order[ie] );
893  }
894  }
895 
896  FaceVector& faces = m_overlap->faces;
897  faces.resize( n_overlap_entitites );
898 
899  Range verts;
900  // let us now get the vertices from all the elements
902 
903  std::map< EntityHandle, int > indxMap;
904  {
905  int j = 0;
906  for( Range::iterator it = verts.begin(); it != verts.end(); ++it )
907  indxMap[*it] = j++;
908  }
909 
910  for( unsigned ifac = 0; ifac < m_overlap_entities.size(); ++ifac )
911  {
912  const unsigned iface = std::get< 0 >( sorted_overlap_order[ifac] );
913  Face& face = faces[ifac];
915 
916  // get the connectivity for each edge
917  const EntityHandle* connectface;
918  int nnodesf;
919  MB_CHK_ERR( m_interface->get_connectivity( ehandle, connectface, nnodesf ) );
920 
921  face.edges.resize( nnodesf );
922  for( int iverts = 0; iverts < nnodesf; ++iverts )
923  {
924  int indx = indxMap[connectface[iverts]];
925  assert( indx >= 0 );
926  face.SetNode( iverts, indx );
927  }
928  }
929  indxMap.clear();
930  sorted_overlap_order.clear();
931 
932  unsigned nnodes = verts.size();
933  NodeVector& nodes = m_overlap->nodes;
934  nodes.resize( nnodes );
935 
936  // Set the data for the vertices
937  std::vector< double > coordx( nnodes ), coordy( nnodes ), coordz( nnodes );
938  MB_CHK_ERR( m_interface->get_coords( verts, &coordx[0], &coordy[0], &coordz[0] ) );
939  for( unsigned inode = 0; inode < nnodes; ++inode )
940  {
941  Node& node = nodes[inode];
942  node.x = coordx[inode];
943  node.y = coordy[inode];
944  node.z = coordz[inode];
945  }
946  coordx.clear();
947  coordy.clear();
948  coordz.clear();
949  verts.clear();
950 
951  // ideally, we should do these in MOAB after intersction computation
952  // m_overlap->RemoveZeroEdges();
953  // m_overlap->RemoveCoincidentNodes( false );
954 
955  // Generate reverse node array and edge map
956  // if ( constructEdgeMap ) m_overlap->ConstructEdgeMap(false);
957  // m_overlap->ConstructReverseNodeArray();
958 
959  // For now, comment out validation; not needed
960  // m_overlap->Validate();
961 
962  // all done. return success
963  return MB_SUCCESS;
964 }

References moab::Range::begin(), moab::Range::clear(), moab::Range::end(), moab::Interface::get_connectivity(), moab::Interface::get_coords(), moab::Interface::get_entities_by_dimension(), moab::Interface::globalId_tag(), iface, moab::index, moab::IntPairComparator(), is_parallel, m_covering_source_entities, moab::Remapper::m_interface, m_overlap, m_overlap_entities, m_overlap_set, m_target_entities, MB_CHK_ERR, MB_CHK_SET_ERR, MB_SUCCESS, offlineWorkflow, moab::Range::size(), moab::Interface::tag_get_data(), and moab::Interface::tag_get_handle().

Referenced by ComputeOverlapMesh(), and ConvertMeshToTempest().

◆ ConvertTempestMesh()

ErrorCode moab::TempestRemapper::ConvertTempestMesh ( Remapper::IntersectionContext  ctx)

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

Parameters
ctxIntersection context
Returns
ErrorCode indicating the status of the mesh conversion

Definition at line 223 of file TempestRemapper.cpp.

224 {
225  const bool outputEnabled = ( TempestRemapper::verbose && is_root );
226  if( ctx == Remapper::SourceMesh )
227  {
228  if( outputEnabled ) std::cout << "Converting (source) TempestRemap Mesh object to MOAB representation ...\n";
231  }
232  else if( ctx == Remapper::TargetMesh )
233  {
234  if( outputEnabled ) std::cout << "Converting (target) TempestRemap Mesh object to MOAB representation ...\n";
237  }
238  else if( ctx != Remapper::DEFAULT )
239  {
240  if( outputEnabled ) std::cout << "Converting (overlap) TempestRemap Mesh object to MOAB representation ...\n";
242  }
243  else
244  {
245  MB_CHK_SET_ERR( MB_FAILURE, "Invalid IntersectionContext context provided" );
246  }
247 }

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 anonymous_namespace{mbtempest.cpp}::convertAndWriteMOABMesh(), and main().

◆ GenerateCSMeshMetadata()

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.

Parameters
ntot_elementsTotal number of elements
entitiesMOAB range of entities
secondary_entitiesMOAB range of secondary entities (optional)
dofTagNameName of the DoF tag
nPNumber of points
Returns
ErrorCode indicating the status of the metadata generation

Definition at line 1070 of file TempestRemapper.cpp.

1075 {
1076  const int csResolution = std::sqrt( ntot_elements / 6.0 );
1077  if( csResolution * csResolution * 6 != ntot_elements ) return MB_INVALID_SIZE;
1078 
1079  // Create a temporary Cubed-Sphere mesh
1080  // NOTE: This will not work for RRM grids. Need to run HOMME for that case anyway
1081  Mesh csMesh;
1082  if( GenerateCSMesh( csMesh, csResolution, "", "NetCDF4" ) )
1083  MB_CHK_SET_ERR( moab::MB_FAILURE, // unsuccessful call
1084  "Failed to generate CS mesh through TempestRemap" );
1085 
1086  // let us now generate the mesh metadata
1087  if( this->GenerateMeshMetadata( csMesh, ntot_elements, ents, secondary_ents, dofTagName, nP ) )
1088  MB_CHK_SET_ERR( moab::MB_FAILURE, "Failed in call to GenerateMeshMetadata" ); // unsuccessful call
1089 
1090  return moab::MB_SUCCESS;
1091 }

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

◆ GenerateMesh()

moab::ErrorCode moab::TempestRemapper::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.

Parameters
ctxIntersection context
typeType of mesh to generate
Returns
ErrorCode indicating the status of the mesh generation

◆ GenerateMeshMetadata()

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.

Parameters
meshMesh object
ntot_elementsTotal number of elements
entitiesMOAB range of entities
secondary_entitiesMOAB range of secondary entities (optional)
dofTagNameName of the DoF tag
nPNumber of points
Returns
ErrorCode indicating the status of the metadata generation

Definition at line 1093 of file TempestRemapper.cpp.

1099 {
1100  Tag dofTag;
1101  bool created = false;
1102  MB_CHK_SET_ERR( m_interface->tag_get_handle( dofTagName.c_str(), nP * nP, MB_TYPE_INTEGER, dofTag,
1103  MB_TAG_DENSE | MB_TAG_CREAT, 0, &created ),
1104  "Failed creating DoF tag" );
1105 
1106  // Number of Faces
1107  int nElements = static_cast< int >( csMesh.faces.size() );
1108 
1109  if( nElements != ntot_elements ) return MB_INVALID_SIZE;
1110 
1111  // Initialize data structures
1112  DataArray3D< int > dataGLLnodes;
1113  dataGLLnodes.Allocate( nP, nP, nElements );
1114 
1115  std::map< Node, int > mapNodes;
1116  std::map< Node, moab::EntityHandle > mapLocalMBNodes;
1117 
1118  // GLL Quadrature nodes
1119  DataArray1D< double > dG;
1120  DataArray1D< double > dW;
1121  GaussLobattoQuadrature::GetPoints( nP, 0.0, 1.0, dG, dW );
1122 
1123  moab::Range entities( ents );
1124  if( secondary_ents ) entities.insert( secondary_ents->begin(), secondary_ents->end() );
1125  double elcoords[3];
1126  for( unsigned iel = 0; iel < entities.size(); ++iel )
1127  {
1128  EntityHandle eh = entities[iel];
1129  MB_CHK_SET_ERR( m_interface->get_coords( &eh, 1, elcoords ), "failed to get element coordinates" );
1130  Node elCentroid( elcoords[0], elcoords[1], elcoords[2] );
1131  mapLocalMBNodes.insert( std::pair< Node, moab::EntityHandle >( elCentroid, eh ) );
1132  }
1133 
1134  // Build a Kd-tree for local mesh (nearest neighbor searches)
1135  // Loop over all elements in CS-Mesh
1136  // Then find if current centroid is in an element
1137  // If yes - then let us compute the DoF numbering and set to tag data
1138  // If no - then compute DoF numbering BUT DO NOT SET to tag data
1139  // continue
1140  int* dofIDs = new int[nP * nP];
1141 
1142  // Write metadata
1143  for( int k = 0; k < nElements; k++ )
1144  {
1145  const Face& face = csMesh.faces[k];
1146  const NodeVector& nodes = csMesh.nodes;
1147 
1148  if( face.edges.size() != 4 )
1149  {
1150  _EXCEPTIONT( "Mesh must only contain quadrilateral elements" );
1151  }
1152 
1153  Node centroid;
1154  centroid.x = centroid.y = centroid.z = 0.0;
1155  for( unsigned l = 0; l < face.edges.size(); ++l )
1156  {
1157  centroid.x += nodes[face[l]].x;
1158  centroid.y += nodes[face[l]].y;
1159  centroid.z += nodes[face[l]].z;
1160  }
1161  const double factor = 1.0 / face.edges.size();
1162  centroid.x *= factor;
1163  centroid.y *= factor;
1164  centroid.z *= factor;
1165 
1166  bool locElem = false;
1167  EntityHandle current_eh;
1168  if( mapLocalMBNodes.find( centroid ) != mapLocalMBNodes.end() )
1169  {
1170  locElem = true;
1171  current_eh = mapLocalMBNodes[centroid];
1172  }
1173 
1174  for( int j = 0; j < nP; j++ )
1175  {
1176  for( int i = 0; i < nP; i++ )
1177  {
1178  // Get local map vectors
1179  Node nodeGLL;
1180  Node dDx1G;
1181  Node dDx2G;
1182 
1183  // ApplyLocalMap(
1184  // face,
1185  // nodevec,
1186  // dG[i],
1187  // dG[j],
1188  // nodeGLL,
1189  // dDx1G,
1190  // dDx2G);
1191  const double& dAlpha = dG[i];
1192  const double& dBeta = dG[j];
1193 
1194  // Calculate nodal locations on the plane
1195  double dXc = nodes[face[0]].x * ( 1.0 - dAlpha ) * ( 1.0 - dBeta ) +
1196  nodes[face[1]].x * dAlpha * ( 1.0 - dBeta ) + nodes[face[2]].x * dAlpha * dBeta +
1197  nodes[face[3]].x * ( 1.0 - dAlpha ) * dBeta;
1198 
1199  double dYc = nodes[face[0]].y * ( 1.0 - dAlpha ) * ( 1.0 - dBeta ) +
1200  nodes[face[1]].y * dAlpha * ( 1.0 - dBeta ) + nodes[face[2]].y * dAlpha * dBeta +
1201  nodes[face[3]].y * ( 1.0 - dAlpha ) * dBeta;
1202 
1203  double dZc = nodes[face[0]].z * ( 1.0 - dAlpha ) * ( 1.0 - dBeta ) +
1204  nodes[face[1]].z * dAlpha * ( 1.0 - dBeta ) + nodes[face[2]].z * dAlpha * dBeta +
1205  nodes[face[3]].z * ( 1.0 - dAlpha ) * dBeta;
1206 
1207  double dR = sqrt( dXc * dXc + dYc * dYc + dZc * dZc );
1208 
1209  // Mapped node location
1210  nodeGLL.x = dXc / dR;
1211  nodeGLL.y = dYc / dR;
1212  nodeGLL.z = dZc / dR;
1213 
1214  // Determine if this is a unique Node
1215  std::map< Node, int >::const_iterator iter = mapNodes.find( nodeGLL );
1216  if( iter == mapNodes.end() )
1217  {
1218  // Insert new unique node into map
1219  int ixNode = static_cast< int >( mapNodes.size() );
1220  mapNodes.insert( std::pair< Node, int >( nodeGLL, ixNode ) );
1221  dataGLLnodes[j][i][k] = ixNode + 1;
1222  }
1223  else
1224  {
1225  dataGLLnodes[j][i][k] = iter->second + 1;
1226  }
1227 
1228  dofIDs[j * nP + i] = dataGLLnodes[j][i][k];
1229  }
1230  }
1231 
1232  if( locElem )
1233  {
1234  MB_CHK_SET_ERR( m_interface->tag_set_data( dofTag, &current_eh, 1, dofIDs ),
1235  "Failed to tag_set_data for DoFs" );
1236  }
1237  }
1238 
1239  // clear memory
1240  delete[] dofIDs;
1241  mapLocalMBNodes.clear();
1242  mapNodes.clear();
1243 
1244  return moab::MB_SUCCESS;
1245 }

References moab::Range::begin(), moab::Range::end(), moab::Interface::get_coords(), moab::Range::insert(), moab::Remapper::m_interface, MB_CHK_SET_ERR, MB_INVALID_SIZE, 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().

◆ GetAreaMethod()

IntxAreaUtils::AreaMethod moab::TempestRemapper::GetAreaMethod ( ) const
inline

Formula currently used for spherical area computations.

Definition at line 176 of file TempestRemapper.hpp.

177  {
178  return m_area_method;
179  }

References m_area_method.

◆ GetCoveringMesh()

Mesh * moab::TempestRemapper::GetCoveringMesh ( )
inline

Get the covering mesh (TempestRemap) object.

Returns
Pointer to the covering mesh object

Definition at line 834 of file TempestRemapper.hpp.

835 {
836  return m_covering_source;
837 }

References m_covering_source.

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

◆ GetCoveringSet()

moab::EntityHandle & moab::TempestRemapper::GetCoveringSet ( )
inline

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

Returns
MOAB entity handle of the covering set

Definition at line 839 of file TempestRemapper.hpp.

840 {
841  return m_covering_source_set;
842 }

References m_covering_source_set.

◆ GetIMasks()

ErrorCode moab::TempestRemapper::GetIMasks ( Remapper::IntersectionContext  ctx,
std::vector< int > &  masks 
)

Get the masks that could have been defined.

Parameters
ctxIntersection context
masksVector of masks
Returns
ErrorCode indicating the status of the get operation

Definition at line 2252 of file TempestRemapper.cpp.

2253 {
2254  Tag maskTag;
2255  // it should have been created already, if not, we might have a problem
2256  int def_val = 1;
2258  &def_val ),
2259  "Trouble creating GRID_IMASK tag" );
2260 
2261  switch( ctx )
2262  {
2263  case Remapper::SourceMesh: {
2264  if( point_cloud_source )
2265  {
2266  masks.resize( m_source_vertices.size() );
2267  MB_CHK_SET_ERR( m_interface->tag_get_data( maskTag, m_source_vertices, &masks[0] ),
2268  "Trouble getting GRID_IMASK tag" );
2269  }
2270  else
2271  {
2272  masks.resize( m_source_entities.size() );
2273  MB_CHK_SET_ERR( m_interface->tag_get_data( maskTag, m_source_entities, &masks[0] ),
2274  "Trouble getting GRID_IMASK tag" );
2275  }
2276  return MB_SUCCESS;
2277  }
2278  case Remapper::TargetMesh: {
2279  if( point_cloud_target )
2280  {
2281  masks.resize( m_target_vertices.size() );
2282  MB_CHK_SET_ERR( m_interface->tag_get_data( maskTag, m_target_vertices, &masks[0] ),
2283  "Trouble getting GRID_IMASK tag" );
2284  }
2285  else
2286  {
2287  masks.resize( m_target_entities.size() );
2288  MB_CHK_SET_ERR( m_interface->tag_get_data( maskTag, m_target_entities, &masks[0] ),
2289  "Trouble getting GRID_IMASK tag" );
2290  }
2291  return MB_SUCCESS;
2292  }
2294  case Remapper::OverlapMesh:
2295  default:
2296  return MB_SUCCESS;
2297  }
2298 }

References moab::Remapper::CoveringMesh, 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.

◆ GetMesh()

Mesh * moab::TempestRemapper::GetMesh ( Remapper::IntersectionContext  ctx)
inline

Get the TempestRemap mesh object according to the intersection context.

Parameters
ctxIntersection context
Returns
Pointer to the TempestRemap mesh object

Definition at line 601 of file TempestRemapper.hpp.

602 {
603  switch( ctx )
604  {
606  return m_source;
608  return m_target;
610  return m_overlap;
612  return m_covering_source;
613  case Remapper::DEFAULT:
614  default:
615  return NULL;
616  }
617 }

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

Referenced by anonymous_namespace{mbtempest.cpp}::handleOverlapMOAB(), main(), and moab::TempestOnlineMap::TempestOnlineMap().

◆ GetMeshEntities() [1/2]

moab::Range & moab::TempestRemapper::GetMeshEntities ( Remapper::IntersectionContext  ctx)
inline

Get the mesh element entities corresponding to the intersection context.

Parameters
ctxIntersection context
Returns
MOAB range of mesh element entities

Definition at line 711 of file TempestRemapper.hpp.

712 {
713  switch( ctx )
714  {
716  return m_source_entities;
718  return m_target_entities;
720  return m_overlap_entities;
723  case Remapper::DEFAULT:
724  default:
725  MB_SET_ERR_RET_VAL( "Invalid context passed to GetMeshSet", m_overlap_entities );
726  }
727 }

References moab::Remapper::CoveringMesh, moab::Remapper::DEFAULT, m_covering_source_entities, m_overlap_entities, m_source_entities, m_target_entities, MB_SET_ERR_RET_VAL, moab::Remapper::OverlapMesh, moab::Remapper::SourceMesh, and moab::Remapper::TargetMesh.

Referenced by main().

◆ GetMeshEntities() [2/2]

const moab::Range & moab::TempestRemapper::GetMeshEntities ( Remapper::IntersectionContext  ctx) const
inline

Const overload. Get the mesh element entities corresponding to the intersection context.

Parameters
ctxIntersection context
Returns
MOAB range of mesh element entities

Definition at line 729 of file TempestRemapper.hpp.

730 {
731  switch( ctx )
732  {
734  return m_source_entities;
736  return m_target_entities;
738  return m_overlap_entities;
741  case Remapper::DEFAULT:
742  default:
743  MB_SET_ERR_RET_VAL( "Invalid context passed to GetMeshSet", m_overlap_entities );
744  }
745 }

References moab::Remapper::CoveringMesh, moab::Remapper::DEFAULT, m_covering_source_entities, m_overlap_entities, m_source_entities, m_target_entities, MB_SET_ERR_RET_VAL, moab::Remapper::OverlapMesh, moab::Remapper::SourceMesh, and moab::Remapper::TargetMesh.

◆ GetMeshSet() [1/2]

moab::EntityHandle & moab::TempestRemapper::GetMeshSet ( Remapper::IntersectionContext  ctx)
inline

Get the MOAB mesh set corresponding to the intersection context.

Parameters
ctxIntersection context
Returns
MOAB mesh set handle

Definition at line 675 of file TempestRemapper.hpp.

676 {
677  switch( ctx )
678  {
680  return m_source_set;
682  return m_target_set;
684  return m_overlap_set;
686  return m_covering_source_set;
687  case Remapper::DEFAULT:
688  default:
689  MB_SET_ERR_RET_VAL( "Invalid context passed to GetMeshSet", m_overlap_set );
690  }
691 }

References moab::Remapper::CoveringMesh, moab::Remapper::DEFAULT, m_covering_source_set, m_overlap_set, m_source_set, m_target_set, MB_SET_ERR_RET_VAL, moab::Remapper::OverlapMesh, moab::Remapper::SourceMesh, and moab::Remapper::TargetMesh.

Referenced by anonymous_namespace{mbtempest.cpp}::convertAndWriteMOABMesh(), anonymous_namespace{mbtempest.cpp}::handleOverlapMOAB(), and main().

◆ GetMeshSet() [2/2]

moab::EntityHandle moab::TempestRemapper::GetMeshSet ( Remapper::IntersectionContext  ctx) const
inline

Const overload. Get the MOAB mesh set corresponding to the intersection context.

Parameters
ctxIntersection context
Returns
MOAB mesh set handle

Definition at line 693 of file TempestRemapper.hpp.

694 {
695  switch( ctx )
696  {
698  return m_source_set;
700  return m_target_set;
702  return m_overlap_set;
704  return m_covering_source_set;
705  case Remapper::DEFAULT:
706  default:
707  MB_SET_ERR_RET_VAL( "Invalid context passed to GetMeshSet", m_overlap_set );
708  }
709 }

References moab::Remapper::CoveringMesh, moab::Remapper::DEFAULT, m_covering_source_set, m_overlap_set, m_source_set, m_target_set, MB_SET_ERR_RET_VAL, moab::Remapper::OverlapMesh, moab::Remapper::SourceMesh, and moab::Remapper::TargetMesh.

◆ GetMeshType()

TempestRemapper::TempestMeshType moab::TempestRemapper::GetMeshType ( Remapper::IntersectionContext  ctx) const
inline

Get the mesh type corresponding to the intersection context.

Parameters
ctxIntersection context
Returns
Mesh type

Definition at line 818 of file TempestRemapper.hpp.

819 {
820  switch( ctx )
821  {
823  return m_source_type;
825  return m_target_type;
827  return m_overlap_type;
828  case Remapper::DEFAULT:
829  default:
831  }
832 }

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

◆ GetMeshVertices() [1/2]

moab::Range & moab::TempestRemapper::GetMeshVertices ( Remapper::IntersectionContext  ctx)
inline

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

Parameters
ctxIntersection context
Returns
MOAB range of mesh vertices

Definition at line 747 of file TempestRemapper.hpp.

748 {
749  switch( ctx )
750  {
752  return m_source_vertices;
754  return m_target_vertices;
757  case Remapper::DEFAULT:
758  default:
759  MB_SET_ERR_RET_VAL( "Invalid context passed to GetMeshSet", m_source_vertices );
760  }
761 }

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().

◆ GetMeshVertices() [2/2]

const moab::Range & moab::TempestRemapper::GetMeshVertices ( Remapper::IntersectionContext  ctx) const
inline

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

Parameters
ctxIntersection context
Returns
MOAB range of mesh vertices

Definition at line 763 of file TempestRemapper.hpp.

764 {
765  switch( ctx )
766  {
768  return m_source_vertices;
770  return m_target_vertices;
773  case Remapper::DEFAULT:
774  default:
775  MB_SET_ERR_RET_VAL( "Invalid context passed to GetMeshSet", m_source_vertices );
776  }
777 }

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.

◆ GetOverlapAugmentedEntities()

moab::ErrorCode moab::TempestRemapper::GetOverlapAugmentedEntities ( moab::Range &  sharedGhostEntities)

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

Parameters
sharedGhostEntitiesMOAB range of ghosted overlap entities
Returns
ErrorCode indicating the status of the get operation

Definition at line 760 of file TempestRemapper.cpp.

761 {
762  sharedGhostEntities.clear();
763 #ifdef MOAB_HAVE_MPI
764 
765  // Remove entities in the intersection mesh that are part of the ghosted overlap
766  if( is_parallel )
767  {
768  moab::Range allents;
770  "Getting entities dim 2 failed" );
771 
772  moab::Range sharedents;
773  moab::Tag ghostTag;
774  std::vector< int > ghFlags( allents.size() );
775  MB_CHK_ERR( m_interface->tag_get_handle( "ORIG_PROC", ghostTag ) );
776  MB_CHK_ERR( m_interface->tag_get_data( ghostTag, allents, &ghFlags[0] ) );
777  for( unsigned i = 0; i < allents.size(); ++i )
778  if( ghFlags[i] >= 0 ) // it means it is a ghost overlap element
779  sharedents.insert( allents[i] ); // this should not participate in smat!
780 
781  allents = subtract( allents, sharedents );
782 
783  // Get connectivity from all ghosted elements and filter out
784  // the vertices that are not owned
785  moab::Range ownedverts, sharedverts;
786  MB_CHK_SET_ERR( m_interface->get_connectivity( allents, ownedverts ), "Deleting entities dim 0 failed" );
787  MB_CHK_SET_ERR( m_interface->get_connectivity( sharedents, sharedverts ), "Deleting entities dim 0 failed" );
788  sharedverts = subtract( sharedverts, ownedverts );
789  // MB_CHK_SET_ERR( m_interface->remove_entities(m_overlap_set, sharedents), // "Deleting entities dim 2 failed" ); MB_CHK_SET_ERR( m_interface->remove_entities(m_overlap_set,
790  // sharedverts), "Deleting entities dim 0 failed" );
791 
792  sharedGhostEntities.merge( sharedents );
793  // sharedGhostEntities.merge(sharedverts);
794  }
795 #endif
796  return moab::MB_SUCCESS;
797 }

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

Referenced by main().

◆ initialize()

ErrorCode moab::TempestRemapper::initialize ( bool  initialize_fsets = true)
virtual

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

Parameters
initialize_fsetsFlag to initialize the mesh sets (default: true)
Returns
ErrorCode indicating the status of the initialization

Definition at line 54 of file TempestRemapper.cpp.

55 {
56  if( initialize_fsets )
57  {
61  }
62  else
63  {
64  m_source_set = 0;
65  m_target_set = 0;
66  m_overlap_set = 0;
67  }
68 
69  is_parallel = false;
70  is_root = true;
71  rank = 0;
72  size = 1;
73 #ifdef MOAB_HAVE_MPI
74  int flagInit;
75  MPI_Initialized( &flagInit );
76  if( flagInit )
77  {
78  assert( m_pcomm != nullptr );
79  rank = m_pcomm->rank();
80  size = m_pcomm->size();
81  is_root = ( rank == 0 );
82  is_parallel = ( size > 1 );
83  // is_parallel = true;
84  }
85  AnnounceOnlyOutputOnRankZero();
86 #endif
87 
88  m_source = nullptr;
89  m_target = nullptr;
90  m_overlap = nullptr;
91  m_covering_source = nullptr;
92 
93  point_cloud_source = false;
94  point_cloud_target = false;
95 
96  return MB_SUCCESS;
97 }

References moab::Interface::create_meshset(), 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().

◆ IsRegionalMesh()

bool moab::TempestRemapper::IsRegionalMesh ( ) const
inline

Whether the meshes have been declared regionally refined; see SetRegionalMesh().

Definition at line 200 of file TempestRemapper.hpp.

201  {
202  return rrmgrids;
203  }

References rrmgrids.

◆ ResetMeshSet()

void moab::TempestRemapper::ResetMeshSet ( Remapper::IntersectionContext  ctx,
moab::EntityHandle  meshSet 
)
inline

Reconstruct mesh, used now only for IO; need a better solution maybe.

Parameters
ctxIntersection context
meshSetMOAB mesh set handle

Definition at line 649 of file TempestRemapper.hpp.

650 {
651  switch( ctx )
652  {
654  delete m_source;
655  m_source = new Mesh;
656  m_source_set = meshSet;
658  m_source->CalculateFaceAreas( false ); // fInputConcave is false ?
659  break;
661  // not needed yet
662  break;
664  // not needed yet
665  break;
667  // not needed yet
668  break;
669  case Remapper::DEFAULT:
670  default:
671  break;
672  }
673 }

References convert_mesh_to_tempest_private(), moab::Remapper::CoveringMesh, moab::Remapper::DEFAULT, m_source, m_source_entities, m_source_set, m_source_vertices, moab::Remapper::OverlapMesh, moab::Remapper::SourceMesh, and moab::Remapper::TargetMesh.

◆ SetAreaMethod()

void moab::TempestRemapper::SetAreaMethod ( IntxAreaUtils::AreaMethod  method)
inline

Validate the GLOBAL_ID tags on the source and target meshes.

The remapping machinery identifies entities across MPI ranks solely by their GLOBAL_ID: the coverage migration packs vertex ids into tuple lists and resolves them on the receiving rank, and the map writer indexes rows/columns by element id. A missing tag reads back as the dense-tag default of -1 (see Core::globalId_tag), which is silently accepted and produces collapsed cells or a corrupt map far from the actual cause.

This checks, collectively, that every vertex and every element of both meshes has a strictly positive id, and that ids are locally unique. It is intended to run before any expensive operation so that a bad mesh fails immediately with a descriptive message.

Parameters
throw_errorIf true (default) return MB_FAILURE on the first problem found; if false only report the diagnosis and continue.
Returns
ErrorCode MB_SUCCESS when both meshes carry valid ids

Select the formula used for all spherical area computations driven by this remapper: the intersection kernel, the covering-set construction and the overlap-orientation fixups.

Offline drivers (mbtempest) should call this so that a single choice applies uniformly; online users get IntxAreaUtils::DEFAULT_AREA_METHOD, which is the adaptive Van Oosterom-Strackee formula.

Must be called before ConstructCoveringSet()/ComputeOverlapMesh() to take effect.

Definition at line 170 of file TempestRemapper.hpp.

171  {
172  m_area_method = method;
173  }

References m_area_method.

Referenced by main().

◆ SetMesh()

void moab::TempestRemapper::SetMesh ( Remapper::IntersectionContext  ctx,
Mesh *  mesh,
bool  overwrite = true 
)
inline

Set the TempestRemap mesh object according to the intersection context.

Parameters
ctxIntersection context
meshPointer to the TempestRemap mesh object
overwriteFlag to overwrite the existing mesh (default: true)

Definition at line 619 of file TempestRemapper.hpp.

620 {
621  switch( ctx )
622  {
624  if( !overwrite && m_source ) return;
625  if( overwrite && m_source ) delete m_source;
626  m_source = mesh;
627  break;
629  if( !overwrite && m_target ) return;
630  if( overwrite && m_target ) delete m_target;
631  m_target = mesh;
632  break;
634  if( !overwrite && m_overlap ) return;
635  if( overwrite && m_overlap ) delete m_overlap;
636  m_overlap = mesh;
637  break;
639  if( !overwrite && m_covering_source ) return;
640  if( overwrite && m_covering_source ) delete m_covering_source;
641  m_covering_source = mesh;
642  break;
643  case Remapper::DEFAULT:
644  default:
645  break;
646  }
647 }

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

Referenced by anonymous_namespace{mbtempest.cpp}::convertAndWriteMOABMesh().

◆ SetMeshSet()

void moab::TempestRemapper::SetMeshSet ( Remapper::IntersectionContext  ctx,
moab::EntityHandle  mset,
moab::Range *  entities = nullptr 
)

Set the mesh set according to the intersection context.

Parameters
ctxIntersection context
msetMOAB mesh set handle
entitiesMOAB range of entities (optional)

Definition at line 1008 of file TempestRemapper.cpp.

1011 {
1012 
1013  if( ctx == Remapper::SourceMesh ) // should not be used
1014  {
1015  m_source_set = mset;
1016  if( entities ) m_source_entities = *entities;
1017  }
1018  else if( ctx == Remapper::TargetMesh )
1019  {
1020  m_target_set = mset;
1021  if( entities ) m_target_entities = *entities;
1022  }
1023  else if( ctx == Remapper::CoveringMesh )
1024  {
1025  m_covering_source_set = mset;
1026  if( entities ) m_covering_source_entities = *entities;
1027  }
1028  else
1029  {
1030  // nothing to do really..
1031  return;
1032  }
1033 }

References moab::Remapper::CoveringMesh, m_covering_source_entities, m_covering_source_set, m_source_entities, m_source_set, m_target_entities, m_target_set, moab::Remapper::SourceMesh, and moab::Remapper::TargetMesh.

◆ SetMeshType()

void moab::TempestRemapper::SetMeshType ( Remapper::IntersectionContext  ctx,
const std::vector< int > &  metadata 
)
inline

Set the mesh type corresponding to the intersection context.

Parameters
ctxIntersection context
metadataVector of mesh type metadata

Definition at line 779 of file TempestRemapper.hpp.

780 {
781  switch( ctx )
782  {
784  m_source_type = static_cast< moab::TempestRemapper::TempestMeshType >( metadata[0] );
785  if( metadata[0] == 1 ) // RLL mesh
786  {
787  m_source_metadata.resize( 2 );
788  m_source_metadata[0] = metadata[1];
789  m_source_metadata[1] = metadata[2];
790  }
791  else
792  {
793  m_source_metadata.resize( 1 );
794  m_source_metadata[0] = metadata[1];
795  }
796  break;
798  m_target_type = static_cast< moab::TempestRemapper::TempestMeshType >( metadata[0] );
799  if( metadata[0] == 1 ) // RLL mesh
800  {
801  m_target_metadata.resize( 2 );
802  m_target_metadata[0] = metadata[1];
803  m_target_metadata[1] = metadata[2];
804  }
805  else
806  {
807  m_target_metadata.resize( 1 );
808  m_target_metadata[0] = metadata[1];
809  }
810  break;
813  default:
814  break;
815  }
816 }

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

Referenced by anonymous_namespace{mbtempest.cpp}::handleOverlapMOAB().

◆ SetRegionalMesh()

void moab::TempestRemapper::SetRegionalMesh ( bool  regional)
inline

Declare that the source and/or target mesh is regionally refined, so their domains need not coincide.

With this set, a source or target cell may be only partially covered by the other mesh (or not covered at all). The overlap-based area correction then treats the accumulated overlap area as authoritative for partially covered cells, rather than requiring it to agree with the geometric area to 1e-10. Without it a partially covered cell keeps its full geometric area while receiving only part of the overlap, which drives its map row sum below one.

Must be set before GenerateRemappingWeights() to take effect.

Definition at line 194 of file TempestRemapper.hpp.

195  {
196  rrmgrids = regional;
197  }

References rrmgrids.

Referenced by main().

◆ validate_global_ids_private()

ErrorCode moab::TempestRemapper::validate_global_ids_private ( moab::EntityHandle  mesh_set,
int  dimension,
const char *  mesh_name,
std::string &  error_message 
)
private

Helper for ValidateGlobalIds: check one mesh set at one dimension.

Definition at line 1250 of file TempestRemapper.cpp.

1254 {
1255  Range ents;
1256  MB_CHK_ERR( m_interface->get_entities_by_dimension( mesh_set, dimension, ents ) );
1257  if( ents.empty() ) return MB_SUCCESS; // nothing to check (e.g. empty partition)
1258 
1259  const char* what = ( 0 == dimension ? "vertex" : "element" );
1260 
1261  std::vector< int > gids( ents.size(), -1 );
1262  MB_CHK_ERR( m_interface->tag_get_data( m_interface->globalId_tag(), ents, gids.data() ) );
1263 
1264  // 1) every id must be strictly positive. A missing tag reads back as the
1265  // dense default of -1, which is the common failure mode.
1266  size_t n_bad = 0;
1267  int first_bad = 0;
1268  for( size_t i = 0; i < gids.size(); ++i )
1269  if( gids[i] <= 0 )
1270  {
1271  if( !n_bad ) first_bad = gids[i];
1272  ++n_bad;
1273  }
1274 
1275  if( n_bad )
1276  {
1277  std::ostringstream os;
1278  os << mesh_name << " mesh has " << n_bad << " of " << ents.size() << " " << what
1279  << " entities with a non-positive GLOBAL_ID (first bad value = " << first_bad << ")";
1280  if( n_bad == ents.size() )
1281  os << "; the GLOBAL_ID tag is most likely absent, so every entry is the tag default";
1282  error_message = os.str();
1283  return MB_FAILURE;
1284  }
1285 
1286  // 2) ids must be locally unique. Duplicates make entity identification
1287  // ambiguous during migration and corrupt the map rows/columns.
1288  std::vector< int > sorted( gids );
1289  std::sort( sorted.begin(), sorted.end() );
1290  std::vector< int >::iterator dup = std::adjacent_find( sorted.begin(), sorted.end() );
1291  if( dup != sorted.end() )
1292  {
1293  const size_t n_unique = std::distance( sorted.begin(), std::unique( sorted.begin(), sorted.end() ) );
1294  std::ostringstream os;
1295  os << mesh_name << " mesh has duplicate " << what << " GLOBAL_IDs: " << ents.size() << " entities but only "
1296  << n_unique << " distinct ids (e.g. id " << *dup << " appears more than once)";
1297  error_message = os.str();
1298  return MB_FAILURE;
1299  }
1300 
1301  return MB_SUCCESS;
1302 }

References moab::Range::empty(), moab::Interface::get_entities_by_dimension(), moab::Interface::globalId_tag(), moab::Remapper::m_interface, MB_CHK_ERR, MB_SUCCESS, moab::Range::size(), and moab::Interface::tag_get_data().

Referenced by ValidateGlobalIds().

◆ ValidateGlobalIds()

ErrorCode moab::TempestRemapper::ValidateGlobalIds ( bool  throw_error = true)

Definition at line 1304 of file TempestRemapper.cpp.

1305 {
1306  // Element ids are always required: they become the rows and columns of the map.
1307  //
1308  // Vertex ids are only required in parallel, where construct_covering_set() keys on
1309  // them to identify the corners of migrated source cells -- unnumbered vertices
1310  // collapse every corner to one handle and produce degenerate cells. Nothing
1311  // migrates in serial, so the vertex ids are never consulted and demanding them
1312  // rejects meshes that work perfectly well: in-memory NetCDF domain meshes, for
1313  // instance, carry element ids but no vertex ids.
1314  const bool check_vertices = is_parallel;
1315 
1316  const EntityHandle sets[2] = { m_source_set, m_target_set };
1317  const char* names[2] = { "source", "target" };
1318 
1319  std::string message;
1320  int local_bad = 0;
1321  for( int im = 0; im < 2 && !local_bad; ++im )
1322  {
1323  if( !sets[im] ) continue;
1324  for( int dim = ( check_vertices ? 0 : 2 ); dim <= 2; dim += 2 ) // vertices (0) and faces (2)
1325  {
1326  if( MB_SUCCESS != validate_global_ids_private( sets[im], dim, names[im], message ) )
1327  {
1328  local_bad = 1;
1329  break;
1330  }
1331  }
1332  }
1333 
1334  int global_bad = local_bad;
1335 #ifdef MOAB_HAVE_MPI
1336  if( m_pcomm )
1337  {
1338  // Collective: a mesh is only valid if it is valid on every rank, and every
1339  // rank must agree so that they fail (or continue) together.
1340  MPI_Allreduce( &local_bad, &global_bad, 1, MPI_INT, MPI_MAX, m_pcomm->comm() );
1341  }
1342 #endif
1343 
1344  if( global_bad )
1345  {
1346  if( local_bad )
1347  std::cout << "[ERROR] rank " << rank << ": " << message << std::endl;
1348  else if( is_root )
1349  std::cout << "[ERROR] invalid GLOBAL_IDs detected on another rank" << std::endl;
1350 
1351  if( throw_error )
1352  MB_SET_ERR( MB_FAILURE, "Invalid GLOBAL_ID tags on input meshes; refusing to proceed. "
1353  "Ensure both meshes carry unique, strictly positive GLOBAL_IDs on "
1354  "vertices and elements (e.g. re-partition with 'mbpart -j', or read "
1355  "SCRIP/NetCDF sources in parallel so ids are assigned)." );
1356  return MB_FAILURE;
1357  }
1358 
1359  return MB_SUCCESS;
1360 }

References is_parallel, is_root, m_source_set, m_target_set, MB_SET_ERR, MB_SUCCESS, rank, and validate_global_ids_private().

Referenced by ConstructCoveringSet().

◆ WriteTempestIntersectionMesh()

moab::ErrorCode moab::TempestRemapper::WriteTempestIntersectionMesh ( std::string  strOutputFileName,
const bool  fAllParallel,
const bool  fInputConcave,
const bool  fOutputConcave 
)

Gather the overlap mesh and associated 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.

Parameters
strOutputFileNameOutput file name
fAllParallelFlag to write all parallel data (default: false)
fInputConcaveFlag to indicate if the input mesh is concave (default: false)
fOutputConcaveFlag to indicate if the output mesh is concave (default: false)
Returns
ErrorCode indicating the status of the write operation

Definition at line 968 of file TempestRemapper.cpp.

972 {
973 
974  // Let us alos write out the TempestRemap equivalent so that we can do some verification checks
975  if( fAllParallel )
976  {
977  if( is_root && size == 1 )
978  {
979  this->m_source->CalculateFaceAreas( fInputConcave );
980  this->m_target->CalculateFaceAreas( fOutputConcave );
981  }
982  else
983  {
984  // Perform reduction and write from root processor
985  this->m_source->CalculateFaceAreas( fInputConcave );
986  this->m_covering_source->CalculateFaceAreas( fInputConcave );
987  this->m_target->CalculateFaceAreas( fOutputConcave );
988  }
989  }
990  else
991  {
992  this->m_source->CalculateFaceAreas( fInputConcave );
993  this->m_target->CalculateFaceAreas( fOutputConcave );
994  }
995 
996  // The overlap mesh is written by TempestRemap's own NetCDF writer (Mesh::Write). This is
997  // forwarded to libTempestRemap and cannot go through the MBNcDispatch layer; guard it in
998  // one place and skip with a notice when NetCDF is unavailable.
999 #ifdef MOAB_HAVE_NETCDF
1000  this->m_overlap->Write( strOutputFileName.c_str(), NcFile::Netcdf4 );
1001 #else
1002  if( is_root ) std::cout << "NetCDF is not configured. Intersection mesh write will be skipped...\n";
1003 #endif
1004 
1005  return moab::MB_SUCCESS;
1006 }

References MB_SUCCESS.

Friends And Related Function Documentation

◆ TempestOnlineMap

friend class TempestOnlineMap
friend

Definition at line 76 of file TempestRemapper.hpp.

Member Data Documentation

◆ constructEdgeMap

bool moab::TempestRemapper::constructEdgeMap

Flag to construct the edge map within the TempestRemap data structures.

If set to true, the edge map will be constructed within the TempestRemap data structures.

Definition at line 471 of file TempestRemapper.hpp.

Referenced by convert_mesh_to_tempest_private(), and main().

◆ is_parallel

bool moab::TempestRemapper::is_parallel = false
private

◆ is_root

bool moab::TempestRemapper::is_root = false
private

◆ m_area_method

IntxAreaUtils::AreaMethod moab::TempestRemapper::m_area_method = IntxAreaUtils::DEFAULT_AREA_METHOD
private

◆ m_covering_source

Mesh* moab::TempestRemapper::m_covering_source = nullptr
private

◆ m_covering_source_entities

moab::Range moab::TempestRemapper::m_covering_source_entities
private

◆ m_covering_source_set

moab::EntityHandle moab::TempestRemapper::m_covering_source_set = 0
private

◆ m_covering_source_vertices

moab::Range moab::TempestRemapper::m_covering_source_vertices
private

◆ m_overlap

Mesh* moab::TempestRemapper::m_overlap = nullptr
private

◆ m_overlap_entities

moab::Range moab::TempestRemapper::m_overlap_entities
private

◆ m_overlap_set

moab::EntityHandle moab::TempestRemapper::m_overlap_set = 0
private

◆ m_overlap_type

TempestMeshType moab::TempestRemapper::m_overlap_type = DEFAULT
private

Definition at line 577 of file TempestRemapper.hpp.

Referenced by ConvertTempestMesh(), GetMeshType(), and SetMeshType().

◆ m_sorted_overlap_order

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

Definition at line 580 of file TempestRemapper.hpp.

◆ m_source

Mesh* moab::TempestRemapper::m_source = nullptr
private

◆ m_source_entities

moab::Range moab::TempestRemapper::m_source_entities
private

◆ m_source_metadata

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

Definition at line 563 of file TempestRemapper.hpp.

Referenced by SetMeshType().

◆ m_source_set

◆ m_source_type

TempestMeshType moab::TempestRemapper::m_source_type
private

Definition at line 557 of file TempestRemapper.hpp.

Referenced by ConvertTempestMesh(), GetMeshType(), and SetMeshType().

◆ m_source_vertices

moab::Range moab::TempestRemapper::m_source_vertices
private

◆ m_target

Mesh* moab::TempestRemapper::m_target = nullptr
private

◆ m_target_entities

moab::Range moab::TempestRemapper::m_target_entities
private

◆ m_target_metadata

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

Definition at line 573 of file TempestRemapper.hpp.

Referenced by SetMeshType().

◆ m_target_set

◆ m_target_type

TempestMeshType moab::TempestRemapper::m_target_type
private

Definition at line 567 of file TempestRemapper.hpp.

Referenced by ConvertTempestMesh(), GetMeshType(), and SetMeshType().

◆ m_target_vertices

moab::Range moab::TempestRemapper::m_target_vertices
private

◆ max_source_edges

int moab::TempestRemapper::max_source_edges = 0
private

Definition at line 561 of file TempestRemapper.hpp.

Referenced by ConstructCoveringSet().

◆ max_target_edges

int moab::TempestRemapper::max_target_edges = 0
private

Definition at line 571 of file TempestRemapper.hpp.

Referenced by ConstructCoveringSet().

◆ mbintx

moab::Intx2MeshOnSphere* moab::TempestRemapper::mbintx = nullptr
private

Definition at line 583 of file TempestRemapper.hpp.

Referenced by ComputeOverlapMesh(), and ConstructCoveringSet().

◆ meshValidate

bool moab::TempestRemapper::meshValidate

Flag to enable mesh validation after loading from file.

If set to true, the mesh will be validated after it is loaded from a file.

Definition at line 463 of file TempestRemapper.hpp.

Referenced by main().

◆ offlineWorkflow

const bool moab::TempestRemapper::offlineWorkflow

Flag indicating whether the workflow is in offline mode.

This flag is used to determine the context of the workflow, specifically whether it is running in an offline mode (mbtempest).

Definition at line 456 of file TempestRemapper.hpp.

Referenced by convert_mesh_to_tempest_private(), and ConvertOverlapMeshSourceOrdered().

◆ point_cloud_source

bool moab::TempestRemapper::point_cloud_source = false
private

Definition at line 562 of file TempestRemapper.hpp.

Referenced by clear(), ConvertMeshToTempest(), GetIMasks(), and initialize().

◆ point_cloud_target

bool moab::TempestRemapper::point_cloud_target = false
private

◆ rank

◆ rrmgrids

bool moab::TempestRemapper::rrmgrids = false
private

Definition at line 593 of file TempestRemapper.hpp.

Referenced by ConstructCoveringSet(), IsRegionalMesh(), and SetRegionalMesh().

◆ size

int moab::TempestRemapper::size = 0
private

◆ verbose

const bool moab::TempestRemapper::verbose = true
static

Global verbosity flag.

This flag controls the verbosity of the output. If set to true, more detailed output will be generated.

Definition at line 479 of file TempestRemapper.hpp.

Referenced by convert_tempest_mesh_private(), ConvertMeshToTempest(), and ConvertTempestMesh().


The documentation for this class was generated from the following files: