![]() |
Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
#include <NCWriteHelper.hpp>
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) | |
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) | |
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. | |
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. | |
Static Public Member Functions | |
static NCWriteHelper * | get_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. | |
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. | |
int | _fileId |
Cache some information from WriteNC. | |
const FileOptions & | _opts |
EntityHandle | _fileSet |
int | nTimeSteps |
Dimensions of time and level. | |
int | nLevels |
int | tDim |
Dimension numbers for time and level. | |
int | levDim |
Range | localCellsOwned |
Local owned cells, edges and vertices. | |
Range | localEdgesOwned |
Range | localVertsOwned |
std::vector< double > | timeStepVals |
Time values of output timesteps. | |
Private Member Functions | |
ErrorCode | write_set_variables (std::vector< WriteNC::VarData > &vsetdatas, std::vector< int > &tstep_nums) |
Definition at line 22 of file NCWriteHelper.hpp.
moab::NCWriteHelper::NCWriteHelper | ( | WriteNC * | writeNC, |
int | fileId, | ||
const FileOptions & | opts, | ||
EntityHandle | fileSet | ||
) | [inline] |
Definition at line 25 of file NCWriteHelper.hpp.
: _writeNC( writeNC ), _fileId( fileId ), _opts( opts ), _fileSet( fileSet ), nTimeSteps( 0 ), nLevels( 1 ),
tDim( -1 ), levDim( -1 )
{
}
virtual moab::NCWriteHelper::~NCWriteHelper | ( | ) | [inline, virtual] |
Definition at line 30 of file NCWriteHelper.hpp.
{};
virtual ErrorCode moab::NCWriteHelper::collect_mesh_info | ( | ) | [pure virtual] |
Collect necessary info about local mesh (implemented in child classes)
Implemented in moab::ScdNCWriteHelper, moab::NCWriteGCRM, moab::NCWriteHOMME, and moab::NCWriteMPAS.
Referenced by moab::WriteNC::write_file().
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::ScdNCWriteHelper, moab::NCWriteGCRM, moab::NCWriteHOMME, and moab::NCWriteMPAS.
Definition at line 51 of file NCWriteHelper.cpp.
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, t, 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::WriteNC::write_file().
{
Interface*& mbImpl = _writeNC->mbImpl;
std::vector< std::string >& dimNames = _writeNC->dimNames;
std::vector< int >& dimLens = _writeNC->dimLens;
std::set< std::string >& usedCoordinates = _writeNC->usedCoordinates;
std::set< std::string >& dummyVarNames = _writeNC->dummyVarNames;
std::map< std::string, WriteNC::VarData >& varInfo = _writeNC->varInfo;
DebugOutput& dbgOut = _writeNC->dbgOut;
ErrorCode rval;
usedCoordinates.clear();
if( tstep_nums.empty() && nTimeSteps > 0 )
{
// No timesteps input, get them all
for( int i = 0; i < nTimeSteps; i++ )
tstep_nums.push_back( i );
}
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;
dbgOut.tprintf( 2, " for variable %s varDims.size %d \n", varname.c_str(),
(int)currentVarData.varDims.size() );
for( size_t j = 0; j < currentVarData.varDims.size(); j++ )
{
std::string dimName = dimNames[currentVarData.varDims[j]];
vit = varInfo.find( dimName );
if( vit == varInfo.end() ) MB_SET_ERR( MB_FAILURE, "Can't find coordinate variable " << dimName );
usedCoordinates.insert( dimName ); // Collect those used, we will need to write them to the file
dbgOut.tprintf( 2, " for variable %s need dimension %s with length %d\n", varname.c_str(),
dimName.c_str(), dimLens[currentVarData.varDims[j]] );
}
// Process coordinate variables later
if( usedCoordinates.find( varname ) != usedCoordinates.end() ) continue;
// Default has_tsteps is false
if( std::find( currentVarData.varDims.begin(), currentVarData.varDims.end(), tDim ) !=
currentVarData.varDims.end() )
currentVarData.has_tsteps = true;
// Default numLev is 0
if( ( std::find( currentVarData.varDims.begin(), currentVarData.varDims.end(), levDim ) !=
currentVarData.varDims.end() ) )
currentVarData.numLev = nLevels;
// Process set variables
if( WriteNC::ENTLOCSET == currentVarData.entLoc )
{
if( currentVarData.has_tsteps )
{
// Set variables with timesteps, e.g. xtime(Time) or xtime(Time, StrLen)
// TBD
MB_SET_ERR( MB_NOT_IMPLEMENTED, "Writing set variables with timesteps is not implemented yet" );
}
else
{
// Get the tag with varname
Tag tag = 0;
rval = mbImpl->tag_get_handle( varname.c_str(), tag );MB_CHK_SET_ERR( rval, "Can't find tag " << varname );
currentVarData.varTags.push_back( tag ); // Really, only one for these
const void* data;
int size;
rval = mbImpl->tag_get_by_ptr( tag, &_fileSet, 1, &data, &size );MB_CHK_SET_ERR( rval, "Can't get data of tag " << varname );
// Find the type of tag, and use it
DataType type;
rval = mbImpl->tag_get_data_type( tag, type );MB_CHK_SET_ERR( rval, "Can't get data type of tag " << varname );
currentVarData.varDataType = NC_DOUBLE;
if( MB_TYPE_INTEGER == type ) currentVarData.varDataType = NC_INT;
assert( 0 == currentVarData.memoryHogs.size() ); // Nothing so far
currentVarData.memoryHogs.push_back( (void*)data );
if( currentVarData.varDims.empty() )
{
// Scalar variable
currentVarData.writeStarts.push_back( 0 );
currentVarData.writeCounts.push_back( 1 );
}
else
{
for( size_t j = 0; j < currentVarData.varDims.size(); j++ )
{
currentVarData.writeStarts.push_back( 0 );
currentVarData.writeCounts.push_back( dimLens[currentVarData.varDims[j]] );
}
}
// Get variable size
currentVarData.sz = 1;
for( std::size_t idx = 0; idx != currentVarData.writeCounts.size(); idx++ )
currentVarData.sz *= currentVarData.writeCounts[idx];
}
} // if (WriteNC::ENTLOCSET == currentVarData.entLoc)
// Process non-set variables
else
{
Tag indexedTag = 0;
if( currentVarData.has_tsteps )
{
for( unsigned int t = 0; t < tstep_nums.size(); t++ )
{
std::stringstream ssTagNameWithIndex;
ssTagNameWithIndex << varname << tstep_nums[t];
rval = mbImpl->tag_get_handle( ssTagNameWithIndex.str().c_str(), indexedTag );MB_CHK_SET_ERR( rval, "Can't find tag " << ssTagNameWithIndex.str() );
dbgOut.tprintf( 2, " found indexed tag %d with name %s\n", tstep_nums[t],
ssTagNameWithIndex.str().c_str() );
currentVarData.varTags.push_back( indexedTag );
}
}
else
{
// This should be a user-created non-set variable without timesteps
// Treat it like having one, 0th, timestep
std::stringstream ssTagNameWithIndex;
ssTagNameWithIndex << varname << 0;
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" );
dbgOut.tprintf( 2, " found indexed tag 0 with name %s\n", ssTagNameWithIndex.str().c_str() );
currentVarData.varTags.push_back( indexedTag );
}
// The type of the tag is fixed though
DataType type;
rval = mbImpl->tag_get_data_type( indexedTag, type );MB_CHK_SET_ERR( rval, "Can't get data type of tag " << varname );
currentVarData.varDataType = NC_DOUBLE;
if( MB_TYPE_INTEGER == type ) currentVarData.varDataType = NC_INT;
}
} // for (size_t i = 0; i < var_names.size(); i++)
// Process coordinate variables here
// Check that for used coordinates we have found the tags
for( std::set< std::string >::iterator setIt = usedCoordinates.begin(); setIt != usedCoordinates.end(); ++setIt )
{
const std::string& coordName = *setIt;
std::map< std::string, WriteNC::VarData >::iterator vit = varInfo.find( coordName );
if( vit == varInfo.end() ) MB_SET_ERR( MB_FAILURE, "Can't find coordinate variable " << coordName );
WriteNC::VarData& varCoordData = vit->second;
Tag coordTag = 0;
rval = mbImpl->tag_get_handle( coordName.c_str(), coordTag );MB_CHK_SET_ERR( rval, "Can't find tag " << coordName );
varCoordData.varTags.push_back( coordTag ); // Really, only one for these
const void* data;
int sizeCoordinate;
rval = mbImpl->tag_get_by_ptr( coordTag, &_fileSet, 1, &data, &sizeCoordinate );MB_CHK_SET_ERR( rval, "Can't get coordinate values of " << coordName );
dbgOut.tprintf( 2, " found coordinate tag with name %s and length %d\n", coordName.c_str(), sizeCoordinate );
// Find the type of tag, and use it
DataType type;
rval = mbImpl->tag_get_data_type( coordTag, type );MB_CHK_SET_ERR( rval, "Can't get data type of tag " << coordName );
varCoordData.varDataType = NC_DOUBLE;
if( MB_TYPE_INTEGER == type ) varCoordData.varDataType = NC_INT;
// Get dimension length (the only dimension of this coordinate variable, with the same name)
assert( 1 == varCoordData.varDims.size() );
int coordDimLen = dimLens[varCoordData.varDims[0]];
if( dummyVarNames.find( coordName ) != dummyVarNames.end() )
{
// For a dummy coordinate variable, the tag size is always 1
// The number of coordinates should be set to dimension length, instead of 1
assert( 1 == sizeCoordinate );
sizeCoordinate = coordDimLen;
// No variable data to write
data = NULL;
}
else
{
// The number of coordinates should be exactly the same as dimension length
// However, if timesteps spread across files and time tag has been updated,
// sizeCoordinate will be larger
if( varCoordData.varDims[0] != tDim ) assert( sizeCoordinate == coordDimLen );
}
// For time, the actual output size and values are determined by tstep_nums
if( varCoordData.varDims[0] == tDim )
{
// Does not apply to dummy time tag (e.g. 'Time' tag of MPAS), when timesteps
// spread across files
if( NULL != data ) assert( tstep_nums.size() > 0 && tstep_nums.size() <= (size_t)sizeCoordinate );
sizeCoordinate = tstep_nums.size();
if( NULL != data )
{
assert( NC_DOUBLE == varCoordData.varDataType );
timeStepVals.resize( sizeCoordinate );
for( unsigned int t = 0; t < tstep_nums.size(); t++ )
timeStepVals[t] = ( (double*)data )[tstep_nums[t]];
data = &timeStepVals[0];
}
}
// This is the length
varCoordData.sz = sizeCoordinate;
varCoordData.writeStarts.resize( 1 );
varCoordData.writeStarts[0] = 0;
varCoordData.writeCounts.resize( 1 );
varCoordData.writeCounts[0] = sizeCoordinate;
assert( 0 == varCoordData.memoryHogs.size() ); // Nothing so far
varCoordData.memoryHogs.push_back( (void*)data );
} // for (std::set::iterator setIt ...
return MB_SUCCESS;
}
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.
References moab::WriteNC::grid_type.
Referenced by moab::WriteNC::write_file().
{
std::string& grid_type = writeNC->grid_type;
if( grid_type == "CAM_EUL" )
return new( std::nothrow ) NCWriteEuler( writeNC, fileId, opts, fileSet );
else if( grid_type == "CAM_FV" )
return new( std::nothrow ) NCWriteFV( writeNC, fileId, opts, fileSet );
else if( grid_type == "CAM_SE" )
return new( std::nothrow ) NCWriteHOMME( writeNC, fileId, opts, fileSet );
else if( grid_type == "MPAS" )
return new( std::nothrow ) NCWriteMPAS( writeNC, fileId, opts, fileSet );
else if( grid_type == "GCRM" )
return new( std::nothrow ) NCWriteGCRM( writeNC, fileId, opts, fileSet );
// Unknown NetCDF grid
return NULL;
}
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.
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().
{
std::vector< std::string >& dimNames = _writeNC->dimNames;
std::set< std::string >& usedCoordinates = _writeNC->usedCoordinates;
std::set< std::string >& dummyVarNames = _writeNC->dummyVarNames;
std::map< std::string, WriteNC::VarData >& varInfo = _writeNC->varInfo;
std::map< std::string, WriteNC::AttData >& globalAtts = _writeNC->globalAtts;
DebugOutput& dbgOut = _writeNC->dbgOut;
int tDim_in_dimNames = tDim;
int levDim_in_dimNames = levDim;
// If append mode, make sure we are in define mode; a simple open will not allow creation of new
// variables
if( append )
{
int errcode = NCFUNC( redef )( _fileId );
if( errcode != NC_NOERR ) MB_SET_ERR( MB_FAILURE, "Can't open file in redefine mode" );
}
// First initialize all coordinates, then fill VarData for actual variables (and dimensions)
// Check that for used coordinates we have found the tags
for( std::set< std::string >::iterator setIt = usedCoordinates.begin(); setIt != usedCoordinates.end(); ++setIt )
{
const std::string& coordName = *setIt;
std::map< std::string, WriteNC::VarData >::iterator vit = varInfo.find( coordName );
if( vit == varInfo.end() ) MB_SET_ERR( MB_FAILURE, "Can't find coordinate variable " << coordName );
WriteNC::VarData& varCoordData = vit->second;
varCoordData.varDims.resize( 1 );
// If not append, create it for sure
// If append, we might already have it, including the tag / variable with the same name
/*
* int ncmpi_inq_dimid(int ncid, const char *name, int *idp);
*/
if( append )
{
int dimId;
if( NCFUNC( inq_dimid )( _fileId, coordName.c_str(), &dimId ) == NC_NOERR )
{ // If not found, create it later
varCoordData.varDims[0] = dimId;
dbgOut.tprintf( 2, " file already has coordName %s dim id is %d \n", coordName.c_str(),
(int)varCoordData.varDims[0] );
// Update tDim and levDim to actual dimension id
if( coordName == dimNames[tDim_in_dimNames] )
tDim = varCoordData.varDims[0];
else if( coordName == dimNames[levDim_in_dimNames] )
levDim = varCoordData.varDims[0];
// Skip dummy coordinate variables (e.g. ncol)
if( dummyVarNames.find( coordName ) != dummyVarNames.end() ) continue;
// Check that the coordinate is a variable too
// Inquire for a variable with the same name
int varId;
if( NCFUNC( inq_varid )( _fileId, coordName.c_str(), &varId ) != NC_NOERR )
MB_SET_ERR( MB_FAILURE, "We do not have a variable with the same name " << coordName );
// We should also check that this variable has one dimension, and it is dimId
varCoordData.varId = varId;
dbgOut.tprintf( 2, " file already has coordinate %s and varId is %d \n", coordName.c_str(), varId );
continue; // Maybe more checks are needed here
}
}
/* int nc_def_dim (int ncid, const char *name, size_t len, int *dimidp);
* example: status = nc_def_dim(fileId, "lat", 18L, &latid);
*/
// Actually define a dimension
if( NCFUNC( def_dim )( _fileId, coordName.c_str(), (size_t)varCoordData.sz, &varCoordData.varDims[0] ) !=
NC_NOERR )
MB_SET_ERR( MB_FAILURE, "Failed to generate dimension " << coordName );
dbgOut.tprintf( 2, " for coordName %s dim id is %d \n", coordName.c_str(), (int)varCoordData.varDims[0] );
// Update tDim and levDim to actual dimension id
if( coordName == dimNames[tDim_in_dimNames] )
tDim = varCoordData.varDims[0];
else if( coordName == dimNames[levDim_in_dimNames] )
levDim = varCoordData.varDims[0];
// Create a variable with the same name, and its only dimension the one we just defined
/*
* int nc_def_var (int ncid, const char *name, nc_type xtype,
int ndims, const int dimids[], int *varidp);
example:
http://www.unidata.ucar.edu/software/netcdf/docs/netcdf-c/nc_005fdef_005fvar.html#nc_005fdef_005fvar
*/
// Skip dummy coordinate variables (e.g. ncol)
if( dummyVarNames.find( coordName ) != dummyVarNames.end() ) continue;
// Define a coordinate variable
if( NCFUNC( def_var )( _fileId, coordName.c_str(), varCoordData.varDataType, 1, &( varCoordData.varDims[0] ),
&varCoordData.varId ) != NC_NOERR )
MB_SET_ERR( MB_FAILURE, "Failed to create coordinate variable " << coordName );
dbgOut.tprintf( 2, " for coordName %s variable id is %d \n", coordName.c_str(), varCoordData.varId );
}
// Now look at requested variables, and update from the index in dimNames to the actual
// dimension id
for( size_t i = 0; i < var_names.size(); i++ )
{
std::map< std::string, WriteNC::VarData >::iterator vit = varInfo.find( var_names[i] );
if( vit == varInfo.end() ) MB_SET_ERR( MB_FAILURE, "Can't find requested variable " << var_names[i] );
// Skip coordinate variables
if( usedCoordinates.find( var_names[i] ) != usedCoordinates.end() ) continue;
WriteNC::VarData& variableData = vit->second;
// The index is for dimNames; we need to find out the actual dimension id (from above)
int numDims = (int)variableData.varDims.size();
for( int j = 0; j < numDims; j++ )
{
std::string dimName = dimNames[variableData.varDims[j]];
std::map< std::string, WriteNC::VarData >::iterator vit2 = varInfo.find( dimName );
if( vit2 == varInfo.end() )
MB_SET_ERR( MB_FAILURE, "Can't find requested coordinate variable " << dimName );
WriteNC::VarData& coordData = vit2->second;
// Index in dimNames to actual dimension id
variableData.varDims[j] = coordData.varDims[0]; // This one, being a coordinate, is the only one
dbgOut.tprintf( 2, " dimension with index %d name %s has ID %d \n", j, dimName.c_str(),
variableData.varDims[j] );
}
// Define the variable now:
int errCode =
NCFUNC( def_var )( _fileId, desired_names[i].c_str(), variableData.varDataType,
(int)variableData.varDims.size(), &( variableData.varDims[0] ), &variableData.varId );
if( errCode != NC_NOERR ) MB_SET_ERR( MB_FAILURE, "Failed to create requested variable " << desired_names[i] );
dbgOut.tprintf( 2, " for variable %s with desired name %s variable id is %d \n", var_names[i].c_str(),
desired_names[i].c_str(), variableData.varId );
// Now define the variable, with all dimensions
}
// Define global attributes (exactly copied from the original file for the time being)
// Should we modify some of them (e.g. revision_Id) later?
std::map< std::string, WriteNC::AttData >::iterator attIt;
for( attIt = globalAtts.begin(); attIt != globalAtts.end(); ++attIt )
{
const std::string& attName = attIt->first;
WriteNC::AttData& attData = attIt->second;
NCDF_SIZE& attLen = attData.attLen;
nc_type& attDataType = attData.attDataType;
const std::string& attValue = attData.attValue;
switch( attDataType )
{
case NC_BYTE:
case NC_CHAR:
if( NC_NOERR !=
NCFUNC( put_att_text )( _fileId, NC_GLOBAL, attName.c_str(), attLen, attValue.c_str() ) )
MB_SET_ERR( MB_FAILURE, "Failed to define text type attribute" );
break;
case NC_DOUBLE:
if( NC_NOERR != NCFUNC( put_att_double )( _fileId, NC_GLOBAL, attName.c_str(), NC_DOUBLE, 1,
(double*)attValue.c_str() ) )
MB_SET_ERR( MB_FAILURE, "Failed to define double type attribute" );
break;
case NC_FLOAT:
if( NC_NOERR != NCFUNC( put_att_float )( _fileId, NC_GLOBAL, attName.c_str(), NC_FLOAT, 1,
(float*)attValue.c_str() ) )
MB_SET_ERR( MB_FAILURE, "Failed to define float type attribute" );
break;
case NC_INT:
if( NC_NOERR !=
NCFUNC( put_att_int )( _fileId, NC_GLOBAL, attName.c_str(), NC_INT, 1, (int*)attValue.c_str() ) )
MB_SET_ERR( MB_FAILURE, "Failed to define int type attribute" );
break;
case NC_SHORT:
if( NC_NOERR != NCFUNC( put_att_short )( _fileId, NC_GLOBAL, attName.c_str(), NC_SHORT, 1,
(short*)attValue.c_str() ) )
MB_SET_ERR( MB_FAILURE, "Failed to define short type attribute" );
break;
default:
MB_SET_ERR( MB_FAILURE, "Unknown attribute data type" );
}
}
// Take it out of define mode
if( NC_NOERR != NCFUNC( enddef )( _fileId ) ) MB_SET_ERR( MB_FAILURE, "Failed to close define mode" );
return MB_SUCCESS;
}
virtual ErrorCode moab::NCWriteHelper::write_nonset_variables | ( | std::vector< WriteNC::VarData > & | vdatas, |
std::vector< int > & | tstep_nums | ||
) | [protected, pure virtual] |
Implemented in moab::ScdNCWriteHelper, moab::NCWriteGCRM, moab::NCWriteHOMME, and moab::NCWriteMPAS.
Referenced by write_values().
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.
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().
{
int success;
// CAUTION: if the NetCDF ID is from a previous call to ncmpi_create rather than ncmpi_open,
// all processors need to call ncmpi_begin_indep_data(). If only the root processor does so,
// ncmpi_begin_indep_data() call will be blocked forever :(
#ifdef MOAB_HAVE_PNETCDF
// Enter independent I/O mode
success = NCFUNC( begin_indep_data )( _fileId );
if( success ) MB_SET_ERR( MB_FAILURE, "Failed to begin independent I/O mode" );
#endif
int rank = 0;
#ifdef MOAB_HAVE_MPI
bool& isParallel = _writeNC->isParallel;
if( isParallel )
{
ParallelComm*& myPcomm = _writeNC->myPcomm;
rank = myPcomm->proc_config().proc_rank();
}
#endif
if( 0 == rank )
{
for( unsigned int i = 0; i < vsetdatas.size(); i++ )
{
WriteNC::VarData& variableData = vsetdatas[i];
// Set variables with timesteps, e.g. xtime(Time) or xtime(Time, StrLen)
if( variableData.has_tsteps )
{
MB_SET_ERR( MB_NOT_IMPLEMENTED, "Writing set variables with timesteps is not implemented yet" );
}
switch( variableData.varDataType )
{
case NC_DOUBLE:
// Independent I/O mode put
success = NCFUNCP( _vara_double )( _fileId, variableData.varId, &variableData.writeStarts[0],
&variableData.writeCounts[0],
(double*)( variableData.memoryHogs[0] ) );
if( success )
MB_SET_ERR( MB_FAILURE, "Failed to write double data for variable " << variableData.varName );
break;
case NC_INT:
// Independent I/O mode put
success =
NCFUNCP( _vara_int )( _fileId, variableData.varId, &variableData.writeStarts[0],
&variableData.writeCounts[0], (int*)( variableData.memoryHogs[0] ) );
if( success )
MB_SET_ERR( MB_FAILURE, "Failed to write int data for variable " << variableData.varName );
break;
default:
MB_SET_ERR( MB_NOT_IMPLEMENTED, "Writing non-double or non-int data is not implemented yet" );
}
}
}
#ifdef MOAB_HAVE_PNETCDF
// End independent I/O mode
success = NCFUNC( end_indep_data )( _fileId );
if( success ) MB_SET_ERR( MB_FAILURE, "Failed to end independent I/O mode" );
#endif
return MB_SUCCESS;
}
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.
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().
{
std::set< std::string >& usedCoordinates = _writeNC->usedCoordinates;
std::set< std::string >& dummyVarNames = _writeNC->dummyVarNames;
std::map< std::string, WriteNC::VarData >& varInfo = _writeNC->varInfo;
std::vector< WriteNC::VarData > vdatas;
std::vector< WriteNC::VarData > vsetdatas;
// For set variables, include coordinates used by requested var_names
for( std::set< std::string >::iterator setIt = usedCoordinates.begin(); setIt != usedCoordinates.end(); ++setIt )
{
const std::string& coordName = *setIt;
// Skip dummy coordinate variables (if any)
if( dummyVarNames.find( coordName ) != dummyVarNames.end() ) continue;
std::map< std::string, WriteNC::VarData >::iterator vit = varInfo.find( coordName );
if( vit == varInfo.end() )
{
MB_SET_ERR( MB_FAILURE, "Can't find coordinate variable " << coordName );
}
vsetdatas.push_back( vit->second );
}
// Collect non-set and set variables from requested var_names
for( unsigned int i = 0; i < var_names.size(); i++ )
{
std::map< std::string, WriteNC::VarData >::iterator vit = varInfo.find( var_names[i] );
if( vit == varInfo.end() )
{
MB_SET_ERR( MB_FAILURE, "Can't find requested variable " << var_names[i] );
}
WriteNC::VarData& variableData = vit->second;
if( WriteNC::ENTLOCSET == variableData.entLoc )
{
// Used coordinates has all ready been included
if( usedCoordinates.find( var_names[i] ) != usedCoordinates.end() ) continue;
vsetdatas.push_back( variableData );
}
else
vdatas.push_back( variableData );
}
// Assume that the data ranges do not overlap across processors
// While overlapped writing might still work, we should better not take that risk
write_nonset_variables( vdatas, tstep_nums );
// Use independent I/O mode put, since this write is only for the root processor
write_set_variables( vsetdatas, tstep_nums );
return MB_SUCCESS;
}
int moab::NCWriteHelper::_fileId [protected] |
Cache some information from WriteNC.
Definition at line 63 of file NCWriteHelper.hpp.
Referenced by init_file(), moab::NCWriteGCRM::write_nonset_variables(), moab::NCWriteHOMME::write_nonset_variables(), moab::NCWriteMPAS::write_nonset_variables(), moab::ScdNCWriteHelper::write_nonset_variables(), and write_set_variables().
EntityHandle moab::NCWriteHelper::_fileSet [protected] |
Definition at line 65 of file NCWriteHelper.hpp.
Referenced by moab::NCWriteGCRM::collect_mesh_info(), moab::NCWriteMPAS::collect_mesh_info(), moab::NCWriteHOMME::collect_mesh_info(), moab::ScdNCWriteHelper::collect_mesh_info(), and collect_variable_data().
const FileOptions& moab::NCWriteHelper::_opts [protected] |
Definition at line 64 of file NCWriteHelper.hpp.
WriteNC* moab::NCWriteHelper::_writeNC [protected] |
Allow NCWriteHelper to directly access members of WriteNC.
Definition at line 60 of file NCWriteHelper.hpp.
Referenced by moab::NCWriteGCRM::collect_mesh_info(), moab::NCWriteHOMME::collect_mesh_info(), moab::NCWriteMPAS::collect_mesh_info(), moab::ScdNCWriteHelper::collect_mesh_info(), moab::NCWriteGCRM::collect_variable_data(), moab::NCWriteMPAS::collect_variable_data(), moab::NCWriteHOMME::collect_variable_data(), collect_variable_data(), moab::ScdNCWriteHelper::collect_variable_data(), init_file(), moab::NCWriteHOMME::write_nonset_variables(), moab::NCWriteGCRM::write_nonset_variables(), moab::NCWriteMPAS::write_nonset_variables(), moab::ScdNCWriteHelper::write_nonset_variables(), write_set_variables(), and write_values().
int moab::NCWriteHelper::levDim [protected] |
Definition at line 71 of file NCWriteHelper.hpp.
Referenced by moab::NCWriteGCRM::collect_mesh_info(), moab::NCWriteHOMME::collect_mesh_info(), moab::NCWriteMPAS::collect_mesh_info(), moab::ScdNCWriteHelper::collect_mesh_info(), moab::NCWriteGCRM::collect_variable_data(), moab::NCWriteMPAS::collect_variable_data(), collect_variable_data(), and init_file().
Range moab::NCWriteHelper::localCellsOwned [protected] |
Local owned cells, edges and vertices.
Definition at line 74 of file NCWriteHelper.hpp.
Referenced by moab::NCWriteGCRM::collect_mesh_info(), moab::NCWriteMPAS::collect_mesh_info(), moab::ScdNCWriteHelper::collect_mesh_info(), moab::NCWriteMPAS::write_nonset_variables(), moab::NCWriteGCRM::write_nonset_variables(), and moab::ScdNCWriteHelper::write_nonset_variables().
Range moab::NCWriteHelper::localEdgesOwned [protected] |
Definition at line 74 of file NCWriteHelper.hpp.
Referenced by moab::NCWriteGCRM::collect_mesh_info(), moab::NCWriteMPAS::collect_mesh_info(), moab::NCWriteMPAS::collect_variable_data(), moab::NCWriteGCRM::collect_variable_data(), moab::NCWriteGCRM::write_nonset_variables(), and moab::NCWriteMPAS::write_nonset_variables().
Range moab::NCWriteHelper::localVertsOwned [protected] |
Definition at line 74 of file NCWriteHelper.hpp.
Referenced by moab::NCWriteGCRM::collect_mesh_info(), moab::NCWriteMPAS::collect_mesh_info(), moab::NCWriteHOMME::collect_mesh_info(), moab::NCWriteHOMME::write_nonset_variables(), moab::NCWriteGCRM::write_nonset_variables(), and moab::NCWriteMPAS::write_nonset_variables().
int moab::NCWriteHelper::nLevels [protected] |
Definition at line 68 of file NCWriteHelper.hpp.
Referenced by moab::NCWriteGCRM::collect_mesh_info(), moab::NCWriteMPAS::collect_mesh_info(), moab::NCWriteHOMME::collect_mesh_info(), moab::ScdNCWriteHelper::collect_mesh_info(), and collect_variable_data().
int moab::NCWriteHelper::nTimeSteps [protected] |
Dimensions of time and level.
Definition at line 68 of file NCWriteHelper.hpp.
Referenced by moab::NCWriteGCRM::collect_mesh_info(), moab::NCWriteMPAS::collect_mesh_info(), moab::NCWriteHOMME::collect_mesh_info(), moab::ScdNCWriteHelper::collect_mesh_info(), and collect_variable_data().
int moab::NCWriteHelper::tDim [protected] |
Dimension numbers for time and level.
Definition at line 71 of file NCWriteHelper.hpp.
Referenced by moab::NCWriteGCRM::collect_mesh_info(), moab::NCWriteHOMME::collect_mesh_info(), moab::NCWriteMPAS::collect_mesh_info(), moab::ScdNCWriteHelper::collect_mesh_info(), moab::NCWriteGCRM::collect_variable_data(), moab::NCWriteHOMME::collect_variable_data(), moab::NCWriteMPAS::collect_variable_data(), collect_variable_data(), moab::ScdNCWriteHelper::collect_variable_data(), init_file(), moab::NCWriteGCRM::write_nonset_variables(), moab::NCWriteHOMME::write_nonset_variables(), moab::NCWriteMPAS::write_nonset_variables(), and moab::ScdNCWriteHelper::write_nonset_variables().
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().