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

Child helper class for HOMME grid (CAM_SE) More...

#include <NCHelperHOMME.hpp>

+ Inheritance diagram for moab::NCHelperHOMME:
+ Collaboration diagram for moab::NCHelperHOMME:

Public Member Functions

 NCHelperHOMME (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, int fileId)
 
- 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...
 

Private Attributes

int _spectralOrder
 
int connectId
 
bool isConnFile
 

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 HOMME grid (CAM_SE)

Definition at line 18 of file NCHelperHOMME.hpp.

Constructor & Destructor Documentation

◆ NCHelperHOMME()

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

Definition at line 11 of file NCHelperHOMME.cpp.

12  : UcdNCHelper( readNC, fileId, opts, fileSet ), _spectralOrder( -1 ), connectId( -1 ), isConnFile( false )
13 {
14  // Calculate spectral order
15  std::map< std::string, ReadNC::AttData >::iterator attIt = readNC->globalAtts.find( "np" );
16  if( attIt != readNC->globalAtts.end() )
17  {
18  int success = NCFUNC( get_att_int )( readNC->fileId, attIt->second.attVarId, attIt->second.attName.c_str(),
19  &_spectralOrder );
20  if( 0 == success ) _spectralOrder--; // Spectral order is one less than np
21  }
22  else
23  {
24  // As can_read_file() returns true and there is no global attribute "np", it should be a
25  // connectivity file
26  isConnFile = true;
27  _spectralOrder = 3; // Assume np is 4
28  }
29 }

References _spectralOrder, moab::ReadNC::fileId, moab::ReadNC::globalAtts, isConnFile, and NCFUNC.

Member Function Documentation

◆ can_read_file()

bool moab::NCHelperHOMME::can_read_file ( ReadNC readNC,
int  fileId 
)
static

Definition at line 31 of file NCHelperHOMME.cpp.

32 {
33  // If global attribute "np" exists then it should be the HOMME grid
34  if( readNC->globalAtts.find( "np" ) != readNC->globalAtts.end() )
35  {
36  // Make sure it is CAM grid
37  std::map< std::string, ReadNC::AttData >::iterator attIt = readNC->globalAtts.find( "source" );
38  if( attIt == readNC->globalAtts.end() ) return false;
39  unsigned int sz = attIt->second.attLen;
40  std::string att_data;
41  att_data.resize( sz + 1 );
42  att_data[sz] = '\000';
43  int success =
44  NCFUNC( get_att_text )( fileId, attIt->second.attVarId, attIt->second.attName.c_str(), &att_data[0] );
45  if( success ) return false;
46  if( att_data.find( "CAM" ) == std::string::npos ) return false;
47 
48  return true;
49  }
50  else
51  {
52  // If dimension names "ncol" AND "ncorners" AND "ncells" exist, then it should be the HOMME
53  // connectivity file In this case, the mesh can still be created
54  std::vector< std::string >& dimNames = readNC->dimNames;
55  if( ( std::find( dimNames.begin(), dimNames.end(), std::string( "ncol" ) ) != dimNames.end() ) &&
56  ( std::find( dimNames.begin(), dimNames.end(), std::string( "ncorners" ) ) != dimNames.end() ) &&
57  ( std::find( dimNames.begin(), dimNames.end(), std::string( "ncells" ) ) != dimNames.end() ) )
58  return true;
59  }
60 
61  return false;
62 }

References moab::ReadNC::dimNames, moab::ReadNC::globalAtts, and NCFUNC.

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

◆ check_existing_mesh()

ErrorCode moab::NCHelperHOMME::check_existing_mesh ( )
privatevirtual

Implementation of NCHelper::check_existing_mesh()

Implements moab::NCHelper.

Definition at line 222 of file NCHelperHOMME.cpp.

223 {
224  Interface*& mbImpl = _readNC->mbImpl;
225  Tag& mGlobalIdTag = _readNC->mGlobalIdTag;
226  bool& noMesh = _readNC->noMesh;
227 
228  if( noMesh && localGidVerts.empty() )
229  {
230  // We need to populate localGidVerts range with the gids of vertices from current file set
231  // localGidVerts is important in reading the variable data into the nodes
232  // Also, for our purposes, localGidVerts is truly the GLOBAL_ID tag data, not other
233  // file_id tags that could get passed around in other scenarios for parallel reading
234 
235  // Get all vertices from current file set (it is the input set in no_mesh scenario)
236  Range local_verts;
237  MB_CHK_SET_ERR( mbImpl->get_entities_by_dimension( _fileSet, 0, local_verts ),
238  "Trouble getting local vertices in current file set" );
239 
240  if( !local_verts.empty() )
241  {
242  std::vector< int > gids( local_verts.size() );
243 
244  // !IMPORTANT : this has to be the GLOBAL_ID tag
245  MB_CHK_SET_ERR( mbImpl->tag_get_data( mGlobalIdTag, local_verts, &gids[0] ),
246  "Trouble getting local gid values of vertices" );
247 
248  // Restore localGidVerts
249  std::copy( gids.rbegin(), gids.rend(), range_inserter( localGidVerts ) );
251  }
252  }
253 
254  return MB_SUCCESS;
255 }

