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

Child helper class for MPAS grid. More...

#include <NCHelperMPAS.hpp>

+ Inheritance diagram for moab::NCHelperMPAS:
+ Collaboration diagram for moab::NCHelperMPAS:

Public Member Functions

 NCHelperMPAS (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 check_existing_mesh ()
 Implementation of NCHelper::check_existing_mesh() 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...
 
virtual ErrorCode read_ucd_variables_to_nonset_allocate (std::vector< ReadNC::VarData > &vdatas, std::vector< int > &tstep_nums)
 Implementation of UcdNCHelper::read_ucd_variables_to_nonset_allocate() More...
 
virtual ErrorCode read_ucd_variables_to_nonset (std::vector< ReadNC::VarData > &vdatas, std::vector< int > &tstep_nums)
 Implementation of UcdNCHelper::read_ucd_variables_to_nonset() More...
 
ErrorCode create_local_vertices (const std::vector< int > &vertices_on_local_cells, EntityHandle &start_vertex)
 Create local vertices. More...
 
ErrorCode create_local_edges (EntityHandle start_vertex, const std::vector< int > &num_edges_on_local_cells)
 Create local edges (optional) 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...
 
ErrorCode create_gather_set_vertices (EntityHandle gather_set, EntityHandle &gather_set_start_vertex)
 Create gather set vertices. More...
 
ErrorCode create_gather_set_edges (EntityHandle gather_set, EntityHandle gather_set_start_vertex)
 Create gather set edges (optional) More...
 
ErrorCode create_gather_set_cells (EntityHandle gather_set, EntityHandle gather_set_start_vertex)
 Create gather set cells without padding (cells are divided into groups based on the number of edges) More...
 
ErrorCode create_padded_gather_set_cells (EntityHandle gather_set, EntityHandle gather_set_start_vertex)
 Create gather set cells with padding (padded cells will have the same number of edges) More...
 

Private Attributes

int maxEdgesPerCell
 
int numCellGroups
 
bool createGatherSet
 
std::map< EntityHandle, int > cellHandleToGlobalID
 
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

Child helper class for MPAS grid.

Definition at line 20 of file NCHelperMPAS.hpp.

Constructor & Destructor Documentation

◆ NCHelperMPAS()

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

Definition at line 18 of file NCHelperMPAS.cpp.

19  : UcdNCHelper( readNC, fileId, opts, fileSet ), maxEdgesPerCell( DEFAULT_MAX_EDGES_PER_CELL ), numCellGroups( 0 ),
20  createGatherSet( false )
21 {
22  // Ignore variables containing topological information
23  ignoredVarNames.insert( "nEdgesOnEdge" );
24  ignoredVarNames.insert( "nEdgesOnCell" );
25  ignoredVarNames.insert( "edgesOnVertex" );
26  ignoredVarNames.insert( "cellsOnVertex" );
27  ignoredVarNames.insert( "verticesOnEdge" );
28  ignoredVarNames.insert( "edgesOnEdge" );
29  ignoredVarNames.insert( "cellsOnEdge" );
30  ignoredVarNames.insert( "verticesOnCell" );
31  ignoredVarNames.insert( "edgesOnCell" );
32  ignoredVarNames.insert( "cellsOnCell" );
33  // ignore variables containing mesh related info, that are currently saved as variable tags on
34  // file set ; if needed, these should be saved as dense tags, and read accordingly, in parallel
35  ignoredVarNames.insert( "weightsOnEdge" );
36  ignoredVarNames.insert( "angleEdge" );
37  ignoredVarNames.insert( "areaCell" );
38  ignoredVarNames.insert( "areaTriangle" );
39  ignoredVarNames.insert( "dcEdge" );
40  ignoredVarNames.insert( "dv1Edge" );
41  ignoredVarNames.insert( "dv2Edge" );
42  ignoredVarNames.insert( "fEdge" );
43  ignoredVarNames.insert( "fVertex" );
44  ignoredVarNames.insert( "h_s" );
45  ignoredVarNames.insert( "kiteAreasOnVertex" );
46  ignoredVarNames.insert( "latCell" );
47  ignoredVarNames.insert( "latEdge" );
48  ignoredVarNames.insert( "latVertex" );
49  ignoredVarNames.insert( "lonCell" );
50  ignoredVarNames.insert( "lonEdge" );
51  ignoredVarNames.insert( "lonVertex" );
52  ignoredVarNames.insert( "meshDensity" );
53  ignoredVarNames.insert( "xCell" );
54  ignoredVarNames.insert( "xEdge" );
55  ignoredVarNames.insert( "xVertex" );
56  ignoredVarNames.insert( "yCell" );
57  ignoredVarNames.insert( "yEdge" );
58  ignoredVarNames.insert( "yVertex" );
59  ignoredVarNames.insert( "zCell" );
60  ignoredVarNames.insert( "zEdge" );
61  ignoredVarNames.insert( "zVertex" );
62  // Ignore variables for index conversion
63  ignoredVarNames.insert( "indexToVertexID" );
64  ignoredVarNames.insert( "indexToEdgeID" );
65  ignoredVarNames.insert( "indexToCellID" );
66 }

References moab::NCHelper::ignoredVarNames.

Member Function Documentation

◆ can_read_file()

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

Definition at line 68 of file NCHelperMPAS.cpp.

69 {
70  std::vector< std::string >& dimNames = readNC->dimNames;
71 
72  // If dimension name "vertexDegree" exists then it should be the MPAS grid
73  if( std::find( dimNames.begin(), dimNames.end(), std::string( "vertexDegree" ) ) != dimNames.end() ) return true;
74 
75  return false;
76 }

References moab::ReadNC::dimNames.

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

◆ check_existing_mesh()

ErrorCode moab::NCHelperMPAS::check_existing_mesh ( )
privatevirtual

Implementation of NCHelper::check_existing_mesh()

Implements moab::NCHelper.

Definition at line 252 of file NCHelperMPAS.cpp.

253 {
254  Interface*& mbImpl = _readNC->mbImpl;
255  Tag& mGlobalIdTag = _readNC->mGlobalIdTag;
256  bool& noMesh = _readNC->noMesh;
257 
258  if( noMesh )
259  {
260  // Restore numCellGroups
261  if( 0 == numCellGroups )
262  {
263  Tag numCellGroupsTag;
264  MB_CHK_SET_ERR( mbImpl->tag_get_handle( "__NUM_CELL_GROUPS", 1, MB_TYPE_INTEGER, numCellGroupsTag ),
265  "Trouble getting __NUM_CELL_GROUPS tag" );
266  MB_CHK_SET_ERR( mbImpl->tag_get_data( numCellGroupsTag, &_fileSet, 1, &numCellGroups ),
267  "Trouble getting data of __NUM_CELL_GROUPS tag" );
268  }
269 
270  if( localGidVerts.empty() )
271  {
272  // Get all vertices from current file set (it is the input set in no_mesh scenario)
273  Range local_verts;
274  MB_CHK_SET_ERR( mbImpl->get_entities_by_dimension( _fileSet, 0, local_verts ),
275  "Trouble getting local vertices in current file set" );
276 
277  if( !local_verts.empty() )
278  {
279  std::vector< int > gids( local_verts.size() );
280 
281  // !IMPORTANT : this has to be the GLOBAL_ID tag
282  MB_CHK_SET_ERR( mbImpl->tag_get_data( mGlobalIdTag, local_verts, &gids[0] ),
283  "Trouble getting local gid values of vertices" );
284 
285  // Restore localGidVerts
286  std::copy( gids.rbegin(), gids.rend(), range_inserter( localGidVerts ) );
288  }
289  }
290 
291  if( localGidEdges.empty() )
292  {
293  // Get all edges from current file set (it is the input set in no_mesh scenario)
294  Range local_edges;
295  MB_CHK_SET_ERR( mbImpl->get_entities_by_dimension( _fileSet, 1, local_edges ),
296  "Trouble getting local edges in current file set" );
297 
298  if( !local_edges.empty() )
299  {
300  std::vector< int > gids( local_edges.size() );
301 
302  // !IMPORTANT : this has to be the GLOBAL_ID tag
303  MB_CHK_SET_ERR( mbImpl->tag_get_data( mGlobalIdTag, local_edges, &gids[0] ),
304  "Trouble getting local gid values of edges" );
305 
306  // Restore localGidEdges
307  std::copy( gids.rbegin(), gids.rend(), range_inserter( localGidEdges ) );
309  }
310  }
311 
312  if( localGidCells.empty() )
313  {
314  // Get all cells from current file set (it is the input set in no_mesh scenario)
315  Range local_cells;
316  MB_CHK_SET_ERR( mbImpl->get_entities_by_dimension( _fileSet, 2, local_cells ),
317  "Trouble getting local cells in current file set" );
318 
319  if( !local_cells.empty() )
320  {
321  std::vector< int > gids( local_cells.size() );
322 
323  // !IMPORTANT : this has to be the GLOBAL_ID tag
324  MB_CHK_SET_ERR( mbImpl->tag_get_data( mGlobalIdTag, local_cells, &gids[0] ),
325  "Trouble getting local gid values of cells" );
326 
327  // Restore localGidCells
328  std::copy( gids.rbegin(), gids.rend(), range_inserter( localGidCells ) );
330 
331  if( numCellGroups > 1 )
332  {
333  // Restore cellHandleToGlobalID map
334  Range::const_iterator rit;
335  int i;
336  for( rit = local_cells.begin(), i = 0; rit != local_cells.end(); ++rit, i++ )
337  cellHandleToGlobalID[*rit] = gids[i];
338  }
339  }
340  }
341  }
342 
343  return MB_SUCCESS;
344 }

References moab::NCHelper::_fileSet, moab::NCHelper::_readNC, moab::Range::begin(), cellHandleToGlobalID, moab::Range::empty(), moab::Range::end(), moab::Interface::get_entities_by_dimension(), moab::UcdNCHelper::localGidCells, moab::UcdNCHelper::localGidEdges, moab::UcdNCHelper::localGidVerts, MB_CHK_SET_ERR, MB_SUCCESS, MB_TYPE_INTEGER, moab::ReadNC::mbImpl, moab::ReadNC::mGlobalIdTag, moab::UcdNCHelper::nLocalCells, moab::UcdNCHelper::nLocalEdges, moab::UcdNCHelper::nLocalVertices, moab::ReadNC::noMesh, numCellGroups, moab::Range::size(), moab::Interface::tag_get_data(), and moab::Interface::tag_get_handle().

◆ create_gather_set_cells()

ErrorCode moab::NCHelperMPAS::create_gather_set_cells ( EntityHandle  gather_set,
EntityHandle  gather_set_start_vertex 
)
private

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

Definition at line 1691 of file NCHelperMPAS.cpp.

1692 {
1693  Interface*& mbImpl = _readNC->mbImpl;
1694 
1695  // Read number of edges on each gather set cell
1696  int nEdgesOnCellVarId;
1697  int success = NCFUNC( inq_varid )( _fileId, "nEdgesOnCell", &nEdgesOnCellVarId );
1698  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of nEdgesOnCell" );
1699  std::vector< int > num_edges_on_gather_set_cells( nCells );
1700  NCDF_SIZE read_start = 0;
1701  NCDF_SIZE read_count = static_cast< NCDF_SIZE >( nCells );
1702 #ifdef MOAB_HAVE_PNETCDF
1703  // Enter independent I/O mode, since this read is only for the gather processor
1704  success = NCFUNC( begin_indep_data )( _fileId );
1705  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to begin independent I/O mode" );
1706  success =
1707  NCFUNCG( _vara_int )( _fileId, nEdgesOnCellVarId, &read_start, &read_count, &num_edges_on_gather_set_cells[0] );
1708  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read nEdgesOnCell data" );
1709  success = NCFUNC( end_indep_data )( _fileId );
1710  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to end independent I/O mode" );
1711 #else
1712  success =
1713  NCFUNCG( _vara_int )( _fileId, nEdgesOnCellVarId, &read_start, &read_count, &num_edges_on_gather_set_cells[0] );
1714  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read nEdgesOnCell data" );
1715 #endif
1716 
1717  // Read vertices on each gather set cell (connectivity)
1718  int verticesOnCellVarId;
1719  success = NCFUNC( inq_varid )( _fileId, "verticesOnCell", &verticesOnCellVarId );
1720  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of verticesOnCell" );
1721  std::vector< int > vertices_on_gather_set_cells( nCells * maxEdgesPerCell );
1722  NCDF_SIZE read_starts[2] = { 0, 0 };
1723  NCDF_SIZE read_counts[2] = { static_cast< NCDF_SIZE >( nCells ), static_cast< NCDF_SIZE >( maxEdgesPerCell ) };
1724 #ifdef MOAB_HAVE_PNETCDF
1725  // Enter independent I/O mode, since this read is only for the gather processor
1726  success = NCFUNC( begin_indep_data )( _fileId );
1727  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to begin independent I/O mode" );
1728  success = NCFUNCG( _vara_int )( _fileId, verticesOnCellVarId, read_starts, read_counts,
1729  &vertices_on_gather_set_cells[0] );
1730  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read verticesOnCell data" );
1731  success = NCFUNC( end_indep_data )( _fileId );
1732  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to end independent I/O mode" );
1733 #else
1734  success = NCFUNCG( _vara_int )( _fileId, verticesOnCellVarId, read_starts, read_counts,
1735  &vertices_on_gather_set_cells[0] );
1736  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read verticesOnCell data" );
1737 #endif
1738 
1739  // Divide gather set cells into groups based on the number of edges
1740  Range gather_set_cells_with_n_edges[DEFAULT_MAX_EDGES_PER_CELL + 1];
1741  // Insert larger values before smaller values to increase efficiency
1742  for( int i = nCells - 1; i >= 0; i-- )
1743  {
1744  int num_edges = num_edges_on_gather_set_cells[i];
1745  gather_set_cells_with_n_edges[num_edges].insert( i + 1 ); // 0 based -> 1 based
1746  }
1747 
1748  // Create gather set cells
1749  EntityHandle* conn_arr_gather_set_cells_with_n_edges[DEFAULT_MAX_EDGES_PER_CELL + 1];
1750  for( int num_edges_per_cell = 3; num_edges_per_cell <= maxEdgesPerCell; num_edges_per_cell++ )
1751  {
1752  int num_group_cells = gather_set_cells_with_n_edges[num_edges_per_cell].size();
1753  if( num_group_cells > 0 )
1754  {
1755  EntityHandle start_element;
1757  num_group_cells, num_edges_per_cell, MBPOLYGON, 0, start_element,
1758  conn_arr_gather_set_cells_with_n_edges[num_edges_per_cell], num_group_cells ),
1759  "Failed to create gather set cells" );
1760 
1761  // Add cells to the gather set
1762  Range gather_set_cells_range( start_element, start_element + num_group_cells - 1 );
1763  MB_CHK_SET_ERR( mbImpl->add_entities( gather_set, gather_set_cells_range ),
1764  "Failed to add cells to the gather set" );
1765 
1766  for( int j = 0; j < num_group_cells; j++ )
1767  {
1768  int gather_set_cell_idx =
1769  gather_set_cells_with_n_edges[num_edges_per_cell][j]; // Global cell index, 1 based
1770  gather_set_cell_idx--; // 1 based -> 0 based
1771 
1772  for( int k = 0; k < num_edges_per_cell; k++ )
1773  {
1774  EntityHandle gather_set_vert_idx =
1775  vertices_on_gather_set_cells[gather_set_cell_idx * maxEdgesPerCell +
1776  k]; // Global vertex index, 1 based
1777  gather_set_vert_idx--; // 1 based -> 0 based
1778 
1779  // Connectivity array is shifted by where the gather set vertices start
1780  conn_arr_gather_set_cells_with_n_edges[num_edges_per_cell][j * num_edges_per_cell + k] =
1781  gather_set_start_vertex + gather_set_vert_idx;
1782  }
1783  }
1784  }
1785  }
1786 
1787  return MB_SUCCESS;
1788 }

