[MOAB-dev] commit/MOAB: danwu: Cleaned up some code for NC writer.

commits-noreply at bitbucket.org commits-noreply at bitbucket.org
Fri May 2 14:08:49 CDT 2014


1 new commit in MOAB:

https://bitbucket.org/fathomteam/moab/commits/b574ca4b0955/
Changeset:   b574ca4b0955
Branch:      master
User:        danwu
Date:        2014-05-02 21:08:15
Summary:     Cleaned up some code for NC writer.

Affected #:  6 files

diff --git a/src/io/NCWriteHOMME.cpp b/src/io/NCWriteHOMME.cpp
index 9320f62..e2bb69e 100644
--- a/src/io/NCWriteHOMME.cpp
+++ b/src/io/NCWriteHOMME.cpp
@@ -47,10 +47,10 @@ ErrorCode NCWriteHOMME::collect_mesh_info()
   }
   nLevels = dimLens[levDim];
 
-  Range local_verts;
-  rval = mbImpl->get_entities_by_dimension(_fileSet, 0, local_verts);
+  // Get local vertices
+  rval = mbImpl->get_entities_by_dimension(_fileSet, 0, localVertsOwned);
   ERRORR(rval, "Trouble getting local vertices in current file set.");
-  assert(!local_verts.empty());
+  assert(!localVertsOwned.empty());
 
 #ifdef USE_MPI
   bool& isParallel = _writeNC->isParallel;
@@ -59,29 +59,24 @@ ErrorCode NCWriteHOMME::collect_mesh_info()
     int rank = myPcomm->proc_config().proc_rank();
     int procs = myPcomm->proc_config().proc_size();
     if (procs > 1) {
-      rval = myPcomm->filter_pstatus(local_verts, PSTATUS_NOT_OWNED, PSTATUS_NOT, -1, &localVertsOwned);
+      unsigned int num_local_verts = localVertsOwned.size();
+      rval = myPcomm->filter_pstatus(localVertsOwned, PSTATUS_NOT_OWNED, PSTATUS_NOT);
       ERRORR(rval, "Trouble getting owned vertices in set.");
+
       // Assume that PARALLEL_RESOLVE_SHARED_ENTS option is set
-      // We should avoid writing in parallel with overlapped data
-      if (rank > 0)
-        assert("PARALLEL_RESOLVE_SHARED_ENTS option is set" && localVertsOwned.size() < local_verts.size());
+      // Verify that not all local vertices are owned by the last processor
+      if (procs - 1 == rank)
+        assert("PARALLEL_RESOLVE_SHARED_ENTS option is set" && localVertsOwned.size() < num_local_verts);
     }
-    else
-      localVertsOwned = local_verts;
   }
-  else
-    localVertsOwned = local_verts; // Not running in parallel, but still with MPI
-#else
-  localVertsOwned = local_verts;
 #endif
 
   std::vector<int> gids(localVertsOwned.size());
   rval = mbImpl->tag_get_data(mGlobalIdTag, localVertsOwned, &gids[0]);
   ERRORR(rval, "Trouble getting global IDs on local vertices.");
 
-  // Restore localGidVerts
+  // Get localGidVertsOwned
   std::copy(gids.rbegin(), gids.rend(), range_inserter(localGidVertsOwned));
-  nLocalVerticesOwned = localGidVertsOwned.size();
 
   return MB_SUCCESS;
 }
@@ -125,7 +120,7 @@ ErrorCode NCWriteHOMME::collect_variable_data(std::vector<std::string>& var_name
           // Start from the first localGidVerts
           // Actually, this will be reset later for writing
           currentVarData.writeStarts[2] = localGidVertsOwned[0] - 1;
-          currentVarData.writeCounts[2] = nLocalVerticesOwned;
+          currentVarData.writeCounts[2] = localGidVertsOwned.size();
           break;
         default:
           ERRORR(MB_FAILURE, "Unexpected entity location type for HOMME non-set variable.");
@@ -149,6 +144,7 @@ ErrorCode NCWriteHOMME::write_values(std::vector<std::string>& var_names)
   std::map<std::string, WriteNC::VarData>& varInfo = _writeNC->varInfo;
 
   int success;
+  int num_local_verts_owned = localVertsOwned.size();
 
   // Now look at requested var_names; if they have time, we will have a list, and write one at a time
   // Need to transpose from lev dimension
@@ -160,7 +156,7 @@ ErrorCode NCWriteHOMME::write_values(std::vector<std::string>& var_names)
       ERRORR(MB_FAILURE, "Can't find variable requested.");
 
     WriteNC::VarData& variableData = vit->second;
-    int numTimeSteps = (int)variableData.varTags.size();
+
     if (variableData.has_tsteps) {
       // Time should be the first dimension
       assert(tDim == variableData.varDims[0]);
@@ -178,13 +174,14 @@ ErrorCode NCWriteHOMME::write_values(std::vector<std::string>& var_names)
       // At each timestep, we need to transpose tag format (ncol, lev) back
       // to NC format (lev, ncol) for writing
       // FIXME: Should use tstep_nums (from writing options) later
+      int numTimeSteps = (int)variableData.varTags.size();
       for (int j = 0; j < numTimeSteps; j++) {
         // We will write one time step, and count will be one; start will be different
         // Use tag_get_data instead of tag_iterate to get values, as localVertsOwned
         // might not be contiguous. We should also transpose for level so that means
         // deep copy for transpose
         variableData.writeStarts[0] = j; // This is time, again
-        std::vector<double> tag_data(nLocalVerticesOwned * variableData.numLev);
+        std::vector<double> tag_data(num_local_verts_owned * variableData.numLev);
         ErrorCode rval = mbImpl->tag_get_data(variableData.varTags[j], localVertsOwned, &tag_data[0]);
         ERRORR(rval, "Trouble getting tag data on owned vertices.");
 
@@ -197,9 +194,9 @@ ErrorCode NCWriteHOMME::write_values(std::vector<std::string>& var_names)
         // Now write from memory directly
         switch (variableData.varDataType) {
           case NC_DOUBLE: {
-            std::vector<double> tmpdoubledata(nLocalVerticesOwned * variableData.numLev);
+            std::vector<double> tmpdoubledata(num_local_verts_owned * variableData.numLev);
             // Transpose (ncol, lev) back to (lev, ncol)
-            jik_to_kji(nLocalVerticesOwned, 1, variableData.numLev, &tmpdoubledata[0], &tag_data[0]);
+            jik_to_kji(num_local_verts_owned, 1, variableData.numLev, &tmpdoubledata[0], &tag_data[0]);
 
             size_t indexInDoubleArray = 0;
             size_t ic = 0;

diff --git a/src/io/NCWriteHelper.cpp b/src/io/NCWriteHelper.cpp
index 58d95c2..1b4b70d 100644
--- a/src/io/NCWriteHelper.cpp
+++ b/src/io/NCWriteHelper.cpp
@@ -222,13 +222,13 @@ ErrorCode NCWriteHelper::init_file(std::vector<std::string>& var_names, std::vec
   int tDim_in_dimNames = tDim;
   int levDim_in_dimNames = levDim;
 
-  // if append mode, make sure we are in define mode; a simple open will not allow creation of new variables
-  if (append)
-  {
+  // If append mode, make sure we are in define mode; a simple open will not allow creation of new variables
+  if (append) {
     int errcode = NCFUNC(redef)(_fileId);
     if (errcode != NC_NOERR)
-      ERRORR(MB_FAILURE, "Can't open file in  redefine mode");
+      ERRORR(MB_FAILURE, "Can't open file in redefine mode");
   }
+
   // First initialize all coordinates, then fill VarData for actual variables (and dimensions)
   // Check that for used coordinates we have found the tags
   for (std::set<std::string>::iterator setIt = usedCoordinates.begin();
@@ -242,40 +242,40 @@ ErrorCode NCWriteHelper::init_file(std::vector<std::string>& var_names, std::vec
     WriteNC::VarData& varCoordData = vit->second;
     varCoordData.varDims.resize(1);
 
-    // if not append, create it for sure
-    // if append, we might already have it, including the tag / variable with the same name
+    // If not append, create it for sure
+    // If append, we might already have it, including the tag / variable with the same name
     /*
      * int ncmpi_inq_dimid(int ncid, const char *name, int *idp);
      */
-    if (append)
-    {
+    if (append) {
       int dimId;
-      if (NCFUNC(inq_dimid)(_fileId, coordName.c_str(), &dimId) == NC_NOERR)
-        // if not found, create it later
-      {
+      if (NCFUNC(inq_dimid)(_fileId, coordName.c_str(), &dimId) == NC_NOERR) { // If not found, create it later
         varCoordData.varDims[0] = dimId;
-        // check that the coordinate is a variable too
-        // Skip dummy coordinate variables (e.g. ncol)
         dbgOut.tprintf(2, "    file already has coordName %s dim id is %d \n", coordName.c_str(), (int)varCoordData.varDims[0]);
+
+        // Update tDim and levDim to actual dimension id
+        if (coordName == dimNames[tDim_in_dimNames])
+          tDim = varCoordData.varDims[0];
+        else if (coordName == dimNames[levDim_in_dimNames])
+          levDim = varCoordData.varDims[0];
+
+        // Skip dummy coordinate variables (e.g. ncol)
         if (dummyVarNames.find(coordName) != dummyVarNames.end())
           continue;
-        // inquire for a variable with the same name
 
+        // Check that the coordinate is a variable too
+        // Inquire for a variable with the same name
         int varId;
         if (NCFUNC(inq_varid)(_fileId, coordName.c_str(), &varId) != NC_NOERR)
-          ERRORR(MB_FAILURE, "we do not have a variable with the same name.");
-        // we should also check that this variable has one dimension, and it is dimId
+          ERRORR(MB_FAILURE, "We do not have a variable with the same name.");
+        // We should also check that this variable has one dimension, and it is dimId
         varCoordData.varId = varId;
         dbgOut.tprintf(2, "    file already has coordinate %s and varId is %d \n", coordName.c_str(), varId);
-        // Update tDim and levDim to actual dimension id
-        if (coordName == dimNames[tDim_in_dimNames])
-          tDim = varCoordData.varDims[0];
-        else if (coordName == dimNames[levDim_in_dimNames])
-          levDim = varCoordData.varDims[0];
-        continue; // maybe more checks are needed here
-      }
 
+        continue; // Maybe more checks are needed here
+      }
     }
+
     /* int nc_def_dim (int ncid, const char *name, size_t len, int *dimidp);
        * example:  status = nc_def_dim(fileId, "lat", 18L, &latid);
     */
@@ -284,7 +284,6 @@ ErrorCode NCWriteHelper::init_file(std::vector<std::string>& var_names, std::vec
     if (NCFUNC(def_dim)(_fileId, coordName.c_str(), (size_t)varCoordData.sz,
         &varCoordData.varDims[0]) != NC_NOERR)
      ERRORR(MB_FAILURE, "Failed to generate dimension.");
-
     dbgOut.tprintf(2, "    for coordName %s dim id is %d \n", coordName.c_str(), (int)varCoordData.varDims[0]);
 
     // Update tDim and levDim to actual dimension id
@@ -323,8 +322,9 @@ ErrorCode NCWriteHelper::init_file(std::vector<std::string>& var_names, std::vec
       continue;
 
     WriteNC::VarData& variableData = vit->second;
-    int numDims = (int)variableData.varDims.size();
+
     // The index is for dimNames; we need to find out the actual dimension id (from above)
+    int numDims = (int)variableData.varDims.size();
     for (int j = 0; j < numDims; j++) {
       std::string dimName = dimNames[variableData.varDims[j]];
       std::map<std::string, WriteNC::VarData>::iterator vit2 = varInfo.find(dimName);
@@ -342,7 +342,7 @@ ErrorCode NCWriteHelper::init_file(std::vector<std::string>& var_names, std::vec
     int errCode = NCFUNC(def_var)(_fileId, desired_names[i].c_str(), variableData.varDataType,
         (int)variableData.varDims.size(), &(variableData.varDims[0]),
         &variableData.varId);
-    if ( errCode != NC_NOERR)
+    if (errCode != NC_NOERR)
       ERRORR(MB_FAILURE, "Failed to create coordinate variable.");
 
     dbgOut.tprintf(2, "    for variable %s with desired name %s variable id is %d \n", var_names[i].c_str(),
@@ -454,6 +454,23 @@ ErrorCode ScdNCWriteHelper::collect_mesh_info()
   lCDims[1] = val[0];
   lCDims[4] = val[1];
 
+  // Get local faces
+  rval = mbImpl->get_entities_by_dimension(_fileSet, 2, localCellsOwned);
+  ERRORR(rval, "Trouble getting local faces in current file set.");
+  assert(!localCellsOwned.empty());
+
+#ifdef USE_MPI
+  bool& isParallel = _writeNC->isParallel;
+  if (isParallel) {
+    ParallelComm*& myPcomm = _writeNC->myPcomm;
+    int procs = myPcomm->proc_config().proc_size();
+    if (procs > 1) {
+      rval = myPcomm->filter_pstatus(localCellsOwned, PSTATUS_NOT_OWNED, PSTATUS_NOT);
+      ERRORR(rval, "Trouble getting owned faces in set.");
+    }
+  }
+#endif
+
   return MB_SUCCESS;
 }
 
@@ -489,7 +506,7 @@ ErrorCode ScdNCWriteHelper::collect_variable_data(std::vector<std::string>& var_
       currentVarData.writeStarts[1] = 0;
       currentVarData.writeCounts[1] = currentVarData.numLev;
 
-      // Finally: lat (or slat) and lon (or slon)
+      // Finally: lat and lon
       switch (currentVarData.entLoc) {
         case WriteNC::ENTLOCFACE:
           // Faces
@@ -499,7 +516,7 @@ ErrorCode ScdNCWriteHelper::collect_variable_data(std::vector<std::string>& var_
           currentVarData.writeCounts[3] = lCDims[3] - lCDims[0] + 1;
           break;
         default:
-          ERRORR(MB_FAILURE, "Not implemented yet.");
+          ERRORR(MB_FAILURE, "Unexpected entity location type for structured mesh non-set variable.");
       }
     }
 
@@ -512,6 +529,11 @@ ErrorCode ScdNCWriteHelper::collect_variable_data(std::vector<std::string>& var_
   return MB_SUCCESS;
 }
 
+// For parallel write, we assume that the data ranges do not overlap across processors
+// While overlapped writing might still work, we should better not take that risk
+// For CAM-EUL and CAM-FV variables on non-shared quads (e.g. T), this is not an issue
+// We assume that there are no variables on vertices and we do not support variables
+// on edges (e.g. US in CAM-FV) for the time being
 ErrorCode ScdNCWriteHelper::write_values(std::vector<std::string>& var_names)
 {
   Interface*& mbImpl = _writeNC->mbImpl;
@@ -519,14 +541,10 @@ ErrorCode ScdNCWriteHelper::write_values(std::vector<std::string>& var_names)
   std::set<std::string>& dummyVarNames = _writeNC->dummyVarNames;
   std::map<std::string, WriteNC::VarData>& varInfo = _writeNC->varInfo;
 
-  ErrorCode rval;
   int success;
 
   // Now look at requested var_names; if they have time, we will have a list, and write one at a time
   // If not, just write regularly
-  // For parallel write, we assume that the data ranges do not overlap across processors (this is true
-  // for Euler and FV variables on quads)
-  // While overlapped writing might still work, we should better not take that risk
   // Use collective I/O mode put (synchronous write) for the time being, we can try nonblocking put
   // (request aggregation) later
   for (size_t i = 0; i < var_names.size(); i++) {
@@ -540,26 +558,13 @@ ErrorCode ScdNCWriteHelper::write_values(std::vector<std::string>& var_names)
       // Time should be the first dimension
       assert(tDim == variableData.varDims[0]);
 
-      // Get entities of this variable
-      Range ents;
+      // Assume this variable is on faces for the time being
       switch (variableData.entLoc) {
         case WriteNC::ENTLOCFACE:
           // Faces
-        {
-          rval = mbImpl->get_entities_by_dimension(_fileSet, 2, ents);
-          ERRORR(rval, "Can't get entities for faces.");
-#ifdef USE_MPI
-          bool &isParallel = _writeNC->isParallel;
-          if (isParallel) {
-            ParallelComm*& myPcomm = _writeNC->myPcomm;
-            rval = myPcomm->filter_pstatus(ents, PSTATUS_NOT_OWNED, PSTATUS_NOT);
-            ERRORR(rval, "Can't get filter for owned entities");
-          }
-#endif
-        }
           break;
         default:
-          ERRORR(MB_FAILURE, "Not implemented yet.");
+          ERRORR(MB_FAILURE, "Unexpected entity location type for structured mesh non-set variable.");
       }
 
       // A typical variable has 4 dimensions as (time, lev, lat, lon)
@@ -578,8 +583,9 @@ ErrorCode ScdNCWriteHelper::write_values(std::vector<std::string>& var_names)
         variableData.writeStarts[0] = j; // This is time, again
         int count;
         void* dataptr;
-        rval = mbImpl->tag_iterate(variableData.varTags[j], ents.begin(), ents.end(), count, dataptr);
-        assert(count == (int)ents.size());
+        ErrorCode rval = mbImpl->tag_iterate(variableData.varTags[j], localCellsOwned.begin(), localCellsOwned.end(), count, dataptr);
+        ERRORR(rval, "Failed to get tag iterator on owned faces.");
+        assert(count == (int)localCellsOwned.size());
 
         // Now write from memory directly
         switch (variableData.varDataType) {

diff --git a/src/io/NCWriteHelper.hpp b/src/io/NCWriteHelper.hpp
index 25a3120..8c64eac 100644
--- a/src/io/NCWriteHelper.hpp
+++ b/src/io/NCWriteHelper.hpp
@@ -60,6 +60,9 @@ protected:
 
   //! Dimension numbers for time and level
   int tDim, levDim;
+
+  //! Local owned cells, edges and vertices
+  Range localCellsOwned, localEdgesOwned, localVertsOwned;
 };
 
 //! Child helper class for scd mesh, e.g. CAM_EL or CAM_FV
@@ -100,22 +103,13 @@ class UcdNCWriteHelper : public NCWriteHelper
 public:
   UcdNCWriteHelper(WriteNC* writeNC, int fileId, const FileOptions& opts, EntityHandle fileSet)
 : NCWriteHelper(writeNC, fileId, opts, fileSet),
-  nLocalCellsOwned(0), nLocalEdgesOwned(0), nLocalVerticesOwned(0),
   cDim(-1), eDim(-1), vDim(-1) {}
   virtual ~UcdNCWriteHelper() {}
 
 protected:
-  //! Dimensions of my local owned part of grid
-  int nLocalCellsOwned;
-  int nLocalEdgesOwned;
-  int nLocalVerticesOwned;
-
   //! Dimension numbers for nCells, nEdges and nVertices
   int cDim, eDim, vDim;
 
-  //! Local owned cells, edges and vertices
-  Range localCellsOwned, localEdgesOwned, localVertsOwned;
-
   //! Local global ID for owned cells, edges and vertices
   Range localGidCellsOwned, localGidEdgesOwned, localGidVertsOwned;
 };

diff --git a/src/io/NCWriteMPAS.cpp b/src/io/NCWriteMPAS.cpp
index 8058726..8fca53d 100644
--- a/src/io/NCWriteMPAS.cpp
+++ b/src/io/NCWriteMPAS.cpp
@@ -49,21 +49,20 @@ ErrorCode NCWriteMPAS::collect_mesh_info()
   }
   nLevels = dimLens[levDim];
 
-  Range local_verts;
-  rval = mbImpl->get_entities_by_dimension(_fileSet, 0, local_verts);
+  // Get local vertices
+  rval = mbImpl->get_entities_by_dimension(_fileSet, 0, localVertsOwned);
   ERRORR(rval, "Trouble getting local vertices in current file set.");
-  assert(!local_verts.empty());
+  assert(!localVertsOwned.empty());
 
-  // Depends on whether NO_EDGES read option is set or not
-  Range local_edges;
-  rval = mbImpl->get_entities_by_dimension(_fileSet, 1, local_edges);
+  // Get local edges
+  rval = mbImpl->get_entities_by_dimension(_fileSet, 1, localEdgesOwned);
   ERRORR(rval, "Trouble getting local edges in current file set.");
-  noEdges = local_edges.empty();
+  // There are no edges if NO_EDGES read option is set
 
-  Range local_cells;
-  rval = mbImpl->get_entities_by_dimension(_fileSet, 2, local_cells);
+  // Get local cells
+  rval = mbImpl->get_entities_by_dimension(_fileSet, 2, localCellsOwned);
   ERRORR(rval, "Trouble getting local cells in current file set.");
-  assert(!local_cells.empty());
+  assert(!localCellsOwned.empty());
 
 #ifdef USE_MPI
   bool& isParallel = _writeNC->isParallel;
@@ -72,62 +71,48 @@ ErrorCode NCWriteMPAS::collect_mesh_info()
     int rank = myPcomm->proc_config().proc_rank();
     int procs = myPcomm->proc_config().proc_size();
     if (procs > 1) {
-      rval = myPcomm->filter_pstatus(local_verts, PSTATUS_NOT_OWNED, PSTATUS_NOT, -1, &localVertsOwned);
+      unsigned int num_local_verts = localVertsOwned.size();
+      rval = myPcomm->filter_pstatus(localVertsOwned, PSTATUS_NOT_OWNED, PSTATUS_NOT);
       ERRORR(rval, "Trouble getting owned vertices in set.");
+
       // Assume that PARALLEL_RESOLVE_SHARED_ENTS option is set
-      // We should avoid writing in parallel with overlapped data
+      // Verify that not all local vertices are owned by the last processor
       if (procs - 1 == rank)
-        assert("PARALLEL_RESOLVE_SHARED_ENTS option is set" && localVertsOwned.size() < local_verts.size());
+        assert("PARALLEL_RESOLVE_SHARED_ENTS option is set" && localVertsOwned.size() < num_local_verts);
 
-      if (!noEdges) {
-        rval = myPcomm->filter_pstatus(local_edges, PSTATUS_NOT_OWNED, PSTATUS_NOT, -1, &localEdgesOwned);
+      if (!localEdgesOwned.empty()) {
+        rval = myPcomm->filter_pstatus(localEdgesOwned, PSTATUS_NOT_OWNED, PSTATUS_NOT);
         ERRORR(rval, "Trouble getting owned edges in set.");
       }
 
-      rval = myPcomm->filter_pstatus(local_cells, PSTATUS_NOT_OWNED, PSTATUS_NOT, -1, &localCellsOwned);
+      rval = myPcomm->filter_pstatus(localCellsOwned, PSTATUS_NOT_OWNED, PSTATUS_NOT);
       ERRORR(rval, "Trouble getting owned cells in set.");
     }
-    else {
-      localVertsOwned = local_verts;
-      localEdgesOwned = local_edges;
-      localCellsOwned = local_cells;
-    }
   }
-  else {
-    // Not running in parallel, but still with MPI
-    localVertsOwned = local_verts;
-    localEdgesOwned = local_edges;
-    localCellsOwned = local_cells;
-  }
-#else
-  localVertsOwned = local_verts;
-  localEdgesOwned = local_edges;
-  localCellsOwned = local_cells;
 #endif
 
   std::vector<int> gids(localVertsOwned.size());
   rval = mbImpl->tag_get_data(mGlobalIdTag, localVertsOwned, &gids[0]);
   ERRORR(rval, "Trouble getting global IDs on local vertices.");
 
-  // Restore localGidVerts
+  // Get localGidVertsOwned
   std::copy(gids.rbegin(), gids.rend(), range_inserter(localGidVertsOwned));
-  nLocalVerticesOwned = localGidVertsOwned.size();
 
-  gids.resize(localEdgesOwned.size());
-  rval = mbImpl->tag_get_data(mGlobalIdTag, localEdgesOwned, &gids[0]);
-  ERRORR(rval, "Trouble getting global IDs on local edges.");
+  if (!localEdgesOwned.empty()) {
+    gids.resize(localEdgesOwned.size());
+    rval = mbImpl->tag_get_data(mGlobalIdTag, localEdgesOwned, &gids[0]);
+    ERRORR(rval, "Trouble getting global IDs on local edges.");
 
-  // Restore localGidEdges
-  std::copy(gids.rbegin(), gids.rend(), range_inserter(localGidEdgesOwned));
-  nLocalEdgesOwned = localGidEdgesOwned.size();
+    // Get localGidEdgesOwned
+    std::copy(gids.rbegin(), gids.rend(), range_inserter(localGidEdgesOwned));
+  }
 
   gids.resize(localCellsOwned.size());
   rval = mbImpl->tag_get_data(mGlobalIdTag, localCellsOwned, &gids[0]);
   ERRORR(rval, "Trouble getting global IDs on local cells.");
 
-  // Restore localGidCells
+  // Get localGidCellsOwned
   std::copy(gids.rbegin(), gids.rend(), range_inserter(localGidCellsOwned));
-  nLocalCellsOwned = localGidCellsOwned.size();
 
   return MB_SUCCESS;
 }
@@ -172,9 +157,13 @@ ErrorCode NCWriteMPAS::collect_variable_data(std::vector<std::string>& var_names
       ERRORR(MB_FAILURE, "Can't find one variable.");
 
     WriteNC::VarData& currentVarData = vit->second;
-    std::vector<int>& varDims = currentVarData.varDims;
+
+    // Skip edge variables, if there are no edges
+    if (localEdgesOwned.empty() && currentVarData.entLoc == WriteNC::ENTLOCEDGE)
+      continue;
 
     // If nVertLevels dimension is not found, try other optional levels such as nVertLevelsP1
+    std::vector<int>& varDims = currentVarData.varDims;
     if (std::find(varDims.begin(), varDims.end(), levDim) == varDims.end()) {
       for (unsigned int j = 0; j < opt_lev_dims.size(); j++) {
         if (std::find(varDims.begin(), varDims.end(), opt_lev_dims[j]) != varDims.end()) {
@@ -187,10 +176,10 @@ ErrorCode NCWriteMPAS::collect_variable_data(std::vector<std::string>& var_names
     if (currentVarData.has_tsteps) {
       // Support non-set variables with 3 dimensions like (Time, nCells, nVertLevels), or
       // 2 dimensions like (Time, nCells)
-      assert(3 == currentVarData.varDims.size() || 2 == currentVarData.varDims.size());
+      assert(3 == varDims.size() || 2 == varDims.size());
 
       // Time should be the first dimension
-      assert(tDim == currentVarData.varDims[0]);
+      assert(tDim == varDims[0]);
 
       // Set up writeStarts and writeCounts
       currentVarData.writeStarts.resize(3);
@@ -207,21 +196,21 @@ ErrorCode NCWriteMPAS::collect_variable_data(std::vector<std::string>& var_names
           // Start from the first localGidVerts
           // Actually, this will be reset later for writing
           currentVarData.writeStarts[1] = localGidVertsOwned[0] - 1;
-          currentVarData.writeCounts[1] = nLocalVerticesOwned;
+          currentVarData.writeCounts[1] = localGidVertsOwned.size();
           break;
         case WriteNC::ENTLOCFACE:
           // Faces
           // Start from the first localGidCells
           // Actually, this will be reset later for writing
           currentVarData.writeStarts[1] = localGidCellsOwned[0] - 1;
-          currentVarData.writeCounts[1] = nLocalCellsOwned;
+          currentVarData.writeCounts[1] = localGidCellsOwned.size();
           break;
         case WriteNC::ENTLOCEDGE:
           // Edges
           // Start from the first localGidEdges
           // Actually, this will be reset later for writing
           currentVarData.writeStarts[1] = localGidEdgesOwned[0] - 1;
-          currentVarData.writeCounts[1] = nLocalEdgesOwned;
+          currentVarData.writeCounts[1] = localGidEdgesOwned.size();
           break;
         default:
           ERRORR(MB_FAILURE, "Unexpected entity location type for MPAS non-set variable.");
@@ -262,12 +251,16 @@ ErrorCode NCWriteMPAS::write_values(std::vector<std::string>& var_names)
       ERRORR(MB_FAILURE, "Can't find variable requested.");
 
     WriteNC::VarData& variableData = vit->second;
-    int numTimeSteps = (int)variableData.varTags.size();
+
+    // Skip edge variables, if there are no edges
+    if (localEdgesOwned.empty() && variableData.entLoc == WriteNC::ENTLOCEDGE)
+      continue;
+
     if (variableData.has_tsteps) {
       // Time should be the first dimension
       assert(tDim == variableData.varDims[0]);
 
-      // Assume this variable is on vertices for the time being
+      // Get local owned entities of this variable
       switch (variableData.entLoc) {
         case WriteNC::ENTLOCVERT:
           // Vertices
@@ -290,6 +283,7 @@ ErrorCode NCWriteMPAS::write_values(std::vector<std::string>& var_names)
 
       // A typical variable has 3 dimensions as (Time, nCells, nVertLevels)
       // FIXME: Should use tstep_nums (from writing options) later
+      int numTimeSteps = (int)variableData.varTags.size();
       for (int j = 0; j < numTimeSteps; j++) {
         // We will write one time step, and count will be one; start will be different
         // Use tag_get_data instead of tag_iterate to get values, as localEntsOwned

diff --git a/src/io/NCWriteMPAS.hpp b/src/io/NCWriteMPAS.hpp
index 89842f3..3c145cf 100644
--- a/src/io/NCWriteMPAS.hpp
+++ b/src/io/NCWriteMPAS.hpp
@@ -17,7 +17,7 @@ class NCWriteMPAS: public UcdNCWriteHelper
 {
 public:
   NCWriteMPAS(WriteNC* writeNC, int fileId, const FileOptions& opts, EntityHandle fileSet)
-: UcdNCWriteHelper(writeNC, fileId, opts, fileSet), noEdges(false) {}
+: UcdNCWriteHelper(writeNC, fileId, opts, fileSet) {}
 
   virtual ~NCWriteMPAS();
 
@@ -30,9 +30,6 @@ private:
 
   //! Implementation of NCWriteHelper::write_values()
   virtual ErrorCode write_values(std::vector<std::string>& var_names);
-
-private:
-  bool noEdges;
 };
 
 } // namespace moab

diff --git a/src/io/WriteNC.cpp b/src/io/WriteNC.cpp
index 0ec1aa8..ca63367 100644
--- a/src/io/WriteNC.cpp
+++ b/src/io/WriteNC.cpp
@@ -93,8 +93,7 @@ ErrorCode WriteNC::write_file(const char* file_name,
   fileName = file_name;
   int success;
 
-  if (append)
-  {
+  if (append) {
     int omode = NC_WRITE;
 #ifdef PNETCDF_FILE
     if (isParallel)
@@ -107,20 +106,20 @@ ErrorCode WriteNC::write_file(const char* file_name,
 #endif
     ERRORS(success, "Failed to open file for appending.");
   }
-  else // case when the file is new, will be overwritten, most likely
-  {
-#ifdef PNETCDF_FILE
+  else { // Case when the file is new, will be overwritten, most likely
     int cmode = overwrite ? NC_CLOBBER : NC_NOCLOBBER;
+#ifdef PNETCDF_FILE
     if (isParallel)
       success = NCFUNC(create)(myPcomm->proc_config().proc_comm(), file_name, cmode, MPI_INFO_NULL, &fileId);
     else
       success = NCFUNC(create)(MPI_COMM_SELF, file_name, cmode, MPI_INFO_NULL, &fileId);
 #else
     // This is a regular netcdf file
-    success = NCFUNC(create)(file_name, overwrite ? NC_CLOBBER : NC_NOCLOBBER, &fileId);
+    success = NCFUNC(create)(file_name, cmode, &fileId);
 #endif
     ERRORS(success, "Failed to create file.");
   }
+
   if (NULL != myHelper)
     delete myHelper;
 
@@ -164,17 +163,14 @@ ErrorCode WriteNC::parse_options(const FileOptions& opts, std::vector<std::strin
   else
     noVars = false;
 
-
   rval = opts.get_strs_option("RENAME", desired_names);
-  if (MB_ENTITY_NOT_FOUND == rval)
-  {
-    if(!noVars)
-    {
+  if (MB_ENTITY_NOT_FOUND == rval) {
+    if (!noVars) {
       desired_names.resize(var_names.size());
       std::copy(var_names.begin(), var_names.end(), desired_names.begin());
     }
   }
-  // either way
+  // Either way
   assert(desired_names.size() == var_names.size());
 
   opts.get_ints_option("TIMESTEP", tstep_nums);

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