References moab::NCHelper::_fileSet, moab::NCHelper::_readNC, moab::Range::empty(), moab::Interface::get_entities_by_dimension(), moab::UcdNCHelper::localGidVerts, MB_CHK_SET_ERR, MB_SUCCESS, moab::ReadNC::mbImpl, moab::ReadNC::mGlobalIdTag, moab::UcdNCHelper::nLocalVertices, moab::ReadNC::noMesh, moab::Range::size(), and moab::Interface::tag_get_data().

◆ create_mesh()

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

Implementation of NCHelper::create_mesh()

Implements moab::NCHelper.

Definition at line 257 of file NCHelperHOMME.cpp.

258 {
259  Interface*& mbImpl = _readNC->mbImpl;
260  std::string& fileName = _readNC->fileName;
261  Tag& mGlobalIdTag = _readNC->mGlobalIdTag;
262  const Tag*& mpFileIdTag = _readNC->mpFileIdTag;
263  DebugOutput& dbgOut = _readNC->dbgOut;
264  bool& spectralMesh = _readNC->spectralMesh;
265  int& gatherSetRank = _readNC->gatherSetRank;
266  int& trivialPartitionShift = _readNC->trivialPartitionShift;
267 
268  int rank = 0;
269  int procs = 1;
270 #ifdef MOAB_HAVE_MPI
271  bool& isParallel = _readNC->isParallel;
272  if( isParallel )
273  {
274  ParallelComm*& myPcomm = _readNC->myPcomm;
275  rank = myPcomm->proc_config().proc_rank();
276  procs = myPcomm->proc_config().proc_size();
277  }
278 #endif
279 
280  int success = 0;
281 
282  // Need to get/read connectivity data before creating elements
283  std::string conn_fname;
284 
285  if( isConnFile )
286  {
287  // Connectivity file has already been read
289  }
290  else
291  {
292  // Try to open the connectivity file through CONN option, if used
293  if( MB_SUCCESS != _opts.get_str_option( "CONN", conn_fname ) )
294  {
295  // Default convention for reading HOMME is a file HommeMapping.nc in same dir as data
296  // file
297  conn_fname = std::string( fileName );
298  size_t idx = conn_fname.find_last_of( "/" );
299  if( idx != std::string::npos )
300  conn_fname = conn_fname.substr( 0, idx ).append( "/HommeMapping.nc" );
301  else
302  conn_fname = "HommeMapping.nc";
303  }
304 #ifdef MOAB_HAVE_PNETCDF
305 #ifdef MOAB_HAVE_MPI
306  if( isParallel )
307  {
308  ParallelComm*& myPcomm = _readNC->myPcomm;
309  success =
310  NCFUNC( open )( myPcomm->proc_config().proc_comm(), conn_fname.c_str(), 0, MPI_INFO_NULL, &connectId );
311  }
312  else
313  success = NCFUNC( open )( MPI_COMM_SELF, conn_fname.c_str(), 0, MPI_INFO_NULL, &connectId );
314 #endif
315 #else
316  success = NCFUNC( open )( conn_fname.c_str(), 0, &connectId );
317 #endif
318  if( success ) MB_SET_ERR( MB_FAILURE, "Failed on open" );
319  }
320 
321  std::vector< std::string > conn_names;
322  std::vector< int > conn_vals;
323  MB_CHK_SET_ERR( _readNC->get_dimensions( connectId, conn_names, conn_vals ),
324  "Failed to get dimensions for connectivity" );
325 
326  // Read connectivity into temporary variable
327  int num_fine_quads = 0;
328  int num_coarse_quads = 0;
329  int start_idx = 0;
330  std::vector< std::string >::iterator vit;
331  int idx = 0;
332  if( ( vit = std::find( conn_names.begin(), conn_names.end(), "ncells" ) ) != conn_names.end() )
333  idx = vit - conn_names.begin();
334  else if( ( vit = std::find( conn_names.begin(), conn_names.end(), "ncenters" ) ) != conn_names.end() )
335  idx = vit - conn_names.begin();
336  else
337  {
338  MB_SET_ERR( MB_FAILURE, "Failed to get number of quads" );
339  }
340  int num_quads = conn_vals[idx];
341  if( !isConnFile && num_quads != nCells )
342  {
343  dbgOut.tprintf( 1,
344  "Warning: number of quads from %s and cells from %s are inconsistent; "
345  "num_quads = %d, nCells = %d.\n",
346  conn_fname.c_str(), fileName.c_str(), num_quads, nCells );
347  }
348 
349  // Get the connectivity into tmp_conn2 and permute into tmp_conn
350  int cornerVarId;
351  success = NCFUNC( inq_varid )( connectId, "element_corners", &cornerVarId );
352  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of 'element_corners'" );
353  NCDF_SIZE tmp_starts[2] = { 0, 0 };
354  NCDF_SIZE tmp_counts[2] = { 4, static_cast< NCDF_SIZE >( num_quads ) };
355  std::vector< int > tmp_conn( 4 * num_quads ), tmp_conn2( 4 * num_quads );
356  success = NCFUNCAG( _vara_int )( connectId, cornerVarId, tmp_starts, tmp_counts, &tmp_conn2[0] );
357  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get temporary connectivity" );
358  if( isConnFile )
359  {
360  // This data/connectivity file will be closed later in ReadNC::load_file()
361  }
362  else
363  {
364  success = NCFUNC( close )( connectId );
365  if( success ) MB_SET_ERR( MB_FAILURE, "Failed on close" );
366  }
367  // Permute the connectivity
368  for( int i = 0; i < num_quads; i++ )
369  {
370  tmp_conn[4 * i] = tmp_conn2[i];
371  tmp_conn[4 * i + 1] = tmp_conn2[i + 1 * num_quads];
372  tmp_conn[4 * i + 2] = tmp_conn2[i + 2 * num_quads];
373  tmp_conn[4 * i + 3] = tmp_conn2[i + 3 * num_quads];
374  }
375 
376  // Need to know whether we'll be creating gather mesh later, to make sure
377  // we allocate enough space in one shot
378  bool create_gathers = false;
379  if( rank == gatherSetRank ) create_gathers = true;
380 
381  // Shift rank to obtain a rotated trivial partition
382  int shifted_rank = rank;
383  if( procs >= 2 && trivialPartitionShift > 0 ) shifted_rank = ( rank + trivialPartitionShift ) % procs;
384 
385  // Compute the number of local quads, accounting for coarse or fine representation
386  // spectral_unit is the # fine quads per coarse quad, or spectralOrder^2
387  int spectral_unit = ( spectralMesh ? _spectralOrder * _spectralOrder : 1 );
388  // num_coarse_quads is the number of quads instantiated in MOAB; if !spectralMesh,
389  // num_coarse_quads = num_fine_quads
390  num_coarse_quads = int( std::floor( 1.0 * num_quads / ( spectral_unit * procs ) ) );
391  // start_idx is the starting index in the HommeMapping connectivity list for this proc, before
392  // converting to coarse quad representation
393  start_idx = 4 * shifted_rank * num_coarse_quads * spectral_unit;
394  // iextra = # coarse quads extra after equal split over procs
395  int iextra = num_quads % ( procs * spectral_unit );
396  if( shifted_rank < iextra ) num_coarse_quads++;
397  start_idx += 4 * spectral_unit * std::min( shifted_rank, iextra );
398  // num_fine_quads is the number of quads in the connectivity list in HommeMapping file assigned
399  // to this proc
400  num_fine_quads = spectral_unit * num_coarse_quads;
401 
402  // Now create num_coarse_quads
403  EntityHandle* conn_arr;
404  EntityHandle start_vertex;
405  Range tmp_range;
406 
407  // Read connectivity into that space
408  EntityHandle* sv_ptr = NULL;
409  EntityHandle start_quad;
410  SpectralMeshTool smt( mbImpl, _spectralOrder );
411  if( !spectralMesh )
412  {
414  num_coarse_quads, 4, MBQUAD, 0, start_quad, conn_arr,
415  // Might have to create gather mesh later
416  ( create_gathers ? num_coarse_quads + num_quads : num_coarse_quads ) ),
417  "Failed to create local quads" );
418  tmp_range.insert( start_quad, start_quad + num_coarse_quads - 1 );
419  int* tmp_conn_end = ( &tmp_conn[start_idx + 4 * num_fine_quads - 1] ) + 1;
420  std::copy( &tmp_conn[start_idx], tmp_conn_end, conn_arr );
421  std::copy( conn_arr, conn_arr + 4 * num_fine_quads, range_inserter( localGidVerts ) );
422  }
423  else
424  {
425  MB_CHK_SET_ERR( smt.create_spectral_elems( &tmp_conn[0], num_fine_quads, 2, tmp_range, start_idx,
426  &localGidVerts ),
427  "Failed to create spectral elements" );
428  int count, v_per_e;
429  MB_CHK_SET_ERR( mbImpl->connect_iterate( tmp_range.begin(), tmp_range.end(), conn_arr, v_per_e, count ),
430  "Failed to get connectivity of spectral elements" );
431  MB_CHK_SET_ERR( mbImpl->tag_iterate( smt.spectral_vertices_tag( true ), tmp_range.begin(), tmp_range.end(),
432  count, (void*&)sv_ptr ),
433  "Failed to get fine connectivity of spectral elements" );
434  }
435 
436  // Create vertices
438  std::vector< double* > arrays;
440  _readNC->readMeshIface->get_node_coords( 3, nLocalVertices, 0, start_vertex, arrays,
441  // Might have to create gather mesh later
442  ( create_gathers ? nLocalVertices + nVertices : nLocalVertices ) ),
443  "Failed to create local vertices" );
444 
445  // Set vertex coordinates
446  Range::iterator rit;
447  double* xptr = arrays[0];
448  double* yptr = arrays[1];
449  double* zptr = arrays[2];
450  int i;
451  for( i = 0, rit = localGidVerts.begin(); i < nLocalVertices; i++, ++rit )
452  {
453  assert( *rit < xVertVals.size() + 1 );
454  xptr[i] = xVertVals[( *rit ) - 1]; // lon
455  yptr[i] = yVertVals[( *rit ) - 1]; // lat
456  }
457 
458  // Convert lon/lat/rad to x/y/z
459  const double pideg = acos( -1.0 ) / 180.0;
460  double rad = ( isConnFile ) ? 8000.0 : 8000.0 + levVals[0];
461  for( i = 0; i < nLocalVertices; i++ )
462  {
463  double cosphi = cos( pideg * yptr[i] );
464  double zmult = sin( pideg * yptr[i] );
465  double xmult = cosphi * cos( xptr[i] * pideg );
466  double ymult = cosphi * sin( xptr[i] * pideg );
467  xptr[i] = rad * xmult;
468  yptr[i] = rad * ymult;
469  zptr[i] = rad * zmult;
470  }
471 
472  // Get ptr to gid memory for vertices
473  Range vert_range( start_vertex, start_vertex + nLocalVertices - 1 );
474  void* data;
475  int count;
476  MB_CHK_SET_ERR( mbImpl->tag_iterate( mGlobalIdTag, vert_range.begin(), vert_range.end(), count, data ),
477  "Failed to iterate global id tag on local vertices" );
478  assert( count == nLocalVertices );
479  int* gid_data = (int*)data;
480  std::copy( localGidVerts.begin(), localGidVerts.end(), gid_data );
481 
482  // Duplicate global id data, which will be used to resolve sharing
483  if( mpFileIdTag )
484  {
485  MB_CHK_SET_ERR( mbImpl->tag_iterate( *mpFileIdTag, vert_range.begin(), vert_range.end(), count, data ),
486  "Failed to iterate file id tag on local vertices" );
487  assert( count == nLocalVertices );
488  int bytes_per_tag = 4;
489  MB_CHK_SET_ERR( mbImpl->tag_get_bytes( *mpFileIdTag, bytes_per_tag ),
490  "Can't get number of bytes for file id tag" );
491  if( 4 == bytes_per_tag )
492  {
493  gid_data = (int*)data;
494  std::copy( localGidVerts.begin(), localGidVerts.end(), gid_data );
495  }
496  else if( 8 == bytes_per_tag )
497  { // Should be a handle tag on 64 bit machine?
498  long* handle_tag_data = (long*)data;
499  std::copy( localGidVerts.begin(), localGidVerts.end(), handle_tag_data );
500  }
501  }
502 
503  // Create map from file ids to vertex handles, used later to set connectivity
504  std::map< EntityHandle, EntityHandle > vert_handles;
505  for( rit = localGidVerts.begin(), i = 0; rit != localGidVerts.end(); ++rit, i++ )
506  vert_handles[*rit] = start_vertex + i;
507 
508  // Compute proper handles in connectivity using offset
509  for( int q = 0; q < 4 * num_coarse_quads; q++ )
510  {
511  conn_arr[q] = vert_handles[conn_arr[q]];
512  assert( conn_arr[q] );
513  }
514  if( spectralMesh )
515  {
516  int verts_per_quad = ( _spectralOrder + 1 ) * ( _spectralOrder + 1 );
517  for( int q = 0; q < verts_per_quad * num_coarse_quads; q++ )
518  {
519  sv_ptr[q] = vert_handles[sv_ptr[q]];
520  assert( sv_ptr[q] );
521  }
522  }
523 
524  // Add new vertices and quads to current file set
525  faces.merge( tmp_range );
526  tmp_range.insert( start_vertex, start_vertex + nLocalVertices - 1 );
527  MB_CHK_SET_ERR( mbImpl->add_entities( _fileSet, tmp_range ),
528  "Failed to add new vertices and quads to current file set" );
529 
530  // Mark the set with the spectral order
531  Tag sporder;
532  MB_CHK_SET_ERR( mbImpl->tag_get_handle( "SPECTRAL_ORDER", 1, MB_TYPE_INTEGER, sporder,
534  "Trouble creating SPECTRAL_ORDER tag" );
535  MB_CHK_SET_ERR( mbImpl->tag_set_data( sporder, &_fileSet, 1, &_spectralOrder ),
536  "Trouble setting data to SPECTRAL_ORDER tag" );
537 
538  if( create_gathers )
539  {
540  EntityHandle gather_set;
541  MB_CHK_SET_ERR( _readNC->readMeshIface->create_gather_set( gather_set ), "Failed to create gather set" );
542 
543  // Create vertices
544  arrays.clear();
545  // Don't need to specify allocation number here, because we know enough verts were created
546  // before
547  MB_CHK_SET_ERR( _readNC->readMeshIface->get_node_coords( 3, nVertices, 0, start_vertex, arrays ),
548  "Failed to create gather set vertices" );
549 
550  xptr = arrays[0];
551  yptr = arrays[1];
552  zptr = arrays[2];
553  for( i = 0; i < nVertices; i++ )
554  {
555  double cosphi = cos( pideg * yVertVals[i] );
556  double zmult = sin( pideg * yVertVals[i] );
557  double xmult = cosphi * cos( xVertVals[i] * pideg );
558  double ymult = cosphi * sin( xVertVals[i] * pideg );
559  xptr[i] = rad * xmult;
560  yptr[i] = rad * ymult;
561  zptr[i] = rad * zmult;
562  }
563 
564  // Get ptr to gid memory for vertices
565  Range gather_set_verts_range( start_vertex, start_vertex + nVertices - 1 );
566  MB_CHK_SET_ERR( mbImpl->tag_iterate( mGlobalIdTag, gather_set_verts_range.begin(), gather_set_verts_range.end(),
567  count, data ),
568  "Failed to iterate global id tag on gather set vertices" );
569  assert( count == nVertices );
570  gid_data = (int*)data;
571  for( int j = 1; j <= nVertices; j++ )
572  gid_data[j - 1] = j;
573  // Set the file id tag too, it should be bigger something not interfering with global id
574  if( mpFileIdTag )
575  {
576  MB_CHK_SET_ERR( mbImpl->tag_iterate( *mpFileIdTag, gather_set_verts_range.begin(),
577  gather_set_verts_range.end(), count, data ),
578  "Failed to iterate file id tag on gather set vertices" );
579  assert( count == nVertices );
580  int bytes_per_tag = 4;
581  MB_CHK_SET_ERR( mbImpl->tag_get_bytes( *mpFileIdTag, bytes_per_tag ),
582  "Can't get number of bytes for file id tag" );
583  if( 4 == bytes_per_tag )
584  {
585  gid_data = (int*)data;
586  for( int j = 1; j <= nVertices; j++ )
587  gid_data[j - 1] = nVertices + j; // Bigger than global id tag
588  }
589  else if( 8 == bytes_per_tag )
590  { // Should be a handle tag on 64 bit machine?
591  long* handle_tag_data = (long*)data;
592  for( int j = 1; j <= nVertices; j++ )
593  handle_tag_data[j - 1] = nVertices + j; // Bigger than global id tag
594  }
595  }
596 
597  MB_CHK_SET_ERR( mbImpl->add_entities( gather_set, gather_set_verts_range ),
598  "Failed to add vertices to the gather set" );
599 
600  // Create quads
601  Range gather_set_quads_range;
602  // Don't need to specify allocation number here, because we know enough quads were created
603  // before
604  MB_CHK_SET_ERR( _readNC->readMeshIface->get_element_connect( num_quads, 4, MBQUAD, 0, start_quad, conn_arr ),
605  "Failed to create gather set quads" );
606  gather_set_quads_range.insert( start_quad, start_quad + num_quads - 1 );
607  int* tmp_conn_end = ( &tmp_conn[4 * num_quads - 1] ) + 1;
608  std::copy( &tmp_conn[0], tmp_conn_end, conn_arr );
609  for( i = 0; i != 4 * num_quads; i++ )
610  conn_arr[i] += start_vertex - 1; // Connectivity array is shifted by where the gather verts start
611  MB_CHK_SET_ERR( mbImpl->add_entities( gather_set, gather_set_quads_range ),
612  "Failed to add quads to the gather set" );
613  }
614 
615  return MB_SUCCESS;
616 }