References moab::NCHelper::_fileId, moab::NCHelper::_readNC, moab::Interface::add_entities(), moab::DEFAULT_MAX_EDGES_PER_CELL, moab::ReadUtilIface::get_element_connect(), moab::Range::insert(), maxEdgesPerCell, MB_CHK_SET_ERR, MB_SET_ERR, MB_SUCCESS, moab::ReadNC::mbImpl, MBPOLYGON, NCDF_SIZE, moab::UcdNCHelper::nCells, NCFUNC, NCFUNCG, moab::ReadNC::readMeshIface, and moab::Range::size().

Referenced by create_mesh().

◆ create_gather_set_edges()

ErrorCode moab::NCHelperMPAS::create_gather_set_edges ( EntityHandle  gather_set,
EntityHandle  gather_set_start_vertex 
)
private

Create gather set edges (optional)

Definition at line 1636 of file NCHelperMPAS.cpp.

1637 {
1638  Interface*& mbImpl = _readNC->mbImpl;
1639 
1640  // Create gather set edges
1641  EntityHandle start_edge;
1642  EntityHandle* conn_arr_gather_set_edges = NULL;
1643  // Don't need to specify allocation number here, because we know enough edges were created
1644  // before
1646  conn_arr_gather_set_edges ),
1647  "Failed to create gather set edges" );
1648 
1649  // Add edges to the gather set
1650  Range gather_set_edges_range( start_edge, start_edge + nEdges - 1 );
1651  MB_CHK_SET_ERR( mbImpl->add_entities( gather_set, gather_set_edges_range ),
1652  "Failed to add edges to the gather set" );
1653 
1654  // Read vertices on each edge
1655  int verticesOnEdgeVarId;
1656  int success = NCFUNC( inq_varid )( _fileId, "verticesOnEdge", &verticesOnEdgeVarId );
1657  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of verticesOnEdge" );
1658  // Utilize the memory storage pointed by conn_arr_gather_set_edges
1659  int* vertices_on_gather_set_edges = (int*)conn_arr_gather_set_edges;
1660  NCDF_SIZE read_starts[2] = { 0, 0 };
1661  NCDF_SIZE read_counts[2] = { static_cast< NCDF_SIZE >( nEdges ), 2 };
1662 #ifdef MOAB_HAVE_PNETCDF
1663  // Enter independent I/O mode, since this read is only for the gather processor
1664  success = NCFUNC( begin_indep_data )( _fileId );
1665  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to begin independent I/O mode" );
1666  success =
1667  NCFUNCG( _vara_int )( _fileId, verticesOnEdgeVarId, read_starts, read_counts, vertices_on_gather_set_edges );
1668  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read verticesOnEdge data" );
1669  success = NCFUNC( end_indep_data )( _fileId );
1670  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to end independent I/O mode" );
1671 #else
1672  success =
1673  NCFUNCG( _vara_int )( _fileId, verticesOnEdgeVarId, read_starts, read_counts, vertices_on_gather_set_edges );
1674  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read verticesOnEdge data" );
1675 #endif
1676 
1677  // Populate connectivity data for gather set edges
1678  // Convert in-place from int (stored in the first half) to EntityHandle
1679  // Reading backward is the trick
1680  for( int edge_vert = nEdges * 2 - 1; edge_vert >= 0; edge_vert-- )
1681  {
1682  int gather_set_vert_idx = vertices_on_gather_set_edges[edge_vert]; // Global vertex index, 1 based
1683  gather_set_vert_idx--; // 1 based -> 0 based
1684  // Connectivity array is shifted by where the gather set vertices start
1685  conn_arr_gather_set_edges[edge_vert] = gather_set_start_vertex + gather_set_vert_idx;
1686  }
1687 
1688  return MB_SUCCESS;
1689 }

References moab::NCHelper::_fileId, moab::NCHelper::_readNC, moab::Interface::add_entities(), moab::ReadUtilIface::get_element_connect(), MB_CHK_SET_ERR, MB_SET_ERR, MB_SUCCESS, MBEDGE, moab::ReadNC::mbImpl, NCDF_SIZE, NCFUNC, NCFUNCG, moab::UcdNCHelper::nEdges, and moab::ReadNC::readMeshIface.

Referenced by create_mesh().

◆ create_gather_set_vertices()

ErrorCode moab::NCHelperMPAS::create_gather_set_vertices ( EntityHandle  gather_set,
EntityHandle gather_set_start_vertex 
)
private

Create gather set vertices.

Definition at line 1524 of file NCHelperMPAS.cpp.

1525 {
1526  Interface*& mbImpl = _readNC->mbImpl;
1527  Tag& mGlobalIdTag = _readNC->mGlobalIdTag;
1528  const Tag*& mpFileIdTag = _readNC->mpFileIdTag;
1529 
1530  // Create gather set vertices
1531  std::vector< double* > arrays;
1532  // Don't need to specify allocation number here, because we know enough vertices were created
1533  // before
1534  MB_CHK_SET_ERR( _readNC->readMeshIface->get_node_coords( 3, nVertices, 0, gather_set_start_vertex, arrays ),
1535  "Failed to create gather set vertices" );
1536 
1537  // Add vertices to the gather set
1538  Range gather_set_verts_range( gather_set_start_vertex, gather_set_start_vertex + nVertices - 1 );
1539  MB_CHK_SET_ERR( mbImpl->add_entities( gather_set, gather_set_verts_range ),
1540  "Failed to add vertices to the gather set" );
1541 
1542  // Read x coordinates for gather set vertices
1543  double* xptr = arrays[0];
1544  int xVertexVarId;
1545  int success = NCFUNC( inq_varid )( _fileId, "xVertex", &xVertexVarId );
1546  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of xVertex" );
1547  NCDF_SIZE read_start = 0;
1548  NCDF_SIZE read_count = static_cast< NCDF_SIZE >( nVertices );
1549 #ifdef MOAB_HAVE_PNETCDF
1550  // Enter independent I/O mode, since this read is only for the gather processor
1551  success = NCFUNC( begin_indep_data )( _fileId );
1552  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to begin independent I/O mode" );
1553  success = NCFUNCG( _vara_double )( _fileId, xVertexVarId, &read_start, &read_count, xptr );
1554  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read xVertex data" );
1555  success = NCFUNC( end_indep_data )( _fileId );
1556  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to end independent I/O mode" );
1557 #else
1558  success = NCFUNCG( _vara_double )( _fileId, xVertexVarId, &read_start, &read_count, xptr );
1559  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read xVertex data" );
1560 #endif
1561 
1562  // Read y coordinates for gather set vertices
1563  double* yptr = arrays[1];
1564  int yVertexVarId;
1565  success = NCFUNC( inq_varid )( _fileId, "yVertex", &yVertexVarId );
1566  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of yVertex" );
1567 #ifdef MOAB_HAVE_PNETCDF
1568  // Enter independent I/O mode, since this read is only for the gather processor
1569  success = NCFUNC( begin_indep_data )( _fileId );
1570  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to begin independent I/O mode" );
1571  success = NCFUNCG( _vara_double )( _fileId, yVertexVarId, &read_start, &read_count, yptr );
1572  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read yVertex data" );
1573  success = NCFUNC( end_indep_data )( _fileId );
1574  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to end independent I/O mode" );
1575 #else
1576  success = NCFUNCG( _vara_double )( _fileId, yVertexVarId, &read_start, &read_count, yptr );
1577  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read yVertex data" );
1578 #endif
1579 
1580  // Read z coordinates for gather set vertices
1581  double* zptr = arrays[2];
1582  int zVertexVarId;
1583  success = NCFUNC( inq_varid )( _fileId, "zVertex", &zVertexVarId );
1584  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of zVertex" );
1585 #ifdef MOAB_HAVE_PNETCDF
1586  // Enter independent I/O mode, since this read is only for the gather processor
1587  success = NCFUNC( begin_indep_data )( _fileId );
1588  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to begin independent I/O mode" );
1589  success = NCFUNCG( _vara_double )( _fileId, zVertexVarId, &read_start, &read_count, zptr );
1590  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read zVertex data" );
1591  success = NCFUNC( end_indep_data )( _fileId );
1592  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to end independent I/O mode" );
1593 #else
1594  success = NCFUNCG( _vara_double )( _fileId, zVertexVarId, &read_start, &read_count, zptr );
1595  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read zVertex data" );
1596 #endif
1597 
1598  // Get ptr to GID memory for gather set vertices
1599  int count = 0;
1600  void* data = NULL;
1601  MB_CHK_SET_ERR( mbImpl->tag_iterate( mGlobalIdTag, gather_set_verts_range.begin(), gather_set_verts_range.end(),
1602  count, data ),
1603  "Failed to iterate global id tag on gather set vertices" );
1604  assert( count == nVertices );
1605  int* gid_data = (int*)data;
1606  for( int j = 1; j <= nVertices; j++ )
1607  gid_data[j - 1] = j;
1608 
1609  // Set the file id tag too, it should be bigger something not interfering with global id
1610  if( mpFileIdTag )
1611  {
1612  MB_CHK_SET_ERR( mbImpl->tag_iterate( *mpFileIdTag, gather_set_verts_range.begin(), gather_set_verts_range.end(),
1613  count, data ),
1614  "Failed to iterate file id tag on gather set vertices" );
1615  assert( count == nVertices );
1616  int bytes_per_tag = 4;
1617  MB_CHK_SET_ERR( mbImpl->tag_get_bytes( *mpFileIdTag, bytes_per_tag ),
1618  "Can't get number of bytes for file id tag" );
1619  if( 4 == bytes_per_tag )
1620  {
1621  gid_data = (int*)data;
1622  for( int j = 1; j <= nVertices; j++ )
1623  gid_data[j - 1] = nVertices + j; // Bigger than global id tag
1624  }
1625  else if( 8 == bytes_per_tag )
1626  { // Should be a handle tag on 64 bit machine?
1627  long* handle_tag_data = (long*)data;
1628  for( int j = 1; j <= nVertices; j++ )
1629  handle_tag_data[j - 1] = nVertices + j; // Bigger than global id tag
1630  }
1631  }
1632 
1633  return MB_SUCCESS;
1634 }

References moab::NCHelper::_fileId, moab::NCHelper::_readNC, moab::Interface::add_entities(), moab::Range::begin(), moab::Range::end(), moab::ReadUtilIface::get_node_coords(), MB_CHK_SET_ERR, MB_SET_ERR, MB_SUCCESS, moab::ReadNC::mbImpl, moab::ReadNC::mGlobalIdTag, moab::ReadNC::mpFileIdTag, NCDF_SIZE, NCFUNC, NCFUNCG, moab::UcdNCHelper::nVertices, moab::ReadNC::readMeshIface, moab::Interface::tag_get_bytes(), and moab::Interface::tag_iterate().

Referenced by create_mesh().

◆ create_local_cells()

ErrorCode moab::NCHelperMPAS::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 1388 of file NCHelperMPAS.cpp.

1392 {
1393  Interface*& mbImpl = _readNC->mbImpl;
1394  Tag& mGlobalIdTag = _readNC->mGlobalIdTag;
1395 
1396  // Divide local cells into groups based on the number of edges
1397  Range local_cells_with_n_edges[DEFAULT_MAX_EDGES_PER_CELL + 1];
1398  // Insert larger values before smaller ones to increase efficiency
1399  for( int i = nLocalCells - 1; i >= 0; i-- )
1400  {
1401  int num_edges = num_edges_on_local_cells[i];
1402  local_cells_with_n_edges[num_edges].insert( localGidCells[i] ); // Global cell index
1403  }
1404 
1405  std::vector< int > num_edges_on_cell_groups;
1406  for( int i = 3; i <= maxEdgesPerCell; i++ )
1407  {
1408  if( local_cells_with_n_edges[i].size() > 0 ) num_edges_on_cell_groups.push_back( i );
1409  }
1410  numCellGroups = num_edges_on_cell_groups.size();
1411 
1412  EntityHandle* conn_arr_local_cells_with_n_edges[DEFAULT_MAX_EDGES_PER_CELL + 1];
1413  for( int i = 0; i < numCellGroups; i++ )
1414  {
1415  int num_edges_per_cell = num_edges_on_cell_groups[i];
1416  int num_group_cells = (int)local_cells_with_n_edges[num_edges_per_cell].size();
1417 
1418  // Create local cells for each non-empty cell group
1419  EntityHandle start_element;
1421  num_group_cells, num_edges_per_cell, MBPOLYGON, 0, start_element,
1422  conn_arr_local_cells_with_n_edges[num_edges_per_cell], num_group_cells ),
1423  "Failed to create local cells" );
1424  faces.insert( start_element, start_element + num_group_cells - 1 );
1425 
1426  // Add local cells to current file set
1427  Range local_cells_range( start_element, start_element + num_group_cells - 1 );
1428  MB_CHK_SET_ERR( _readNC->mbImpl->add_entities( _fileSet, local_cells_range ),
1429  "Failed to add local cells to current file set" );
1430 
1431  // Get ptr to gid memory for local cells
1432  int count = 0;
1433  void* data = NULL;
1434  MB_CHK_SET_ERR( mbImpl->tag_iterate( mGlobalIdTag, local_cells_range.begin(), local_cells_range.end(), count,
1435  data ),
1436  "Failed to iterate global id tag on local cells" );
1437  assert( count == num_group_cells );
1438  int* gid_data = (int*)data;
1439  std::copy( local_cells_with_n_edges[num_edges_per_cell].begin(),
1440  local_cells_with_n_edges[num_edges_per_cell].end(), gid_data );
1441 
1442  // Set connectivity array with proper local vertices handles
1443  for( int j = 0; j < num_group_cells; j++ )
1444  {
1445  EntityHandle global_cell_idx =
1446  local_cells_with_n_edges[num_edges_per_cell][j]; // Global cell index, 1 based
1447  int local_cell_idx = localGidCells.index( global_cell_idx ); // Local cell index, 0 based
1448  assert( local_cell_idx != -1 );
1449 
1450  if( numCellGroups > 1 )
1451  {
1452  // Populate cellHandleToGlobalID map to read cell variables
1453  cellHandleToGlobalID[start_element + j] = global_cell_idx;
1454  }
1455 
1456  for( int k = 0; k < num_edges_per_cell; k++ )
1457  {
1458  EntityHandle global_vert_idx =
1459  vertices_on_local_cells[local_cell_idx * maxEdgesPerCell + k]; // Global vertex index, 1 based
1460  int local_vert_idx = localGidVerts.index( global_vert_idx ); // Local vertex index, 0 based
1461  assert( local_vert_idx != -1 );
1462  conn_arr_local_cells_with_n_edges[num_edges_per_cell][j * num_edges_per_cell + k] =
1463  start_vertex + local_vert_idx;
1464  }
1465  }
1466  }
1467 
1468  return MB_SUCCESS;
1469 }

References moab::NCHelper::_fileSet, moab::NCHelper::_readNC, moab::Interface::add_entities(), moab::Range::begin(), cellHandleToGlobalID, 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, moab::ReadNC::mGlobalIdTag, moab::UcdNCHelper::nLocalCells, numCellGroups, moab::ReadNC::readMeshIface, and moab::Interface::tag_iterate().

Referenced by create_mesh().

◆ create_local_edges()

ErrorCode moab::NCHelperMPAS::create_local_edges ( EntityHandle  start_vertex,
const std::vector< int > &  num_edges_on_local_cells 
)
private

Create local edges (optional)

Definition at line 1238 of file NCHelperMPAS.cpp.

1240 {
1241  Interface*& mbImpl = _readNC->mbImpl;
1242  Tag& mGlobalIdTag = _readNC->mGlobalIdTag;
1243  DebugOutput& dbgOut = _readNC->dbgOut;
1244 
1245  // Read edges on each local cell, to get localGidEdges
1246  int edgesOnCellVarId;
1247  int success = NCFUNC( inq_varid )( _fileId, "edgesOnCell", &edgesOnCellVarId );
1248  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of edgesOnCell" );
1249 
1250  std::vector< int > edges_on_local_cells( nLocalCells * maxEdgesPerCell );
1251  dbgOut.tprintf( 1, " edges_on_local_cells.size() = %d\n", (int)edges_on_local_cells.size() );
1252 
1253 #ifdef MOAB_HAVE_PNETCDF
1254  size_t nb_reads = localGidCells.psize();
1255  std::vector< int > requests( nb_reads );
1256  std::vector< int > statuss( nb_reads );
1257  size_t idxReq = 0;
1258 #endif
1259  size_t indexInArray = 0;
1260  for( Range::pair_iterator pair_iter = localGidCells.pair_begin(); pair_iter != localGidCells.pair_end();
1261  ++pair_iter )
1262  {
1263  EntityHandle starth = pair_iter->first;
1264  EntityHandle endh = pair_iter->second;
1265  NCDF_SIZE read_starts[2] = { static_cast< NCDF_SIZE >( starth - 1 ), 0 };
1266  NCDF_SIZE read_counts[2] = { static_cast< NCDF_SIZE >( endh - starth + 1 ),
1267  static_cast< NCDF_SIZE >( maxEdgesPerCell ) };
1268 
1269  // Do a partial read in each subrange
1270 #ifdef MOAB_HAVE_PNETCDF
1271  success = NCFUNCREQG( _vara_int )( _fileId, edgesOnCellVarId, read_starts, read_counts,
1272  &( edges_on_local_cells[indexInArray] ), &requests[idxReq++] );
1273 #else
1274  success = NCFUNCAG( _vara_int )( _fileId, edgesOnCellVarId, read_starts, read_counts,
1275  &( edges_on_local_cells[indexInArray] ) );
1276 #endif
1277  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read edgesOnCell data in a loop" );
1278 
1279  // Increment the index for next subrange
1280  indexInArray += ( endh - starth + 1 ) * maxEdgesPerCell;
1281  }
1282 
1283 #ifdef MOAB_HAVE_PNETCDF
1284  // Wait outside the loop
1285  success = NCFUNC( wait_all )( _fileId, requests.size(), &requests[0], &statuss[0] );
1286  if( success ) MB_SET_ERR( MB_FAILURE, "Failed on wait_all" );
1287 #endif
1288 
1289  // Correct local cell edges array in the same way as local cell vertices array, replace the
1290  // padded edges with the last edges in the corresponding cells
1291  for( int local_cell_idx = 0; local_cell_idx < nLocalCells; local_cell_idx++ )
1292  {
1293  int num_edges = num_edges_on_local_cells[local_cell_idx];
1294  int idx_in_local_edge_arr = local_cell_idx * maxEdgesPerCell;
1295  int last_edge_idx = edges_on_local_cells[idx_in_local_edge_arr + num_edges - 1];
1296  for( int i = num_edges; i < maxEdgesPerCell; i++ )
1297  edges_on_local_cells[idx_in_local_edge_arr + i] = last_edge_idx;
1298  }
1299 
1300  // Collect local edges
1301  std::sort( edges_on_local_cells.begin(), edges_on_local_cells.end() );
1302  std::copy( edges_on_local_cells.rbegin(), edges_on_local_cells.rend(), range_inserter( localGidEdges ) );
1304 
1305  dbgOut.tprintf( 1, " localGidEdges.psize() = %d\n", (int)localGidEdges.psize() );
1306  dbgOut.tprintf( 1, " localGidEdges.size() = %d\n", (int)localGidEdges.size() );
1307 
1308  // Create local edges
1309  EntityHandle start_edge;
1310  EntityHandle* conn_arr_edges = NULL;
1312  _readNC->readMeshIface->get_element_connect( nLocalEdges, 2, MBEDGE, 0, start_edge, conn_arr_edges,
1313  // Might have to create gather mesh later
1315  "Failed to create local edges" );
1316 
1317  // Add local edges to current file set
1318  Range local_edges_range( start_edge, start_edge + nLocalEdges - 1 );
1319  MB_CHK_SET_ERR( _readNC->mbImpl->add_entities( _fileSet, local_edges_range ),
1320  "Failed to add local edges to current file set" );
1321 
1322  // Get ptr to GID memory for edges
1323  int count = 0;
1324  void* data = NULL;
1325  MB_CHK_SET_ERR( mbImpl->tag_iterate( mGlobalIdTag, local_edges_range.begin(), local_edges_range.end(), count,
1326  data ),
1327  "Failed to iterate global id tag on local edges" );
1328  assert( count == nLocalEdges );
1329  int* gid_data = (int*)data;
1330  std::copy( localGidEdges.begin(), localGidEdges.end(), gid_data );
1331 
1332  int verticesOnEdgeVarId;
1333 
1334  // Read vertices on each local edge, to get edge connectivity
1335  success = NCFUNC( inq_varid )( _fileId, "verticesOnEdge", &verticesOnEdgeVarId );
1336  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of verticesOnEdge" );
1337  // Utilize the memory storage pointed by conn_arr_edges
1338  int* vertices_on_local_edges = (int*)conn_arr_edges;
1339 #ifdef MOAB_HAVE_PNETCDF
1340  nb_reads = localGidEdges.psize();
1341  requests.resize( nb_reads );
1342  statuss.resize( nb_reads );
1343  idxReq = 0;
1344 #endif
1345  indexInArray = 0;
1346  for( Range::pair_iterator pair_iter = localGidEdges.pair_begin(); pair_iter != localGidEdges.pair_end();
1347  ++pair_iter )
1348  {
1349  EntityHandle starth = pair_iter->first;
1350  EntityHandle endh = pair_iter->second;
1351  NCDF_SIZE read_starts[2] = { static_cast< NCDF_SIZE >( starth - 1 ), 0 };
1352  NCDF_SIZE read_counts[2] = { static_cast< NCDF_SIZE >( endh - starth + 1 ), 2 };
1353 
1354  // Do a partial read in each subrange
1355 #ifdef MOAB_HAVE_PNETCDF
1356  success = NCFUNCREQG( _vara_int )( _fileId, verticesOnEdgeVarId, read_starts, read_counts,
1357  &( vertices_on_local_edges[indexInArray] ), &requests[idxReq++] );
1358 #else
1359  success = NCFUNCAG( _vara_int )( _fileId, verticesOnEdgeVarId, read_starts, read_counts,
1360  &( vertices_on_local_edges[indexInArray] ) );
1361 #endif
1362  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read verticesOnEdge data in a loop" );
1363 
1364  // Increment the index for next subrange
1365  indexInArray += ( endh - starth + 1 ) * 2;
1366  }
1367 
1368 #ifdef MOAB_HAVE_PNETCDF
1369  // Wait outside the loop
1370  success = NCFUNC( wait_all )( _fileId, requests.size(), &requests[0], &statuss[0] );
1371  if( success ) MB_SET_ERR( MB_FAILURE, "Failed on wait_all" );
1372 #endif
1373 
1374  // Populate connectivity data for local edges
1375  // Convert in-place from int (stored in the first half) to EntityHandle
1376  // Reading backward is the trick
1377  for( int edge_vert = nLocalEdges * 2 - 1; edge_vert >= 0; edge_vert-- )
1378  {
1379  int global_vert_idx = vertices_on_local_edges[edge_vert]; // Global vertex index, 1 based
1380  int local_vert_idx = localGidVerts.index( global_vert_idx ); // Local vertex index, 0 based
1381  assert( local_vert_idx != -1 );
1382  conn_arr_edges[edge_vert] = start_vertex + local_vert_idx;
1383  }
1384 
1385  return MB_SUCCESS;
1386 }

References moab::NCHelper::_fileId, moab::NCHelper::_fileSet, moab::NCHelper::_readNC, moab::Interface::add_entities(), moab::Range::begin(), createGatherSet, moab::ReadNC::dbgOut, moab::Range::end(), moab::ReadUtilIface::get_element_connect(), moab::Range::index(), moab::UcdNCHelper::localGidCells, moab::UcdNCHelper::localGidEdges, moab::UcdNCHelper::localGidVerts, maxEdgesPerCell, MB_CHK_SET_ERR, MB_SET_ERR, MB_SUCCESS, MBEDGE, moab::ReadNC::mbImpl, moab::ReadNC::mGlobalIdTag, NCDF_SIZE, NCFUNC, NCFUNCAG, moab::UcdNCHelper::nEdges, moab::UcdNCHelper::nLocalCells, moab::UcdNCHelper::nLocalEdges, moab::Range::pair_begin(), moab::Range::pair_end(), moab::Range::psize(), moab::ReadNC::readMeshIface, moab::Range::size(), moab::Interface::tag_iterate(), and moab::DebugOutput::tprintf().

Referenced by create_mesh().

◆ create_local_vertices()

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

Create local vertices.

Definition at line 1059 of file NCHelperMPAS.cpp.

1061 {
1062  Interface*& mbImpl = _readNC->mbImpl;
1063  Tag& mGlobalIdTag = _readNC->mGlobalIdTag;
1064  const Tag*& mpFileIdTag = _readNC->mpFileIdTag;
1065  DebugOutput& dbgOut = _readNC->dbgOut;
1066 
1067  // Make a copy of vertices_on_local_cells for sorting (keep original one to set cell
1068  // connectivity later)
1069  std::vector< int > vertices_on_local_cells_sorted( vertices_on_local_cells );
1070  std::sort( vertices_on_local_cells_sorted.begin(), vertices_on_local_cells_sorted.end() );
1071  std::copy( vertices_on_local_cells_sorted.rbegin(), vertices_on_local_cells_sorted.rend(),
1072  range_inserter( localGidVerts ) );
1074 
1075  dbgOut.tprintf( 1, " localGidVerts.psize() = %d\n", (int)localGidVerts.psize() );
1076  dbgOut.tprintf( 1, " localGidVerts.size() = %d\n", (int)localGidVerts.size() );
1077 
1078  // Create local vertices
1079  std::vector< double* > arrays;
1081  _readNC->readMeshIface->get_node_coords( 3, nLocalVertices, 0, start_vertex, arrays,
1082  // Might have to create gather mesh later
1084  "Failed to create local vertices" );
1085 
1086  // Add local vertices to current file set
1087  Range local_verts_range( start_vertex, start_vertex + nLocalVertices - 1 );
1088  MB_CHK_SET_ERR( _readNC->mbImpl->add_entities( _fileSet, local_verts_range ),
1089  "Failed to add local vertices to current file set" );
1090 
1091  // Get ptr to GID memory for local vertices
1092  int count = 0;
1093  void* data = NULL;
1094  MB_CHK_SET_ERR( mbImpl->tag_iterate( mGlobalIdTag, local_verts_range.begin(), local_verts_range.end(), count,
1095  data ),
1096  "Failed to iterate global id tag on local vertices" );
1097  assert( count == nLocalVertices );
1098  int* gid_data = (int*)data;
1099  std::copy( localGidVerts.begin(), localGidVerts.end(), gid_data );
1100 
1101  // Duplicate GID data, which will be used to resolve sharing
1102  if( mpFileIdTag )
1103  {
1104  MB_CHK_SET_ERR( mbImpl->tag_iterate( *mpFileIdTag, local_verts_range.begin(), local_verts_range.end(), count,
1105  data ),
1106  "Failed to iterate file id tag on local vertices" );
1107  assert( count == nLocalVertices );
1108  int bytes_per_tag = 4;
1109  MB_CHK_SET_ERR( mbImpl->tag_get_bytes( *mpFileIdTag, bytes_per_tag ),
1110  "Can't get number of bytes for file id tag" );
1111  if( 4 == bytes_per_tag )
1112  {
1113  gid_data = (int*)data;
1114  std::copy( localGidVerts.begin(), localGidVerts.end(), gid_data );
1115  }
1116  else if( 8 == bytes_per_tag )
1117  { // Should be a handle tag on 64 bit machine?
1118  long* handle_tag_data = (long*)data;
1119  std::copy( localGidVerts.begin(), localGidVerts.end(), handle_tag_data );
1120  }
1121  }
1122 
1123 #ifdef MOAB_HAVE_PNETCDF
1124  size_t nb_reads = localGidVerts.psize();
1125  std::vector< int > requests( nb_reads );
1126  std::vector< int > statuss( nb_reads );
1127  size_t idxReq = 0;
1128 #endif
1129 
1130  // Read x coordinates for local vertices
1131  double* xptr = arrays[0];
1132  int xVertexVarId;
1133  int success = NCFUNC( inq_varid )( _fileId, "xVertex", &xVertexVarId );
1134  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of xVertex" );
1135  size_t indexInArray = 0;
1136  for( Range::pair_iterator pair_iter = localGidVerts.pair_begin(); pair_iter != localGidVerts.pair_end();
1137  ++pair_iter )
1138  {
1139  EntityHandle starth = pair_iter->first;
1140  EntityHandle endh = pair_iter->second;
1141  NCDF_SIZE read_start = (NCDF_SIZE)( starth - 1 );
1142  NCDF_SIZE read_count = (NCDF_SIZE)( endh - starth + 1 );
1143 
1144  // Do a partial read in each subrange
1145 #ifdef MOAB_HAVE_PNETCDF
1146  success = NCFUNCREQG( _vara_double )( _fileId, xVertexVarId, &read_start, &read_count, &( xptr[indexInArray] ),
1147  &requests[idxReq++] );
1148 #else
1149  success = NCFUNCAG( _vara_double )( _fileId, xVertexVarId, &read_start, &read_count, &( xptr[indexInArray] ) );
1150 #endif
1151  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read xVertex data in a loop" );
1152 
1153  // Increment the index for next subrange
1154  indexInArray += ( endh - starth + 1 );
1155  }
1156 
1157 #ifdef MOAB_HAVE_PNETCDF
1158  // Wait outside the loop
1159  success = NCFUNC( wait_all )( _fileId, requests.size(), &requests[0], &statuss[0] );
1160  if( success ) MB_SET_ERR( MB_FAILURE, "Failed on wait_all" );
1161 #endif
1162 
1163  // Read y coordinates for local vertices
1164  double* yptr = arrays[1];
1165  int yVertexVarId;
1166  success = NCFUNC( inq_varid )( _fileId, "yVertex", &yVertexVarId );
1167  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of yVertex" );
1168 #ifdef MOAB_HAVE_PNETCDF
1169  idxReq = 0;
1170 #endif
1171  indexInArray = 0;
1172  for( Range::pair_iterator pair_iter = localGidVerts.pair_begin(); pair_iter != localGidVerts.pair_end();
1173  ++pair_iter )
1174  {
1175  EntityHandle starth = pair_iter->first;
1176  EntityHandle endh = pair_iter->second;
1177  NCDF_SIZE read_start = (NCDF_SIZE)( starth - 1 );
1178  NCDF_SIZE read_count = (NCDF_SIZE)( endh - starth + 1 );
1179 
1180  // Do a partial read in each subrange
1181 #ifdef MOAB_HAVE_PNETCDF
1182  success = NCFUNCREQG( _vara_double )( _fileId, yVertexVarId, &read_start, &read_count, &( yptr[indexInArray] ),
1183  &requests[idxReq++] );
1184 #else
1185  success = NCFUNCAG( _vara_double )( _fileId, yVertexVarId, &read_start, &read_count, &( yptr[indexInArray] ) );
1186 #endif
1187  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read yVertex data in a loop" );
1188 
1189  // Increment the index for next subrange
1190  indexInArray += ( endh - starth + 1 );
1191  }
1192 
1193 #ifdef MOAB_HAVE_PNETCDF
1194  // Wait outside the loop
1195  success = NCFUNC( wait_all )( _fileId, requests.size(), &requests[0], &statuss[0] );
1196  if( success ) MB_SET_ERR( MB_FAILURE, "Failed on wait_all" );
1197 #endif
1198 
1199  // Read z coordinates for local vertices
1200  double* zptr = arrays[2];
1201  int zVertexVarId;
1202  success = NCFUNC( inq_varid )( _fileId, "zVertex", &zVertexVarId );
1203  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of zVertex" );
1204 #ifdef MOAB_HAVE_PNETCDF
1205  idxReq = 0;
1206 #endif
1207  indexInArray = 0;
1208  for( Range::pair_iterator pair_iter = localGidVerts.pair_begin(); pair_iter != localGidVerts.pair_end();
1209  ++pair_iter )
1210  {
1211  EntityHandle starth = pair_iter->first;
1212  EntityHandle endh = pair_iter->second;
1213  NCDF_SIZE read_start = (NCDF_SIZE)( starth - 1 );
1214  NCDF_SIZE read_count = (NCDF_SIZE)( endh - starth + 1 );
1215 
1216  // Do a partial read in each subrange
1217 #ifdef MOAB_HAVE_PNETCDF
1218  success = NCFUNCREQG( _vara_double )( _fileId, zVertexVarId, &read_start, &read_count, &( zptr[indexInArray] ),
1219  &requests[idxReq++] );
1220 #else
1221  success = NCFUNCAG( _vara_double )( _fileId, zVertexVarId, &read_start, &read_count, &( zptr[indexInArray] ) );
1222 #endif
1223  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read zVertex data in a loop" );
1224 
1225  // Increment the index for next subrange
1226  indexInArray += ( endh - starth + 1 );
1227  }
1228 
1229 #ifdef MOAB_HAVE_PNETCDF
1230  // Wait outside the loop
1231  success = NCFUNC( wait_all )( _fileId, requests.size(), &requests[0], &statuss[0] );
1232  if( success ) MB_SET_ERR( MB_FAILURE, "Failed on wait_all" );
1233 #endif
1234 
1235  return MB_SUCCESS;
1236 }

