[MOAB-dev] commit/MOAB: danwu: NCHelperMPAS::create_mesh() is too complicated to read or debug. Rewrite it with some shorter helper functions.
commits-noreply at bitbucket.org
commits-noreply at bitbucket.org
Wed Oct 23 17:32:43 CDT 2013
1 new commit in MOAB:
https://bitbucket.org/fathomteam/moab/commits/66379d6ff569/
Changeset: 66379d6ff569
Branch: master
User: danwu
Date: 2013-10-24 00:32:15
Summary: NCHelperMPAS::create_mesh() is too complicated to read or debug. Rewrite it with some shorter helper functions.
Affected #: 2 files
diff --git a/src/io/NCHelperMPAS.cpp b/src/io/NCHelperMPAS.cpp
index 7770ee7..80f3a1e 100644
--- a/src/io/NCHelperMPAS.cpp
+++ b/src/io/NCHelperMPAS.cpp
@@ -20,54 +20,11 @@ namespace moab {
const int DEFAULT_MAX_EDGES_PER_CELL = 10;
-// This is used for Zoltan only related stuff
-#if HAVE_ZOLTAN
-#define GET_VAR(name, id, dims) \
-{ \
- id = -1; \
- int gvfail = NCFUNC(inq_varid)(_fileId, name, &id); \
- if (NC_NOERR == gvfail) { \
- int ndims; \
- gvfail = NCFUNC(inq_varndims)(_fileId, id, &ndims); \
- if (NC_NOERR == gvfail) { \
- dims.resize(ndims); \
- gvfail = NCFUNC(inq_vardimid)(_fileId, id, &dims[0]); \
- } \
- } \
-}
-
-#define GET_1D_DBL_VAR_RANGE(name, id, startIndex, endIndex, vals) \
-{ \
- std::vector<int> dum_dims; \
- GET_VAR(name, id, dum_dims); \
- if (-1 != id) { \
- if (0 == rank) \
- std::cout << "var: " << name << " id: " << id << "\n"; \
- NCDF_SIZE ntmp; \
- int dvfail = NCFUNC(inq_dimlen)(_fileId, dum_dims[0], &ntmp); \
- if (0 == rank) \
- std::cout << "Prepare reading var " << name << " start: " << startIndex << \
- " end: " << endIndex << " Actual size: " << ntmp << "\n" ; \
- if (startIndex > (int)ntmp || endIndex > (int)ntmp || startIndex >= endIndex) { \
- std::cout << "Bad input\n"; \
- return MB_FAILURE; \
- } \
- vals.resize(endIndex - startIndex); \
- NCDF_SIZE ntmp1 = startIndex; \
- NCDF_SIZE count = endIndex - startIndex; \
- dvfail = NCFUNC(get_vara_double_all)(_fileId, id, &ntmp1, &count, &vals[0]); \
- if (NC_NOERR != dvfail) { \
- std::cout << "ReadNCDF: Problem getting variable " << name << "\n"; \
- return MB_FAILURE; \
- } \
- } \
-}
-#endif
-
NCHelperMPAS::NCHelperMPAS(ReadNC* readNC, int fileId, const FileOptions& opts, EntityHandle fileSet)
: UcdNCHelper(readNC, fileId, opts, fileSet)
, maxEdgesPerCell(DEFAULT_MAX_EDGES_PER_CELL)
, numCellGroups(0)
+, createGatherSet(false)
{
}
@@ -280,8 +237,6 @@ ErrorCode NCHelperMPAS::check_existing_mesh()
ErrorCode NCHelperMPAS::create_mesh(Range& faces)
{
Interface*& mbImpl = _readNC->mbImpl;
- Tag& mGlobalIdTag = _readNC->mGlobalIdTag;
- const Tag*& mpFileIdTag = _readNC->mpFileIdTag;
int& gatherSetRank = _readNC->gatherSetRank;
bool& noMixedElements = _readNC->noMixedElements;
bool& noEdges = _readNC->noEdges;
@@ -299,62 +254,34 @@ ErrorCode NCHelperMPAS::create_mesh(Range& faces)
#endif
// Need to know whether we'll be creating gather mesh
- bool create_gathers = false;
if (rank == gatherSetRank)
- create_gathers = true;
-
- // Trivial partition
- // Compute the number of local cells on this proc
- nLocalCells = int(std::floor(1.0 * nCells / procs));
- // start_cell_idx is the starting global cell index in the MPAS file for this proc
- int start_cell_idx = rank * nLocalCells;
- // iextra = # cells extra after equal split over procs
- int iextra = nCells % procs;
- if (rank < iextra)
- nLocalCells++;
- start_cell_idx += std::min(rank, iextra);
+ createGatherSet = true;
-#ifdef USE_MPI
-#ifdef HAVE_ZOLTAN
- int& partMethod = _readNC->partMethod;
- if (partMethod == ScdParData::RCBZOLTAN && procs >= 2) // it does not make sense to partition
- // if the number of processors is less than 2; trivial partition is good enough
- {
- // Zoltan partition using RCB; maybe more studies would be good, as to which partition
- // is better
- int temp_dim;
- MBZoltan* mbZTool = new MBZoltan(mbImpl, false, 0, NULL);
+ if (procs >= 2) {
+ // Compute the number of local cells on this proc
+ nLocalCells = int(std::floor(1.0 * nCells / procs));
- std::vector<double> x, y, z;
- int end_cell_index = start_cell_idx + nLocalCells;
- GET_1D_DBL_VAR_RANGE("xCell", temp_dim, start_cell_idx, end_cell_index, x);
- GET_1D_DBL_VAR_RANGE("yCell", temp_dim, start_cell_idx, end_cell_index, y);
- GET_1D_DBL_VAR_RANGE("zCell", temp_dim, start_cell_idx, end_cell_index, z);
+ // The starting global cell index in the MPAS file for this proc
+ int start_cell_idx = rank * nLocalCells;
- ErrorCode rval = mbZTool->repartition(x, y, z, start_cell_idx + 1, "RCB", localGidCells);
- //delete mbZTool;
- if (rval != MB_SUCCESS) {
- std::cout << "Error in partitioning\n";
- return MB_FAILURE;
- }
+ // Number of extra cells after equal split over procs
+ int iextra = nCells % procs;
- dbgOut.tprintf(1, "After partitioning, localGidCells.psize() = %d\n", (int)localGidCells.psize());
- dbgOut.tprintf(1, " localGidCells.size() = %d\n", (int)localGidCells.size());
+ // Allocate extra cells over procs
+ if (rank < iextra)
+ nLocalCells++;
+ start_cell_idx += std::min(rank, iextra);
- // This is important: local cells are now redistributed, so nLocalCells is different!
- nLocalCells = localGidCells.size();
+ 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);
+ ERRORR(rval, "Failed to redistribute local cells after trivial partition.");
}
else {
-#endif /* this is end for HAVE_ZOLTAN */
-#endif /* if use mpi */
- /* without zoltan, only trivial partition is possible */
- start_cell_idx++; // 0 based -> 1 based
- localGidCells.insert(start_cell_idx, start_cell_idx + nLocalCells - 1);
-#ifdef USE_MPI
-#ifdef HAVE_ZOLTAN
+ nLocalCells = nCells;
+ localGidCells.insert(1, nLocalCells);
}
-#endif /* end for HAVE_ZOLTAN */
-#endif /* end for USE_MPI */
// Read number of edges on each local cell, to calculate actual maxEdgesPerCell
int nEdgesOnCellVarId;
@@ -373,15 +300,15 @@ ErrorCode NCHelperMPAS::create_mesh(Range& faces)
pair_iter++) {
EntityHandle starth = pair_iter->first;
EntityHandle endh = pair_iter->second;
- NCDF_SIZE tmp_start = (NCDF_SIZE) (starth - 1);
- NCDF_SIZE tmp_count = (NCDF_SIZE) (endh - starth + 1);
+ 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 PNETCDF_FILE
- success = NCFUNCREQG(_vara_int)(_fileId, nEdgesOnCellVarId, &tmp_start, &tmp_count,
+ success = NCFUNCREQG(_vara_int)(_fileId, nEdgesOnCellVarId, &read_start, &read_count,
&(num_edges_on_local_cells[indexInArray]), &requests[idxReq++]);
#else
- success = NCFUNCAG(_vara_int)(_fileId, nEdgesOnCellVarId, &tmp_start, &tmp_count,
+ success = NCFUNCAG(_vara_int)(_fileId, nEdgesOnCellVarId, &read_start, &read_count,
&(num_edges_on_local_cells[indexInArray]));
#endif
ERRORS(success, "Failed to read nEdgesOnCell data in a loop");
@@ -400,7 +327,7 @@ ErrorCode NCHelperMPAS::create_mesh(Range& faces)
int local_max_edges_per_cell = *(std::max_element(num_edges_on_local_cells.begin(), num_edges_on_local_cells.end()));
maxEdgesPerCell = local_max_edges_per_cell;
- // If parallel, do a MPI_Allreduce to get a common global maxEdgesPerCell used across all procs
+ // If parallel, do a MPI_Allreduce to get global maxEdgesPerCell across all procs
#ifdef USE_MPI
if (procs > 1) {
int global_max_edges_per_cell;
@@ -408,56 +335,11 @@ ErrorCode NCHelperMPAS::create_mesh(Range& faces)
MPI_Allreduce(&local_max_edges_per_cell, &global_max_edges_per_cell, 1, MPI_INTEGER, MPI_MAX, myPcomm->proc_config().proc_comm());
assert(local_max_edges_per_cell <= global_max_edges_per_cell);
maxEdgesPerCell = global_max_edges_per_cell;
- if (0==rank)
+ if (0 == rank)
dbgOut.tprintf(1, " global_max_edges_per_cell = %d\n", global_max_edges_per_cell);
}
#endif
- // Read edges on each local cell, to get localGidEdges later
- int edgesOnCellVarId;
- success = NCFUNC(inq_varid)(_fileId, "edgesOnCell", &edgesOnCellVarId);
- ERRORS(success, "Failed to get variable id of edgesOnCell.");
- std::vector<int> edges_on_local_cells(nLocalCells * maxEdgesPerCell);
- dbgOut.tprintf(1, " edges_on_local_cells.size() = %d\n", (int)edges_on_local_cells.size());
-#ifdef PNETCDF_FILE
- idxReq = 0;
-#endif
- 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;
- NCDF_SIZE tmp_starts[2] = {static_cast<NCDF_SIZE>(starth - 1), 0};
- NCDF_SIZE tmp_counts[2] = {static_cast<NCDF_SIZE>(endh - starth + 1), static_cast<NCDF_SIZE>(maxEdgesPerCell)};
-
- // Do a partial read in each subrange
-#ifdef PNETCDF_FILE
- success = NCFUNCREQG(_vara_int)(_fileId, edgesOnCellVarId, tmp_starts, tmp_counts,
- &(edges_on_local_cells[indexInArray]), &requests[idxReq++]);
-#else
- success = NCFUNCAG(_vara_int)(_fileId, edgesOnCellVarId, tmp_starts, tmp_counts,
- &(edges_on_local_cells[indexInArray]));
-#endif
- ERRORS(success, "Failed to read edgesOnCell data in a loop");
-
- // Increment the index for next subrange
- indexInArray += (endh - starth + 1) * maxEdgesPerCell;
- }
-#ifdef PNETCDF_FILE
- // Wait outside the loop
- success = NCFUNC(wait_all)(_fileId, requests.size(), &requests[0], &statuss[0]);
- ERRORS(success, "Failed on wait_all.");
-#endif
-
- // 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());
-
// Read vertices on each local cell, to get localGidVerts and cell connectivity later
int verticesOnCellVarId;
success = NCFUNC(inq_varid)(_fileId, "verticesOnCell", &verticesOnCellVarId);
@@ -472,15 +354,15 @@ ErrorCode NCHelperMPAS::create_mesh(Range& faces)
pair_iter++) {
EntityHandle starth = pair_iter->first;
EntityHandle endh = pair_iter->second;
- NCDF_SIZE tmp_starts[2] = {static_cast<NCDF_SIZE>(starth - 1), 0};
- NCDF_SIZE tmp_counts[2] = {static_cast<NCDF_SIZE>(endh - starth + 1), maxEdgesPerCell};
+ NCDF_SIZE read_starts[2] = {static_cast<NCDF_SIZE>(starth - 1), 0};
+ NCDF_SIZE read_counts[2] = {static_cast<NCDF_SIZE>(endh - starth + 1), maxEdgesPerCell};
// Do a partial read in each subrange
#ifdef PNETCDF_FILE
- success = NCFUNCREQG(_vara_int)(_fileId, verticesOnCellVarId, tmp_starts, tmp_counts,
+ success = NCFUNCREQG(_vara_int)(_fileId, verticesOnCellVarId, read_starts, read_counts,
&(vertices_on_local_cells[indexInArray]), &requests[idxReq++]);
#else
- success = NCFUNCAG(_vara_int)(_fileId, verticesOnCellVarId, tmp_starts, tmp_counts,
+ success = NCFUNCAG(_vara_int)(_fileId, verticesOnCellVarId, read_starts, read_counts,
&(vertices_on_local_cells[indexInArray]));
#endif
ERRORS(success, "Failed to read verticesOnCell data in a loop");
@@ -495,704 +377,170 @@ ErrorCode NCHelperMPAS::create_mesh(Range& faces)
ERRORS(success, "Failed on wait_all.");
#endif
- // To keep unsorted vertices_on_local_cells for cell connectivity, we reuse edges_on_local_cells for sorting
- std::vector<int>& vertices_on_local_cells_sorted = edges_on_local_cells;
- std::copy(vertices_on_local_cells.begin(), vertices_on_local_cells.end(), vertices_on_local_cells_sorted.begin());
-
- // Collect local vertices
- 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
- // We can temporarily use the memory storage allocated before it will be populated
EntityHandle start_vertex;
- std::vector<double*> arrays;
- Range tmp_range;
- ErrorCode rval = _readNC->readMeshIface->get_node_coords(3, nLocalVertices, 0, start_vertex, arrays,
- // Might have to create gather mesh later
- (create_gathers ? nLocalVertices + nVertices : nLocalVertices));
- ERRORR(rval, "Couldn't create local vertices in MPAS mesh.");
- tmp_range.insert(start_vertex, start_vertex + nLocalVertices - 1);
-
- // Get ptr to GID memory for local vertices
- Range local_verts_range(start_vertex, start_vertex + nLocalVertices - 1);
- int count = 0;
- void* data = NULL;
- rval = mbImpl->tag_iterate(mGlobalIdTag, local_verts_range.begin(), local_verts_range.end(), count, data);
- ERRORR(rval, "Failed to get global id tag iterator on local vertices.");
- assert(count == nLocalVertices);
- int* gid_data = (int*) data;
- std::copy(localGidVerts.begin(), localGidVerts.end(), gid_data);
+ ErrorCode rval = create_local_vertices(vertices_on_local_cells, start_vertex);
+ ERRORR(rval, "Failed to create local vertices for MPAS mesh.");
- // 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);
- ERRORR(rval, "Failed to get file id tag iterator on local vertices.");
- assert(count == nLocalVertices);
- gid_data = (int*) data;
- std::copy(localGidVerts.begin(), localGidVerts.end(), gid_data);
+ // Create local edges (unless NO_EDGES read option is set)
+ if (!noEdges) {
+ rval = create_local_edges(start_vertex);
+ ERRORR(rval, "Failed to create local edges for MPAS mesh.");
}
- // Create local edges
- // We can temporarily use the memory storage allocated before it will be populated
- EntityHandle start_edge;
- EntityHandle* conn_arr_edges = NULL;
- if (!noEdges) {
- rval = _readNC->readMeshIface->get_element_connect(nLocalEdges, 2, MBEDGE, 0, start_edge, conn_arr_edges,
- // Might have to create gather mesh later
- (create_gathers ? nLocalEdges + nEdges : nLocalEdges));
- ERRORR(rval, "Couldn't create local edges in MPAS mesh.");
- Range local_edges_range(start_edge, start_edge + nLocalEdges - 1);
- tmp_range.insert(start_edge, start_edge + nLocalEdges - 1);
-
- // Get ptr to GID memory for edges
- rval = mbImpl->tag_iterate(mGlobalIdTag, local_edges_range.begin(), local_edges_range.end(), count, data);
- ERRORR(rval, "Failed to get global id tag iterator on local edges.");
- assert(count == (int) nLocalEdges);
- gid_data = (int*) data;
- std::copy(localGidEdges.begin(), localGidEdges.end(), gid_data);
+ // Create local cells, either unpadded or padded
+ if (noMixedElements) {
+ rval = create_padded_local_cells(vertices_on_local_cells, num_edges_on_local_cells, start_vertex, faces);
+ ERRORR(rval, "Failed to create padded local cells for MPAS mesh.");
+ }
+ else {
+ rval = create_local_cells(vertices_on_local_cells, num_edges_on_local_cells, start_vertex, faces);
+ ERRORR(rval, "Failed to create local cells for MPAS mesh.");
}
- EntityHandle start_element = 0;
+ // Set tag for numCellGroups
+ Tag numCellGroupsTag = 0;
+ rval = mbImpl->tag_get_handle("__NUM_CELL_GROUPS", 1, MB_TYPE_INTEGER, numCellGroupsTag, MB_TAG_SPARSE | MB_TAG_CREAT);
+ ERRORR(rval, "Failed to get __NUM_CELL_GROUPS tag.");
+ rval = mbImpl->tag_set_data(numCellGroupsTag, &_fileSet, 1, &numCellGroups);
+ ERRORR(rval, "Failed to set data for __NUM_CELL_GROUPS tag.");
- // Used when NO_MIXED_ELEMENTS option is NOT set
- EntityHandle* conn_arr_local_cells_with_n_edges[DEFAULT_MAX_EDGES_PER_CELL + 1];
- // put in subranges; each subrange (for numEdges) will contain, in order, the
- // gids for cells with that many edges (numEdges)
- Range local_cells_with_n_edges[DEFAULT_MAX_EDGES_PER_CELL + 1];
- std::vector<int> num_edges_on_cell_groups;
- std::vector<EntityHandle> start_element_on_cell_groups;
+ if (createGatherSet) {
+ EntityHandle gather_set;
+ rval = _readNC->readMeshIface->create_gather_set(gather_set);
+ ERRORR(rval, "Failed to create gather set.");
- // Used when NO_MIXED_ELEMENTS option is set
- EntityHandle* conn_arr_local_cells = NULL;
+ // Create gather set vertices
+ EntityHandle start_gather_set_vertex;
+ rval = create_gather_set_vertices(gather_set, start_gather_set_vertex);
+ ERRORR(rval, "Failed to create gather set vertices for MPAS mesh");
- // Create local cells
- // We can temporarily use the memory storage allocated before it will be populated
- if (noMixedElements) {
- // Only one group of cells (each cell is represented by a polygon with maxEdgesPerCell edges)
- numCellGroups = 1;
-
- // Create cells for this cell group
- rval = _readNC->readMeshIface->get_element_connect(nLocalCells, maxEdgesPerCell, MBPOLYGON, 0, start_element, conn_arr_local_cells,
- // Might have to create gather mesh later
- (create_gathers ? nLocalCells + nCells : nLocalCells));
- ERRORR(rval, "Couldn't create local cells in MPAS mesh.");
- Range local_cell_range(start_element, start_element + nLocalCells - 1);
- tmp_range.insert(start_element, start_element + nLocalCells - 1);
- faces.insert(start_element, start_element + nLocalCells - 1);
-
- // Get ptr to GID memory for local cells
- rval = mbImpl->tag_iterate(mGlobalIdTag, local_cell_range.begin(), local_cell_range.end(), count, data);
- ERRORR(rval, "Failed to get global id tag iterator on local cells.");
- assert(count == nLocalCells);
- gid_data = (int*) data;
- std::copy(localGidCells.begin(), localGidCells.end(), gid_data);
- }
- else {
- // Divide local cells into groups based on the number of edges
- for (int i = 0; i < nLocalCells; i++) {
- int num_edges = num_edges_on_local_cells[i];
- local_cells_with_n_edges[num_edges].insert(localGidCells[i]); // Global cell index
- // by construction, this subrange will contain cells in order
+ // Create gather set edges (unless NO_EDGES read option is set)
+ if (!noEdges) {
+ rval = create_gather_set_edges(gather_set, start_gather_set_vertex);
+ ERRORR(rval, "Failed to create gather set edges for MPAS mesh.");
}
- for (int i = 3; i <= maxEdgesPerCell; i++) {
- if (local_cells_with_n_edges[i].size() > 0)
- num_edges_on_cell_groups.push_back(i);
+ // Create gather set cells, either unpadded or padded
+ if (noMixedElements) {
+ rval = create_padded_gather_set_cells(gather_set, start_gather_set_vertex);
+ ERRORR(rval, "Failed to create padded gather set cells for MPAS mesh.");
}
- numCellGroups = num_edges_on_cell_groups.size();
-
- // Create cells for each non-empty cell group
- for (int i = 0; i < numCellGroups; i++) {
- int num_edges_per_cell = num_edges_on_cell_groups[i];
- int num_group_cells = local_cells_with_n_edges[num_edges_per_cell].size();
-
- rval = _readNC->readMeshIface->get_element_connect(num_group_cells, num_edges_per_cell, MBPOLYGON, 0, start_element,
- conn_arr_local_cells_with_n_edges[num_edges_per_cell], num_group_cells);
- ERRORR(rval, "Couldn't create local cells in MPAS mesh.");
- start_element_on_cell_groups.push_back(start_element);
- Range local_cell_range(start_element, start_element + num_group_cells - 1);
- tmp_range.insert(start_element, start_element + num_group_cells - 1);
- faces.insert(start_element, start_element + num_group_cells - 1);
-
- // Get ptr to gid memory for local cells
- rval = mbImpl->tag_iterate(mGlobalIdTag, local_cell_range.begin(), local_cell_range.end(), count, data);
- ERRORR(rval, "Failed to get global id tag iterator on local cells.");
- assert(count == num_group_cells);
- gid_data = (int*) data;
- std::copy(local_cells_with_n_edges[num_edges_per_cell].begin(), local_cells_with_n_edges[num_edges_per_cell].end(), gid_data);
+ else {
+ rval = create_gather_set_cells(gather_set, start_gather_set_vertex);
+ ERRORR(rval, "Failed to create gather set cells for MPAS mesh.");
}
}
- // Create a temporary map from vertex GIDs to local handles
- // Utilize the memory storage pointed by arrays[0]
- // EntityHandle* vert_gid_to_local_handle_tmp_map = (EntityHandle*) arrays[0];
- // you don't need it:
- // so vertex handle start_vertex+idx has the global ID localGidVerts[idx]
- // if I need the vertex handle for gid, use Range::index();
- // so, from gid to eh: int index = localGidVerts.index(gid)
- // eh = start_vertex+idx;
- /*Range::const_iterator rit;
- int vert_idx;
- for (rit = localGidVerts.begin(), vert_idx = 0; rit != localGidVerts.end(); ++rit, vert_idx++)
- vert_gid_to_local_handle_tmp_map[*rit - 1] = start_vertex + vert_idx;*/
+ return MB_SUCCESS;
+}
- int verticesOnEdgeVarId;
- if (!noEdges) {
- // Read vertices on each local edge, to get edge connectivity
- // Utilize the memory storage pointed by conn_arr_edges
- success = NCFUNC(inq_varid)(_fileId, "verticesOnEdge", &verticesOnEdgeVarId);
- ERRORS(success, "Failed to get variable id of verticesOnEdge.");
- int* vertices_on_local_edges = (int*) conn_arr_edges;
-#ifdef PNETCDF_FILE
- 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 tmp_starts[2] = {static_cast<NCDF_SIZE>(starth - 1), 0};
- NCDF_SIZE tmp_counts[2] = {static_cast<NCDF_SIZE>(endh - starth + 1), 2};
-
- // Do a partial read in each subrange
-#ifdef PNETCDF_FILE
- success = NCFUNCREQG(_vara_int)(_fileId, verticesOnEdgeVarId, tmp_starts, tmp_counts,
- &(vertices_on_local_edges[indexInArray]), &requests[idxReq++]);
-#else
- success = NCFUNCAG(_vara_int)(_fileId, verticesOnEdgeVarId, tmp_starts, tmp_counts,
- &(vertices_on_local_edges[indexInArray]));
-#endif
- ERRORS(success, "Failed to read verticesOnEdge data in a loop");
+ErrorCode NCHelperMPAS::read_ucd_variable_setup(std::vector<std::string>& var_names, std::vector<int>& tstep_nums,
+ std::vector<ReadNC::VarData>& vdatas, std::vector<ReadNC::VarData>& vsetdatas)
+{
+ std::map<std::string, ReadNC::VarData>& varInfo = _readNC->varInfo;
+ std::map<std::string, ReadNC::VarData>::iterator mit;
- // Increment the index for next subrange
- indexInArray += (endh - starth + 1) * 2;
+ // If empty read them all
+ if (var_names.empty()) {
+ for (mit = varInfo.begin(); mit != varInfo.end(); ++mit) {
+ ReadNC::VarData vd = (*mit).second;
+ if (3 == vd.varDims.size()) {
+ if ((std::find(vd.varDims.begin(), vd.varDims.end(), tDim) != vd.varDims.end()) && (std::find(vd.varDims.begin(),
+ vd.varDims.end(), cDim) != vd.varDims.end()) && (std::find(vd.varDims.begin(), vd.varDims.end(), levDim)
+ != vd.varDims.end()))
+ vdatas.push_back(vd); // 3D data (Time, nCells, nVertLevels) read here
+ else if ((std::find(vd.varDims.begin(), vd.varDims.end(), tDim) != vd.varDims.end()) && (std::find(vd.varDims.begin(),
+ vd.varDims.end(), eDim) != vd.varDims.end()) && (std::find(vd.varDims.begin(), vd.varDims.end(), levDim)
+ != vd.varDims.end()))
+ vdatas.push_back(vd); // 3D data (Time, nEdges, nVertLevels) read here
+ else if ((std::find(vd.varDims.begin(), vd.varDims.end(), tDim) != vd.varDims.end()) && (std::find(vd.varDims.begin(),
+ vd.varDims.end(), vDim) != vd.varDims.end()) && (std::find(vd.varDims.begin(), vd.varDims.end(), levDim)
+ != vd.varDims.end()))
+ vdatas.push_back(vd); // 3D data (Time, nVertices, nVertLevels) read here
+ }
+ else if (1 == vd.varDims.size())
+ vsetdatas.push_back(vd);
}
-
-#ifdef PNETCDF_FILE
- // Wait outside the loop
- success = NCFUNC(wait_all)(_fileId, requests.size(), &requests[0], &statuss[0]);
- ERRORS(success, "Failed on wait_all.");
-#endif
-
- // Populate connectivity for local edges
- // Convert in-place from int to EntityHandle type (backward)
- for (int edge_vert = nLocalEdges * 2 - 1; edge_vert >= 0; edge_vert--) {
- EntityHandle global_vert_id = vertices_on_local_edges[edge_vert];
- int idx_vertex = localGidVerts.index(global_vert_id);
- assert(idx_vertex != -1);
- conn_arr_edges[edge_vert] = start_vertex + idx_vertex;
+ }
+ else {
+ for (unsigned int i = 0; i < var_names.size(); i++) {
+ mit = varInfo.find(var_names[i]);
+ if (mit != varInfo.end()) {
+ ReadNC::VarData vd = (*mit).second;
+ if (3 == vd.varDims.size()) {
+ if ((std::find(vd.varDims.begin(), vd.varDims.end(), tDim) != vd.varDims.end()) && (std::find(vd.varDims.begin(),
+ vd.varDims.end(), cDim) != vd.varDims.end()) && (std::find(vd.varDims.begin(), vd.varDims.end(), levDim)
+ != vd.varDims.end()))
+ vdatas.push_back(vd); // 3D data (Time, nCells, nVertLevels) read here
+ else if ((std::find(vd.varDims.begin(), vd.varDims.end(), tDim) != vd.varDims.end()) && (std::find(vd.varDims.begin(),
+ vd.varDims.end(), eDim) != vd.varDims.end()) && (std::find(vd.varDims.begin(), vd.varDims.end(), levDim)
+ != vd.varDims.end()))
+ vdatas.push_back(vd); // 3D data (Time, nEdges, nVertLevels) read here
+ else if ((std::find(vd.varDims.begin(), vd.varDims.end(), tDim) != vd.varDims.end()) && (std::find(vd.varDims.begin(),
+ vd.varDims.end(), vDim) != vd.varDims.end()) && (std::find(vd.varDims.begin(), vd.varDims.end(), levDim)
+ != vd.varDims.end()))
+ vdatas.push_back(vd); // 3D data (Time, nVertices, nVertLevels) read here
+ }
+ else if (1 == vd.varDims.size())
+ vsetdatas.push_back(vd);
+ }
+ else {
+ ERRORR(MB_FAILURE, "Couldn't find variable.");
+ }
}
}
- // Populate connectivity for local cells
- int cell_idx;
- if (noMixedElements) {
- // Set connectivity array with proper local vertices handles
- for (cell_idx = 0; cell_idx < nLocalCells; cell_idx++) {
- int num_edges = num_edges_on_local_cells[cell_idx];
- for (int i = 0; i < num_edges; i++) {
- EntityHandle global_vert_id = vertices_on_local_cells[cell_idx * maxEdgesPerCell + i];
- int idx_vertex=localGidVerts.index(global_vert_id);
- assert(idx_vertex!=-1);
- conn_arr_local_cells[cell_idx * maxEdgesPerCell + i] = start_vertex+idx_vertex;
- }
+ if (tstep_nums.empty() && nTimeSteps > 0) {
+ // No timesteps input, get them all
+ for (int i = 0; i < nTimeSteps; i++)
+ tstep_nums.push_back(i);
+ }
- // Padding: fill connectivity array with last vertex handle
- if (num_edges < maxEdgesPerCell) {
- EntityHandle last_vert_id = conn_arr_local_cells[cell_idx * maxEdgesPerCell + num_edges - 1];
- for (int i = num_edges; i < maxEdgesPerCell; i++)
- conn_arr_local_cells[cell_idx * maxEdgesPerCell + i] = last_vert_id;
- }
+ if (!tstep_nums.empty()) {
+ for (unsigned int i = 0; i < vdatas.size(); i++) {
+ vdatas[i].varTags.resize(tstep_nums.size(), 0);
+ vdatas[i].varDatas.resize(tstep_nums.size());
+ vdatas[i].readStarts.resize(tstep_nums.size());
+ vdatas[i].readCounts.resize(tstep_nums.size());
}
- } // if (noMixedElements)
- else {
- // Create a temporary map from cell GID to local index
- // Utilize the memory storage pointed by arrays[1]
- // again, not correct because of overflow
- // here we have to use a different map, maybe RangeMap
- /*EntityHandle* cell_gid_to_local_index_tmp_map = (EntityHandle*) arrays[1];
- for (rit = localGidCells.begin(), cell_idx = 0; rit != localGidCells.end(); ++rit, cell_idx++)
- cell_gid_to_local_index_tmp_map[*rit - 1] = cell_idx;*/
-
- // For each non-empty cell group, set connectivity array with proper local vertices handles
- for (int i = 0; i < numCellGroups; i++) {
- int num_edges_per_cell = num_edges_on_cell_groups[i];
- int num_cells = (int)local_cells_with_n_edges[num_edges_per_cell].size();
- start_element = start_element_on_cell_groups[i];
-
- for (int j = 0; j < num_cells; j++) {
- cell_idx = local_cells_with_n_edges[num_edges_per_cell][j]; // Global cell index
-
- if (numCellGroups > 1)
- cellHandleToGlobalID[start_element + j] = cell_idx;
- // find the index in the range: local_cells_with_n_edges[num_edges_per_cell];
-
- // overflow averted :(
- // cell_idx = cell_gid_to_local_index_tmp_map[cell_idx - 1]; // Local cell index
- cell_idx = localGidCells.index(cell_idx);
- assert(cell_idx!=-1);
- for (int k = 0; k < num_edges_per_cell; k++) {
- EntityHandle global_vert_id = vertices_on_local_cells[cell_idx * maxEdgesPerCell + k];
- int idx_vertex=localGidVerts.index(global_vert_id);
- assert(idx_vertex!=-1);
- conn_arr_local_cells_with_n_edges[num_edges_per_cell][j * num_edges_per_cell + k] =
- start_vertex+idx_vertex;
- }
+ for (unsigned int i = 0; i < vsetdatas.size(); i++) {
+ if ((std::find(vsetdatas[i].varDims.begin(), vsetdatas[i].varDims.end(), tDim) != vsetdatas[i].varDims.end())
+ && (vsetdatas[i].varDims.size() != 1)) {
+ vsetdatas[i].varTags.resize(tstep_nums.size(), 0);
+ vsetdatas[i].varDatas.resize(tstep_nums.size());
+ vsetdatas[i].readStarts.resize(tstep_nums.size());
+ vsetdatas[i].readCounts.resize(tstep_nums.size());
+ }
+ else {
+ vsetdatas[i].varTags.resize(1, 0);
+ vsetdatas[i].varDatas.resize(1);
+ vsetdatas[i].readStarts.resize(1);
+ vsetdatas[i].readCounts.resize(1);
}
}
}
-#ifdef PNETCDF_FILE
- nb_reads = localGidVerts.psize();
- requests.resize(nb_reads);
- statuss.resize(nb_reads);
-#endif
+ return MB_SUCCESS;
+}
- // Read x coordinates for local vertices
- // Note: vert_gid_to_local_handle_tmp_map is no longer used
- double* xptr = arrays[0];
- int xVertexVarId;
- success = NCFUNC(inq_varid)(_fileId, "xVertex", &xVertexVarId);
- ERRORS(success, "Failed to get variable id of xVertex.");
-#ifdef PNETCDF_FILE
- 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 tmp_start = (NCDF_SIZE) (starth - 1);
- NCDF_SIZE tmp_count = (NCDF_SIZE) (endh - starth + 1);
+ErrorCode NCHelperMPAS::read_ucd_variable_to_nonset_allocate(std::vector<ReadNC::VarData>& vdatas, std::vector<int>& tstep_nums)
+{
+ Interface*& mbImpl = _readNC->mbImpl;
+ std::vector<int>& dimLens = _readNC->dimLens;
+ bool& noEdges = _readNC->noEdges;
+ DebugOutput& dbgOut = _readNC->dbgOut;
- // Do a partial read in each subrange
-#ifdef PNETCDF_FILE
- success = NCFUNCREQG(_vara_double)(_fileId, xVertexVarId, &tmp_start, &tmp_count,
- &(xptr[indexInArray]), &requests[idxReq++]);
-#else
- success = NCFUNCAG(_vara_double)(_fileId, xVertexVarId, &tmp_start, &tmp_count,
- &(xptr[indexInArray]));
-#endif
- ERRORS(success, "Failed to read xVertex data in a loop");
+ ErrorCode rval = MB_SUCCESS;
- // Increment the index for next subrange
- indexInArray += (endh - starth + 1);
- }
+ Range* range = NULL;
-#ifdef PNETCDF_FILE
- // Wait outside the loop
- success = NCFUNC(wait_all)(_fileId, requests.size(), &requests[0], &statuss[0]);
- ERRORS(success, "Failed on wait_all.");
-#endif
-
- // Read y coordinates for local vertices
- // Note: cell_gid_to_local_index_tmp_ma is no longer used
- double* yptr = arrays[1];
- int yVertexVarId;
- success = NCFUNC(inq_varid)(_fileId, "yVertex", &yVertexVarId);
- ERRORS(success, "Failed to get variable id of yVertex.");
-#ifdef PNETCDF_FILE
- 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 tmp_start = (NCDF_SIZE) (starth - 1);
- NCDF_SIZE tmp_count = (NCDF_SIZE) (endh - starth + 1);
-
- // Do a partial read in each subrange
-#ifdef PNETCDF_FILE
- success = NCFUNCREQG(_vara_double)(_fileId, yVertexVarId, &tmp_start, &tmp_count,
- &(yptr[indexInArray]), &requests[idxReq++]);
-#else
- success = NCFUNCAG(_vara_double)(_fileId, yVertexVarId, &tmp_start, &tmp_count,
- &(yptr[indexInArray]));
-#endif
- ERRORS(success, "Failed to read yVertex data in a loop");
-
- // Increment the index for next subrange
- indexInArray += (endh - starth + 1);
- }
-
-#ifdef PNETCDF_FILE
- // Wait outside the loop
- success = NCFUNC(wait_all)(_fileId, requests.size(), &requests[0], &statuss[0]);
- ERRORS(success, "Failed on wait_all.");
-#endif
-
- // Read z coordinates for local vertices
- double* zptr = arrays[2];
- int zVertexVarId;
- success = NCFUNC(inq_varid)(_fileId, "zVertex", &zVertexVarId);
- ERRORS(success, "Failed to get variable id of zVertex.");
-#ifdef PNETCDF_FILE
- 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 tmp_start = (NCDF_SIZE) (starth - 1);
- NCDF_SIZE tmp_count = (NCDF_SIZE) (endh - starth + 1);
-
- // Do a partial read in each subrange
-#ifdef PNETCDF_FILE
- success = NCFUNCREQG(_vara_double)(_fileId, zVertexVarId, &tmp_start, &tmp_count,
- &(zptr[indexInArray]), &requests[idxReq++]);
-#else
- success = NCFUNCAG(_vara_double)(_fileId, zVertexVarId, &tmp_start, &tmp_count,
- &(zptr[indexInArray]));
-#endif
- ERRORS(success, "Failed to read zVertex data in a loop");
-
- // Increment the index for next subrange
- indexInArray += (endh - starth + 1);
- }
-
-#ifdef PNETCDF_FILE
- // Wait outside the loop
- success = NCFUNC(wait_all)(_fileId, requests.size(), &requests[0], &statuss[0]);
- ERRORS(success, "Failed on wait_all.");
-#endif
-
- // Set tag for numCellGroups
- Tag numCellGroupsTag = 0;
- rval = mbImpl->tag_get_handle("__NUM_CELL_GROUPS", 1, MB_TYPE_INTEGER, numCellGroupsTag, MB_TAG_SPARSE | MB_TAG_CREAT);
- ERRORR(rval, "Trouble creating __NUM_CELL_GROUPS tag.");
- rval = mbImpl->tag_set_data(numCellGroupsTag, &_fileSet, 1, &numCellGroups);
- ERRORR(rval, "Trouble setting data for __NUM_CELL_GROUPS tag.");
-
- // Add new vertices, elements and edges to the file set
- rval = _readNC->mbImpl->add_entities(_fileSet, tmp_range);
- ERRORR(rval, "Couldn't add new vertices/faces/edges to file set.");
-
- dbgOut.tprintf(1, " local entities in set: tmp_range.size() = %d\n", (int)tmp_range.size());
- if (create_gathers) {
- EntityHandle gather_set;
- rval = _readNC->readMeshIface->create_gather_set(gather_set);
- ERRORR(rval, "Trouble creating gather set.");
-
- // Create gather vertices
- arrays.clear();
- // Don't need to specify allocation number here, because we know enough vertices were created before
- rval = _readNC->readMeshIface->get_node_coords(3, nVertices, 0, start_vertex, arrays);
- ERRORR(rval, "Couldn't create vertices in MPAS mesh for gather set.");
- Range gather_verts_range(start_vertex, start_vertex + nVertices - 1);
-
- xptr = arrays[0];
- yptr = arrays[1];
- zptr = arrays[2];
- NCDF_SIZE tmp_start = 0;
- NCDF_SIZE tmp_count = static_cast<NCDF_SIZE>(nVertices);
-
- // Read x coordinates for gather vertices
-#ifdef PNETCDF_FILE
- // Enter independent I/O mode, since this read is only for the gather processor
- success = NCFUNC(begin_indep_data)(_fileId);
- ERRORS(success, "Failed to begin independent I/O mode.");
- success = NCFUNCG(_vara_double)(_fileId, xVertexVarId, &tmp_start, &tmp_count, xptr);
- ERRORS(success, "Failed to read xVertex data.");
- success = NCFUNC(end_indep_data)(_fileId);
- ERRORS(success, "Failed to end independent I/O mode.");
-#else
- success = NCFUNCG(_vara_double)(_fileId, xVertexVarId, &tmp_start, &tmp_count, xptr);
- ERRORS(success, "Failed to read xVertex data.");
-#endif
-
- // Read y coordinates for gather vertices
-#ifdef PNETCDF_FILE
- // Enter independent I/O mode, since this read is only for the gather processor
- success = NCFUNC(begin_indep_data)(_fileId);
- ERRORS(success, "Failed to begin independent I/O mode.");
- success = NCFUNCG(_vara_double)(_fileId, yVertexVarId, &tmp_start, &tmp_count, yptr);
- ERRORS(success, "Failed to read yVertex data.");
- success = NCFUNC(end_indep_data)(_fileId);
- ERRORS(success, "Failed to end independent I/O mode.");
-#else
- success = NCFUNCG(_vara_double)(_fileId, yVertexVarId, &tmp_start, &tmp_count, yptr);
- ERRORS(success, "Failed to read yVertex data.");
-#endif
-
- // Read z coordinates for gather vertices
-#ifdef PNETCDF_FILE
- // Enter independent I/O mode, since this read is only for the gather processor
- success = NCFUNC(begin_indep_data)(_fileId);
- ERRORS(success, "Failed to begin independent I/O mode.");
- success = NCFUNCG(_vara_double)(_fileId, zVertexVarId, &tmp_start, &tmp_count, zptr);
- ERRORS(success, "Failed to read zVertex data.");
- success = NCFUNC(end_indep_data)(_fileId);
- ERRORS(success, "Failed to end independent I/O mode.");
-#else
- success = NCFUNCG(_vara_double)(_fileId, zVertexVarId, &tmp_start, &tmp_count, zptr);
- ERRORS(success, "Failed to read zVertex data.");
-#endif
-
- // Get ptr to GID memory for gather vertices
- rval = mbImpl->tag_iterate(mGlobalIdTag, gather_verts_range.begin(), gather_verts_range.end(), count, data);
- ERRORR(rval, "Failed to get global id tag iterator on gather 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_verts_range.begin(), gather_verts_range.end(), count, data);
- ERRORR(rval, "Failed to get file id tag iterator on gather vertices.");
- assert(count == nVertices);
- gid_data = (int*) data;
- for (int j = 1; j <= nVertices; j++)
- gid_data[j - 1] = nVertices + j; // Bigger than global id tag
- }
-
- rval = mbImpl->add_entities(gather_set, gather_verts_range);
- ERRORR(rval, "Couldn't add vertices to gather set.");
-
- // Read number of edges on each gather cell
- std::vector<int> num_edges_on_gather_cells(nCells);
- tmp_start = 0;
- tmp_count = static_cast<NCDF_SIZE>(nCells);
-#ifdef PNETCDF_FILE
- // Enter independent I/O mode, since this read is only for the gather processor
- success = NCFUNC(begin_indep_data)(_fileId);
- ERRORS(success, "Failed to begin independent I/O mode.");
- success = NCFUNCG(_vara_int)(_fileId, nEdgesOnCellVarId, &tmp_start, &tmp_count, &num_edges_on_gather_cells[0]);
- ERRORS(success, "Failed to read nEdgesOnCell data.");
- success = NCFUNC(end_indep_data)(_fileId);
- ERRORS(success, "Failed to end independent I/O mode.");
-#else
- success = NCFUNCG(_vara_int)(_fileId, nEdgesOnCellVarId, &tmp_start, &tmp_count, &num_edges_on_gather_cells[0]);
- ERRORS(success, "Failed to read nEdgesOnCell data.");
-#endif
-
- // Create gather edges
- EntityHandle* conn_arr_gather_edges;
- if (!noEdges) {
- // Don't need to specify allocation number here, because we know enough edges were created before
- rval = _readNC->readMeshIface->get_element_connect(nEdges, 2, MBEDGE, 0, start_edge, conn_arr_gather_edges);
- ERRORR(rval, "Couldn't create edges in MPAS mesh for gather set.");
- Range gather_edges_range(start_edge, start_edge + nEdges - 1);
- rval = mbImpl->add_entities(gather_set, gather_edges_range);
- ERRORR(rval, "Couldn't add edges to gather set.");
-
- // Read vertices on each edge
- std::vector<int> vertices_on_gather_edges(nEdges * 2);
- NCDF_SIZE tmp_starts[2] = {0, 0};
- NCDF_SIZE tmp_counts[2] = {static_cast<NCDF_SIZE>(nEdges), 2};
-#ifdef PNETCDF_FILE
- // Enter independent I/O mode, since this read is only for the gather processor
- success = NCFUNC(begin_indep_data)(_fileId);
- ERRORS(success, "Failed to begin independent I/O mode.");
- success = NCFUNCG(_vara_int)(_fileId, verticesOnEdgeVarId, tmp_starts, tmp_counts, &vertices_on_gather_edges[0]);
- ERRORS(success, "Failed to read verticesOnEdge data.");
- success = NCFUNC(end_indep_data)(_fileId);
- ERRORS(success, "Failed to end independent I/O mode.");
-#else
- success = NCFUNCG(_vara_int)(_fileId, verticesOnEdgeVarId, tmp_starts, tmp_counts, &vertices_on_gather_edges[0]);
- ERRORS(success, "Failed to read verticesOnEdge data.");
-#endif
-
- std::copy(vertices_on_gather_edges.begin(), vertices_on_gather_edges.end(), conn_arr_gather_edges);
- for (int i = 0; i < 2 * nEdges; i++)
- // Connectivity array is shifted by where the gather verts start
- conn_arr_gather_edges[i] += start_vertex - 1;
- }
-
- // Read vertices on each gather cell (connectivity)
- std::vector<int> vertices_on_gather_cells(nCells * maxEdgesPerCell);
- NCDF_SIZE tmp_starts[2] = {0, 0};
- NCDF_SIZE tmp_counts[2] = {static_cast<NCDF_SIZE>(nCells), maxEdgesPerCell};
-#ifdef PNETCDF_FILE
- // Enter independent I/O mode, since this read is only for the gather processor
- success = NCFUNC(begin_indep_data)(_fileId);
- ERRORS(success, "Failed to begin independent I/O mode.");
- success = NCFUNCG(_vara_int)(_fileId, verticesOnCellVarId, tmp_starts, tmp_counts, &vertices_on_gather_cells[0]);
- ERRORS(success, "Failed to read verticesOnCell data.");
- success = NCFUNC(end_indep_data)(_fileId);
- ERRORS(success, "Failed to end independent I/O mode.");
-#else
- success = NCFUNCG(_vara_int)(_fileId, verticesOnCellVarId, tmp_starts, tmp_counts, &vertices_on_gather_cells[0]);
- ERRORS(success, "Failed to read verticesOnCell data.");
-#endif
-
- Range gather_cells_range;
- if (noMixedElements) {
- // Create gather cells
- EntityHandle* conn_arr_gather_cells;
- // Don't need to specify allocation number here, because we know enough cells were created before
- rval = _readNC->readMeshIface->get_element_connect(nCells, maxEdgesPerCell, MBPOLYGON, 0, start_element, conn_arr_gather_cells);
- ERRORR(rval, "Couldn't create cells in MPAS mesh for gather set.");
- gather_cells_range.insert(start_element, start_element + nCells - 1);
-
- for (cell_idx = 0; cell_idx < nCells; cell_idx++) {
- int num_edges = num_edges_on_gather_cells[cell_idx];
- for (int i = 0; i < num_edges; i++)
- // Connectivity array is shifted by where the gather verts start
- conn_arr_gather_cells[cell_idx * maxEdgesPerCell + i] = (start_vertex - 1) + vertices_on_gather_cells[cell_idx * maxEdgesPerCell + i];
-
- // Padding: fill connectivity array with last vertex handle
- EntityHandle last_vert_id = conn_arr_gather_cells[cell_idx * maxEdgesPerCell + num_edges - 1];
- for (int i = num_edges; i < maxEdgesPerCell; i++)
- conn_arr_gather_cells[cell_idx * maxEdgesPerCell + i] = last_vert_id;
- }
- }
- else {
- // Divide gather cells into groups based on the number of edges
- std::vector<int> gather_cells_with_n_edges[DEFAULT_MAX_EDGES_PER_CELL + 1];
- for (int i = 0; i < nCells; i++) {
- int num_edges = num_edges_on_gather_cells[i];
- gather_cells_with_n_edges[num_edges].push_back(i + 1); // 0 based -> 1 based
- }
-
- // Create gather cells
- EntityHandle* conn_arr_gather_cells_with_n_edges[DEFAULT_MAX_EDGES_PER_CELL + 1];
- for (int num_edges_per_cell = 3; num_edges_per_cell <= maxEdgesPerCell; num_edges_per_cell++) {
- int num_cells = gather_cells_with_n_edges[num_edges_per_cell].size();
- if (num_cells > 0) {
- rval = _readNC->readMeshIface->get_element_connect(num_cells, num_edges_per_cell, MBPOLYGON, 0, start_element,
- conn_arr_gather_cells_with_n_edges[num_edges_per_cell], num_cells);
- ERRORR(rval, "Couldn't create cells in MPAS mesh for gather set.");
- gather_cells_range.insert(start_element, start_element + num_cells - 1);
- for (int j = 0; j < num_cells; j++) {
- cell_idx = gather_cells_with_n_edges[num_edges_per_cell][j];
- cell_idx--; // 1 based -> 0 based
- for (int k = 0; k < num_edges_per_cell; k++)
- // Connectivity array is shifted by where the gather verts start
- conn_arr_gather_cells_with_n_edges[num_edges_per_cell][j * num_edges_per_cell + k] =
- (start_vertex - 1) + vertices_on_gather_cells[cell_idx * maxEdgesPerCell + k];
- }
- }
- }
- }
-
- rval = mbImpl->add_entities(gather_set, gather_cells_range);
- ERRORR(rval, "Couldn't add cells to gather set.");
- }
-
- return MB_SUCCESS;
-}
-
-ErrorCode NCHelperMPAS::read_ucd_variable_setup(std::vector<std::string>& var_names, std::vector<int>& tstep_nums,
- std::vector<ReadNC::VarData>& vdatas, std::vector<ReadNC::VarData>& vsetdatas)
-{
- std::map<std::string, ReadNC::VarData>& varInfo = _readNC->varInfo;
- std::map<std::string, ReadNC::VarData>::iterator mit;
-
- // If empty read them all
- if (var_names.empty()) {
- for (mit = varInfo.begin(); mit != varInfo.end(); ++mit) {
- ReadNC::VarData vd = (*mit).second;
- if (3 == vd.varDims.size()) {
- if ((std::find(vd.varDims.begin(), vd.varDims.end(), tDim) != vd.varDims.end()) && (std::find(vd.varDims.begin(),
- vd.varDims.end(), cDim) != vd.varDims.end()) && (std::find(vd.varDims.begin(), vd.varDims.end(), levDim)
- != vd.varDims.end()))
- vdatas.push_back(vd); // 3D data (Time, nCells, nVertLevels) read here
- else if ((std::find(vd.varDims.begin(), vd.varDims.end(), tDim) != vd.varDims.end()) && (std::find(vd.varDims.begin(),
- vd.varDims.end(), eDim) != vd.varDims.end()) && (std::find(vd.varDims.begin(), vd.varDims.end(), levDim)
- != vd.varDims.end()))
- vdatas.push_back(vd); // 3D data (Time, nEdges, nVertLevels) read here
- else if ((std::find(vd.varDims.begin(), vd.varDims.end(), tDim) != vd.varDims.end()) && (std::find(vd.varDims.begin(),
- vd.varDims.end(), vDim) != vd.varDims.end()) && (std::find(vd.varDims.begin(), vd.varDims.end(), levDim)
- != vd.varDims.end()))
- vdatas.push_back(vd); // 3D data (Time, nVertices, nVertLevels) read here
- }
- else if (1 == vd.varDims.size())
- vsetdatas.push_back(vd);
- }
- }
- else {
- for (unsigned int i = 0; i < var_names.size(); i++) {
- mit = varInfo.find(var_names[i]);
- if (mit != varInfo.end()) {
- ReadNC::VarData vd = (*mit).second;
- if (3 == vd.varDims.size()) {
- if ((std::find(vd.varDims.begin(), vd.varDims.end(), tDim) != vd.varDims.end()) && (std::find(vd.varDims.begin(),
- vd.varDims.end(), cDim) != vd.varDims.end()) && (std::find(vd.varDims.begin(), vd.varDims.end(), levDim)
- != vd.varDims.end()))
- vdatas.push_back(vd); // 3D data (Time, nCells, nVertLevels) read here
- else if ((std::find(vd.varDims.begin(), vd.varDims.end(), tDim) != vd.varDims.end()) && (std::find(vd.varDims.begin(),
- vd.varDims.end(), eDim) != vd.varDims.end()) && (std::find(vd.varDims.begin(), vd.varDims.end(), levDim)
- != vd.varDims.end()))
- vdatas.push_back(vd); // 3D data (Time, nEdges, nVertLevels) read here
- else if ((std::find(vd.varDims.begin(), vd.varDims.end(), tDim) != vd.varDims.end()) && (std::find(vd.varDims.begin(),
- vd.varDims.end(), vDim) != vd.varDims.end()) && (std::find(vd.varDims.begin(), vd.varDims.end(), levDim)
- != vd.varDims.end()))
- vdatas.push_back(vd); // 3D data (Time, nVertices, nVertLevels) read here
- }
- else if (1 == vd.varDims.size())
- vsetdatas.push_back(vd);
- }
- else {
- ERRORR(MB_FAILURE, "Couldn't find variable.");
- }
- }
- }
-
- if (tstep_nums.empty() && nTimeSteps > 0) {
- // No timesteps input, get them all
- for (int i = 0; i < nTimeSteps; i++)
- tstep_nums.push_back(i);
- }
-
- if (!tstep_nums.empty()) {
- for (unsigned int i = 0; i < vdatas.size(); i++) {
- vdatas[i].varTags.resize(tstep_nums.size(), 0);
- vdatas[i].varDatas.resize(tstep_nums.size());
- vdatas[i].readStarts.resize(tstep_nums.size());
- vdatas[i].readCounts.resize(tstep_nums.size());
- }
- for (unsigned int i = 0; i < vsetdatas.size(); i++) {
- if ((std::find(vsetdatas[i].varDims.begin(), vsetdatas[i].varDims.end(), tDim) != vsetdatas[i].varDims.end())
- && (vsetdatas[i].varDims.size() != 1)) {
- vsetdatas[i].varTags.resize(tstep_nums.size(), 0);
- vsetdatas[i].varDatas.resize(tstep_nums.size());
- vsetdatas[i].readStarts.resize(tstep_nums.size());
- vsetdatas[i].readCounts.resize(tstep_nums.size());
- }
- else {
- vsetdatas[i].varTags.resize(1, 0);
- vsetdatas[i].varDatas.resize(1);
- vsetdatas[i].readStarts.resize(1);
- vsetdatas[i].readCounts.resize(1);
- }
- }
- }
-
- return MB_SUCCESS;
-}
-
-ErrorCode NCHelperMPAS::read_ucd_variable_to_nonset_allocate(std::vector<ReadNC::VarData>& vdatas, std::vector<int>& tstep_nums)
-{
- Interface*& mbImpl = _readNC->mbImpl;
- std::vector<int>& dimLens = _readNC->dimLens;
- bool& noEdges = _readNC->noEdges;
- DebugOutput& dbgOut = _readNC->dbgOut;
-
- ErrorCode rval = MB_SUCCESS;
-
- Range* range = NULL;
-
- // Get vertices in set
- Range verts;
- rval = mbImpl->get_entities_by_dimension(_fileSet, 0, verts);
- ERRORR(rval, "Trouble getting vertices in set.");
- assert("Should only have a single vertex subrange, since they were read in one shot" &&
- verts.psize() == 1);
+ // Get vertices in set
+ Range verts;
+ rval = mbImpl->get_entities_by_dimension(_fileSet, 0, verts);
+ ERRORR(rval, "Trouble getting vertices in set.");
+ assert("Should only have a single vertex subrange, since they were read in one shot" &&
+ verts.psize() == 1);
// Get edges in set
Range edges;
@@ -1285,7 +633,7 @@ ErrorCode NCHelperMPAS::read_ucd_variable_to_nonset_allocate(std::vector<ReadNC:
void* data;
int count;
rval = mbImpl->tag_iterate(vdatas[i].varTags[t], range->begin(), range->end(), count, data);
- ERRORR(rval, "Failed to get tag iterator.");
+ ERRORR(rval, "Failed to iterate tag.");
assert((unsigned)count == range->size());
vdatas[i].varDatas[t] = data;
}
@@ -1393,7 +741,7 @@ ErrorCode NCHelperMPAS::read_ucd_variable_to_nonset_async(std::vector<ReadNC::Va
int count;
void* ptr;
rval = mbImpl->tag_iterate(vdatas[i].varTags[t], iter, facesOwned.end(), count, ptr);
- ERRORR(rval, "Failed to get tag iterator.");
+ ERRORR(rval, "Failed to iterate tag on owned faces.");
for (int j = 0; j < count; j++) {
int cell_idx = cellHandleToGlobalID[*(iter + j)]; // Global cell index
@@ -1537,7 +885,7 @@ ErrorCode NCHelperMPAS::read_ucd_variable_to_nonset(std::vector<ReadNC::VarData>
int count;
void* ptr;
rval = mbImpl->tag_iterate(vdatas[i].varTags[t], iter, facesOwned.end(), count, ptr);
- ERRORR(rval, "Failed to get tag iterator.");
+ ERRORR(rval, "Failed to iterate tag on owned faces.");
for (int j = 0; j < count; j++) {
int cell_idx = cellHandleToGlobalID[*(iter + j)]; // Global cell index
@@ -1602,4 +950,773 @@ ErrorCode NCHelperMPAS::read_ucd_variable_to_nonset(std::vector<ReadNC::VarData>
}
#endif
+ErrorCode NCHelperMPAS::redistribute_local_cells(int start_cell_idx)
+{
+ // If possible, apply Zoltan partition
+ if (_readNC->partMethod == ScdParData::RCBZOLTAN) {
+#if defined(USE_MPI) && defined(PNETCDF_FILE) && defined(HAVE_ZOLTAN)
+ // Read x coordinates of cell centers
+ int xCellVarId;
+ int success = NCFUNC(inq_varid)(_fileId, "xCell", &xCellVarId);
+ ERRORS(success, "Failed to get variable id of xCell.");
+ std::vector<double> xCell(nLocalCells);
+ NCDF_SIZE read_start = 0;
+ NCDF_SIZE read_count = static_cast<NCDF_SIZE>(nLocalCells);
+ success = NCFUNCAG(_vara_double)(_fileId, xCellVarId, &read_start, &read_count, &xCell[0]);
+ ERRORS(success, "Failed to read xCell data.");
+
+ // Read y coordinates of cell centers
+ int yCellVarId;
+ success = NCFUNC(inq_varid)(_fileId, "yCell", &yCellVarId);
+ ERRORS(success, "Failed to get variable id of yCell.");
+ std::vector<double> yCell(nLocalCells);
+ success = NCFUNCAG(_vara_double)(_fileId, yCellVarId, &read_start, &read_count, &yCell[0]);
+ ERRORS(success, "Failed to read yCell data.");
+
+ // Read z coordinates of cell centers
+ int zCellVarId;
+ success = NCFUNC(inq_varid)(_fileId, "zCell", &zCellVarId);
+ ERRORS(success, "Failed to get variable id of zCell.");
+ std::vector<double> zCell(nLocalCells);
+ success = NCFUNCAG(_vara_double)(_fileId, zCellVarId, &read_start, &read_count, &zCell[0]);
+ ERRORS(success, "Failed to read zCell data.");
+
+ // Zoltan partition using RCB; maybe more studies would be good, as to which partition
+ // is better
+ Interface*& mbImpl = _readNC->mbImpl;
+ DebugOutput& dbgOut = _readNC->dbgOut;
+ MBZoltan* mbZTool = new MBZoltan(mbImpl, false, 0, NULL);
+ ErrorCode rval = mbZTool->repartition(xCell, yCell, zCell, start_cell_idx, "RCB", localGidCells);
+ //delete mbZTool;
+ ERRORR(rval, "Error in Zoltan partitioning.");
+
+ dbgOut.tprintf(1, "After Zoltan partitioning, localGidCells.psize() = %d\n", (int)localGidCells.psize());
+ dbgOut.tprintf(1, " localGidCells.size() = %d\n", (int)localGidCells.size());
+
+ // This is important: local cells are now redistributed, so nLocalCells might be different!
+ nLocalCells = localGidCells.size();
+
+ return MB_SUCCESS;
+#endif
+ }
+
+ // By default, apply trivial partition
+ localGidCells.insert(start_cell_idx, start_cell_idx + nLocalCells - 1);
+
+ return MB_SUCCESS;
+}
+
+ErrorCode NCHelperMPAS::create_local_vertices(const std::vector<int>& vertices_on_local_cells, EntityHandle& start_vertex)
+{
+ Interface*& mbImpl = _readNC->mbImpl;
+ Tag& mGlobalIdTag = _readNC->mGlobalIdTag;
+ const Tag*& mpFileIdTag = _readNC->mpFileIdTag;
+ DebugOutput& dbgOut = _readNC->dbgOut;
+
+ // 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));
+ ERRORR(rval, "Failed to create local vertices.");
+
+ // Add local vertices to the file set
+ Range local_verts_range(start_vertex, start_vertex + nLocalVertices - 1);
+ rval = _readNC->mbImpl->add_entities(_fileSet, local_verts_range);
+ ERRORR(rval, "Failed to add local vertices to the 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);
+ ERRORR(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);
+ ERRORR(rval, "Failed to iterate file id tag on local vertices.");
+ assert(count == nLocalVertices);
+ gid_data = (int*) data;
+ std::copy(localGidVerts.begin(), localGidVerts.end(), gid_data);
+ }
+
+#ifdef PNETCDF_FILE
+ size_t nb_reads = localGidVerts.psize();
+ std::vector<int> requests(nb_reads);
+ std::vector<int> statuss(nb_reads);
+ size_t idxReq = 0;
+#endif
+
+ // Read x coordinates for local vertices
+ double* xptr = arrays[0];
+ int xVertexVarId;
+ int success = NCFUNC(inq_varid)(_fileId, "xVertex", &xVertexVarId);
+ ERRORS(success, "Failed to get variable id of xVertex.");
+ 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 PNETCDF_FILE
+ 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
+ ERRORS(success, "Failed to read xVertex data in a loop");
+
+ // Increment the index for next subrange
+ indexInArray += (endh - starth + 1);
+ }
+
+#ifdef PNETCDF_FILE
+ // Wait outside the loop
+ success = NCFUNC(wait_all)(_fileId, requests.size(), &requests[0], &statuss[0]);
+ ERRORS(success, "Failed on wait_all.");
+#endif
+
+ // Read y coordinates for local vertices
+ double* yptr = arrays[1];
+ int yVertexVarId;
+ success = NCFUNC(inq_varid)(_fileId, "yVertex", &yVertexVarId);
+ ERRORS(success, "Failed to get variable id of yVertex.");
+#ifdef PNETCDF_FILE
+ 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 PNETCDF_FILE
+ 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
+ ERRORS(success, "Failed to read yVertex data in a loop");
+
+ // Increment the index for next subrange
+ indexInArray += (endh - starth + 1);
+ }
+
+#ifdef PNETCDF_FILE
+ // Wait outside the loop
+ success = NCFUNC(wait_all)(_fileId, requests.size(), &requests[0], &statuss[0]);
+ ERRORS(success, "Failed on wait_all.");
+#endif
+
+ // Read z coordinates for local vertices
+ double* zptr = arrays[2];
+ int zVertexVarId;
+ success = NCFUNC(inq_varid)(_fileId, "zVertex", &zVertexVarId);
+ ERRORS(success, "Failed to get variable id of zVertex.");
+#ifdef PNETCDF_FILE
+ 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 PNETCDF_FILE
+ success = NCFUNCREQG(_vara_double)(_fileId, zVertexVarId, &read_start, &read_count,
+ &(zptr[indexInArray]), &requests[idxReq++]);
+#else
+ success = NCFUNCAG(_vara_double)(_fileId, zVertexVarId, &read_start, &read_count,
+ &(zptr[indexInArray]));
+#endif
+ ERRORS(success, "Failed to read zVertex data in a loop");
+
+ // Increment the index for next subrange
+ indexInArray += (endh - starth + 1);
+ }
+
+#ifdef PNETCDF_FILE
+ // Wait outside the loop
+ success = NCFUNC(wait_all)(_fileId, requests.size(), &requests[0], &statuss[0]);
+ ERRORS(success, "Failed on wait_all.");
+#endif
+
+ return MB_SUCCESS;
+}
+
+ErrorCode NCHelperMPAS::create_local_edges(EntityHandle start_vertex)
+{
+ 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, "edgesOnCell", &edgesOnCellVarId);
+ ERRORS(success, "Failed to get variable id of edgesOnCell.");
+
+ std::vector<int> edges_on_local_cells(nLocalCells * maxEdgesPerCell);
+ dbgOut.tprintf(1, " edges_on_local_cells.size() = %d\n", (int)edges_on_local_cells.size());
+
+#ifdef PNETCDF_FILE
+ 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;
+ 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>(maxEdgesPerCell)};
+
+ // Do a partial read in each subrange
+#ifdef PNETCDF_FILE
+ 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
+ ERRORS(success, "Failed to read edgesOnCell data in a loop");
+
+ // Increment the index for next subrange
+ indexInArray += (endh - starth + 1) * maxEdgesPerCell;
+ }
+
+#ifdef PNETCDF_FILE
+ // Wait outside the loop
+ success = NCFUNC(wait_all)(_fileId, requests.size(), &requests[0], &statuss[0]);
+ ERRORS(success, "Failed on wait_all.");
+#endif
+
+ // 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));
+ ERRORR(rval, "Failed to create edges.");
+
+ // Add local edges to the file set
+ Range local_edges_range(start_edge, start_edge + nLocalEdges - 1);
+ rval = _readNC->mbImpl->add_entities(_fileSet, local_edges_range);
+ ERRORR(rval, "Failed to add local edges to the 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);
+ ERRORR(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
+ // Utilize the memory storage pointed by conn_arr_edges
+ success = NCFUNC(inq_varid)(_fileId, "verticesOnEdge", &verticesOnEdgeVarId);
+ ERRORS(success, "Failed to get variable id of verticesOnEdge.");
+ int* vertices_on_local_edges = (int*) conn_arr_edges;
+#ifdef PNETCDF_FILE
+ 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 PNETCDF_FILE
+ 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
+ ERRORS(success, "Failed to read verticesOnEdge data in a loop");
+
+ // Increment the index for next subrange
+ indexInArray += (endh - starth + 1) * 2;
+ }
+
+#ifdef PNETCDF_FILE
+ // Wait outside the loop
+ success = NCFUNC(wait_all)(_fileId, requests.size(), &requests[0], &statuss[0]);
+ ERRORS(success, "Failed on wait_all.");
+#endif
+
+ // Populate connectivity for local edges
+ // Convert in-place from int to EntityHandle type (backward)
+ for (int edge_vert = nLocalEdges * 2 - 1; edge_vert >= 0; edge_vert--) {
+ EntityHandle global_vert_id = vertices_on_local_edges[edge_vert]; // 1 based
+ int vert_idx = localGidVerts.index(global_vert_id); // 0 based
+ assert(vert_idx != -1);
+ conn_arr_edges[edge_vert] = start_vertex + vert_idx;
+ }
+
+ return MB_SUCCESS;
+}
+
+ErrorCode NCHelperMPAS::create_local_cells(const std::vector<int>& vertices_on_local_cells,
+ const std::vector<int>& num_edges_on_local_cells,
+ EntityHandle start_vertex, Range& faces)
+{
+ Interface*& mbImpl = _readNC->mbImpl;
+ Tag& mGlobalIdTag = _readNC->mGlobalIdTag;
+
+ // Divide local cells into groups based on the number of edges
+ Range local_cells_with_n_edges[DEFAULT_MAX_EDGES_PER_CELL + 1];
+ for (int i = nLocalCells - 1; i >= 0; i--) {
+ int num_edges = num_edges_on_local_cells[i];
+ local_cells_with_n_edges[num_edges].insert(localGidCells[i]); // Global cell index
+ }
+
+ std::vector<int> num_edges_on_cell_groups;
+ for (int i = 3; i <= maxEdgesPerCell; i++) {
+ if (local_cells_with_n_edges[i].size() > 0)
+ num_edges_on_cell_groups.push_back(i);
+ }
+ numCellGroups = num_edges_on_cell_groups.size();
+
+ EntityHandle* conn_arr_local_cells_with_n_edges[DEFAULT_MAX_EDGES_PER_CELL + 1];
+ for (int i = 0; i < numCellGroups; i++) {
+ int num_edges_per_cell = num_edges_on_cell_groups[i];
+ int num_group_cells = (int)local_cells_with_n_edges[num_edges_per_cell].size();
+
+ // Create local cells for each non-empty cell group
+ EntityHandle start_element;
+ ErrorCode rval = _readNC->readMeshIface->get_element_connect(num_group_cells, num_edges_per_cell, MBPOLYGON, 0, start_element,
+ conn_arr_local_cells_with_n_edges[num_edges_per_cell], num_group_cells);
+ ERRORR(rval, "Failed to create cells");
+ faces.insert(start_element, start_element + num_group_cells - 1);
+
+ // Add local cells to the file set
+ Range local_cells_range(start_element, start_element + num_group_cells - 1);
+ rval = _readNC->mbImpl->add_entities(_fileSet, local_cells_range);
+ ERRORR(rval, "Failed to add local cells to the 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);
+ ERRORR(rval, "Failed to iterate global id tag on local cells.");
+ assert(count == num_group_cells);
+ int* gid_data = (int*) data;
+ std::copy(local_cells_with_n_edges[num_edges_per_cell].begin(), local_cells_with_n_edges[num_edges_per_cell].end(), gid_data);
+
+ // Set connectivity array with proper local vertices handles
+ for (int j = 0; j < num_group_cells; j++) {
+ int cell_idx = (int)local_cells_with_n_edges[num_edges_per_cell][j]; // Global cell index
+
+ if (numCellGroups > 1)
+ cellHandleToGlobalID[start_element + j] = cell_idx;
+
+ cell_idx = localGidCells.index(cell_idx);
+ assert(cell_idx != -1);
+
+ for (int k = 0; k < num_edges_per_cell; k++) {
+ EntityHandle global_vert_id = vertices_on_local_cells[cell_idx * maxEdgesPerCell + k];
+ int idx_vertex = localGidVerts.index(global_vert_id);
+ assert(idx_vertex != -1);
+ conn_arr_local_cells_with_n_edges[num_edges_per_cell][j * num_edges_per_cell + k] =
+ start_vertex + idx_vertex;
+ }
+ }
+ }
+
+ return MB_SUCCESS;
+}
+
+ErrorCode NCHelperMPAS::create_padded_local_cells(const std::vector<int>& vertices_on_local_cells,
+ const std::vector<int>& num_edges_on_local_cells,
+ EntityHandle start_vertex, Range& faces)
+{
+ Interface*& mbImpl = _readNC->mbImpl;
+ Tag& mGlobalIdTag = _readNC->mGlobalIdTag;
+
+ // Only one group of cells (each cell is represented by a polygon with maxEdgesPerCell edges)
+ numCellGroups = 1;
+
+ // Create cells for this cell group
+ EntityHandle start_element;
+ EntityHandle* conn_arr_local_cells = NULL;
+ ErrorCode rval = _readNC->readMeshIface->get_element_connect(nLocalCells, maxEdgesPerCell, MBPOLYGON, 0, start_element, conn_arr_local_cells,
+ // Might have to create gather mesh later
+ (createGatherSet ? nLocalCells + nCells : nLocalCells));
+ ERRORR(rval, "Failed to create cells.");
+ faces.insert(start_element, start_element + nLocalCells - 1);
+
+ // Add local cells to the file set
+ Range local_cells_range(start_element, start_element + nLocalCells - 1);
+ rval = _readNC->mbImpl->add_entities(_fileSet, local_cells_range);
+ ERRORR(rval, "Failed to add local cells to the 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);
+ ERRORR(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
+ for (int cell_idx = 0; cell_idx < nLocalCells; cell_idx++) {
+ int num_edges = num_edges_on_local_cells[cell_idx];
+ for (int i = 0; i < num_edges; i++) {
+ EntityHandle global_vert_id = vertices_on_local_cells[cell_idx * maxEdgesPerCell + i]; // 1 based
+ int local_vert_idx = localGidVerts.index(global_vert_id); // 0 based
+ assert(local_vert_idx != -1);
+ conn_arr_local_cells[cell_idx * maxEdgesPerCell + i] = start_vertex + local_vert_idx;
+ }
+
+ // Padding: fill connectivity array with last vertex handle
+ if (num_edges < maxEdgesPerCell) {
+ EntityHandle last_vert_id = conn_arr_local_cells[cell_idx * maxEdgesPerCell + num_edges - 1];
+ for (int i = num_edges; i < maxEdgesPerCell; i++)
+ conn_arr_local_cells[cell_idx * maxEdgesPerCell + i] = last_vert_id;
+ }
+ }
+
+ return MB_SUCCESS;
+}
+
+ErrorCode NCHelperMPAS::create_gather_set_vertices(EntityHandle gather_set, EntityHandle& gather_set_start_vertex)
+{
+ 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);
+ ERRORR(rval, "Failed to create 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);
+ ERRORR(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, "xVertex", &xVertexVarId);
+ ERRORS(success, "Failed to get variable id of xVertex.");
+ NCDF_SIZE read_start = 0;
+ NCDF_SIZE read_count = static_cast<NCDF_SIZE>(nVertices);
+#ifdef PNETCDF_FILE
+ // Enter independent I/O mode, since this read is only for the gather processor
+ success = NCFUNC(begin_indep_data)(_fileId);
+ ERRORS(success, "Failed to begin independent I/O mode.");
+ success = NCFUNCG(_vara_double)(_fileId, xVertexVarId, &read_start, &read_count, xptr);
+ ERRORS(success, "Failed to read xVertex data.");
+ success = NCFUNC(end_indep_data)(_fileId);
+ ERRORS(success, "Failed to end independent I/O mode.");
+#else
+ success = NCFUNCG(_vara_double)(_fileId, xVertexVarId, &read_start, &read_count, xptr);
+ ERRORS(success, "Failed to read xVertex data.");
+#endif
+
+ // Read y coordinates for gather set vertices
+ double* yptr = arrays[1];
+ int yVertexVarId;
+ success = NCFUNC(inq_varid)(_fileId, "yVertex", &yVertexVarId);
+ ERRORS(success, "Failed to get variable id of yVertex.");
+#ifdef PNETCDF_FILE
+ // Enter independent I/O mode, since this read is only for the gather processor
+ success = NCFUNC(begin_indep_data)(_fileId);
+ ERRORS(success, "Failed to begin independent I/O mode.");
+ success = NCFUNCG(_vara_double)(_fileId, yVertexVarId, &read_start, &read_count, yptr);
+ ERRORS(success, "Failed to read yVertex data.");
+ success = NCFUNC(end_indep_data)(_fileId);
+ ERRORS(success, "Failed to end independent I/O mode.");
+#else
+ success = NCFUNCG(_vara_double)(_fileId, yVertexVarId, &read_start, &read_count, yptr);
+ ERRORS(success, "Failed to read yVertex data.");
+#endif
+
+ // Read z coordinates for gather set vertices
+ double* zptr = arrays[2];
+ int zVertexVarId;
+ success = NCFUNC(inq_varid)(_fileId, "zVertex", &zVertexVarId);
+ ERRORS(success, "Failed to get variable id of zVertex.");
+#ifdef PNETCDF_FILE
+ // Enter independent I/O mode, since this read is only for the gather processor
+ success = NCFUNC(begin_indep_data)(_fileId);
+ ERRORS(success, "Failed to begin independent I/O mode.");
+ success = NCFUNCG(_vara_double)(_fileId, zVertexVarId, &read_start, &read_count, zptr);
+ ERRORS(success, "Failed to read zVertex data.");
+ success = NCFUNC(end_indep_data)(_fileId);
+ ERRORS(success, "Failed to end independent I/O mode.");
+#else
+ success = NCFUNCG(_vara_double)(_fileId, zVertexVarId, &read_start, &read_count, zptr);
+ ERRORS(success, "Failed to read zVertex data.");
+#endif
+
+ // 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);
+ ERRORR(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);
+ ERRORR(rval, "Failed to iterate file id tag on gather set vertices.");
+ assert(count == nVertices);
+ gid_data = (int*) data;
+ for (int j = 1; j <= nVertices; j++)
+ gid_data[j - 1] = nVertices + j; // Bigger than global id tag
+ }
+
+ return MB_SUCCESS;
+}
+
+ErrorCode NCHelperMPAS::create_gather_set_edges(EntityHandle gather_set, EntityHandle gather_set_start_vertex)
+{
+ Interface*& mbImpl = _readNC->mbImpl;
+
+ // Create gather set edges
+ EntityHandle start_edge;
+ EntityHandle* conn_arr_gather_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_edges);
+ ERRORR(rval, "Failed to create edges.");
+
+ // Add edges to the gather set
+ Range gather_edges_range(start_edge, start_edge + nEdges - 1);
+ rval = mbImpl->add_entities(gather_set, gather_edges_range);
+ ERRORR(rval, "Failed to add edges to the gather set.");
+
+ // Read vertices on each edge
+ int verticesOnEdgeVarId;
+ int success = NCFUNC(inq_varid)(_fileId, "verticesOnEdge", &verticesOnEdgeVarId);
+ ERRORS(success, "Failed to get variable id of verticesOnEdge.");
+ std::vector<int> vertices_on_gather_edges(nEdges * 2);
+ NCDF_SIZE read_starts[2] = {0, 0};
+ NCDF_SIZE read_counts[2] = {static_cast<NCDF_SIZE>(nEdges), 2};
+ #ifdef PNETCDF_FILE
+ // Enter independent I/O mode, since this read is only for the gather processor
+ success = NCFUNC(begin_indep_data)(_fileId);
+ ERRORS(success, "Failed to begin independent I/O mode.");
+ success = NCFUNCG(_vara_int)(_fileId, verticesOnEdgeVarId, read_starts, read_counts, &vertices_on_gather_edges[0]);
+ ERRORS(success, "Failed to read verticesOnEdge data.");
+ success = NCFUNC(end_indep_data)(_fileId);
+ ERRORS(success, "Failed to end independent I/O mode.");
+ #else
+ success = NCFUNCG(_vara_int)(_fileId, verticesOnEdgeVarId, read_starts, read_counts, &vertices_on_gather_edges[0]);
+ ERRORS(success, "Failed to read verticesOnEdge data.");
+ #endif
+
+ std::copy(vertices_on_gather_edges.begin(), vertices_on_gather_edges.end(), conn_arr_gather_edges);
+ for (int i = 0; i < 2 * nEdges; i++)
+ // Connectivity array is shifted by where the gather set vertices start
+ conn_arr_gather_edges[i] += gather_set_start_vertex - 1;
+
+ return MB_SUCCESS;
+}
+
+ErrorCode NCHelperMPAS::create_gather_set_cells(EntityHandle gather_set, EntityHandle gather_set_start_vertex)
+{
+ Interface*& mbImpl = _readNC->mbImpl;
+
+ // Read number of edges on each gather set cell
+ int nEdgesOnCellVarId;
+ int success = NCFUNC(inq_varid)(_fileId, "nEdgesOnCell", &nEdgesOnCellVarId);
+ ERRORS(success, "Failed to get variable id of nEdgesOnCell.");
+ std::vector<int> num_edges_on_gather_cells(nCells);
+ NCDF_SIZE read_start = 0;
+ NCDF_SIZE read_count = static_cast<NCDF_SIZE>(nCells);
+#ifdef PNETCDF_FILE
+ // Enter independent I/O mode, since this read is only for the gather processor
+ success = NCFUNC(begin_indep_data)(_fileId);
+ ERRORS(success, "Failed to begin independent I/O mode.");
+ success = NCFUNCG(_vara_int)(_fileId, nEdgesOnCellVarId, &read_start, &read_count, &num_edges_on_gather_cells[0]);
+ ERRORS(success, "Failed to read nEdgesOnCell data.");
+ success = NCFUNC(end_indep_data)(_fileId);
+ ERRORS(success, "Failed to end independent I/O mode.");
+#else
+ success = NCFUNCG(_vara_int)(_fileId, nEdgesOnCellVarId, &read_start, &read_count, &num_edges_on_gather_cells[0]);
+ ERRORS(success, "Failed to read nEdgesOnCell data.");
+#endif
+
+ // Read vertices on each gather set cell (connectivity)
+ int verticesOnCellVarId;
+ success = NCFUNC(inq_varid)(_fileId, "verticesOnCell", &verticesOnCellVarId);
+ ERRORS(success, "Failed to get variable id of verticesOnCell.");
+ std::vector<int> vertices_on_gather_cells(nCells * maxEdgesPerCell);
+ NCDF_SIZE read_starts[2] = {0, 0};
+ NCDF_SIZE read_counts[2] = {static_cast<NCDF_SIZE>(nCells), maxEdgesPerCell};
+#ifdef PNETCDF_FILE
+ // Enter independent I/O mode, since this read is only for the gather processor
+ success = NCFUNC(begin_indep_data)(_fileId);
+ ERRORS(success, "Failed to begin independent I/O mode.");
+ success = NCFUNCG(_vara_int)(_fileId, verticesOnCellVarId, read_starts, read_counts, &vertices_on_gather_cells[0]);
+ ERRORS(success, "Failed to read verticesOnCell data.");
+ success = NCFUNC(end_indep_data)(_fileId);
+ ERRORS(success, "Failed to end independent I/O mode.");
+#else
+ success = NCFUNCG(_vara_int)(_fileId, verticesOnCellVarId, read_starts, read_counts, &vertices_on_gather_cells[0]);
+ ERRORS(success, "Failed to read verticesOnCell data.");
+#endif
+
+ // Divide gather set cells into groups based on the number of edges
+ std::vector<int> gather_cells_with_n_edges[DEFAULT_MAX_EDGES_PER_CELL + 1];
+ for (int i = 0; i < nCells; i++) {
+ int num_edges = num_edges_on_gather_cells[i];
+ gather_cells_with_n_edges[num_edges].push_back(i + 1); // 0 based -> 1 based
+ }
+
+ // Create gather set cells
+ EntityHandle* conn_arr_gather_cells_with_n_edges[DEFAULT_MAX_EDGES_PER_CELL + 1];
+ for (int num_edges_per_cell = 3; num_edges_per_cell <= maxEdgesPerCell; num_edges_per_cell++) {
+ int num_group_cells = gather_cells_with_n_edges[num_edges_per_cell].size();
+ if (num_group_cells > 0) {
+ EntityHandle start_element;
+ ErrorCode rval = _readNC->readMeshIface->get_element_connect(num_group_cells, num_edges_per_cell, MBPOLYGON, 0, start_element,
+ conn_arr_gather_cells_with_n_edges[num_edges_per_cell], num_group_cells);
+ ERRORR(rval, "Failed to create cells.");
+
+ // Add cells to the gather set
+ Range gather_cells_range(start_element, start_element + num_group_cells - 1);
+ rval = mbImpl->add_entities(gather_set, gather_cells_range);
+ ERRORR(rval, "Failed to add cells to the gather set.");
+
+ for (int j = 0; j < num_group_cells; j++) {
+ int cell_idx = gather_cells_with_n_edges[num_edges_per_cell][j]; // Global cell index
+ cell_idx--; // 1 based -> 0 based
+
+ for (int k = 0; k < num_edges_per_cell; k++)
+ // Connectivity array is shifted by where the gather set vertices start
+ conn_arr_gather_cells_with_n_edges[num_edges_per_cell][j * num_edges_per_cell + k] =
+ (gather_set_start_vertex - 1) + vertices_on_gather_cells[cell_idx * maxEdgesPerCell + k];
+ }
+ }
+ }
+
+ return MB_SUCCESS;
+}
+
+ErrorCode NCHelperMPAS::create_padded_gather_set_cells(EntityHandle gather_set, EntityHandle gather_set_start_vertex)
+{
+ Interface*& mbImpl = _readNC->mbImpl;
+
+ // Read number of edges on each gather set cell
+ int nEdgesOnCellVarId;
+ int success = NCFUNC(inq_varid)(_fileId, "nEdgesOnCell", &nEdgesOnCellVarId);
+ ERRORS(success, "Failed to get variable id of nEdgesOnCell.");
+ std::vector<int> num_edges_on_gather_cells(nCells);
+ NCDF_SIZE read_start = 0;
+ NCDF_SIZE read_count = static_cast<NCDF_SIZE>(nCells);
+#ifdef PNETCDF_FILE
+ // Enter independent I/O mode, since this read is only for the gather processor
+ success = NCFUNC(begin_indep_data)(_fileId);
+ ERRORS(success, "Failed to begin independent I/O mode.");
+ success = NCFUNCG(_vara_int)(_fileId, nEdgesOnCellVarId, &read_start, &read_count, &num_edges_on_gather_cells[0]);
+ ERRORS(success, "Failed to read nEdgesOnCell data.");
+ success = NCFUNC(end_indep_data)(_fileId);
+ ERRORS(success, "Failed to end independent I/O mode.");
+#else
+ success = NCFUNCG(_vara_int)(_fileId, nEdgesOnCellVarId, &read_start, &read_count, &num_edges_on_gather_cells[0]);
+ ERRORS(success, "Failed to read nEdgesOnCell data.");
+#endif
+
+ // Read vertices on each gather set cell (connectivity)
+ int verticesOnCellVarId;
+ success = NCFUNC(inq_varid)(_fileId, "verticesOnCell", &verticesOnCellVarId);
+ ERRORS(success, "Failed to get variable id of verticesOnCell.");
+ std::vector<int> vertices_on_gather_cells(nCells * maxEdgesPerCell);
+ NCDF_SIZE read_starts[2] = {0, 0};
+ NCDF_SIZE read_counts[2] = {static_cast<NCDF_SIZE>(nCells), maxEdgesPerCell};
+#ifdef PNETCDF_FILE
+ // Enter independent I/O mode, since this read is only for the gather processor
+ success = NCFUNC(begin_indep_data)(_fileId);
+ ERRORS(success, "Failed to begin independent I/O mode.");
+ success = NCFUNCG(_vara_int)(_fileId, verticesOnCellVarId, read_starts, read_counts, &vertices_on_gather_cells[0]);
+ ERRORS(success, "Failed to read verticesOnCell data.");
+ success = NCFUNC(end_indep_data)(_fileId);
+ ERRORS(success, "Failed to end independent I/O mode.");
+#else
+ success = NCFUNCG(_vara_int)(_fileId, verticesOnCellVarId, read_starts, read_counts, &vertices_on_gather_cells[0]);
+ ERRORS(success, "Failed to read verticesOnCell data.");
+#endif
+
+ // Create gather set cells
+ EntityHandle start_element;
+ EntityHandle* conn_arr_gather_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, maxEdgesPerCell, MBPOLYGON, 0, start_element, conn_arr_gather_cells);
+ ERRORR(rval, "Failed to create cells.");
+
+ // Add cells to the gather set
+ Range gather_cells_range(start_element, start_element + nCells - 1);
+ rval = mbImpl->add_entities(gather_set, gather_cells_range);
+ ERRORR(rval, "Failed to add cells to the gather set.");
+
+ for (int cell_idx = 0; cell_idx < nCells; cell_idx++) {
+ int num_edges = num_edges_on_gather_cells[cell_idx];
+ for (int i = 0; i < num_edges; i++)
+ // Connectivity array is shifted by where the gather set vertices start
+ conn_arr_gather_cells[cell_idx * maxEdgesPerCell + i] = (gather_set_start_vertex - 1) + vertices_on_gather_cells[cell_idx * maxEdgesPerCell + i];
+
+ // Padding: fill connectivity array with last vertex handle
+ EntityHandle last_vert_id = conn_arr_gather_cells[cell_idx * maxEdgesPerCell + num_edges - 1];
+ for (int i = num_edges; i < maxEdgesPerCell; i++)
+ conn_arr_gather_cells[cell_idx * maxEdgesPerCell + i] = last_vert_id;
+ }
+
+ return MB_SUCCESS;
+}
+
} // namespace moab
diff --git a/src/io/NCHelperMPAS.hpp b/src/io/NCHelperMPAS.hpp
index ba440b8..5c751a0 100644
--- a/src/io/NCHelperMPAS.hpp
+++ b/src/io/NCHelperMPAS.hpp
@@ -26,7 +26,7 @@ private:
//! Implementation of NCHelper::check_existing_mesh()
virtual ErrorCode check_existing_mesh();
//! Implementation of NCHelper::create_mesh()
- virtual ErrorCode create_mesh(Range& quads);
+ virtual ErrorCode create_mesh(Range& faces);
//! Implementation of NCHelper::get_mesh_type_name()
virtual std::string get_mesh_type_name() { return "MPAS"; }
@@ -48,9 +48,41 @@ private:
std::vector<int>& tstep_nums);
#endif
+ //! Redistribute local cells after trivial partition (e.g. Zoltan partition, if applicable)
+ ErrorCode redistribute_local_cells(int start_cell_index);
+
+ //! Create local vertices
+ ErrorCode create_local_vertices(const std::vector<int>& vertices_on_local_cells, EntityHandle& start_vertex);
+
+ //! Create local edges (optional)
+ ErrorCode create_local_edges(EntityHandle start_vertex);
+
+ //! Create local cells without padding (cells are divided into groups based on the number of edges)
+ ErrorCode create_local_cells(const std::vector<int>& vertices_on_local_cells,
+ const std::vector<int>& num_edges_on_local_cells,
+ EntityHandle start_vertex, Range& faces);
+
+ //! Create local cells with padding (padded cells will have the same number of edges)
+ ErrorCode create_padded_local_cells(const std::vector<int>& vertices_on_local_cells,
+ const std::vector<int>& num_edges_on_local_cells,
+ EntityHandle start_vertex, Range& faces);
+
+ //! Create gather set vertices
+ ErrorCode create_gather_set_vertices(EntityHandle gather_set, EntityHandle& gather_set_start_vertex);
+
+ //! Create gather set edges (optional)
+ ErrorCode create_gather_set_edges(EntityHandle gather_set, EntityHandle gather_set_start_vertex);
+
+ //! Create gather set cells without padding (cells are divided into groups based on the number of edges)
+ ErrorCode create_gather_set_cells(EntityHandle gather_set, EntityHandle gather_set_start_vertex);
+
+ //! Create gather set cells with padding (padded cells will have the same number of edges)
+ ErrorCode create_padded_gather_set_cells(EntityHandle gather_set, EntityHandle gather_set_start_vertex);
+
private:
int maxEdgesPerCell;
int numCellGroups;
+ bool createGatherSet;
std::map<EntityHandle, int> cellHandleToGlobalID;
Range facesOwned;
};
Repository URL: https://bitbucket.org/fathomteam/moab/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
More information about the moab-dev
mailing list