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

Child helper class for scd mesh, e.g. CAM_EL or CAM_FV. More...

#include <NCWriteHelper.hpp>

+ Inheritance diagram for moab::ScdNCWriteHelper:
+ Collaboration diagram for moab::ScdNCWriteHelper:

Public Member Functions

 ScdNCWriteHelper (WriteNC *writeNC, int fileId, const FileOptions &opts, EntityHandle fileSet)
 
virtual ~ScdNCWriteHelper () override
 
- Public Member Functions inherited from moab::NCWriteHelper
 NCWriteHelper (WriteNC *writeNC, int fileId, const FileOptions &opts, EntityHandle fileSet)
 
virtual ~NCWriteHelper ()
 
virtual 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. Virtual so that grid-output writers (NCWriteScrip / NCWriteESMF / NCWriteDomain) can synthesize a fresh schema from mesh state instead of going through the climate var_names plumbing. More...
 
virtual 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. Virtual for the same reason as init_file. More...
 

Protected Attributes

int lDims [6]
 Dimensions of my local part of grid. More...
 
int lCDims [6]
 Center dimensions of my local part of grid. More...
 
- Protected Attributes inherited from moab::NCWriteHelper
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 collect_mesh_info () override
 Implementation of NCWriteHelper::collect_mesh_info() More...
 
ErrorCode collect_variable_data (std::vector< std::string > &var_names, std::vector< int > &tstep_nums) override
 Collect data for specified variables. More...
 
ErrorCode write_nonset_variables (std::vector< WriteNC::VarData > &vdatas, std::vector< int > &tstep_nums) override
 Implementation of NCWriteHelper::write_nonset_variables() More...
 

Static Private Member Functions

template<typename T >
static void jik_to_kji (size_t ni, size_t nj, size_t nk, T *dest, T *source)
 

Additional Inherited Members

- Static Public Member Functions inherited from moab::NCWriteHelper
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...
 

Detailed Description

Child helper class for scd mesh, e.g. CAM_EL or CAM_FV.

Definition at line 84 of file NCWriteHelper.hpp.

Constructor & Destructor Documentation

◆ ScdNCWriteHelper()

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

Definition at line 87 of file NCWriteHelper.hpp.

88  : NCWriteHelper( writeNC, fileId, opts, fileSet )
89  {
90  for( unsigned int i = 0; i < 6; i++ )
91  {
92  lDims[i] = -1;
93  lCDims[i] = -1;
94  }
95  }

References lCDims, and lDims.

◆ ~ScdNCWriteHelper()

virtual moab::ScdNCWriteHelper::~ScdNCWriteHelper ( )
inlineoverridevirtual

Definition at line 96 of file NCWriteHelper.hpp.

96 {}

Member Function Documentation

◆ collect_mesh_info()

ErrorCode moab::ScdNCWriteHelper::collect_mesh_info ( )
overrideprivatevirtual

Implementation of NCWriteHelper::collect_mesh_info()

Implements moab::NCWriteHelper.

Definition at line 603 of file NCWriteHelper.cpp.

604 {
605  Interface*& mbImpl = _writeNC->mbImpl;
606  std::vector< std::string >& dimNames = _writeNC->dimNames;
607  std::vector< int >& dimLens = _writeNC->dimLens;
608 
609  // Look for time dimension
610  std::vector< std::string >::iterator vecIt;
611  if( ( vecIt = std::find( dimNames.begin(), dimNames.end(), "time" ) ) != dimNames.end() )
612  tDim = vecIt - dimNames.begin();
613  else if( ( vecIt = std::find( dimNames.begin(), dimNames.end(), "t" ) ) != dimNames.end() )
614  tDim = vecIt - dimNames.begin();
615  else
616  {
617  MB_SET_ERR( MB_FAILURE, "Couldn't find 'time' or 't' dimension" );
618  }
619  nTimeSteps = dimLens[tDim];
620 
621  // Get number of levels
622  if( ( vecIt = std::find( dimNames.begin(), dimNames.end(), "lev" ) ) != dimNames.end() )
623  levDim = vecIt - dimNames.begin();
624  else if( ( vecIt = std::find( dimNames.begin(), dimNames.end(), "ilev" ) ) != dimNames.end() )
625  levDim = vecIt - dimNames.begin();
626  else
627  {
628  MB_SET_ERR( MB_FAILURE, "Couldn't find 'lev' or 'ilev' dimension" );
629  }
630  nLevels = dimLens[levDim];
631 
632  // __<dim_name>_LOC_MINMAX (for slon, slat, lon and lat)
633  Tag convTag = 0;
634  MB_CHK_SET_ERR( mbImpl->tag_get_handle( "__slon_LOC_MINMAX", 0, MB_TYPE_INTEGER, convTag, MB_TAG_ANY ),
635  "Trouble getting conventional tag __slon_LOC_MINMAX" );
636  int val[2];
637  MB_CHK_SET_ERR( mbImpl->tag_get_data( convTag, &_fileSet, 1, val ),
638  "Trouble getting data of conventional tag __slon_LOC_MINMAX" );
639  lDims[0] = val[0];
640  lDims[3] = val[1];
641 
642  MB_CHK_SET_ERR( mbImpl->tag_get_handle( "__slat_LOC_MINMAX", 0, MB_TYPE_INTEGER, convTag, MB_TAG_ANY ),
643  "Trouble getting conventional tag __slat_LOC_MINMAX" );
644  MB_CHK_SET_ERR( mbImpl->tag_get_data( convTag, &_fileSet, 1, val ),
645  "Trouble getting data of conventional tag __slat_LOC_MINMAX" );
646  lDims[1] = val[0];
647  lDims[4] = val[1];
648 
649  MB_CHK_SET_ERR( mbImpl->tag_get_handle( "__lon_LOC_MINMAX", 0, MB_TYPE_INTEGER, convTag, MB_TAG_ANY ),
650  "Trouble getting conventional tag __lon_LOC_MINMAX" );
651  MB_CHK_SET_ERR( mbImpl->tag_get_data( convTag, &_fileSet, 1, val ),
652  "Trouble getting data of conventional tag __lon_LOC_MINMAX" );
653  lCDims[0] = val[0];
654  lCDims[3] = val[1];
655 
656  MB_CHK_SET_ERR( mbImpl->tag_get_handle( "__lat_LOC_MINMAX", 0, MB_TYPE_INTEGER, convTag, MB_TAG_ANY ),
657  "Trouble getting conventional tag __lat_LOC_MINMAX" );
658  MB_CHK_SET_ERR( mbImpl->tag_get_data( convTag, &_fileSet, 1, val ),
659  "Trouble getting data of conventional tag __lat_LOC_MINMAX" );
660  lCDims[1] = val[0];
661  lCDims[4] = val[1];
662 
663  // Get local faces
664  MB_CHK_SET_ERR( mbImpl->get_entities_by_dimension( _fileSet, 2, localCellsOwned ),
665  "Trouble getting local faces in current file set" );
666  assert( !localCellsOwned.empty() );
667 
668 #ifdef MOAB_HAVE_MPI
669  bool& isParallel = _writeNC->isParallel;
670  if( isParallel )
671  {
672  ParallelComm*& myPcomm = _writeNC->myPcomm;
673  int procs = myPcomm->proc_config().proc_size();
674  if( procs > 1 )
675  {
676  MB_CHK_SET_ERR( myPcomm->filter_pstatus( localCellsOwned, PSTATUS_NOT_OWNED, PSTATUS_NOT ),
677  "Trouble getting owned faces in current file set" );
678  }
679  }
680 #endif
681 
682  return MB_SUCCESS;
683 }