References moab::NCHelper::_fileId, moab::NCHelper::_fileSet, moab::NCHelper::_readNC, moab::Interface::add_entities(), moab::Range::begin(), createGatherSet, moab::ReadNC::dbgOut, 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::UcdNCHelper::nVertices, moab::Range::pair_begin(), moab::Range::pair_end(), 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::NCHelperMPAS::create_mesh ( Range faces)
privatevirtual

Implementation of NCHelper::create_mesh()

Implements moab::NCHelper.

Definition at line 346 of file NCHelperMPAS.cpp.

347 {
348  Interface*& mbImpl = _readNC->mbImpl;
349  bool& noMixedElements = _readNC->noMixedElements;
350  bool& noEdges = _readNC->noEdges;
351  DebugOutput& dbgOut = _readNC->dbgOut;
352 
353 #ifdef MOAB_HAVE_MPI
354  int rank = 0;
355  int procs = 1;
356  bool& isParallel = _readNC->isParallel;
357  ParallelComm* myPcomm = NULL;
358  if( isParallel )
359  {
360  myPcomm = _readNC->myPcomm;
361  rank = myPcomm->proc_config().proc_rank();
362  procs = myPcomm->proc_config().proc_size();
363  }
364 
365  // Need to know whether we'll be creating gather mesh
366  if( rank == _readNC->gatherSetRank ) createGatherSet = true;
367 
368  if( procs >= 2 )
369  {
370  // Shift rank to obtain a rotated trivial partition
371  int shifted_rank = rank;
372  int& trivialPartitionShift = _readNC->trivialPartitionShift;
373  if( trivialPartitionShift > 0 ) shifted_rank = ( rank + trivialPartitionShift ) % procs;
374 
375  // Compute the number of local cells on this proc
376  nLocalCells = int( std::floor( 1.0 * nCells / procs ) );
377 
378  // The starting global cell index in the MPAS file for this proc
379  int start_cell_idx = shifted_rank * nLocalCells;
380 
381  // Number of extra cells after equal split over procs
382  int iextra = nCells % procs;
383 
384  // Allocate extra cells over procs
385  if( shifted_rank < iextra ) nLocalCells++;
386  start_cell_idx += std::min( shifted_rank, iextra );
387 
388  start_cell_idx++; // 0 based -> 1 based
389 
390  // Redistribute local cells after trivial partition (e.g. apply Zoltan partition)
391  MB_CHK_SET_ERR( redistribute_local_cells( start_cell_idx, myPcomm ),
392  "Failed to redistribute local cells after trivial partition" );
393  }
394  else
395  {
398  }
399 #else
402 #endif
403  dbgOut.tprintf( 1, " localGidCells.psize() = %d\n", (int)localGidCells.psize() );
404  dbgOut.tprintf( 1, " localGidCells.size() = %d\n", (int)localGidCells.size() );
405 
406  // Read number of edges on each local cell, to calculate actual maxEdgesPerCell
407  int nEdgesOnCellVarId;
408  int success = NCFUNC( inq_varid )( _fileId, "nEdgesOnCell", &nEdgesOnCellVarId );
409  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of nEdgesOnCell" );
410  std::vector< int > num_edges_on_local_cells( nLocalCells );
411 #ifdef MOAB_HAVE_PNETCDF
412  size_t nb_reads = localGidCells.psize();
413  std::vector< int > requests( nb_reads );
414  std::vector< int > statuss( nb_reads );
415  size_t idxReq = 0;
416 #endif
417  size_t indexInArray = 0;
418  for( Range::pair_iterator pair_iter = localGidCells.pair_begin(); pair_iter != localGidCells.pair_end();
419  ++pair_iter )
420  {
421  EntityHandle starth = pair_iter->first;
422  EntityHandle endh = pair_iter->second;
423  NCDF_SIZE read_start = (NCDF_SIZE)( starth - 1 );
424  NCDF_SIZE read_count = (NCDF_SIZE)( endh - starth + 1 );
425 
426  // Do a partial read in each subrange
427 #ifdef MOAB_HAVE_PNETCDF
428  success = NCFUNCREQG( _vara_int )( _fileId, nEdgesOnCellVarId, &read_start, &read_count,
429  &( num_edges_on_local_cells[indexInArray] ), &requests[idxReq++] );
430 #else
431  success = NCFUNCAG( _vara_int )( _fileId, nEdgesOnCellVarId, &read_start, &read_count,
432  &( num_edges_on_local_cells[indexInArray] ) );
433 #endif
434  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read nEdgesOnCell data in a loop" );
435 
436  // Increment the index for next subrange
437  indexInArray += ( endh - starth + 1 );
438  }
439 
440 #ifdef MOAB_HAVE_PNETCDF
441  // Wait outside the loop
442  success = NCFUNC( wait_all )( _fileId, requests.size(), &requests[0], &statuss[0] );
443  if( success ) MB_SET_ERR( MB_FAILURE, "Failed on wait_all" );
444 #endif
445 
446  // Get local maxEdgesPerCell on this proc
447  int local_max_edges_per_cell =
448  *( std::max_element( num_edges_on_local_cells.begin(), num_edges_on_local_cells.end() ) );
449  maxEdgesPerCell = local_max_edges_per_cell;
450 
451  // If parallel, do a MPI_Allreduce to get global maxEdgesPerCell across all procs
452 #ifdef MOAB_HAVE_MPI
453  if( procs >= 2 )
454  {
455  int global_max_edges_per_cell;
456  ParallelComm*& myPcomm = _readNC->myPcomm;
457  MPI_Allreduce( &local_max_edges_per_cell, &global_max_edges_per_cell, 1, MPI_INT, MPI_MAX,
458  myPcomm->proc_config().proc_comm() );
459  assert( local_max_edges_per_cell <= global_max_edges_per_cell );
460  maxEdgesPerCell = global_max_edges_per_cell;
461  if( 0 == rank ) dbgOut.tprintf( 1, " global_max_edges_per_cell = %d\n", global_max_edges_per_cell );
462  }
463 #endif
464 
465  // Read vertices on each local cell, to get localGidVerts and cell connectivity later
466  int verticesOnCellVarId;
467  success = NCFUNC( inq_varid )( _fileId, "verticesOnCell", &verticesOnCellVarId );
468  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of verticesOnCell" );
469  std::vector< int > vertices_on_local_cells( nLocalCells * maxEdgesPerCell );
470 #ifdef MOAB_HAVE_PNETCDF
471  idxReq = 0;
472 #endif
473  indexInArray = 0;
474  for( Range::pair_iterator pair_iter = localGidCells.pair_begin(); pair_iter != localGidCells.pair_end();
475  ++pair_iter )
476  {
477  EntityHandle starth = pair_iter->first;
478  EntityHandle endh = pair_iter->second;
479  NCDF_SIZE read_starts[2] = { static_cast< NCDF_SIZE >( starth - 1 ), 0 };
480  NCDF_SIZE read_counts[2] = { static_cast< NCDF_SIZE >( endh - starth + 1 ),
481  static_cast< NCDF_SIZE >( maxEdgesPerCell ) };
482 
483  // Do a partial read in each subrange
484 #ifdef MOAB_HAVE_PNETCDF
485  success = NCFUNCREQG( _vara_int )( _fileId, verticesOnCellVarId, read_starts, read_counts,
486  &( vertices_on_local_cells[indexInArray] ), &requests[idxReq++] );
487 #else
488  success = NCFUNCAG( _vara_int )( _fileId, verticesOnCellVarId, read_starts, read_counts,
489  &( vertices_on_local_cells[indexInArray] ) );
490 #endif
491  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read verticesOnCell data in a loop" );
492 
493  // Increment the index for next subrange
494  indexInArray += ( endh - starth + 1 ) * maxEdgesPerCell;
495  }
496 
497 #ifdef MOAB_HAVE_PNETCDF
498  // Wait outside the loop
499  success = NCFUNC( wait_all )( _fileId, requests.size(), &requests[0], &statuss[0] );
500  if( success ) MB_SET_ERR( MB_FAILURE, "Failed on wait_all" );
501 #endif
502 
503  // Correct local cell vertices array, replace the padded vertices with the last vertices
504  // in the corresponding cells; sometimes the padded vertices are 0, sometimes a large
505  // vertex id. Make sure they are consistent to our padded option
506  for( int local_cell_idx = 0; local_cell_idx < nLocalCells; local_cell_idx++ )
507  {
508  int num_edges = num_edges_on_local_cells[local_cell_idx];
509  int idx_in_local_vert_arr = local_cell_idx * maxEdgesPerCell;
510  int last_vert_idx = vertices_on_local_cells[idx_in_local_vert_arr + num_edges - 1];
511  for( int i = num_edges; i < maxEdgesPerCell; i++ )
512  vertices_on_local_cells[idx_in_local_vert_arr + i] = last_vert_idx;
513  }
514 
515  // Create local vertices
516  EntityHandle start_vertex;
517  MB_CHK_SET_ERR( create_local_vertices( vertices_on_local_cells, start_vertex ),
518  "Failed to create local vertices for MPAS mesh" );
519 
520  // Create local edges (unless NO_EDGES read option is set)
521  if( !noEdges )
522  {
523  MB_CHK_SET_ERR( create_local_edges( start_vertex, num_edges_on_local_cells ),
524  "Failed to create local edges for MPAS mesh" );
525  }
526 
527  // Create local cells, either unpadded or padded
528  if( noMixedElements )
529  {
530  MB_CHK_SET_ERR( create_padded_local_cells( vertices_on_local_cells, start_vertex, faces ),
531  "Failed to create padded local cells for MPAS mesh" );
532  }
533  else
534  {
535  MB_CHK_SET_ERR( create_local_cells( vertices_on_local_cells, num_edges_on_local_cells, start_vertex, faces ),
536  "Failed to create local cells for MPAS mesh" );
537  }
538 
539  // Set tag for numCellGroups
540  Tag numCellGroupsTag = 0;
541  MB_CHK_SET_ERR( mbImpl->tag_get_handle( "__NUM_CELL_GROUPS", 1, MB_TYPE_INTEGER, numCellGroupsTag,
543  "Trouble creating __NUM_CELL_GROUPS tag" );
544  MB_CHK_SET_ERR( mbImpl->tag_set_data( numCellGroupsTag, &_fileSet, 1, &numCellGroups ),
545  "Trouble setting data to __NUM_CELL_GROUPS tag" );
546 
547  if( createGatherSet )
548  {
549  EntityHandle gather_set;
550  MB_CHK_SET_ERR( _readNC->readMeshIface->create_gather_set( gather_set ), "Failed to create gather set" );
551 
552  // Create gather set vertices
553  EntityHandle start_gather_set_vertex;
554  MB_CHK_SET_ERR( create_gather_set_vertices( gather_set, start_gather_set_vertex ),
555  "Failed to create gather set vertices for MPAS mesh" );
556 
557  // Create gather set edges (unless NO_EDGES read option is set)
558  if( !noEdges )
559  {
560  MB_CHK_SET_ERR( create_gather_set_edges( gather_set, start_gather_set_vertex ),
561  "Failed to create gather set edges for MPAS mesh" );
562  }
563 
564  // Create gather set cells, either unpadded or padded
565  if( noMixedElements )
566  {
567  MB_CHK_SET_ERR( create_padded_gather_set_cells( gather_set, start_gather_set_vertex ),
568  "Failed to create padded gather set cells for MPAS mesh" );
569  }
570  else
571  {
572  MB_CHK_SET_ERR( create_gather_set_cells( gather_set, start_gather_set_vertex ),
573  "Failed to create gather set cells for MPAS mesh" );
574  }
575  }
576 
577  return MB_SUCCESS;
578 }

References moab::NCHelper::_fileId, moab::NCHelper::_fileSet, moab::NCHelper::_readNC, moab::ReadUtilIface::create_gather_set(), create_gather_set_cells(), create_gather_set_edges(), create_gather_set_vertices(), create_local_cells(), create_local_edges(), create_local_vertices(), create_padded_gather_set_cells(), create_padded_local_cells(), createGatherSet, moab::ReadNC::dbgOut, moab::ReadNC::gatherSetRank, moab::Range::insert(), moab::ReadNC::isParallel, moab::UcdNCHelper::localGidCells, maxEdgesPerCell, MB_CHK_SET_ERR, MB_SET_ERR, MB_SUCCESS, MB_TAG_CREAT, MB_TAG_SPARSE, MB_TYPE_INTEGER, moab::ReadNC::mbImpl, NCDF_SIZE, moab::UcdNCHelper::nCells, NCFUNC, NCFUNCAG, moab::UcdNCHelper::nLocalCells, moab::ReadNC::noEdges, moab::ReadNC::noMixedElements, numCellGroups, moab::Range::pair_begin(), moab::Range::pair_end(), moab::ProcConfig::proc_comm(), moab::ParallelComm::proc_config(), moab::ProcConfig::proc_rank(), moab::ProcConfig::proc_size(), moab::Range::psize(), moab::ReadNC::readMeshIface, moab::Range::size(), moab::Interface::tag_get_handle(), moab::Interface::tag_set_data(), moab::DebugOutput::tprintf(), and moab::ReadNC::trivialPartitionShift.

◆ create_padded_gather_set_cells()

ErrorCode moab::NCHelperMPAS::create_padded_gather_set_cells ( EntityHandle  gather_set,
EntityHandle  gather_set_start_vertex 
)
private

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

Definition at line 1790 of file NCHelperMPAS.cpp.

1791 {
1792  Interface*& mbImpl = _readNC->mbImpl;
1793 
1794  // Read number of edges on each gather set cell
1795  int nEdgesOnCellVarId;
1796  int success = NCFUNC( inq_varid )( _fileId, "nEdgesOnCell", &nEdgesOnCellVarId );
1797  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of nEdgesOnCell" );
1798  std::vector< int > num_edges_on_gather_set_cells( nCells );
1799  NCDF_SIZE read_start = 0;
1800  NCDF_SIZE read_count = static_cast< NCDF_SIZE >( nCells );
1801 #ifdef MOAB_HAVE_PNETCDF
1802  // Enter independent I/O mode, since this read is only for the gather processor
1803  success = NCFUNC( begin_indep_data )( _fileId );
1804  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to begin independent I/O mode" );
1805  success =
1806  NCFUNCG( _vara_int )( _fileId, nEdgesOnCellVarId, &read_start, &read_count, &num_edges_on_gather_set_cells[0] );
1807  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read nEdgesOnCell data" );
1808  success = NCFUNC( end_indep_data )( _fileId );
1809  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to end independent I/O mode" );
1810 #else
1811  success =
1812  NCFUNCG( _vara_int )( _fileId, nEdgesOnCellVarId, &read_start, &read_count, &num_edges_on_gather_set_cells[0] );
1813  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read nEdgesOnCell data" );
1814 #endif
1815 
1816  // Create gather set cells
1817  EntityHandle start_element;
1818  EntityHandle* conn_arr_gather_set_cells = NULL;
1819  // Don't need to specify allocation number here, because we know enough cells were created
1820  // before
1822  conn_arr_gather_set_cells ),
1823  "Failed to create gather set cells" );
1824 
1825  // Add cells to the gather set
1826  Range gather_set_cells_range( start_element, start_element + nCells - 1 );
1827  MB_CHK_SET_ERR( mbImpl->add_entities( gather_set, gather_set_cells_range ),
1828  "Failed to add cells to the gather set" );
1829 
1830  // Read vertices on each gather set cell (connectivity)
1831  int verticesOnCellVarId;
1832  success = NCFUNC( inq_varid )( _fileId, "verticesOnCell", &verticesOnCellVarId );
1833  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of verticesOnCell" );
1834  // Utilize the memory storage pointed by conn_arr_gather_set_cells
1835  int* vertices_on_gather_set_cells = (int*)conn_arr_gather_set_cells;
1836  NCDF_SIZE read_starts[2] = { 0, 0 };
1837  NCDF_SIZE read_counts[2] = { static_cast< NCDF_SIZE >( nCells ), static_cast< NCDF_SIZE >( maxEdgesPerCell ) };
1838 #ifdef MOAB_HAVE_PNETCDF
1839  // Enter independent I/O mode, since this read is only for the gather processor
1840  success = NCFUNC( begin_indep_data )( _fileId );
1841  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to begin independent I/O mode" );
1842  success =
1843  NCFUNCG( _vara_int )( _fileId, verticesOnCellVarId, read_starts, read_counts, vertices_on_gather_set_cells );
1844  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read verticesOnCell data" );
1845  success = NCFUNC( end_indep_data )( _fileId );
1846  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to end independent I/O mode" );
1847 #else
1848  success =
1849  NCFUNCG( _vara_int )( _fileId, verticesOnCellVarId, read_starts, read_counts, vertices_on_gather_set_cells );
1850  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read verticesOnCell data" );
1851 #endif
1852 
1853  // Correct gather set cell vertices array in the same way as local cell vertices array,
1854  // replace the padded vertices with the last vertices in the corresponding cells
1855  for( int gather_set_cell_idx = 0; gather_set_cell_idx < nCells; gather_set_cell_idx++ )
1856  {
1857  int num_edges = num_edges_on_gather_set_cells[gather_set_cell_idx];
1858  int idx_in_gather_set_vert_arr = gather_set_cell_idx * maxEdgesPerCell;
1859  int last_vert_idx = vertices_on_gather_set_cells[idx_in_gather_set_vert_arr + num_edges - 1];
1860  for( int i = num_edges; i < maxEdgesPerCell; i++ )
1861  vertices_on_gather_set_cells[idx_in_gather_set_vert_arr + i] = last_vert_idx;
1862  }
1863 
1864  // Populate connectivity data for gather set cells
1865  // Convert in-place from int (stored in the first half) to EntityHandle
1866  // Reading backward is the trick
1867  for( int cell_vert = nCells * maxEdgesPerCell - 1; cell_vert >= 0; cell_vert-- )
1868  {
1869  int gather_set_vert_idx = vertices_on_gather_set_cells[cell_vert]; // Global vertex index, 1 based
1870  gather_set_vert_idx--; // 1 based -> 0 based
1871  // Connectivity array is shifted by where the gather set vertices start
1872  conn_arr_gather_set_cells[cell_vert] = gather_set_start_vertex + gather_set_vert_idx;
1873  }
1874 
1875  return MB_SUCCESS;
1876 }

References moab::NCHelper::_fileId, moab::NCHelper::_readNC, moab::Interface::add_entities(), moab::ReadUtilIface::get_element_connect(), maxEdgesPerCell, MB_CHK_SET_ERR, MB_SET_ERR, MB_SUCCESS, moab::ReadNC::mbImpl, MBPOLYGON, NCDF_SIZE, moab::UcdNCHelper::nCells, NCFUNC, NCFUNCG, and moab::ReadNC::readMeshIface.

Referenced by create_mesh().

◆ create_padded_local_cells()

ErrorCode moab::NCHelperMPAS::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 1471 of file NCHelperMPAS.cpp.

1474 {
1475  Interface*& mbImpl = _readNC->mbImpl;
1476  Tag& mGlobalIdTag = _readNC->mGlobalIdTag;
1477 
1478  // Only one group of cells (each cell is represented by a polygon with maxEdgesPerCell edges)
1479  numCellGroups = 1;
1480 
1481  // Create cells for this cell group
1482  EntityHandle start_element;
1483  EntityHandle* conn_arr_local_cells = NULL;
1485  nLocalCells, maxEdgesPerCell, MBPOLYGON, 0, start_element, conn_arr_local_cells,
1486  // Might have to create gather mesh later
1488  "Failed to create local cells" );
1489  faces.insert( start_element, start_element + nLocalCells - 1 );
1490 
1491  // Add local cells to current file set
1492  Range local_cells_range( start_element, start_element + nLocalCells - 1 );
1493  MB_CHK_SET_ERR( _readNC->mbImpl->add_entities( _fileSet, local_cells_range ),
1494  "Failed to add local cells to current file set" );
1495 
1496  // Get ptr to GID memory for local cells
1497  int count = 0;
1498  void* data = NULL;
1499  MB_CHK_SET_ERR( mbImpl->tag_iterate( mGlobalIdTag, local_cells_range.begin(), local_cells_range.end(), count,
1500  data ),
1501  "Failed to iterate global id tag on local cells" );
1502  assert( count == nLocalCells );
1503  int* gid_data = (int*)data;
1504  std::copy( localGidCells.begin(), localGidCells.end(), gid_data );
1505 
1506  // Set connectivity array with proper local vertices handles
1507  // vertices_on_local_cells array was already corrected to have the last vertices padded
1508  // no need for extra checks considering
1509  for( int local_cell_idx = 0; local_cell_idx < nLocalCells; local_cell_idx++ )
1510  {
1511  for( int i = 0; i < maxEdgesPerCell; i++ )
1512  {
1513  EntityHandle global_vert_idx =
1514  vertices_on_local_cells[local_cell_idx * maxEdgesPerCell + i]; // Global vertex index, 1 based
1515  int local_vert_idx = localGidVerts.index( global_vert_idx ); // Local vertex index, 0 based
1516  assert( local_vert_idx != -1 );
1517  conn_arr_local_cells[local_cell_idx * maxEdgesPerCell + i] = start_vertex + local_vert_idx;
1518  }
1519  }
1520 
1521  return MB_SUCCESS;
1522 }

