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 LoadMesh (Remapper::IntersectionContext ctx, std::string inputFilename, TempestMeshType type)
 Load a mesh from disk of given type and store it under the context specified by the user. 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...
 
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::EntityHandleGetMeshSet (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::RangeGetMeshEntities (Remapper::IntersectionContext ctx)
 Get the mesh element entities corresponding to the intersection context. More...
 
const moab::RangeGetMeshEntities (Remapper::IntersectionContext ctx) const
 Const overload. Get the mesh element entities corresponding to the intersection context. More...
 
moab::RangeGetMeshVertices (Remapper::IntersectionContext ctx)
 Get the mesh vertices corresponding to the intersection context. Useful for point-cloud meshes. More...
 
const moab::RangeGetMeshVertices (Remapper::IntersectionContext ctx) const
 Const overload. Get the mesh vertices corresponding to the intersection context. Useful for point-cloud meshes. More...
 
moab::EntityHandleGetCoveringSet ()
 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::Interfaceget_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

ErrorCode ConvertAllMeshesToTempest ()
 Convert all MOAB meshes to TempestRemap format. More...
 
moab::ErrorCode ConvertOverlapMeshSourceOrdered ()
 Convert overlap mesh to source-ordered format. More...
 
moab::ErrorCode load_tempest_mesh_private (std::string inputFilename, Mesh **tempest_mesh)
 Load a mesh from disk in TempestRemap 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
 
TempestMeshType m_source_type
 
moab::Range m_source_entities
 
moab::Range m_source_vertices
 
moab::EntityHandle m_source_set
 
int max_source_edges
 
bool point_cloud_source
 
std::vector< int > m_source_metadata
 
Mesh * m_target
 
TempestMeshType m_target_type
 
moab::Range m_target_entities
 
moab::Range m_target_vertices
 
moab::EntityHandle m_target_set
 
int max_target_edges
 
bool point_cloud_target
 
std::vector< int > m_target_metadata
 
Mesh * m_overlap
 
TempestMeshType m_overlap_type
 
moab::Range m_overlap_entities
 
moab::EntityHandle m_overlap_set
 
std::vector< std::pair< int, int > > m_sorted_overlap_order
 
moab::Intx2MeshOnSpherembintx
 
Mesh * m_covering_source
 
moab::EntityHandle m_covering_source_set
 
moab::Range m_covering_source_entities
 
moab::Range m_covering_source_vertices
 
IntxAreaUtils::AreaMethod m_area_method
 
bool rrmgrids
 
bool is_parallel
 
bool is_root
 
int rank
 
int size
 

Friends

class TempestOnlineMap
 

Additional Inherited Members

- Protected Attributes inherited from moab::Remapper
Interfacem_interface
 

Detailed Description

Definition at line 36 of file TempestRemapper.hpp.

Member Enumeration Documentation

◆ TempestMeshType

Enumerator
DEFAULT 
CS 
RLL 
ICO 
ICOD 
OVERLAP_FILES 
OVERLAP_MEMORY 
OVERLAP_MOAB 

Definition at line 54 of file TempestRemapper.hpp.

55  {
56  DEFAULT = -1,
57  CS = 0,
58  RLL = 1,
59  ICO = 2,
60  ICOD = 3,
61  OVERLAP_FILES = 4,
62  OVERLAP_MEMORY = 5,
63  OVERLAP_MOAB = 6
64  };

Constructor & Destructor Documentation

◆ TempestRemapper()

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

Definition at line 43 of file TempestRemapper.hpp.

44  : Remapper( mbInt ),
45 #endif
46  offlineWorkflow( offlineMode ), meshValidate( false ), constructEdgeMap( false ), m_source_type( DEFAULT ),
48  {
49  }

◆ ~TempestRemapper()

moab::TempestRemapper::~TempestRemapper ( )
virtual

Definition at line 100 of file TempestRemapper.cpp.

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

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 1012 of file TempestRemapper.cpp.

1016 {
1017  assert( idtag );
1018 
1019  ErrorCode rval;
1020  Range entities;
1021  MB_CHK_SET_ERR( m_interface->get_entities_by_dimension( this_set, dimension, entities ), "Failed to get entities" );
1022 
1023  if( entities.size() == 0 ) return moab::MB_SUCCESS;
1024 
1025  int idoffset = start_id;
1026  std::vector< int > gid( entities.size() );
1027  for( unsigned i = 0; i < entities.size(); ++i )
1028  gid[i] = idoffset++;
1029 
1030  MB_CHK_ERR( m_interface->tag_set_data( idtag, entities, &gid[0] ) );
1031 
1032  return moab::MB_SUCCESS;
1033 }

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 105 of file TempestRemapper.cpp.

106 {
107  // destroy all meshes
108  if( m_source )
109  {
110  delete m_source;
111  m_source = nullptr;
112  }
113  if( m_target )
114  {
115  delete m_target;
116  m_target = nullptr;
117  }
118  if( m_overlap )
119  {
120  delete m_overlap;
121  m_overlap = nullptr;
122  }
123  if( m_covering_source && size > 1 )
124  {
125  delete m_covering_source;
126  m_covering_source = nullptr;
127  }
128 
129  point_cloud_source = false;
130  point_cloud_target = false;
131 
139  // gid_to_lid_src.clear();
140  // gid_to_lid_tgt.clear();
141  // gid_to_lid_covsrc.clear();
142  // lid_to_gid_src.clear();
143  // lid_to_gid_tgt.clear();
144  // lid_to_gid_covsrc.clear();
145 
146  return MB_SUCCESS;
147 }

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 1371 of file TempestRemapper.cpp.

1372 {
1373  const bool outputEnabled = ( this->rank == 0 );
1374  moab::DebugOutput dbgprint( std::cout, this->rank, 0 );
1375  dbgprint.set_prefix( "[ComputeOverlapMesh]: " );
1376 
1377  //
1378  // Create the intersection on the sphere object and set up necessary parameters
1379  //
1380  // First, split based on whether to use TempestRemap or MOAB for intersection
1381  // If TempestRemap,
1382  // 1) Check for valid Mesh and pointers to objects for source/target
1383  // 2) Invoke GenerateOverlapWithMeshes routine from Tempest library
1384  // If MOAB,
1385  // 1) Check for valid source and target meshsets (and entities)
1386  // 2) Build processor bounding boxes and construct a covering set
1387  // 3) Perform intersection between the source (covering) and target entities
1388  if( use_tempest )
1389  {
1390  // Now let us construct the overlap mesh, by calling TempestRemap interface directly
1391  // For the overlap method, choose between: "fuzzy", "exact" or "mixed"
1392  assert( m_covering_source != nullptr );
1393  assert( m_target != nullptr );
1394  if( m_overlap != nullptr ) delete m_overlap;
1395  bool concaveMeshA = false, concaveMeshB = false;
1396  // we have reset the overlap mesh - allocate now
1397  m_overlap = new Mesh();
1398  // Generate the overlap mesh using TempestRemap
1399  if( GenerateOverlapWithMeshes( *m_covering_source, *m_target, *m_overlap, "" /*outFilename*/, "Netcdf4",
1400  "exact", concaveMeshA, concaveMeshB, true, false ) )
1401  MB_CHK_SET_ERR( MB_FAILURE, "TempestRemap: cannot compute the intersection of meshes on the sphere" );
1402  }
1403  else
1404  {
1405  // Now perform the actual parallel intersection between the source and the target meshes
1406  if( kdtree_search )
1407  {
1408  if( outputEnabled ) dbgprint.printf( 0, "Computing intersection mesh with the Kd-tree search algorithm" );
1410  "Can't compute the intersection of meshes on the sphere with brute-force" );
1411  }
1412  else
1413  {
1414  if( outputEnabled )
1415  dbgprint.printf( 0, "Computing intersection mesh with the advancing-front propagation algorithm" );
1417  "Can't compute the intersection of meshes on the sphere" );
1418  }
1419 
1420 #ifdef MOAB_HAVE_MPI
1421  if( is_parallel || rrmgrids )
1422  {
1423 #ifdef VERBOSE
1424  std::stringstream ffc, fft, ffo;
1425  ffc << "cover_" << rank << ".h5m";
1426  fft << "target_" << rank << ".h5m";
1427  ffo << "intx_" << rank << ".h5m";
1428  MB_CHK_ERR( m_interface->write_mesh( ffc.str().c_str(), &m_covering_source_set, 1 ) );
1429  MB_CHK_ERR( m_interface->write_mesh( fft.str().c_str(), &m_target_set, 1 ) );
1430  MB_CHK_ERR( m_interface->write_mesh( ffo.str().c_str(), &m_overlap_set, 1 ) );
1431 #endif
1432  // because we do not want to work with elements in coverage set that do not participate
1433  // in intersection, remove them from the coverage set we will not delete them yet, just
1434  // remove from the set !
1435  if( !point_cloud_target )
1436  {
1437  Range covEnts;
1439 
1440  std::map< int, int > loc_gid_to_lid_covsrc;
1441  std::vector< int > gids( covEnts.size(), -1 );
1442 
1443  Tag gidtag = m_interface->globalId_tag();
1444  MB_CHK_ERR( m_interface->tag_get_data( gidtag, covEnts, gids.data() ) );
1445 
1446  for( unsigned ie = 0; ie < gids.size(); ++ie )
1447  {
1448  assert( gids[ie] > 0 );
1449  loc_gid_to_lid_covsrc[gids[ie]] = ie;
1450  }
1451 
1452  Range intxCov, intxCells;
1453  Tag srcParentTag;
1454  MB_CHK_ERR( m_interface->tag_get_handle( "SourceParent", srcParentTag ) );
1456  for( Range::iterator it = intxCells.begin(); it != intxCells.end(); it++ )
1457  {
1458  EntityHandle intxCell = *it;
1459  int srcParent = -1;
1460  MB_CHK_ERR( m_interface->tag_get_data( srcParentTag, &intxCell, 1, &srcParent ) );
1461 
1462  assert( srcParent >= 0 );
1463  intxCov.insert( covEnts[loc_gid_to_lid_covsrc[srcParent]] );
1464  }
1465 
1466  Range notNeededCovCells = moab::subtract( covEnts, intxCov );
1467 
1468  // now let us get only the covering entities that participate in intersection mesh
1469  covEnts = moab::subtract( covEnts, notNeededCovCells );
1470 
1471  // in order for getting 1-ring neighborhood, we need to be sure that the adjacencies are updated (created)
1472  if( false )
1473  {
1474  // update all adjacency list
1475  Core* mb = dynamic_cast< Core* >( m_interface );
1476  AEntityFactory* adj_fact = mb->a_entity_factory();
1477  if( !adj_fact->vert_elem_adjacencies() )
1478  adj_fact->create_vert_elem_adjacencies();
1479  else
1480  {
1481  for( Range::iterator it = covEnts.begin(); it != covEnts.end(); ++it )
1482  {
1483  EntityHandle eh = *it;
1484  const EntityHandle* conn = nullptr;
1485  int num_nodes = 0;
1486  MB_CHK_ERR( mb->get_connectivity( eh, conn, num_nodes ) );
1487  adj_fact->notify_create_entity( eh, conn, num_nodes );
1488  }
1489  }
1490 
1491  // next, for elements on the edge of the partition, get one ring adjacencies
1492  Skinner skinner( mb );
1493  Range skin;
1494  MB_CHK_SET_ERR( skinner.find_skin( m_covering_source_set, covEnts, false, skin ),
1495  "Unable to find skin" );
1496  for( Range::iterator it = skin.begin(); it != skin.end(); ++it )
1497  {
1498  const EntityHandle* conn = nullptr;
1499  int len = 0;
1500  MB_CHK_ERR( mb->get_connectivity( *it, conn, len, false ) );
1501  for( int ie = 0; ie < len; ++ie )
1502  {
1503  std::vector< EntityHandle > adjacent_entities;
1504  MB_CHK_ERR( adj_fact->get_adjacencies( conn[ie], 2, false, adjacent_entities ) );
1505  for( auto ent : adjacent_entities )
1506  notNeededCovCells.erase( ent ); // ent is part of the 1-ring neighborhood
1507  }
1508  }
1509 
1511  std::string( "sourcecoveragemesh_p" + std::to_string( rank ) + ".h5m" ).c_str(),
1512  &m_covering_source_set, 1 ) );
1513  }
1514 
1515  // remove now from coverage set the cells that are not needed
1516  // MB_CHK_ERR( m_interface->remove_entities( m_covering_source_set, notNeededCovCells ) );
1517 
1518  // Need to loop over covEnts now and ensure at least N-rings are available dependign on whether bilinear (1) or
1519  // high order FV (p) methods are being used for map generation. For bilinear/FV(1): need 1 ring, and for FV(p)
1520  // need p=ring neighborhood to recover exact conservation and consistency wrt serial/parallel.
1521 #ifdef VERBOSE
1522  std::cout << " total participating elements in the covering set: " << intxCov.size() << "\n";
1523  std::cout << " remove from coverage set elements that are not intersected: " << notNeededCovCells.size()
1524  << "\n";
1525 #endif
1526  if( size > 1 )
1527  {
1528  // some source elements cover multiple target partitions; the conservation logic
1529  // requires to know all overlap elements for a source element; they need to be
1530  // communicated from the other target partitions
1531  //
1532  // so first we have to identify source (coverage) elements that cover multiple
1533  // target partitions
1534  //
1535  // we will then mark the source, we will need to migrate the overlap elements
1536  // that cover this to the original source for the source element; then
1537  // distribute the overlap elements to all processors that have the coverage mesh
1538  // used
1540  }
1541  }
1542  }
1543 #endif
1544 
1545  // Fix any inconsistencies in the overlap mesh
1546  {
1547  IntxAreaUtils areaAdaptor;
1549  MB_CHK_ERR( areaAdaptor.positive_orientation( m_interface, m_overlap_set, 1.0 /*radius*/ ) );
1550  }
1551 
1552  // free the memory
1553  delete mbintx;
1554  }
1555 
1556  // Now, let us convert the overlap mesh to MOAB format so that we have a consistent interface
1557  MB_CHK_SET_ERR( ConvertOverlapMeshSourceOrdered(), "Can't convert overlap TempestRemap mesh to MOAB format" );
1558 
1559  return MB_SUCCESS;
1560 }

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_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, rrmgrids, 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 1224 of file TempestRemapper.cpp.

1231 {
1232  if( nb_ghost_layers >= 1 ) gnomonic = false;
1233  rrmgrids = regional_mesh;
1234  moab::Range local_verts;
1235 
1236  // Initialize intersection context
1238 
1240  mbintx->set_radius_source_mesh( radius_src );
1241  mbintx->set_radius_destination_mesh( radius_tgt );
1242  mbintx->set_box_error( boxeps );
1243 #ifdef MOAB_HAVE_MPI
1244  mbintx->set_parallel_comm( m_pcomm );
1245 #endif
1246 
1247  // compute the maxiumum edges in elements comprising source and target mesh
1249 
1252 
1253  // Note: lots of communication possible, if mesh is distributed very differently
1254 #ifdef MOAB_HAVE_MPI
1255  if( is_parallel )
1256  {
1257  MB_CHK_ERR( mbintx->build_processor_euler_boxes( m_target_set, local_verts, gnomonic ) );
1258 
1260  "Can't create new set" );
1261 
1262  MB_CHK_ERR( mbintx->construct_covering_set( m_source_set, m_covering_source_set, gnomonic, nb_ghost_layers ) );
1263 #ifdef MOAB_DBG
1264  std::stringstream filename;
1265  filename << "covering" << rank << ".h5m";
1266  MB_CHK_ERR( m_interface->write_file( filename.str().c_str(), 0, 0, &m_covering_source_set, 1 ) );
1267  std::stringstream targetFile;
1268  targetFile << "target" << rank << ".h5m";
1269  MB_CHK_ERR( m_interface->write_file( targetFile.str().c_str(), 0, 0, &m_target_set, 1 ) );
1270 #endif
1271  }
1272  else
1273  {
1274 #endif
1275  if( rrmgrids )
1276  {
1278  "Can't create new set" );
1279 
1280  double tolerance = 1e-6, btolerance = 1e-3;
1282  moab::Range targetVerts;
1283 
1284  MB_CHK_ERR( m_interface->get_connectivity( m_target_entities, targetVerts, true ) );
1285 
1286  MB_CHK_ERR( tree.build_tree( m_source_entities, &m_source_set ) );
1287 
1288  for( unsigned ie = 0; ie < targetVerts.size(); ++ie )
1289  {
1290  EntityHandle el = targetVerts[ie], leaf;
1291  double point[3];
1292 
1293  // Get the element centroid to be queried
1294  MB_CHK_ERR( m_interface->get_coords( &el, 1, point ) );
1295 
1296  // Search for the closest source element in the master mesh corresponding
1297  // to the target element centroid in the slave mesh
1298  MB_CHK_ERR( tree.point_search( point, leaf, tolerance, btolerance ) );
1299 
1300  if( leaf == 0 )
1301  {
1302  leaf = m_source_set; // no hint
1303  }
1304 
1305  std::vector< moab::EntityHandle > leaf_elems;
1306  // We only care about the dimension that the user specified.
1307  // MOAB partitions are ordered by elements anyway.
1308  MB_CHK_ERR( m_interface->get_entities_by_dimension( leaf, 2, leaf_elems ) );
1309 
1310  if( !leaf_elems.size() )
1311  {
1312  // std::cout << ie << ": " << " No leaf elements found." << std::endl;
1313  continue;
1314  }
1315 
1316  // Now get the master element centroids so that we can compute
1317  // the minimum distance to the target point
1318  std::vector< double > centroids( leaf_elems.size() * 3 );
1319  MB_CHK_ERR( m_interface->get_coords( &leaf_elems[0], leaf_elems.size(), &centroids[0] ) );
1320 
1321  double dist = 1e5;
1322  int pinelem = -1;
1323  for( size_t il = 0; il < leaf_elems.size(); ++il )
1324  {
1325  const double* centroid = &centroids[il * 3];
1326  const double locdist = std::pow( point[0] - centroid[0], 2 ) +
1327  std::pow( point[1] - centroid[1], 2 ) +
1328  std::pow( point[2] - centroid[2], 2 );
1329 
1330  if( locdist < dist )
1331  {
1332  dist = locdist;
1333  pinelem = il;
1334  m_covering_source_entities.insert( leaf_elems[il] );
1335  }
1336  }
1337 
1338  if( pinelem < 0 )
1339  {
1340  std::cout << ie
1341  << ": [Error] - Could not find a minimum distance within the leaf "
1342  "nodes. Dist = "
1343  << dist << std::endl;
1344  }
1345  }
1346  // MB_CHK_ERR( tree.reset_tree() );
1347  std::cout << "[INFO] - Total covering source entities = " << m_covering_source_entities.size() << std::endl;
1349  }
1350  else
1351  {
1354  m_covering_source_entities = m_source_entities; // this is a tempest mesh object; careful about
1355  // incrementing the reference?
1356  m_covering_source_vertices = m_source_vertices; // this is a tempest mesh object; careful about
1357  // incrementing the reference?
1358  }
1359 #ifdef MOAB_HAVE_MPI
1360  }
1361 #endif
1362 
1363  // Convert the source, target and coverage meshes to TempestRemap format
1365 
1366  return moab::MB_SUCCESS;
1367 }

References moab::Interface::add_entities(), moab::AdaptiveKDTree::build_tree(), ConvertAllMeshesToTempest(), moab::Interface::create_meshset(), moab::Intx2Mesh::FindMaxEdges(), moab::IntxAreaUtils::GaussQuadrature, moab::Interface::get_connectivity(), moab::Interface::get_coords(), moab::Interface::get_entities_by_dimension(), moab::Range::insert(), is_parallel, m_covering_source, m_covering_source_entities, m_covering_source_set, m_covering_source_vertices, moab::Remapper::m_interface, m_source, m_source_entities, m_source_set, m_source_vertices, m_target_entities, m_target_set, moab::Intx2Mesh::max_edges_1, moab::Intx2Mesh::max_edges_2, max_source_edges, max_target_edges, MB_CHK_ERR, MB_CHK_SET_ERR, MB_SUCCESS, mbintx, MESHSET_SET, moab::AdaptiveKDTree::point_search(), 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::Range::size(), moab::tolerance, 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 640 of file TempestRemapper.cpp.

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

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 254 of file TempestRemapper.cpp.

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

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 562 of file TempestRemapper.cpp.

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

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 588 of file TempestRemapper.cpp.

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

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(), CreateTempestMesh(), 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 797 of file TempestRemapper.cpp.

798 {
801  size_t n_overlap_entitites = m_overlap_entities.size();
802 
803  // Allocate for the overlap mesh
804  if( !m_overlap ) m_overlap = new Mesh();
805 
806  std::vector< std::array< int, 3 > > sorted_overlap_order( n_overlap_entitites,
807  std::array< int, 3 >( { -1, -1, -1 } ) );
808  {
809  Tag srcParentTag, tgtParentTag;
810  MB_CHK_ERR( m_interface->tag_get_handle( "SourceParent", srcParentTag ) );
811  MB_CHK_ERR( m_interface->tag_get_handle( "TargetParent", tgtParentTag ) );
812  // Overlap mesh: resize the source and target connection arrays
813  m_overlap->vecTargetFaceIx.resize( n_overlap_entitites );
814  m_overlap->vecSourceFaceIx.resize( n_overlap_entitites );
815 
816  // We need a global to local numbering
817  Tag gidtag = m_interface->globalId_tag();
818  std::vector< int > gids_src( m_covering_source_entities.size(), -1 ), gids_tgt( m_target_entities.size(), -1 );
819  MB_CHK_ERR( m_interface->tag_get_data( gidtag, m_covering_source_entities, gids_src.data() ) );
820  MB_CHK_ERR( m_interface->tag_get_data( gidtag, m_target_entities, gids_tgt.data() ) );
821 
822 // #define USE_SORTED_GIDS
823 #ifdef USE_SORTED_GIDS
824  // let us sort the global indices so that we always have a consistent ordering
825  std::sort( gids_src.begin(), gids_src.end() );
826  std::sort( gids_tgt.begin(), gids_tgt.end() );
827 
828  auto find_lid = []( std::vector< int >& gids, int gid ) -> int {
829  // auto it = std::equal_range( gids.begin(), gids.end(), gid );
830  // return ( ( it.first != it.second ) ? std::distance( gids.begin(), it.first ) : -1 );
831 
832  auto it = std::lower_bound( gids.begin(), gids.end(), gid );
833  return ( it != gids.end() ? std::distance( gids.begin(), it ) : -1 );
834  };
835 #else
836  auto find_lid = []( std::vector< int >& gids, int gid ) -> int {
837  auto it = std::find( gids.begin(), gids.end(), gid );
838  return ( it != gids.end() ? std::distance( gids.begin(), it ) : -1 );
839  };
840 #endif
841 
842  std::vector< int > ghFlags;
843  if( is_parallel )
844  {
845  Tag ghostTag;
846  ghFlags.resize( n_overlap_entitites );
847  MB_CHK_SET_ERR( m_interface->tag_get_handle( "ORIG_PROC", ghostTag ), "Could not find ORIG_PROC tag" );
848  MB_CHK_ERR( m_interface->tag_get_data( ghostTag, m_overlap_entities, ghFlags.data() ) );
849  }
850 
851  // Overlap mesh: resize the source and target connection arrays
852  std::vector< int > rbids_src( n_overlap_entitites ), rbids_tgt( n_overlap_entitites );
853  MB_CHK_ERR( m_interface->tag_get_data( srcParentTag, m_overlap_entities, rbids_src.data() ) );
854  MB_CHK_ERR( m_interface->tag_get_data( tgtParentTag, m_overlap_entities, rbids_tgt.data() ) );
855 
856  for( size_t ix = 0; ix < n_overlap_entitites; ++ix )
857  {
858  std::get< 0 >( sorted_overlap_order[ix] ) = ix;
859  std::get< 1 >( sorted_overlap_order[ix] ) = find_lid( gids_src, rbids_src[ix] );
860  assert( std::get< 1 >( sorted_overlap_order[ix] ) >= 0 );
861  if( is_parallel && ghFlags[ix] >= 0 ) // it means it is a ghost overlap element
862  std::get< 2 >( sorted_overlap_order[ix] ) = -1; // this should not participate in the map!
863  else
864  std::get< 2 >( sorted_overlap_order[ix] ) = find_lid( gids_tgt, rbids_tgt[ix] );
865  }
866  // now sort the overlap elements such that they are ordered by source parent first
867  // and then target parent next
868  std::sort( sorted_overlap_order.begin(), sorted_overlap_order.end(), IntPairComparator );
869 
870  for( unsigned ie = 0; ie < n_overlap_entitites; ++ie )
871  {
872  // int ix = std::get< 0 >( sorted_overlap_order[ie] ); // original index of the element
873  m_overlap->vecSourceFaceIx[ie] = std::get< 1 >( sorted_overlap_order[ie] );
874  m_overlap->vecTargetFaceIx[ie] = std::get< 2 >( sorted_overlap_order[ie] );
875  }
876  }
877 
878  FaceVector& faces = m_overlap->faces;
879  faces.resize( n_overlap_entitites );
880 
881  Range verts;
882  // let us now get the vertices from all the elements
884 
885  std::map< EntityHandle, int > indxMap;
886  {
887  int j = 0;
888  for( Range::iterator it = verts.begin(); it != verts.end(); ++it )
889  indxMap[*it] = j++;
890  }
891 
892  for( unsigned ifac = 0; ifac < m_overlap_entities.size(); ++ifac )
893  {
894  const unsigned iface = std::get< 0 >( sorted_overlap_order[ifac] );
895  Face& face = faces[ifac];
897 
898  // get the connectivity for each edge
899  const EntityHandle* connectface;
900  int nnodesf;
901  MB_CHK_ERR( m_interface->get_connectivity( ehandle, connectface, nnodesf ) );
902 
903  face.edges.resize( nnodesf );
904  for( int iverts = 0; iverts < nnodesf; ++iverts )
905  {
906  int indx = indxMap[connectface[iverts]];
907  assert( indx >= 0 );
908  face.SetNode( iverts, indx );
909  }
910  }
911  indxMap.clear();
912  sorted_overlap_order.clear();
913 
914  unsigned nnodes = verts.size();
915  NodeVector& nodes = m_overlap->nodes;
916  nodes.resize( nnodes );
917 
918  // Set the data for the vertices
919  std::vector< double > coordx( nnodes ), coordy( nnodes ), coordz( nnodes );
920  MB_CHK_ERR( m_interface->get_coords( verts, &coordx[0], &coordy[0], &coordz[0] ) );
921  for( unsigned inode = 0; inode < nnodes; ++inode )
922  {
923  Node& node = nodes[inode];
924  node.x = coordx[inode];
925  node.y = coordy[inode];
926  node.z = coordz[inode];
927  }
928  coordx.clear();
929  coordy.clear();
930  coordz.clear();
931  verts.clear();
932 
933  // m_overlap->RemoveZeroEdges();
934  // m_overlap->RemoveCoincidentNodes( false );
935 
936  // Generate reverse node array and edge map
937  // if ( constructEdgeMap ) m_overlap->ConstructEdgeMap(false);
938  // m_overlap->ConstructReverseNodeArray();
939 
940  m_overlap->Validate();
941  return MB_SUCCESS;
942 }

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::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, 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 225 of file TempestRemapper.cpp.

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

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

Referenced by main().

◆ 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 1044 of file TempestRemapper.cpp.

1049 {
1050  const int csResolution = std::sqrt( ntot_elements / 6.0 );
1051  if( csResolution * csResolution * 6 != ntot_elements ) return MB_INVALID_SIZE;
1052 
1053  // Create a temporary Cubed-Sphere mesh
1054  // NOTE: This will not work for RRM grids. Need to run HOMME for that case anyway
1055  Mesh csMesh;
1056  if( GenerateCSMesh( csMesh, csResolution, "", "NetCDF4" ) )
1057  MB_CHK_SET_ERR( moab::MB_FAILURE, // unsuccessful call
1058  "Failed to generate CS mesh through TempestRemap" );
1059 
1060  // let us now generate the mesh metadata
1061  if( this->GenerateMeshMetadata( csMesh, ntot_elements, ents, secondary_ents, dofTagName, nP ) )
1062  MB_CHK_SET_ERR( moab::MB_FAILURE, "Failed in call to GenerateMeshMetadata" ); // unsuccessful call
1063 
1064  return moab::MB_SUCCESS;
1065 }

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 1067 of file TempestRemapper.cpp.

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

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

◆ GetCoveringMesh()

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

Get the covering mesh (TempestRemap) object.

Returns
Pointer to the covering mesh object

