Mesh Oriented datABase  (version 5.5.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 59 of file NCHelperESMF.hpp.

59 {return MB_SUCCESS;}

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 617 of file NCHelperESMF.cpp.

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

References moab::NCHelper::_fileSet, moab::NCHelper::_readNC, moab::Interface::add_entities(), moab::Range::begin(), moab::DEFAULT_MAX_EDGES_PER_CELL, moab::Range::end(), ErrorCode, 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, size, 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 501 of file NCHelperESMF.cpp.

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

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(), ErrorCode, 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 139 of file NCHelperESMF.cpp.

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

References moab::NCHelper::_fileId, moab::NCHelper::_readNC, create_local_cells(), create_local_vertices(), create_padded_local_cells(), moab::ReadNC::dbgOut, ErrorCode, 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 693 of file NCHelperESMF.cpp.

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

References moab::NCHelper::_fileSet, moab::NCHelper::_readNC, moab::Interface::add_entities(), moab::Range::begin(), moab::Range::end(), ErrorCode, 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 33 of file NCHelperESMF.hpp.

34  {
35  return "ESMF";
36  }

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

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, ErrorCode, 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: