Mesh Oriented datABase  (version 5.6.0)
An array-based unstructured mesh library
moab::NCHelperESMF Class Reference

#include <NCHelperESMF.hpp>

+ Inheritance diagram for moab::NCHelperESMF:
+ Collaboration diagram for moab::NCHelperESMF:

Public Member Functions

 NCHelperESMF (ReadNC *readNC, int fileId, const FileOptions &opts, EntityHandle fileSet)
 
- Public Member Functions inherited from moab::UcdNCHelper
 UcdNCHelper (ReadNC *readNC, int fileId, const FileOptions &opts, EntityHandle fileSet)
 
virtual ~UcdNCHelper ()
 
- Public Member Functions inherited from moab::NCHelper
 NCHelper (ReadNC *readNC, int fileId, const FileOptions &opts, EntityHandle fileSet)
 
virtual ~NCHelper ()
 
ErrorCode create_conventional_tags (const std::vector< int > &tstep_nums)
 Create NC conventional tags. More...
 
ErrorCode update_time_tag_vals ()
 Update time tag values if timesteps spread across files. More...
 

Static Public Member Functions

static bool can_read_file (ReadNC *readNC)
 
- Static Public Member Functions inherited from moab::NCHelper
static ReadNC::NCFormatType get_nc_format (ReadNC *readNC, int fileId)
 Get appropriate format to read the file. More...
 
static std::string get_default_ncformat_options (ReadNC::NCFormatType format)
 Get appropriate format to read the file. More...
 
static NCHelperget_nc_helper (ReadNC *readNC, int fileId, const FileOptions &opts, EntityHandle fileSet)
 Get appropriate helper instance for ReadNC class. More...
 

Private Member Functions

virtual ErrorCode init_mesh_vals ()
 Implementation of NCHelper::init_mesh_vals() More...
 
virtual ErrorCode create_mesh (Range &faces)
 Implementation of NCHelper::create_mesh() More...
 
virtual std::string get_mesh_type_name ()
 Implementation of NCHelper::get_mesh_type_name() More...
 
ErrorCode create_local_vertices (const std::vector< int > &vertices_on_local_cells, EntityHandle &start_vertex)
 Create local vertices. More...
 
ErrorCode create_local_cells (const std::vector< int > &vertices_on_local_cells, const std::vector< int > &num_edges_on_local_cells, EntityHandle start_vertex, Range &faces)
 Create local cells without padding (cells are divided into groups based on the number of edges) More...
 
ErrorCode create_padded_local_cells (const std::vector< int > &vertices_on_local_cells, EntityHandle start_vertex, Range &faces)
 Create local cells with padding (padded cells will have the same number of edges) More...
 
virtual ErrorCode check_existing_mesh ()
 
virtual ErrorCode read_ucd_variables_to_nonset_allocate (std::vector< ReadNC::VarData > &, std::vector< int > &)
 Implementation of UcdNCHelper::read_ucd_variables_to_nonset_allocate() More...
 
virtual ErrorCode read_ucd_variables_to_nonset (std::vector< ReadNC::VarData > &, std::vector< int > &)
 Implementation of UcdNCHelper::read_ucd_variables_to_nonset() More...
 

Private Attributes

int maxEdgesPerCell
 
int coordDim
 
int centerCoordsId
 
bool degrees
 
Range facesOwned
 

Additional Inherited Members

- Protected Member Functions inherited from moab::UcdNCHelper
template<typename T >
void kji_to_jik_stride (size_t, size_t nj, size_t nk, void *dest, T *source, Range &localGid)
 This version takes as input the moab range, from which we actually need just the size of each sequence, for a proper transpose of the data. More...
 
- Protected Member Functions inherited from moab::NCHelper
ErrorCode read_variables_setup (std::vector< std::string > &var_names, std::vector< int > &tstep_nums, std::vector< ReadNC::VarData > &vdatas, std::vector< ReadNC::VarData > &vsetdatas)
 Separate set and non-set variables (common to scd mesh and ucd mesh) More...
 
ErrorCode read_variables_to_set (std::vector< ReadNC::VarData > &vdatas, std::vector< int > &tstep_nums)
 Read set variables (common to scd mesh and ucd mesh) More...
 
ErrorCode read_coordinate (const char *var_name, int lmin, int lmax, std::vector< double > &cvals)
 
ErrorCode get_tag_to_set (ReadNC::VarData &var_data, int tstep_num, Tag &tagh)
 
ErrorCode get_tag_to_nonset (ReadNC::VarData &var_data, int tstep_num, Tag &tagh, int num_lev)
 
ErrorCode create_attrib_string (const std::map< std::string, ReadNC::AttData > &attMap, std::string &attString, std::vector< int > &attLen)
 Create a character string attString of attMap. with '\0' terminating each attribute name, ';' separating the data type and value, and ';' separating one name/data type/value from the next'. attLen stores the end position for each name/data type/ value. More...
 
ErrorCode create_dummy_variables ()
 For a dimension that does not have a corresponding coordinate variable (e.g. ncol for HOMME), create a dummy variable with a sparse tag to store the dimension length. More...
 
- Protected Attributes inherited from moab::UcdNCHelper
int nCells
 Dimensions of global grid in file. More...
 
int nEdges
 
int nVertices
 
int nLocalCells
 Dimensions of my local part of grid. More...
 
int nLocalEdges
 
int nLocalVertices
 
std::vector< double > xVertVals
 Coordinate values for vertices. More...
 
std::vector< double > yVertVals
 
std::vector< double > zVertVals
 
int cDim
 Dimension numbers for nCells, nEdges and nVertices. More...
 
int eDim
 
int vDim
 
Range localGidCells
 Local global ID for cells, edges and vertices. More...
 
Range localGidEdges
 
Range localGidVerts
 
- Protected Attributes inherited from moab::NCHelper
ReadNC_readNC
 Allow NCHelper to directly access members of ReadNC. More...
 
int _fileId
 Cache some information from ReadNC. More...
 
const FileOptions_opts
 
EntityHandle _fileSet
 
int nTimeSteps
 Dimensions of time and level. More...
 
int nLevels
 
std::vector< double > tVals
 Values for time and level. More...
 
std::vector< double > levVals
 
int tDim
 Dimension numbers for time and level. More...
 
int levDim
 
std::set< std::string > ignoredVarNames
 Ignored variables. More...
 
std::set< std::string > dummyVarNames
 Dummy variables. More...
 

Detailed Description

Definition at line 18 of file NCHelperESMF.hpp.

Constructor & Destructor Documentation

◆ NCHelperESMF()

moab::NCHelperESMF::NCHelperESMF ( ReadNC readNC,
int  fileId,
const FileOptions opts,
EntityHandle  fileSet 
)

Definition at line 24 of file NCHelperESMF.cpp.

25  : UcdNCHelper( readNC, fileId, opts, fileSet ), maxEdgesPerCell( DEFAULT_MAX_EDGES_PER_CELL ), coordDim( 0 ),
26  centerCoordsId( -1 ), degrees( true )
27 {
28 }

Member Function Documentation

◆ can_read_file()

bool moab::NCHelperESMF::can_read_file ( ReadNC readNC)
static

Definition at line 30 of file NCHelperESMF.cpp.

31 {
32  std::vector< std::string >& dimNames = readNC->dimNames;
33  if( ( std::find( dimNames.begin(), dimNames.end(), std::string( "nodeCount" ) ) != dimNames.end() ) &&
34  ( std::find( dimNames.begin(), dimNames.end(), std::string( "elementCount" ) ) != dimNames.end() ) &&
35  ( std::find( dimNames.begin(), dimNames.end(), std::string( "maxNodePElement" ) ) != dimNames.end() ) &&
36  ( std::find( dimNames.begin(), dimNames.end(), std::string( "coordDim" ) ) != dimNames.end() ) )
37  {
38  return true;
39  }
40 
41  return false;
42 }

References moab::ReadNC::dimNames.

Referenced by moab::NCHelper::get_nc_format().

◆ check_existing_mesh()

virtual ErrorCode moab::NCHelperESMF::check_existing_mesh ( )
inlineprivatevirtual

Implements moab::NCHelper.

Definition at line 56 of file NCHelperESMF.hpp.

57  {
58  return MB_SUCCESS;
59  }

References MB_SUCCESS.

◆ create_local_cells()

ErrorCode moab::NCHelperESMF::create_local_cells ( const std::vector< int > &  vertices_on_local_cells,
const std::vector< int > &  num_edges_on_local_cells,
EntityHandle  start_vertex,
Range faces 
)
private

Create local cells without padding (cells are divided into groups based on the number of edges)

Definition at line 627 of file NCHelperESMF.cpp.

631 {
632  Interface*& mbImpl = _readNC->mbImpl;
633  Tag& mGlobalIdTag = _readNC->mGlobalIdTag;
634 
635  // Divide local cells into groups based on the number of edges
636  Range local_cells_with_n_edges[DEFAULT_MAX_EDGES_PER_CELL + 1];
637  // Insert larger values before smaller ones to increase efficiency
638  for( int i = nLocalCells - 1; i >= 0; i-- )
639  {
640  int num_edges = num_edges_on_local_cells[i];
641  local_cells_with_n_edges[num_edges].insert( localGidCells[i] ); // Global cell index
642  }
643 
644  std::vector< int > num_edges_on_cell_groups;
645  for( int i = 3; i <= maxEdgesPerCell; i++ )
646  {
647  if( local_cells_with_n_edges[i].size() > 0 ) num_edges_on_cell_groups.push_back( i );
648  }
649  int numCellGroups = (int)num_edges_on_cell_groups.size();
650  EntityHandle* conn_arr_local_cells_with_n_edges[DEFAULT_MAX_EDGES_PER_CELL + 1];
651  for( int i = 0; i < numCellGroups; i++ )
652  {
653  int num_edges_per_cell = num_edges_on_cell_groups[i];
654  int num_group_cells = (int)local_cells_with_n_edges[num_edges_per_cell].size();
655 
656  EntityType typeEl = MBTRI;
657  if( num_edges_per_cell == 4 ) typeEl = MBQUAD;
658  if( num_edges_per_cell > 4 ) typeEl = MBPOLYGON;
659  // Create local cells for each non-empty cell group
660  EntityHandle start_element;
662  num_group_cells, num_edges_per_cell, typeEl, 0, start_element,
663  conn_arr_local_cells_with_n_edges[num_edges_per_cell], num_group_cells ),
664  "Failed to create local cells" );
665  faces.insert( start_element, start_element + num_group_cells - 1 );
666 
667  // Add local cells to current file set
668  Range local_cells_range( start_element, start_element + num_group_cells - 1 );
669  MB_CHK_SET_ERR( _readNC->mbImpl->add_entities( _fileSet, local_cells_range ),
670  "Failed to add local cells to current file set" );
671 
672  // Get ptr to gid memory for local cells
673  int count = 0;
674  void* data = NULL;
675  MB_CHK_SET_ERR( mbImpl->tag_iterate( mGlobalIdTag, local_cells_range.begin(), local_cells_range.end(), count,
676  data ),
677  "Failed to iterate global id tag on local cells" );
678  assert( count == num_group_cells );
679  int* gid_data = (int*)data;
680  std::copy( local_cells_with_n_edges[num_edges_per_cell].begin(),
681  local_cells_with_n_edges[num_edges_per_cell].end(), gid_data );
682 
683  // Set connectivity array with proper local vertices handles
684  for( int j = 0; j < num_group_cells; j++ )
685  {
686  EntityHandle global_cell_idx =
687  local_cells_with_n_edges[num_edges_per_cell][j]; // Global cell index, 1 based
688  int local_cell_idx = localGidCells.index( global_cell_idx ); // Local cell index, 0 based
689  assert( local_cell_idx != -1 );
690 
691  for( int k = 0; k < num_edges_per_cell; k++ )
692  {
693  EntityHandle global_vert_idx =
694  vertices_on_local_cells[local_cell_idx * maxEdgesPerCell + k]; // Global vertex index, 1 based
695  int local_vert_idx = localGidVerts.index( global_vert_idx ); // Local vertex index, 0 based
696  assert( local_vert_idx != -1 );
697  conn_arr_local_cells_with_n_edges[num_edges_per_cell][j * num_edges_per_cell + k] =
698  start_vertex + local_vert_idx;
699  }
700  }
701  }
702 
703  return MB_SUCCESS;
704 }

References moab::NCHelper::_fileSet, moab::NCHelper::_readNC, moab::Interface::add_entities(), moab::Range::begin(), moab::DEFAULT_MAX_EDGES_PER_CELL, moab::Range::end(), moab::ReadUtilIface::get_element_connect(), moab::Range::index(), moab::Range::insert(), moab::UcdNCHelper::localGidCells, moab::UcdNCHelper::localGidVerts, maxEdgesPerCell, MB_CHK_SET_ERR, MB_SUCCESS, moab::ReadNC::mbImpl, MBPOLYGON, MBQUAD, MBTRI, moab::ReadNC::mGlobalIdTag, moab::UcdNCHelper::nLocalCells, moab::ReadNC::readMeshIface, and moab::Interface::tag_iterate().

Referenced by create_mesh().

◆ create_local_vertices()

ErrorCode moab::NCHelperESMF::create_local_vertices ( const std::vector< int > &  vertices_on_local_cells,
EntityHandle start_vertex 
)
private

Create local vertices.

Definition at line 504 of file NCHelperESMF.cpp.

506 {
507  Interface*& mbImpl = _readNC->mbImpl;
508  Tag& mGlobalIdTag = _readNC->mGlobalIdTag;
509  const Tag*& mpFileIdTag = _readNC->mpFileIdTag;
510  DebugOutput& dbgOut = _readNC->dbgOut;
511 
512  // Make a copy of vertices_on_local_cells for sorting (keep original one to set cell
513  // connectivity later)
514  std::vector< int > vertices_on_local_cells_sorted( vertices_on_local_cells );
515  std::sort( vertices_on_local_cells_sorted.begin(), vertices_on_local_cells_sorted.end() );
516  std::copy( vertices_on_local_cells_sorted.rbegin(), vertices_on_local_cells_sorted.rend(),
517  range_inserter( localGidVerts ) );
519 
520  dbgOut.tprintf( 1, " localGidVerts.psize() = %d\n", (int)localGidVerts.psize() );
521  dbgOut.tprintf( 1, " localGidVerts.size() = %d\n", (int)localGidVerts.size() );
522 
523  // Create local vertices
524  std::vector< double* > arrays;
525  MB_CHK_SET_ERR( _readNC->readMeshIface->get_node_coords( 3, nLocalVertices, 0, start_vertex, arrays,
526  nLocalVertices ),
527  "Failed to create local vertices" );
528 
529  // Add local vertices to current file set
530  Range local_verts_range( start_vertex, start_vertex + nLocalVertices - 1 );
531  MB_CHK_SET_ERR( _readNC->mbImpl->add_entities( _fileSet, local_verts_range ),
532  "Failed to add local vertices to current file set" );
533 
534  // Get ptr to GID memory for local vertices
535  int count = 0;
536  void* data = NULL;
537  MB_CHK_SET_ERR( mbImpl->tag_iterate( mGlobalIdTag, local_verts_range.begin(), local_verts_range.end(), count,
538  data ),
539  "Failed to iterate global id tag on local vertices" );
540  assert( count == nLocalVertices );
541  int* gid_data = (int*)data;
542  std::copy( localGidVerts.begin(), localGidVerts.end(), gid_data );
543 
544  // Duplicate GID data, which will be used to resolve sharing
545  if( mpFileIdTag )
546  {
547  MB_CHK_SET_ERR( mbImpl->tag_iterate( *mpFileIdTag, local_verts_range.begin(), local_verts_range.end(), count,
548  data ),
549  "Failed to iterate file id tag on local vertices" );
550  assert( count == nLocalVertices );
551  int bytes_per_tag = 4;
552  MB_CHK_SET_ERR( mbImpl->tag_get_bytes( *mpFileIdTag, bytes_per_tag ),
553  "Can't get number of bytes for file id tag" );
554  if( 4 == bytes_per_tag )
555  {
556  gid_data = (int*)data;
557  std::copy( localGidVerts.begin(), localGidVerts.end(), gid_data );
558  }
559  else if( 8 == bytes_per_tag )
560  { // Should be a handle tag on 64 bit machine?
561  long* handle_tag_data = (long*)data;
562  std::copy( localGidVerts.begin(), localGidVerts.end(), handle_tag_data );
563  }
564  }
565 
566 #ifdef MOAB_HAVE_PNETCDF
567  size_t nb_reads = localGidVerts.psize();
568  std::vector< int > requests( nb_reads );
569  std::vector< int > statuss( nb_reads );
570  size_t idxReq = 0;
571 #endif
572 
573  // Read nodeCoords for local vertices
574  double* coords = new double[localGidVerts.size() * coordDim];
575  int nodeCoordVarId;
576  int success = NCFUNC( inq_varid )( _fileId, "nodeCoords", &nodeCoordVarId );
577  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of nodeCoords" );
578  size_t indexInArray = 0;
579  for( Range::pair_iterator pair_iter = localGidVerts.pair_begin(); pair_iter != localGidVerts.pair_end();
580  ++pair_iter )
581  {
582  EntityHandle starth = pair_iter->first;
583  EntityHandle endh = pair_iter->second;
584  NCDF_SIZE read_starts[2] = { static_cast< NCDF_SIZE >( starth - 1 ), 0 };
585  NCDF_SIZE read_counts[2] = { static_cast< NCDF_SIZE >( endh - starth + 1 ),
586  static_cast< NCDF_SIZE >( coordDim ) };
587 
588  // Do a partial read in each subrange
589 #ifdef MOAB_HAVE_PNETCDF
590  success = NCFUNCREQG( _vara_double )( _fileId, nodeCoordVarId, read_starts, read_counts, &coords[indexInArray],
591  &requests[idxReq++] );
592 #else
593  success = NCFUNCAG( _vara_double )( _fileId, nodeCoordVarId, read_starts, read_counts, &coords[indexInArray] );
594 #endif
595  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read nodeCoords data in a loop" );
596 
597  // Increment the index for next subrange
598  indexInArray += ( endh - starth + 1 ) * coordDim;
599  }
600 
601 #ifdef MOAB_HAVE_PNETCDF
602  // Wait outside the loop
603  success = NCFUNC( wait_all )( _fileId, requests.size(), &requests[0], &statuss[0] );
604  if( success ) MB_SET_ERR( MB_FAILURE, "Failed on wait_all" );
605 #endif
606 
607  // now convert from lat/lon to 3d
608  if( 2 == coordDim )
609  {
610  // basically convert from degrees to xyz on a sphere
611  double factor = 1;
612  if( degrees ) factor = pideg;
613  for( int i = 0; i < (int)localGidVerts.size(); i++ )
614  {
615  double lon = coords[i * 2] * factor;
616  double lat = coords[i * 2 + 1] * factor;
617  double cosphi = cos( lat );
618  arrays[2][i] = sin( lat );
619  arrays[0][i] = cosphi * cos( lon );
620  arrays[1][i] = cosphi * sin( lon );
621  }
622  }
623  delete[] coords;
624  return MB_SUCCESS;
625 }

References moab::NCHelper::_fileId, moab::NCHelper::_fileSet, moab::NCHelper::_readNC, moab::Interface::add_entities(), moab::Range::begin(), coordDim, moab::ReadNC::dbgOut, degrees, moab::Range::end(), moab::ReadUtilIface::get_node_coords(), moab::UcdNCHelper::localGidVerts, MB_CHK_SET_ERR, MB_SET_ERR, MB_SUCCESS, moab::ReadNC::mbImpl, moab::ReadNC::mGlobalIdTag, moab::ReadNC::mpFileIdTag, NCDF_SIZE, NCFUNC, NCFUNCAG, moab::UcdNCHelper::nLocalVertices, moab::Range::pair_begin(), moab::Range::pair_end(), moab::pideg, moab::Range::psize(), moab::ReadNC::readMeshIface, moab::Range::size(), moab::Interface::tag_get_bytes(), moab::Interface::tag_iterate(), and moab::DebugOutput::tprintf().

Referenced by create_mesh().

◆ create_mesh()

ErrorCode moab::NCHelperESMF::create_mesh ( Range faces)
privatevirtual

Implementation of NCHelper::create_mesh()

Implements moab::NCHelper.

Definition at line 136 of file NCHelperESMF.cpp.

137 {
138  bool& noMixedElements = _readNC->noMixedElements;
139  DebugOutput& dbgOut = _readNC->dbgOut;
140 
141 #ifdef MOAB_HAVE_MPI
142  int rank = 0;
143  int procs = 1;
144  bool& isParallel = _readNC->isParallel;
145  ParallelComm* myPcomm = NULL;
146  if( isParallel )
147  {
148  myPcomm = _readNC->myPcomm;
149  rank = myPcomm->proc_config().proc_rank();
150  procs = myPcomm->proc_config().proc_size();
151  }
152 
153  if( procs >= 2 )
154  {
155  // Shift rank to obtain a rotated trivial partition
156  int shifted_rank = rank;
157  int& trivialPartitionShift = _readNC->trivialPartitionShift;
158  if( trivialPartitionShift > 0 ) shifted_rank = ( rank + trivialPartitionShift ) % procs;
159 
160  // Compute the number of local cells on this proc
161  nLocalCells = int( std::floor( 1.0 * nCells / procs ) );
162 
163  // The starting global cell index in the ESMF file for this proc
164  int start_cell_idx = shifted_rank * nLocalCells;
165 
166  // Number of extra cells after equal split over procs
167  int iextra = nCells % procs;
168 
169  // Allocate extra cells over procs
170  if( shifted_rank < iextra ) nLocalCells++;
171  start_cell_idx += std::min( shifted_rank, iextra );
172 
173  start_cell_idx++; // 0 based -> 1 based
174 
175  // Redistribute local cells after trivial partition (e.g. apply Zoltan partition)
176  MB_CHK_SET_ERR( redistribute_local_cells( start_cell_idx, myPcomm ),
177  "Failed to redistribute local cells after trivial partition" );
178  }
179  else
180  {
183  }
184 #else
187 #endif
188  dbgOut.tprintf( 1, " localGidCells.psize() = %d\n", (int)localGidCells.psize() );
189  dbgOut.tprintf( 1, " localGidCells.size() = %d\n", (int)localGidCells.size() );
190 
191  // Read number of edges on each local cell, to calculate actual maxEdgesPerCell
192  int nEdgesOnCellVarId;
193  int success = NCFUNC( inq_varid )( _fileId, "numElementConn", &nEdgesOnCellVarId );
194  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of numElementConn" );
195  std::vector< int > num_edges_on_local_cells( nLocalCells );
196 
197 #ifdef MOAB_HAVE_PNETCDF
198  size_t nb_reads = localGidCells.psize();
199  std::vector< int > requests( nb_reads );
200  std::vector< int > statuss( nb_reads );
201  size_t idxReq = 0;
202 #endif
203  size_t indexInArray = 0;
204  for( Range::pair_iterator pair_iter = localGidCells.pair_begin(); pair_iter != localGidCells.pair_end();
205  ++pair_iter )
206  {
207  EntityHandle starth = pair_iter->first;
208  EntityHandle endh = pair_iter->second;
209  NCDF_SIZE read_start = (NCDF_SIZE)( starth - 1 );
210  NCDF_SIZE read_count = (NCDF_SIZE)( endh - starth + 1 );
211 
212  // Do a partial read in each subrange
213 #ifdef MOAB_HAVE_PNETCDF
214  success = NCFUNCREQG( _vara_int )( _fileId, nEdgesOnCellVarId, &read_start, &read_count,
215  &( num_edges_on_local_cells[indexInArray] ), &requests[idxReq++] );
216 #else
217  success = NCFUNCAG( _vara_int )( _fileId, nEdgesOnCellVarId, &read_start, &read_count,
218  &( num_edges_on_local_cells[indexInArray] ) );
219 #endif
220  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read nEdgesOnCell data in a loop" );
221 
222  // Increment the index for next subrange
223  indexInArray += ( endh - starth + 1 );
224  }
225 
226 #ifdef MOAB_HAVE_PNETCDF
227  // Wait outside the loop
228  success = NCFUNC( wait_all )( _fileId, requests.size(), &requests[0], &statuss[0] );
229  if( success ) MB_SET_ERR( MB_FAILURE, "Failed on wait_all" );
230 #endif
231 
232  // Read vertices on each local cell, to get localGidVerts and cell connectivity later
233  int verticesOnCellVarId;
234  success = NCFUNC( inq_varid )( _fileId, "elementConn", &verticesOnCellVarId );
235  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of elementConn" );
236  std::vector< int > vertices_on_local_cells( nLocalCells * maxEdgesPerCell );
237 #ifdef MOAB_HAVE_PNETCDF
238  idxReq = 0;
239 #endif
240  indexInArray = 0;
241  for( Range::pair_iterator pair_iter = localGidCells.pair_begin(); pair_iter != localGidCells.pair_end();
242  ++pair_iter )
243  {
244  EntityHandle starth = pair_iter->first;
245  EntityHandle endh = pair_iter->second;
246  NCDF_SIZE read_starts[2] = { static_cast< NCDF_SIZE >( starth - 1 ), 0 };
247  NCDF_SIZE read_counts[2] = { static_cast< NCDF_SIZE >( endh - starth + 1 ),
248  static_cast< NCDF_SIZE >( maxEdgesPerCell ) };
249 
250  // Do a partial read in each subrange
251 #ifdef MOAB_HAVE_PNETCDF
252  success = NCFUNCREQG( _vara_int )( _fileId, verticesOnCellVarId, read_starts, read_counts,
253  &( vertices_on_local_cells[indexInArray] ), &requests[idxReq++] );
254 #else
255  success = NCFUNCAG( _vara_int )( _fileId, verticesOnCellVarId, read_starts, read_counts,
256  &( vertices_on_local_cells[indexInArray] ) );
257 #endif
258  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read verticesOnCell data in a loop" );
259 
260  // Increment the index for next subrange
261  indexInArray += ( endh - starth + 1 ) * maxEdgesPerCell;
262  }
263 
264 #ifdef MOAB_HAVE_PNETCDF
265  // Wait outside the loop
266  success = NCFUNC( wait_all )( _fileId, requests.size(), &requests[0], &statuss[0] );
267  if( success ) MB_SET_ERR( MB_FAILURE, "Failed on wait_all" );
268 #endif
269 
270  // Correct local cell vertices array, replace the padded vertices with the last vertices
271  // in the corresponding cells; sometimes the padded vertices are 0, sometimes a large
272  // vertex id. Make sure they are consistent to our padded option
273  for( int local_cell_idx = 0; local_cell_idx < nLocalCells; local_cell_idx++ )
274  {
275  int num_edges = num_edges_on_local_cells[local_cell_idx];
276  int idx_in_local_vert_arr = local_cell_idx * maxEdgesPerCell;
277  int last_vert_idx = vertices_on_local_cells[idx_in_local_vert_arr + num_edges - 1];
278  for( int i = num_edges; i < maxEdgesPerCell; i++ )
279  vertices_on_local_cells[idx_in_local_vert_arr + i] = last_vert_idx;
280  }
281 
282  // Create local vertices
283  EntityHandle start_vertex;
284  MB_CHK_SET_ERR( create_local_vertices( vertices_on_local_cells, start_vertex ),
285  "Failed to create local vertices for MPAS mesh" );
286 
287  // Create local cells, either unpadded or padded
288  if( noMixedElements )
289  {
290  MB_CHK_SET_ERR( create_padded_local_cells( vertices_on_local_cells, start_vertex, faces ),
291  "Failed to create padded local cells for MPAS mesh" );
292  }
293  else
294  {
295  MB_CHK_SET_ERR( create_local_cells( vertices_on_local_cells, num_edges_on_local_cells, start_vertex, faces ),
296  "Failed to create local cells for MPAS mesh" );
297  }
298 
299  return MB_SUCCESS;
300 }

References moab::NCHelper::_fileId, moab::NCHelper::_readNC, create_local_cells(), create_local_vertices(), create_padded_local_cells(), moab::ReadNC::dbgOut, moab::Range::insert(), moab::ReadNC::isParallel, moab::UcdNCHelper::localGidCells, maxEdgesPerCell, MB_CHK_SET_ERR, MB_SET_ERR, MB_SUCCESS, NCDF_SIZE, moab::UcdNCHelper::nCells, NCFUNC, NCFUNCAG, moab::UcdNCHelper::nLocalCells, moab::ReadNC::noMixedElements, moab::Range::pair_begin(), moab::Range::pair_end(), moab::ParallelComm::proc_config(), moab::ProcConfig::proc_rank(), moab::ProcConfig::proc_size(), moab::Range::psize(), moab::Range::size(), moab::DebugOutput::tprintf(), and moab::ReadNC::trivialPartitionShift.

◆ create_padded_local_cells()

ErrorCode moab::NCHelperESMF::create_padded_local_cells ( const std::vector< int > &  vertices_on_local_cells,
EntityHandle  start_vertex,
Range faces 
)
private

Create local cells with padding (padded cells will have the same number of edges)

Definition at line 706 of file NCHelperESMF.cpp.

709 {
710  Interface*& mbImpl = _readNC->mbImpl;
711  Tag& mGlobalIdTag = _readNC->mGlobalIdTag;
712 
713  // Create cells for this cell group
714  EntityHandle start_element;
715  EntityHandle* conn_arr_local_cells = NULL;
717  start_element, conn_arr_local_cells, nLocalCells ),
718  "Failed to create local cells" );
719  faces.insert( start_element, start_element + nLocalCells - 1 );
720 
721  // Add local cells to current file set
722  Range local_cells_range( start_element, start_element + nLocalCells - 1 );
723  MB_CHK_SET_ERR( _readNC->mbImpl->add_entities( _fileSet, local_cells_range ),
724  "Failed to add local cells to current file set" );
725 
726  // Get ptr to GID memory for local cells
727  int count = 0;
728  void* data = NULL;
729  MB_CHK_SET_ERR( mbImpl->tag_iterate( mGlobalIdTag, local_cells_range.begin(), local_cells_range.end(), count,
730  data ),
731  "Failed to iterate global id tag on local cells" );
732  assert( count == nLocalCells );
733  int* gid_data = (int*)data;
734  std::copy( localGidCells.begin(), localGidCells.end(), gid_data );
735 
736  // Set connectivity array with proper local vertices handles
737  // vertices_on_local_cells array was already corrected to have the last vertices padded
738  // no need for extra checks considering
739  for( int local_cell_idx = 0; local_cell_idx < nLocalCells; local_cell_idx++ )
740  {
741  for( int i = 0; i < maxEdgesPerCell; i++ )
742  {
743  EntityHandle global_vert_idx =
744  vertices_on_local_cells[local_cell_idx * maxEdgesPerCell + i]; // Global vertex index, 1 based
745  int local_vert_idx = localGidVerts.index( global_vert_idx ); // Local vertex index, 0 based
746  assert( local_vert_idx != -1 );
747  conn_arr_local_cells[local_cell_idx * maxEdgesPerCell + i] = start_vertex + local_vert_idx;
748  }
749  }
750 
751  return MB_SUCCESS;
752 }

References moab::NCHelper::_fileSet, moab::NCHelper::_readNC, moab::Interface::add_entities(), moab::Range::begin(), moab::Range::end(), moab::ReadUtilIface::get_element_connect(), moab::Range::index(), moab::Range::insert(), moab::UcdNCHelper::localGidCells, moab::UcdNCHelper::localGidVerts, maxEdgesPerCell, MB_CHK_SET_ERR, MB_SUCCESS, moab::ReadNC::mbImpl, MBPOLYGON, moab::ReadNC::mGlobalIdTag, moab::UcdNCHelper::nLocalCells, moab::ReadNC::readMeshIface, and moab::Interface::tag_iterate().

Referenced by create_mesh().

◆ get_mesh_type_name()

virtual std::string moab::NCHelperESMF::get_mesh_type_name ( )
inlineprivatevirtual

Implementation of NCHelper::get_mesh_type_name()

Implements moab::NCHelper.

Definition at line 31 of file NCHelperESMF.hpp.

32  {
33  return "ESMF";
34  }

◆ init_mesh_vals()

ErrorCode moab::NCHelperESMF::init_mesh_vals ( )
privatevirtual

Implementation of NCHelper::init_mesh_vals()

Implements moab::NCHelper.

Definition at line 44 of file NCHelperESMF.cpp.

45 {
46  std::vector< std::string >& dimNames = _readNC->dimNames;
47  std::vector< int >& dimLens = _readNC->dimLens;
48  std::map< std::string, ReadNC::VarData >& varInfo = _readNC->varInfo;
49 
50  unsigned int idx;
51  std::vector< std::string >::iterator vit;
52 
53  // Get max edges per cell reported in the ESMF file header
54  if( ( vit = std::find( dimNames.begin(), dimNames.end(), "maxNodePElement" ) ) != dimNames.end() )
55  {
56  idx = vit - dimNames.begin();
57  maxEdgesPerCell = dimLens[idx];
59  {
61  "maxEdgesPerCell read from the ESMF file header has exceeded " << DEFAULT_MAX_EDGES_PER_CELL );
62  }
63  }
64 
65  // Get number of cells
66  if( ( vit = std::find( dimNames.begin(), dimNames.end(), "elementCount" ) ) != dimNames.end() )
67  idx = vit - dimNames.begin();
68  else
69  {
70  MB_SET_ERR( MB_FAILURE, "Couldn't find 'elementCount' dimension" );
71  }
72  cDim = idx;
73  nCells = dimLens[idx];
74 
75  // Get number of vertices per cell (max)
76  if( ( vit = std::find( dimNames.begin(), dimNames.end(), "maxNodePElement" ) ) != dimNames.end() )
77  idx = vit - dimNames.begin();
78  else
79  {
80  MB_SET_ERR( MB_FAILURE, "Couldn't find 'maxNodePElement' dimension" );
81  }
82 
83  maxEdgesPerCell = dimLens[idx];
84 
85  // Get number of vertices
86  vDim = -1;
87  if( ( vit = std::find( dimNames.begin(), dimNames.end(), "nodeCount" ) ) != dimNames.end() )
88  idx = vit - dimNames.begin();
89  else
90  {
91  MB_SET_ERR( MB_FAILURE, "Couldn't find 'nodeCount' dimension" );
92  }
93  vDim = idx;
94  nVertices = dimLens[idx];
95 
96  // Get number of coord dimensions
97  if( ( vit = std::find( dimNames.begin(), dimNames.end(), "coordDim" ) ) != dimNames.end() )
98  idx = vit - dimNames.begin();
99  else
100  {
101  MB_SET_ERR( MB_FAILURE, "Couldn't find 'coordDim' dimension" );
102  }
103 
104  coordDim = dimLens[idx];
105 
106  int success = NCFUNC( inq_varid )( _fileId, "centerCoords", &centerCoordsId );
107  if( success ) centerCoordsId = -1; // no center coords variable
108 
109  // decide now the units, by looking at nodeCoords; they should always exist
110  int nodeCoordsId;
111  success = NCFUNC( inq_varid )( _fileId, "nodeCoords", &nodeCoordsId );
112  if( success ) MB_CHK_SET_ERR( MB_FAILURE, "Trouble getting nodeCoords" );
113 
114  auto vmit = varInfo.find( "nodeCoords" );
115  if( varInfo.end() == vmit ) MB_SET_ERR( MB_FAILURE, "Couldn't find variable " << "nodeCoords" );
116  ReadNC::VarData& glData = vmit->second;
117  auto attIt = glData.varAtts.find( "units" );
118  if( attIt != glData.varAtts.end() )
119  {
120  unsigned int sz = attIt->second.attLen;
121  std::string att_data;
122  att_data.resize( sz + 1 );
123  att_data[sz] = '\000';
124  success =
125  NCFUNC( get_att_text )( _fileId, attIt->second.attVarId, attIt->second.attName.c_str(), &att_data[0] );
126  if( 0 == success && att_data.find( "radians" ) != std::string::npos ) degrees = false;
127  }
128 
129  // Hack: create dummy variables for dimensions (like nCells) with no corresponding coordinate
130  // variables
131  MB_CHK_SET_ERR( create_dummy_variables(), "Failed to create dummy variables" );
132 
133  return MB_SUCCESS;
134 }

References moab::NCHelper::_fileId, moab::NCHelper::_readNC, moab::UcdNCHelper::cDim, centerCoordsId, coordDim, moab::NCHelper::create_dummy_variables(), moab::DEFAULT_MAX_EDGES_PER_CELL, degrees, moab::ReadNC::dimLens, moab::ReadNC::dimNames, maxEdgesPerCell, MB_CHK_SET_ERR, MB_INVALID_SIZE, MB_SET_ERR, MB_SUCCESS, moab::UcdNCHelper::nCells, NCFUNC, moab::UcdNCHelper::nVertices, moab::ReadNC::VarData::varAtts, moab::ReadNC::varInfo, and moab::UcdNCHelper::vDim.

◆ read_ucd_variables_to_nonset()

virtual ErrorCode moab::NCHelperESMF::read_ucd_variables_to_nonset ( std::vector< ReadNC::VarData > &  ,
std::vector< int > &   
)
inlineprivatevirtual

Implementation of UcdNCHelper::read_ucd_variables_to_nonset()

Implements moab::UcdNCHelper.

Definition at line 77 of file NCHelperESMF.hpp.

79  {
80  return MB_SUCCESS;
81  }

References MB_SUCCESS.

◆ read_ucd_variables_to_nonset_allocate()

virtual ErrorCode moab::NCHelperESMF::read_ucd_variables_to_nonset_allocate ( std::vector< ReadNC::VarData > &  ,
std::vector< int > &   
)
inlineprivatevirtual

Implementation of UcdNCHelper::read_ucd_variables_to_nonset_allocate()

Implements moab::UcdNCHelper.

Definition at line 62 of file NCHelperESMF.hpp.

64  {
65  return MB_SUCCESS;
66  }

References MB_SUCCESS.

Member Data Documentation

◆ centerCoordsId

int moab::NCHelperESMF::centerCoordsId
private

Definition at line 87 of file NCHelperESMF.hpp.

Referenced by init_mesh_vals().

◆ coordDim

int moab::NCHelperESMF::coordDim
private

Definition at line 86 of file NCHelperESMF.hpp.

Referenced by create_local_vertices(), and init_mesh_vals().

◆ degrees

bool moab::NCHelperESMF::degrees
private

Definition at line 88 of file NCHelperESMF.hpp.

Referenced by create_local_vertices(), and init_mesh_vals().

◆ facesOwned

Range moab::NCHelperESMF::facesOwned
private

Definition at line 89 of file NCHelperESMF.hpp.

◆ maxEdgesPerCell

int moab::NCHelperESMF::maxEdgesPerCell
private

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