Mesh Oriented datABase  (version 5.4.1)
Array-based unstructured mesh datastructure
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 ()

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)

Detailed Description

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

Definition at line 81 of file NCWriteHelper.hpp.


Constructor & Destructor Documentation

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

Definition at line 84 of file NCWriteHelper.hpp.

References lCDims, and lDims.

        : 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.

{}

Member Function Documentation

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;
}
template<typename T >
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;
}

Member Data Documentation

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().

List of all members.


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines