[MOAB-dev] commit/MOAB: danwu: Introduced ScdNCWriteHelper and UcdNCWriteHelper classes to NC writer and refactored some code, to support parallel write in next step.

commits-noreply at bitbucket.org commits-noreply at bitbucket.org
Thu Apr 17 18:13:08 CDT 2014


1 new commit in MOAB:

https://bitbucket.org/fathomteam/moab/commits/8d793ea8d0d8/
Changeset:   8d793ea8d0d8
Branch:      ncwriter
User:        danwu
Date:        2014-04-18 01:12:46
Summary:     Introduced ScdNCWriteHelper and UcdNCWriteHelper classes to NC writer and refactored some code, to support parallel write in next step.

Affected #:  13 files

diff --git a/src/io/NCWriteEuler.cpp b/src/io/NCWriteEuler.cpp
index 41661a7..4b3f1ff 100644
--- a/src/io/NCWriteEuler.cpp
+++ b/src/io/NCWriteEuler.cpp
@@ -20,123 +20,4 @@ NCWriteEuler::~NCWriteEuler()
   // TODO Auto-generated destructor stub
 }
 
-ErrorCode NCWriteEuler::write_values(std::vector<std::string>& var_names)
-{
-  Interface*& mbImpl = _writeNC->mbImpl;
-  std::set<std::string>& usedCoordinates = _writeNC->usedCoordinates;
-  std::set<std::string>& dummyVarNames = _writeNC->dummyVarNames;
-  std::map<std::string, WriteNC::VarData>& varInfo = _writeNC->varInfo;
-
-  // Start with coordinates
-  for (std::set<std::string>::iterator setIt = usedCoordinates.begin();
-      setIt != usedCoordinates.end(); ++setIt) {
-    std::string coordName = *setIt; // Deep copy
-
-    // Skip dummy coordinate variables (if any)
-    if (dummyVarNames.find(coordName) != dummyVarNames.end())
-      continue;
-
-    std::map<std::string, WriteNC::VarData>::iterator vit = varInfo.find(coordName);
-    if (vit == varInfo.end())
-      ERRORR(MB_FAILURE, "Can't find one coordinate variable.");
-
-    WriteNC::VarData& varCoordData = vit->second;
-
-    int success = 0;
-    switch (varCoordData.varDataType) {
-      case NC_DOUBLE:
-        success = NCFUNCAP(_vara_double)(_fileId, varCoordData.varId, &varCoordData.writeStarts[0],
-                  &varCoordData.writeCounts[0], (double*)(varCoordData.memoryHogs[0]));
-        ERRORS(success, "Failed to write double data.");
-        break;
-      case NC_INT:
-        success = NCFUNCAP(_vara_int)(_fileId, varCoordData.varId, &varCoordData.writeStarts[0],
-                  &varCoordData.writeCounts[0], (int*)(varCoordData.memoryHogs[0]));
-        ERRORS(success, "Failed to write int data.");
-        break;
-      default:
-        success = 1;
-        break;
-    }
- }
-
-  // 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
-  ErrorCode rval;
-
-  // For each variable tag in the indexed lists, write a time step data
-  // Assume the first dimension is time (need to check); if not, just write regularly
-  for (size_t i = 0; i < var_names.size(); i++) {
-    std::map<std::string, WriteNC::VarData>::iterator vit = varInfo.find(var_names[i]);
-    if (vit == varInfo.end())
-      ERRORR(MB_FAILURE, "Can't find variable requested.");
-
-    WriteNC::VarData& variableData = vit->second;
-    int numTimeSteps = (int)variableData.varTags.size();
-    if (variableData.has_tsteps) {
-      // Get entities of this variable
-      Range ents;
-      switch (variableData.entLoc) {
-        case WriteNC::ENTLOCFACE:
-          // Faces
-          rval = mbImpl->get_entities_by_dimension(_fileSet, 2, ents);
-          ERRORR(rval, "Can't get entities for faces.");
-          break;
-        default:
-          ERRORR(MB_FAILURE, "Unexpected entity location type for CAM-EUL non-set variable.");
-      }
-
-      // A typical variable has 4 dimensions as (time, lev, lat, lon)
-      // At each timestep, we need to transpose tag format (lat, lon, lev) back
-      // to NC format (lev, lat, lon) for writing
-      size_t ni = variableData.writeCounts[3]; // lon
-      size_t nj = variableData.writeCounts[2]; // lat
-      size_t nk = variableData.writeCounts[1]; // lev
-
-      variableData.writeCounts[0] = 1; // We will write one time step
-      for (int j = 0; j < numTimeSteps; j++) {
-        // We will write one time step, and count will be one; start will be different
-        // We will write values directly from tag_iterate, but we should also transpose for level
-        // so that means deep copy for transpose
-        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());
-
-        // Now write from memory directly
-        int success = 0;
-        switch (variableData.varDataType) {
-          case NC_DOUBLE: {
-            std::vector<double> tmpdoubledata(ni*nj*nk);
-            // Transpose (lat, lon, lev) back to (lev, lat, lon)
-            jik_to_kji(ni, nj, nk, &tmpdoubledata[0], (double*)(dataptr));
-            success = NCFUNCAP(_vara_double)(_fileId, variableData.varId,
-                      &variableData.writeStarts[0], &variableData.writeCounts[0],
-                      &tmpdoubledata[0]);
-            ERRORS(success, "Failed to write double data.");
-            break;
-          }
-          default:
-            ERRORR(MB_FAILURE, "Not implemented yet.");
-        }
-      }
-    }
-    else {
-      int success = 0;
-      switch (variableData.varDataType) {
-        case NC_DOUBLE:
-          success = NCFUNCAP(_vara_double)(_fileId, variableData.varId, &variableData.writeStarts[0],
-                    &variableData.writeCounts[0], (double*)(variableData.memoryHogs[0]));
-          ERRORS(success, "Failed to write double data.");
-          break;
-        default:
-          ERRORR(MB_FAILURE, "Not implemented yet.");
-      }
-    }
-  }
-
-  return MB_SUCCESS;
-}
-
 } /* namespace moab */

diff --git a/src/io/NCWriteEuler.hpp b/src/io/NCWriteEuler.hpp
index e7009e7..2cb6486 100644
--- a/src/io/NCWriteEuler.hpp
+++ b/src/io/NCWriteEuler.hpp
@@ -13,16 +13,13 @@
 
 namespace moab {
 
-class NCWriteEuler: public NCWriteHelper
+class NCWriteEuler: public ScdNCWriteHelper
 {
 public:
-  NCWriteEuler(WriteNC* writeNC, int fileId, const FileOptions& opts, EntityHandle fileSet) :
-    NCWriteHelper(writeNC, fileId, opts, fileSet) {}
+  NCWriteEuler(WriteNC* writeNC, int fileId, const FileOptions& opts, EntityHandle fileSet)
+: ScdNCWriteHelper(writeNC, fileId, opts, fileSet) {}
 
   virtual ~NCWriteEuler();
-
-private:
-  ErrorCode write_values(std::vector<std::string>& var_names);
 };
 
 } // namespace moab

diff --git a/src/io/NCWriteFV.cpp b/src/io/NCWriteFV.cpp
index 39e325e..8de489f 100644
--- a/src/io/NCWriteFV.cpp
+++ b/src/io/NCWriteFV.cpp
@@ -20,9 +20,4 @@ NCWriteFV::~NCWriteFV()
   // TODO Auto-generated destructor stub
 }
 
-ErrorCode NCWriteFV::write_values(std::vector<std::string>& var_names)
-{
-  return MB_NOT_IMPLEMENTED;
-}
-
 } /* namespace moab */

diff --git a/src/io/NCWriteFV.hpp b/src/io/NCWriteFV.hpp
index c9c6a7d..d3286fc 100644
--- a/src/io/NCWriteFV.hpp
+++ b/src/io/NCWriteFV.hpp
@@ -13,16 +13,13 @@
 
 namespace moab {
 
-class NCWriteFV: public NCWriteHelper
+class NCWriteFV: public ScdNCWriteHelper
 {
 public:
-  NCWriteFV(WriteNC* writeNC, int fileId, const FileOptions& opts, EntityHandle fileSet) :
-    NCWriteHelper(writeNC, fileId, opts, fileSet) {}
+  NCWriteFV(WriteNC* writeNC, int fileId, const FileOptions& opts, EntityHandle fileSet)
+: ScdNCWriteHelper(writeNC, fileId, opts, fileSet) {}
 
   virtual ~NCWriteFV();
-
-private:
-  ErrorCode write_values(std::vector<std::string>& var_names);
 };
 
 } // namespace moab

diff --git a/src/io/NCWriteHOMME.cpp b/src/io/NCWriteHOMME.cpp
index bc92cc4..45ccff0 100644
--- a/src/io/NCWriteHOMME.cpp
+++ b/src/io/NCWriteHOMME.cpp
@@ -20,18 +20,116 @@ NCWriteHOMME::~NCWriteHOMME()
   // TODO Auto-generated destructor stub
 }
 
-ErrorCode NCWriteHOMME::write_values(std::vector<std::string>& var_names)
+ErrorCode NCWriteHOMME::collect_mesh_info()
 {
   Interface*& mbImpl = _writeNC->mbImpl;
+  std::vector<std::string>& dimNames = _writeNC->dimNames;
+  std::vector<int>& dimLens = _writeNC->dimLens;
   Tag& mGlobalIdTag = _writeNC->mGlobalIdTag;
+
+  ErrorCode rval;
+
+  // Look for time dimension
+  std::vector<std::string>::iterator vecIt;
+  if ((vecIt = std::find(dimNames.begin(), dimNames.end(), "time")) != dimNames.end())
+    tDim = vecIt - dimNames.begin();
+  else {
+    ERRORR(MB_FAILURE, "Couldn't find 'time' dimension.");
+  }
+  nTimeSteps = dimLens[tDim];
+
+  // Get number of levels
+  if ((vecIt = std::find(dimNames.begin(), dimNames.end(), "lev")) != dimNames.end())
+    levDim = vecIt - dimNames.begin();
+  else {
+    ERRORR(MB_FAILURE, "Couldn't find 'lev' dimension.");
+  }
+  nLevels = dimLens[levDim];
+
+  Range local_verts;
+  rval = mbImpl->get_entities_by_dimension(_fileSet, 0, local_verts);
+  ERRORR(rval, "Trouble getting local vertices in current file set.");
+  assert(!local_verts.empty());
+
+  std::vector<int> gids(local_verts.size());
+  rval = mbImpl->tag_get_data(mGlobalIdTag, local_verts, &gids[0]);
+  ERRORR(rval, "Trouble getting global IDs on local vertices.");
+
+  // Restore localGidVerts
+  std::copy(gids.rbegin(), gids.rend(), range_inserter(localGidVerts));
+  nLocalVertices = localGidVerts.size();
+
+  return MB_SUCCESS;
+}
+
+ErrorCode NCWriteHOMME::collect_variable_data(std::vector<std::string>& var_names)
+{
+  NCWriteHelper::collect_variable_data(var_names);
+
+  std::map<std::string, WriteNC::VarData>& varInfo = _writeNC->varInfo;
+
+  for (size_t i = 0; i < var_names.size(); i++) {
+    std::string varname = var_names[i];
+    std::map<std::string, WriteNC::VarData>::iterator vit = varInfo.find(varname);
+    if (vit == varInfo.end())
+      ERRORR(MB_FAILURE, "Can't find one variable.");
+
+    WriteNC::VarData& currentVarData = vit->second;
+    if (currentVarData.has_tsteps) {
+      // Support non-set variables with 3 dimensions like (time, lev, ncol)
+      assert(3 == currentVarData.varDims.size());
+
+      // Time should be the first dimension
+      assert(tDim == currentVarData.varDims[0]);
+
+      // Set up writeStarts and writeCounts
+      currentVarData.writeStarts.resize(3);
+      currentVarData.writeCounts.resize(3);
+
+      // First: time
+      currentVarData.writeStarts[0] = 0; // This value is timestep dependent, will be set later
+      currentVarData.writeCounts[0] = 1;
+
+      // Next: lev
+      currentVarData.writeStarts[1] = 0;
+      currentVarData.writeCounts[1] = currentVarData.numLev;
+
+      // Finally: ncol
+      switch (currentVarData.entLoc) {
+        case WriteNC::ENTLOCVERT:
+          // Vertices
+          // Start from the first localGidVerts
+          // Actually, this will be reset later for writing
+          currentVarData.writeStarts[2] = localGidVerts[0] - 1;
+          currentVarData.writeCounts[2] = nLocalVertices;
+          break;
+        default:
+          ERRORR(MB_FAILURE, "Unexpected entity location type for HOMME non-set variable.");
+      }
+    }
+
+    // Get variable size
+    currentVarData.sz = 1;
+    for (std::size_t idx = 0; idx != currentVarData.writeCounts.size(); idx++)
+      currentVarData.sz *= currentVarData.writeCounts[idx];
+  }
+
+  return MB_SUCCESS;
+}
+
+ErrorCode NCWriteHOMME::write_values(std::vector<std::string>& var_names)
+{
+  Interface*& mbImpl = _writeNC->mbImpl;
   std::set<std::string>& usedCoordinates = _writeNC->usedCoordinates;
   std::set<std::string>& dummyVarNames = _writeNC->dummyVarNames;
   std::map<std::string, WriteNC::VarData>& varInfo = _writeNC->varInfo;
 
+  ErrorCode rval;
+
   // Start with coordinates
   for (std::set<std::string>::iterator setIt = usedCoordinates.begin();
       setIt != usedCoordinates.end(); ++setIt) {
-    std::string coordName = *setIt; // Deep copy
+    const std::string& coordName = *setIt;
 
     // Skip dummy coordinate variables (e.g. ncol)
     if (dummyVarNames.find(coordName) != dummyVarNames.end())
@@ -59,25 +157,10 @@ ErrorCode NCWriteHOMME::write_values(std::vector<std::string>& var_names)
         success = 1;
         break;
     }
- }
+  }
 
   // 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