Definition at line 746 of file TempestRemapper.hpp.

747 {
748  return m_covering_source;
749 }

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 751 of file TempestRemapper.hpp.

752 {
753  return m_covering_source_set;
754 }

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 2178 of file TempestRemapper.cpp.

2179 {
2180  Tag maskTag;
2181  // it should have been created already, if not, we might have a problem
2182  int def_val = 1;
2184  &def_val ),
2185  "Trouble creating GRID_IMASK tag" );
2186 
2187  switch( ctx )
2188  {
2189  case Remapper::SourceMesh: {
2190  if( point_cloud_source )
2191  {
2192  masks.resize( m_source_vertices.size() );
2193  MB_CHK_SET_ERR( m_interface->tag_get_data( maskTag, m_source_vertices, &masks[0] ),
2194  "Trouble getting GRID_IMASK tag" );
2195  }
2196  else
2197  {
2198  masks.resize( m_source_entities.size() );
2199  MB_CHK_SET_ERR( m_interface->tag_get_data( maskTag, m_source_entities, &masks[0] ),
2200  "Trouble getting GRID_IMASK tag" );
2201  }
2202  return MB_SUCCESS;
2203  }
2204  case Remapper::TargetMesh: {
2205  if( point_cloud_target )
2206  {
2207  masks.resize( m_target_vertices.size() );
2208  MB_CHK_SET_ERR( m_interface->tag_get_data( maskTag, m_target_vertices, &masks[0] ),
2209  "Trouble getting GRID_IMASK tag" );
2210  }
2211  else
2212  {
2213  masks.resize( m_target_entities.size() );
2214  MB_CHK_SET_ERR( m_interface->tag_get_data( maskTag, m_target_entities, &masks[0] ),
2215  "Trouble getting GRID_IMASK tag" );
2216  }
2217  return MB_SUCCESS;
2218  }
2220  case Remapper::OverlapMesh:
2221  default:
2222  return MB_SUCCESS;
2223  }
2224 }

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 513 of file TempestRemapper.hpp.

514 {
515  switch( ctx )
516  {
518  return m_source;
520  return m_target;
522  return m_overlap;
524  return m_covering_source;
525  case Remapper::DEFAULT:
526  default:
527  return NULL;
528  }
529 }

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 CreateTempestMesh(), 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 623 of file TempestRemapper.hpp.

624 {
625  switch( ctx )
626  {
628  return m_source_entities;
630  return m_target_entities;
632  return m_overlap_entities;
635  case Remapper::DEFAULT:
636  default:
637  MB_SET_ERR_RET_VAL( "Invalid context passed to GetMeshSet", m_overlap_entities );
638  }
639 }

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 641 of file TempestRemapper.hpp.

642 {
643  switch( ctx )
644  {
646  return m_source_entities;
648  return m_target_entities;
650  return m_overlap_entities;
653  case Remapper::DEFAULT:
654  default:
655  MB_SET_ERR_RET_VAL( "Invalid context passed to GetMeshSet", m_overlap_entities );
656  }
657 }

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 587 of file TempestRemapper.hpp.

588 {
589  switch( ctx )
590  {
592  return m_source_set;
594  return m_target_set;
596  return m_overlap_set;
598  return m_covering_source_set;
599  case Remapper::DEFAULT:
600  default:
601  MB_SET_ERR_RET_VAL( "Invalid context passed to GetMeshSet", m_overlap_set );
602  }
603 }

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 CreateTempestMesh(), 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 605 of file TempestRemapper.hpp.

606 {
607  switch( ctx )
608  {
610  return m_source_set;
612  return m_target_set;
614  return m_overlap_set;
616  return m_covering_source_set;
617  case Remapper::DEFAULT:
618  default:
619  MB_SET_ERR_RET_VAL( "Invalid context passed to GetMeshSet", m_overlap_set );
620  }
621 }

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 730 of file TempestRemapper.hpp.

731 {
732  switch( ctx )
733  {
735  return m_source_type;
737  return m_target_type;
739  return m_overlap_type;
740  case Remapper::DEFAULT:
741  default:
743  }
744 }

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 659 of file TempestRemapper.hpp.

660 {
661  switch( ctx )
662  {
664  return m_source_vertices;
666  return m_target_vertices;
669  case Remapper::DEFAULT:
670  default:
671  MB_SET_ERR_RET_VAL( "Invalid context passed to GetMeshSet", m_source_vertices );
672  }
673 }

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 675 of file TempestRemapper.hpp.

