Mesh Oriented datABase  (version 5.5.1)
An array-based unstructured mesh library
Remapper.hpp
Go to the documentation of this file.
1 /*
2  * =====================================================================================
3  *
4  * Filename: Remapper.hpp
5  *
6  * Description: Interface to the a general remapping capability on arbitrary topology
7  * that performs both mesh intersection between a source and target grid,
8  * with arbitrary decompositions. The intersections can then be used to
9  * either evaluate interpolation weights or to perform high-order
10  * conservative remapping of solutions defined on the source grid.
11  *
12  * Author: Vijay S. Mahadevan (vijaysm), [email protected]
13  *
14  * =====================================================================================
15  */
16 
17 #ifndef MB_REMAPPER_HPP
18 #define MB_REMAPPER_HPP
19 
20 #include <string>
21 
22 #include "moab/Interface.hpp"
23 #ifdef MOAB_HAVE_MPI
24 #include "moab/ParallelComm.hpp"
25 #endif
26 
27 // Tempest includes
28 #ifdef MOAB_HAVE_TEMPESTREMAP
29 #include "netcdfcpp.h"
30 #include "TempestRemapAPI.h"
31 #else
32 #error "This tool depends on TempestRemap library. Reconfigure using --with-tempestremap"
33 #endif
34 
35 namespace moab
36 {
37 
38 class Remapper
39 {
40  public:
41 #ifdef MOAB_HAVE_MPI
42  Remapper( moab::Interface* mbInt, moab::ParallelComm* pcomm = NULL ) : m_interface( mbInt ), m_pcomm( pcomm )
43 #else
44  Remapper( moab::Interface* mbInt ) : m_interface( mbInt )
45 #endif
46  {
47  }
48 
49  virtual ~Remapper()
50  {
51 #ifdef MOAB_HAVE_MPI
52  m_pcomm = NULL;
53 #endif
54  m_interface = NULL;
55  }
56 
58  {
59  DEFAULT = -1, // default context
60  SourceMesh = 0, // source mesh
61  TargetMesh = 1, // target mesh
62  OverlapMesh = 2, // overlap/intersection mesh
63  CoveringMesh = 3, // source mesh covering target mesh
64  SourceMeshWithGhosts = 4, // mesh with extra ghost layers to compute coverage in high order case or bilin
65  TargetMeshWithGhosts = 5 // mesh with extra ghost layers to impose target data limiting
66  };
67 
69  {
70  return m_interface;
71  }
72 
73 #ifdef MOAB_HAVE_MPI
74  moab::ParallelComm* get_parallel_communicator()
75  {
76  return m_pcomm;
77  }
78 
79  /// <summary>
80  /// ghost layers
81  /// </summary>
82  moab::ErrorCode GhostLayers( moab::EntityHandle& meshset, const int ngh_layers, moab::EntityHandle& set_with_ghosts )
83  {
84  // meshset contains the mesh set distributed already
85  //
86  moab::ErrorCode rval = m_interface->create_meshset( MESHSET_SET, set_with_ghosts );MB_CHK_ERR( rval );
87  // copy original content of mesh set here; we will use it later for local area, for example
88  // it will not have any ghosts in it
89  moab::Range orgEnts;
90  rval = m_interface->get_entities_by_handle( meshset, orgEnts );MB_CHK_ERR( rval );
91  rval = m_interface->add_entities( set_with_ghosts, orgEnts );MB_CHK_ERR( rval );
92  rval = m_pcomm->exchange_ghost_cells( 2, 0, 1, 0, true, true, &set_with_ghosts );MB_CHK_ERR( rval );
93  for( int i = 2; i <= ngh_layers; i++ )
94  {
95  rval = m_pcomm->correct_thin_ghost_layers();MB_CHK_ERR( rval );
96  rval = m_pcomm->exchange_ghost_cells( 2, 0, i, 0, true, true, &set_with_ghosts );MB_CHK_ERR( rval );
97  }
98 
99  // need to set global id tags
100  // need also to propagate global id to ghost cells; it is not done by default :(
103  rval = m_interface->get_entities_by_dimension( set_with_ghosts, 2, entities );MB_CHK_ERR( rval );
104  // get all vertices too, need to exchange global ids for vertices too
105  moab::Range vertices;
106  rval = m_interface->get_connectivity( entities, vertices );MB_CHK_ERR( rval );
107  entities.merge( vertices );
108  rval = m_pcomm->exchange_tags( gtag, entities );MB_CHK_ERR( rval );
109  return rval;
110  }
111 
112 #endif
113 
114  ErrorCode LoadNativeMesh( std::string filename,
115  moab::EntityHandle& meshset,
116  std::vector< int >& metadata,
117  const char* readopts = 0 )
118  {
119 #ifdef MOAB_HAVE_MPI
120  std::string opts = "";
121  if( readopts )
122  {
123  if( opts.size() )
124  opts = opts + ";" + std::string( readopts );
125  else
126  opts = std::string( readopts );
127  }
128 
129  if( !m_pcomm->rank() ) std::cout << "Reading file (" << filename << ") with options = [" << opts << "]\n";
130 #else
131  const std::string opts = std::string( ( readopts ? readopts : "" ) );
132  std::cout << "Reading file (" << filename << ") with options = [" << opts << "]\n";
133 #endif
134  moab::ErrorCode rval = m_interface->load_file( filename.c_str(), &meshset, opts.c_str() );MB_CHK_ERR( rval );
135 
136  Tag rectilinearTag;
137  rval = m_interface->tag_get_handle( "ClimateMetadata", rectilinearTag );
138 
139  if( rval != MB_FAILURE && rval != MB_TAG_NOT_FOUND && rval != MB_ALREADY_ALLOCATED &&
140  rectilinearTag != nullptr )
141  {
142  int dimSizes[3];
143  rval = m_interface->tag_get_data( rectilinearTag, &meshset, 1,
144  dimSizes ); // MB_CHK_SET_ERR( rval, "Error geting tag data" );
145  metadata.clear();
146  metadata.push_back( dimSizes[0] );
147  metadata.push_back( dimSizes[1] );
148  metadata.push_back( dimSizes[2] );
149  }
150 
151  return MB_SUCCESS;
152  }
153 
154  protected:
155  // member data
157 
158 #ifdef MOAB_HAVE_MPI
159  ParallelComm* m_pcomm;
160 #endif
161 };
162 
163 } // namespace moab
164 
165 #endif /* MB_REMAPPER_HPP */