Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
Child helper class for scd mesh, e.g. CAM_EL or CAM_FV. More...
#include <NCWriteHelper.hpp>
Public Member Functions | |
ScdNCWriteHelper (WriteNC *writeNC, int fileId, const FileOptions &opts, EntityHandle fileSet) | |
virtual | ~ScdNCWriteHelper () |
Protected Attributes | |
int | lDims [6] |
Dimensions of my local part of grid. | |
int | lCDims [6] |
Center dimensions of my local part of grid. | |
Private Member Functions | |
virtual ErrorCode | collect_mesh_info () |
Implementation of NCWriteHelper::collect_mesh_info() | |
virtual ErrorCode | collect_variable_data (std::vector< std::string > &var_names, std::vector< int > &tstep_nums) |
Collect data for specified variables. | |
virtual ErrorCode | write_nonset_variables (std::vector< WriteNC::VarData > &vdatas, std::vector< int > &tstep_nums) |
Implementation of NCWriteHelper::write_nonset_variables() | |
template<typename T > | |
void | jik_to_kji (size_t ni, size_t nj, size_t nk, T *dest, T *source) |
Child helper class for scd mesh, e.g. CAM_EL or CAM_FV.
Definition at line 81 of file NCWriteHelper.hpp.
moab::ScdNCWriteHelper::ScdNCWriteHelper | ( | WriteNC * | writeNC, |
int | fileId, | ||
const FileOptions & | opts, | ||
EntityHandle | fileSet | ||
) | [inline] |
Definition at line 84 of file NCWriteHelper.hpp.
: NCWriteHelper( writeNC, fileId, opts, fileSet ) { for( unsigned int i = 0; i < 6; i++ ) { lDims[i] = -1; lCDims[i] = -1; } }
virtual moab::ScdNCWriteHelper::~ScdNCWriteHelper | ( | ) | [inline, virtual] |
Definition at line 93 of file NCWriteHelper.hpp.
{}
ErrorCode moab::ScdNCWriteHelper::collect_mesh_info | ( | ) | [private, virtual] |
Implementation of NCWriteHelper::collect_mesh_info()
Implements moab::NCWriteHelper.
Definition at line 593 of file NCWriteHelper.cpp.
References moab::NCWriteHelper::_fileSet, moab::NCWriteHelper::_writeNC, moab::WriteNC::dimLens, moab::WriteNC::dimNames, moab::Range::empty(), ErrorCode, 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.
{ Interface*& mbImpl = _writeNC->mbImpl; std::vector< std::string >& dimNames = _writeNC->dimNames; std::vector< int >& dimLens = _writeNC->dimLens; ErrorCode rval; // Look for time dimension std::vector< std::string >::iterator vecIt; if( ( vecIt = std::find( dimNames.begin(), dimNames.end(), "time" ) ) != dimNames.end() ) tDim = vecIt - dimNames.begin(); else if( ( vecIt = std::find( dimNames.begin(), dimNames.end(), "t" ) ) != dimNames.end() ) tDim = vecIt - dimNames.begin(); else { MB_SET_ERR( MB_FAILURE, "Couldn't find 'time' or 't' dimension" ); } nTimeSteps = dimLens[tDim]; // Get number of levels if( ( vecIt = std::find( dimNames.begin(), dimNames.end(), "lev" ) ) != dimNames.end() ) levDim = vecIt - dimNames.begin(); else if( ( vecIt = std::find( dimNames.begin(), dimNames.end(), "ilev" ) ) != dimNames.end() ) levDim = vecIt - dimNames.begin(); else { MB_SET_ERR( MB_FAILURE, "Couldn't find 'lev' or 'ilev' dimension" ); } nLevels = dimLens[levDim]; // __<dim_name>_LOC_MINMAX (for slon, slat, lon and lat) Tag convTag = 0; rval = mbImpl->tag_get_handle( "__slon_LOC_MINMAX", 0, MB_TYPE_INTEGER, convTag, MB_TAG_ANY );MB_CHK_SET_ERR( rval, "Trouble getting conventional tag __slon_LOC_MINMAX" ); int val[2]; rval = mbImpl->tag_get_data( convTag, &_fileSet, 1, val );MB_CHK_SET_ERR( rval, "Trouble getting data of conventional tag __slon_LOC_MINMAX" ); lDims[0] = val[0]; lDims[3] = val[1]; rval = mbImpl->tag_get_handle( "__slat_LOC_MINMAX", 0, MB_TYPE_INTEGER, convTag, MB_TAG_ANY );MB_CHK_SET_ERR( rval, "Trouble getting conventional tag __slat_LOC_MINMAX" ); rval = mbImpl->tag_get_data( convTag, &_fileSet, 1, val );MB_CHK_SET_ERR( rval, "Trouble getting data of conventional tag __slat_LOC_MINMAX" ); lDims[1] = val[0]; lDims[4] = val[1]; rval = mbImpl->tag_get_handle( "__lon_LOC_MINMAX", 0, MB_TYPE_INTEGER, convTag, MB_TAG_ANY );MB_CHK_SET_ERR( rval, "Trouble getting conventional tag __lon_LOC_MINMAX" ); rval = mbImpl->tag_get_data( convTag, &_fileSet, 1, val );MB_CHK_SET_ERR( rval, "Trouble getting data of conventional tag __lon_LOC_MINMAX" ); lCDims[0] = val[0]; lCDims[3] = val[1]; rval = mbImpl->tag_get_handle( "__lat_LOC_MINMAX", 0, MB_TYPE_INTEGER, convTag, MB_TAG_ANY );MB_CHK_SET_ERR( rval, "Trouble getting conventional tag __lat_LOC_MINMAX" ); rval = mbImpl->tag_get_data( convTag, &_fileSet, 1, val );MB_CHK_SET_ERR( rval, "Trouble getting data of conventional tag __lat_LOC_MINMAX" ); lCDims[1] = val[0]; lCDims[4] = val[1]; // Get local faces rval = mbImpl->get_entities_by_dimension( _fileSet, 2, localCellsOwned );MB_CHK_SET_ERR( rval, "Trouble getting local faces in current file set" ); assert( !localCellsOwned.empty() ); #ifdef MOAB_HAVE_MPI bool& isParallel = _writeNC->isParallel; if( isParallel ) { ParallelComm*& myPcomm = _writeNC->myPcomm; int procs = myPcomm->proc_config().proc_size(); if( procs > 1 ) { rval = myPcomm->filter_pstatus( localCellsOwned, PSTATUS_NOT_OWNED, PSTATUS_NOT );MB_CHK_SET_ERR( rval, "Trouble getting owned faces in current file set" ); } } #endif return MB_SUCCESS; }
ErrorCode moab::ScdNCWriteHelper::collect_variable_data | ( | std::vector< std::string > & | var_names, |
std::vector< int > & | tstep_nums | ||
) | [private, virtual] |
Collect data for specified variables.
Reimplemented from moab::NCWriteHelper.
Definition at line 667 of file NCWriteHelper.cpp.
References moab::NCWriteHelper::_writeNC, 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.
{ NCWriteHelper::collect_variable_data( var_names, tstep_nums ); std::map< std::string, WriteNC::VarData >& varInfo = _writeNC->varInfo; for( size_t i = 0; i < var_names.size(); i++ ) { std::string varname = var_names[i]; std::map< std::string, WriteNC::VarData >::iterator vit = varInfo.find( varname ); if( vit == varInfo.end() ) MB_SET_ERR( MB_FAILURE, "Can't find variable " << varname ); WriteNC::VarData& currentVarData = vit->second; #ifndef NDEBUG std::vector< int >& varDims = currentVarData.varDims; #endif // Skip set variables, which were already processed in // NCWriteHelper::collect_variable_data() if( WriteNC::ENTLOCSET == currentVarData.entLoc ) continue; // Set up writeStarts and writeCounts (maximum number of dimensions is 4) currentVarData.writeStarts.resize( 4 ); currentVarData.writeCounts.resize( 4 ); unsigned int dim_idx = 0; // First: time if( currentVarData.has_tsteps ) { // Non-set variables with timesteps // 4 dimensions like (time, lev, lat, lon) // 3 dimensions like (time, lat, lon) assert( 4 == varDims.size() || 3 == varDims.size() ); // Time should be the first dimension assert( tDim == varDims[0] ); currentVarData.writeStarts[dim_idx] = 0; // This value is timestep dependent, will be set later currentVarData.writeCounts[dim_idx] = 1; dim_idx++; } else { // Non-set variables without timesteps // 3 dimensions like (lev, lat, lon) // 2 dimensions like (lat, lon) assert( 3 == varDims.size() || 2 == varDims.size() ); } // Next: lev if( currentVarData.numLev > 0 ) { // Non-set variables with levels // 4 dimensions like (time, lev, lat, lon) // 3 dimensions like (lev, lat, lon) assert( 4 == varDims.size() || 3 == varDims.size() ); currentVarData.writeStarts[dim_idx] = 0; currentVarData.writeCounts[dim_idx] = currentVarData.numLev; dim_idx++; } else { // Non-set variables without levels // 3 dimensions like (time, lat, lon) // 2 dimensions like (lat, lon) assert( 3 == varDims.size() || 2 == varDims.size() ); } // Finally: lat and lon switch( currentVarData.entLoc ) { case WriteNC::ENTLOCFACE: // Faces currentVarData.writeStarts[dim_idx] = lCDims[1]; currentVarData.writeCounts[dim_idx] = lCDims[4] - lCDims[1] + 1; currentVarData.writeStarts[dim_idx + 1] = lCDims[0]; currentVarData.writeCounts[dim_idx + 1] = lCDims[3] - lCDims[0] + 1; break; default: MB_SET_ERR( MB_FAILURE, "Unexpected entity location type for variable " << varname ); } dim_idx += 2; // Get variable size currentVarData.sz = 1; for( std::size_t idx = 0; idx < dim_idx; idx++ ) currentVarData.sz *= currentVarData.writeCounts[idx]; } // for (size_t i = 0; i < var_names.size(); i++) return MB_SUCCESS; }
void moab::ScdNCWriteHelper::jik_to_kji | ( | size_t | ni, |
size_t | nj, | ||
size_t | nk, | ||
T * | dest, | ||
T * | source | ||
) | [inline, private] |
Definition at line 106 of file NCWriteHelper.hpp.
Referenced by write_nonset_variables().
{ size_t nik = ni * nk, nij = ni * nj; for( std::size_t k = 0; k != nk; k++ ) for( std::size_t j = 0; j != nj; j++ ) for( std::size_t i = 0; i != ni; i++ ) dest[k * nij + j * ni + i] = source[j * nik + i * nk + k]; }
ErrorCode moab::ScdNCWriteHelper::write_nonset_variables | ( | std::vector< WriteNC::VarData > & | vdatas, |
std::vector< int > & | tstep_nums | ||
) | [private, virtual] |
Implementation of NCWriteHelper::write_nonset_variables()
Implements moab::NCWriteHelper.
Definition at line 764 of file NCWriteHelper.cpp.
References moab::NCWriteHelper::_fileId, moab::NCWriteHelper::_writeNC, moab::Range::begin(), moab::Range::end(), moab::WriteNC::VarData::entLoc, moab::WriteNC::ENTLOCFACE, ErrorCode, 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(), t, 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.
{ Interface*& mbImpl = _writeNC->mbImpl; int success; // For each indexed variable tag, write a time step data for( unsigned int i = 0; i < vdatas.size(); i++ ) { WriteNC::VarData& variableData = vdatas[i]; // Assume this variable is on faces for the time being switch( variableData.entLoc ) { case WriteNC::ENTLOCFACE: // Faces break; default: MB_SET_ERR( MB_FAILURE, "Unexpected entity location type for variable " << variableData.varName ); } unsigned int num_timesteps; unsigned int lat_idx = 0; unsigned int lon_idx = 1; if( variableData.has_tsteps ) { // Non-set variables with timesteps // 4 dimensions like (time, lev, lat, lon) // 3 dimensions like (time, lat, lon) num_timesteps = tstep_nums.size(); lat_idx++; lon_idx++; } else { // Non-set variables without timesteps // 3 dimensions like (lev, lat, lon) // 2 dimensions like (lat, lon) num_timesteps = 1; } unsigned int num_lev; if( variableData.numLev > 0 ) { // Non-set variables with levels // 4 dimensions like (time, lev, lat, lon) // 3 dimensions like (lev, lat, lon) num_lev = variableData.numLev; lat_idx++; lon_idx++; } else { // Non-set variables without levels // 3 dimensions like (time, lat, lon) // 2 dimensions like (lat, lon) num_lev = 1; } size_t ni = variableData.writeCounts[lon_idx]; // lon size_t nj = variableData.writeCounts[lat_idx]; // lat // At each timestep, we need to transpose tag format (lat, lon, lev) back // to NC format (lev, lat, lon) for writing for( unsigned int t = 0; t < num_timesteps; t++ ) { // We will write one time step, and count will be one; start will be different // Use tag_iterate to get tag data (assume that localCellsOwned is contiguous) // We should also transpose for level so that means deep copy for transpose if( tDim == variableData.varDims[0] ) variableData.writeStarts[0] = t; // This is start for time int count; void* dataptr; ErrorCode rval = mbImpl->tag_iterate( variableData.varTags[t], localCellsOwned.begin(), localCellsOwned.end(), count, dataptr );MB_CHK_SET_ERR( rval, "Failed to iterate tag on owned faces" ); assert( count == (int)localCellsOwned.size() ); // Now transpose and write tag data // Use collective I/O mode put (synchronous write) for the time being, we can try // nonblocking put (request aggregation) later switch( variableData.varDataType ) { case NC_DOUBLE: { std::vector< double > tmpdoubledata( ni * nj * num_lev ); if( num_lev > 1 ) // Transpose (lat, lon, lev) back to (lev, lat, lon) jik_to_kji( ni, nj, num_lev, &tmpdoubledata[0], (double*)( dataptr ) ); success = NCFUNCAP( _vara_double )( _fileId, variableData.varId, &variableData.writeStarts[0], &variableData.writeCounts[0], &tmpdoubledata[0] ); if( success ) MB_SET_ERR( MB_FAILURE, "Failed to write double data for variable " << variableData.varName ); break; } default: MB_SET_ERR( MB_NOT_IMPLEMENTED, "Writing non-double data is not implemented yet" ); } } } return MB_SUCCESS; }
int moab::ScdNCWriteHelper::lCDims[6] [protected] |
Center dimensions of my local part of grid.
Definition at line 120 of file NCWriteHelper.hpp.
Referenced by collect_mesh_info(), collect_variable_data(), and ScdNCWriteHelper().
int moab::ScdNCWriteHelper::lDims[6] [protected] |
Dimensions of my local part of grid.
Definition at line 117 of file NCWriteHelper.hpp.
Referenced by collect_mesh_info(), and ScdNCWriteHelper().