676 {
677  switch( ctx )
678  {
680  return m_source_vertices;
682  return m_target_vertices;
685  case Remapper::DEFAULT:
686  default:
687  MB_SET_ERR_RET_VAL( "Invalid context passed to GetMeshSet", m_source_vertices );
688  }
689 }

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 758 of file TempestRemapper.cpp.

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

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 53 of file TempestRemapper.cpp.

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

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

◆ load_tempest_mesh_private()

ErrorCode moab::TempestRemapper::load_tempest_mesh_private ( std::string  inputFilename,
Mesh **  tempest_mesh 
)
private

Load a mesh from disk in TempestRemap format.

Parameters
inputFilenamePath to the input mesh file
tempest_meshPointer to store the loaded TempestRemap mesh
Returns
moab::ErrorCode Status of the load operation

Definition at line 176 of file TempestRemapper.cpp.

177 {
178  const bool outputEnabled = ( TempestRemapper::verbose && is_root );
179  if( outputEnabled ) std::cout << "\nLoading TempestRemap Mesh object from file = " << inputFilename << " ...\n";
180 
181  {
182  NcError error( NcError::silent_nonfatal );
183 
184  try
185  {
186  // Load input mesh
187  if( outputEnabled ) std::cout << "Loading mesh ...\n";
188  Mesh* mesh = new Mesh( inputFilename );
189  mesh->RemoveZeroEdges();
190  if( outputEnabled ) std::cout << "----------------\n";
191 
192  // Validate mesh
193  if( meshValidate )
194  {
195  if( outputEnabled ) std::cout << "Validating mesh ...\n";
196  mesh->Validate();
197  if( outputEnabled ) std::cout << "-------------------\n";
198  }
199 
200  // Construct the edge map on the mesh
201  if( constructEdgeMap )
202  {
203  if( outputEnabled ) std::cout << "Constructing edge map on mesh ...\n";
204  mesh->ConstructEdgeMap( false );
205  if( outputEnabled ) std::cout << "---------------------------------\n";
206  }
207 
208  if( tempest_mesh ) *tempest_mesh = mesh;
209  }
210  catch( Exception& e )
211  {
212  std::cout << "TempestRemap ERROR: " << e.ToString() << "\n";
213  return MB_FAILURE;
214  }
215  catch( ... )
216  {
217  return MB_FAILURE;
218  }
219  }
220  return MB_SUCCESS;
221 }

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

Referenced by LoadMesh().

◆ LoadMesh()

ErrorCode moab::TempestRemapper::LoadMesh ( Remapper::IntersectionContext  ctx,
std::string  inputFilename,
TempestMeshType  type 
)

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

Parameters
ctxIntersection context
inputFilenameFile name of the mesh to load
typeType of mesh to load
Returns
ErrorCode indicating the status of the mesh loading

Definition at line 151 of file TempestRemapper.cpp.

154 {
155  if( ctx == Remapper::SourceMesh )
156  {
157  m_source_type = type;
158  return load_tempest_mesh_private( inputFilename, &m_source );
159  }
160  else if( ctx == Remapper::TargetMesh )
161  {
162  m_target_type = type;
163  return load_tempest_mesh_private( inputFilename, &m_target );
164  }
165  else if( ctx != Remapper::DEFAULT )
166  {
167  m_overlap_type = type;
168  return load_tempest_mesh_private( inputFilename, &m_overlap );
169  }
170  else
171  {
172  MB_CHK_SET_ERR( MB_FAILURE, "Invalid IntersectionContext context provided" );
173  }
174 }

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

Referenced by CreateTempestMesh(), and main().

◆ 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 561 of file TempestRemapper.hpp.

562 {
563  switch( ctx )
564  {
566  delete m_source;
567  m_source = new Mesh;
568  m_source_set = meshSet;
570  m_source->CalculateFaceAreas( false ); // fInputConcave is false ?
571  break;
573  // not needed yet
574  break;
576  // not needed yet
577  break;
579  // not needed yet
580  break;
581  case Remapper::DEFAULT:
582  default:
583  break;
584  }
585 }

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.

◆ 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 531 of file TempestRemapper.hpp.

532 {
533  switch( ctx )
534  {
536  if( !overwrite && m_source ) return;
537  if( overwrite && m_source ) delete m_source;
538  m_source = mesh;
539  break;
541  if( !overwrite && m_target ) return;
542  if( overwrite && m_target ) delete m_target;
543  m_target = mesh;
544  break;
546  if( !overwrite && m_overlap ) return;
547  if( overwrite && m_overlap ) delete m_overlap;
548  m_overlap = mesh;
549  break;
551  if( !overwrite && m_covering_source ) return;
552  if( overwrite && m_covering_source ) delete m_covering_source;
553  m_covering_source = mesh;
554  break;
555  case Remapper::DEFAULT:
556  default:
557  break;
558  }
559 }

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

◆ 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 982 of file TempestRemapper.cpp.

985 {
986 
987  if( ctx == Remapper::SourceMesh ) // should not be used
988  {
989  m_source_set = mset;
990  if( entities ) m_source_entities = *entities;
991  }
992  else if( ctx == Remapper::TargetMesh )
993  {
994  m_target_set = mset;
995  if( entities ) m_target_entities = *entities;
996  }
997  else if( ctx == Remapper::CoveringMesh )
998  {
999  m_covering_source_set = mset;
1000  if( entities ) m_covering_source_entities = *entities;
1001  }
1002  else
1003  {
1004  // nothing to do really..
1005  return;
1006  }
1007 }

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 691 of file TempestRemapper.hpp.

