MOAB: Mesh Oriented datABase
(version 5.4.1)
|
Child helper class for GCRM grid. More...
#include <NCHelperGCRM.hpp>
Public Member Functions | |
NCHelperGCRM (ReadNC *readNC, int fileId, const FileOptions &opts, EntityHandle fileSet) | |
Static Public Member Functions | |
static bool | can_read_file (ReadNC *readNC) |
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() | |
ErrorCode | create_local_vertices (const std::vector< int > &vertices_on_local_cells, EntityHandle &start_vertex) |
Create local vertices. | |
ErrorCode | create_local_edges (EntityHandle start_vertex) |
Create local edges (optional) | |
ErrorCode | create_padded_local_cells (const std::vector< int > &vertices_on_local_cells, EntityHandle start_vertex, Range &faces) |
Create local cells with padding (pentagons are padded to hexagons) | |
ErrorCode | create_gather_set_vertices (EntityHandle gather_set, EntityHandle &gather_set_start_vertex) |
Create gather set vertices. | |
ErrorCode | create_gather_set_edges (EntityHandle gather_set, EntityHandle gather_set_start_vertex) |
Create gather set edges (optional) | |
ErrorCode | create_padded_gather_set_cells (EntityHandle gather_set, EntityHandle gather_set_start_vertex) |
Create gather set cells with padding (pentagons are padded to hexagons) | |
Private Attributes | |
bool | createGatherSet |
Range | facesOwned |
Child helper class for GCRM grid.
Definition at line 20 of file NCHelperGCRM.hpp.
moab::NCHelperGCRM::NCHelperGCRM | ( | ReadNC * | readNC, |
int | fileId, | ||
const FileOptions & | opts, | ||
EntityHandle | fileSet | ||
) |
Definition at line 19 of file NCHelperGCRM.cpp.
References moab::NCHelper::ignoredVarNames.
: UcdNCHelper( readNC, fileId, opts, fileSet ), createGatherSet( false ) { // Ignore variables containing topological information ignoredVarNames.insert( "grid" ); ignoredVarNames.insert( "cell_corners" ); ignoredVarNames.insert( "cell_edges" ); ignoredVarNames.insert( "edge_corners" ); ignoredVarNames.insert( "cell_neighbors" ); }
bool moab::NCHelperGCRM::can_read_file | ( | ReadNC * | readNC | ) | [static] |
Definition at line 30 of file NCHelperGCRM.cpp.
References moab::ReadNC::dimNames.
Referenced by moab::NCHelper::get_nc_helper().
{ std::vector< std::string >& dimNames = readNC->dimNames; // If dimension name "cells" exists then it should be the GCRM grid if( std::find( dimNames.begin(), dimNames.end(), std::string( "cells" ) ) != dimNames.end() ) return true; return false; }
ErrorCode moab::NCHelperGCRM::check_existing_mesh | ( | ) | [private, virtual] |
Implementation of NCHelper::check_existing_mesh()
Implements moab::NCHelper.
Definition at line 178 of file NCHelperGCRM.cpp.
References moab::Range::empty(), ErrorCode, moab::Interface::get_entities_by_dimension(), MB_CHK_SET_ERR, MB_SUCCESS, moab::Range::size(), and moab::Interface::tag_get_data().
{ Interface*& mbImpl = _readNC->mbImpl; Tag& mGlobalIdTag = _readNC->mGlobalIdTag; bool& noMesh = _readNC->noMesh; if( noMesh ) { ErrorCode rval; if( localGidVerts.empty() ) { // Get all vertices from current file set (it is the input set in no_mesh scenario) Range local_verts; 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(); } } if( localGidEdges.empty() ) { // Get all edges from current file set (it is the input set in no_mesh scenario) Range local_edges; rval = mbImpl->get_entities_by_dimension( _fileSet, 1, local_edges );MB_CHK_SET_ERR( rval, "Trouble getting local edges in current file set" ); if( !local_edges.empty() ) { std::vector< int > gids( local_edges.size() ); // !IMPORTANT : this has to be the GLOBAL_ID tag rval = mbImpl->tag_get_data( mGlobalIdTag, local_edges, &gids[0] );MB_CHK_SET_ERR( rval, "Trouble getting local gid values of edges" ); // Restore localGidEdges std::copy( gids.rbegin(), gids.rend(), range_inserter( localGidEdges ) ); nLocalEdges = localGidEdges.size(); } } if( localGidCells.empty() ) { // Get all cells from current file set (it is the input set in no_mesh scenario) Range local_cells; rval = mbImpl->get_entities_by_dimension( _fileSet, 2, local_cells );MB_CHK_SET_ERR( rval, "Trouble getting local cells in current file set" ); if( !local_cells.empty() ) { std::vector< int > gids( local_cells.size() ); // !IMPORTANT : this has to be the GLOBAL_ID tag rval = mbImpl->tag_get_data( mGlobalIdTag, local_cells, &gids[0] );MB_CHK_SET_ERR( rval, "Trouble getting local gid values of cells" ); // Restore localGidCells std::copy( gids.rbegin(), gids.rend(), range_inserter( localGidCells ) ); nLocalCells = localGidCells.size(); } } } return MB_SUCCESS; }
ErrorCode moab::NCHelperGCRM::create_gather_set_edges | ( | EntityHandle | gather_set, |
EntityHandle | gather_set_start_vertex | ||
) | [private] |
Create gather set edges (optional)
Definition at line 1275 of file NCHelperGCRM.cpp.
References moab::Interface::add_entities(), ErrorCode, MB_CHK_SET_ERR, MB_SET_ERR, MB_SUCCESS, MBEDGE, NCDF_SIZE, NCFUNC, and NCFUNCG.
{ Interface*& mbImpl = _readNC->mbImpl; // Create gather set edges EntityHandle start_edge; EntityHandle* conn_arr_gather_set_edges = NULL; // Don't need to specify allocation number here, because we know enough edges were created // before ErrorCode rval = _readNC->readMeshIface->get_element_connect( nEdges, 2, MBEDGE, 0, start_edge, conn_arr_gather_set_edges );MB_CHK_SET_ERR( rval, "Failed to create gather set edges" ); // Add edges to the gather set Range gather_set_edges_range( start_edge, start_edge + nEdges - 1 ); rval = mbImpl->add_entities( gather_set, gather_set_edges_range );MB_CHK_SET_ERR( rval, "Failed to add edges to the gather set" ); // Read vertices on each edge int verticesOnEdgeVarId; int success = NCFUNC( inq_varid )( _fileId, "edge_corners", &verticesOnEdgeVarId ); if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of edge_corners" ); // Utilize the memory storage pointed by conn_arr_gather_set_edges int* vertices_on_gather_set_edges = (int*)conn_arr_gather_set_edges; NCDF_SIZE read_starts[2] = { 0, 0 }; NCDF_SIZE read_counts[2] = { static_cast< NCDF_SIZE >( nEdges ), 2 }; #ifdef MOAB_HAVE_PNETCDF // Enter independent I/O mode, since this read is only for the gather processor success = NCFUNC( begin_indep_data )( _fileId ); if( success ) MB_SET_ERR( MB_FAILURE, "Failed to begin independent I/O mode" ); success = NCFUNCG( _vara_int )( _fileId, verticesOnEdgeVarId, read_starts, read_counts, vertices_on_gather_set_edges ); if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read edge_corners data" ); success = NCFUNC( end_indep_data )( _fileId ); if( success ) MB_SET_ERR( MB_FAILURE, "Failed to end independent I/O mode" ); #else success = NCFUNCG( _vara_int )( _fileId, verticesOnEdgeVarId, read_starts, read_counts, vertices_on_gather_set_edges ); if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read edge_corners data" ); #endif // Populate connectivity data for gather set edges // Convert in-place from int (stored in the first half) to EntityHandle // Reading backward is the trick for( int edge_vert = nEdges * 2 - 1; edge_vert >= 0; edge_vert-- ) { // Note, indices stored in vertices_on_gather_set_edges are 0 based int gather_set_vert_idx = vertices_on_gather_set_edges[edge_vert]; // Global vertex index, 0 based // Connectivity array is shifted by where the gather set vertices start conn_arr_gather_set_edges[edge_vert] = gather_set_start_vertex + gather_set_vert_idx; } return MB_SUCCESS; }
ErrorCode moab::NCHelperGCRM::create_gather_set_vertices | ( | EntityHandle | gather_set, |
EntityHandle & | gather_set_start_vertex | ||
) | [private] |
Create gather set vertices.
Definition at line 1172 of file NCHelperGCRM.cpp.
References moab::Interface::add_entities(), moab::Range::begin(), moab::Range::end(), ErrorCode, MB_CHK_SET_ERR, MB_SET_ERR, MB_SUCCESS, NCDF_SIZE, NCFUNC, NCFUNCG, moab::Interface::tag_get_bytes(), and moab::Interface::tag_iterate().
{ Interface*& mbImpl = _readNC->mbImpl; Tag& mGlobalIdTag = _readNC->mGlobalIdTag; const Tag*& mpFileIdTag = _readNC->mpFileIdTag; // Create gather set vertices std::vector< double* > arrays; // Don't need to specify allocation number here, because we know enough vertices were created // before ErrorCode rval = _readNC->readMeshIface->get_node_coords( 3, nVertices, 0, gather_set_start_vertex, arrays );MB_CHK_SET_ERR( rval, "Failed to create gather set vertices" ); // Add vertices to the gather set Range gather_set_verts_range( gather_set_start_vertex, gather_set_start_vertex + nVertices - 1 ); rval = mbImpl->add_entities( gather_set, gather_set_verts_range );MB_CHK_SET_ERR( rval, "Failed to add vertices to the gather set" ); // Read x coordinates for gather set vertices double* xptr = arrays[0]; int xVertexVarId; int success = NCFUNC( inq_varid )( _fileId, "grid_corner_lon", &xVertexVarId ); if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of grid_corner_lon" ); NCDF_SIZE read_start = 0; NCDF_SIZE read_count = static_cast< NCDF_SIZE >( nVertices ); #ifdef MOAB_HAVE_PNETCDF // Enter independent I/O mode, since this read is only for the gather processor success = NCFUNC( begin_indep_data )( _fileId ); if( success ) MB_SET_ERR( MB_FAILURE, "Failed to begin independent I/O mode" ); success = NCFUNCG( _vara_double )( _fileId, xVertexVarId, &read_start, &read_count, xptr ); if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read grid_corner_lon data" ); success = NCFUNC( end_indep_data )( _fileId ); if( success ) MB_SET_ERR( MB_FAILURE, "Failed to end independent I/O mode" ); #else success = NCFUNCG( _vara_double )( _fileId, xVertexVarId, &read_start, &read_count, xptr ); if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read grid_corner_lon data" ); #endif // Read y coordinates for gather set vertices double* yptr = arrays[1]; int yVertexVarId; success = NCFUNC( inq_varid )( _fileId, "grid_corner_lat", &yVertexVarId ); if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of grid_corner_lat" ); #ifdef MOAB_HAVE_PNETCDF // Enter independent I/O mode, since this read is only for the gather processor success = NCFUNC( begin_indep_data )( _fileId ); if( success ) MB_SET_ERR( MB_FAILURE, "Failed to begin independent I/O mode" ); success = NCFUNCG( _vara_double )( _fileId, yVertexVarId, &read_start, &read_count, yptr ); if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read grid_corner_lat data" ); success = NCFUNC( end_indep_data )( _fileId ); if( success ) MB_SET_ERR( MB_FAILURE, "Failed to end independent I/O mode" ); #else success = NCFUNCG( _vara_double )( _fileId, yVertexVarId, &read_start, &read_count, yptr ); if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read grid_corner_lat data" ); #endif // Convert lon/lat/rad to x/y/z double* zptr = arrays[2]; double rad = 8000.0 + levVals[0]; for( int i = 0; i < nVertices; i++ ) { double cosphi = cos( yptr[i] ); double zmult = sin( yptr[i] ); double xmult = cosphi * cos( xptr[i] ); double ymult = cosphi * sin( xptr[i] ); xptr[i] = rad * xmult; yptr[i] = rad * ymult; zptr[i] = rad * zmult; } // Get ptr to GID memory for gather set vertices int count = 0; void* data = NULL; 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 ); int* 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 } } return MB_SUCCESS; }
ErrorCode moab::NCHelperGCRM::create_local_edges | ( | EntityHandle | start_vertex | ) | [private] |
Create local edges (optional)
Definition at line 983 of file NCHelperGCRM.cpp.
References moab::Range::begin(), moab::Range::end(), ErrorCode, MB_CHK_SET_ERR, MB_SET_ERR, MB_SUCCESS, MBEDGE, NCDF_SIZE, NCFUNC, NCFUNCAG, moab::Interface::tag_iterate(), and moab::DebugOutput::tprintf().
{ Interface*& mbImpl = _readNC->mbImpl; Tag& mGlobalIdTag = _readNC->mGlobalIdTag; DebugOutput& dbgOut = _readNC->dbgOut; // Read edges on each local cell, to get localGidEdges int edgesOnCellVarId; int success = NCFUNC( inq_varid )( _fileId, "cell_edges", &edgesOnCellVarId ); if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of cell_edges" ); std::vector< int > edges_on_local_cells( nLocalCells * EDGES_PER_CELL ); dbgOut.tprintf( 1, " edges_on_local_cells.size() = %d\n", (int)edges_on_local_cells.size() ); #ifdef MOAB_HAVE_PNETCDF size_t nb_reads = localGidCells.psize(); std::vector< int > requests( nb_reads ); std::vector< int > statuss( nb_reads ); size_t idxReq = 0; #endif size_t indexInArray = 0; for( Range::pair_iterator pair_iter = localGidCells.pair_begin(); pair_iter != localGidCells.pair_end(); ++pair_iter ) { EntityHandle starth = pair_iter->first; EntityHandle endh = pair_iter->second; dbgOut.tprintf( 1, " starth = %d\n", (int)starth ); dbgOut.tprintf( 1, " endh = %d\n", (int)endh ); NCDF_SIZE read_starts[2] = { static_cast< NCDF_SIZE >( starth - 1 ), 0 }; NCDF_SIZE read_counts[2] = { static_cast< NCDF_SIZE >( endh - starth + 1 ), static_cast< NCDF_SIZE >( EDGES_PER_CELL ) }; // Do a partial read in each subrange #ifdef MOAB_HAVE_PNETCDF success = NCFUNCREQG( _vara_int )( _fileId, edgesOnCellVarId, read_starts, read_counts, &( edges_on_local_cells[indexInArray] ), &requests[idxReq++] ); #else success = NCFUNCAG( _vara_int )( _fileId, edgesOnCellVarId, read_starts, read_counts, &( edges_on_local_cells[indexInArray] ) ); #endif if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read cell_edges data in a loop" ); // Increment the index for next subrange indexInArray += ( endh - starth + 1 ) * EDGES_PER_CELL; } #ifdef MOAB_HAVE_PNETCDF // Wait outside the loop success = NCFUNC( wait_all )( _fileId, requests.size(), &requests[0], &statuss[0] ); if( success ) MB_SET_ERR( MB_FAILURE, "Failed on wait_all" ); #endif // GCRM is 0 based, convert edge indices from 0 to 1 based for( std::size_t idx = 0; idx < edges_on_local_cells.size(); idx++ ) edges_on_local_cells[idx] += 1; // Collect local edges std::sort( edges_on_local_cells.begin(), edges_on_local_cells.end() ); std::copy( edges_on_local_cells.rbegin(), edges_on_local_cells.rend(), range_inserter( localGidEdges ) ); nLocalEdges = localGidEdges.size(); dbgOut.tprintf( 1, " localGidEdges.psize() = %d\n", (int)localGidEdges.psize() ); dbgOut.tprintf( 1, " localGidEdges.size() = %d\n", (int)localGidEdges.size() ); // Create local edges EntityHandle start_edge; EntityHandle* conn_arr_edges = NULL; ErrorCode rval = _readNC->readMeshIface->get_element_connect( nLocalEdges, 2, MBEDGE, 0, start_edge, conn_arr_edges, // Might have to create gather mesh later ( createGatherSet ? nLocalEdges + nEdges : nLocalEdges ) );MB_CHK_SET_ERR( rval, "Failed to create local edges" ); // Add local edges to current file set Range local_edges_range( start_edge, start_edge + nLocalEdges - 1 ); rval = _readNC->mbImpl->add_entities( _fileSet, local_edges_range );MB_CHK_SET_ERR( rval, "Failed to add local edges to current file set" ); // Get ptr to GID memory for edges int count = 0; void* data = NULL; rval = mbImpl->tag_iterate( mGlobalIdTag, local_edges_range.begin(), local_edges_range.end(), count, data );MB_CHK_SET_ERR( rval, "Failed to iterate global id tag on local edges" ); assert( count == nLocalEdges ); int* gid_data = (int*)data; std::copy( localGidEdges.begin(), localGidEdges.end(), gid_data ); int verticesOnEdgeVarId; // Read vertices on each local edge, to get edge connectivity success = NCFUNC( inq_varid )( _fileId, "edge_corners", &verticesOnEdgeVarId ); if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of edge_corners" ); // Utilize the memory storage pointed by conn_arr_edges int* vertices_on_local_edges = (int*)conn_arr_edges; #ifdef MOAB_HAVE_PNETCDF nb_reads = localGidEdges.psize(); requests.resize( nb_reads ); statuss.resize( nb_reads ); idxReq = 0; #endif indexInArray = 0; for( Range::pair_iterator pair_iter = localGidEdges.pair_begin(); pair_iter != localGidEdges.pair_end(); ++pair_iter ) { EntityHandle starth = pair_iter->first; EntityHandle endh = pair_iter->second; NCDF_SIZE read_starts[2] = { static_cast< NCDF_SIZE >( starth - 1 ), 0 }; NCDF_SIZE read_counts[2] = { static_cast< NCDF_SIZE >( endh - starth + 1 ), 2 }; // Do a partial read in each subrange #ifdef MOAB_HAVE_PNETCDF success = NCFUNCREQG( _vara_int )( _fileId, verticesOnEdgeVarId, read_starts, read_counts, &( vertices_on_local_edges[indexInArray] ), &requests[idxReq++] ); #else success = NCFUNCAG( _vara_int )( _fileId, verticesOnEdgeVarId, read_starts, read_counts, &( vertices_on_local_edges[indexInArray] ) ); #endif if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read edge_corners data in a loop" ); // Increment the index for next subrange indexInArray += ( endh - starth + 1 ) * 2; } #ifdef MOAB_HAVE_PNETCDF // Wait outside the loop success = NCFUNC( wait_all )( _fileId, requests.size(), &requests[0], &statuss[0] ); if( success ) MB_SET_ERR( MB_FAILURE, "Failed on wait_all" ); #endif // Populate connectivity data for local edges // Convert in-place from int (stored in the first half) to EntityHandle // Reading backward is the trick for( int edge_vert = nLocalEdges * 2 - 1; edge_vert >= 0; edge_vert-- ) { // Note, indices stored in vertices_on_local_edges are 0 based int global_vert_idx = vertices_on_local_edges[edge_vert] + 1; // Global vertex index, 1 based int local_vert_idx = localGidVerts.index( global_vert_idx ); // Local vertex index, 0 based assert( local_vert_idx != -1 ); conn_arr_edges[edge_vert] = start_vertex + local_vert_idx; } return MB_SUCCESS; }
ErrorCode moab::NCHelperGCRM::create_local_vertices | ( | const std::vector< int > & | vertices_on_local_cells, |
EntityHandle & | start_vertex | ||
) | [private] |
Create local vertices.
Definition at line 808 of file NCHelperGCRM.cpp.
References moab::Range::begin(), moab::Range::end(), ErrorCode, MB_CHK_SET_ERR, MB_SET_ERR, MB_SUCCESS, NCDF_SIZE, NCFUNC, NCFUNCAG, moab::Interface::tag_get_bytes(), moab::Interface::tag_iterate(), and moab::DebugOutput::tprintf().
{ Interface*& mbImpl = _readNC->mbImpl; Tag& mGlobalIdTag = _readNC->mGlobalIdTag; const Tag*& mpFileIdTag = _readNC->mpFileIdTag; DebugOutput& dbgOut = _readNC->dbgOut; std::map< std::string, ReadNC::VarData >& varInfo = _readNC->varInfo; // Make a copy of vertices_on_local_cells for sorting (keep original one to set cell // connectivity later) std::vector< int > vertices_on_local_cells_sorted( vertices_on_local_cells ); std::sort( vertices_on_local_cells_sorted.begin(), vertices_on_local_cells_sorted.end() ); std::copy( vertices_on_local_cells_sorted.rbegin(), vertices_on_local_cells_sorted.rend(), range_inserter( localGidVerts ) ); nLocalVertices = localGidVerts.size(); dbgOut.tprintf( 1, " localGidVerts.psize() = %d\n", (int)localGidVerts.psize() ); dbgOut.tprintf( 1, " localGidVerts.size() = %d\n", (int)localGidVerts.size() ); // Create local vertices std::vector< double* > arrays; ErrorCode rval = _readNC->readMeshIface->get_node_coords( 3, nLocalVertices, 0, start_vertex, arrays, // Might have to create gather mesh later ( createGatherSet ? nLocalVertices + nVertices : nLocalVertices ) );MB_CHK_SET_ERR( rval, "Failed to create local vertices" ); // Add local vertices to current file set Range local_verts_range( start_vertex, start_vertex + nLocalVertices - 1 ); rval = _readNC->mbImpl->add_entities( _fileSet, local_verts_range );MB_CHK_SET_ERR( rval, "Failed to add local vertices to current file set" ); // Get ptr to GID memory for local vertices int count = 0; void* data = NULL; rval = mbImpl->tag_iterate( mGlobalIdTag, local_verts_range.begin(), local_verts_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 GID data, which will be used to resolve sharing if( mpFileIdTag ) { rval = mbImpl->tag_iterate( *mpFileIdTag, local_verts_range.begin(), local_verts_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 ); } } #ifdef MOAB_HAVE_PNETCDF size_t nb_reads = localGidVerts.psize(); std::vector< int > requests( nb_reads ); std::vector< int > statuss( nb_reads ); size_t idxReq = 0; #endif // Store lev values in levVals std::map< std::string, ReadNC::VarData >::iterator vmit; if( ( vmit = varInfo.find( "layers" ) ) != varInfo.end() && ( *vmit ).second.varDims.size() == 1 ) { rval = read_coordinate( "layers", 0, nLevels - 1, levVals );MB_CHK_SET_ERR( rval, "Trouble reading 'layers' variable" ); } else if( ( vmit = varInfo.find( "interfaces" ) ) != varInfo.end() && ( *vmit ).second.varDims.size() == 1 ) { rval = read_coordinate( "interfaces", 0, nLevels - 1, levVals );MB_CHK_SET_ERR( rval, "Trouble reading 'interfaces' variable" ); } else { MB_SET_ERR( MB_FAILURE, "Couldn't find 'layers' or 'interfaces' 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 && !strncmp( posval, "down", 4 ) ) { for( std::vector< double >::iterator dvit = levVals.begin(); dvit != levVals.end(); ++dvit ) ( *dvit ) *= -1.0; } // Read x coordinates for local vertices double* xptr = arrays[0]; int xVertexVarId; success = NCFUNC( inq_varid )( _fileId, "grid_corner_lon", &xVertexVarId ); if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of grid_corner_lon" ); size_t indexInArray = 0; for( Range::pair_iterator pair_iter = localGidVerts.pair_begin(); pair_iter != localGidVerts.pair_end(); ++pair_iter ) { EntityHandle starth = pair_iter->first; EntityHandle endh = pair_iter->second; NCDF_SIZE read_start = (NCDF_SIZE)( starth - 1 ); NCDF_SIZE read_count = (NCDF_SIZE)( endh - starth + 1 ); // Do a partial read in each subrange #ifdef MOAB_HAVE_PNETCDF success = NCFUNCREQG( _vara_double )( _fileId, xVertexVarId, &read_start, &read_count, &( xptr[indexInArray] ), &requests[idxReq++] ); #else success = NCFUNCAG( _vara_double )( _fileId, xVertexVarId, &read_start, &read_count, &( xptr[indexInArray] ) ); #endif if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read grid_corner_lon data in a loop" ); // Increment the index for next subrange indexInArray += ( endh - starth + 1 ); } #ifdef MOAB_HAVE_PNETCDF // Wait outside the loop success = NCFUNC( wait_all )( _fileId, requests.size(), &requests[0], &statuss[0] ); if( success ) MB_SET_ERR( MB_FAILURE, "Failed on wait_all" ); #endif // Read y coordinates for local vertices double* yptr = arrays[1]; int yVertexVarId; success = NCFUNC( inq_varid )( _fileId, "grid_corner_lat", &yVertexVarId ); if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of grid_corner_lat" ); #ifdef MOAB_HAVE_PNETCDF idxReq = 0; #endif indexInArray = 0; for( Range::pair_iterator pair_iter = localGidVerts.pair_begin(); pair_iter != localGidVerts.pair_end(); ++pair_iter ) { EntityHandle starth = pair_iter->first; EntityHandle endh = pair_iter->second; NCDF_SIZE read_start = (NCDF_SIZE)( starth - 1 ); NCDF_SIZE read_count = (NCDF_SIZE)( endh - starth + 1 ); // Do a partial read in each subrange #ifdef MOAB_HAVE_PNETCDF success = NCFUNCREQG( _vara_double )( _fileId, yVertexVarId, &read_start, &read_count, &( yptr[indexInArray] ), &requests[idxReq++] ); #else success = NCFUNCAG( _vara_double )( _fileId, yVertexVarId, &read_start, &read_count, &( yptr[indexInArray] ) ); #endif if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read grid_corner_lat data in a loop" ); // Increment the index for next subrange indexInArray += ( endh - starth + 1 ); } #ifdef MOAB_HAVE_PNETCDF // Wait outside the loop success = NCFUNC( wait_all )( _fileId, requests.size(), &requests[0], &statuss[0] ); if( success ) MB_SET_ERR( MB_FAILURE, "Failed on wait_all" ); #endif // Convert lon/lat/rad to x/y/z double* zptr = arrays[2]; double rad = 8000.0 + levVals[0]; for( int i = 0; i < nLocalVertices; i++ ) { double cosphi = cos( yptr[i] ); double zmult = sin( yptr[i] ); double xmult = cosphi * cos( xptr[i] ); double ymult = cosphi * sin( xptr[i] ); xptr[i] = rad * xmult; yptr[i] = rad * ymult; zptr[i] = rad * zmult; } return MB_SUCCESS; }
ErrorCode moab::NCHelperGCRM::create_mesh | ( | Range & | faces | ) | [private, virtual] |
Implementation of NCHelper::create_mesh()
Implements moab::NCHelper.
Definition at line 249 of file NCHelperGCRM.cpp.
References moab::EDGES_PER_CELL, ErrorCode, MB_CHK_SET_ERR, MB_SET_ERR, MB_SUCCESS, NCDF_SIZE, NCFUNC, NCFUNCAG, moab::ParallelComm::proc_config(), moab::ProcConfig::proc_rank(), moab::ProcConfig::proc_size(), rank, and moab::DebugOutput::tprintf().
{ bool& noEdges = _readNC->noEdges; DebugOutput& dbgOut = _readNC->dbgOut; #ifdef MOAB_HAVE_MPI int rank = 0; int procs = 1; bool& isParallel = _readNC->isParallel; ParallelComm* myPcomm = NULL; if( isParallel ) { myPcomm = _readNC->myPcomm; rank = myPcomm->proc_config().proc_rank(); procs = myPcomm->proc_config().proc_size(); } // Need to know whether we'll be creating gather mesh if( rank == _readNC->gatherSetRank ) createGatherSet = true; if( procs >= 2 ) { // Shift rank to obtain a rotated trivial partition int shifted_rank = rank; int& trivialPartitionShift = _readNC->trivialPartitionShift; if( trivialPartitionShift > 0 ) shifted_rank = ( rank + trivialPartitionShift ) % procs; // Compute the number of local cells on this proc nLocalCells = int( std::floor( 1.0 * nCells / procs ) ); // The starting global cell index in the GCRM file for this proc int start_cell_idx = shifted_rank * nLocalCells; // Number of extra cells after equal split over procs int iextra = nCells % procs; // Allocate extra cells over procs if( shifted_rank < iextra ) nLocalCells++; start_cell_idx += std::min( shifted_rank, iextra ); start_cell_idx++; // 0 based -> 1 based // Redistribute local cells after trivial partition (e.g. apply Zoltan partition) ErrorCode rval = redistribute_local_cells( start_cell_idx, myPcomm);MB_CHK_SET_ERR( rval, "Failed to redistribute local cells after trivial partition" ); } else { nLocalCells = nCells; localGidCells.insert( 1, nLocalCells ); } #else nLocalCells = nCells; localGidCells.insert( 1, nLocalCells ); #endif dbgOut.tprintf( 1, " localGidCells.psize() = %d\n", (int)localGidCells.psize() ); dbgOut.tprintf( 1, " localGidCells.size() = %d\n", (int)localGidCells.size() ); // Read vertices on each local cell, to get localGidVerts and cell connectivity later int verticesOnCellVarId; int success = NCFUNC( inq_varid )( _fileId, "cell_corners", &verticesOnCellVarId ); if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of cell_corners" ); std::vector< int > vertices_on_local_cells( nLocalCells * EDGES_PER_CELL ); dbgOut.tprintf( 1, " nLocalCells = %d\n", (int)nLocalCells ); dbgOut.tprintf( 1, " vertices_on_local_cells.size() = %d\n", (int)vertices_on_local_cells.size() ); #ifdef MOAB_HAVE_PNETCDF size_t nb_reads = localGidCells.psize(); std::vector< int > requests( nb_reads ); std::vector< int > statuss( nb_reads ); size_t idxReq = 0; #endif size_t indexInArray = 0; for( Range::pair_iterator pair_iter = localGidCells.pair_begin(); pair_iter != localGidCells.pair_end(); ++pair_iter ) { EntityHandle starth = pair_iter->first; EntityHandle endh = pair_iter->second; dbgOut.tprintf( 1, " cell_corners starth = %d\n", (int)starth ); dbgOut.tprintf( 1, " cell_corners endh = %d\n", (int)endh ); NCDF_SIZE read_starts[2] = { static_cast< NCDF_SIZE >( starth - 1 ), 0 }; NCDF_SIZE read_counts[2] = { static_cast< NCDF_SIZE >( endh - starth + 1 ), static_cast< NCDF_SIZE >( EDGES_PER_CELL ) }; // Do a partial read in each subrange #ifdef MOAB_HAVE_PNETCDF success = NCFUNCREQG( _vara_int )( _fileId, verticesOnCellVarId, read_starts, read_counts, &( vertices_on_local_cells[indexInArray] ), &requests[idxReq++] ); #else success = NCFUNCAG( _vara_int )( _fileId, verticesOnCellVarId, read_starts, read_counts, &( vertices_on_local_cells[indexInArray] ) ); #endif if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read cell_corners data in a loop" ); // Increment the index for next subrange indexInArray += ( endh - starth + 1 ) * EDGES_PER_CELL; } #ifdef MOAB_HAVE_PNETCDF // Wait outside the loop success = NCFUNC( wait_all )( _fileId, requests.size(), &requests[0], &statuss[0] ); if( success ) MB_SET_ERR( MB_FAILURE, "Failed on wait_all" ); #endif // Correct vertices_on_local_cells array. Pentagons as hexagons should have // a connectivity like 123455 and not 122345 for( int local_cell_idx = 0; local_cell_idx < nLocalCells; local_cell_idx++ ) { int* pvertex = &vertices_on_local_cells[local_cell_idx * EDGES_PER_CELL]; for( int k = 0; k < EDGES_PER_CELL - 2; k++ ) { if( *( pvertex + k ) == *( pvertex + k + 1 ) ) { // Shift the connectivity for( int kk = k + 1; kk < EDGES_PER_CELL - 1; kk++ ) *( pvertex + kk ) = *( pvertex + kk + 1 ); // No need to try next k break; } } } // GCRM is 0 based, convert vertex indices from 0 to 1 based for( std::size_t idx = 0; idx < vertices_on_local_cells.size(); idx++ ) vertices_on_local_cells[idx] += 1; // Create local vertices EntityHandle start_vertex; ErrorCode rval = create_local_vertices( vertices_on_local_cells, start_vertex );MB_CHK_SET_ERR( rval, "Failed to create local vertices for GCRM mesh" ); // Create local edges (unless NO_EDGES read option is set) if( !noEdges ) { rval = create_local_edges( start_vertex );MB_CHK_SET_ERR( rval, "Failed to create local edges for GCRM mesh" ); } // Create local cells, padded rval = create_padded_local_cells( vertices_on_local_cells, start_vertex, faces );MB_CHK_SET_ERR( rval, "Failed to create padded local cells for GCRM mesh" ); if( createGatherSet ) { EntityHandle gather_set; rval = _readNC->readMeshIface->create_gather_set( gather_set );MB_CHK_SET_ERR( rval, "Failed to create gather set" ); // Create gather set vertices EntityHandle start_gather_set_vertex; rval = create_gather_set_vertices( gather_set, start_gather_set_vertex );MB_CHK_SET_ERR( rval, "Failed to create gather set vertices for GCRM mesh" ); // Create gather set edges (unless NO_EDGES read option is set) if( !noEdges ) { rval = create_gather_set_edges( gather_set, start_gather_set_vertex );MB_CHK_SET_ERR( rval, "Failed to create gather set edges for GCRM mesh" ); } // Create gather set cells with padding rval = create_padded_gather_set_cells( gather_set, start_gather_set_vertex );MB_CHK_SET_ERR( rval, "Failed to create padded gather set cells for GCRM mesh" ); } return MB_SUCCESS; }
ErrorCode moab::NCHelperGCRM::create_padded_gather_set_cells | ( | EntityHandle | gather_set, |
EntityHandle | gather_set_start_vertex | ||
) | [private] |
Create gather set cells with padding (pentagons are padded to hexagons)
Definition at line 1328 of file NCHelperGCRM.cpp.
References moab::Interface::add_entities(), moab::EDGES_PER_CELL, ErrorCode, MB_CHK_SET_ERR, MB_SET_ERR, MB_SUCCESS, MBPOLYGON, NCDF_SIZE, NCFUNC, and NCFUNCG.
{ Interface*& mbImpl = _readNC->mbImpl; // Create gather set cells EntityHandle start_element; EntityHandle* conn_arr_gather_set_cells = NULL; // Don't need to specify allocation number here, because we know enough cells were created // before ErrorCode rval = _readNC->readMeshIface->get_element_connect( nCells, EDGES_PER_CELL, MBPOLYGON, 0, start_element, conn_arr_gather_set_cells );MB_CHK_SET_ERR( rval, "Failed to create gather set cells" ); // Add cells to the gather set Range gather_set_cells_range( start_element, start_element + nCells - 1 ); rval = mbImpl->add_entities( gather_set, gather_set_cells_range );MB_CHK_SET_ERR( rval, "Failed to add cells to the gather set" ); // Read vertices on each gather set cell (connectivity) int verticesOnCellVarId; int success = NCFUNC( inq_varid )( _fileId, "cell_corners", &verticesOnCellVarId ); if( success ) MB_SET_ERR( MB_FAILURE, "Failed to get variable id of cell_corners" ); // Utilize the memory storage pointed by conn_arr_gather_set_cells int* vertices_on_gather_set_cells = (int*)conn_arr_gather_set_cells; NCDF_SIZE read_starts[2] = { 0, 0 }; NCDF_SIZE read_counts[2] = { static_cast< NCDF_SIZE >( nCells ), static_cast< NCDF_SIZE >( EDGES_PER_CELL ) }; #ifdef MOAB_HAVE_PNETCDF // Enter independent I/O mode, since this read is only for the gather processor success = NCFUNC( begin_indep_data )( _fileId ); if( success ) MB_SET_ERR( MB_FAILURE, "Failed to begin independent I/O mode" ); success = NCFUNCG( _vara_int )( _fileId, verticesOnCellVarId, read_starts, read_counts, vertices_on_gather_set_cells ); if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read cell_corners data" ); success = NCFUNC( end_indep_data )( _fileId ); if( success ) MB_SET_ERR( MB_FAILURE, "Failed to end independent I/O mode" ); #else success = NCFUNCG( _vara_int )( _fileId, verticesOnCellVarId, read_starts, read_counts, vertices_on_gather_set_cells ); if( success ) MB_SET_ERR( MB_FAILURE, "Failed to read cell_corners data" ); #endif // Correct gather set cell vertices array in the same way as local cell vertices array // Pentagons as hexagons should have a connectivity like 123455 and not 122345 for( int gather_set_cell_idx = 0; gather_set_cell_idx < nCells; gather_set_cell_idx++ ) { int* pvertex = vertices_on_gather_set_cells + gather_set_cell_idx * EDGES_PER_CELL; for( int k = 0; k < EDGES_PER_CELL - 2; k++ ) { if( *( pvertex + k ) == *( pvertex + k + 1 ) ) { // Shift the connectivity for( int kk = k + 1; kk < EDGES_PER_CELL - 1; kk++ ) *( pvertex + kk ) = *( pvertex + kk + 1 ); // No need to try next k break; } } } // Populate connectivity data for gather set cells // Convert in-place from int (stored in the first half) to EntityHandle // Reading backward is the trick for( int cell_vert = nCells * EDGES_PER_CELL - 1; cell_vert >= 0; cell_vert-- ) { // Note, indices stored in vertices_on_gather_set_cells are 0 based int gather_set_vert_idx = vertices_on_gather_set_cells[cell_vert]; // Global vertex index, 0 based // Connectivity array is shifted by where the gather set vertices start conn_arr_gather_set_cells[cell_vert] = gather_set_start_vertex + gather_set_vert_idx; } return MB_SUCCESS; }
ErrorCode moab::NCHelperGCRM::create_padded_local_cells | ( | const std::vector< int > & | vertices_on_local_cells, |
EntityHandle | start_vertex, | ||
Range & | faces | ||
) | [private] |
Create local cells with padding (pentagons are padded to hexagons)
Definition at line 1124 of file NCHelperGCRM.cpp.
References moab::Range::begin(), moab::EDGES_PER_CELL, moab::Range::end(), ErrorCode, moab::Range::insert(), MB_CHK_SET_ERR, MB_SUCCESS, MBPOLYGON, and moab::Interface::tag_iterate().
{ Interface*& mbImpl = _readNC->mbImpl; Tag& mGlobalIdTag = _readNC->mGlobalIdTag; // Create cells EntityHandle start_element; EntityHandle* conn_arr_local_cells = NULL; ErrorCode rval = _readNC->readMeshIface->get_element_connect( nLocalCells, EDGES_PER_CELL, MBPOLYGON, 0, start_element, conn_arr_local_cells, // Might have to create gather mesh later ( createGatherSet ? nLocalCells + nCells : nLocalCells ) );MB_CHK_SET_ERR( rval, "Failed to create local cells" ); faces.insert( start_element, start_element + nLocalCells - 1 ); // Add local cells to current file set Range local_cells_range( start_element, start_element + nLocalCells - 1 ); rval = _readNC->mbImpl->add_entities( _fileSet, local_cells_range );MB_CHK_SET_ERR( rval, "Failed to add local cells to current file set" ); // Get ptr to GID memory for local cells int count = 0; void* data = NULL; rval = mbImpl->tag_iterate( mGlobalIdTag, local_cells_range.begin(), local_cells_range.end(), count, data );MB_CHK_SET_ERR( rval, "Failed to iterate global id tag on local cells" ); assert( count == nLocalCells ); int* gid_data = (int*)data; std::copy( localGidCells.begin(), localGidCells.end(), gid_data ); // Set connectivity array with proper local vertices handles // vertices_on_local_cells array was already corrected to have // the last vertices repeated for pentagons, e.g. 122345 => 123455 for( int local_cell_idx = 0; local_cell_idx < nLocalCells; local_cell_idx++ ) { for( int i = 0; i < EDGES_PER_CELL; i++ ) { // Note, indices stored in vertices_on_local_cells are 1 based EntityHandle global_vert_idx = vertices_on_local_cells[local_cell_idx * EDGES_PER_CELL + i]; // Global vertex index, 1 based int local_vert_idx = localGidVerts.index( global_vert_idx ); // Local vertex index, 0 based assert( local_vert_idx != -1 ); conn_arr_local_cells[local_cell_idx * EDGES_PER_CELL + i] = start_vertex + local_vert_idx; } } return MB_SUCCESS; }
virtual std::string moab::NCHelperGCRM::get_mesh_type_name | ( | ) | [inline, private, virtual] |
Implementation of NCHelper::get_mesh_type_name()
Implements moab::NCHelper.
Definition at line 34 of file NCHelperGCRM.hpp.
{ return "GCRM"; }
ErrorCode moab::NCHelperGCRM::init_mesh_vals | ( | ) | [private, virtual] |
Implementation of NCHelper::init_mesh_vals()
Implements moab::NCHelper.
Definition at line 40 of file NCHelperGCRM.cpp.
References moab::NCHelper::_readNC, moab::UcdNCHelper::cDim, moab::ReadNC::dimLens, moab::ReadNC::dimNames, moab::UcdNCHelper::eDim, moab::ReadNC::VarData::entLoc, moab::ReadNC::ENTLOCEDGE, moab::ReadNC::ENTLOCFACE, moab::ReadNC::ENTLOCVERT, ErrorCode, moab::NCHelper::levDim, MB_CHK_SET_ERR, MB_SET_ERR, moab::UcdNCHelper::nCells, moab::UcdNCHelper::nEdges, 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, and moab::UcdNCHelper::vDim.
{ 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( ( vit = std::find( dimNames.begin(), dimNames.end(), "Time" ) ) != dimNames.end() ) idx = vit - dimNames.begin(); else if( ( vit = std::find( dimNames.begin(), dimNames.end(), "time" ) ) != dimNames.end() ) idx = vit - dimNames.begin(); else { MB_SET_ERR( MB_FAILURE, "Couldn't find 'Time' or 'time' dimension" ); } tDim = idx; nTimeSteps = dimLens[idx]; // Get number of cells if( ( vit = std::find( dimNames.begin(), dimNames.end(), "cells" ) ) != dimNames.end() ) idx = vit - dimNames.begin(); else { MB_SET_ERR( MB_FAILURE, "Couldn't find 'cells' dimension" ); } cDim = idx; nCells = dimLens[idx]; // Get number of edges if( ( vit = std::find( dimNames.begin(), dimNames.end(), "edges" ) ) != dimNames.end() ) idx = vit - dimNames.begin(); else { MB_SET_ERR( MB_FAILURE, "Couldn't find 'edges' dimension" ); } eDim = idx; nEdges = dimLens[idx]; // Get number of vertices vDim = -1; if( ( vit = std::find( dimNames.begin(), dimNames.end(), "corners" ) ) != dimNames.end() ) idx = vit - dimNames.begin(); else { MB_SET_ERR( MB_FAILURE, "Couldn't find 'corners' dimension" ); } vDim = idx; nVertices = dimLens[idx]; // Get number of layers if( ( vit = std::find( dimNames.begin(), dimNames.end(), "layers" ) ) != dimNames.end() ) idx = vit - dimNames.begin(); else { MB_SET_ERR( MB_FAILURE, "Couldn't find 'layers' dimension" ); } levDim = idx; nLevels = dimLens[idx]; // Dimension indices for other optional levels std::vector< unsigned int > opt_lev_dims; // Get index of interface levels if( ( vit = std::find( dimNames.begin(), dimNames.end(), "interfaces" ) ) != dimNames.end() ) { idx = vit - dimNames.begin(); opt_lev_dims.push_back( idx ); } std::map< std::string, ReadNC::VarData >::iterator vmit; // Store time coordinate values in tVals if( nTimeSteps > 0 ) { if( ( vmit = varInfo.find( "time" ) ) != varInfo.end() ) { 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() ) { rval = read_coordinate( "t", 0, nTimeSteps - 1, tVals );MB_CHK_SET_ERR( rval, "Trouble reading 't' variable" ); } else { // If expected time variable is not available, set dummy time coordinate 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 for( vmit = varInfo.begin(); vmit != varInfo.end(); ++vmit ) { ReadNC::VarData& vd = ( *vmit ).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; else if( std::find( vd.varDims.begin(), vd.varDims.end(), eDim ) != vd.varDims.end() ) vd.entLoc = ReadNC::ENTLOCEDGE; else if( std::find( vd.varDims.begin(), vd.varDims.end(), cDim ) != vd.varDims.end() ) vd.entLoc = ReadNC::ENTLOCFACE; } // Default numLev is 0 if( std::find( vd.varDims.begin(), vd.varDims.end(), levDim ) != vd.varDims.end() ) vd.numLev = nLevels; else { // If layers dimension is not found, try other optional levels such as interfaces for( unsigned int i = 0; i < opt_lev_dims.size(); i++ ) { if( std::find( vd.varDims.begin(), vd.varDims.end(), opt_lev_dims[i] ) != vd.varDims.end() ) { vd.numLev = dimLens[opt_lev_dims[i]]; break; } } } } // Hack: create dummy variables for dimensions (like cells) with no corresponding coordinate // variables rval = create_dummy_variables();MB_CHK_SET_ERR( rval, "Failed to create dummy variables" ); return MB_SUCCESS; }
ErrorCode moab::NCHelperGCRM::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 645 of file NCHelperGCRM.cpp.
References ErrorCode, moab::DebugOutput::get_verbosity(), MB_CHK_SET_ERR, MB_SET_ERR, NCDF_SIZE, NCFUNCAG, moab::Range::pair_begin(), moab::Range::pair_end(), moab::DebugOutput::printf(), moab::Range::psize(), t, and moab::DebugOutput::tprintf().
{ bool& noEdges = _readNC->noEdges; 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; Range* pLocalGid = NULL; for( unsigned int i = 0; i < vdatas.size(); i++ ) { // Skip edge variables, if specified by the read options if( noEdges && vdatas[i].entLoc == ReadNC::ENTLOCEDGE ) continue; switch( vdatas[i].entLoc ) { case ReadNC::ENTLOCVERT: pLocalGid = &localGidVerts; break; case ReadNC::ENTLOCFACE: pLocalGid = &localGidCells; break; case ReadNC::ENTLOCEDGE: pLocalGid = &localGidEdges; break; default: MB_SET_ERR( MB_FAILURE, "Unexpected entity location type for variable " << vdatas[i].varName ); } std::size_t sz = vdatas[i].sz; for( unsigned int t = 0; t < tstep_nums.size(); 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 // localGid 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 = pLocalGid->pair_begin(); pair_iter != pLocalGid->pair_end(); ++pair_iter, ic++ ) { EntityHandle starth = pair_iter->first; EntityHandle endh = pair_iter->second; // Inclusive vdatas[i].readStarts[1] = (NCDF_SIZE)( starth - 1 ); vdatas[i].readCounts[1] = (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 == pLocalGid->psize() ); void* data = vdatas[i].varDatas[t]; 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::NCHelperGCRM::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 408 of file NCHelperGCRM.cpp.
References moab::Range::begin(), moab::Range::end(), ErrorCode, moab::ParallelComm::filter_pstatus(), moab::Interface::get_entities_by_dimension(), MB_CHK_SET_ERR, MB_INDEX_OUT_OF_RANGE, MB_SET_ERR, moab::Range::psize(), PSTATUS_NOT, PSTATUS_NOT_OWNED, moab::Range::size(), t, moab::Interface::tag_iterate(), and moab::DebugOutput::tprintf().
{ Interface*& mbImpl = _readNC->mbImpl; std::vector< int >& dimLens = _readNC->dimLens; bool& noEdges = _readNC->noEdges; 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 ); // Get edges Range edges; rval = mbImpl->get_entities_by_dimension( _fileSet, 1, edges );MB_CHK_SET_ERR( rval, "Trouble getting edges in current file set" ); // Get faces Range faces; rval = mbImpl->get_entities_by_dimension( _fileSet, 2, faces );MB_CHK_SET_ERR( rval, "Trouble getting faces in current file set" ); assert( "Should only have a single face subrange, since they were read in one shot" && faces.psize() == 1 ); #ifdef MOAB_HAVE_MPI bool& isParallel = _readNC->isParallel; if( isParallel ) { ParallelComm*& myPcomm = _readNC->myPcomm; rval = myPcomm->filter_pstatus( faces, PSTATUS_NOT_OWNED, PSTATUS_NOT, -1, &facesOwned );MB_CHK_SET_ERR( rval, "Trouble getting owned faces in current file set" ); } else facesOwned = faces; // not running in parallel, but still with MPI #else facesOwned = faces; #endif for( unsigned int i = 0; i < vdatas.size(); i++ ) { // Skip edge variables, if specified by the read options if( noEdges && vdatas[i].entLoc == ReadNC::ENTLOCEDGE ) continue; // Support non-set variables with 3 dimensions like (time, cells, layers), or // 2 dimensions like (time, cells) assert( 3 == vdatas[i].varDims.size() || 2 == 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: nVertices / nCells / nEdges 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[1] = localGidVerts[0] - 1; vdatas[i].readCounts[1] = nLocalVertices; range = &verts; break; case ReadNC::ENTLOCFACE: // Faces // Start from the first localGidCells // Actually, this will be reset later on in a loop vdatas[i].readStarts[1] = localGidCells[0] - 1; vdatas[i].readCounts[1] = nLocalCells; range = &facesOwned; break; case ReadNC::ENTLOCEDGE: // Edges // Start from the first localGidEdges // Actually, this will be reset later on in a loop vdatas[i].readStarts[1] = localGidEdges[0] - 1; vdatas[i].readCounts[1] = nLocalEdges; range = &edges; break; default: MB_SET_ERR( MB_FAILURE, "Unexpected entity location type for variable " << vdatas[i].varName ); } // Finally: layers or other optional levels, it is possible that there is no // level dimension (numLev is 0) for this non-set variable if( vdatas[i].numLev < 1 ) vdatas[i].numLev = 1; vdatas[i].readStarts[2] = 0; vdatas[i].readCounts[2] = vdatas[i].numLev; // 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 assert( 1 == range->psize() ); 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; }
bool moab::NCHelperGCRM::createGatherSet [private] |
Definition at line 78 of file NCHelperGCRM.hpp.
Range moab::NCHelperGCRM::facesOwned [private] |
Definition at line 79 of file NCHelperGCRM.hpp.