-  Range localGidVerts;
-  Range local_verts;
-  ErrorCode rval = mbImpl->get_entities_by_dimension(_fileSet, 0, local_verts);
-  ERRORR(rval, "Trouble getting local vertices in current file set.");
-
-  if (!local_verts.empty()) {
-    std::vector<int> gids(local_verts.size());
-
-    rval = mbImpl->tag_get_data(mGlobalIdTag, local_verts, &gids[0]);
-    ERRORR(rval, "Trouble getting global IDs on local vertices.");
-
-    // Restore localGidVerts
-    std::copy(gids.rbegin(), gids.rend(), range_inserter(localGidVerts));
-  }
-
   // For each variable tag in the indexed lists, write a time step data
   // Assume the first dimension is time (need to check); if not, just write regularly
   for (size_t i = 0; i < var_names.size(); i++) {
@@ -103,10 +186,7 @@ ErrorCode NCWriteHOMME::write_values(std::vector<std::string>& var_names)
       // A typical variable has 3 dimensions as (time, lev, ncol)
       // At each timestep, we need to transpose tag format (ncol, lev) back
       // to NC format (lev, ncol) for writing
-      int nLocalVertices = localGidVerts.size(); // ncol
-      size_t numLev = variableData.writeCounts[1]; // lev
-
-      variableData.writeCounts[0] = 1; // We will write one time step
+      // FIXME: Should use tstep_nums (from writing options) later
       for (int j = 0; j < numTimeSteps; j++) {
         // We will write one time step, and count will be one; start will be different
         // We will write values directly from tag_iterate, but we should also transpose for level
@@ -127,9 +207,9 @@ ErrorCode NCWriteHOMME::write_values(std::vector<std::string>& var_names)
         int success = 0;
         switch (variableData.varDataType) {
           case NC_DOUBLE: {
-            std::vector<double> tmpdoubledata(nLocalVertices * numLev);
+            std::vector<double> tmpdoubledata(nLocalVertices * variableData.numLev);
             // Transpose (ncol, lev) back to (lev, ncol)
-            jik_to_kji(nLocalVertices, 1, numLev, &tmpdoubledata[0], (double*)(dataptr));
+            jik_to_kji(nLocalVertices, 1, variableData.numLev, &tmpdoubledata[0], (double*)(dataptr));
 
             size_t indexInDoubleArray = 0;
             size_t ic = 0;
@@ -154,7 +234,7 @@ ErrorCode NCWriteHOMME::write_values(std::vector<std::string>& var_names)
               ERRORS(success, "Failed to read double data in loop");
               // We need to increment the index in double array for the
               // next subrange
-              indexInDoubleArray += (endh - starth + 1) * numLev;
+              indexInDoubleArray += (endh - starth + 1) * variableData.numLev;
             }
             assert(ic == localGidVerts.psize());
 #ifdef PNETCDF_FILE

diff --git a/src/io/NCWriteHOMME.hpp b/src/io/NCWriteHOMME.hpp
index 4cdf299..7bb99d9 100644
--- a/src/io/NCWriteHOMME.hpp
+++ b/src/io/NCWriteHOMME.hpp
@@ -13,16 +13,23 @@
 
 namespace moab {
 
-class NCWriteHOMME: public NCWriteHelper
+class NCWriteHOMME: public UcdNCWriteHelper
 {
 public:
-  NCWriteHOMME(WriteNC* writeNC, int fileId, const FileOptions& opts, EntityHandle fileSet) :
-    NCWriteHelper(writeNC, fileId, opts, fileSet) {}
+  NCWriteHOMME(WriteNC* writeNC, int fileId, const FileOptions& opts, EntityHandle fileSet)
+: UcdNCWriteHelper(writeNC, fileId, opts, fileSet) {}
 
   virtual ~NCWriteHOMME();
 
 private:
-  ErrorCode write_values(std::vector<std::string>& var_names);
+  //! Implementation of NCWriteHelper::collect_mesh_info()
+  virtual ErrorCode collect_mesh_info();
+
+  //! Collect data for specified variables
+  virtual ErrorCode collect_variable_data(std::vector<std::string>& var_names);
+
+  //! Implementation of NCWriteHelper::write_values()
+  virtual ErrorCode write_values(std::vector<std::string>& var_names);
 };
 
 } // namespace moab

diff --git a/src/io/NCWriteHelper.cpp b/src/io/NCWriteHelper.cpp
index e70b701..8e50903 100644
--- a/src/io/NCWriteHelper.cpp
+++ b/src/io/NCWriteHelper.cpp
@@ -11,6 +11,16 @@
 #include "NCWriteHOMME.hpp"
 #include "NCWriteMPAS.hpp"
 
+#include "moab/WriteUtilIface.hpp"
+
+#include <sstream>
+
+#define ERRORR(rval, str) \
+  if (MB_SUCCESS != rval) { _writeNC->mWriteIface->report_error("%s", str); return rval; }
+
+#define ERRORS(err, str) \
+  if (err) { _writeNC->mWriteIface->report_error("%s", str); return MB_FAILURE; }
+
 namespace moab {
 
 //! Get appropriate helper instance for WriteNC class; based on some info in the file set
@@ -30,4 +40,534 @@ NCWriteHelper* NCWriteHelper::get_nc_helper(WriteNC* writeNC, int fileId, const
   return NULL;
 }
 
+ErrorCode NCWriteHelper::collect_variable_data(std::vector<std::string>& var_names)
+{
+  Interface*& mbImpl = _writeNC->mbImpl;
+  std::vector<std::string>& dimNames = _writeNC->dimNames;
+  std::vector<int>& dimLens = _writeNC->dimLens;
+  std::set<std::string>& usedCoordinates = _writeNC->usedCoordinates;
+  std::set<std::string>& dummyVarNames = _writeNC->dummyVarNames;
+  std::map<std::string, WriteNC::VarData>& varInfo = _writeNC->varInfo;
+  DebugOutput& dbgOut = _writeNC->dbgOut;
+
+  ErrorCode rval;
+
+  usedCoordinates.clear();
+
+  for (size_t i = 0; i < var_names.size(); i++) {
+    std::string varname = var_names[i];
+    std::map<std::string, WriteNC::VarData>::iterator vit = varInfo.find(varname);
+    if (vit == varInfo.end())
+      ERRORR(MB_FAILURE, "Can't find one variable.");
+
+    WriteNC::VarData& currentVarData = vit->second;
+
+    currentVarData.has_tsteps = false;
+    if ((std::find(currentVarData.varDims.begin(), currentVarData.varDims.end(), tDim) != currentVarData.varDims.end())
+        && (currentVarData.varDims.size() > 1)) // So it is not time itself
+      currentVarData.has_tsteps = true;
+
+    currentVarData.numLev = 1;
+    if ((std::find(currentVarData.varDims.begin(), currentVarData.varDims.end(), tDim) != currentVarData.varDims.end()))
+      currentVarData.numLev = nLevels;
+
+    dbgOut.tprintf(2, "    for variable %s varDims.size %d \n", varname.c_str(), (int)currentVarData.varDims.size());
+    for (size_t j = 0; j < currentVarData.varDims.size(); j++) {
+      std::string dimName = dimNames[currentVarData.varDims[j]];
+      vit = varInfo.find(dimName);
+      if (vit == varInfo.end())
+        ERRORR(MB_FAILURE, "Can't find one coordinate variable.");
+
+      usedCoordinates.insert(dimName); // Collect those used, we will need to write them to the file
+      dbgOut.tprintf(2, "    for variable %s need dimension %s with length %d\n", varname.c_str(), dimName.c_str(), dimLens[currentVarData.varDims[j]]);
+    }
+
+    if (currentVarData.has_tsteps) {
+      int index = 0;
+      // FIXME: Should use tstep_nums (from writing options) later
+      while (true) {
+        Tag indexedTag = 0;
+        std::stringstream ssTagNameWithIndex;
+        ssTagNameWithIndex << varname << index;
+        rval = mbImpl->tag_get_handle(ssTagNameWithIndex.str().c_str(), indexedTag);
+        if (MB_SUCCESS != rval)
+          break;
+        dbgOut.tprintf(2, "    found indexed tag %d with name %s\n", index, ssTagNameWithIndex.str().c_str());
+        currentVarData.varTags.push_back(indexedTag);
+        index++; // We should get out of the loop at some point
+
+        // The type of the tag is fixed though
+        DataType type;
+        rval = mbImpl->tag_get_data_type(indexedTag, type);
+        ERRORR(rval, "Can't get tag type.");
+
+        currentVarData.varDataType = NC_DOUBLE;
+        if (MB_TYPE_INTEGER == type)
+          currentVarData.varDataType = NC_INT;
+      }
+    }
+    else {
+      // Get the tag with varname
+      Tag tag = 0;
+      rval = mbImpl->tag_get_handle(varname.c_str(), tag);
+      ERRORR(rval, "Can't find one tag.");
+      currentVarData.varTags.push_back(tag); // Really, only one for these
+      const void* data;
+      int size;
+      rval = mbImpl->tag_get_by_ptr(tag, &_fileSet, 1, &data, &size);
+      ERRORR(rval, "Can't get tag values.");
+
+      // Find the type of tag, and use it
+      DataType type;
+      rval = mbImpl->tag_get_data_type(tag, type);
+      ERRORR(rval, "Can't get tag type.");
+
+      currentVarData.varDataType = NC_DOUBLE;
+      if (MB_TYPE_INTEGER == type)
+        currentVarData.varDataType = NC_INT;
+
+      assert(currentVarData.memoryHogs.size() == 0); // Nothing so far
+      currentVarData.memoryHogs.push_back((void*)data);
+
+      if (currentVarData.varDims.empty()) {
+        // Scalar variable
+        currentVarData.writeStarts.push_back(0);
+        currentVarData.writeCounts.push_back(1);
+      }
+      else {
+        for (unsigned int idx = 0; idx != currentVarData.varDims.size(); idx++){
+          currentVarData.writeStarts.push_back(0);
+          currentVarData.writeCounts.push_back(dimLens[currentVarData.varDims[idx]]);
+        }
+      }
+    }
+  }
+
+  // Check that for used coordinates we have found the tags
+  for (std::set<std::string>::iterator setIt = usedCoordinates.begin();
+      setIt != usedCoordinates.end(); ++setIt) {
+    const std::string& coordName = *setIt;
+
+    std::map<std::string, WriteNC::VarData>::iterator vit = varInfo.find(coordName);
+    if (vit == varInfo.end())
+      ERRORR(MB_FAILURE, "Can't find one coordinate variable.");
+
+    WriteNC::VarData& varCoordData = vit->second;
+    Tag coordTag = 0;
+    rval = mbImpl->tag_get_handle(coordName.c_str(), coordTag);
+    ERRORR(rval, "Can't find one tag.");
+    varCoordData.varTags.push_back(coordTag); // Really, only one for these
+
+    const void* data;
+    int sizeCoordinate;
+    rval = mbImpl->tag_get_by_ptr(coordTag, &_fileSet, 1, &data, &sizeCoordinate);
+    ERRORR(rval, "Can't get coordinate values.");
+    dbgOut.tprintf(2, "    found coordinate tag with name %s and length %d\n", coordName.c_str(),
+        sizeCoordinate);
+
+    // Get dimension length (the only dimension of this coordinate variable, with the same name)
+    assert(1 == varCoordData.varDims.size());
+    int coordDimLen = dimLens[varCoordData.varDims[0]];
+
+    if (dummyVarNames.find(coordName) != dummyVarNames.end()) {
+      // For a dummy coordinate variable, the tag size is always 1
+      // The number of coordinates should be set to dimension length, instead of 1
+      assert(1 == sizeCoordinate);
+      sizeCoordinate = coordDimLen;
+    }
+    else {
+      // The number of coordinates should be exactly the same as dimension length
+      assert(sizeCoordinate == coordDimLen);
+    }
+
+    // This is the length
+    varCoordData.sz = sizeCoordinate;
+    varCoordData.writeStarts.resize(1);
+    varCoordData.writeStarts[0] = 0;
+    varCoordData.writeCounts.resize(1);
+    varCoordData.writeCounts[0] = sizeCoordinate;
+
+    // Find the type of tag, and use it
+    DataType type;
+    rval = mbImpl->tag_get_data_type(coordTag, type);
+    ERRORR(rval, "Can't get tag type.");
+
+    varCoordData.varDataType = NC_DOUBLE;
+    if (MB_TYPE_INTEGER == type)
+      varCoordData.varDataType = NC_INT;
+
+    assert(0 == varCoordData.memoryHogs.size()); // Nothing so far
+    varCoordData.memoryHogs.push_back((void*)data);
+  }
+
+  return MB_SUCCESS;
+}
+
+ErrorCode NCWriteHelper::init_file(std::vector<std::string>& var_names)
+{
+  std::vector<std::string>& dimNames = _writeNC->dimNames;
+  std::set<std::string>& usedCoordinates = _writeNC->usedCoordinates;
+  std::set<std::string>& dummyVarNames = _writeNC->dummyVarNames;
+  std::map<std::string, WriteNC::VarData>& varInfo = _writeNC->varInfo;
+  std::map<std::string, WriteNC::AttData>& globalAtts = _writeNC->globalAtts;
+  DebugOutput& dbgOut = _writeNC->dbgOut;
+
+  // 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();
+      setIt != usedCoordinates.end(); ++setIt) {
+    const std::string& coordName = *setIt;
+
+    std::map<std::string, WriteNC::VarData>::iterator vit = varInfo.find(coordName);
+    if (vit == varInfo.end())
+      ERRORR(MB_FAILURE, "Can't find one coordinate variable.");
+
+    WriteNC::VarData& varCoordData = vit->second;
+    varCoordData.varDims.resize(1);
+
+    /* int nc_def_dim (int ncid, const char *name, size_t len, int *dimidp);
+       * example:  status = nc_def_dim(fileId, "lat", 18L, &latid);
+    */
+
+    // Actually define a dimension
+    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]);
+
+    // Create a variable with the same name, and its only dimension the one we just defined
+    /*
+     * int nc_def_var (int ncid, const char *name, nc_type xtype,
+                       int ndims, const int dimids[], int *varidp);
+       example: http://www.unidata.ucar.edu/software/netcdf/docs/netcdf-c/nc_005fdef_005fvar.html#nc_005fdef_005fvar
+     */
+
+    // Skip dummy coordinate variables (e.g. ncol)
+    if (dummyVarNames.find(coordName) != dummyVarNames.end())
+      continue;
+
+    // Define a coordinate variable
+    if (NCFUNC(def_var)(_fileId, coordName.c_str(), varCoordData.varDataType,
+        1, &(varCoordData.varDims[0]), &varCoordData.varId) != NC_NOERR)
+      ERRORR(MB_FAILURE, "Failed to create coordinate variable.");
+
+    dbgOut.tprintf(2, "    for coordName %s variable id is %d \n", coordName.c_str(), varCoordData.varId);
+  }
+
+  // Now look at requested variables, and update from the index in dimNames to the actual dimension id
+  for (size_t i = 0; i < var_names.size(); i++) {
+    std::map<std::string, WriteNC::VarData>::iterator vit = varInfo.find(var_names[i]);
+    if (vit == varInfo.end())
+      ERRORR(MB_FAILURE, "Can't find variable requested.");
+
+    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)
+    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);
+      if (vit2 == varInfo.end())
+        ERRORR(MB_FAILURE, "Can't find coordinate variable requested.");
+
+      WriteNC::VarData& coordData = vit2->second;
+      // Index in dimNames to actual dimension id
+      variableData.varDims[j] = coordData.varDims[0]; // This one, being a coordinate, is the only one
+      dbgOut.tprintf(2, "          dimension with index %d name %s has ID %d \n",
+          j, dimName.c_str(), variableData.varDims[j]);
+    }
+
+    // Define the variable now:
+    if (NCFUNC(def_var)(_fileId, var_names[i].c_str(), variableData.varDataType,
+        (int)variableData.varDims.size(), &(variableData.varDims[0]),
+        &variableData.varId) != NC_NOERR)
+      ERRORR(MB_FAILURE, "Failed to create coordinate variable.");
+
+    dbgOut.tprintf(2, "    for variable %s variable id is %d \n", var_names[i].c_str(), variableData.varId);
+    // Now define the variable, with all dimensions
+  }
+
+  // Define global attributes (exactly copied from the original file for the time being)
+  // Should we modify some of them (e.g. revision_Id) later?
+  std::map<std::string, WriteNC::AttData>::iterator attIt;
+  for (attIt = globalAtts.begin(); attIt != globalAtts.end(); ++attIt) {
+    const std::string& attName = attIt->first;
+    WriteNC::AttData& attData = attIt->second;
+    NCDF_SIZE& attLen = attData.attLen;
+    nc_type& attDataType = attData.attDataType;
+    const std::string& attValue = attData.attValue;
+
+    switch (attDataType) {
+      case NC_BYTE:
+      case NC_CHAR:
+        if (NC_NOERR != NCFUNC(put_att_text)(_fileId, NC_GLOBAL, attName.c_str(), attLen, attValue.c_str()))
+          ERRORR(MB_FAILURE, "Failed to define text type attribute.");
+        break;
+      case NC_DOUBLE:
+        if (NC_NOERR != NCFUNC(put_att_double)(_fileId, NC_GLOBAL, attName.c_str(), NC_DOUBLE, 1, (double*)attValue.c_str()))
+          ERRORR(MB_FAILURE, "Failed to define double type attribute.");
+        break;
+      case NC_FLOAT:
+        if (NC_NOERR != NCFUNC(put_att_float)(_fileId, NC_GLOBAL, attName.c_str(), NC_FLOAT, 1, (float*)attValue.c_str()))
+          ERRORR(MB_FAILURE, "Failed to define float type attribute.");
+        break;
+      case NC_INT:
+        if (NC_NOERR != NCFUNC(put_att_int)(_fileId, NC_GLOBAL, attName.c_str(), NC_INT, 1, (int*)attValue.c_str()))
+          ERRORR(MB_FAILURE, "Failed to define int type attribute.");
+        break;
+      case NC_SHORT:
+        if (NC_NOERR != NCFUNC(put_att_short)(_fileId, NC_GLOBAL, attName.c_str(), NC_SHORT, 1, (short*)attValue.c_str()))
+          ERRORR(MB_FAILURE, "Failed to define short type attribute.");
+        break;
+      default:
+        ERRORR(MB_FAILURE, "Unknown attribute data type.");
+    }
+  }
+
+  // Take it out of define mode
+  if (NC_NOERR != NCFUNC(enddef)(_fileId))
+    ERRORR(MB_FAILURE, "Failed to close define mode.");
+
+  return MB_SUCCESS;
+}
+
+ErrorCode ScdNCWriteHelper::collect_mesh_info()
+{
+  Interface*& mbImpl = _writeNC->mbImpl;
+  std::vector<std::string>& dimNames = _writeNC->dimNames;
+  std::vector<int>& dimLens = _writeNC->dimLens;
+
+  ErrorCode rval;
+
+  // Look for time dimension
+  std::vector<std::string>::iterator vecIt;
+  if ((vecIt = std::find(dimNames.begin(), dimNames.end(), "time")) != dimNames.end())
+    tDim = vecIt - dimNames.begin();
+  else if ((vecIt = std::find(dimNames.begin(), dimNames.end(), "t")) != dimNames.end())
+    tDim = vecIt - dimNames.begin();
+  else {
+    ERRORR(MB_FAILURE, "Couldn't find 'time' or 't' dimension.");
+  }
+  nTimeSteps = dimLens[tDim];
+
+  // Get number of levels
+  if ((vecIt = std::find(dimNames.begin(), dimNames.end(), "lev")) != dimNames.end())
+    levDim = vecIt - dimNames.begin();
+  else if ((vecIt = std::find(dimNames.begin(), dimNames.end(), "ilev")) != dimNames.end())
+    levDim = vecIt - dimNames.begin();
+  else {
+    ERRORR(MB_FAILURE, "Couldn't find 'lev' or 'ilev' dimension.");
+  }
+  nLevels = dimLens[levDim];
+
+  // __<dim_name>_LOC_MINMAX (for slon, slat, lon and lat)
+  Tag convTag = 0;
+  rval = mbImpl->tag_get_handle("__slon_LOC_MINMAX", 0, MB_TYPE_INTEGER, convTag, MB_TAG_ANY);
+  ERRORR(rval, "Trouble getting conventional tag __slon_LOC_MINMAX.");
+  int val[2];
+  rval = mbImpl->tag_get_data(convTag, &_fileSet, 1, val);
+  ERRORR(rval, "Trouble getting values for conventional tag __slon_LOC_MINMAX.");
+  lDims[0] = val[0];
+  lDims[3] = val[1];
+
+  rval = mbImpl->tag_get_handle("__slat_LOC_MINMAX", 0, MB_TYPE_INTEGER, convTag, MB_TAG_ANY);
+  ERRORR(rval, "Trouble getting conventional tag __slat_LOC_MINMAX.");
+  rval = mbImpl->tag_get_data(convTag, &_fileSet, 1, val);
+  ERRORR(rval, "Trouble getting values for conventional tag __slat_LOC_MINMAX.");
+  lDims[1] = val[0];
+  lDims[4] = val[1];
+
+  rval = mbImpl->tag_get_handle("__lon_LOC_MINMAX", 0, MB_TYPE_INTEGER, convTag, MB_TAG_ANY);
+  ERRORR(rval, "Trouble getting conventional tag __lon_LOC_MINMAX.");
+  rval = mbImpl->tag_get_data(convTag, &_fileSet, 1, val);
+  ERRORR(rval, "Trouble getting values for conventional tag __lon_LOC_MINMAX.");
+  lCDims[0] = val[0];
+  lCDims[3] = val[1];
+
+  rval = mbImpl->tag_get_handle("__lat_LOC_MINMAX", 0, MB_TYPE_INTEGER, convTag, MB_TAG_ANY);
+  ERRORR(rval, "Trouble getting conventional tag __lat_LOC_MINMAX.");
+  rval = mbImpl->tag_get_data(convTag, &_fileSet, 1, val);
+  ERRORR(rval, "Trouble getting values for conventional tag __lat_LOC_MINMAX.");
+  lCDims[1] = val[0];
+  lCDims[4] = val[1];
+
+  return MB_SUCCESS;
+}
+
+ErrorCode ScdNCWriteHelper::collect_variable_data(std::vector<std::string>& var_names)
+{
+  NCWriteHelper::collect_variable_data(var_names);
+
+  std::map<std::string, WriteNC::VarData>& varInfo = _writeNC->varInfo;
+
+  for (size_t i = 0; i < var_names.size(); i++) {
+    std::string varname = var_names[i];
+    std::map<std::string, WriteNC::VarData>::iterator vit = varInfo.find(varname);
+    if (vit == varInfo.end())
+      ERRORR(MB_FAILURE, "Can't find one variable.");
+
+    WriteNC::VarData& currentVarData = vit->second;
+    if (currentVarData.has_tsteps) {
+      // Support non-set variables with 4 dimensions like (time, lev, lat, lon)
+      assert(4 == currentVarData.varDims.size());
+
+      // Time should be the first dimension
+      assert(tDim == currentVarData.varDims[0]);
+
+      // Set up writeStarts and writeCounts
+      currentVarData.writeStarts.resize(4);
+      currentVarData.writeCounts.resize(4);
+
+      // First: time
+      currentVarData.writeStarts[0] = 0; // This value is timestep dependent, will be set later
+      currentVarData.writeCounts[0] = 1;
+
+      // Next: lev
+      currentVarData.writeStarts[1] = 0;
+      currentVarData.writeCounts[1] = currentVarData.numLev;
+
+      // Finally: lat (or slat) and lon (or slon)
+      switch (currentVarData.entLoc) {
+        case WriteNC::ENTLOCFACE:
+          // Faces
+          currentVarData.writeStarts[2] = lCDims[1];
+          currentVarData.writeCounts[2] = lCDims[4] - lCDims[1] + 1;
+          currentVarData.writeStarts[3] = lCDims[0];
+          currentVarData.writeCounts[3] = lCDims[3] - lCDims[0] + 1;
+          break;
+        default:
+          ERRORR(MB_FAILURE, "Not implemented yet.");
+      }
+    }
+
+    // Get variable size
+    currentVarData.sz = 1;
+    for (std::size_t idx = 0; idx != currentVarData.writeCounts.size(); idx++)
+      currentVarData.sz *= currentVarData.writeCounts[idx];
+  }
+
+  return MB_SUCCESS;
+}
+
+ErrorCode ScdNCWriteHelper::write_values(std::vector<std::string>& var_names)
+{
+  Interface*& mbImpl = _writeNC->mbImpl;
+  std::set<std::string>& usedCoordinates = _writeNC->usedCoordinates;
+  std::set<std::string>& dummyVarNames = _writeNC->dummyVarNames;
+  std::map<std::string, WriteNC::VarData>& varInfo = _writeNC->varInfo;
+
+  ErrorCode rval;
+
+  // Start with coordinates
+  for (std::set<std::string>::iterator setIt = usedCoordinates.begin();
+      setIt != usedCoordinates.end(); ++setIt) {
+    const std::string& coordName = *setIt;
+
+    // Skip dummy coordinate variables (if any)
+    if (dummyVarNames.find(coordName) != dummyVarNames.end())
+      continue;
+
+    std::map<std::string, WriteNC::VarData>::iterator vit = varInfo.find(coordName);
+    if (vit == varInfo.end())
+      ERRORR(MB_FAILURE, "Can't find one coordinate variable.");
+
+    WriteNC::VarData& varCoordData = vit->second;
+
+    int success = 0;
+    switch (varCoordData.varDataType) {
+      case NC_DOUBLE:
+        success = NCFUNCAP(_vara_double)(_fileId, varCoordData.varId, &varCoordData.writeStarts[0],
+                  &varCoordData.writeCounts[0], (double*)(varCoordData.memoryHogs[0]));
+        ERRORS(success, "Failed to write double data.");
+        break;
+      case NC_INT:
+        success = NCFUNCAP(_vara_int)(_fileId, varCoordData.varId, &varCoordData.writeStarts[0],
+                  &varCoordData.writeCounts[0], (int*)(varCoordData.memoryHogs[0]));
+        ERRORS(success, "Failed to write int data.");
+        break;
+      default:
+        success = 1;
+        break;
+    }
+ }
+
+  // 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 (size_t i = 0; i < var_names.size(); i++) {
+    std::map<std::string, WriteNC::VarData>::iterator vit = varInfo.find(var_names[i]);
+    if (vit == varInfo.end())
+      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]);
+
+      // Get entities of this variable
+      Range ents;
+      switch (variableData.entLoc) {
+        case WriteNC::ENTLOCFACE:
+          // Faces
+          rval = mbImpl->get_entities_by_dimension(_fileSet, 2, ents);
+          ERRORR(rval, "Can't get entities for faces.");
+          break;
+        default:
+          ERRORR(MB_FAILURE, "Not implemented yet.");
+      }
+
+      // A typical variable has 4 dimensions as (time, lev, lat, lon)
+      // At each timestep, we need to transpose tag format (lat, lon, lev) back
+      // to NC format (lev, lat, lon) for writing
+      size_t ni = variableData.writeCounts[3]; // lon
+      size_t nj = variableData.writeCounts[2]; // lat
+      size_t nk = variableData.writeCounts[1]; // lev
+
+      variableData.writeCounts[0] = 1; // We will write one time step
+      // FIXME: Should use tstep_nums (from writing options) later
+      for (int j = 0; j < numTimeSteps; j++) {
+        // We will write one time step, and count will be one; start will be different
+        // We will write values directly from tag_iterate, but we should also transpose for level
+        // so that means deep copy for transpose
+        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());
+
+        // Now write from memory directly
+        int success = 0;
+        switch (variableData.varDataType) {
+          case NC_DOUBLE: {
+            std::vector<double> tmpdoubledata(ni*nj*nk);
+            // Transpose (lat, lon, lev) back to (lev, lat, lon)
+            jik_to_kji(ni, nj, nk, &tmpdoubledata[0], (double*)(dataptr));
+            success = NCFUNCAP(_vara_double)(_fileId, variableData.varId,
+                      &variableData.writeStarts[0], &variableData.writeCounts[0],
+                      &tmpdoubledata[0]);
+            ERRORS(success, "Failed to write double data.");
+            break;
+          }
+          default:
+            ERRORR(MB_FAILURE, "Not implemented yet.");
+        }
+      }
+    }
+    else {
+      int success = 0;
+      switch (variableData.varDataType) {
+        case NC_DOUBLE:
+          success = NCFUNCAP(_vara_double)(_fileId, variableData.varId, &variableData.writeStarts[0],
+                    &variableData.writeCounts[0], (double*)(variableData.memoryHogs[0]));
+          ERRORS(success, "Failed to write double data.");
+          break;
+        default:
+          ERRORR(MB_FAILURE, "Not implemented yet.");
+      }
+    }
+  }
+
+  return MB_SUCCESS;
+}
+
 } /* namespace moab */

diff --git a/src/io/NCWriteHelper.hpp b/src/io/NCWriteHelper.hpp
index d190922..6678bb5 100644
--- a/src/io/NCWriteHelper.hpp
+++ b/src/io/NCWriteHelper.hpp
@@ -16,16 +16,26 @@ class NCWriteHelper
 {
 public:
   NCWriteHelper(WriteNC* writeNC, int fileId, const FileOptions& opts, EntityHandle fileSet)
-  :_writeNC(writeNC), _fileId(fileId), _opts(opts), _fileSet(fileSet) {}
-
+: _writeNC(writeNC), _fileId(fileId), _opts(opts), _fileSet(fileSet),
+  nTimeSteps(0), nLevels(1), tDim(-1), levDim(-1) {}
   virtual ~NCWriteHelper() {};
 
-  //! Get appropriate helper instance for WriteNC class; based on some info in the file set
+  //! Get appropriate helper instance for WriteNC class based on some info in the file set
   static NCWriteHelper* get_nc_helper(WriteNC* writeNC, int fileId, const FileOptions& opts, EntityHandle fileSet);
 
+  //! Collect necessary info about local mesh
+  virtual ErrorCode collect_mesh_info() = 0;
+
+  //! Collect data for specified variables
+  virtual ErrorCode collect_variable_data(std::vector<std::string>& var_names);
+
   //! Take the info from VarData and write first the coordinates, then the actual variables
   virtual ErrorCode write_values(std::vector<std::string>& var_names) = 0;
 
+  //! Initialize file: this is where all defines are done
+  //! The VarData dimension ids are filled up after define
+  ErrorCode init_file(std::vector<std::string>& var_names);
+
 protected:
   template <typename T> void jik_to_kji(size_t ni, size_t nj, size_t nk, T* dest, T* source)
   {
@@ -36,6 +46,7 @@ protected:
           dest[k*nij + j*ni + i] = source[j*nik + i*nk + k];
   }
 
+protected:
   //! Allow NCWriteHelper to directly access members of WriteNC
   WriteNC* _writeNC;
 
@@ -43,9 +54,69 @@ protected:
   int _fileId;
   const FileOptions& _opts;
   EntityHandle _fileSet;
+
+  //! Dimensions of time and level
+  int nTimeSteps, nLevels;
+
+  //! Dimension numbers for time and level
+  int tDim, levDim;
+};
+
+//! Child helper class for scd mesh, e.g. CAM_EL or CAM_FV
+class ScdNCWriteHelper : public NCWriteHelper
+{
+public:
+  ScdNCWriteHelper(WriteNC* writeNC, int fileId, const FileOptions& opts, EntityHandle fileSet)
+: NCWriteHelper(writeNC, fileId, opts, fileSet)
+  {
+    for (unsigned int i = 0; i < 6; i++) {
+      lDims[i] = -1;
+      lCDims[i] = -1;
+    }
+  }
+  virtual ~ScdNCWriteHelper() {}
+
+private:
+  //! Implementation of NCWriteHelper::collect_mesh_info()
+  virtual ErrorCode collect_mesh_info();
+
+  //! Collect data for specified variables
+  virtual ErrorCode collect_variable_data(std::vector<std::string>& var_names);
+
+  //! Implementation of NCWriteHelper::write_values()
+  virtual ErrorCode write_values(std::vector<std::string>& var_names);
+
+protected:
+  //! Dimensions of my local part of grid
+  int lDims[6];
+
+  //! Center dimensions of my local part of grid
+  int lCDims[6];
+};
+
+//! Child helper class for ucd mesh, e.g. CAM_SE (HOMME) or MPAS
+class UcdNCWriteHelper : public NCWriteHelper
+{
+public:
+  UcdNCWriteHelper(WriteNC* writeNC, int fileId, const FileOptions& opts, EntityHandle fileSet)
+: NCWriteHelper(writeNC, fileId, opts, fileSet),
+  nLocalCells(0), nLocalEdges(0), nLocalVertices(0),
+  cDim(-1), eDim(-1), vDim(-1) {}
+  virtual ~UcdNCWriteHelper() {}
+
+protected:
+  //! Dimensions of my local part of grid
+  int nLocalCells;
+  int nLocalEdges;
+  int nLocalVertices;
+
+  //! Dimension numbers for nCells, nEdges and nVertices
+  int cDim, eDim, vDim;
+
+  //! Local global ID for cells, edges and vertices
+  Range localGidCells, localGidEdges, localGidVerts;
 };
 
 } // namespace moab
 
 #endif
-

diff --git a/src/io/NCWriteMPAS.cpp b/src/io/NCWriteMPAS.cpp
index f544e96..72dc35f 100644
--- a/src/io/NCWriteMPAS.cpp
+++ b/src/io/NCWriteMPAS.cpp
@@ -20,7 +20,12 @@ NCWriteMPAS::~NCWriteMPAS()
   // TODO Auto-generated destructor stub
 }
 
-ErrorCode NCWriteMPAS::write_values(std::vector<std::string>& var_names)
+ErrorCode NCWriteMPAS::collect_mesh_info()
+{
+  return MB_NOT_IMPLEMENTED;
+}
+
+ErrorCode NCWriteMPAS::write_values(std::vector<std::string>& /* var_names */)
 {
   return MB_NOT_IMPLEMENTED;
 }

diff --git a/src/io/NCWriteMPAS.hpp b/src/io/NCWriteMPAS.hpp
index 3d9e829..702984f 100644
--- a/src/io/NCWriteMPAS.hpp
+++ b/src/io/NCWriteMPAS.hpp
@@ -13,16 +13,20 @@
 
 namespace moab {
 
-class NCWriteMPAS: public NCWriteHelper
+class NCWriteMPAS: public UcdNCWriteHelper
 {
 public:
-  NCWriteMPAS(WriteNC* writeNC, int fileId, const FileOptions& opts, EntityHandle fileSet) :
-    NCWriteHelper(writeNC, fileId, opts, fileSet) {}
+  NCWriteMPAS(WriteNC* writeNC, int fileId, const FileOptions& opts, EntityHandle fileSet)
+: UcdNCWriteHelper(writeNC, fileId, opts, fileSet) {}
 
   virtual ~NCWriteMPAS();
 
 private:
-  ErrorCode write_values(std::vector<std::string>& var_names);
+  //! Implementation of NCWriteHelper::collect_mesh_info()
+  virtual ErrorCode collect_mesh_info();
+
+  //! Collect data for specified variables
+  virtual ErrorCode write_values(std::vector<std::string>& var_names);
 };
 
 } // namespace moab

diff --git a/src/io/WriteNC.cpp b/src/io/WriteNC.cpp
index af20151..2f96223 100644
--- a/src/io/WriteNC.cpp
+++ b/src/io/WriteNC.cpp
@@ -29,12 +29,12 @@ WriterIface *WriteNC::factory(Interface* iface)
 }
 
 WriteNC::WriteNC(Interface* impl) :
-  mbImpl(impl), dbgOut(stderr), partMethod(ScdParData::ALLJORKORI), scdi(NULL),
+  mbImpl(impl), dbgOut(stderr),
 #ifdef USE_MPI
   myPcomm(NULL),
 #endif
-  noMesh(false), noVars(false), /*spectralMesh(false), noMixedElements(false), noEdges(false),*/
-  gatherSetRank(-1), mGlobalIdTag(0), isParallel(false),
+  noMesh(false), noVars(false),
+  mGlobalIdTag(0), isParallel(false),
   myHelper(NULL)
 {
   assert(impl != NULL);
@@ -82,7 +82,7 @@ ErrorCode WriteNC::write_file(const char* file_name,
   // new variables still need to have some way of defining their dimensions
   // maybe it will be passed as write options
   rval = process_conventional_tags(*file_set);
-  ERRORR(rval, "Trouble getting conventional tags.");
+  ERRORR(rval, "Trouble processing conventional tags.");
 
   // Create the file ; assume we will overwrite always, for the time being
   dbgOut.tprintf(1, "creating file %s\n", file_name);
@@ -90,7 +90,7 @@ ErrorCode WriteNC::write_file(const char* file_name,
   int success;
 
 #ifdef PNETCDF_FILE
-  int cmode= overwrite ? NC_CLOBBER : NC_NOCLOBBER;
+  int cmode = overwrite ? NC_CLOBBER : NC_NOCLOBBER;
   if (isParallel)
     success = NCFUNC(create)(myPcomm->proc_config().proc_comm(), file_name, cmode, MPI_INFO_NULL, &fileId);
   else
@@ -110,10 +110,13 @@ ErrorCode WriteNC::write_file(const char* file_name,
     ERRORR(MB_FAILURE, "Failed to get NCWriteHelper class instance.");
   }
 
-  rval = collect_variable_data(var_names, tstep_nums, tstep_vals, *file_set);
-  ERRORR(rval, "Trouble collecting data.");
+  rval = myHelper->collect_mesh_info();
+  ERRORR(rval, "Trouble collecting mesh info.");
 
-  rval = initialize_file(var_names);
+  rval = myHelper->collect_variable_data(var_names);
+  ERRORR(rval, "Trouble collecting variable data.");
+
+  rval = myHelper->init_file(var_names);
   ERRORR(rval, "Failed to initialize file.");
 
   rval = myHelper->write_values(var_names);
@@ -145,19 +148,6 @@ ErrorCode WriteNC::parse_options(const FileOptions& opts, std::vector<std::strin
   if (MB_SUCCESS == rval)
     noMesh = true;
 
- /* these are not used yet, maybe later
-  rval = opts.get_null_option("SPECTRAL_MESH");
-  if (MB_SUCCESS == rval)
-    spectralMesh = true;
-
-  rval = opts.get_null_option("NO_MIXED_ELEMENTS");
-  if (MB_SUCCESS == rval)
-    noMixedElements = true;
-
-  rval = opts.get_null_option("NO_EDGES");
-  if (MB_SUCCESS == rval)
-    noEdges = true;*/
-
   if (2 <= dbgOut.get_verbosity()) {
     if (!var_names.empty()) {
       std::cerr << "Variables requested: ";
@@ -179,17 +169,9 @@ ErrorCode WriteNC::parse_options(const FileOptions& opts, std::vector<std::strin
     }
   }
 
-  // The gather set will be important in parallel, this will be the rank that will accumulate the data
-  // to be written in serial
-  // Improvement will be for writing in true parallel
-  rval = opts.get_int_option("GATHER_SET", 0, gatherSetRank);
-  if (MB_TYPE_OUT_OF_RANGE == rval) {
-    mWriteIface->report_error("Invalid value for GATHER_SET option.");
-    return rval;
-  }
 // FIXME: copied from readnc, may need revise
 #ifdef USE_MPI
-  isParallel = (opts.match_option("PARALLEL", "READ_PART") != MB_ENTITY_NOT_FOUND);
+  isParallel = (opts.match_option("PARALLEL", "WRITE_PART") != MB_ENTITY_NOT_FOUND);
 
   if (!isParallel)
   // Return success here, since rval still has _NOT_FOUND from not finding option
@@ -209,17 +191,6 @@ ErrorCode WriteNC::parse_options(const FileOptions& opts, std::vector<std::strin
   }
   const int rank = myPcomm->proc_config().proc_rank();
   dbgOut.set_rank(rank);
-
-  int dum;
-  rval = opts.match_option("PARTITION_METHOD", ScdParData::PartitionMethodNames, dum);
-  if (rval == MB_FAILURE) {
-    mWriteIface->report_error("Unknown partition method specified.");
-    partMethod = ScdParData::ALLJORKORI;
-  }
-  else if (rval == MB_ENTITY_NOT_FOUND)
-    partMethod = ScdParData::ALLJORKORI;
-  else
-    partMethod = dum;
 #endif
 
   return MB_SUCCESS;
@@ -301,8 +272,6 @@ ErrorCode WriteNC::process_conventional_tags(EntityHandle fileSet)
   std::vector<int> varNamesLocs(varNamesLocsSz);
   std::copy(int_p, int_p + varNamesLocsSz, varNamesLocs.begin());
 
-  int nthVar = 0;
-
   Tag varNamesTag = 0;
   tag_name = "__VAR_NAMES";
   rval = mbImpl->tag_get_handle(tag_name.c_str(), 0, MB_TYPE_OPAQUE, varNamesTag, MB_TAG_ANY);
@@ -323,8 +292,8 @@ ErrorCode WriteNC::process_conventional_tags(EntityHandle fileSet)
       std::string var_name(&p[start], i - start);
 
       dbgOut.tprintf(2, "var name: %s index %d \n", var_name.c_str(), idxVar);
-      // process var name:
-      // This will create/initiate map; we will populate variableDataStruct wit info about dims, tags, etc
+      // Process var name:
+      // This will create/initiate map; we will populate variableDataStruct with info about dims, tags, etc
       // reference & is important; otherwise variableDataStruct will go out of scope, and deleted :(
       VarData& variableDataStruct = varInfo[var_name];
       variableDataStruct.varName = var_name;
@@ -336,19 +305,13 @@ ErrorCode WriteNC::process_conventional_tags(EntityHandle fileSet)
       Tag dims_tag = 0;
       std::string dim_names = "__" + var_name + "_DIMS";
       rval = mbImpl->tag_get_handle(dim_names.c_str(), 0, MB_TYPE_OPAQUE, dims_tag, MB_TAG_ANY);
+      // FIXME: Doesn't handle variables with 0 dimension
       ERRORR(rval, "Failed to get tag for a variable dimensions.");
-      // FIXME: Doesn't handle variables have 0 dimension
-      if (MB_SUCCESS != rval) {
-        start = i + 1;
-        ++nthVar;
-        continue;
-      }
       rval = mbImpl->tag_get_length(dims_tag, sz);
       ERRORR(rval, " size of dimensions for variable");
       dbgOut.tprintf(2, "var name: %s has %d dimensions \n", var_name.c_str(), sz);
 
       variableDataStruct.varDims.resize(sz);
-      //std::vector<const pcdim*> dims(sz, NULL);
       const void* ptr = NULL;
       rval = mbImpl->tag_get_by_ptr(dims_tag, &fileSet, 1, &ptr);
 
@@ -363,9 +326,6 @@ ErrorCode WriteNC::process_conventional_tags(EntityHandle fileSet)
           ERRORR(MB_FAILURE, "Dimension not found\n");
         variableDataStruct.varDims[j] = (int)(vit - dimNames.begin()); // Will be used for writing
         // This will have to change to actual file dimension, for writing
-
-        // Do we have a variable for each dimension? I mean, a tag?
-        //dims[j] = &(get_dim(dim_name));
       }
 
       // Attributes for this variable
@@ -503,273 +463,4 @@ ErrorCode WriteNC::process_concatenated_attribute(const void* attPtr, int attSz,
   return MB_SUCCESS;
 }
 
-ErrorCode WriteNC::collect_variable_data(std::vector<std::string>& var_names, std::vector<int>& /* tstep_nums */,
-                                         std::vector<double>& /* tstep_vals */, EntityHandle fileSet)
-{
-  // In general, in netcdf, variables that have the same name as their only dimension are called
-  // coordinate variables
-  // For the time being, check if all dimensions for variables are coordinate variables
-  ErrorCode rval;
-
-  usedCoordinates.clear();
-
-  for (size_t i = 0; i < var_names.size(); i++) {
-    std::string varname = var_names[i];
-    std::map<std::string, VarData>::iterator vit = varInfo.find(varname);
-    if (vit == varInfo.end())
-      ERRORR(MB_FAILURE, "Can't find one variable.");
-
-    size_t sizeVar = 1; // Get multiplied by dim lengths
-    VarData& currentVarData = vit->second;
-    dbgOut.tprintf(2, "    for variable %s varDims.size %d \n", varname.c_str(), (int)currentVarData.varDims.size());
-    for (size_t j = 0; j < currentVarData.varDims.size(); j++) {
-      std::string dimName = dimNames[currentVarData.varDims[j]];
-      vit = varInfo.find(dimName);
-      if (vit == varInfo.end())
-        ERRORR(MB_FAILURE, "Can't find one coordinate variable.");
-
-      if ((dimName == "time" || dimName == "Time" || dimName == "t") &&
-          currentVarData.varDims.size() > 1) // So it is not time itself
-        currentVarData.has_tsteps = true;
-
-      // Probably will have to look at tstep_vals to match them
-      sizeVar *= dimLens[currentVarData.varDims[j]];
-      usedCoordinates.insert(dimName); // Collect those used, we will need to write them to the file
-      dbgOut.tprintf(2, "    for variable %s need dimension %s with length %d\n", varname.c_str(), dimName.c_str(), dimLens[currentVarData.varDims[j]]);
-    }
-
-    currentVarData.sz = sizeVar;
-
-    if (currentVarData.has_tsteps) {
-      int index = 0;
-      while (true) {
-        Tag indexedTag = 0;
-        std::stringstream ssTagNameWithIndex;
-        ssTagNameWithIndex << varname << index;
-        rval = mbImpl->tag_get_handle(ssTagNameWithIndex.str().c_str(), indexedTag);
-        if (MB_SUCCESS != rval)
-          break;
-        dbgOut.tprintf(2, "    found indexed tag %d with name %s\n", index, ssTagNameWithIndex.str().c_str());
-        currentVarData.varTags.push_back(indexedTag);
-        index++; // We should get out of the loop at some point
-        // We will have to collect data for these tags; maybe even allocate memory again
-
-        // The type of the tag is fixed though
-        DataType type;
-        rval = mbImpl->tag_get_data_type(indexedTag, type);
-        ERRORR(rval, "Can't get tag type.");
-
-        currentVarData.varDataType = NC_DOUBLE;
-        if (MB_TYPE_INTEGER == type)
-          currentVarData.varDataType = NC_INT;
-      }
-    }
-    else {
-      // Get the tag with varname
-      Tag tag = 0;
-      rval = mbImpl->tag_get_handle(varname.c_str(), tag);
-      ERRORR(rval, "Can't find one tag.");
-      currentVarData.varTags.push_back(tag); // Really, only one for these
-      const void* data;
-      int size;
-      rval = mbImpl->tag_get_by_ptr(tag, &fileSet, 1, &data, &size);
-      ERRORR(rval, "Can't get tag values.");
-
-      // Find the type of tag, and use it
-      DataType type;
-      rval = mbImpl->tag_get_data_type(tag, type);
-      ERRORR(rval, "Can't get tag type.");
-
-      currentVarData.varDataType = NC_DOUBLE;
-      if (MB_TYPE_INTEGER == type)
-        currentVarData.varDataType = NC_INT;
-
-      assert(currentVarData.memoryHogs.size() == 0); // Nothing so far
-      currentVarData.memoryHogs.push_back((void*)data);
-    }
-  }
-
-  // Check that for used coordinates we have found the tags
-  for (std::set<std::string>::iterator setIt = usedCoordinates.begin();
-      setIt != usedCoordinates.end(); ++setIt) {
-    std::string coordName = *setIt; // Deep copy
-
-    std::map<std::string, VarData>::iterator vit = varInfo.find(coordName);
-    if (vit == varInfo.end())
-      ERRORR(MB_FAILURE, "Can't find one coordinate variable.");
-
-    VarData& varCoordData = vit->second;
-    Tag coordTag = 0;
-    rval = mbImpl->tag_get_handle(coordName.c_str(), coordTag);
-    ERRORR(rval, "Can't find one tag.");
-    varCoordData.varTags.push_back(coordTag); // Really, only one for these
-
-    const void* data;
-    int sizeCoordinate;
-    rval = mbImpl->tag_get_by_ptr(coordTag, &fileSet, 1, &data, &sizeCoordinate);
-    ERRORR(rval, "Can't get coordinate values.");
-    dbgOut.tprintf(2, "    found coordinate tag with name %s and length %d\n", coordName.c_str(),
-        sizeCoordinate);
-
-    // Get dimension length (the only dimension of this coordinate variable, with the same name)
-    assert(1 == varCoordData.varDims.size());
-    int coordDimLen = dimLens[varCoordData.varDims[0]];
-
-    if (dummyVarNames.find(coordName) != dummyVarNames.end()) {
-      // For a dummy coordinate variable, the tag size is always 1
-      // The number of coordinates should be set to dimension length, instead of 1
-      assert(1 == sizeCoordinate);
-      sizeCoordinate = coordDimLen;
-    }
-    else {
-      // The number of coordinates should be exactly the same as dimension length
-      assert(sizeCoordinate == coordDimLen);
-    }
-
-    // This is the length
-    varCoordData.sz = sizeCoordinate;
-    varCoordData.writeStarts.resize(1);
-    varCoordData.writeStarts[0] = 0;
-    varCoordData.writeCounts.resize(1);
-    varCoordData.writeCounts[0] = sizeCoordinate;
-
-    // Find the type of tag, and use it
-    DataType type;
-    rval = mbImpl->tag_get_data_type(coordTag, type);
-    ERRORR(rval, "Can't get tag type.");
-
-    varCoordData.varDataType = NC_DOUBLE;
-    if (MB_TYPE_INTEGER == type)
-      varCoordData.varDataType = NC_INT;
-
-    assert(varCoordData.memoryHogs.size() == 0); // Nothing so far
-    varCoordData.memoryHogs.push_back((void*)data);
-  }
-
-  return MB_SUCCESS;
-}
-
-ErrorCode WriteNC::initialize_file(std::vector<std::string>& var_names)
-{
-  // 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();
-      setIt != usedCoordinates.end(); ++setIt) {
-    std::string coordName = *setIt; // Deep copy
-
-    std::map<std::string, VarData>::iterator vit = varInfo.find(coordName);
-    if (vit == varInfo.end())
-      ERRORR(MB_FAILURE, "Can't find one coordinate variable.");
-
-    VarData& varCoordData = vit->second;
-    varCoordData.varDims.resize(1);
-
-    /* int nc_def_dim (int ncid, const char *name, size_t len, int *dimidp);
-       * example:  status = nc_def_dim(fileId, "lat", 18L, &latid);
-    */
-
-    // Actually define a dimension
-    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]);
-
-    // Create a variable with the same name, and its only dimension the one we just defined
-    /*
-     * int nc_def_var (int ncid, const char *name, nc_type xtype,
-                       int ndims, const int dimids[], int *varidp);
-       example: http://www.unidata.ucar.edu/software/netcdf/docs/netcdf-c/nc_005fdef_005fvar.html#nc_005fdef_005fvar
-     */
-
-    // Skip dummy coordinate variables (e.g. ncol)
-    if (dummyVarNames.find(coordName) != dummyVarNames.end())
-      continue;
-
-    // Define a coordinate variable
-    if (NCFUNC(def_var)(fileId, coordName.c_str(), varCoordData.varDataType,
-        1, &(varCoordData.varDims[0]), &varCoordData.varId) != NC_NOERR)
-      ERRORR(MB_FAILURE, "Failed to create coordinate variable.");
-
-    dbgOut.tprintf(2, "    for coordName %s variable id is %d \n", coordName.c_str(), varCoordData.varId);
-  }
-
-  // Now look at requested variables, and update from the index in dimNames to the actual dimension id
-  for (size_t i = 0; i < var_names.size(); i++) {
-    std::map<std::string, VarData>::iterator vit = varInfo.find(var_names[i]);
-    if (vit == varInfo.end())
-      ERRORR(MB_FAILURE, "Can't find variable requested.");
-
-    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)
-    for (int j = 0; j < numDims; j++) {
-      std::string dimName = dimNames[variableData.varDims[j]];
-      std::map<std::string, VarData>::iterator vit2 = varInfo.find(dimName);
-      if (vit2 == varInfo.end())
-        ERRORR(MB_FAILURE, "Can't find coordinate variable requested.");
-
-      VarData& coordData = vit2->second;
-      variableData.varDims[j] = coordData.varDims[0]; // This one, being a coordinate, is the only one
-      dbgOut.tprintf(2, "          dimension with index %d name %s has ID %d \n",
-          j, dimName.c_str(), variableData.varDims[j]);
-
-      variableData.writeStarts.push_back(0); // Assume we will write all, so start at 0 for all dimensions
-      variableData.writeCounts.push_back(coordData.sz); // Again, write all; times will be one at a time
-    }
-
-    // Define the variable now:
-    if (NCFUNC(def_var)(fileId, var_names[i].c_str(), variableData.varDataType,
-        (int)variableData.varDims.size(), &(variableData.varDims[0]),
-        &variableData.varId) != NC_NOERR)
-      ERRORR(MB_FAILURE, "Failed to create coordinate variable.");
-
-    dbgOut.tprintf(2, "    for variable %s variable id is %d \n", var_names[i].c_str(), variableData.varId);
-    // Now define the variable, with all dimensions
-  }
-
-  // Define global attributes (exactly copied from the original file for the time being)
-  // Should we modify some of them (e.g. revision_Id) later?
-  std::map<std::string, WriteNC::AttData>::iterator attIt;
-  for (attIt = globalAtts.begin(); attIt != globalAtts.end(); ++attIt) {
-    const std::string& attName = attIt->first;
-    WriteNC::AttData& attData = attIt->second;
-    NCDF_SIZE& attLen = attData.attLen;
-    nc_type& attDataType = attData.attDataType;
-    const std::string& attValue = attData.attValue;
-
-    switch (attDataType) {
-      case NC_BYTE:
-      case NC_CHAR:
-        if (NC_NOERR != NCFUNC(put_att_text)(fileId, NC_GLOBAL, attName.c_str(), attLen, attValue.c_str()))
-          ERRORR(MB_FAILURE, "Failed to define text type attribute.");
-        break;
-      case NC_DOUBLE:
-        if (NC_NOERR != NCFUNC(put_att_double)(fileId, NC_GLOBAL, attName.c_str(), NC_DOUBLE, 1, (double*)attValue.c_str()))
-          ERRORR(MB_FAILURE, "Failed to define double type attribute.");
-        break;
-      case NC_FLOAT:
-        if (NC_NOERR != NCFUNC(put_att_float)(fileId, NC_GLOBAL, attName.c_str(), NC_FLOAT, 1, (float*)attValue.c_str()))
-          ERRORR(MB_FAILURE, "Failed to define float type attribute.");
-        break;
-      case NC_INT:
-        if (NC_NOERR != NCFUNC(put_att_int)(fileId, NC_GLOBAL, attName.c_str(), NC_INT, 1, (int*)attValue.c_str()))
-          ERRORR(MB_FAILURE, "Failed to define int type attribute.");
-        break;
-      case NC_SHORT:
-        if (NC_NOERR != NCFUNC(put_att_short)(fileId, NC_GLOBAL, attName.c_str(), NC_SHORT, 1, (short*)attValue.c_str()))
-          ERRORR(MB_FAILURE, "Failed to define short type attribute.");
-        break;
-      default:
-        ERRORR(MB_FAILURE, "Unknown attribute data type.");
-    }
-  }
-
-  // Take it out of define mode
-  if (NC_NOERR != NCFUNC(enddef)(fileId))
-    ERRORR(MB_FAILURE, "Failed to close define mode.");
-
-  return MB_SUCCESS;
-}
-
 } // namespace moab

diff --git a/src/io/WriteNC.hpp b/src/io/WriteNC.hpp
index 47debd5..f9af683 100644
--- a/src/io/WriteNC.hpp
+++ b/src/io/WriteNC.hpp
@@ -57,7 +57,6 @@
 namespace moab {
 
 class WriteUtilIface;
-class ScdInterface;
 class NCWriteHelper;
 
 /**
@@ -66,13 +65,14 @@ class NCWriteHelper;
 class WriteNC : public WriterIface
 {
   friend class NCWriteHelper;
+  friend class ScdNCWriteHelper;
+  friend class UcdNCWriteHelper;
   friend class NCWriteEuler;
   friend class NCWriteFV;
   friend class NCWriteHOMME;
   friend class NCWriteMPAS;
 
 public:
-
   //! Factory method
   static WriterIface* factory(Interface*);
 
@@ -94,7 +94,6 @@ public:
                        int export_dimension = 3);
 
 private:
-
   //! ENTLOCNSEDGE for north/south edge
   //! ENTLOCWEEDGE for west/east edge
   enum EntityLocation {ENTLOCVERT = 0, ENTLOCNSEDGE, ENTLOCEWEDGE, ENTLOCFACE, ENTLOCSET, ENTLOCEDGE, ENTLOCREGION};
@@ -162,37 +161,19 @@ private:
                                            std::vector<int>& attLen,
                                            std::map<std::string, AttData>& attributes);
 
-  //! Will collect data; it should be only on gather processor, but for the time being, collect
-  //! for everybody
-  ErrorCode collect_variable_data(std::vector<std::string>& var_names, std::vector<int>& tstep_nums,
-                                  std::vector<double>& tstep_vals, EntityHandle fileSet);
-
-  //! Initialize file: this is where all defines are done
-  //! the VarData dimension ids are filled up after define
-  ErrorCode initialize_file(std::vector<std::string>& var_names); // These are from options
-
   //! Interface instance
   Interface* mbImpl;
   WriteUtilIface* mWriteIface;
 
   //! File var
   const char* fileName;
-  int IndexFile;
+
   //! File numbers assigned by (p)netcdf
   int fileId;
 
   //! Debug stuff
   DebugOutput dbgOut;
 
-  //! Partitioning method
-  int partMethod;
-
-  //! Scd interface
-  ScdInterface* scdi;
-
-  //! Parallel data object, to be cached with ScdBox
-  ScdParData parData;
-
 #ifdef USE_MPI
   ParallelComm* myPcomm;
 #endif
@@ -201,14 +182,7 @@ private:
   bool noMesh;
   bool noVars;
 
-  /*
-   *  Not used yet, maybe later
-  bool spectralMesh;
-  bool noMixedElements;
-  bool noEdges;*/
-  int gatherSetRank;
-
-  //! Cached tags for writing. this will be important for ordering the data, in parallel
+  //! Cached tags for writing. This will be important for ordering the data, in parallel
   Tag mGlobalIdTag;
 
   //! Are we writing in parallel? (probably in the future)

diff --git a/test/io/write_nc.cpp b/test/io/write_nc.cpp
index a9b9e0c..30b3f15 100644
--- a/test/io/write_nc.cpp
+++ b/test/io/write_nc.cpp
@@ -71,13 +71,13 @@ void test_eul_read_write_T()
   CHECK_ERR(rval);
 
   // Load non-set variable T, set variable gw, and the mesh
-  std::string opts = orig + std::string(";DEBUG_IO=3;VARIABLE=T,gw");
+  std::string opts = orig + std::string(";DEBUG_IO=0;VARIABLE=T,gw");
   rval = mb.load_file(example_eul, &set, opts.c_str());
   CHECK_ERR(rval);
 
   // Write variables T and gw
   std::string writeopts;
-  writeopts = std::string(";;VARIABLE=T,gw;DEBUG_IO=2;");
+  writeopts = std::string(";;VARIABLE=T,gw;DEBUG_IO=0;");
   rval = mb.write_file("test_eul_T.nc", 0, writeopts.c_str(), &set, 1);
   CHECK_ERR(rval);
 }

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