References moab::NCHelper::_fileSet, moab::NCHelper::_opts, moab::NCHelper::_readNC, _spectralOrder, moab::Interface::add_entities(), moab::Range::begin(), moab::Interface::connect_iterate(), connectId, moab::ReadUtilIface::create_gather_set(), moab::SpectralMeshTool::create_spectral_elems(), moab::ReadNC::dbgOut, moab::Range::end(), moab::ReadNC::fileId, moab::ReadNC::fileName, moab::ReadNC::gatherSetRank, moab::ReadNC::get_dimensions(), moab::ReadUtilIface::get_element_connect(), moab::ReadUtilIface::get_node_coords(), moab::FileOptions::get_str_option(), moab::Range::insert(), isConnFile, moab::ReadNC::isParallel, moab::NCHelper::levVals, moab::UcdNCHelper::localGidVerts, MB_CHK_SET_ERR, MB_SET_ERR, MB_SUCCESS, MB_TAG_CREAT, MB_TAG_SPARSE, MB_TYPE_INTEGER, moab::ReadNC::mbImpl, MBQUAD, moab::Range::merge(), moab::ReadNC::mGlobalIdTag, moab::ReadNC::mpFileIdTag, NCDF_SIZE, moab::UcdNCHelper::nCells, NCFUNC, NCFUNCAG, moab::UcdNCHelper::nLocalVertices, moab::UcdNCHelper::nVertices, moab::pideg, moab::ProcConfig::proc_comm(), moab::ParallelComm::proc_config(), moab::ProcConfig::proc_rank(), moab::ProcConfig::proc_size(), moab::ReadNC::readMeshIface, moab::Range::size(), moab::SpectralMeshTool::spectral_vertices_tag(), moab::ReadNC::spectralMesh, moab::Interface::tag_get_bytes(), moab::Interface::tag_get_handle(), moab::Interface::tag_iterate(), moab::Interface::tag_set_data(), moab::DebugOutput::tprintf(), moab::ReadNC::trivialPartitionShift, moab::UcdNCHelper::xVertVals, and moab::UcdNCHelper::yVertVals.

◆ get_mesh_type_name()

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

Implementation of NCHelper::get_mesh_type_name()

Implements moab::NCHelper.

Definition at line 32 of file NCHelperHOMME.hpp.

33  {
34  return "CAM_SE";
35  }

◆ init_mesh_vals()

ErrorCode moab::NCHelperHOMME::init_mesh_vals ( )
privatevirtual

Implementation of NCHelper::init_mesh_vals()

Implements moab::NCHelper.

Definition at line 64 of file NCHelperHOMME.cpp.

65 {
66  std::vector< std::string >& dimNames = _readNC->dimNames;
67  std::vector< int >& dimLens = _readNC->dimLens;
68  std::map< std::string, ReadNC::VarData >& varInfo = _readNC->varInfo;
69 
70  unsigned int idx;
71  std::vector< std::string >::iterator vit;
72 
73  // Look for time dimension
74  if( isConnFile )
75  {
76  // Connectivity file might not have time dimension
77  }
78  else
79  {
80  if( ( vit = std::find( dimNames.begin(), dimNames.end(), "time" ) ) != dimNames.end() )
81  idx = vit - dimNames.begin();
82  else if( ( vit = std::find( dimNames.begin(), dimNames.end(), "t" ) ) != dimNames.end() )
83  idx = vit - dimNames.begin();
84  else
85  {
86  MB_SET_ERR( MB_FAILURE, "Couldn't find 'time' or 't' dimension" );
87  }
88  tDim = idx;
89  nTimeSteps = dimLens[idx];
90  }
91 
92  // Get number of vertices (labeled as number of columns)
93  if( ( vit = std::find( dimNames.begin(), dimNames.end(), "ncol" ) ) != dimNames.end() )
94  idx = vit - dimNames.begin();
95  else
96  {
97  MB_SET_ERR( MB_FAILURE, "Couldn't find 'ncol' dimension" );
98  }
99  vDim = idx;
100  nVertices = dimLens[idx];
101 
102  // Set number of cells
103  nCells = nVertices - 2;
104 
105  // Get number of levels
106  if( isConnFile )
107  {
108  // Connectivity file might not have level dimension
109  }
110  else
111  {
112  if( ( vit = std::find( dimNames.begin(), dimNames.end(), "lev" ) ) != dimNames.end() )
113  idx = vit - dimNames.begin();
114  else if( ( vit = std::find( dimNames.begin(), dimNames.end(), "ilev" ) ) != dimNames.end() )
115  idx = vit - dimNames.begin();
116  else
117  {
118  MB_SET_ERR( MB_FAILURE, "Couldn't find 'lev' or 'ilev' dimension" );
119  }
120  levDim = idx;
121  nLevels = dimLens[idx];
122  }
123 
124  // Store lon values in xVertVals
125  std::map< std::string, ReadNC::VarData >::iterator vmit;
126  if( ( vmit = varInfo.find( "lon" ) ) != varInfo.end() && ( *vmit ).second.varDims.size() == 1 )
127  {
128  MB_CHK_SET_ERR( read_coordinate( "lon", 0, nVertices - 1, xVertVals ), "Trouble reading 'lon' variable" );
129  }
130  else
131  {
132  MB_SET_ERR( MB_FAILURE, "Couldn't find 'lon' variable" );
133  }
134 
135  // Store lat values in yVertVals
136  if( ( vmit = varInfo.find( "lat" ) ) != varInfo.end() && ( *vmit ).second.varDims.size() == 1 )
137  {
138  MB_CHK_SET_ERR( read_coordinate( "lat", 0, nVertices - 1, yVertVals ), "Trouble reading 'lat' variable" );
139  }
140  else
141  {
142  MB_SET_ERR( MB_FAILURE, "Couldn't find 'lat' variable" );
143  }
144 
145  // Store lev values in levVals
146  if( isConnFile )
147  {
148  // Connectivity file might not have level variable
149  }
150  else
151  {
152  if( ( vmit = varInfo.find( "lev" ) ) != varInfo.end() && ( *vmit ).second.varDims.size() == 1 )
153  {
154  MB_CHK_SET_ERR( read_coordinate( "lev", 0, nLevels - 1, levVals ), "Trouble reading 'lev' variable" );
155 
156  // Decide whether down is positive
157  char posval[10] = { 0 };
158  int success = NCFUNC( get_att_text )( _fileId, ( *vmit ).second.varId, "positive", posval );
159  if( 0 == success && !strcmp( posval, "down" ) )
160  {
161  for( std::vector< double >::iterator dvit = levVals.begin(); dvit != levVals.end(); ++dvit )
162  ( *dvit ) *= -1.0;
163  }
164  }
165  else
166  {
167  MB_SET_ERR( MB_FAILURE, "Couldn't find 'lev' variable" );
168  }
169  }
170 
171  // Store time coordinate values in tVals
172  if( isConnFile )
173  {
174  // Connectivity file might not have time variable
175  }
176  else
177  {
178  if( ( vmit = varInfo.find( "time" ) ) != varInfo.end() && ( *vmit ).second.varDims.size() == 1 )
179  {
180  MB_CHK_SET_ERR( read_coordinate( "time", 0, nTimeSteps - 1, tVals ), "Trouble reading 'time' variable" );
181  }
182  else if( ( vmit = varInfo.find( "t" ) ) != varInfo.end() && ( *vmit ).second.varDims.size() == 1 )
183  {
184  MB_CHK_SET_ERR( read_coordinate( "t", 0, nTimeSteps - 1, tVals ), "Trouble reading 't' variable" );
185  }
186  else
187  {
188  // If expected time variable does not exist, set dummy values to tVals
189  for( int t = 0; t < nTimeSteps; t++ )
190  tVals.push_back( (double)t );
191  }
192  }
193 
194  // For each variable, determine the entity location type and number of levels
195  std::map< std::string, ReadNC::VarData >::iterator mit;
196  for( mit = varInfo.begin(); mit != varInfo.end(); ++mit )
197  {
198  ReadNC::VarData& vd = ( *mit ).second;
199 
200  // Default entLoc is ENTLOCSET
201  if( std::find( vd.varDims.begin(), vd.varDims.end(), tDim ) != vd.varDims.end() )
202  {
203  if( std::find( vd.varDims.begin(), vd.varDims.end(), vDim ) != vd.varDims.end() )
204  vd.entLoc = ReadNC::ENTLOCVERT;
205  }
206 
207  // Default numLev is 0
208  if( std::find( vd.varDims.begin(), vd.varDims.end(), levDim ) != vd.varDims.end() ) vd.numLev = nLevels;
209  }
210 
211  // Hack: create dummy variables for dimensions (like ncol) with no corresponding coordinate
212  // variables
213  MB_CHK_SET_ERR( create_dummy_variables(), "Failed to create dummy variables" );
214 
215  return MB_SUCCESS;
216 }