References moab::NCWriteHelper::_fileSet, moab::NCWriteHelper::_writeNC, moab::WriteNC::dimLens, moab::WriteNC::dimNames, moab::Range::empty(), moab::ParallelComm::filter_pstatus(), moab::Interface::get_entities_by_dimension(), moab::WriteNC::isParallel, lCDims, lDims, moab::NCWriteHelper::levDim, moab::NCWriteHelper::localCellsOwned, MB_CHK_SET_ERR, MB_SET_ERR, MB_SUCCESS, MB_TAG_ANY, MB_TYPE_INTEGER, moab::WriteNC::mbImpl, moab::NCWriteHelper::nLevels, moab::NCWriteHelper::nTimeSteps, moab::ParallelComm::proc_config(), moab::ProcConfig::proc_size(), PSTATUS_NOT, PSTATUS_NOT_OWNED, moab::Interface::tag_get_data(), moab::Interface::tag_get_handle(), and moab::NCWriteHelper::tDim.

◆ collect_variable_data()

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

Collect data for specified variables.

Reimplemented from moab::NCWriteHelper.

Definition at line 685 of file NCWriteHelper.cpp.

687 {
688  NCWriteHelper::collect_variable_data( var_names, tstep_nums );
689 
690  std::map< std::string, WriteNC::VarData >& varInfo = _writeNC->varInfo;
691 
692  for( size_t i = 0; i < var_names.size(); i++ )
693  {
694  std::string varname = var_names[i];
695  std::map< std::string, WriteNC::VarData >::iterator vit = varInfo.find( varname );
696  if( vit == varInfo.end() ) MB_SET_ERR( MB_FAILURE, "Can't find variable " << varname );
697 
698  WriteNC::VarData& currentVarData = vit->second;
699 #ifndef NDEBUG
700  std::vector< int >& varDims = currentVarData.varDims;
701 #endif
702 
703  // Skip set variables, which were already processed in
704  // NCWriteHelper::collect_variable_data()
705  if( WriteNC::ENTLOCSET == currentVarData.entLoc ) continue;
706 
707  // Set up writeStarts and writeCounts (maximum number of dimensions is 4)
708  currentVarData.writeStarts.resize( 4 );
709  currentVarData.writeCounts.resize( 4 );
710  unsigned int dim_idx = 0;
711 
712  // First: time
713  if( currentVarData.has_tsteps )
714  {
715  // Non-set variables with timesteps
716  // 4 dimensions like (time, lev, lat, lon)
717  // 3 dimensions like (time, lat, lon)
718  assert( 4 == varDims.size() || 3 == varDims.size() );
719 
720  // Time should be the first dimension
721  assert( tDim == varDims[0] );
722 
723  currentVarData.writeStarts[dim_idx] = 0; // This value is timestep dependent, will be set later
724  currentVarData.writeCounts[dim_idx] = 1;
725  dim_idx++;
726  }
727  else
728  {
729  // Non-set variables without timesteps
730  // 3 dimensions like (lev, lat, lon)
731  // 2 dimensions like (lat, lon)
732  assert( 3 == varDims.size() || 2 == varDims.size() );
733  }
734 
735  // Next: lev
736  if( currentVarData.numLev > 0 )
737  {
738  // Non-set variables with levels
739  // 4 dimensions like (time, lev, lat, lon)
740  // 3 dimensions like (lev, lat, lon)
741  assert( 4 == varDims.size() || 3 == varDims.size() );
742 
743  currentVarData.writeStarts[dim_idx] = 0;
744  currentVarData.writeCounts[dim_idx] = currentVarData.numLev;
745  dim_idx++;
746  }
747  else
748  {
749  // Non-set variables without levels
750  // 3 dimensions like (time, lat, lon)
751  // 2 dimensions like (lat, lon)
752  assert( 3 == varDims.size() || 2 == varDims.size() );
753  }
754 
755  // Finally: lat and lon
756  switch( currentVarData.entLoc )
757  {
758  case WriteNC::ENTLOCFACE:
759  // Faces
760  currentVarData.writeStarts[dim_idx] = lCDims[1];
761  currentVarData.writeCounts[dim_idx] = lCDims[4] - lCDims[1] + 1;
762  currentVarData.writeStarts[dim_idx + 1] = lCDims[0];
763  currentVarData.writeCounts[dim_idx + 1] = lCDims[3] - lCDims[0] + 1;
764  break;
765  default:
766  MB_SET_ERR( MB_FAILURE, "Unexpected entity location type for variable " << varname );
767  }
768  dim_idx += 2;
769 
770  // Get variable size
771  currentVarData.sz = 1;
772  for( std::size_t idx = 0; idx < dim_idx; idx++ )
773  currentVarData.sz *= currentVarData.writeCounts[idx];
774  } // for (size_t i = 0; i < var_names.size(); i++)
775 
776  return MB_SUCCESS;
777 }

References moab::NCWriteHelper::_writeNC, moab::NCWriteHelper::collect_variable_data(), moab::WriteNC::VarData::entLoc, moab::WriteNC::ENTLOCFACE, moab::WriteNC::ENTLOCSET, moab::WriteNC::VarData::has_tsteps, lCDims, MB_SET_ERR, MB_SUCCESS, moab::WriteNC::VarData::numLev, moab::WriteNC::VarData::sz, moab::NCWriteHelper::tDim, moab::WriteNC::VarData::varDims, moab::WriteNC::varInfo, moab::WriteNC::VarData::writeCounts, and moab::WriteNC::VarData::writeStarts.

◆ jik_to_kji()

template<typename T >
static void moab::ScdNCWriteHelper::jik_to_kji ( size_t  ni,
size_t  nj,
size_t  nk,
T *  dest,
T *  source 
)
inlinestaticprivate

Definition at line 109 of file NCWriteHelper.hpp.

110  {
111  size_t nik = ni * nk, nij = ni * nj;
112  for( std::size_t k = 0; k != nk; k++ )
113  for( std::size_t j = 0; j != nj; j++ )
114  for( std::size_t i = 0; i != ni; i++ )
115  dest[k * nij + j * ni + i] = source[j * nik + i * nk + k];
116  }

Referenced by write_nonset_variables().

◆ write_nonset_variables()

ErrorCode moab::ScdNCWriteHelper::write_nonset_variables ( std::vector< WriteNC::VarData > &  vdatas,
std::vector< int > &  tstep_nums 
)
overrideprivatevirtual

Implementation of NCWriteHelper::write_nonset_variables()

Implements moab::NCWriteHelper.

Definition at line 782 of file NCWriteHelper.cpp.

784 {
785  Interface*& mbImpl = _writeNC->mbImpl;
786 
787  int success;
788 
789  // For each indexed variable tag, write a time step data
790  for( unsigned int i = 0; i < vdatas.size(); i++ )
791  {
792  WriteNC::VarData& variableData = vdatas[i];
793 
794  // Assume this variable is on faces for the time being
795  switch( variableData.entLoc )
796  {
797  case WriteNC::ENTLOCFACE:
798  // Faces
799  break;
800  default:
801  MB_SET_ERR( MB_FAILURE, "Unexpected entity location type for variable " << variableData.varName );
802  }
803 
804  unsigned int num_timesteps;
805  unsigned int lat_idx = 0;
806  unsigned int lon_idx = 1;
807  if( variableData.has_tsteps )
808  {
809  // Non-set variables with timesteps
810  // 4 dimensions like (time, lev, lat, lon)
811  // 3 dimensions like (time, lat, lon)
812  num_timesteps = tstep_nums.size();
813  lat_idx++;
814  lon_idx++;
815  }
816  else
817  {
818  // Non-set variables without timesteps
819  // 3 dimensions like (lev, lat, lon)
820  // 2 dimensions like (lat, lon)
821  num_timesteps = 1;
822  }
823 
824  unsigned int num_lev;
825  if( variableData.numLev > 0 )
826  {
827  // Non-set variables with levels
828  // 4 dimensions like (time, lev, lat, lon)
829  // 3 dimensions like (lev, lat, lon)
830  num_lev = variableData.numLev;
831  lat_idx++;
832  lon_idx++;
833  }
834  else
835  {
836  // Non-set variables without levels
837  // 3 dimensions like (time, lat, lon)
838  // 2 dimensions like (lat, lon)
839  num_lev = 1;
840  }
841 
842  size_t ni = variableData.writeCounts[lon_idx]; // lon
843  size_t nj = variableData.writeCounts[lat_idx]; // lat
844 
845  // At each timestep, we need to transpose tag format (lat, lon, lev) back
846  // to NC format (lev, lat, lon) for writing
847  for( unsigned int t = 0; t < num_timesteps; t++ )
848  {
849  // We will write one time step, and count will be one; start will be different
850  // Use tag_iterate to get tag data (assume that localCellsOwned is contiguous)
851  // We should also transpose for level so that means deep copy for transpose
852  if( tDim == variableData.varDims[0] ) variableData.writeStarts[0] = t; // This is start for time
853  int count;
854  void* dataptr;
855  MB_CHK_SET_ERR( mbImpl->tag_iterate( variableData.varTags[t], localCellsOwned.begin(),
856  localCellsOwned.end(), count, dataptr ),
857  "Failed to iterate tag on owned faces" );
858  assert( count == (int)localCellsOwned.size() );
859 
860  // Now transpose and write tag data
861  // Use collective I/O mode put (synchronous write) for the time being, we can try
862  // nonblocking put (request aggregation) later
863  switch( variableData.varDataType )
864  {
865  case NC_DOUBLE: {
866  std::vector< double > tmpdoubledata( ni * nj * num_lev );
867  if( num_lev > 1 )
868  // Transpose (lat, lon, lev) back to (lev, lat, lon)
869  jik_to_kji( ni, nj, num_lev, &tmpdoubledata[0], (double*)( dataptr ) );
870  success = NCFUNCAP( _vara_double )( _fileId, variableData.varId, &variableData.writeStarts[0],
871  &variableData.writeCounts[0], &tmpdoubledata[0] );
872  if( success )
873  MB_SET_ERR( MB_FAILURE, "Failed to write double data for variable " << variableData.varName );
874  break;
875  }
876  default:
877  MB_SET_ERR( MB_NOT_IMPLEMENTED, "Writing non-double data is not implemented yet" );
878  }
879  }
880  }
881 
882  return MB_SUCCESS;
883 }

References moab::NCWriteHelper::_fileId, moab::NCWriteHelper::_writeNC, moab::Range::begin(), moab::Range::end(), moab::WriteNC::VarData::entLoc, moab::WriteNC::ENTLOCFACE, moab::WriteNC::VarData::has_tsteps, jik_to_kji(), moab::NCWriteHelper::localCellsOwned, MB_CHK_SET_ERR, MB_NOT_IMPLEMENTED, MB_SET_ERR, MB_SUCCESS, moab::WriteNC::mbImpl, NCFUNCAP, moab::WriteNC::VarData::numLev, moab::Range::size(), moab::Interface::tag_iterate(), moab::NCWriteHelper::tDim, moab::WriteNC::VarData::varDataType, moab::WriteNC::VarData::varDims, moab::WriteNC::VarData::varId, moab::WriteNC::VarData::varName, moab::WriteNC::VarData::varTags, moab::WriteNC::VarData::writeCounts, and moab::WriteNC::VarData::writeStarts.

Member Data Documentation

◆ lCDims

int moab::ScdNCWriteHelper::lCDims[6]
protected

Center dimensions of my local part of grid.

Definition at line 123 of file NCWriteHelper.hpp.

Referenced by collect_mesh_info(), collect_variable_data(), and ScdNCWriteHelper().

◆ lDims

int moab::ScdNCWriteHelper::lDims[6]
protected

Dimensions of my local part of grid.

Definition at line 120 of file NCWriteHelper.hpp.

Referenced by collect_mesh_info(), and ScdNCWriteHelper().


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