References moab::NCHelper::_fileSet, moab::NCHelper::_readNC, moab::Interface::add_entities(), moab::Range::begin(), createGatherSet, 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::nCells, moab::UcdNCHelper::nLocalCells, numCellGroups, moab::ReadNC::readMeshIface, and moab::Interface::tag_iterate().

Referenced by create_mesh().

◆ get_mesh_type_name()

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

Implementation of NCHelper::get_mesh_type_name()

Implements moab::NCHelper.

Definition at line 34 of file NCHelperMPAS.hpp.

35  {
36  return "MPAS";
37  }

◆ init_mesh_vals()

ErrorCode moab::NCHelperMPAS::init_mesh_vals ( )
privatevirtual

Implementation of NCHelper::init_mesh_vals()

Implements moab::NCHelper.

Definition at line 78 of file NCHelperMPAS.cpp.

79 {
80  std::vector< std::string >& dimNames = _readNC->dimNames;
81  std::vector< int >& dimLens = _readNC->dimLens;
82  std::map< std::string, ReadNC::VarData >& varInfo = _readNC->varInfo;
83 
84  int idx;
85  std::vector< std::string >::iterator vit;
86 
87  // Get max edges per cell reported in the MPAS file header
88  if( ( vit = std::find( dimNames.begin(), dimNames.end(), "maxEdges" ) ) != dimNames.end() )
89  {
90  idx = vit - dimNames.begin();
91  maxEdgesPerCell = dimLens[idx];
93  {
95  "maxEdgesPerCell read from the MPAS file header has exceeded " << DEFAULT_MAX_EDGES_PER_CELL );
96  }
97  }
98 
99  // Look for time dimension
100  idx = -1;
101  if( ( vit = std::find( dimNames.begin(), dimNames.end(), "Time" ) ) != dimNames.end() )
102  idx = vit - dimNames.begin();
103  else if( ( vit = std::find( dimNames.begin(), dimNames.end(), "time" ) ) != dimNames.end() )
104  idx = vit - dimNames.begin();
105  else
106  {
107  tDim = -1;
108  }
109  if( idx >= 0 )
110  {
111  tDim = idx;
112  nTimeSteps = dimLens[idx];
113  }
114  else
115  nTimeSteps = 0;
116 
117  // Get number of cells
118  if( ( vit = std::find( dimNames.begin(), dimNames.end(), "nCells" ) ) != dimNames.end() )
119  idx = vit - dimNames.begin();
120  else
121  {
122  MB_SET_ERR( MB_FAILURE, "Couldn't find 'nCells' dimension" );
123  }
124  cDim = idx;
125  nCells = dimLens[idx];
126 
127  // Get number of edges
128  if( ( vit = std::find( dimNames.begin(), dimNames.end(), "nEdges" ) ) != dimNames.end() )
129  idx = vit - dimNames.begin();
130  else
131  {
132  MB_SET_ERR( MB_FAILURE, "Couldn't find 'nEdges' dimension" );
133  }
134  eDim = idx;
135  nEdges = dimLens[idx];
136 
137  // Get number of vertices
138  vDim = -1;
139  if( ( vit = std::find( dimNames.begin(), dimNames.end(), "nVertices" ) ) != dimNames.end() )
140  idx = vit - dimNames.begin();
141  else
142  {
143  MB_SET_ERR( MB_FAILURE, "Couldn't find 'nVertices' dimension" );
144  }
145  vDim = idx;
146  nVertices = dimLens[idx];
147 
148  // Get number of vertex levels
149  if( ( vit = std::find( dimNames.begin(), dimNames.end(), "nVertLevels" ) ) != dimNames.end() )
150  idx = vit - dimNames.begin();
151  else
152  {
153  std::cerr << "Warning: dimension nVertLevels not found in header.\nThe file may contain "
154  "just the mesh"
155  << std::endl;
156  }
157  levDim = idx;
158  nLevels = dimLens[idx];
159 
160  // Dimension indices for other optional levels
161  std::vector< unsigned int > opt_lev_dims;
162 
163  // Get index of vertex levels P1
164  if( ( vit = std::find( dimNames.begin(), dimNames.end(), "nVertLevelsP1" ) ) != dimNames.end() )
165  {
166  idx = vit - dimNames.begin();
167  opt_lev_dims.push_back( idx );
168  }
169 
170  // Get index of vertex levels P2
171  if( ( vit = std::find( dimNames.begin(), dimNames.end(), "nVertLevelsP2" ) ) != dimNames.end() )
172  {
173  idx = vit - dimNames.begin();
174  opt_lev_dims.push_back( idx );
175  }
176 
177  // Get index of soil levels
178  if( ( vit = std::find( dimNames.begin(), dimNames.end(), "nSoilLevels" ) ) != dimNames.end() )
179  {
180  idx = vit - dimNames.begin();
181  opt_lev_dims.push_back( idx );
182  }
183 
184  std::map< std::string, ReadNC::VarData >::iterator vmit;
185 
186  // Store time coordinate values in tVals
187  if( nTimeSteps > 0 )
188  {
189  // Note, two possible types for xtime variable: double(Time) or char(Time, StrLen)
190  if( ( vmit = varInfo.find( "xtime" ) ) != varInfo.end() && ( *vmit ).second.varDims.size() == 1 )
191  {
192  // If xtime variable is double type, read time coordinate values to tVals
193  MB_CHK_SET_ERR( read_coordinate( "xtime", 0, nTimeSteps - 1, tVals ), "Trouble reading 'xtime' variable" );
194  }
195  else
196  {
197  // If xtime variable does not exist, or it is string type, set dummy values to tVals
198  for( int t = 0; t < nTimeSteps; t++ )
199  tVals.push_back( (double)t );
200  }
201  }
202 
203  // For each variable, determine the entity location type and number of levels
204  for( vmit = varInfo.begin(); vmit != varInfo.end(); ++vmit )
205  {
206  ReadNC::VarData& vd = ( *vmit ).second;
207 
208  // Default entLoc is ENTLOCSET
209  if( std::find( vd.varDims.begin(), vd.varDims.end(), tDim ) != vd.varDims.end() )
210  {
211  if( std::find( vd.varDims.begin(), vd.varDims.end(), vDim ) != vd.varDims.end() )
212  vd.entLoc = ReadNC::ENTLOCVERT;
213  else if( std::find( vd.varDims.begin(), vd.varDims.end(), eDim ) != vd.varDims.end() )
214  vd.entLoc = ReadNC::ENTLOCEDGE;
215  else if( std::find( vd.varDims.begin(), vd.varDims.end(), cDim ) != vd.varDims.end() )
216  vd.entLoc = ReadNC::ENTLOCFACE;
217  }
218 
219  // Default numLev is 0
220  if( std::find( vd.varDims.begin(), vd.varDims.end(), levDim ) != vd.varDims.end() )
221  vd.numLev = nLevels;
222  else
223  {
224  // If nVertLevels dimension is not found, try other optional levels such as
225  // nVertLevelsP1
226  for( unsigned int i = 0; i < opt_lev_dims.size(); i++ )
227  {
228  if( std::find( vd.varDims.begin(), vd.varDims.end(), opt_lev_dims[i] ) != vd.varDims.end() )
229  {
230  vd.numLev = dimLens[opt_lev_dims[i]];
231  break;
232  }
233  }
234  }
235 
236  // Hack: ignore variables with more than 3 dimensions, e.g. tracers(Time, nCells,
237  // nVertLevels, nTracers)
238  if( vd.varDims.size() > 3 ) ignoredVarNames.insert( vd.varName );
239  }
240 
241  // Hack: create dummy variables for dimensions (like nCells) with no corresponding coordinate
242  // variables
243  MB_CHK_SET_ERR( create_dummy_variables(), "Failed to create dummy variables" );
244 
245  return MB_SUCCESS;
246 }

References moab::NCHelper::_readNC, moab::UcdNCHelper::cDim, moab::NCHelper::create_dummy_variables(), moab::DEFAULT_MAX_EDGES_PER_CELL, moab::ReadNC::dimLens, moab::ReadNC::dimNames, moab::UcdNCHelper::eDim, moab::ReadNC::VarData::entLoc, moab::ReadNC::ENTLOCEDGE, moab::ReadNC::ENTLOCFACE, moab::ReadNC::ENTLOCVERT, moab::NCHelper::ignoredVarNames, moab::NCHelper::levDim, maxEdgesPerCell, MB_CHK_SET_ERR, MB_INVALID_SIZE, MB_SET_ERR, MB_SUCCESS, moab::UcdNCHelper::nCells, moab::UcdNCHelper::nEdges, moab::NCHelper::nLevels, moab::NCHelper::nTimeSteps, moab::ReadNC::VarData::numLev, moab::UcdNCHelper::nVertices, moab::NCHelper::read_coordinate(), moab::NCHelper::tDim, moab::NCHelper::tVals, moab::ReadNC::VarData::varDims, moab::ReadNC::varInfo, moab::ReadNC::VarData::varName, and moab::UcdNCHelper::vDim.

◆ read_ucd_variables_to_nonset()

ErrorCode moab::NCHelperMPAS::read_ucd_variables_to_nonset ( std::vector< ReadNC::VarData > &  vdatas,
std::vector< int > &  tstep_nums 
)
privatevirtual

Implementation of UcdNCHelper::read_ucd_variables_to_nonset()

Implements moab::UcdNCHelper.

Definition at line 866 of file NCHelperMPAS.cpp.

868 {
869  Interface*& mbImpl = _readNC->mbImpl;
870  bool& noEdges = _readNC->noEdges;
871  DebugOutput& dbgOut = _readNC->dbgOut;
872 
874  "Trouble allocating space to read non-set variables" );
875 
876  // Finally, read into that space
877  int success;
878  Range* pLocalGid = NULL;
879 
880  for( unsigned int i = 0; i < vdatas.size(); i++ )
881  {
882  // Skip edge variables, if specified by the read options
883  if( noEdges && vdatas[i].entLoc == ReadNC::ENTLOCEDGE ) continue;
884 
885  switch( vdatas[i].entLoc )
886  {
887  case ReadNC::ENTLOCVERT:
888  pLocalGid = &localGidVerts;
889  break;
890  case ReadNC::ENTLOCFACE:
891  pLocalGid = &localGidCells;
892  break;
893  case ReadNC::ENTLOCEDGE:
894  pLocalGid = &localGidEdges;
895  break;
896  default:
897  MB_SET_ERR( MB_FAILURE, "Unexpected entity location type for variable " << vdatas[i].varName );
898  }
899 
900  std::size_t sz = vdatas[i].sz;
901 
902  for( unsigned int t = 0; t < tstep_nums.size(); t++ )
903  {
904  // Set readStart for each timestep along time dimension
905  vdatas[i].readStarts[0] = tstep_nums[t];
906 
907  switch( vdatas[i].varDataType )
908  {
909  case NC_FLOAT:
910  case NC_DOUBLE: {
911  // Read float as double
912  std::vector< double > tmpdoubledata( sz );
913 
914  // In the case of ucd mesh, and on multiple proc,
915  // we need to read as many times as subranges we have in the
916  // localGid range;
917  // basically, we have to give a different point
918  // for data to start, for every subrange :(
919  size_t indexInDoubleArray = 0;
920  size_t ic = 0;
921  for( Range::pair_iterator pair_iter = pLocalGid->pair_begin(); pair_iter != pLocalGid->pair_end();
922  ++pair_iter, ic++ )
923  {
924  EntityHandle starth = pair_iter->first;
925  EntityHandle endh = pair_iter->second; // Inclusive
926  vdatas[i].readStarts[1] = (NCDF_SIZE)( starth - 1 );
927  vdatas[i].readCounts[1] = (NCDF_SIZE)( endh - starth + 1 );
928 
929  success = NCFUNCAG( _vara_double )( _fileId, vdatas[i].varId, &( vdatas[i].readStarts[0] ),
930  &( vdatas[i].readCounts[0] ),
931  &( tmpdoubledata[indexInDoubleArray] ) );
932  if( success )
933  MB_SET_ERR( MB_FAILURE,
934  "Failed to read double data in a loop for variable " << vdatas[i].varName );
935  // We need to increment the index in double array for the
936  // next subrange
937  indexInDoubleArray += ( endh - starth + 1 ) * 1 * vdatas[i].numLev;
938  }
939  assert( ic == pLocalGid->psize() );
940 
941  if( vdatas[i].entLoc == ReadNC::ENTLOCFACE && numCellGroups > 1 )
942  {
943  // For a cell variable that is NOT on one contiguous chunk of faces,
944  // allocate tag space for each cell group, and utilize cellHandleToGlobalID
945  // map to read tag data
947  while( iter != facesOwned.end() )
948  {
949  int count;
950  void* ptr;
951  MB_CHK_SET_ERR( mbImpl->tag_iterate( vdatas[i].varTags[t], iter, facesOwned.end(), count,
952  ptr ),
953  "Failed to iterate tag on owned faces" );
954 
955  for( int j = 0; j < count; j++ )
956  {
957  int global_cell_idx =
958  cellHandleToGlobalID[*( iter + j )]; // Global cell index, 1 based
959  int local_cell_idx =
960  localGidCells.index( global_cell_idx ); // Local cell index, 0 based
961  assert( local_cell_idx != -1 );
962  for( int level = 0; level < vdatas[i].numLev; level++ )
963  ( (double*)ptr )[j * vdatas[i].numLev + level] =
964  tmpdoubledata[local_cell_idx * vdatas[i].numLev + level];
965  }
966 
967  iter += count;
968  }
969  }
970  else
971  {
972  void* data = vdatas[i].varDatas[t];
973  for( std::size_t idx = 0; idx != tmpdoubledata.size(); idx++ )
974  ( (double*)data )[idx] = tmpdoubledata[idx];
975  }
976 
977  break;
978  }
979  default:
980  MB_SET_ERR( MB_FAILURE, "Unexpected data type for variable " << vdatas[i].varName );
981  }
982  }
983  }
984 
985  // Debug output, if requested
986  if( 1 == dbgOut.get_verbosity() )
987  {
988  dbgOut.printf( 1, "Read variables: %s", vdatas.begin()->varName.c_str() );
989  for( unsigned int i = 1; i < vdatas.size(); i++ )
990  dbgOut.printf( 1, ", %s ", vdatas[i].varName.c_str() );
991  dbgOut.tprintf( 1, "\n" );
992  }
993 
994  return MB_SUCCESS;
995 }

References moab::NCHelper::_fileId, moab::NCHelper::_readNC, moab::Range::begin(), cellHandleToGlobalID, moab::ReadNC::dbgOut, moab::Range::end(), moab::ReadNC::ENTLOCEDGE, moab::ReadNC::ENTLOCFACE, moab::ReadNC::ENTLOCVERT, facesOwned, moab::DebugOutput::get_verbosity(), moab::Range::index(), moab::UcdNCHelper::localGidCells, moab::UcdNCHelper::localGidEdges, moab::UcdNCHelper::localGidVerts, MB_CHK_SET_ERR, MB_SET_ERR, MB_SUCCESS, moab::ReadNC::mbImpl, NCDF_SIZE, NCFUNCAG, moab::ReadNC::noEdges, numCellGroups, moab::Range::pair_begin(), moab::Range::pair_end(), moab::DebugOutput::printf(), moab::Range::psize(), read_ucd_variables_to_nonset_allocate(), moab::Interface::tag_iterate(), and moab::DebugOutput::tprintf().

◆ read_ucd_variables_to_nonset_allocate()

ErrorCode moab::NCHelperMPAS::read_ucd_variables_to_nonset_allocate ( std::vector< ReadNC::VarData > &  vdatas,
std::vector< int > &  tstep_nums 
)
privatevirtual

Implementation of UcdNCHelper::read_ucd_variables_to_nonset_allocate()

Implements moab::UcdNCHelper.

Definition at line 580 of file NCHelperMPAS.cpp.

582 {
583  Interface*& mbImpl = _readNC->mbImpl;
584  std::vector< int >& dimLens = _readNC->dimLens;
585  bool& noEdges = _readNC->noEdges;
586  DebugOutput& dbgOut = _readNC->dbgOut;
587 
588  Range* range = NULL;
589 
590  // Get vertices
591  Range verts;
592  MB_CHK_SET_ERR( mbImpl->get_entities_by_dimension( _fileSet, 0, verts ),
593  "Trouble getting vertices in current file set" );
594  assert( "Should only have a single vertex subrange, since they were read in one shot" && verts.psize() == 1 );
595 
596  // Get edges
597  Range edges;
598  MB_CHK_SET_ERR( mbImpl->get_entities_by_dimension( _fileSet, 1, edges ),
599  "Trouble getting edges in current file set" );
600 
601  // Get faces
602  Range faces;
603  MB_CHK_SET_ERR( mbImpl->get_entities_by_dimension( _fileSet, 2, faces ),
604  "Trouble getting faces in current file set" );
605  // Note, for MPAS faces.psize() can be more than 1
606 
607 #ifdef MOAB_HAVE_MPI
608  bool& isParallel = _readNC->isParallel;
609  if( isParallel )
610  {
611  ParallelComm*& myPcomm = _readNC->myPcomm;
612  MB_CHK_SET_ERR( myPcomm->filter_pstatus( faces, PSTATUS_NOT_OWNED, PSTATUS_NOT, -1, &facesOwned ),
613  "Trouble getting owned faces in current file set" );
614  }
615  else
616  facesOwned = faces; // not running in parallel, but still with MPI
617 #else
618  facesOwned = faces;
619 #endif
620 
621  for( unsigned int i = 0; i < vdatas.size(); i++ )
622  {
623  // Skip edge variables, if specified by the read options
624  if( noEdges && vdatas[i].entLoc == ReadNC::ENTLOCEDGE ) continue;
625 
626  // Support non-set variables with 3 dimensions like (Time, nCells, nVertLevels), or
627  // 2 dimensions like (Time, nCells)
628  assert( 3 == vdatas[i].varDims.size() || 2 == vdatas[i].varDims.size() );
629 
630  // For a non-set variable, time should be the first dimension
631  assert( tDim == vdatas[i].varDims[0] );
632 
633  // Set up readStarts and readCounts
634  vdatas[i].readStarts.resize( 3 );
635  vdatas[i].readCounts.resize( 3 );
636 
637  // First: Time
638  vdatas[i].readStarts[0] = 0; // This value is timestep dependent, will be set later
639  vdatas[i].readCounts[0] = 1;
640 
641  // Next: nVertices / nCells / nEdges
642  switch( vdatas[i].entLoc )
643  {
644  case ReadNC::ENTLOCVERT:
645  // Vertices
646  // Start from the first localGidVerts
647  // Actually, this will be reset later on in a loop
648  vdatas[i].readStarts[1] = localGidVerts[0] - 1;
649  vdatas[i].readCounts[1] = nLocalVertices;
650  range = &verts;
651  break;
652  case ReadNC::ENTLOCFACE:
653  // Faces
654  // Start from the first localGidCells
655  // Actually, this will be reset later on in a loop
656  vdatas[i].readStarts[1] = localGidCells[0] - 1;
657  vdatas[i].readCounts[1] = nLocalCells;
658  range = &facesOwned;
659  break;
660  case ReadNC::ENTLOCEDGE:
661  // Edges
662  // Start from the first localGidEdges
663  // Actually, this will be reset later on in a loop
664  vdatas[i].readStarts[1] = localGidEdges[0] - 1;
665  vdatas[i].readCounts[1] = nLocalEdges;
666  range = &edges;
667  break;
668  default:
669  MB_SET_ERR( MB_FAILURE, "Unexpected entity location type for variable " << vdatas[i].varName );
670  }
671 
672  // Finally: nVertLevels or other optional levels, it is possible that there is no
673  // level dimension (numLev is 0) for this non-set variable, e.g. (Time, nCells)
674  if( vdatas[i].numLev < 1 ) vdatas[i].numLev = 1;
675  vdatas[i].readStarts[2] = 0;
676  vdatas[i].readCounts[2] = vdatas[i].numLev;
677 
678  // Get variable size
679  vdatas[i].sz = 1;
680  for( std::size_t idx = 0; idx != 3; idx++ )
681  vdatas[i].sz *= vdatas[i].readCounts[idx];
682 
683  for( unsigned int t = 0; t < tstep_nums.size(); t++ )
684  {
685  dbgOut.tprintf( 2, "Reading variable %s, time step %d\n", vdatas[i].varName.c_str(), tstep_nums[t] );
686 
687  if( tstep_nums[t] >= dimLens[tDim] )
688  {
689  MB_SET_ERR( MB_INDEX_OUT_OF_RANGE, "Wrong value for timestep number " << tstep_nums[t] );
690  }
691 
692  // Get the tag to read into
693  if( !vdatas[i].varTags[t] )
694  {
695  MB_CHK_SET_ERR( get_tag_to_nonset( vdatas[i], tstep_nums[t], vdatas[i].varTags[t], vdatas[i].numLev ),
696  "Trouble getting tag for variable " << vdatas[i].varName );
697  }
698 
699  // Get ptr to tag space
700  if( vdatas[i].entLoc == ReadNC::ENTLOCFACE && numCellGroups > 1 )
701  {
702  // For a cell variable that is NOT on one contiguous chunk of faces, defer its tag
703  // space allocation
704  vdatas[i].varDatas[t] = NULL;
705  }
706  else
707  {
708  assert( 1 == range->psize() );
709  void* data;
710  int count;
711  MB_CHK_SET_ERR( mbImpl->tag_iterate( vdatas[i].varTags[t], range->begin(), range->end(), count, data ),
712  "Failed to iterate tag for variable " << vdatas[i].varName );
713  assert( (unsigned)count == range->size() );
714  vdatas[i].varDatas[t] = data;
715  }
716  }
717  }
718 
719  return MB_SUCCESS;
720 }

References moab::NCHelper::_fileSet, moab::NCHelper::_readNC, moab::Range::begin(), moab::ReadNC::dbgOut, moab::ReadNC::dimLens, moab::Range::end(), moab::ReadNC::ENTLOCEDGE, moab::ReadNC::ENTLOCFACE, moab::ReadNC::ENTLOCVERT, facesOwned, moab::ParallelComm::filter_pstatus(), moab::Interface::get_entities_by_dimension(), moab::NCHelper::get_tag_to_nonset(), moab::ReadNC::isParallel, moab::UcdNCHelper::localGidCells, moab::UcdNCHelper::localGidEdges, moab::UcdNCHelper::localGidVerts, MB_CHK_SET_ERR, MB_INDEX_OUT_OF_RANGE, MB_SET_ERR, MB_SUCCESS, moab::ReadNC::mbImpl, moab::UcdNCHelper::nLocalCells, moab::UcdNCHelper::nLocalEdges, moab::UcdNCHelper::nLocalVertices, moab::ReadNC::noEdges, numCellGroups, moab::Range::psize(), PSTATUS_NOT, PSTATUS_NOT_OWNED, moab::Range::size(), moab::Interface::tag_iterate(), moab::NCHelper::tDim, and moab::DebugOutput::tprintf().

Referenced by read_ucd_variables_to_nonset().

Member Data Documentation

◆ cellHandleToGlobalID

std::map< EntityHandle, int > moab::NCHelperMPAS::cellHandleToGlobalID
private

◆ createGatherSet

bool moab::NCHelperMPAS::createGatherSet
private

◆ facesOwned

Range moab::NCHelperMPAS::facesOwned
private

◆ maxEdgesPerCell

◆ numCellGroups


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