Loading [MathJax]/extensions/tex2jax.js
Mesh Oriented datABase  (version 5.5.1)
An array-based unstructured mesh library
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
moab::NCWriteHelper Class Referenceabstract

#include <NCWriteHelper.hpp>

+ Inheritance diagram for moab::NCWriteHelper:
+ Collaboration diagram for moab::NCWriteHelper:

Public Member Functions

 NCWriteHelper (WriteNC *writeNC, int fileId, const FileOptions &opts, EntityHandle fileSet)
 
virtual ~NCWriteHelper ()
 
virtual ErrorCode collect_mesh_info ()=0
 Collect necessary info about local mesh (implemented in child classes) More...
 
virtual ErrorCode collect_variable_data (std::vector< std::string > &var_names, std::vector< int > &tstep_nums)
 Collect data for specified variables (partially implemented in child classes) More...
 
ErrorCode init_file (std::vector< std::string > &var_names, std::vector< std::string > &desired_names, bool _append)
 Initialize file: this is where all defines are done The VarData dimension ids are filled up after define. More...
 
ErrorCode write_values (std::vector< std::string > &var_names, std::vector< int > &tstep_nums)
 Take the info from VarData and write first non-set variables, then set variables. More...
 

Static Public Member Functions

static NCWriteHelperget_nc_helper (WriteNC *writeNC, int fileId, const FileOptions &opts, EntityHandle fileSet)
 Get appropriate helper instance for WriteNC class based on some info in the file set. More...
 

Protected Member Functions

virtual ErrorCode write_nonset_variables (std::vector< WriteNC::VarData > &vdatas, std::vector< int > &tstep_nums)=0
 

Protected Attributes

WriteNC_writeNC
 Allow NCWriteHelper to directly access members of WriteNC. More...
 
int _fileId
 Cache some information from WriteNC. More...
 
const FileOptions_opts
 
EntityHandle _fileSet
 
int nTimeSteps
 Dimensions of time and level. More...
 
int nLevels
 
int tDim
 Dimension numbers for time and level. More...
 
int levDim
 
Range localCellsOwned
 Local owned cells, edges and vertices. More...
 
Range localEdgesOwned
 
Range localVertsOwned
 
std::vector< double > timeStepVals
 Time values of output timesteps. More...
 

Private Member Functions

ErrorCode write_set_variables (std::vector< WriteNC::VarData > &vsetdatas, std::vector< int > &tstep_nums)
 

Detailed Description

Definition at line 22 of file NCWriteHelper.hpp.

Constructor & Destructor Documentation

◆ NCWriteHelper()

moab::NCWriteHelper::NCWriteHelper ( WriteNC writeNC,
int  fileId,
const FileOptions opts,
EntityHandle  fileSet 
)
inline

Definition at line 25 of file NCWriteHelper.hpp.

26  : _writeNC( writeNC ), _fileId( fileId ), _opts( opts ), _fileSet( fileSet ), nTimeSteps( 0 ), nLevels( 1 ), 27  tDim( -1 ), levDim( -1 ) 28  { 29  }

◆ ~NCWriteHelper()

virtual moab::NCWriteHelper::~NCWriteHelper ( )
inlinevirtual

Definition at line 30 of file NCWriteHelper.hpp.

30 {};

Member Function Documentation

◆ collect_mesh_info()

virtual ErrorCode moab::NCWriteHelper::collect_mesh_info ( )
pure virtual

Collect necessary info about local mesh (implemented in child classes)

Implemented in moab::NCWriteMPAS, moab::NCWriteHOMME, moab::ScdNCWriteHelper, and moab::NCWriteGCRM.

Referenced by moab::WriteNC::write_file().

◆ collect_variable_data()

ErrorCode moab::NCWriteHelper::collect_variable_data ( std::vector< std::string > &  var_names,
std::vector< int > &  tstep_nums 
)
virtual

Collect data for specified variables (partially implemented in child classes)

Reimplemented in moab::NCWriteMPAS, moab::NCWriteHOMME, moab::ScdNCWriteHelper, and moab::NCWriteGCRM.

Definition at line 51 of file NCWriteHelper.cpp.

52 { 53  Interface*& mbImpl = _writeNC->mbImpl; 54  std::vector< std::string >& dimNames = _writeNC->dimNames; 55  std::vector< int >& dimLens = _writeNC->dimLens; 56  std::set< std::string >& usedCoordinates = _writeNC->usedCoordinates; 57  std::set< std::string >& dummyVarNames = _writeNC->dummyVarNames; 58  std::map< std::string, WriteNC::VarData >& varInfo = _writeNC->varInfo; 59  DebugOutput& dbgOut = _writeNC->dbgOut; 60  61  ErrorCode rval; 62  63  usedCoordinates.clear(); 64  65  if( tstep_nums.empty() && nTimeSteps > 0 ) 66  { 67  // No timesteps input, get them all 68  for( int i = 0; i < nTimeSteps; i++ ) 69  tstep_nums.push_back( i ); 70  } 71  72  for( size_t i = 0; i < var_names.size(); i++ ) 73  { 74  std::string varname = var_names[i]; 75  std::map< std::string, WriteNC::VarData >::iterator vit = varInfo.find( varname ); 76  if( vit == varInfo.end() ) MB_SET_ERR( MB_FAILURE, "Can't find variable " << varname ); 77  78  WriteNC::VarData& currentVarData = vit->second; 79  80  dbgOut.tprintf( 2, " for variable %s varDims.size %d \n", varname.c_str(), 81  (int)currentVarData.varDims.size() ); 82  for( size_t j = 0; j < currentVarData.varDims.size(); j++ ) 83  { 84  std::string dimName = dimNames[currentVarData.varDims[j]]; 85  vit = varInfo.find( dimName ); 86  if( vit == varInfo.end() ) MB_SET_ERR( MB_FAILURE, "Can't find coordinate variable " << dimName ); 87  88  usedCoordinates.insert( dimName ); // Collect those used, we will need to write them to the file 89  dbgOut.tprintf( 2, " for variable %s need dimension %s with length %d\n", varname.c_str(), 90  dimName.c_str(), dimLens[currentVarData.varDims[j]] ); 91  } 92  93  // Process coordinate variables later 94  if( usedCoordinates.find( varname ) != usedCoordinates.end() ) continue; 95  96  // Default has_tsteps is false 97  if( std::find( currentVarData.varDims.begin(), currentVarData.varDims.end(), tDim ) != 98  currentVarData.varDims.end() ) 99  currentVarData.has_tsteps = true; 100  101  // Default numLev is 0 102  if( ( std::find( currentVarData.varDims.begin(), currentVarData.varDims.end(), levDim ) != 103  currentVarData.varDims.end() ) ) 104  currentVarData.numLev = nLevels; 105  106  // Process set variables 107  if( WriteNC::ENTLOCSET == currentVarData.entLoc ) 108  { 109  if( currentVarData.has_tsteps ) 110  { 111  // Set variables with timesteps, e.g. xtime(Time) or xtime(Time, StrLen) 112  // TBD 113  MB_SET_ERR( MB_NOT_IMPLEMENTED, "Writing set variables with timesteps is not implemented yet" ); 114  } 115  else 116  { 117  // Get the tag with varname 118  Tag tag = 0; 119  rval = mbImpl->tag_get_handle( varname.c_str(), tag );MB_CHK_SET_ERR( rval, "Can't find tag " << varname ); 120  currentVarData.varTags.push_back( tag ); // Really, only one for these 121  const void* data; 122  int size; 123  rval = mbImpl->tag_get_by_ptr( tag, &_fileSet, 1, &data, &size );MB_CHK_SET_ERR( rval, "Can't get data of tag " << varname ); 124  125  // Find the type of tag, and use it 126  DataType type; 127  rval = mbImpl->tag_get_data_type( tag, type );MB_CHK_SET_ERR( rval, "Can't get data type of tag " << varname ); 128  129  currentVarData.varDataType = NC_DOUBLE; 130  if( MB_TYPE_INTEGER == type ) currentVarData.varDataType = NC_INT; 131  132  assert( 0 == currentVarData.memoryHogs.size() ); // Nothing so far 133  currentVarData.memoryHogs.push_back( (void*)data ); 134  135  if( currentVarData.varDims.empty() ) 136  { 137  // Scalar variable 138  currentVarData.writeStarts.push_back( 0 ); 139  currentVarData.writeCounts.push_back( 1 ); 140  } 141  else 142  { 143  for( size_t j = 0; j < currentVarData.varDims.size(); j++ ) 144  { 145  currentVarData.writeStarts.push_back( 0 ); 146  currentVarData.writeCounts.push_back( dimLens[currentVarData.varDims[j]] ); 147  } 148  } 149  150  // Get variable size 151  currentVarData.sz = 1; 152  for( std::size_t idx = 0; idx != currentVarData.writeCounts.size(); idx++ ) 153  currentVarData.sz *= currentVarData.writeCounts[idx]; 154  } 155  } // if (WriteNC::ENTLOCSET == currentVarData.entLoc) 156  // Process non-set variables 157  else 158  { 159  Tag indexedTag = 0; 160  161  if( currentVarData.has_tsteps ) 162  { 163  for( unsigned int t = 0; t < tstep_nums.size(); t++ ) 164  { 165  std::stringstream ssTagNameWithIndex; 166  ssTagNameWithIndex << varname << tstep_nums[t]; 167  rval = mbImpl->tag_get_handle( ssTagNameWithIndex.str().c_str(), indexedTag );MB_CHK_SET_ERR( rval, "Can't find tag " << ssTagNameWithIndex.str() ); 168  dbgOut.tprintf( 2, " found indexed tag %d with name %s\n", tstep_nums[t], 169  ssTagNameWithIndex.str().c_str() ); 170  currentVarData.varTags.push_back( indexedTag ); 171  } 172  } 173  else 174  { 175  // This should be a user-created non-set variable without timesteps 176  // Treat it like having one, 0th, timestep 177  std::stringstream ssTagNameWithIndex; 178  ssTagNameWithIndex << varname << 0; 179  rval = mbImpl->tag_get_handle( ssTagNameWithIndex.str().c_str(), indexedTag );MB_CHK_SET_ERR( rval, "Can't find tag " << ssTagNameWithIndex.str() << " for a user-created variable" ); 180  dbgOut.tprintf( 2, " found indexed tag 0 with name %s\n", ssTagNameWithIndex.str().c_str() ); 181  currentVarData.varTags.push_back( indexedTag ); 182  } 183  184  // The type of the tag is fixed though 185  DataType type; 186  rval = mbImpl->tag_get_data_type( indexedTag, type );MB_CHK_SET_ERR( rval, "Can't get data type of tag " << varname ); 187  188  currentVarData.varDataType = NC_DOUBLE; 189  if( MB_TYPE_INTEGER == type ) currentVarData.varDataType = NC_INT; 190  } 191  } // for (size_t i = 0; i < var_names.size(); i++) 192  193  // Process coordinate variables here 194  // Check that for used coordinates we have found the tags 195  for( std::set< std::string >::iterator setIt = usedCoordinates.begin(); setIt != usedCoordinates.end(); ++setIt ) 196  { 197  const std::string& coordName = *setIt; 198  199  std::map< std::string, WriteNC::VarData >::iterator vit = varInfo.find( coordName ); 200  if( vit == varInfo.end() ) MB_SET_ERR( MB_FAILURE, "Can't find coordinate variable " << coordName ); 201  202  WriteNC::VarData& varCoordData = vit->second; 203  Tag coordTag = 0; 204  rval = mbImpl->tag_get_handle( coordName.c_str(), coordTag );MB_CHK_SET_ERR( rval, "Can't find tag " << coordName ); 205  varCoordData.varTags.push_back( coordTag ); // Really, only one for these 206  207  const void* data; 208  int sizeCoordinate; 209  rval = mbImpl->tag_get_by_ptr( coordTag, &_fileSet, 1, &data, &sizeCoordinate );MB_CHK_SET_ERR( rval, "Can't get coordinate values of " << coordName ); 210  dbgOut.tprintf( 2, " found coordinate tag with name %s and length %d\n", coordName.c_str(), sizeCoordinate ); 211  212  // Find the type of tag, and use it 213  DataType type; 214  rval = mbImpl->tag_get_data_type( coordTag, type );MB_CHK_SET_ERR( rval, "Can't get data type of tag " << coordName ); 215  varCoordData.varDataType = NC_DOUBLE; 216  if( MB_TYPE_INTEGER == type ) varCoordData.varDataType = NC_INT; 217  218  // Get dimension length (the only dimension of this coordinate variable, with the same name) 219  assert( 1 == varCoordData.varDims.size() ); 220  int coordDimLen = dimLens[varCoordData.varDims[0]]; 221  222  if( dummyVarNames.find( coordName ) != dummyVarNames.end() ) 223  { 224  // For a dummy coordinate variable, the tag size is always 1 225  // The number of coordinates should be set to dimension length, instead of 1 226  assert( 1 == sizeCoordinate ); 227  sizeCoordinate = coordDimLen; 228  229  // No variable data to write 230  data = NULL; 231  } 232  else 233  { 234  // The number of coordinates should be exactly the same as dimension length 235  // However, if timesteps spread across files and time tag has been updated, 236  // sizeCoordinate will be larger 237  if( varCoordData.varDims[0] != tDim ) assert( sizeCoordinate == coordDimLen ); 238  } 239  240  // For time, the actual output size and values are determined by tstep_nums 241  if( varCoordData.varDims[0] == tDim ) 242  { 243  // Does not apply to dummy time tag (e.g. 'Time' tag of MPAS), when timesteps 244  // spread across files 245  if( NULL != data ) assert( tstep_nums.size() > 0 && tstep_nums.size() <= (size_t)sizeCoordinate ); 246  247  sizeCoordinate = tstep_nums.size(); 248  249  if( NULL != data ) 250  { 251  assert( NC_DOUBLE == varCoordData.varDataType ); 252  timeStepVals.resize( sizeCoordinate ); 253  for( unsigned int t = 0; t < tstep_nums.size(); t++ ) 254  timeStepVals[t] = ( (double*)data )[tstep_nums[t]]; 255  256  data = &timeStepVals[0]; 257  } 258  } 259  260  // This is the length 261  varCoordData.sz = sizeCoordinate; 262  varCoordData.writeStarts.resize( 1 ); 263  varCoordData.writeStarts[0] = 0; 264  varCoordData.writeCounts.resize( 1 ); 265  varCoordData.writeCounts[0] = sizeCoordinate; 266  267  assert( 0 == varCoordData.memoryHogs.size() ); // Nothing so far 268  varCoordData.memoryHogs.push_back( (void*)data ); 269  } // for (std::set<std::string>::iterator setIt ... 270  271  return MB_SUCCESS; 272 }

References _fileSet, _writeNC, moab::WriteNC::dbgOut, moab::WriteNC::dimLens, moab::WriteNC::dimNames, moab::WriteNC::dummyVarNames, moab::WriteNC::VarData::entLoc, moab::WriteNC::ENTLOCSET, ErrorCode, moab::WriteNC::VarData::has_tsteps, levDim, MB_CHK_SET_ERR, MB_NOT_IMPLEMENTED, MB_SET_ERR, MB_SUCCESS, MB_TYPE_INTEGER, moab::WriteNC::mbImpl, moab::WriteNC::VarData::memoryHogs, nLevels, nTimeSteps, moab::WriteNC::VarData::numLev, size, moab::WriteNC::VarData::sz, moab::Interface::tag_get_by_ptr(), moab::Interface::tag_get_data_type(), moab::Interface::tag_get_handle(), tDim, timeStepVals, moab::DebugOutput::tprintf(), moab::WriteNC::usedCoordinates, moab::WriteNC::VarData::varDataType, moab::WriteNC::VarData::varDims, moab::WriteNC::varInfo, moab::WriteNC::VarData::varTags, moab::WriteNC::VarData::writeCounts, and moab::WriteNC::VarData::writeStarts.

Referenced by moab::NCWriteGCRM::collect_variable_data(), moab::ScdNCWriteHelper::collect_variable_data(), moab::NCWriteHOMME::collect_variable_data(), moab::NCWriteMPAS::collect_variable_data(), and moab::WriteNC::write_file().

◆ get_nc_helper()

NCWriteHelper * moab::NCWriteHelper::get_nc_helper ( WriteNC writeNC,
int  fileId,
const FileOptions opts,
EntityHandle  fileSet 
)
static

Get appropriate helper instance for WriteNC class based on some info in the file set.

Get appropriate helper instance for WriteNC class; based on some info in the file set.

Definition at line 30 of file NCWriteHelper.cpp.

34 { 35  std::string& grid_type = writeNC->grid_type; 36  if( grid_type == "CAM_EUL" ) 37  return new( std::nothrow ) NCWriteEuler( writeNC, fileId, opts, fileSet ); 38  else if( grid_type == "CAM_FV" ) 39  return new( std::nothrow ) NCWriteFV( writeNC, fileId, opts, fileSet ); 40  else if( grid_type == "CAM_SE" ) 41  return new( std::nothrow ) NCWriteHOMME( writeNC, fileId, opts, fileSet ); 42  else if( grid_type == "MPAS" ) 43  return new( std::nothrow ) NCWriteMPAS( writeNC, fileId, opts, fileSet ); 44  else if( grid_type == "GCRM" ) 45  return new( std::nothrow ) NCWriteGCRM( writeNC, fileId, opts, fileSet ); 46  47  // Unknown NetCDF grid 48  return NULL; 49 }

References moab::WriteNC::grid_type.

Referenced by moab::WriteNC::write_file().

◆ init_file()

ErrorCode moab::NCWriteHelper::init_file ( std::vector< std::string > &  var_names,
std::vector< std::string > &  desired_names,
bool  _append 
)

Initialize file: this is where all defines are done The VarData dimension ids are filled up after define.

Definition at line 274 of file NCWriteHelper.cpp.

277 { 278  std::vector< std::string >& dimNames = _writeNC->dimNames; 279  std::set< std::string >& usedCoordinates = _writeNC->usedCoordinates; 280  std::set< std::string >& dummyVarNames = _writeNC->dummyVarNames; 281  std::map< std::string, WriteNC::VarData >& varInfo = _writeNC->varInfo; 282  std::map< std::string, WriteNC::AttData >& globalAtts = _writeNC->globalAtts; 283  DebugOutput& dbgOut = _writeNC->dbgOut; 284  285  int tDim_in_dimNames = tDim; 286  int levDim_in_dimNames = levDim; 287  288  // If append mode, make sure we are in define mode; a simple open will not allow creation of new 289  // variables 290  if( append ) 291  { 292  int errcode = NCFUNC( redef )( _fileId ); 293  if( errcode != NC_NOERR ) MB_SET_ERR( MB_FAILURE, "Can't open file in redefine mode" ); 294  } 295  296  // First initialize all coordinates, then fill VarData for actual variables (and dimensions) 297  // Check that for used coordinates we have found the tags 298  for( std::set< std::string >::iterator setIt = usedCoordinates.begin(); setIt != usedCoordinates.end(); ++setIt ) 299  { 300  const std::string& coordName = *setIt; 301  302  std::map< std::string, WriteNC::VarData >::iterator vit = varInfo.find( coordName ); 303  if( vit == varInfo.end() ) MB_SET_ERR( MB_FAILURE, "Can't find coordinate variable " << coordName ); 304  305  WriteNC::VarData& varCoordData = vit->second; 306  varCoordData.varDims.resize( 1 ); 307  308  // If not append, create it for sure 309  // If append, we might already have it, including the tag / variable with the same name 310  /* 311  * int ncmpi_inq_dimid(int ncid, const char *name, int *idp); 312  */ 313  if( append ) 314  { 315  int dimId; 316  if( NCFUNC( inq_dimid )( _fileId, coordName.c_str(), &dimId ) == NC_NOERR ) 317  { // If not found, create it later 318  varCoordData.varDims[0] = dimId; 319  dbgOut.tprintf( 2, " file already has coordName %s dim id is %d \n", coordName.c_str(), 320  (int)varCoordData.varDims[0] ); 321  322  // Update tDim and levDim to actual dimension id 323  if( coordName == dimNames[tDim_in_dimNames] ) 324  tDim = varCoordData.varDims[0]; 325  else if( coordName == dimNames[levDim_in_dimNames] ) 326  levDim = varCoordData.varDims[0]; 327  328  // Skip dummy coordinate variables (e.g. ncol) 329  if( dummyVarNames.find( coordName ) != dummyVarNames.end() ) continue; 330  331  // Check that the coordinate is a variable too 332  // Inquire for a variable with the same name 333  int varId; 334  if( NCFUNC( inq_varid )( _fileId, coordName.c_str(), &varId ) != NC_NOERR ) 335  MB_SET_ERR( MB_FAILURE, "We do not have a variable with the same name " << coordName ); 336  // We should also check that this variable has one dimension, and it is dimId 337  varCoordData.varId = varId; 338  dbgOut.tprintf( 2, " file already has coordinate %s and varId is %d \n", coordName.c_str(), varId ); 339  340  continue; // Maybe more checks are needed here 341  } 342  } 343  344  /* int nc_def_dim (int ncid, const char *name, size_t len, int *dimidp); 345  * example: status = nc_def_dim(fileId, "lat", 18L, &latid); 346  */ 347  348  // Actually define a dimension 349  if( NCFUNC( def_dim )( _fileId, coordName.c_str(), (size_t)varCoordData.sz, &varCoordData.varDims[0] ) != 350  NC_NOERR ) 351  MB_SET_ERR( MB_FAILURE, "Failed to generate dimension " << coordName ); 352  dbgOut.tprintf( 2, " for coordName %s dim id is %d \n", coordName.c_str(), (int)varCoordData.varDims[0] ); 353  354  // Update tDim and levDim to actual dimension id 355  if( coordName == dimNames[tDim_in_dimNames] ) 356  tDim = varCoordData.varDims[0]; 357  else if( coordName == dimNames[levDim_in_dimNames] ) 358  levDim = varCoordData.varDims[0]; 359  360  // Create a variable with the same name, and its only dimension the one we just defined 361  /* 362  * int nc_def_var (int ncid, const char *name, nc_type xtype, 363  int ndims, const int dimids[], int *varidp); 364  example: 365  http://www.unidata.ucar.edu/software/netcdf/docs/netcdf-c/nc_005fdef_005fvar.html#nc_005fdef_005fvar 366  */ 367  368  // Skip dummy coordinate variables (e.g. ncol) 369  if( dummyVarNames.find( coordName ) != dummyVarNames.end() ) continue; 370  371  // Define a coordinate variable 372  if( NCFUNC( def_var )( _fileId, coordName.c_str(), varCoordData.varDataType, 1, &( varCoordData.varDims[0] ), 373  &varCoordData.varId ) != NC_NOERR ) 374  MB_SET_ERR( MB_FAILURE, "Failed to create coordinate variable " << coordName ); 375  376  dbgOut.tprintf( 2, " for coordName %s variable id is %d \n", coordName.c_str(), varCoordData.varId ); 377  } 378  379  // Now look at requested variables, and update from the index in dimNames to the actual 380  // dimension id 381  for( size_t i = 0; i < var_names.size(); i++ ) 382  { 383  std::map< std::string, WriteNC::VarData >::iterator vit = varInfo.find( var_names[i] ); 384  if( vit == varInfo.end() ) MB_SET_ERR( MB_FAILURE, "Can't find requested variable " << var_names[i] ); 385  386  // Skip coordinate variables 387  if( usedCoordinates.find( var_names[i] ) != usedCoordinates.end() ) continue; 388  389  WriteNC::VarData& variableData = vit->second; 390  391  // The index is for dimNames; we need to find out the actual dimension id (from above) 392  int numDims = (int)variableData.varDims.size(); 393  for( int j = 0; j < numDims; j++ ) 394  { 395  std::string dimName = dimNames[variableData.varDims[j]]; 396  std::map< std::string, WriteNC::VarData >::iterator vit2 = varInfo.find( dimName ); 397  if( vit2 == varInfo.end() ) 398  MB_SET_ERR( MB_FAILURE, "Can't find requested coordinate variable " << dimName ); 399  400  WriteNC::VarData& coordData = vit2->second; 401  // Index in dimNames to actual dimension id 402  variableData.varDims[j] = coordData.varDims[0]; // This one, being a coordinate, is the only one 403  dbgOut.tprintf( 2, " dimension with index %d name %s has ID %d \n", j, dimName.c_str(), 404  variableData.varDims[j] ); 405  } 406  407  // Define the variable now: 408  int errCode = 409  NCFUNC( def_var )( _fileId, desired_names[i].c_str(), variableData.varDataType, 410  (int)variableData.varDims.size(), &( variableData.varDims[0] ), &variableData.varId ); 411  if( errCode != NC_NOERR ) MB_SET_ERR( MB_FAILURE, "Failed to create requested variable " << desired_names[i] ); 412  413  dbgOut.tprintf( 2, " for variable %s with desired name %s variable id is %d \n", var_names[i].c_str(), 414  desired_names[i].c_str(), variableData.varId ); 415  // Now define the variable, with all dimensions 416  } 417  418  // Define global attributes (exactly copied from the original file for the time being) 419  // Should we modify some of them (e.g. revision_Id) later? 420  std::map< std::string, WriteNC::AttData >::iterator attIt; 421  for( attIt = globalAtts.begin(); attIt != globalAtts.end(); ++attIt ) 422  { 423  const std::string& attName = attIt->first; 424  WriteNC::AttData& attData = attIt->second; 425  NCDF_SIZE& attLen = attData.attLen; 426  nc_type& attDataType = attData.attDataType; 427  const std::string& attValue = attData.attValue; 428  429  switch( attDataType ) 430  { 431  case NC_BYTE: 432  case NC_CHAR: 433  if( NC_NOERR != 434  NCFUNC( put_att_text )( _fileId, NC_GLOBAL, attName.c_str(), attLen, attValue.c_str() ) ) 435  MB_SET_ERR( MB_FAILURE, "Failed to define text type attribute" ); 436  break; 437  case NC_DOUBLE: 438  if( NC_NOERR != NCFUNC( put_att_double )( _fileId, NC_GLOBAL, attName.c_str(), NC_DOUBLE, 1, 439  (double*)attValue.c_str() ) ) 440  MB_SET_ERR( MB_FAILURE, "Failed to define double type attribute" ); 441  break; 442  case NC_FLOAT: 443  if( NC_NOERR != NCFUNC( put_att_float )( _fileId, NC_GLOBAL, attName.c_str(), NC_FLOAT, 1, 444  (float*)attValue.c_str() ) ) 445  MB_SET_ERR( MB_FAILURE, "Failed to define float type attribute" ); 446  break; 447  case NC_INT: 448  if( NC_NOERR != 449  NCFUNC( put_att_int )( _fileId, NC_GLOBAL, attName.c_str(), NC_INT, 1, (int*)attValue.c_str() ) ) 450  MB_SET_ERR( MB_FAILURE, "Failed to define int type attribute" ); 451  break; 452  case NC_SHORT: 453  if( NC_NOERR != NCFUNC( put_att_short )( _fileId, NC_GLOBAL, attName.c_str(), NC_SHORT, 1, 454  (short*)attValue.c_str() ) ) 455  MB_SET_ERR( MB_FAILURE, "Failed to define short type attribute" ); 456  break; 457  default: 458  MB_SET_ERR( MB_FAILURE, "Unknown attribute data type" ); 459  } 460  } 461  462  // Take it out of define mode 463  if( NC_NOERR != NCFUNC( enddef )( _fileId ) ) MB_SET_ERR( MB_FAILURE, "Failed to close define mode" ); 464  465  return MB_SUCCESS; 466 }

References _fileId, _writeNC, moab::WriteNC::AttData::attDataType, moab::WriteNC::AttData::attLen, moab::WriteNC::AttData::attValue, moab::WriteNC::dbgOut, moab::WriteNC::dimNames, moab::WriteNC::dummyVarNames, moab::WriteNC::globalAtts, levDim, MB_SET_ERR, MB_SUCCESS, NCDF_SIZE, NCFUNC, moab::WriteNC::VarData::sz, tDim, moab::DebugOutput::tprintf(), moab::WriteNC::usedCoordinates, moab::WriteNC::VarData::varDataType, moab::WriteNC::VarData::varDims, moab::WriteNC::VarData::varId, and moab::WriteNC::varInfo.

Referenced by moab::WriteNC::write_file().

◆ write_nonset_variables()

virtual ErrorCode moab::NCWriteHelper::write_nonset_variables ( std::vector< WriteNC::VarData > &  vdatas,
std::vector< int > &  tstep_nums 
)
protectedpure virtual

◆ write_set_variables()

ErrorCode moab::NCWriteHelper::write_set_variables ( std::vector< WriteNC::VarData > &  vsetdatas,
std::vector< int > &  tstep_nums 
)
private

Definition at line 525 of file NCWriteHelper.cpp.

527 { 528  int success; 529  530  // CAUTION: if the NetCDF ID is from a previous call to ncmpi_create rather than ncmpi_open, 531  // all processors need to call ncmpi_begin_indep_data(). If only the root processor does so, 532  // ncmpi_begin_indep_data() call will be blocked forever :( 533 #ifdef MOAB_HAVE_PNETCDF 534  // Enter independent I/O mode 535  success = NCFUNC( begin_indep_data )( _fileId ); 536  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to begin independent I/O mode" ); 537 #endif 538  539  int rank = 0; 540 #ifdef MOAB_HAVE_MPI 541  bool& isParallel = _writeNC->isParallel; 542  if( isParallel ) 543  { 544  ParallelComm*& myPcomm = _writeNC->myPcomm; 545  rank = myPcomm->proc_config().proc_rank(); 546  } 547 #endif 548  if( 0 == rank ) 549  { 550  for( unsigned int i = 0; i < vsetdatas.size(); i++ ) 551  { 552  WriteNC::VarData& variableData = vsetdatas[i]; 553  554  // Set variables with timesteps, e.g. xtime(Time) or xtime(Time, StrLen) 555  if( variableData.has_tsteps ) 556  { 557  MB_SET_ERR( MB_NOT_IMPLEMENTED, "Writing set variables with timesteps is not implemented yet" ); 558  } 559  560  switch( variableData.varDataType ) 561  { 562  case NC_DOUBLE: 563  // Independent I/O mode put 564  success = NCFUNCP( _vara_double )( _fileId, variableData.varId, &variableData.writeStarts[0], 565  &variableData.writeCounts[0], 566  (double*)( variableData.memoryHogs[0] ) ); 567  if( success ) 568  MB_SET_ERR( MB_FAILURE, "Failed to write double data for variable " << variableData.varName ); 569  break; 570  case NC_INT: 571  // Independent I/O mode put 572  success = 573  NCFUNCP( _vara_int )( _fileId, variableData.varId, &variableData.writeStarts[0], 574  &variableData.writeCounts[0], (int*)( variableData.memoryHogs[0] ) ); 575  if( success ) 576  MB_SET_ERR( MB_FAILURE, "Failed to write int data for variable " << variableData.varName ); 577  break; 578  default: 579  MB_SET_ERR( MB_NOT_IMPLEMENTED, "Writing non-double or non-int data is not implemented yet" ); 580  } 581  } 582  } 583  584 #ifdef MOAB_HAVE_PNETCDF 585  // End independent I/O mode 586  success = NCFUNC( end_indep_data )( _fileId ); 587  if( success ) MB_SET_ERR( MB_FAILURE, "Failed to end independent I/O mode" ); 588 #endif 589  590  return MB_SUCCESS; 591 }

References _fileId, _writeNC, moab::WriteNC::VarData::has_tsteps, moab::WriteNC::isParallel, MB_NOT_IMPLEMENTED, MB_SET_ERR, MB_SUCCESS, moab::WriteNC::VarData::memoryHogs, NCFUNC, NCFUNCP, moab::ParallelComm::proc_config(), moab::ProcConfig::proc_rank(), moab::WriteNC::VarData::varDataType, moab::WriteNC::VarData::varId, moab::WriteNC::VarData::varName, moab::WriteNC::VarData::writeCounts, and moab::WriteNC::VarData::writeStarts.

Referenced by write_values().

◆ write_values()

ErrorCode moab::NCWriteHelper::write_values ( std::vector< std::string > &  var_names,
std::vector< int > &  tstep_nums 
)

Take the info from VarData and write first non-set variables, then set variables.

Definition at line 468 of file NCWriteHelper.cpp.

469 { 470  std::set< std::string >& usedCoordinates = _writeNC->usedCoordinates; 471  std::set< std::string >& dummyVarNames = _writeNC->dummyVarNames; 472  std::map< std::string, WriteNC::VarData >& varInfo = _writeNC->varInfo; 473  474  std::vector< WriteNC::VarData > vdatas; 475  std::vector< WriteNC::VarData > vsetdatas; 476  477  // For set variables, include coordinates used by requested var_names 478  for( std::set< std::string >::iterator setIt = usedCoordinates.begin(); setIt != usedCoordinates.end(); ++setIt ) 479  { 480  const std::string& coordName = *setIt; 481  482  // Skip dummy coordinate variables (if any) 483  if( dummyVarNames.find( coordName ) != dummyVarNames.end() ) continue; 484  485  std::map< std::string, WriteNC::VarData >::iterator vit = varInfo.find( coordName ); 486  if( vit == varInfo.end() ) 487  { 488  MB_SET_ERR( MB_FAILURE, "Can't find coordinate variable " << coordName ); 489  } 490  491  vsetdatas.push_back( vit->second ); 492  } 493  494  // Collect non-set and set variables from requested var_names 495  for( unsigned int i = 0; i < var_names.size(); i++ ) 496  { 497  std::map< std::string, WriteNC::VarData >::iterator vit = varInfo.find( var_names[i] ); 498  if( vit == varInfo.end() ) 499  { 500  MB_SET_ERR( MB_FAILURE, "Can't find requested variable " << var_names[i] ); 501  } 502  503  WriteNC::VarData& variableData = vit->second; 504  if( WriteNC::ENTLOCSET == variableData.entLoc ) 505  { 506  // Used coordinates has all ready been included 507  if( usedCoordinates.find( var_names[i] ) != usedCoordinates.end() ) continue; 508  509  vsetdatas.push_back( variableData ); 510  } 511  else 512  vdatas.push_back( variableData ); 513  } 514  515  // Assume that the data ranges do not overlap across processors 516  // While overlapped writing might still work, we should better not take that risk 517  write_nonset_variables( vdatas, tstep_nums ); 518  519  // Use independent I/O mode put, since this write is only for the root processor 520  write_set_variables( vsetdatas, tstep_nums ); 521  522  return MB_SUCCESS; 523 }

References _writeNC, moab::WriteNC::dummyVarNames, moab::WriteNC::VarData::entLoc, moab::WriteNC::ENTLOCSET, MB_SET_ERR, MB_SUCCESS, moab::WriteNC::usedCoordinates, moab::WriteNC::varInfo, write_nonset_variables(), and write_set_variables().

Referenced by moab::WriteNC::write_file().

Member Data Documentation

◆ _fileId

◆ _fileSet

◆ _opts

const FileOptions& moab::NCWriteHelper::_opts
protected

Definition at line 64 of file NCWriteHelper.hpp.

◆ _writeNC

◆ levDim

◆ localCellsOwned

◆ localEdgesOwned

◆ localVertsOwned

◆ nLevels

◆ nTimeSteps

int moab::NCWriteHelper::nTimeSteps
protected

◆ tDim

◆ timeStepVals

std::vector< double > moab::NCWriteHelper::timeStepVals
protected

Time values of output timesteps.

Definition at line 77 of file NCWriteHelper.hpp.

Referenced by collect_variable_data().


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