692 {
693  switch( ctx )
694  {
696  m_source_type = static_cast< moab::TempestRemapper::TempestMeshType >( metadata[0] );
697  if( metadata[0] == 1 ) // RLL mesh
698  {
699  m_source_metadata.resize( 2 );
700  m_source_metadata[0] = metadata[1];
701  m_source_metadata[1] = metadata[2];
702  }
703  else
704  {
705  m_source_metadata.resize( 1 );
706  m_source_metadata[0] = metadata[1];
707  }
708  break;
710  m_target_type = static_cast< moab::TempestRemapper::TempestMeshType >( metadata[0] );
711  if( metadata[0] == 1 ) // RLL mesh
712  {
713  m_target_metadata.resize( 2 );
714  m_target_metadata[0] = metadata[1];
715  m_target_metadata[1] = metadata[2];
716  }
717  else
718  {
719  m_target_metadata.resize( 1 );
720  m_target_metadata[0] = metadata[1];
721  }
722  break;
725  default:
726  break;
727  }
728 }

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

◆ 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 946 of file TempestRemapper.cpp.

950 {
951  // Let us alos write out the TempestRemap equivalent so that we can do some verification checks
952  if( fAllParallel )
953  {
954  if( is_root && size == 1 )
955  {
956  this->m_source->CalculateFaceAreas( fInputConcave );
957  this->m_target->CalculateFaceAreas( fOutputConcave );
958  this->m_overlap->Write( strOutputFileName.c_str(), NcFile::Netcdf4 );
959  }
960  else
961  {
962  // Perform reduction and write from root processor
963  // if ( is_root )
964  // std::cout << "--- PARALLEL IMPLEMENTATION is NOT AVAILABLE yet ---\n";
965 
966  this->m_source->CalculateFaceAreas( fInputConcave );
967  this->m_covering_source->CalculateFaceAreas( fInputConcave );
968  this->m_target->CalculateFaceAreas( fOutputConcave );
969  this->m_overlap->Write( strOutputFileName.c_str(), NcFile::Netcdf4 );
970  }
971  }
972  else
973  {
974  this->m_source->CalculateFaceAreas( fInputConcave );
975  this->m_target->CalculateFaceAreas( fOutputConcave );
976  this->m_overlap->Write( strOutputFileName.c_str(), NcFile::Netcdf4 );
977  }
978 
979  return moab::MB_SUCCESS;
980 }

References MB_SUCCESS.

Friends And Related Function Documentation

◆ TempestOnlineMap

friend class TempestOnlineMap
friend

Definition at line 66 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 383 of file TempestRemapper.hpp.

Referenced by convert_mesh_to_tempest_private(), load_tempest_mesh_private(), and main().

◆ is_parallel

bool moab::TempestRemapper::is_parallel
private

◆ is_root

◆ m_area_method

IntxAreaUtils::AreaMethod moab::TempestRemapper::m_area_method
private

Definition at line 505 of file TempestRemapper.hpp.

◆ m_covering_source

Mesh* moab::TempestRemapper::m_covering_source
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
private

◆ m_covering_source_vertices

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

◆ m_overlap

Mesh* moab::TempestRemapper::m_overlap
private

◆ m_overlap_entities

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

◆ m_overlap_set

moab::EntityHandle moab::TempestRemapper::m_overlap_set
private

◆ m_overlap_type

TempestMeshType moab::TempestRemapper::m_overlap_type
private

Definition at line 487 of file TempestRemapper.hpp.

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

◆ m_sorted_overlap_order

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

Definition at line 490 of file TempestRemapper.hpp.

◆ m_source

◆ 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 473 of file TempestRemapper.hpp.

Referenced by SetMeshType().

◆ m_source_set

moab::EntityHandle moab::TempestRemapper::m_source_set
private

◆ m_source_type

TempestMeshType moab::TempestRemapper::m_source_type
private

Definition at line 467 of file TempestRemapper.hpp.

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

◆ m_source_vertices

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

◆ m_target

Mesh* moab::TempestRemapper::m_target
private

◆ m_target_entities

◆ m_target_metadata

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

Definition at line 483 of file TempestRemapper.hpp.

Referenced by SetMeshType().

◆ m_target_set

moab::EntityHandle moab::TempestRemapper::m_target_set
private

◆ m_target_type

TempestMeshType moab::TempestRemapper::m_target_type
private

Definition at line 477 of file TempestRemapper.hpp.

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

◆ m_target_vertices

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

◆ max_source_edges

int moab::TempestRemapper::max_source_edges
private

Definition at line 471 of file TempestRemapper.hpp.

Referenced by ConstructCoveringSet().

◆ max_target_edges

int moab::TempestRemapper::max_target_edges
private

Definition at line 481 of file TempestRemapper.hpp.

Referenced by ConstructCoveringSet().

◆ mbintx

moab::Intx2MeshOnSphere* moab::TempestRemapper::mbintx
private

Definition at line 493 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 375 of file TempestRemapper.hpp.

Referenced by load_tempest_mesh_private(), and 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 368 of file TempestRemapper.hpp.

Referenced by convert_mesh_to_tempest_private().

◆ point_cloud_source

bool moab::TempestRemapper::point_cloud_source
private

Definition at line 472 of file TempestRemapper.hpp.

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

◆ point_cloud_target

bool moab::TempestRemapper::point_cloud_target
private

◆ rank

◆ rrmgrids

bool moab::TempestRemapper::rrmgrids
private

Definition at line 507 of file TempestRemapper.hpp.

Referenced by ComputeOverlapMesh(), and ConstructCoveringSet().

◆ size

int moab::TempestRemapper::size
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 391 of file TempestRemapper.hpp.

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


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