References moab::NCHelper::_fileId, moab::NCHelper::_readNC, moab::NCHelper::create_dummy_variables(), moab::ReadNC::dimLens, moab::ReadNC::dimNames, moab::ReadNC::VarData::entLoc, moab::ReadNC::ENTLOCVERT, isConnFile, moab::NCHelper::levDim, moab::NCHelper::levVals, MB_CHK_SET_ERR, MB_SET_ERR, MB_SUCCESS, moab::UcdNCHelper::nCells, NCFUNC, 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::UcdNCHelper::vDim, moab::UcdNCHelper::xVertVals, and moab::UcdNCHelper::yVertVals.

◆ read_ucd_variables_to_nonset()

ErrorCode moab::NCHelperHOMME::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 807 of file NCHelperHOMME.cpp.

809 {
810  DebugOutput& dbgOut = _readNC->dbgOut;
811 
813  "Trouble allocating space to read non-set variables" );
814 
815  // Finally, read into that space
816  int success;
817  for( unsigned int i = 0; i < vdatas.size(); i++ )
818  {
819  std::size_t sz = vdatas[i].sz;
820 
821  // A typical supported variable: float T(time, lev, ncol)
822  // For tag values, need transpose (lev, ncol) to (ncol, lev)
823  size_t ni = vdatas[i].readCounts[2]; // ncol
824  size_t nj = 1; // Here we should just set nj to 1
825  size_t nk = vdatas[i].readCounts[1]; // lev
826 
827  for( unsigned int t = 0; t < tstep_nums.size(); t++ )
828  {
829  // Tag data for this timestep
830  void* data = vdatas[i].varDatas[t];
831 
832  // Set readStart for each timestep along time dimension
833  vdatas[i].readStarts[0] = tstep_nums[t];
834 
835  switch( vdatas[i].varDataType )
836  {
837  case NC_FLOAT:
838  case NC_DOUBLE: {
839  // Read float as double
840  std::vector< double > tmpdoubledata( sz );
841 
842  // In the case of ucd mesh, and on multiple proc,
843  // we need to read as many times as subranges we have in the
844  // localGidVerts range;
845  // basically, we have to give a different point
846  // for data to start, for every subrange :(
847  size_t indexInDoubleArray = 0;
848  size_t ic = 0;
849  for( Range::pair_iterator pair_iter = localGidVerts.pair_begin();
850  pair_iter != localGidVerts.pair_end(); ++pair_iter, ic++ )
851  {
852  EntityHandle starth = pair_iter->first;
853  EntityHandle endh = pair_iter->second; // Inclusive
854  vdatas[i].readStarts[2] = (NCDF_SIZE)( starth - 1 );
855  vdatas[i].readCounts[2] = (NCDF_SIZE)( endh - starth + 1 );
856 
857  success = NCFUNCAG( _vara_double )( _fileId, vdatas[i].varId, &( vdatas[i].readStarts[0] ),
858  &( vdatas[i].readCounts[0] ),
859  &( tmpdoubledata[indexInDoubleArray] ) );
860  if( success )
861  MB_SET_ERR( MB_FAILURE,
862  "Failed to read double data in a loop for variable " << vdatas[i].varName );
863  // We need to increment the index in double array for the
864  // next subrange
865  indexInDoubleArray += ( endh - starth + 1 ) * 1 * vdatas[i].numLev;
866  }
867  assert( ic == localGidVerts.psize() );
868 
869  if( vdatas[i].numLev > 1 )
870  // Transpose (lev, ncol) to (ncol, lev)
871  kji_to_jik_stride( ni, nj, nk, data, &tmpdoubledata[0], localGidVerts );
872  else
873  {
874  for( std::size_t idx = 0; idx != tmpdoubledata.size(); idx++ )
875  ( (double*)data )[idx] = tmpdoubledata[idx];
876  }
877 
878  break;
879  }
880  default:
881  MB_SET_ERR( MB_FAILURE, "Unexpected data type for variable " << vdatas[i].varName );
882  }
883  }
884  }
885 
886  // Debug output, if requested
887  if( 1 == dbgOut.get_verbosity() )
888  {
889  dbgOut.printf( 1, "Read variables: %s", vdatas.begin()->varName.c_str() );
890  for( unsigned int i = 1; i < vdatas.size(); i++ )
891  dbgOut.printf( 1, ", %s ", vdatas[i].varName.c_str() );
892  dbgOut.tprintf( 1, "\n" );
893  }
894 
895  return MB_SUCCESS;
896 }

References moab::NCHelper::_fileId, moab::NCHelper::_readNC, moab::ReadNC::dbgOut, moab::DebugOutput::get_verbosity(), moab::UcdNCHelper::kji_to_jik_stride(), moab::UcdNCHelper::localGidVerts, MB_CHK_SET_ERR, MB_SET_ERR, MB_SUCCESS, NCDF_SIZE, NCFUNCAG, moab::Range::pair_begin(), moab::Range::pair_end(), moab::DebugOutput::printf(), moab::Range::psize(), read_ucd_variables_to_nonset_allocate(), and moab::DebugOutput::tprintf().

◆ read_ucd_variables_to_nonset_allocate()

ErrorCode moab::NCHelperHOMME::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 618 of file NCHelperHOMME.cpp.

620 {
621  Interface*& mbImpl = _readNC->mbImpl;
622  std::vector< int >& dimLens = _readNC->dimLens;
623  DebugOutput& dbgOut = _readNC->dbgOut;
624 
625  Range* range = NULL;
626 
627  // Get vertices
628  Range verts;
629  MB_CHK_SET_ERR( mbImpl->get_entities_by_dimension( _fileSet, 0, verts ),
630  "Trouble getting vertices in current file set" );
631  assert( "Should only have a single vertex subrange, since they were read in one shot" && verts.psize() == 1 );
632 
633  for( unsigned int i = 0; i < vdatas.size(); i++ )
634  {
635  // Support non-set variables with 3 dimensions like (time, lev, ncol)
636  assert( 3 == vdatas[i].varDims.size() );
637 
638  // For a non-set variable, time should be the first dimension
639  assert( tDim == vdatas[i].varDims[0] );
640 
641  // Set up readStarts and readCounts
642  vdatas[i].readStarts.resize( 3 );
643  vdatas[i].readCounts.resize( 3 );
644 
645  // First: time
646  vdatas[i].readStarts[0] = 0; // This value is timestep dependent, will be set later
647  vdatas[i].readCounts[0] = 1;
648 
649  // Next: lev
650  vdatas[i].readStarts[1] = 0;
651  vdatas[i].readCounts[1] = vdatas[i].numLev;
652 
653  // Finally: ncol
654  switch( vdatas[i].entLoc )
655  {
656  case ReadNC::ENTLOCVERT:
657  // Vertices
658  // Start from the first localGidVerts
659  // Actually, this will be reset later on in a loop
660  vdatas[i].readStarts[2] = localGidVerts[0] - 1;
661  vdatas[i].readCounts[2] = nLocalVertices;
662  range = &verts;
663  break;
664  default:
665  MB_SET_ERR( MB_FAILURE, "Unexpected entity location type for variable " << vdatas[i].varName );
666  }
667 
668  // Get variable size
669  vdatas[i].sz = 1;
670  for( std::size_t idx = 0; idx != 3; idx++ )
671  vdatas[i].sz *= vdatas[i].readCounts[idx];
672 
673  for( unsigned int t = 0; t < tstep_nums.size(); t++ )
674  {
675  dbgOut.tprintf( 2, "Reading variable %s, time step %d\n", vdatas[i].varName.c_str(), tstep_nums[t] );
676 
677  if( tstep_nums[t] >= dimLens[tDim] )
678  {
679  MB_SET_ERR( MB_INDEX_OUT_OF_RANGE, "Wrong value for timestep number " << tstep_nums[t] );
680  }
681 
682  // Get the tag to read into
683  if( !vdatas[i].varTags[t] )
684  {
685  MB_CHK_SET_ERR( get_tag_to_nonset( vdatas[i], tstep_nums[t], vdatas[i].varTags[t], vdatas[i].numLev ),
686  "Trouble getting tag for variable " << vdatas[i].varName );
687  }
688 
689  // Get ptr to tag space
690  void* data;
691  int count;
692  MB_CHK_SET_ERR( mbImpl->tag_iterate( vdatas[i].varTags[t], range->begin(), range->end(), count, data ),
693  "Failed to iterate tag for variable " << vdatas[i].varName );
694  assert( (unsigned)count == range->size() );
695  vdatas[i].varDatas[t] = data;
696  }
697  }
698 
699  return MB_SUCCESS;
700 }

References moab::NCHelper::_fileSet, moab::NCHelper::_readNC, moab::Range::begin(), moab::ReadNC::dbgOut, moab::ReadNC::dimLens, moab::Range::end(), moab::ReadNC::ENTLOCVERT, moab::Interface::get_entities_by_dimension(), moab::NCHelper::get_tag_to_nonset(), moab::UcdNCHelper::localGidVerts, MB_CHK_SET_ERR, MB_INDEX_OUT_OF_RANGE, MB_SET_ERR, MB_SUCCESS, moab::ReadNC::mbImpl, moab::UcdNCHelper::nLocalVertices, moab::Range::psize(), moab::Range::size(), moab::Interface::tag_iterate(), moab::NCHelper::tDim, and moab::DebugOutput::tprintf().

Referenced by read_ucd_variables_to_nonset().

Member Data Documentation

◆ _spectralOrder

int moab::NCHelperHOMME::_spectralOrder
private

Definition at line 51 of file NCHelperHOMME.hpp.

Referenced by create_mesh(), and NCHelperHOMME().

◆ connectId

int moab::NCHelperHOMME::connectId
private

Definition at line 52 of file NCHelperHOMME.hpp.

Referenced by create_mesh().

◆ isConnFile

bool moab::NCHelperHOMME::isConnFile
private

Definition at line 53 of file NCHelperHOMME.hpp.

Referenced by create_mesh(), init_mesh_vals(), and NCHelperHOMME().


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