Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
Child helper class for HOMME grid (CAM_SE) More...
#include <NCHelperHOMME.hpp>
Public Member Functions | |
NCHelperHOMME (ReadNC *readNC, int fileId, const FileOptions &opts, EntityHandle fileSet) | |
Static Public Member Functions | |
static bool | can_read_file (ReadNC *readNC, int fileId) |
Private Member Functions | |
virtual ErrorCode | init_mesh_vals () |
Implementation of NCHelper::init_mesh_vals() | |
virtual ErrorCode | check_existing_mesh () |
Implementation of NCHelper::check_existing_mesh() | |
virtual ErrorCode | create_mesh (Range &faces) |
Implementation of NCHelper::create_mesh() | |
virtual std::string | get_mesh_type_name () |
Implementation of NCHelper::get_mesh_type_name() | |
virtual ErrorCode | read_ucd_variables_to_nonset_allocate (std::vector< ReadNC::VarData > &vdatas, std::vector< int > &tstep_nums) |
Implementation of UcdNCHelper::read_ucd_variables_to_nonset_allocate() | |
virtual ErrorCode | read_ucd_variables_to_nonset (std::vector< ReadNC::VarData > &vdatas, std::vector< int > &tstep_nums) |
Implementation of UcdNCHelper::read_ucd_variables_to_nonset() | |
Private Attributes | |
int | _spectralOrder |
int | connectId |
bool | isConnFile |
Child helper class for HOMME grid (CAM_SE)
Definition at line 18 of file NCHelperHOMME.hpp.
moab::NCHelperHOMME::NCHelperHOMME | ( | ReadNC * | readNC, |
int | fileId, | ||
const FileOptions & | opts, | ||
EntityHandle | fileSet | ||
) |
Definition at line 11 of file NCHelperHOMME.cpp.
References _spectralOrder, moab::ReadNC::fileId, moab::ReadNC::globalAtts, isConnFile, and NCFUNC.
: UcdNCHelper( readNC, fileId, opts, fileSet ), _spectralOrder( -1 ), connectId( -1 ), isConnFile( false ) { // Calculate spectral order std::map< std::string, ReadNC::AttData >::iterator attIt = readNC->globalAtts.find( "np" ); if( attIt != readNC->globalAtts.end() ) { int success = NCFUNC( get_att_int )( readNC->fileId, attIt->second.attVarId, attIt->second.attName.c_str(), &_spectralOrder ); if( 0 == success ) _spectralOrder--; // Spectral order is one less than np } else { // As can_read_file() returns true and there is no global attribute "np", it should be a // connectivity file isConnFile = true; _spectralOrder = 3; // Assume np is 4 } }
bool moab::NCHelperHOMME::can_read_file | ( | ReadNC * | readNC, |
int | fileId | ||
) | [static] |
Definition at line 31 of file NCHelperHOMME.cpp.
References moab::ReadNC::dimNames, moab::ReadNC::globalAtts, and NCFUNC.
Referenced by moab::NCHelper::get_nc_helper().
{ // If global attribute "np" exists then it should be the HOMME grid if( readNC->globalAtts.find( "np" ) != readNC->globalAtts.end() ) { // Make sure it is CAM grid std::map< std::string, ReadNC::AttData >::iterator attIt = readNC->globalAtts.find( "source" ); if( attIt == readNC->globalAtts.end() ) return false; unsigned int sz = attIt->second.attLen; std::string att_data; att_data.resize( sz + 1 ); att_data[sz] = '\000'; int success = NCFUNC( get_att_text )( fileId, attIt->second.attVarId, attIt->second.attName.c_str(), &att_data[0] ); if( success ) return false; if( att_data.find( "CAM" ) == std::string::npos ) return false; return true; } else { // If dimension names "ncol" AND "ncorners" AND "ncells" exist, then it should be the HOMME // connectivity file In this case, the mesh can still be created std::vector< std::string >& dimNames = readNC->dimNames; if( ( std::find( dimNames.begin(), dimNames.end(), std::string( "ncol" ) ) != dimNames.end() ) && ( std::find( dimNames.begin(), dimNames.end(), std::string( "ncorners" ) ) != dimNames.end() ) && ( std::find( dimNames.begin(), dimNames.end(), std::string( "ncells" ) ) != dimNames.end() ) ) return true; } return false; }
ErrorCode moab::NCHelperHOMME::check_existing_mesh | ( | ) | [private, virtual] |
Implementation of NCHelper::check_existing_mesh()
Implements moab::NCHelper.
Definition at line 223 of file NCHelperHOMME.cpp.
References moab::NCHelper::_fileSet, moab::NCHelper::_readNC, moab::Range::empty(), ErrorCode, moab::Interface::get_entities_by_dimension(), moab::UcdNCHelper::localGidVerts, MB_CHK_SET_ERR, MB_SUCCESS, moab::ReadNC::mbImpl, moab::ReadNC::mGlobalIdTag, moab::UcdNCHelper::nLocalVertices, moab::ReadNC::noMesh, moab::Range::size(), and moab::Interface::tag_get_data().
{ Interface*& mbImpl = _readNC->mbImpl; Tag& mGlobalIdTag = _readNC->mGlobalIdTag; bool& noMesh = _readNC->noMesh; if( noMesh && localGidVerts.empty() ) { // We need to populate localGidVerts range with the gids of vertices from current file set // localGidVerts is important in reading the variable data into the nodes // Also, for our purposes, localGidVerts is truly the GLOBAL_ID tag data, not other // file_id tags that could get passed around in other scenarios for parallel reading // Get all vertices from current file set (it is the input set in no_mesh scenario) Range local_verts; ErrorCode rval = mbImpl->get_entities_by_dimension( _fileSet, 0, local_verts );MB_CHK_SET_ERR( rval, "Trouble getting local vertices in current file set" ); if( !local_verts.empty() ) { std::vector< int > gids( local_verts.size() ); // !IMPORTANT : this has to be the GLOBAL_ID tag rval = mbImpl->tag_get_data( mGlobalIdTag, local_verts, &gids[0] );MB_CHK_SET_ERR( rval, "Trouble getting local gid values of vertices" ); // Restore localGidVerts std::copy( gids.rbegin(), gids.rend(), range_inserter( localGidVerts ) ); nLocalVertices = localGidVerts.size(); } } return MB_SUCCESS; }
ErrorCode moab::NCHelperHOMME::create_mesh | ( | Range & | faces | ) | [private, virtual] |
Implementation of NCHelper::create_mesh()
Implements moab::NCHelper.
Definition at line 256 of file NCHelperHOMME.cpp.
References moab::NCHelper::_fileSet, moab::NCHelper::_opts, moab::NCHelper::_readNC, _spectralOrder, moab::Interface::add_entities(), moab::Range::begin(), moab::Interface::connect_iterate(), connectId, moab::ReadUtilIface::create_gather_set(), moab::SpectralMeshTool::create_spectral_elems(), moab::ReadNC::dbgOut, moab::Range::end(), ErrorCode, moab::ReadNC::fileId, moab::ReadNC::fileName, moab::ReadNC::gatherSetRank, moab::ReadNC::get_dimensions(), moab::ReadUtilIface::get_element_connect(), moab::ReadUtilIface::get_node_coords(), moab::FileOptions::get_str_option(), moab::Range::insert(), isConnFile, moab::ReadNC::isParallel, moab::NCHelper::levVals, moab::UcdNCHelper::localGidVerts, MB_CHK_SET_ERR, MB_SET_ERR, MB_SUCCESS, MB_TAG_CREAT, MB_TAG_SPARSE, MB_TYPE_INTEGER, moab::ReadNC::mbImpl, MBQUAD, moab::Range::merge(), moab::ReadNC::mGlobalIdTag, moab::ReadNC::mpFileIdTag, NCDF_SIZE, moab::UcdNCHelper::nCells, NCFUNC, NCFUNCAG, moab::UcdNCHelper::nLocalVertices, moab::UcdNCHelper::nVertices, moab::ProcConfig::proc_comm(), moab::ParallelComm::proc_config(), moab::ProcConfig::proc_rank(), moab::ProcConfig::proc_size(), moab::ReadNC::readMeshIface, moab::Range::size(), moab::SpectralMeshTool::spectral_vertices_tag(), moab::ReadNC::spectralMesh, moab::Interface::tag_get_bytes(), moab::Interface::tag_get_handle(), moab::Interface::tag_iterate(), moab::Interface::tag_set_data(), moab::DebugOutput::tprintf(), moab::ReadNC::trivialPartitionShift, moab::UcdNCHelper::xVertVals, and moab::UcdNCHelper::yVertVals.
{ Interface*& mbImpl = _readNC->mbImpl; std::string& fileName = _readNC->fileName; Tag& mGlobalIdTag = _readNC->mGlobalIdTag; const Tag*& mpFileIdTag = _readNC->mpFileIdTag; DebugOutput& dbgOut = _readNC->dbgOut; bool& spectralMesh = _readNC->spectralMesh; int& gatherSetRank = _readNC->gatherSetRank; int& trivialPartitionShift = _readNC->trivialPartitionShift; int rank = 0; int procs = 1; #ifdef MOAB_HAVE_MPI bool& isParallel = _readNC->isParallel; if( isParallel ) { ParallelComm*& myPcomm = _readNC->myPcomm; rank = myPcomm->proc_config().proc_rank(); procs = myPcomm->proc_config().proc_size(); } #endif ErrorCode rval; int success = 0; // Need to get/read connectivity data before creating elements std::string conn_fname; if( isConnFile ) { // Connectivity file has already been read connectId = _readNC->fileId; } else { // Try to open the connectivity file through CONN option, if used rval = _opts.get_str_option( "CONN", conn_fname ); if( MB_SUCCESS != rval ) { // Default convention for reading HOMME is a file HommeMapping.nc in same dir as data // file conn_fname = std::string( fileName ); size_t idx = conn_fname.find_last_of( "/" ); if( idx != std::string::npos ) conn_fname = conn_fname.substr( 0, idx ).append( "/HommeMapping.nc" ); else conn_fname = "HommeMapping.nc"; } #ifdef MOAB_HAVE_PNETCDF #ifdef MOAB_HAVE_MPI if( isParallel ) { ParallelComm*& myPcomm = _readNC->myPcomm; success = NCFUNC( open )( myPcomm->proc_config().proc_comm(), conn_fname.c_str(), 0, MPI_INFO_NULL, &connectId ); } else success = NCFUNC( open )( MPI_COMM_SELF, conn_fname.c_str(), 0, MPI_INFO_NULL, &connectId ); #endif #else success = NCFUNC( open )( conn_fname.c_str(), 0, &connectId ); #endif if( success ) MB_SET_ERR( MB_FAILURE, "Failed on open" ); } std::vector< std::string > conn_names; std::vector< int > conn_vals; rval = _readNC->get_dimensions( connectId, conn_names, conn_vals );MB_CHK_SET_ERR( rval, "Failed to get dimensions for connectivity" ); // Read connectivity into temporary variable int num_fine_quads = 0; int num_coarse_quads = 0; int start_idx = 0; std::vector< std::string >::iterator vit; int idx = 0; if( ( vit = std::find( conn_names.begin(), conn_names.end(), "ncells" ) ) != conn_names.end() ) idx = vit - conn_names.begin(); else if( ( vit = std::find( conn_names.begin(), conn_names.end(), "ncenters" ) ) != conn_names.end() ) idx = vit - conn_names.begin(); else { MB_SET_ERR( MB_FAILURE, "Failed to get number of quads" ); } int num_quads = conn_vals[idx]; if( !isConnFile && num_quads != nCells ) { dbgOut.tprintf( 1, "Warning: number of quads from %s and cells from %s are inconsistent; " "num_quads = %d, nCells = %d.\n", conn_fname.c_str(), fileName.c_str(), num_quads, nCells ); } // Get the connectivity into tmp_conn2 and permute into tmp_conn int cornerVarId; success = NCFUNC( inq_varid )( connectId, "element_corners", &cornerVarId ); if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of 'element_corners'" ); NCDF_SIZE tmp_starts[2] = { 0, 0 }; NCDF_SIZE tmp_counts[2] = { 4, static_cast< NCDF_SIZE >( num_quads ) }; std::vector< int > tmp_conn( 4 * num_quads ), tmp_conn2( 4 * num_quads ); success = NCFUNCAG( _vara_int )( connectId, cornerVarId, tmp_starts, tmp_counts, &tmp_conn2[0] ); if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get temporary connectivity" ); if( isConnFile ) { // This data/connectivity file will be closed later in ReadNC::load_file() } else { success = NCFUNC( close )( connectId ); if( success ) MB_SET_ERR( MB_FAILURE, "Failed on close" ); } // Permute the connectivity for( int i = 0; i < num_quads; i++ ) { tmp_conn[4 * i] = tmp_conn2[i]; tmp_conn[4 * i + 1] = tmp_conn2[i + 1 * num_quads]; tmp_conn[4 * i + 2] = tmp_conn2[i + 2 * num_quads]; tmp_conn[4 * i + 3] = tmp_conn2[i + 3 * num_quads]; } // Need to know whether we'll be creating gather mesh later, to make sure // we allocate enough space in one shot bool create_gathers = false; if( rank == gatherSetRank ) create_gathers = true; // Shift rank to obtain a rotated trivial partition int shifted_rank = rank; if( procs >= 2 && trivialPartitionShift > 0 ) shifted_rank = ( rank + trivialPartitionShift ) % procs; // Compute the number of local quads, accounting for coarse or fine representation // spectral_unit is the # fine quads per coarse quad, or spectralOrder^2 int spectral_unit = ( spectralMesh ? _spectralOrder * _spectralOrder : 1 ); // num_coarse_quads is the number of quads instantiated in MOAB; if !spectralMesh, // num_coarse_quads = num_fine_quads num_coarse_quads = int( std::floor( 1.0 * num_quads / ( spectral_unit * procs ) ) ); // start_idx is the starting index in the HommeMapping connectivity list for this proc, before // converting to coarse quad representation start_idx = 4 * shifted_rank * num_coarse_quads * spectral_unit; // iextra = # coarse quads extra after equal split over procs int iextra = num_quads % ( procs * spectral_unit ); if( shifted_rank < iextra ) num_coarse_quads++; start_idx += 4 * spectral_unit * std::min( shifted_rank, iextra ); // num_fine_quads is the number of quads in the connectivity list in HommeMapping file assigned // to this proc num_fine_quads = spectral_unit * num_coarse_quads; // Now create num_coarse_quads EntityHandle* conn_arr; EntityHandle start_vertex; Range tmp_range; // Read connectivity into that space EntityHandle* sv_ptr = NULL; EntityHandle start_quad; SpectralMeshTool smt( mbImpl, _spectralOrder ); if( !spectralMesh ) { rval = _readNC->readMeshIface->get_element_connect( num_coarse_quads, 4, MBQUAD, 0, start_quad, conn_arr, // Might have to create gather mesh later ( create_gathers ? num_coarse_quads + num_quads : num_coarse_quads ) );MB_CHK_SET_ERR( rval, "Failed to create local quads" ); tmp_range.insert( start_quad, start_quad + num_coarse_quads - 1 ); int* tmp_conn_end = ( &tmp_conn[start_idx + 4 * num_fine_quads - 1] ) + 1; std::copy( &tmp_conn[start_idx], tmp_conn_end, conn_arr ); std::copy( conn_arr, conn_arr + 4 * num_fine_quads, range_inserter( localGidVerts ) ); } else { rval = smt.create_spectral_elems( &tmp_conn[0], num_fine_quads, 2, tmp_range, start_idx, &localGidVerts );MB_CHK_SET_ERR( rval, "Failed to create spectral elements" ); int count, v_per_e; rval = mbImpl->connect_iterate( tmp_range.begin(), tmp_range.end(), conn_arr, v_per_e, count );MB_CHK_SET_ERR( rval, "Failed to get connectivity of spectral elements" ); rval = mbImpl->tag_iterate( smt.spectral_vertices_tag( true ), tmp_range.begin(), tmp_range.end(), count, (void*&)sv_ptr );MB_CHK_SET_ERR( rval, "Failed to get fine connectivity of spectral elements" ); } // Create vertices nLocalVertices = localGidVerts.size(); std::vector< double* > arrays; rval = _readNC->readMeshIface->get_node_coords( 3, nLocalVertices, 0, start_vertex, arrays, // Might have to create gather mesh later ( create_gathers ? nLocalVertices + nVertices : nLocalVertices ) );MB_CHK_SET_ERR( rval, "Failed to create local vertices" ); // Set vertex coordinates Range::iterator rit; double* xptr = arrays[0]; double* yptr = arrays[1]; double* zptr = arrays[2]; int i; for( i = 0, rit = localGidVerts.begin(); i < nLocalVertices; i++, ++rit ) { assert( *rit < xVertVals.size() + 1 ); xptr[i] = xVertVals[( *rit ) - 1]; // lon yptr[i] = yVertVals[( *rit ) - 1]; // lat } // Convert lon/lat/rad to x/y/z const double pideg = acos( -1.0 ) / 180.0; double rad = ( isConnFile ) ? 8000.0 : 8000.0 + levVals[0]; for( i = 0; i < nLocalVertices; i++ ) { double cosphi = cos( pideg * yptr[i] ); double zmult = sin( pideg * yptr[i] ); double xmult = cosphi * cos( xptr[i] * pideg ); double ymult = cosphi * sin( xptr[i] * pideg ); xptr[i] = rad * xmult; yptr[i] = rad * ymult; zptr[i] = rad * zmult; } // Get ptr to gid memory for vertices Range vert_range( start_vertex, start_vertex + nLocalVertices - 1 ); void* data; int count; rval = mbImpl->tag_iterate( mGlobalIdTag, vert_range.begin(), vert_range.end(), count, data );MB_CHK_SET_ERR( rval, "Failed to iterate global id tag on local vertices" ); assert( count == nLocalVertices ); int* gid_data = (int*)data; std::copy( localGidVerts.begin(), localGidVerts.end(), gid_data ); // Duplicate global id data, which will be used to resolve sharing if( mpFileIdTag ) { rval = mbImpl->tag_iterate( *mpFileIdTag, vert_range.begin(), vert_range.end(), count, data );MB_CHK_SET_ERR( rval, "Failed to iterate file id tag on local vertices" ); assert( count == nLocalVertices ); int bytes_per_tag = 4; rval = mbImpl->tag_get_bytes( *mpFileIdTag, bytes_per_tag );MB_CHK_SET_ERR( rval, "Can't get number of bytes for file id tag" ); if( 4 == bytes_per_tag ) { gid_data = (int*)data; std::copy( localGidVerts.begin(), localGidVerts.end(), gid_data ); } else if( 8 == bytes_per_tag ) { // Should be a handle tag on 64 bit machine? long* handle_tag_data = (long*)data; std::copy( localGidVerts.begin(), localGidVerts.end(), handle_tag_data ); } } // Create map from file ids to vertex handles, used later to set connectivity std::map< EntityHandle, EntityHandle > vert_handles; for( rit = localGidVerts.begin(), i = 0; rit != localGidVerts.end(); ++rit, i++ ) vert_handles[*rit] = start_vertex + i; // Compute proper handles in connectivity using offset for( int q = 0; q < 4 * num_coarse_quads; q++ ) { conn_arr[q] = vert_handles[conn_arr[q]]; assert( conn_arr[q] ); } if( spectralMesh ) { int verts_per_quad = ( _spectralOrder + 1 ) * ( _spectralOrder + 1 ); for( int q = 0; q < verts_per_quad * num_coarse_quads; q++ ) { sv_ptr[q] = vert_handles[sv_ptr[q]]; assert( sv_ptr[q] ); } } // Add new vertices and quads to current file set faces.merge( tmp_range ); tmp_range.insert( start_vertex, start_vertex + nLocalVertices - 1 ); rval = mbImpl->add_entities( _fileSet, tmp_range );MB_CHK_SET_ERR( rval, "Failed to add new vertices and quads to current file set" ); // Mark the set with the spectral order Tag sporder; rval = mbImpl->tag_get_handle( "SPECTRAL_ORDER", 1, MB_TYPE_INTEGER, sporder, MB_TAG_SPARSE | MB_TAG_CREAT );MB_CHK_SET_ERR( rval, "Trouble creating SPECTRAL_ORDER tag" ); rval = mbImpl->tag_set_data( sporder, &_fileSet, 1, &_spectralOrder );MB_CHK_SET_ERR( rval, "Trouble setting data to SPECTRAL_ORDER tag" ); if( create_gathers ) { EntityHandle gather_set; rval = _readNC->readMeshIface->create_gather_set( gather_set );MB_CHK_SET_ERR( rval, "Failed to create gather set" ); // Create vertices arrays.clear(); // Don't need to specify allocation number here, because we know enough verts were created // before rval = _readNC->readMeshIface->get_node_coords( 3, nVertices, 0, start_vertex, arrays );MB_CHK_SET_ERR( rval, "Failed to create gather set vertices" ); xptr = arrays[0]; yptr = arrays[1]; zptr = arrays[2]; for( i = 0; i < nVertices; i++ ) { double cosphi = cos( pideg * yVertVals[i] ); double zmult = sin( pideg * yVertVals[i] ); double xmult = cosphi * cos( xVertVals[i] * pideg ); double ymult = cosphi * sin( xVertVals[i] * pideg ); xptr[i] = rad * xmult; yptr[i] = rad * ymult; zptr[i] = rad * zmult; } // Get ptr to gid memory for vertices Range gather_set_verts_range( start_vertex, start_vertex + nVertices - 1 ); rval = mbImpl->tag_iterate( mGlobalIdTag, gather_set_verts_range.begin(), gather_set_verts_range.end(), count, data );MB_CHK_SET_ERR( rval, "Failed to iterate global id tag on gather set vertices" ); assert( count == nVertices ); gid_data = (int*)data; for( int j = 1; j <= nVertices; j++ ) gid_data[j - 1] = j; // Set the file id tag too, it should be bigger something not interfering with global id if( mpFileIdTag ) { rval = mbImpl->tag_iterate( *mpFileIdTag, gather_set_verts_range.begin(), gather_set_verts_range.end(), count, data );MB_CHK_SET_ERR( rval, "Failed to iterate file id tag on gather set vertices" ); assert( count == nVertices ); int bytes_per_tag = 4; rval = mbImpl->tag_get_bytes( *mpFileIdTag, bytes_per_tag );MB_CHK_SET_ERR( rval, "Can't get number of bytes for file id tag" ); if( 4 == bytes_per_tag ) { gid_data = (int*)data; for( int j = 1; j <= nVertices; j++ ) gid_data[j - 1] = nVertices + j; // Bigger than global id tag } else if( 8 == bytes_per_tag ) { // Should be a handle tag on 64 bit machine? long* handle_tag_data = (long*)data; for( int j = 1; j <= nVertices; j++ ) handle_tag_data[j - 1] = nVertices + j; // Bigger than global id tag } } rval = mbImpl->add_entities( gather_set, gather_set_verts_range );MB_CHK_SET_ERR( rval, "Failed to add vertices to the gather set" ); // Create quads Range gather_set_quads_range; // Don't need to specify allocation number here, because we know enough quads were created // before rval = _readNC->readMeshIface->get_element_connect( num_quads, 4, MBQUAD, 0, start_quad, conn_arr );MB_CHK_SET_ERR( rval, "Failed to create gather set quads" ); gather_set_quads_range.insert( start_quad, start_quad + num_quads - 1 ); int* tmp_conn_end = ( &tmp_conn[4 * num_quads - 1] ) + 1; std::copy( &tmp_conn[0], tmp_conn_end, conn_arr ); for( i = 0; i != 4 * num_quads; i++ ) conn_arr[i] += start_vertex - 1; // Connectivity array is shifted by where the gather verts start rval = mbImpl->add_entities( gather_set, gather_set_quads_range );MB_CHK_SET_ERR( rval, "Failed to add quads to the gather set" ); } return MB_SUCCESS; }
virtual std::string moab::NCHelperHOMME::get_mesh_type_name | ( | ) | [inline, private, virtual] |
Implementation of NCHelper::get_mesh_type_name()
Implements moab::NCHelper.
Definition at line 32 of file NCHelperHOMME.hpp.
{ return "CAM_SE"; }
ErrorCode moab::NCHelperHOMME::init_mesh_vals | ( | ) | [private, virtual] |
Implementation of NCHelper::init_mesh_vals()
Implements moab::NCHelper.
Definition at line 64 of file NCHelperHOMME.cpp.
References moab::NCHelper::_fileId, moab::NCHelper::_readNC, moab::NCHelper::create_dummy_variables(), moab::ReadNC::dimLens, moab::ReadNC::dimNames, moab::ReadNC::VarData::entLoc, moab::ReadNC::ENTLOCVERT, ErrorCode, isConnFile, moab::NCHelper::levDim, moab::NCHelper::levVals, MB_CHK_SET_ERR, MB_SET_ERR, MB_SUCCESS, moab::UcdNCHelper::nCells, NCFUNC, moab::NCHelper::nLevels, moab::NCHelper::nTimeSteps, moab::ReadNC::VarData::numLev, moab::UcdNCHelper::nVertices, moab::NCHelper::read_coordinate(), t, moab::NCHelper::tDim, moab::NCHelper::tVals, moab::ReadNC::VarData::varDims, moab::ReadNC::varInfo, moab::UcdNCHelper::vDim, moab::UcdNCHelper::xVertVals, and moab::UcdNCHelper::yVertVals.
{ std::vector< std::string >& dimNames = _readNC->dimNames; std::vector< int >& dimLens = _readNC->dimLens; std::map< std::string, ReadNC::VarData >& varInfo = _readNC->varInfo; ErrorCode rval; unsigned int idx; std::vector< std::string >::iterator vit; // Look for time dimension if( isConnFile ) { // Connectivity file might not have time dimension } else { if( ( vit = std::find( dimNames.begin(), dimNames.end(), "time" ) ) != dimNames.end() ) idx = vit - dimNames.begin(); else if( ( vit = std::find( dimNames.begin(), dimNames.end(), "t" ) ) != dimNames.end() ) idx = vit - dimNames.begin(); else { MB_SET_ERR( MB_FAILURE, "Couldn't find 'time' or 't' dimension" ); } tDim = idx; nTimeSteps = dimLens[idx]; } // Get number of vertices (labeled as number of columns) if( ( vit = std::find( dimNames.begin(), dimNames.end(), "ncol" ) ) != dimNames.end() ) idx = vit - dimNames.begin(); else { MB_SET_ERR( MB_FAILURE, "Couldn't find 'ncol' dimension" ); } vDim = idx; nVertices = dimLens[idx]; // Set number of cells nCells = nVertices - 2; // Get number of levels if( isConnFile ) { // Connectivity file might not have level dimension } else { if( ( vit = std::find( dimNames.begin(), dimNames.end(), "lev" ) ) != dimNames.end() ) idx = vit - dimNames.begin(); else if( ( vit = std::find( dimNames.begin(), dimNames.end(), "ilev" ) ) != dimNames.end() ) idx = vit - dimNames.begin(); else { MB_SET_ERR( MB_FAILURE, "Couldn't find 'lev' or 'ilev' dimension" ); } levDim = idx; nLevels = dimLens[idx]; } // Store lon values in xVertVals std::map< std::string, ReadNC::VarData >::iterator vmit; if( ( vmit = varInfo.find( "lon" ) ) != varInfo.end() && ( *vmit ).second.varDims.size() == 1 ) { rval = read_coordinate( "lon", 0, nVertices - 1, xVertVals );MB_CHK_SET_ERR( rval, "Trouble reading 'lon' variable" ); } else { MB_SET_ERR( MB_FAILURE, "Couldn't find 'lon' variable" ); } // Store lat values in yVertVals if( ( vmit = varInfo.find( "lat" ) ) != varInfo.end() && ( *vmit ).second.varDims.size() == 1 ) { rval = read_coordinate( "lat", 0, nVertices - 1, yVertVals );MB_CHK_SET_ERR( rval, "Trouble reading 'lat' variable" ); } else { MB_SET_ERR( MB_FAILURE, "Couldn't find 'lat' variable" ); } // Store lev values in levVals if( isConnFile ) { // Connectivity file might not have level variable } else { if( ( vmit = varInfo.find( "lev" ) ) != varInfo.end() && ( *vmit ).second.varDims.size() == 1 ) { rval = read_coordinate( "lev", 0, nLevels - 1, levVals );MB_CHK_SET_ERR( rval, "Trouble reading 'lev' variable" ); // Decide whether down is positive char posval[10] = { 0 }; int success = NCFUNC( get_att_text )( _fileId, ( *vmit ).second.varId, "positive", posval ); if( 0 == success && !strcmp( posval, "down" ) ) { for( std::vector< double >::iterator dvit = levVals.begin(); dvit != levVals.end(); ++dvit ) ( *dvit ) *= -1.0; } } else { MB_SET_ERR( MB_FAILURE, "Couldn't find 'lev' variable" ); } } // Store time coordinate values in tVals if( isConnFile ) { // Connectivity file might not have time variable } else { if( ( vmit = varInfo.find( "time" ) ) != varInfo.end() && ( *vmit ).second.varDims.size() == 1 ) { rval = read_coordinate( "time", 0, nTimeSteps - 1, tVals );MB_CHK_SET_ERR( rval, "Trouble reading 'time' variable" ); } else if( ( vmit = varInfo.find( "t" ) ) != varInfo.end() && ( *vmit ).second.varDims.size() == 1 ) { rval = read_coordinate( "t", 0, nTimeSteps - 1, tVals );MB_CHK_SET_ERR( rval, "Trouble reading 't' variable" ); } else { // If expected time variable does not exist, set dummy values to tVals for( int t = 0; t < nTimeSteps; t++ ) tVals.push_back( (double)t ); } } // For each variable, determine the entity location type and number of levels std::map< std::string, ReadNC::VarData >::iterator mit; for( mit = varInfo.begin(); mit != varInfo.end(); ++mit ) { ReadNC::VarData& vd = ( *mit ).second; // Default entLoc is ENTLOCSET if( std::find( vd.varDims.begin(), vd.varDims.end(), tDim ) != vd.varDims.end() ) { if( std::find( vd.varDims.begin(), vd.varDims.end(), vDim ) != vd.varDims.end() ) vd.entLoc = ReadNC::ENTLOCVERT; } // Default numLev is 0 if( std::find( vd.varDims.begin(), vd.varDims.end(), levDim ) != vd.varDims.end() ) vd.numLev = nLevels; } // Hack: create dummy variables for dimensions (like ncol) with no corresponding coordinate // variables rval = create_dummy_variables();MB_CHK_SET_ERR( rval, "Failed to create dummy variables" ); return MB_SUCCESS; }
ErrorCode moab::NCHelperHOMME::read_ucd_variables_to_nonset | ( | std::vector< ReadNC::VarData > & | vdatas, |
std::vector< int > & | tstep_nums | ||
) | [private, virtual] |
Implementation of UcdNCHelper::read_ucd_variables_to_nonset()
Implements moab::UcdNCHelper.
Definition at line 782 of file NCHelperHOMME.cpp.
References moab::NCHelper::_fileId, moab::NCHelper::_readNC, moab::ReadNC::dbgOut, ErrorCode, moab::DebugOutput::get_verbosity(), moab::UcdNCHelper::kji_to_jik_stride(), moab::UcdNCHelper::localGidVerts, MB_CHK_SET_ERR, MB_SET_ERR, NCDF_SIZE, NCFUNCAG, moab::Range::pair_begin(), moab::Range::pair_end(), moab::DebugOutput::printf(), moab::Range::psize(), read_ucd_variables_to_nonset_allocate(), t, and moab::DebugOutput::tprintf().
{ DebugOutput& dbgOut = _readNC->dbgOut; ErrorCode rval = read_ucd_variables_to_nonset_allocate( vdatas, tstep_nums );MB_CHK_SET_ERR( rval, "Trouble allocating space to read non-set variables" ); // Finally, read into that space int success; for( unsigned int i = 0; i < vdatas.size(); i++ ) { std::size_t sz = vdatas[i].sz; // A typical supported variable: float T(time, lev, ncol) // For tag values, need transpose (lev, ncol) to (ncol, lev) size_t ni = vdatas[i].readCounts[2]; // ncol size_t nj = 1; // Here we should just set nj to 1 size_t nk = vdatas[i].readCounts[1]; // lev for( unsigned int t = 0; t < tstep_nums.size(); t++ ) { // Tag data for this timestep void* data = vdatas[i].varDatas[t]; // Set readStart for each timestep along time dimension vdatas[i].readStarts[0] = tstep_nums[t]; switch( vdatas[i].varDataType ) { case NC_FLOAT: case NC_DOUBLE: { // Read float as double std::vector< double > tmpdoubledata( sz ); // In the case of ucd mesh, and on multiple proc, // we need to read as many times as subranges we have in the // localGidVerts range; // basically, we have to give a different point // for data to start, for every subrange :( size_t indexInDoubleArray = 0; size_t ic = 0; for( Range::pair_iterator pair_iter = localGidVerts.pair_begin(); pair_iter != localGidVerts.pair_end(); ++pair_iter, ic++ ) { EntityHandle starth = pair_iter->first; EntityHandle endh = pair_iter->second; // Inclusive vdatas[i].readStarts[2] = (NCDF_SIZE)( starth - 1 ); vdatas[i].readCounts[2] = (NCDF_SIZE)( endh - starth + 1 ); success = NCFUNCAG( _vara_double )( _fileId, vdatas[i].varId, &( vdatas[i].readStarts[0] ), &( vdatas[i].readCounts[0] ), &( tmpdoubledata[indexInDoubleArray] ) ); if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read double data in a loop for variable " << vdatas[i].varName ); // We need to increment the index in double array for the // next subrange indexInDoubleArray += ( endh - starth + 1 ) * 1 * vdatas[i].numLev; } assert( ic == localGidVerts.psize() ); if( vdatas[i].numLev > 1 ) // Transpose (lev, ncol) to (ncol, lev) kji_to_jik_stride( ni, nj, nk, data, &tmpdoubledata[0], localGidVerts ); else { for( std::size_t idx = 0; idx != tmpdoubledata.size(); idx++ ) ( (double*)data )[idx] = tmpdoubledata[idx]; } break; } default: MB_SET_ERR( MB_FAILURE, "Unexpected data type for variable " << vdatas[i].varName ); } } } // Debug output, if requested if( 1 == dbgOut.get_verbosity() ) { dbgOut.printf( 1, "Read variables: %s", vdatas.begin()->varName.c_str() ); for( unsigned int i = 1; i < vdatas.size(); i++ ) dbgOut.printf( 1, ", %s ", vdatas[i].varName.c_str() ); dbgOut.tprintf( 1, "\n" ); } return rval; }
ErrorCode moab::NCHelperHOMME::read_ucd_variables_to_nonset_allocate | ( | std::vector< ReadNC::VarData > & | vdatas, |
std::vector< int > & | tstep_nums | ||
) | [private, virtual] |
Implementation of UcdNCHelper::read_ucd_variables_to_nonset_allocate()
Implements moab::UcdNCHelper.
Definition at line 597 of file NCHelperHOMME.cpp.
References moab::NCHelper::_fileSet, moab::NCHelper::_readNC, moab::Range::begin(), moab::ReadNC::dbgOut, moab::ReadNC::dimLens, moab::Range::end(), moab::ReadNC::ENTLOCVERT, ErrorCode, moab::Interface::get_entities_by_dimension(), moab::NCHelper::get_tag_to_nonset(), moab::UcdNCHelper::localGidVerts, MB_CHK_SET_ERR, MB_INDEX_OUT_OF_RANGE, MB_SET_ERR, moab::ReadNC::mbImpl, moab::UcdNCHelper::nLocalVertices, moab::Range::psize(), moab::Range::size(), t, moab::Interface::tag_iterate(), moab::NCHelper::tDim, and moab::DebugOutput::tprintf().
Referenced by read_ucd_variables_to_nonset().
{ Interface*& mbImpl = _readNC->mbImpl; std::vector< int >& dimLens = _readNC->dimLens; DebugOutput& dbgOut = _readNC->dbgOut; Range* range = NULL; // Get vertices Range verts; ErrorCode rval = mbImpl->get_entities_by_dimension( _fileSet, 0, verts );MB_CHK_SET_ERR( rval, "Trouble getting vertices in current file set" ); assert( "Should only have a single vertex subrange, since they were read in one shot" && verts.psize() == 1 ); for( unsigned int i = 0; i < vdatas.size(); i++ ) { // Support non-set variables with 3 dimensions like (time, lev, ncol) assert( 3 == vdatas[i].varDims.size() ); // For a non-set variable, time should be the first dimension assert( tDim == vdatas[i].varDims[0] ); // Set up readStarts and readCounts vdatas[i].readStarts.resize( 3 ); vdatas[i].readCounts.resize( 3 ); // First: time vdatas[i].readStarts[0] = 0; // This value is timestep dependent, will be set later vdatas[i].readCounts[0] = 1; // Next: lev vdatas[i].readStarts[1] = 0; vdatas[i].readCounts[1] = vdatas[i].numLev; // Finally: ncol switch( vdatas[i].entLoc ) { case ReadNC::ENTLOCVERT: // Vertices // Start from the first localGidVerts // Actually, this will be reset later on in a loop vdatas[i].readStarts[2] = localGidVerts[0] - 1; vdatas[i].readCounts[2] = nLocalVertices; range = &verts; break; default: MB_SET_ERR( MB_FAILURE, "Unexpected entity location type for variable " << vdatas[i].varName ); } // Get variable size vdatas[i].sz = 1; for( std::size_t idx = 0; idx != 3; idx++ ) vdatas[i].sz *= vdatas[i].readCounts[idx]; for( unsigned int t = 0; t < tstep_nums.size(); t++ ) { dbgOut.tprintf( 2, "Reading variable %s, time step %d\n", vdatas[i].varName.c_str(), tstep_nums[t] ); if( tstep_nums[t] >= dimLens[tDim] ) { MB_SET_ERR( MB_INDEX_OUT_OF_RANGE, "Wrong value for timestep number " << tstep_nums[t] ); } // Get the tag to read into if( !vdatas[i].varTags[t] ) { rval = get_tag_to_nonset( vdatas[i], tstep_nums[t], vdatas[i].varTags[t], vdatas[i].numLev );MB_CHK_SET_ERR( rval, "Trouble getting tag for variable " << vdatas[i].varName ); } // Get ptr to tag space void* data; int count; rval = mbImpl->tag_iterate( vdatas[i].varTags[t], range->begin(), range->end(), count, data );MB_CHK_SET_ERR( rval, "Failed to iterate tag for variable " << vdatas[i].varName ); assert( (unsigned)count == range->size() ); vdatas[i].varDatas[t] = data; } } return rval; }
int moab::NCHelperHOMME::_spectralOrder [private] |
Definition at line 51 of file NCHelperHOMME.hpp.
Referenced by create_mesh(), and NCHelperHOMME().
int moab::NCHelperHOMME::connectId [private] |
Definition at line 52 of file NCHelperHOMME.hpp.
Referenced by create_mesh().
bool moab::NCHelperHOMME::isConnFile [private] |
Definition at line 53 of file NCHelperHOMME.hpp.
Referenced by create_mesh(), init_mesh_vals(), and NCHelperHOMME().