[MOAB-dev] commit/MOAB: danwu: Moved some variables and functions from ReadNC class to its helper classes, reducing ReadNC.cpp to less than 450 lines. This change passed make check.

commits-noreply at bitbucket.org commits-noreply at bitbucket.org
Wed Aug 7 14:18:05 CDT 2013


1 new commit in MOAB:

https://bitbucket.org/fathomteam/moab/commits/778cccf0a49f/
Changeset:   778cccf0a49f
Branch:      master
User:        danwu
Date:        2013-08-07 21:16:57
Summary:     Moved some variables and functions from ReadNC class to its helper classes, reducing ReadNC.cpp to less than 450 lines. This change passed make check.

Affected #:  9 files

diff --git a/src/io/NCHelper.cpp b/src/io/NCHelper.cpp
index b6158a9..69e24eb 100644
--- a/src/io/NCHelper.cpp
+++ b/src/io/NCHelper.cpp
@@ -4,6 +4,8 @@
 #include "NCHelperHOMME.hpp"
 #include "NCHelperMPAS.hpp"
 
+#include <sstream>
+
 #include "moab/ReadUtilIface.hpp"
 #include "MBTagConventions.hpp"
 
@@ -52,89 +54,254 @@ NCHelper* NCHelper::get_nc_helper(ReadNC* readNC, int fileId, const FileOptions&
   return NULL;
 }
 
-ErrorCode NCHelper::read_variable_to_set_allocate(std::vector<ReadNC::VarData>& vdatas, std::vector<int>& tstep_nums)
-{
+ErrorCode NCHelper::create_conventional_tags(ScdInterface* scdi, EntityHandle file_set, const std::vector<int>& tstep_nums) {
+  Interface*& mbImpl = _readNC->mbImpl;
+  std::vector<std::string>& dimNames = _readNC->dimNames;
   std::vector<int>& dimVals = _readNC->dimVals;
-  int tDim = _readNC->tDim;
+  std::map<std::string, ReadNC::AttData>& globalAtts = _readNC->globalAtts;
+  std::map<std::string, ReadNC::VarData>& varInfo = _readNC->varInfo;
   DebugOutput& dbgOut = _readNC->dbgOut;
+  int& partMethod = _readNC->partMethod;
+
+  ErrorCode rval;
+  std::string tag_name;
+
+  // <__NUM_DIMS>
+  Tag numDimsTag = 0;
+  tag_name = "__NUM_DIMS";
+  int numDims = dimNames.size();
+  rval = mbImpl->tag_get_handle(tag_name.c_str(), 1, MB_TYPE_INTEGER, numDimsTag, MB_TAG_SPARSE | MB_TAG_CREAT);
+  ERRORR(rval, "Trouble creating __NUM_DIMS tag.");
+  rval = mbImpl->tag_set_data(numDimsTag, &file_set, 1, &numDims);
+  ERRORR(rval, "Trouble setting data for __NUM_DIMS tag.");
+  if (MB_SUCCESS == rval)
+    dbgOut.tprintf(2, "Tag created for variable %s\n", tag_name.c_str());
+
+  // <__NUM_VARS>
+  Tag numVarsTag = 0;
+  tag_name = "__NUM_VARS";
+  int numVars = varInfo.size();
+  rval = mbImpl->tag_get_handle(tag_name.c_str(), 1, MB_TYPE_INTEGER, numVarsTag, MB_TAG_SPARSE | MB_TAG_CREAT);
+  ERRORR(rval, "Trouble creating __NUM_VARS tag.");
+  rval = mbImpl->tag_set_data(numVarsTag, &file_set, 1, &numVars);
+  ERRORR(rval, "Trouble setting data for __NUM_VARS tag.");
+  if (MB_SUCCESS == rval)
+    dbgOut.tprintf(2, "Tag created for variable %s\n", tag_name.c_str());
+
+  // <__DIM_NAMES>
+  Tag dimNamesTag = 0;
+  tag_name = "__DIM_NAMES";
+  std::string dimnames;
+  unsigned int dimNamesSz = dimNames.size();
+  for (unsigned int i = 0; i != dimNamesSz; ++i) {
+    dimnames.append(dimNames[i]);
+    dimnames.push_back('\0');
+  }
+  int dimnamesSz = dimnames.size();
+  rval = mbImpl->tag_get_handle(tag_name.c_str(), 0, MB_TYPE_OPAQUE, dimNamesTag, MB_TAG_CREAT | MB_TAG_SPARSE | MB_TAG_VARLEN);
+  ERRORR(rval, "Trouble creating __DIM_NAMES tag.");
+  const void* ptr = dimnames.c_str();
+  rval = mbImpl->tag_set_by_ptr(dimNamesTag, &file_set, 1, &ptr, &dimnamesSz);
+  ERRORR(rval, "Trouble setting data for __DIM_NAMES tag.");
+  if (MB_SUCCESS == rval)
+    dbgOut.tprintf(2, "Tag created for variable %s\n", tag_name.c_str());
+
+  // <__DIM_VALUES>
+  Tag dimValsTag = 0;
+  tag_name = "__DIM_VALUES";
+  int dimValsSz = (int)dimVals.size();
+
+  rval = mbImpl->tag_get_handle(tag_name.c_str(), 0, MB_TYPE_INTEGER, dimValsTag, MB_TAG_CREAT | MB_TAG_SPARSE | MB_TAG_VARLEN);
+  ERRORR(rval, "Trouble creating __DIM_VALUES tag.");
+  ptr = &(dimVals[0]);
+  rval = mbImpl->tag_set_by_ptr(dimValsTag, &file_set, 1, &ptr, &dimValsSz);
+  ERRORR(rval, "Trouble setting data for __DIM_VALUES tag.");
+  if (MB_SUCCESS == rval)
+    dbgOut.tprintf(2, "Tag created for variable %s\n", tag_name.c_str());
+
+  // <__VAR_NAMES>
+  Tag varNamesTag = 0;
+  tag_name = "__VAR_NAMES";
+  std::string varnames;
+  std::map<std::string, ReadNC::VarData>::iterator mapIter;
+  for (mapIter = varInfo.begin(); mapIter != varInfo.end(); ++mapIter) {
+    varnames.append(mapIter->first);
+    varnames.push_back('\0');
+  }
+  int varnamesSz = varnames.size();
+  rval = mbImpl->tag_get_handle(tag_name.c_str(), 0, MB_TYPE_OPAQUE, varNamesTag, MB_TAG_CREAT | MB_TAG_SPARSE | MB_TAG_VARLEN);
+  ERRORR(rval, "Trouble creating __VAR_NAMES tag.");
+  ptr = varnames.c_str();
+  rval = mbImpl->tag_set_by_ptr(varNamesTag, &file_set, 1, &ptr, &varnamesSz);
+  ERRORR(rval, "Trouble setting data for __VAR_NAMES tag.");
+  if (MB_SUCCESS == rval)
+    dbgOut.tprintf(2, "Tag created for variable %s\n", tag_name.c_str());
+
+  // __<dim_name>_LOC_MINMAX
+  for (unsigned int i = 0; i != dimNamesSz; ++i) {
+    if (dimNames[i] == "time") {
+      std::stringstream ss_tag_name;
+      ss_tag_name << "__" << dimNames[i] << "_LOC_MINMAX";
+      tag_name = ss_tag_name.str();
+      Tag tagh = 0;
+      std::vector<int> val(2, 0);
+      val[0] = 0;
+      val[1] = nTimeSteps - 1;
+      rval = mbImpl->tag_get_handle(tag_name.c_str(), 2, MB_TYPE_INTEGER, tagh, MB_TAG_SPARSE | MB_TAG_CREAT);
+      ERRORR(rval, "Trouble creating __<dim_name>_LOC_MINMAX tag.");
+      rval = mbImpl->tag_set_data(tagh, &file_set, 1, &val[0]);
+      ERRORR(rval, "Trouble setting data for __<dim_name>_LOC_MINMAX tag.");
+      if (MB_SUCCESS == rval)
+        dbgOut.tprintf(2, "Tag created for variable %s\n", tag_name.c_str());
+    }
+  }
 
-  ErrorCode rval = MB_SUCCESS;
-
-  for (unsigned int i = 0; i < vdatas.size(); i++) {
-    if ((std::find(vdatas[i].varDims.begin(), vdatas[i].varDims.end(), tDim) != vdatas[i].varDims.end()))
-      vdatas[i].has_t = true;
-
-    for (unsigned int t = 0; t < tstep_nums.size(); t++) {
-      dbgOut.tprintf(2, "Reading variable %s, time step %d\n", vdatas[i].varName.c_str(), tstep_nums[t]);
-
-      // Get the tag to read into
-      if (!vdatas[i].varTags[t]) {
-        rval = _readNC->get_tag_to_set(vdatas[i], tstep_nums[t], vdatas[i].varTags[t]);
-        ERRORR(rval, "Trouble getting tag.");
-      }
+  // __<dim_name>_LOC_VALS
+  for (unsigned int i = 0; i != dimNamesSz; ++i) {
+    if (dimNames[i] != "time")
+      continue;
+    std::vector<int> val;
+    if (!tstep_nums.empty())
+      val = tstep_nums;
+    else {
+      val.resize(tVals.size());
+      for (unsigned int j = 0; j != tVals.size(); ++j)
+        val[j] = j;
+    }
+    Tag tagh = 0;
+    std::stringstream ss_tag_name;
+    ss_tag_name << "__" << dimNames[i] << "_LOC_VALS";
+    tag_name = ss_tag_name.str();
+    rval = mbImpl->tag_get_handle(tag_name.c_str(), val.size(), MB_TYPE_INTEGER, tagh, MB_TAG_SPARSE | MB_TAG_CREAT);
+    ERRORR(rval, "Trouble creating __<dim_name>_LOC_VALS tag.");
+    rval = mbImpl->tag_set_data(tagh, &file_set, 1, &val[0]);
+    ERRORR(rval, "Trouble setting data for __<dim_name>_LOC_VALS tag.");
+    if (MB_SUCCESS == rval)
+      dbgOut.tprintf(2, "Tag created for variable %s\n", tag_name.c_str());
+  }
 
-      // Assume point-based values for now?
-      if (-1 == tDim || dimVals[tDim] <= (int) t)
-        ERRORR(MB_INDEX_OUT_OF_RANGE, "Wrong value for timestep number.");
+  // __<var_name>_DIMS
+  for (mapIter = varInfo.begin(); mapIter != varInfo.end(); ++mapIter) {
+    Tag varNamesDimsTag = 0;
+    std::stringstream ss_tag_name;
+    ss_tag_name << "__" << mapIter->first << "_DIMS";
+    tag_name = ss_tag_name.str();
+    unsigned int varDimSz = varInfo[mapIter->first].varDims.size();
+    if (varDimSz == 0)
+      continue;
+    varInfo[mapIter->first].varTags.resize(varDimSz, 0);
+    for (unsigned int i = 0; i != varDimSz; ++i) {
+      Tag tmptag = 0;
+      std::string tmptagname = dimNames[varInfo[mapIter->first].varDims[i]];
+      mbImpl->tag_get_handle(tmptagname.c_str(), 0, MB_TYPE_OPAQUE, tmptag, MB_TAG_ANY);
+      varInfo[mapIter->first].varTags[i] = tmptag;
+    }
+    rval = mbImpl->tag_get_handle(tag_name.c_str(), varDimSz, MB_TYPE_HANDLE, varNamesDimsTag, MB_TAG_SPARSE | MB_TAG_CREAT);
+    ERRORR(rval, "Trouble creating __<var_name>_DIMS tag.");
+    rval = mbImpl->tag_set_data(varNamesDimsTag, &file_set, 1, &(varInfo[mapIter->first].varTags[0]));
+    ERRORR(rval, "Trouble setting data for __<var_name>_DIMS tag.");
+    if (MB_SUCCESS == rval)
+      dbgOut.tprintf(2, "Tag created for variable %s\n", tag_name.c_str());
+  }
 
-      // Set up the dimensions and counts
-      // First variable dimension is time, if it exists
-      if (vdatas[i].has_t)
-      {
-        if (vdatas[i].varDims.size() != 1)
-        {
-          vdatas[i].readStarts[t].push_back(tstep_nums[t]);
-          vdatas[i].readCounts[t].push_back(1);
-        }
-        else
-        {
-          vdatas[i].readStarts[t].push_back(0);
-          vdatas[i].readCounts[t].push_back(tstep_nums.size());
-        }
-      }
+  // <PARTITION_METHOD>
+  Tag part_tag = scdi->part_method_tag();
+  if (!part_tag)
+    ERRORR(MB_FAILURE, "Trouble getting partition method tag.");
+  rval = mbImpl->tag_set_data(part_tag, &file_set, 1, &partMethod);
+  ERRORR(rval, "Trouble setting data for PARTITION_METHOD tag.");
+  if (MB_SUCCESS == rval)
+    dbgOut.tprintf(2, "Tag created for variable %s\n", tag_name.c_str());
+
+  // <__GLOBAL_ATTRIBS>
+  tag_name = "__GLOBAL_ATTRIBS";
+  Tag globalAttTag = 0;
+  rval = mbImpl->tag_get_handle(tag_name.c_str(), 0, MB_TYPE_OPAQUE, globalAttTag, MB_TAG_CREAT | MB_TAG_SPARSE | MB_TAG_VARLEN);
+  ERRORR(rval, "Trouble creating __GLOBAL_ATTRIBS tag.");
+  std::string gattVal;
+  std::vector<int> gattLen;
+  rval = create_attrib_string(globalAtts, gattVal, gattLen);
+  ERRORR(rval, "Trouble creating attribute strings.");
+  const void* gattptr = gattVal.c_str();
+  int globalAttSz = gattVal.size();
+  rval = mbImpl->tag_set_by_ptr(globalAttTag, &file_set, 1, &gattptr, &globalAttSz);
+  ERRORR(rval, "Trouble setting data for __GLOBAL_ATTRIBS tag.");
+  if (MB_SUCCESS == rval)
+    dbgOut.tprintf(2, "Tag created for variable %s\n", tag_name.c_str());
+
+  // <__GLOBAL_ATTRIBS_LEN>
+  tag_name = "__GLOBAL_ATTRIBS_LEN";
+  Tag globalAttLenTag = 0;
+  if (gattLen.size() == 0)
+    gattLen.push_back(0);
+  rval = mbImpl->tag_get_handle(tag_name.c_str(), gattLen.size(), MB_TYPE_INTEGER, globalAttLenTag, MB_TAG_SPARSE | MB_TAG_CREAT);
+  ERRORR(rval, "Trouble creating __GLOBAL_ATTRIBS_LEN tag.");
+  rval = mbImpl->tag_set_data(globalAttLenTag, &file_set, 1, &gattLen[0]);
+  ERRORR(rval, "Trouble setting data for __GLOBAL_ATTRIBS_LEN tag.");
+  if (MB_SUCCESS == rval)
+    dbgOut.tprintf(2, "Tag created for variable %s\n", tag_name.c_str());
+
+  // __<var_name>_ATTRIBS and __<var_name>_ATTRIBS_LEN
+  for (mapIter = varInfo.begin(); mapIter != varInfo.end(); ++mapIter) {
+    std::stringstream ssTagName;
+    ssTagName << "__" << mapIter->first << "_ATTRIBS";
+    tag_name = ssTagName.str();
+    Tag varAttTag = 0;
+    rval = mbImpl->tag_get_handle(tag_name.c_str(), 0, MB_TYPE_OPAQUE, varAttTag, MB_TAG_CREAT | MB_TAG_SPARSE | MB_TAG_VARLEN);
+    ERRORR(rval, "Trouble creating __<var_name>_ATTRIBS tag.");
+    std::string varAttVal;
+    std::vector<int> varAttLen;
+    rval = create_attrib_string(mapIter->second.varAtts, varAttVal, varAttLen);
+    ERRORR(rval, "Trouble creating attribute strings.");
+    const void* varAttPtr = varAttVal.c_str();
+    int varAttSz = varAttVal.size();
+    rval = mbImpl->tag_set_by_ptr(varAttTag, &file_set, 1, &varAttPtr, &varAttSz);
+    ERRORR(rval, "Trouble setting data for __<var_name>_ATTRIBS tag.");
+    if (MB_SUCCESS == rval)
+      dbgOut.tprintf(2, "Tag created for variable %s\n", tag_name.c_str());
+    if (varAttLen.size() == 0)
+      varAttLen.push_back(0);
+    ssTagName << "_LEN";
+    tag_name = ssTagName.str();
+    Tag varAttLenTag = 0;
+    rval = mbImpl->tag_get_handle(tag_name.c_str(), varAttLen.size(), MB_TYPE_INTEGER, varAttLenTag, MB_TAG_SPARSE | MB_TAG_CREAT);
+    ERRORR(rval, "Trouble creating __<var_name>_ATTRIBS_LEN tag.");
+    rval = mbImpl->tag_set_data(varAttLenTag, &file_set, 1, &varAttLen[0]);
+    ERRORR(rval, "Trouble setting data for __<var_name>_ATTRIBS_LEN tag.");
+    if (MB_SUCCESS == rval)
+      dbgOut.tprintf(2, "Tag created for variable %s\n", tag_name.c_str());
+  }
 
-      // Set up other dimensions and counts
-      if (vdatas[i].varDims.empty()) {
-        // Scalar variable
-        vdatas[i].readStarts[t].push_back(0);
-        vdatas[i].readCounts[t].push_back(1);
-      }
-      else {
-        for (unsigned int idx = 0; idx != vdatas[i].varDims.size(); idx++){
-          if (tDim != vdatas[i].varDims[idx]){
-            // Push other variable dimensions, except time, which was already pushed
-            vdatas[i].readStarts[t].push_back(0);
-            vdatas[i].readCounts[t].push_back(dimVals[vdatas[i].varDims[idx]]);
-          }
-        }
-      }
-      std::size_t sz = 1;
-      for (std::size_t idx = 0; idx != vdatas[i].readCounts[t].size(); idx++)
-        sz *= vdatas[i].readCounts[t][idx];
-      vdatas[i].sz = sz;
-      switch (vdatas[i].varDataType) {
-        case NC_BYTE:
-        case NC_CHAR:
-          vdatas[i].varDatas[t] = new char[sz];
-          break;
-        case NC_DOUBLE:
-        case NC_FLOAT:
-          vdatas[i].varDatas[t] = new double[sz];
-          break;
-        case NC_INT:
-        case NC_SHORT:
-          vdatas[i].varDatas[t] = new int[sz];
-          break;
-        default:
-          std::cerr << "Unrecognized data type for tag " << std::endl;
-          rval = MB_FAILURE;
-      }
-      if (vdatas[i].varDims.size() <= 1)
-        break;
-    }
+  // <__VAR_NAMES_LOCATIONS>
+  tag_name = "__VAR_NAMES_LOCATIONS";
+  Tag varNamesLocsTag = 0;
+  std::vector<int> varNamesLocs(varInfo.size());
+  rval = mbImpl->tag_get_handle(tag_name.c_str(), varNamesLocs.size(), MB_TYPE_INTEGER, varNamesLocsTag, MB_TAG_CREAT
+      | MB_TAG_SPARSE);
+  ERRORR(rval, "Trouble creating __VAR_NAMES_LOCATIONS tag.");
+  for (mapIter = varInfo.begin(); mapIter != varInfo.end(); ++mapIter) {
+    varNamesLocs[std::distance(varInfo.begin(), mapIter)] = mapIter->second.entLoc;
   }
+  rval = mbImpl->tag_set_data(varNamesLocsTag, &file_set, 1, &varNamesLocs[0]);
+  ERRORR(rval, "Trouble setting data for __VAR_NAMES_LOCATIONS tag.");
+  if (MB_SUCCESS == rval)
+    dbgOut.tprintf(2, "Tag created for variable %s\n", tag_name.c_str());
+
+  // <__MESH_TYPE>
+  Tag meshTypeTag = 0;
+  tag_name = "__MESH_TYPE";
+  std::string meshTypeName = get_mesh_type_name();
+
+  rval = mbImpl->tag_get_handle(tag_name.c_str(), 0, MB_TYPE_OPAQUE, meshTypeTag, MB_TAG_CREAT | MB_TAG_SPARSE | MB_TAG_VARLEN);
+  ERRORR(rval, "Trouble creating __MESH_TYPE tag.");
+  ptr = meshTypeName.c_str();
+  int leng= meshTypeName.size();
+  rval = mbImpl->tag_set_by_ptr(meshTypeTag, &file_set, 1, &ptr, &leng);
+  ERRORR(rval, "Trouble setting data for __MESH_TYPE tag.");
+  if (MB_SUCCESS == rval)
+    dbgOut.tprintf(2, "Tag created for variable %s\n", tag_name.c_str());
 
-  return rval;
+  return MB_SUCCESS;
 }
 
 ErrorCode NCHelper::read_variable_to_set(EntityHandle file_set, std::vector<ReadNC::VarData>& vdatas, std::vector<int>& tstep_nums)
@@ -314,9 +481,294 @@ ErrorCode NCHelper::convert_variable(ReadNC::VarData& var_data, int tstep_num)
   return MB_SUCCESS;
 }
 
+ErrorCode NCHelper::read_coordinate(const char* var_name, int lmin, int lmax, std::vector<double>& cvals)
+{
+  std::map<std::string, ReadNC::VarData>& varInfo = _readNC->varInfo;
+  std::map<std::string, ReadNC::VarData>::iterator vmit = varInfo.find(var_name);
+  if (varInfo.end() == vmit)
+    return MB_FAILURE;
+
+  // Check to make sure it's a float or double
+  int fail;
+  NCDF_SIZE tmin = lmin, tcount = lmax - lmin + 1;
+  NCDF_DIFF dum_stride = 1;
+  if (NC_DOUBLE == (*vmit).second.varDataType) {
+    cvals.resize(tcount);
+    fail = NCFUNCA(get_vars_double)(_fileId, (*vmit).second.varId, &tmin, &tcount, &dum_stride, &cvals[0]);
+    if (fail)
+      ERRORS(MB_FAILURE, "Failed to get coordinate values.");
+  }
+  else if (NC_FLOAT == (*vmit).second.varDataType) {
+    std::vector<float> tcvals(tcount);
+    fail = NCFUNCA(get_vars_float)(_fileId, (*vmit).second.varId, &tmin, &tcount, &dum_stride, &tcvals[0]);
+    if (fail)
+      ERRORS(MB_FAILURE, "Failed to get coordinate values.");
+    cvals.resize(tcount);
+    std::copy(tcvals.begin(), tcvals.end(), cvals.begin());
+  }
+  else ERRORR(MB_FAILURE, "Wrong data type for coordinate variable.");
+
+  return MB_SUCCESS;
+}
+
+ErrorCode NCHelper::get_tag_to_set(ReadNC::VarData& var_data, int tstep_num, Tag& tagh)
+{
+  Interface*& mbImpl = _readNC->mbImpl;
+  DebugOutput& dbgOut = _readNC->dbgOut;
+
+  std::ostringstream tag_name;
+  if ((!var_data.has_t) || (var_data.varDims.size() <= 1))
+    tag_name << var_data.varName;
+  else if (!tstep_num) {
+    std::string tmp_name = var_data.varName + "0";
+    tag_name << tmp_name.c_str();
+  }
+  else
+    tag_name << var_data.varName << tstep_num;
+  ErrorCode rval = MB_SUCCESS;
+  tagh = 0;
+  switch (var_data.varDataType) {
+    case NC_BYTE:
+    case NC_CHAR:
+      rval = mbImpl->tag_get_handle(tag_name.str().c_str(), 0, MB_TYPE_OPAQUE, tagh, MB_TAG_CREAT | MB_TAG_SPARSE | MB_TAG_VARLEN);
+      break;
+    case NC_DOUBLE:
+    case NC_FLOAT:
+      rval = mbImpl->tag_get_handle(tag_name.str().c_str(), 0, MB_TYPE_DOUBLE, tagh, MB_TAG_CREAT | MB_TAG_SPARSE | MB_TAG_VARLEN);
+      break;
+    case NC_INT:
+    case NC_SHORT:
+      rval = mbImpl->tag_get_handle(tag_name.str().c_str(), 0, MB_TYPE_INTEGER, tagh, MB_TAG_CREAT | MB_TAG_SPARSE | MB_TAG_VARLEN);
+      break;
+    default:
+      std::cerr << "Unrecognized data type for tag " << tag_name << std::endl;
+      rval = MB_FAILURE;
+  }
+
+  if (MB_SUCCESS == rval)
+    dbgOut.tprintf(2, "Tag created for variable %s\n", tag_name.str().c_str());
+
+  return rval;
+}
+
+ErrorCode NCHelper::get_tag_to_nonset(ReadNC::VarData& var_data, int tstep_num, Tag& tagh, int num_lev)
+{
+  Interface*& mbImpl = _readNC->mbImpl;
+  DebugOutput& dbgOut = _readNC->dbgOut;
+
+  std::ostringstream tag_name;
+  if (!tstep_num) {
+    std::string tmp_name = var_data.varName + "0";
+    tag_name << tmp_name.c_str();
+  }
+  else
+    tag_name << var_data.varName << tstep_num;
+  ErrorCode rval = MB_SUCCESS;
+  tagh = 0;
+  switch (var_data.varDataType) {
+    case NC_BYTE:
+    case NC_CHAR:
+      rval = mbImpl->tag_get_handle(tag_name.str().c_str(), num_lev, MB_TYPE_OPAQUE, tagh, MB_TAG_DENSE | MB_TAG_CREAT);
+      break;
+    case NC_DOUBLE:
+    case NC_FLOAT:
+      rval = mbImpl->tag_get_handle(tag_name.str().c_str(), num_lev, MB_TYPE_DOUBLE, tagh, MB_TAG_DENSE | MB_TAG_CREAT);
+      break;
+    case NC_INT:
+    case NC_SHORT:
+      rval = mbImpl->tag_get_handle(tag_name.str().c_str(), num_lev, MB_TYPE_INTEGER, tagh, MB_TAG_DENSE | MB_TAG_CREAT);
+      break;
+    default:
+      std::cerr << "Unrecognized data type for tag " << tag_name.str() << std::endl;
+      rval = MB_FAILURE;
+  }
+
+  if (MB_SUCCESS == rval)
+    dbgOut.tprintf(2, "Tag created for variable %s\n", tag_name.str().c_str());
+
+  return rval;
+}
+
+ErrorCode NCHelper::create_attrib_string(const std::map<std::string, ReadNC::AttData>& attMap, std::string& attVal, std::vector<int>& attLen)
+{
+  int success;
+  std::stringstream ssAtt;
+  unsigned int sz = 0;
+  std::map<std::string, ReadNC::AttData>::const_iterator attIt = attMap.begin();
+  for (; attIt != attMap.end(); ++attIt) {
+    ssAtt << attIt->second.attName;
+    ssAtt << '\0';
+    void* attData = NULL;
+    switch (attIt->second.attDataType) {
+      case NC_BYTE:
+      case NC_CHAR:
+        sz = attIt->second.attLen;
+        attData = (char *) malloc(sz);
+        success = NCFUNC(get_att_text)(_fileId, attIt->second.attVarId, attIt->second.attName.c_str(), (char*) attData);
+        ERRORS(success, "Failed to read attribute char data.");
+        ssAtt << "char;";
+        break;
+      case NC_DOUBLE:
+        sz = attIt->second.attLen * sizeof(double);
+        attData = (double *) malloc(sz);
+        success = NCFUNC(get_att_double)(_fileId, attIt->second.attVarId, attIt->second.attName.c_str(), (double*) attData);
+        ERRORS(success, "Failed to read attribute double data.");
+        ssAtt << "double;";
+        break;
+      case NC_FLOAT:
+        sz = attIt->second.attLen * sizeof(float);
+        attData = (float *) malloc(sz);
+        success = NCFUNC(get_att_float)(_fileId, attIt->second.attVarId, attIt->second.attName.c_str(), (float*) attData);
+        ERRORS(success, "Failed to read attribute float data.");
+        ssAtt << "float;";
+        break;
+      case NC_INT:
+        sz = attIt->second.attLen * sizeof(int);
+        attData = (int *) malloc(sz);
+        success = NCFUNC(get_att_int)(_fileId, attIt->second.attVarId, attIt->second.attName.c_str(), (int*) attData);
+        ERRORS(success, "Failed to read attribute int data.");
+        ssAtt << "int;";
+        break;
+      case NC_SHORT:
+        sz = attIt->second.attLen * sizeof(short);
+        attData = (short *) malloc(sz);
+        success = NCFUNC(get_att_short)(_fileId, attIt->second.attVarId, attIt->second.attName.c_str(), (short*) attData);
+        ERRORS(success, "Failed to read attribute short data.");
+        ssAtt << "short;";
+        break;
+      default:
+        success = 1;
+    }
+    char* tmpc = (char *) attData;
+    for (unsigned int counter = 0; counter != sz; ++counter)
+      ssAtt << tmpc[counter];
+    free(attData);
+    ssAtt << ';';
+    attLen.push_back(ssAtt.str().size() - 1);
+  }
+  attVal = ssAtt.str();
+
+  return MB_SUCCESS;
+}
+
+void NCHelper::init_dims_with_no_cvars_info()
+{
+  std::vector<std::string>& dimNames = _readNC->dimNames;
+  std::set<std::string>& dummyVarNames = _readNC->dummyVarNames;
+  std::map<std::string, ReadNC::VarData>& varInfo = _readNC->varInfo;
+  DebugOutput& dbgOut = _readNC->dbgOut;
+
+  // Hack: look at all dimensions, and see if we have one that does not appear in the list of varInfo names
+  // right now, candidates are ncol and nbnd
+  // for them, create dummy tags
+  for (unsigned int i = 0; i < dimNames.size(); i++)
+  {
+    // If there is a var with this name, skip, we are fine; if not, create a varInfo...
+    if (varInfo.find(dimNames[i]) != varInfo.end())
+      continue; // We already have a variable with this dimension name
+
+    int sizeTotalVar = varInfo.size();
+    std::string var_name(dimNames[i]);
+    ReadNC::VarData &data = varInfo[var_name];
+    data.varName = std::string(var_name);
+    data.varId =sizeTotalVar;
+    data.varTags.resize(1, 0);
+    data.varDataType = NC_DOUBLE; // could be int, actually, but we do not really need the type
+    data.varDims.resize(1);
+    data.varDims[0]= (int)i;
+    data.numAtts=0;
+    data.entLoc = ReadNC::ENTLOCSET;
+    dbgOut.tprintf(2, "Dummy varInfo created for dimension %s\n", dimNames[i].c_str());
+    dummyVarNames.insert(dimNames[i]);
+  }
+}
+
+ErrorCode NCHelper::read_variable_to_set_allocate(std::vector<ReadNC::VarData>& vdatas, std::vector<int>& tstep_nums)
+{
+  std::vector<int>& dimVals = _readNC->dimVals;
+  DebugOutput& dbgOut = _readNC->dbgOut;
+
+  ErrorCode rval = MB_SUCCESS;
+
+  for (unsigned int i = 0; i < vdatas.size(); i++) {
+    if ((std::find(vdatas[i].varDims.begin(), vdatas[i].varDims.end(), tDim) != vdatas[i].varDims.end()))
+      vdatas[i].has_t = true;
+
+    for (unsigned int t = 0; t < tstep_nums.size(); t++) {
+      dbgOut.tprintf(2, "Reading variable %s, time step %d\n", vdatas[i].varName.c_str(), tstep_nums[t]);
+
+      // Get the tag to read into
+      if (!vdatas[i].varTags[t]) {
+        rval = get_tag_to_set(vdatas[i], tstep_nums[t], vdatas[i].varTags[t]);
+        ERRORR(rval, "Trouble getting tag.");
+      }
+
+      // Assume point-based values for now?
+      if (-1 == tDim || dimVals[tDim] <= (int) t)
+        ERRORR(MB_INDEX_OUT_OF_RANGE, "Wrong value for timestep number.");
+
+      // Set up the dimensions and counts
+      // First variable dimension is time, if it exists
+      if (vdatas[i].has_t)
+      {
+        if (vdatas[i].varDims.size() != 1)
+        {
+          vdatas[i].readStarts[t].push_back(tstep_nums[t]);
+          vdatas[i].readCounts[t].push_back(1);
+        }
+        else
+        {
+          vdatas[i].readStarts[t].push_back(0);
+          vdatas[i].readCounts[t].push_back(tstep_nums.size());
+        }
+      }
+
+      // Set up other dimensions and counts
+      if (vdatas[i].varDims.empty()) {
+        // Scalar variable
+        vdatas[i].readStarts[t].push_back(0);
+        vdatas[i].readCounts[t].push_back(1);
+      }
+      else {
+        for (unsigned int idx = 0; idx != vdatas[i].varDims.size(); idx++){
+          if (tDim != vdatas[i].varDims[idx]){
+            // Push other variable dimensions, except time, which was already pushed
+            vdatas[i].readStarts[t].push_back(0);
+            vdatas[i].readCounts[t].push_back(dimVals[vdatas[i].varDims[idx]]);
+          }
+        }
+      }
+      std::size_t sz = 1;
+      for (std::size_t idx = 0; idx != vdatas[i].readCounts[t].size(); idx++)
+        sz *= vdatas[i].readCounts[t][idx];
+      vdatas[i].sz = sz;
+      switch (vdatas[i].varDataType) {
+        case NC_BYTE:
+        case NC_CHAR:
+          vdatas[i].varDatas[t] = new char[sz];
+          break;
+        case NC_DOUBLE:
+        case NC_FLOAT:
+          vdatas[i].varDatas[t] = new double[sz];
+          break;
+        case NC_INT:
+        case NC_SHORT:
+          vdatas[i].varDatas[t] = new int[sz];
+          break;
+        default:
+          std::cerr << "Unrecognized data type for tag " << std::endl;
+          rval = MB_FAILURE;
+      }
+      if (vdatas[i].varDims.size() <= 1)
+        break;
+    }
+  }
+
+  return rval;
+}
+
 ErrorCode ScdNCHelper::check_existing_mesh(EntityHandle file_set) {
   Interface*& mbImpl = _readNC->mbImpl;
-  int (&lDims)[6] = _readNC->lDims;
 
   // Get the number of vertices
   int num_verts;
@@ -358,15 +810,8 @@ ErrorCode ScdNCHelper::check_existing_mesh(EntityHandle file_set) {
 ErrorCode ScdNCHelper::create_mesh(ScdInterface* scdi, const FileOptions& opts, EntityHandle file_set, Range& faces)
 {
   Interface*& mbImpl = _readNC->mbImpl;
-  int (&gDims)[6] = _readNC->gDims;
-  int (&lDims)[6] = _readNC->lDims;
-  std::vector<double>& ilVals = _readNC->ilVals;
-  std::vector<double>& jlVals = _readNC->jlVals;
-  std::vector<double>& klVals = _readNC->klVals;
   Tag& mGlobalIdTag = _readNC->mGlobalIdTag;
   DebugOutput& dbgOut = _readNC->dbgOut;
-  int (&locallyPeriodic)[2] = _readNC->locallyPeriodic;
-  int (&globallyPeriodic)[2] = _readNC->globallyPeriodic;
   ScdParData& parData = _readNC->parData;
 
   Range tmp_range;
@@ -406,7 +851,7 @@ ErrorCode ScdNCHelper::create_mesh(ScdInterface* scdi, const FileOptions& opts,
   int di = gDims[3] - gDims[0] + 1;
   int dj = gDims[4] - gDims[1] + 1;
   assert(dil == (int)ilVals.size() && djl == (int)jlVals.size() &&
-      (-1 == lDims[2] || lDims[5]-lDims[2]+1 == (int)klVals.size()));
+      (-1 == lDims[2] || lDims[5]-lDims[2] + 1 == (int)levVals.size()));
 #define INDEX(i, j, k) ()
   for (kl = lDims[2]; kl <= lDims[5]; kl++) {
     k = kl - lDims[2];
@@ -417,7 +862,7 @@ ErrorCode ScdNCHelper::create_mesh(ScdInterface* scdi, const FileOptions& opts,
         unsigned int pos = i + j * dil + k * dil * djl;
         xc[pos] = ilVals[i];
         yc[pos] = jlVals[j];
-        zc[pos] = (-1 == lDims[2] ? 0.0 : klVals[k]);
+        zc[pos] = (-1 == lDims[2] ? 0.0 : levVals[k]);
         itmp = (!locallyPeriodic[0] && globallyPeriodic[0] && il == gDims[3] ? gDims[0] : il);
         *gid_data = (-1 != kl ? kl * di * dj : 0) + jl * di + itmp + 1;
         gid_data++;
@@ -468,7 +913,7 @@ ErrorCode ScdNCHelper::read_variables(EntityHandle file_set, std::vector<std::st
   ERRORR(rval, "Trouble setting up read variable.");
 
   // Create COORDS tag for quads
-  rval = _readNC->create_quad_coordinate_tag(file_set);
+  rval = create_quad_coordinate_tag(file_set);
   ERRORR(rval, "Trouble creating coordinate tags to entities quads");
 
   if (!vsetdatas.empty()) {
@@ -488,14 +933,6 @@ ErrorCode ScdNCHelper::read_scd_variable_setup(std::vector<std::string>& var_nam
                                                std::vector<ReadNC::VarData>& vdatas, std::vector<ReadNC::VarData>& vsetdatas)
 {
   std::map<std::string, ReadNC::VarData>& varInfo = _readNC->varInfo;
-  int& tMin = _readNC->tMin;
-  int& tMax = _readNC->tMax;
-  int& iDim = _readNC->iDim;
-  int& jDim = _readNC->jDim;
-  int& tDim = _readNC->tDim;
-  int& iCDim = _readNC->iCDim;
-  int& jCDim = _readNC->jCDim;
-
   std::map<std::string, ReadNC::VarData>::iterator mit;
 
   // If empty read them all
@@ -536,9 +973,9 @@ ErrorCode ScdNCHelper::read_scd_variable_setup(std::vector<std::string>& var_nam
     }
   }
 
-  if (tstep_nums.empty() && -1 != tMin) {
+  if (tstep_nums.empty() && nTimeSteps > 0) {
     // No timesteps input, get them all
-    for (int i = tMin; i <= tMax; i++)
+    for (int i = 0; i < nTimeSteps; i++)
       tstep_nums.push_back(i);
   }
   if (!tstep_nums.empty()) {
@@ -571,16 +1008,9 @@ ErrorCode ScdNCHelper::read_scd_variable_setup(std::vector<std::string>& var_nam
 ErrorCode ScdNCHelper::read_scd_variable_to_nonset_allocate(EntityHandle file_set, std::vector<ReadNC::VarData>& vdatas, std::vector<int>& tstep_nums)
 {
   Interface*& mbImpl = _readNC->mbImpl;
-  std::vector<std::string>& dimNames = _readNC->dimNames;
   std::vector<int>& dimVals = _readNC->dimVals;
-  int (&lDims)[6] = _readNC->lDims;
-  int (&lCDims)[6] = _readNC->lCDims;
-  int& tDim = _readNC->tDim;
   DebugOutput& dbgOut = _readNC->dbgOut;
   bool& isParallel = _readNC->isParallel;
- #ifdef USE_MPI
-  ParallelComm*& myPcomm = _readNC->myPcomm;
-#endif
 
   ErrorCode rval = MB_SUCCESS;
 
@@ -606,8 +1036,8 @@ ErrorCode ScdNCHelper::read_scd_variable_to_nonset_allocate(EntityHandle file_se
 
 #ifdef USE_MPI
   moab::Range faces_owned;
-  if (isParallel)
-  {
+  if (isParallel) {
+    ParallelComm*& myPcomm = _readNC->myPcomm;
     rval = myPcomm->filter_pstatus(faces, PSTATUS_NOT_OWNED, PSTATUS_NOT, -1, &faces_owned);
     ERRORR(rval, "Trouble getting owned faces in set.");
   }
@@ -616,24 +1046,14 @@ ErrorCode ScdNCHelper::read_scd_variable_to_nonset_allocate(EntityHandle file_se
 #endif
 
   for (unsigned int i = 0; i < vdatas.size(); i++) {
+    vdatas[i].numLev = nLevels;
+
     for (unsigned int t = 0; t < tstep_nums.size(); t++) {
       dbgOut.tprintf(2, "Reading variable %s, time step %d\n", vdatas[i].varName.c_str(), tstep_nums[t]);
 
-      std::vector<std::string>::iterator vit;
-      int idx_lev = -1;
-      int idx_ilev = -1;
-      if ((vit = std::find(dimNames.begin(), dimNames.end(), "lev")) != dimNames.end())
-        idx_lev = vit - dimNames.begin();
-      if ((vit = std::find(dimNames.begin(), dimNames.end(), "ilev")) != dimNames.end())
-        idx_ilev = vit - dimNames.begin();
-      if (std::find(vdatas[i].varDims.begin(), vdatas[i].varDims.end(), idx_lev) != vdatas[i].varDims.end())
-        vdatas[i].numLev = dimVals[idx_lev];
-      else if (std::find(vdatas[i].varDims.begin(), vdatas[i].varDims.end(), idx_ilev) != vdatas[i].varDims.end())
-        vdatas[i].numLev = dimVals[idx_ilev];
-
       // Get the tag to read into
       if (!vdatas[i].varTags[t]) {
-        rval = _readNC->get_tag_to_nonset(vdatas[i], tstep_nums[t], vdatas[i].varTags[t], vdatas[i].numLev);
+        rval = get_tag_to_nonset(vdatas[i], tstep_nums[t], vdatas[i].varTags[t], vdatas[i].numLev);
         ERRORR(rval, "Trouble getting tag.");
       }
 
@@ -838,6 +1258,66 @@ ErrorCode ScdNCHelper::read_scd_variable_to_nonset(EntityHandle file_set, std::v
   return rval;
 }
 
+ErrorCode ScdNCHelper::create_quad_coordinate_tag(EntityHandle file_set) {
+  Interface*& mbImpl = _readNC->mbImpl;
+  bool& isParallel = _readNC->isParallel;
+
+  Range ents;
+  ErrorCode rval = mbImpl->get_entities_by_type(file_set, moab::MBQUAD, ents);
+  ERRORR(rval, "Trouble getting QUAD entity.");
+
+  std::size_t numOwnedEnts = 0;
+#ifdef USE_MPI
+  Range ents_owned;
+  if (isParallel) {
+    ParallelComm*& myPcomm = _readNC->myPcomm;
+    rval = myPcomm->filter_pstatus(ents, PSTATUS_NOT_OWNED, PSTATUS_NOT, -1, &ents_owned);
+    ERRORR(rval, "Trouble getting owned QUAD entity.");
+    numOwnedEnts = ents_owned.size();
+  }
+  else
+  {
+    numOwnedEnts = ents.size();
+    ents_owned = ents;
+  }
+#else
+  numOwnedEnts = ents.size();
+#endif
+
+  if (numOwnedEnts == 0)
+    return MB_SUCCESS;
+
+  assert(numOwnedEnts == ilCVals.size() * jlCVals.size());
+  std::vector<double> coords(numOwnedEnts * 3);
+  std::size_t pos = 0;
+  for (std::size_t j = 0; j != jlCVals.size(); ++j) {
+    for (std::size_t i = 0; i != ilCVals.size(); ++i) {
+      pos = j * ilCVals.size() * 3 + i * 3;
+      coords[pos] = ilCVals[i];
+      coords[pos + 1] = jlCVals[j];
+      coords[pos + 2] = 0.0;
+    }
+  }
+  std::string tag_name = "COORDS";
+  Tag tagh = 0;
+  rval = mbImpl->tag_get_handle(tag_name.c_str(), 3, MB_TYPE_DOUBLE, tagh, MB_TAG_DENSE | MB_TAG_CREAT);
+  ERRORR(rval, "Trouble creating COORDS tag.");
+
+  void *data;
+  int count;
+#ifdef USE_MPI
+  rval = mbImpl->tag_iterate(tagh, ents_owned.begin(), ents_owned.end(), count, data);
+#else
+  rval = mbImpl->tag_iterate(tagh, ents.begin(), ents.end(), count, data);
+#endif
+  ERRORR(rval, "Failed to get COORDS tag iterator.");
+  assert(count == (int)numOwnedEnts);
+  double* quad_data = (double*) data;
+  std::copy(coords.begin(), coords.end(), quad_data);
+
+  return MB_SUCCESS;
+}
+
 ErrorCode UcdNCHelper::read_variables(EntityHandle file_set, std::vector<std::string>& var_names, std::vector<int>& tstep_nums)
 {
   std::vector<ReadNC::VarData> vdatas;

diff --git a/src/io/NCHelper.hpp b/src/io/NCHelper.hpp
index f59663e..83fcec1 100644
--- a/src/io/NCHelper.hpp
+++ b/src/io/NCHelper.hpp
@@ -17,7 +17,8 @@ namespace moab {
 class NCHelper
 {
 public:
-  NCHelper(ReadNC* readNC, int fileId) : _readNC(readNC), _fileId(fileId) {}
+  NCHelper(ReadNC* readNC, int fileId) :_readNC(readNC), _fileId(fileId),
+  nTimeSteps(0), nLevels(1), tDim(-1), levDim(-1) {}
   virtual ~NCHelper() {}
 
   //! Get appropriate helper instance for ReadNC class
@@ -30,6 +31,10 @@ public:
   virtual ErrorCode read_variables(EntityHandle file_set, std::vector<std::string>& var_names, std::vector<int>& tstep_nums) = 0;
   virtual std::string get_mesh_type_name() = 0;
 
+  //! Create NC conventional tags
+  ErrorCode create_conventional_tags(ScdInterface* scdi, EntityHandle file_set,
+                                     const std::vector<int>& tstep_nums);
+
 protected:
   //! Read set variables, common to scd mesh and ucd mesh
   ErrorCode read_variable_to_set(EntityHandle file_set, std::vector<ReadNC::VarData>& vdatas, std::vector<int>& tstep_nums);
@@ -37,20 +42,62 @@ protected:
   //! Convert variables in place
   ErrorCode convert_variable(ReadNC::VarData& var_data, int tstep_num);
 
+  ErrorCode read_coordinate(const char* var_name, int lmin, int lmax,
+                            std::vector<double>& cvals);
+
+  ErrorCode get_tag_to_set(ReadNC::VarData& var_data, int tstep_num, Tag& tagh);
+
+  ErrorCode get_tag_to_nonset(ReadNC::VarData& var_data, int tstep_num, Tag& tagh, int num_lev);
+
+  //! Create a character string attString of attMap.  with '\0'
+  //! terminating each attribute name, ';' separating the data type
+  //! and value, and ';' separating one name/data type/value from
+  //! the next'.  attLen stores the end position for each name/data
+  //! type/ value.
+  ErrorCode create_attrib_string(const std::map<std::string, ReadNC::AttData>& attMap,
+                                 std::string& attString,
+                                 std::vector<int>& attLen);
+
+  //! Init info for dimensions that don't have corresponding
+  //! coordinate variables - this info is used for creating tags
+  void init_dims_with_no_cvars_info();
+
 private:
   //! Used by read_variable_to_set()
   ErrorCode read_variable_to_set_allocate(std::vector<ReadNC::VarData>& vdatas, std::vector<int>& tstep_nums);
 
 protected:
   ReadNC* _readNC;
+
   int _fileId;
+
+  //! Dimensions of time and level
+  int nTimeSteps, nLevels;
+
+  //! Values for time and level
+  std::vector<double> tVals, levVals;
+
+  //! Dimension numbers for time and level
+  int tDim, levDim;
 };
 
 //! Child helper class for scd mesh, e.g. CAM_EL or CAM_FV
 class ScdNCHelper : public NCHelper
 {
 public:
-  ScdNCHelper(ReadNC* readNC, int fileId) : NCHelper(readNC, fileId) {}
+  ScdNCHelper(ReadNC* readNC, int fileId) : NCHelper(readNC, fileId),
+  iDim(-1), jDim(-1), iCDim(-1), jCDim(-1)
+  {
+    for (unsigned int i = 0; i < 6; i++) {
+      gDims[i] = -1;
+      lDims[i] = -1;
+      gCDims[i] = -1;
+      lCDims[i] = -1;
+    }
+
+    locallyPeriodic[0] = locallyPeriodic[1] = 0;
+    globallyPeriodic[0] = globallyPeriodic[1] = 0;
+  }
   virtual ~ScdNCHelper() {}
 
 private:
@@ -73,6 +120,9 @@ private:
   ErrorCode read_scd_variable_to_nonset(EntityHandle file_set, std::vector<ReadNC::VarData>& vdatas,
                                         std::vector<int>& tstep_nums);
 
+  //! Create COORDS tag for quads coordinate
+  ErrorCode create_quad_coordinate_tag(EntityHandle file_set);
+
   template <typename T> ErrorCode kji_to_jik(size_t ni, size_t nj, size_t nk, void* dest, T* source)
   {
     size_t nik = ni * nk, nij = ni * nj;
@@ -83,6 +133,37 @@ private:
           tmp_data[j*nik + i*nk + k] = source[k*nij + j*ni + i];
     return MB_SUCCESS;
   }
+
+protected:
+  //! Dimensions of global grid in file
+  int gDims[6];
+
+  //! Dimensions of my local part of grid
+  int lDims[6];
+
+  //! Center dimensions of global grid in file
+  int gCDims[6];
+
+  //! Center dimensions of my local part of grid
+  int lCDims[6];
+
+  //! Values for i/j
+  std::vector<double> ilVals, jlVals;
+
+  //! Center values for i/j
+  std::vector<double> ilCVals, jlCVals;
+
+  //! Dimension numbers for i/j
+  int iDim, jDim;
+
+  //! Center dimension numbers for i/j
+  int iCDim, jCDim;
+
+  //! Whether mesh is locally periodic in i or j
+  int locallyPeriodic[2];
+
+  //! Whether mesh is globally periodic in i or j
+  int globallyPeriodic[2];
 };
 
 //! Child helper class for ucd mesh, e.g. CAM_SE (HOMME) or MPAS
@@ -90,9 +171,9 @@ class UcdNCHelper : public NCHelper
 {
 public:
   UcdNCHelper(ReadNC* readNC, int fileId) : NCHelper(readNC, fileId),
-  cDim(-1), eDim(-1), vDim(-1), levDim(-1),
   nCells(0), nEdges(0), nVertices(0),
-  nLocalCells(0), nLocalEdges(0), nLocalVertices(0) {}
+  nLocalCells(0), nLocalEdges(0), nLocalVertices(0),
+  cDim(-1), eDim(-1), vDim(-1) {}
   virtual ~UcdNCHelper() {}
 
 private:
@@ -139,20 +220,23 @@ protected:
     return MB_SUCCESS;
   }
 
-  //! Dimension numbers for nCells, nEdges, nVertices, nLevels
-  int cDim, eDim, vDim, levDim;
-
-  //! Coordinate values for vertices
-  std::vector<double> xVertVals, yVertVals, zVertVals;
-
+  //! Dimensions of global grid in file
   int nCells;
   int nEdges;
   int nVertices;
 
+  //! Dimensions of my local part of grid
   int nLocalCells;
   int nLocalEdges;
   int nLocalVertices;
 
+  //! Coordinate values for vertices
+  std::vector<double> xVertVals, yVertVals, zVertVals;
+
+  //! Dimension numbers for nCells, nEdges and nVertices
+  int cDim, eDim, vDim;
+
+  //! Local global ID for cells, edges and vertices
   Range localGidCells, localGidEdges, localGidVerts;
 };
 

diff --git a/src/io/NCHelperEuler.cpp b/src/io/NCHelperEuler.cpp
index 7336fa9..f0489a7 100644
--- a/src/io/NCHelperEuler.cpp
+++ b/src/io/NCHelperEuler.cpp
@@ -54,78 +54,53 @@ ErrorCode NCHelperEuler::init_mesh_vals(const FileOptions& opts, EntityHandle fi
   Interface*& mbImpl = _readNC->mbImpl;
   std::vector<std::string>& dimNames = _readNC->dimNames;
   std::vector<int>& dimVals = _readNC->dimVals;
-  std::string& iName = _readNC->iName;
-  std::string& jName = _readNC->jName;
-  std::string& tName = _readNC->tName;
-  std::string& iCName = _readNC->iCName;
-  std::string& jCName = _readNC->jCName;
   std::map<std::string, ReadNC::VarData>& varInfo = _readNC->varInfo;
-  int& tMin = _readNC->tMin;
-  int& tMax = _readNC->tMax;
-  int (&gDims)[6] = _readNC->gDims;
-  int (&lDims)[6] = _readNC->lDims;
-  int (&lCDims)[6] = _readNC->lCDims;
-  int (&gCDims)[6] = _readNC->gCDims;
-  std::vector<double>& ilVals = _readNC->ilVals;
-  std::vector<double>& jlVals = _readNC->jlVals;
-  std::vector<double>& tVals = _readNC->tVals;
-  std::vector<double>& ilCVals = _readNC->ilCVals;
-  std::vector<double>& jlCVals = _readNC->jlCVals;
-  int& tDim = _readNC->tDim;
-  int& iCDim = _readNC->iCDim;
-  int& jCDim = _readNC->jCDim;
   DebugOutput& dbgOut = _readNC->dbgOut;
   bool& isParallel = _readNC->isParallel;
   int& partMethod = _readNC->partMethod;
-  int (&locallyPeriodic)[2] = _readNC->locallyPeriodic;
-  int (&globallyPeriodic)[2] = _readNC->globallyPeriodic;
   ScdParData& parData = _readNC->parData;
 #ifdef USE_MPI
   ParallelComm*& myPcomm = _readNC->myPcomm;
 #endif
 
-  // look for names of center i/j dimensions
+  // Look for names of center i/j dimensions
   std::vector<std::string>::iterator vit;
   unsigned int idx;
-  iCName = std::string("lon");
-  iName = std::string("slon");
-  if ((vit = std::find(dimNames.begin(), dimNames.end(), iCName.c_str())) != dimNames.end())
+  if ((vit = std::find(dimNames.begin(), dimNames.end(), "lon")) != dimNames.end())
     idx = vit - dimNames.begin();
   else {
-    ERRORR(MB_FAILURE, "Couldn't find center i variable.");
+    ERRORR(MB_FAILURE, "Couldn't find 'lon' dimension.");
   }
   iCDim = idx;
 
-  // decide on i periodicity using math for now
+  // Decide on i periodicity using math for now
   std::vector<double> tilVals(dimVals[idx]);
-  ErrorCode rval = _readNC->read_coordinate(iCName.c_str(), 0, dimVals[idx] - 1, tilVals);
-  ERRORR(rval, "Trouble reading lon variable.");
+  ErrorCode rval = read_coordinate("lon", 0, dimVals[idx] - 1, tilVals);
+  ERRORR(rval, "Trouble reading 'lon' variable.");
   if (std::fabs(2 * (*(tilVals.rbegin())) - *(tilVals.rbegin() + 1) - 360) < 0.001)
     globallyPeriodic[0] = 1;
 
-  // now we can set gCDims and gDims for i
+  // Now we can set gCDims and gDims for i
   gCDims[0] = 0;
   gDims[0] = 0;
-  gCDims[3] = dimVals[idx] - 1; // these are stored directly in file
-  gDims[3] = gCDims[3] + (globallyPeriodic[0] ? 0 : 1); // only if not periodic is vertex param max > elem param max
+  gCDims[3] = dimVals[idx] - 1; // These are stored directly in file
+  gDims[3] = gCDims[3] + (globallyPeriodic[0] ? 0 : 1); // Only if not periodic is vertex param max > elem param max
 
-  // now j
-  jCName = std::string("lat");
-  jName = std::string("slat");
-  if ((vit = std::find(dimNames.begin(), dimNames.end(), jCName.c_str())) != dimNames.end())
+  // Now j
+  if ((vit = std::find(dimNames.begin(), dimNames.end(), "lat")) != dimNames.end())
     idx = vit - dimNames.begin();
   else {
-    ERRORR(MB_FAILURE, "Couldn't find center j variable.");
+    ERRORR(MB_FAILURE, "Couldn't find 'lat' dimension.");
   }
   jCDim = idx;
 
-  // for Eul models, will always be non-periodic in j
+  // For Eul models, will always be non-periodic in j
   gCDims[1] = 0;
   gDims[1] = 0;
   gCDims[4] = dimVals[idx] - 1;
   gDims[4] = gCDims[4] + 1;
 
-  // try a truly 2d mesh
+  // Try a truly 2D mesh
   gDims[2] = -1;
   gDims[5] = -1;
 
@@ -135,14 +110,23 @@ ErrorCode NCHelperEuler::init_mesh_vals(const FileOptions& opts, EntityHandle fi
   else if ((vit = std::find(dimNames.begin(), dimNames.end(), "t")) != dimNames.end())
     idx = vit - dimNames.begin();
   else {
-    ERRORR(MB_FAILURE, "Couldn't find time dimension.");
+    ERRORR(MB_FAILURE, "Couldn't find 'time' or 't' dimension.");
   }
   tDim = idx;
-  tMax = dimVals[idx] - 1;
-  tMin = 0;
-  tName = dimNames[idx];
+  nTimeSteps = dimVals[idx];
 
-  // parse options to get subset
+  // Look for level dimension
+  if ((vit = std::find(dimNames.begin(), dimNames.end(), "lev")) != dimNames.end())
+    idx = vit - dimNames.begin();
+  else if ((vit = std::find(dimNames.begin(), dimNames.end(), "ilev")) != dimNames.end())
+    idx = vit - dimNames.begin();
+  else {
+    ERRORR(MB_FAILURE, "Couldn't find 'lev' or 'ilev' dimension.");
+  }
+  levDim = idx;
+  nLevels = dimVals[idx];
+
+  // Parse options to get subset
   if (isParallel) {
 #ifdef USE_MPI
     for (int i = 0; i < 6; i++)
@@ -178,16 +162,16 @@ ErrorCode NCHelperEuler::init_mesh_vals(const FileOptions& opts, EntityHandle fi
   opts.get_int_option("JMIN", lDims[1]);
   opts.get_int_option("JMAX", lDims[4]);
 
-  // now get actual coordinate values for vertices and cell centers; first resize
+  // Now get actual coordinate values for vertices and cell centers; first resize
   if (locallyPeriodic[0]) {
-    // if locally periodic, doesn't matter what global periodicity is, # vertex coords = # elem coords
+    // If locally periodic, doesn't matter what global periodicity is, # vertex coords = # elem coords
     ilVals.resize(lDims[3] - lDims[0] + 1);
     ilCVals.resize(lDims[3] - lDims[0] + 1);
     lCDims[3] = lDims[3];
   }
   else {
     if (!locallyPeriodic[0] && globallyPeriodic[0] && lDims[3] > gDims[3]) {
-      // globally periodic and I'm the last proc, get fewer vertex coords than vertices in i
+      // Globally periodic and I'm the last proc, get fewer vertex coords than vertices in i
       ilVals.resize(lDims[3] - lDims[0] + 1);
       ilCVals.resize(lDims[3] - lDims[0]);
       lCDims[3] = lDims[3] - 1;
@@ -200,62 +184,62 @@ ErrorCode NCHelperEuler::init_mesh_vals(const FileOptions& opts, EntityHandle fi
   }
 
   lCDims[0] = lDims[0];
-  lCDims[4] = lDims[4] - 1;
   lCDims[1] = lDims[1];
+  lCDims[4] = lDims[4] - 1;
 
   if (-1 != lDims[1]) {
     jlVals.resize(lDims[4] - lDims[1] + 1);
     jlCVals.resize(lCDims[4] - lCDims[1] + 1);
   }
 
-  if (-1 != tMin)
-    tVals.resize(tMax - tMin + 1);
+  if (nTimeSteps > 0)
+    tVals.resize(nTimeSteps);
 
-  // now read coord values
+  // Now read coord values
   std::map<std::string, ReadNC::VarData>::iterator vmit;
   if (!ilCVals.empty()) {
-    if ((vmit = varInfo.find(iCName)) != varInfo.end() && (*vmit).second.varDims.size() == 1) {
-      rval = _readNC->read_coordinate(iCName.c_str(), lDims[0], lDims[0] + ilCVals.size() - 1, ilCVals);
-      ERRORR(rval, "Trouble reading lon variable.");
+    if ((vmit = varInfo.find("lon")) != varInfo.end() && (*vmit).second.varDims.size() == 1) {
+      rval = read_coordinate("lon", lDims[0], lDims[0] + ilCVals.size() - 1, ilCVals);
+      ERRORR(rval, "Trouble reading 'lon' variable.");
     }
     else {
-      ERRORR(MB_FAILURE, "Couldn't find lon coordinate.");
+      ERRORR(MB_FAILURE, "Couldn't find 'lon' variable.");
     }
   }
 
   if (!jlCVals.empty()) {
-    if ((vmit = varInfo.find(jCName)) != varInfo.end() && (*vmit).second.varDims.size() == 1) {
-      rval = _readNC->read_coordinate(jCName.c_str(), lDims[1], lDims[1] + jlCVals.size() - 1, jlCVals);
-      ERRORR(rval, "Trouble reading lat variable.");
+    if ((vmit = varInfo.find("lat")) != varInfo.end() && (*vmit).second.varDims.size() == 1) {
+      rval = read_coordinate("lat", lDims[1], lDims[1] + jlCVals.size() - 1, jlCVals);
+      ERRORR(rval, "Trouble reading 'lat' variable.");
     }
     else {
-      ERRORR(MB_FAILURE, "Couldn't find lat coordinate.");
+      ERRORR(MB_FAILURE, "Couldn't find 'lat' variable.");
     }
   }
 
   if (lDims[0] != -1) {
-    if ((vmit = varInfo.find(iCName)) != varInfo.end() && (*vmit).second.varDims.size() == 1) {
+    if ((vmit = varInfo.find("lon")) != varInfo.end() && (*vmit).second.varDims.size() == 1) {
       double dif = (ilCVals[1] - ilCVals[0]) / 2;
       std::size_t i;
       for (i = 0; i != ilCVals.size(); i++)
         ilVals[i] = ilCVals[i] - dif;
-      // the last one is needed only if not periodic
+      // The last one is needed only if not periodic
       if (!locallyPeriodic[0])
         ilVals[i] = ilCVals[i - 1] + dif;
     }
     else {
-      ERRORR(MB_FAILURE, "Couldn't find x coordinate.");
+      ERRORR(MB_FAILURE, "Couldn't find 'lon' variable.");
     }
   }
 
   if (lDims[1] != -1) {
-    if ((vmit = varInfo.find(jCName)) != varInfo.end() && (*vmit).second.varDims.size() == 1) {
+    if ((vmit = varInfo.find("lat")) != varInfo.end() && (*vmit).second.varDims.size() == 1) {
       if (!isParallel || ((gDims[4] - gDims[1]) == (lDims[4] - lDims[1]))) {
         std::string gwName("gw");
         std::vector<double> gwVals(lDims[4] - lDims[1] - 1);
-        rval = _readNC->read_coordinate(gwName.c_str(), lDims[1], lDims[4] - 2, gwVals);
-        ERRORR(rval, "Trouble reading gw variable.");
-        // copy the correct piece
+        rval = read_coordinate(gwName.c_str(), lDims[1], lDims[4] - 2, gwVals);
+        ERRORR(rval, "Trouble reading 'gw' variable.");
+        // Copy the correct piece
         jlVals[0] = -(M_PI / 2) * 180 / M_PI;
         unsigned int i = 0;
         double gwSum = -1;
@@ -263,7 +247,7 @@ ErrorCode NCHelperEuler::init_mesh_vals(const FileOptions& opts, EntityHandle fi
           gwSum = gwSum + gwVals[i - 1];
           jlVals[i] = std::asin(gwSum) * 180 / M_PI;
         }
-        jlVals[i] = 90.0; // using value of i after loop exits.
+        jlVals[i] = 90.0; // Using value of i after loop exits.
       }
       else {
         std::string gwName("gw");
@@ -272,9 +256,9 @@ ErrorCode NCHelperEuler::init_mesh_vals(const FileOptions& opts, EntityHandle fi
         // If this is the first row
         if (lDims[1] == gDims[1]) {
           std::vector<double> gwVals(lDims[4]);
-          rval = _readNC->read_coordinate(gwName.c_str(), 0, lDims[4] - 1, gwVals);
-          ERRORR(rval, "Trouble reading gw variable.");
-          // copy the correct piece
+          rval = read_coordinate(gwName.c_str(), 0, lDims[4] - 1, gwVals);
+          ERRORR(rval, "Trouble reading 'gw' variable.");
+          // Copy the correct piece
           jlVals[0] = -(M_PI / 2) * 180 / M_PI;
           gwSum = -1;
           for (std::size_t i = 1; i != jlVals.size(); i++) {
@@ -282,11 +266,11 @@ ErrorCode NCHelperEuler::init_mesh_vals(const FileOptions& opts, EntityHandle fi
             jlVals[i] = std::asin(gwSum) * 180 / M_PI;
           }
         }
-        // or if it's the last row
+        // Or if it's the last row
         else if (lDims[4] == gDims[4]) {
           std::vector<double> gwVals(lDims[4] - 1);
-          rval = _readNC->read_coordinate(gwName.c_str(), 0, lDims[4] - 2, gwVals);
-          ERRORR(rval, "Trouble reading gw variable.");
+          rval = read_coordinate(gwName.c_str(), 0, lDims[4] - 2, gwVals);
+          ERRORR(rval, "Trouble reading 'gw' variable.");
           // copy the correct piece
           gwSum = -1;
           for (int j = 0; j != lDims[1] - 1; j++) {
@@ -297,15 +281,15 @@ ErrorCode NCHelperEuler::init_mesh_vals(const FileOptions& opts, EntityHandle fi
             gwSum = gwSum + gwVals[lDims[1] - 1 + i];
             jlVals[i] = std::asin(gwSum) * 180 / M_PI;
           }
-          jlVals[i] = 90.0; // using value of i after loop exits.
+          jlVals[i] = 90.0; // Using value of i after loop exits.
         }
-        // it's in the middle
+        // It's in the middle
         else {
           int start = lDims[1] - 1;
           int end = lDims[4] - 1;
           std::vector<double> gwVals(end);
-          rval = _readNC->read_coordinate(gwName.c_str(), 0, end - 1, gwVals);
-          ERRORR(rval, "Trouble reading gw variable.");
+          rval = read_coordinate(gwName.c_str(), 0, end - 1, gwVals);
+          ERRORR(rval, "Trouble reading 'gw' variable.");
           gwSum = -1;
           for (int j = 0; j != start - 1; j++) {
             gwSum = gwSum + gwVals[j];
@@ -319,19 +303,23 @@ ErrorCode NCHelperEuler::init_mesh_vals(const FileOptions& opts, EntityHandle fi
       }
     }
     else {
-      ERRORR(MB_FAILURE, "Couldn't find y coordinate.");
+      ERRORR(MB_FAILURE, "Couldn't find 'lat' variable.");
     }
   }
 
   // Store time coordinate values in tVals
-  if (tMin != -1) {
-    if ((vmit = varInfo.find(tName)) != varInfo.end() && (*vmit).second.varDims.size() == 1) {
-      rval = _readNC->read_coordinate(tName.c_str(), tMin, tMax, tVals);
-      ERRORR(rval, "Trouble reading time variable.");
+  if (nTimeSteps > 0) {
+    if ((vmit = varInfo.find("time")) != varInfo.end() && (*vmit).second.varDims.size() == 1) {
+      rval = read_coordinate("time", 0, nTimeSteps - 1, tVals);
+      ERRORR(rval, "Trouble reading 'time' variable.");
+    }
+    else if ((vmit = varInfo.find("t")) != varInfo.end() && (*vmit).second.varDims.size() == 1) {
+      rval = read_coordinate("t", 0, nTimeSteps - 1, tVals);
+      ERRORR(rval, "Trouble reading 't' variable.");
     }
     else {
       // If expected time variable is not available, set dummy time coordinate values to tVals
-      for (int t = tMin; t <= tMax; t++)
+      for (int t = 0; t < nTimeSteps; t++)
         tVals.push_back((double)t);
     }
   }
@@ -340,7 +328,7 @@ ErrorCode NCHelperEuler::init_mesh_vals(const FileOptions& opts, EntityHandle fi
   dbgOut.tprintf(1, "%d elements, %d vertices\n", (lDims[3] - lDims[0]) * (lDims[4] - lDims[1]), (lDims[3] - lDims[0] + 1)
       * (lDims[4] - lDims[1] + 1));
 
-  // determine the entity location type of a variable
+  // Determine the entity location type of a variable
   std::map<std::string, ReadNC::VarData>::iterator mit;
   for (mit = varInfo.begin(); mit != varInfo.end(); ++mit) {
     ReadNC::VarData& vd = (*mit).second;
@@ -360,7 +348,7 @@ ErrorCode NCHelperEuler::init_mesh_vals(const FileOptions& opts, EntityHandle fi
   int val_len = 0;
   for (unsigned int i = 0; i != ijdimNames.size(); i++) {
     tag_name = ijdimNames[i];
-    void * val = NULL;
+    void* val = NULL;
     if (tag_name == "__slon") {
       val = &ilVals[0];
       val_len = ilVals.size();
@@ -380,7 +368,7 @@ ErrorCode NCHelperEuler::init_mesh_vals(const FileOptions& opts, EntityHandle fi
     Tag tagh = 0;
     DataType data_type;
 
-    // assume all has same data type as lon
+    // Assume all has same data type as lon
     switch (varInfo["lon"].varDataType) {
       case NC_BYTE:
       case NC_CHAR:
@@ -469,9 +457,8 @@ ErrorCode NCHelperEuler::init_mesh_vals(const FileOptions& opts, EntityHandle fi
       dbgOut.tprintf(2, "Tag created for variable %s\n", tag_name.c_str());
   }
 
-  // hack: create dummy tags, if needed, for variables like nbnd
-  // with no corresponding variables
-  _readNC->init_dims_with_no_cvars_info();
+  // Hack: create dummy tags, if needed, for variables with no corresponding variables
+  init_dims_with_no_cvars_info();
 
   return MB_SUCCESS;
 }

diff --git a/src/io/NCHelperFV.cpp b/src/io/NCHelperFV.cpp
index cb6229e..48d5f4b 100644
--- a/src/io/NCHelperFV.cpp
+++ b/src/io/NCHelperFV.cpp
@@ -47,33 +47,10 @@ ErrorCode NCHelperFV::init_mesh_vals(const FileOptions& opts, EntityHandle file_
   Interface*& mbImpl = _readNC->mbImpl;
   std::vector<std::string>& dimNames = _readNC->dimNames;
   std::vector<int>& dimVals = _readNC->dimVals;
-  std::string& iName = _readNC->iName;
-  std::string& jName = _readNC->jName;
-  std::string& tName = _readNC->tName;
-  std::string& iCName = _readNC->iCName;
-  std::string& jCName = _readNC->jCName;
   std::map<std::string, ReadNC::VarData>& varInfo = _readNC->varInfo;
-  int& tMin = _readNC->tMin;
-  int& tMax = _readNC->tMax;
-  int (&gDims)[6] = _readNC->gDims;
-  int (&lDims)[6] = _readNC->lDims;
-  int (&gCDims)[6] = _readNC->gCDims;
-  int (&lCDims)[6] = _readNC->lCDims;
-  std::vector<double>& ilVals = _readNC->ilVals;
-  std::vector<double>& jlVals = _readNC->jlVals;
-  std::vector<double>& tVals = _readNC->tVals;
-  std::vector<double>& ilCVals = _readNC->ilCVals;
-  std::vector<double>& jlCVals = _readNC->jlCVals;
-  int& iDim = _readNC->iDim;
-  int& jDim = _readNC->jDim;
-  int& tDim = _readNC->tDim;
-  int& iCDim = _readNC->iCDim;
-  int& jCDim = _readNC->jCDim;
   DebugOutput& dbgOut = _readNC->dbgOut;
   bool& isParallel = _readNC->isParallel;
   int& partMethod = _readNC->partMethod;
-  int (&locallyPeriodic)[2] = _readNC->locallyPeriodic;
-  int (&globallyPeriodic)[2] = _readNC->globallyPeriodic;
   ScdParData& parData = _readNC->parData;
 #ifdef USE_MPI
   ParallelComm*& myPcomm = _readNC->myPcomm;
@@ -84,39 +61,35 @@ ErrorCode NCHelperFV::init_mesh_vals(const FileOptions& opts, EntityHandle file_
   if ((vit = std::find(dimNames.begin(), dimNames.end(), "slon")) != dimNames.end())
     idx = vit - dimNames.begin();
   else {
-    ERRORR(MB_FAILURE, "Couldn't find slon variable.");
+    ERRORR(MB_FAILURE, "Couldn't find 'slon' variable.");
   }
-
   iDim = idx;
   gDims[3] = dimVals[idx] - 1;
   gDims[0] = 0;
-  iName = dimNames[idx];
 
   if ((vit = std::find(dimNames.begin(), dimNames.end(), "slat")) != dimNames.end())
     idx = vit - dimNames.begin();
   else {
-    ERRORR(MB_FAILURE, "Couldn't find slat variable.");
+    ERRORR(MB_FAILURE, "Couldn't find 'slat' variable.");
   }
   jDim = idx;
-  gDims[4] = dimVals[idx] - 1 + 2; // add 2 for the pole points
+  gDims[4] = dimVals[idx] - 1 + 2; // Add 2 for the pole points
   gDims[1] = 0;
-  jName = dimNames[idx];
 
-  // look for names of center i/j dimensions
+  // Look for names of center i/j dimensions
   if ((vit = std::find(dimNames.begin(), dimNames.end(), "lon")) != dimNames.end())
     idx = vit - dimNames.begin();
   else {
-    ERRORR(MB_FAILURE, "Couldn't find lon variable.");
+    ERRORR(MB_FAILURE, "Couldn't find 'lon' variable.");
   }
   iCDim = idx;
   gCDims[3] = dimVals[idx] - 1;
   gCDims[0] = 0;
-  iCName = dimNames[idx];
 
-  // check and set globallyPeriodic[0]
+  // Check and set globallyPeriodic[0]
   std::vector<double> til_vals(2);
-  ErrorCode rval = _readNC->read_coordinate(iCName.c_str(), dimVals[idx] - 2, dimVals[idx] - 1, til_vals);
-  ERRORR(rval, "Trouble reading slon variable.");
+  ErrorCode rval = read_coordinate("lon", dimVals[idx] - 2, dimVals[idx] - 1, til_vals);
+  ERRORR(rval, "Trouble reading 'lon' variable.");
   if (std::fabs(2 * til_vals[1] - til_vals[0] - 360) < 0.001)
     globallyPeriodic[0] = 1;
   if (globallyPeriodic[0])
@@ -125,7 +98,7 @@ ErrorCode NCHelperFV::init_mesh_vals(const FileOptions& opts, EntityHandle file_
     assert("Number of vertices should equal to number of edges plus one" && gDims[3] == gCDims[3] + 1);
 
 #ifdef USE_MPI
-  // if serial, use a locally-periodic representation only if local mesh is periodic, otherwise don't
+  // If serial, use a locally-periodic representation only if local mesh is periodic, otherwise don't
   if ((isParallel && myPcomm->proc_config().proc_size() == 1) && globallyPeriodic[0])
     locallyPeriodic[0] = 1;
 #else
@@ -136,25 +109,35 @@ ErrorCode NCHelperFV::init_mesh_vals(const FileOptions& opts, EntityHandle file_
   if ((vit = std::find(dimNames.begin(), dimNames.end(), "lat")) != dimNames.end())
     idx = vit - dimNames.begin();
   else {
-    ERRORR(MB_FAILURE, "Couldn't find lat variable.");
+    ERRORR(MB_FAILURE, "Couldn't find 'lat' variable.");
   }
   jCDim = idx;
   gCDims[4] = dimVals[idx] - 1;
   gCDims[1] = 0;
-  jCName = dimNames[idx];
 
   // Look for time dimension
   if ((vit = std::find(dimNames.begin(), dimNames.end(), "time")) != dimNames.end())
     idx = vit - dimNames.begin();
+  else if ((vit = std::find(dimNames.begin(), dimNames.end(), "t")) != dimNames.end())
+    idx = vit - dimNames.begin();
   else {
-    ERRORR(MB_FAILURE, "Couldn't find time dimension.");
+    ERRORR(MB_FAILURE, "Couldn't find 'time' or 't' dimension.");
   }
   tDim = idx;
-  tMax = dimVals[idx] - 1;
-  tMin = 0;
-  tName = dimNames[idx];
+  nTimeSteps = dimVals[idx];
+
+  // Get number of levels
+  if ((vit = std::find(dimNames.begin(), dimNames.end(), "lev")) != dimNames.end())
+    idx = vit - dimNames.begin();
+  else if ((vit = std::find(dimNames.begin(), dimNames.end(), "ilev")) != dimNames.end())
+    idx = vit - dimNames.begin();
+  else {
+    ERRORR(MB_FAILURE, "Couldn't find 'lev' or 'ilev' dimension.");
+  }
+  levDim = idx;
+  nLevels = dimVals[idx];
 
-  // parse options to get subset
+  // Parse options to get subset
   if (isParallel) {
 #ifdef USE_MPI
     for (int i = 0; i < 6; i++)
@@ -189,16 +172,16 @@ ErrorCode NCHelperFV::init_mesh_vals(const FileOptions& opts, EntityHandle file_
   opts.get_int_option("JMIN", lDims[1]);
   opts.get_int_option("JMAX", lDims[4]);
 
-  // now get actual coordinate values for vertices and cell centers; first resize
+  // Now get actual coordinate values for vertices and cell centers; first resize
   if (locallyPeriodic[0]) {
-    // if locally periodic, doesn't matter what global periodicity is, # vertex coords = # elem coords
+    // If locally periodic, doesn't matter what global periodicity is, # vertex coords = # elem coords
     ilVals.resize(lDims[3] - lDims[0] + 1);
     ilCVals.resize(lDims[3] - lDims[0] + 1);
     lCDims[3] = lDims[3];
   }
   else {
     if (!locallyPeriodic[0] && globallyPeriodic[0] && lDims[3] > gDims[3]) {
-      // globally periodic and I'm the last proc, get fewer vertex coords than vertices in i
+      // Globally periodic and I'm the last proc, get fewer vertex coords than vertices in i
       ilVals.resize(lDims[3] - lDims[0] + 1);
       ilCVals.resize(lDims[3] - lDims[0]);
       lCDims[3] = lDims[3] - 1;
@@ -211,45 +194,45 @@ ErrorCode NCHelperFV::init_mesh_vals(const FileOptions& opts, EntityHandle file_
   }
 
   lCDims[0] = lDims[0];
-  lCDims[4] = lDims[4] - 1;
   lCDims[1] = lDims[1];
+  lCDims[4] = lDims[4] - 1;
 
   if (-1 != lDims[1]) {
     jlVals.resize(lDims[4] - lDims[1] + 1);
     jlCVals.resize(lCDims[4] - lCDims[1] + 1);
   }
 
-  if (-1 != tMin)
-    tVals.resize(tMax - tMin + 1);
+  if (nTimeSteps > 0)
+    tVals.resize(nTimeSteps);
 
   // ... then read actual values
   std::map<std::string, ReadNC::VarData>::iterator vmit;
   if (lCDims[0] != -1) {
-    if ((vmit = varInfo.find(iCName)) != varInfo.end() && (*vmit).second.varDims.size() == 1) {
-      rval = _readNC->read_coordinate(iCName.c_str(), lCDims[0], lCDims[3], ilCVals);
-      ERRORR(rval, "Trouble reading lon variable.");
+    if ((vmit = varInfo.find("lon")) != varInfo.end() && (*vmit).second.varDims.size() == 1) {
+      rval = read_coordinate("lon", lCDims[0], lCDims[3], ilCVals);
+      ERRORR(rval, "Trouble reading 'lon' variable.");
     }
     else {
-      ERRORR(MB_FAILURE, "Couldn't find lon coordinate.");
+      ERRORR(MB_FAILURE, "Couldn't find 'lon' variable.");
     }
   }
 
   if (lCDims[1] != -1) {
-    if ((vmit = varInfo.find(jCName)) != varInfo.end() && (*vmit).second.varDims.size() == 1) {
-      rval = _readNC->read_coordinate(jCName.c_str(), lCDims[1], lCDims[4], jlCVals);
-      ERRORR(rval, "Trouble reading lat variable.");
+    if ((vmit = varInfo.find("lat")) != varInfo.end() && (*vmit).second.varDims.size() == 1) {
+      rval = read_coordinate("lat", lCDims[1], lCDims[4], jlCVals);
+      ERRORR(rval, "Trouble reading 'lat' variable.");
     }
     else {
-      ERRORR(MB_FAILURE, "Couldn't find lat coordinate.");
+      ERRORR(MB_FAILURE, "Couldn't find 'lat' variable.");
     }
   }
 
   if (lDims[0] != -1) {
-    if ((vmit = varInfo.find(iName)) != varInfo.end() && (*vmit).second.varDims.size() == 1) {
-      // last column
+    if ((vmit = varInfo.find("slon")) != varInfo.end() && (*vmit).second.varDims.size() == 1) {
+      // Last column
       if (!locallyPeriodic[0] && globallyPeriodic[0] && lDims[3] > gDims[3]) {
         til_vals.resize(ilVals.size() - 1, 0.0);
-        rval = _readNC->read_coordinate(iName.c_str(), lDims[0], lDims[3] - 1, til_vals);
+        rval = read_coordinate("slon", lDims[0], lDims[3] - 1, til_vals);
         double dif = til_vals[1] - til_vals[0];
         std::size_t i;
         for (i = 0; i != til_vals.size(); i++)
@@ -257,72 +240,76 @@ ErrorCode NCHelperFV::init_mesh_vals(const FileOptions& opts, EntityHandle file_
         ilVals[i] = ilVals[i - 1] + dif;
       }
       else {
-        rval = _readNC->read_coordinate(iName.c_str(), lDims[0], lDims[3], ilVals);
-        ERRORR(rval, "Trouble reading x variable.");
+        rval = read_coordinate("slon", lDims[0], lDims[3], ilVals);
+        ERRORR(rval, "Trouble reading 'slon' variable.");
       }
     }
     else {
-      ERRORR(MB_FAILURE, "Couldn't find x coordinate.");
+      ERRORR(MB_FAILURE, "Couldn't find 'slon' variable.");
     }
   }
 
   if (lDims[1] != -1) {
-    if ((vmit = varInfo.find(jName)) != varInfo.end() && (*vmit).second.varDims.size() == 1) {
+    if ((vmit = varInfo.find("slat")) != varInfo.end() && (*vmit).second.varDims.size() == 1) {
       if (!isParallel || ((gDims[4] - gDims[1]) == (lDims[4] - lDims[1]))) {
         std::vector<double> dummyVar(lDims[4] - lDims[1] - 1);
-        rval = _readNC->read_coordinate(jName.c_str(), lDims[1], lDims[4] - 2, dummyVar);
-        ERRORR(rval, "Trouble reading y variable.");
-        // copy the correct piece
+        rval = read_coordinate("slat", lDims[1], lDims[4] - 2, dummyVar);
+        ERRORR(rval, "Trouble reading 'slat' variable.");
+        // Copy the correct piece
         jlVals[0] = -90.0;
         unsigned int i = 0;
         for (i = 1; i != dummyVar.size() + 1; i++)
           jlVals[i] = dummyVar[i - 1];
-        jlVals[i] = 90.0; // using value of i after loop exits.
+        jlVals[i] = 90.0; // Using value of i after loop exits.
       }
       else {
         // If this is the first row
-        // need to read one less then available and read it into a dummy var
+        // Need to read one less then available and read it into a dummy var
         if (lDims[1] == gDims[1]) {
           std::vector<double> dummyVar(lDims[4] - lDims[1]);
-          rval = _readNC->read_coordinate(jName.c_str(), lDims[1], lDims[4] - 1, dummyVar);
-          ERRORR(rval, "Trouble reading y variable.");
-          // copy the correct piece
+          rval = read_coordinate("slat", lDims[1], lDims[4] - 1, dummyVar);
+          ERRORR(rval, "Trouble reading 'slat' variable.");
+          // Copy the correct piece
           jlVals[0] = -90.0;
           for (int i = 1; i < lDims[4] + 1; i++)
             jlVals[i] = dummyVar[i - 1];
         }
-        // or if it's the last row
+        // Or if it's the last row
         else if (lDims[4] == gDims[4]) {
           std::vector<double> dummyVar(lDims[4] - lDims[1]);
-          rval = _readNC->read_coordinate(jName.c_str(), lDims[1] - 1, lDims[4] - 2, dummyVar);
-          ERRORR(rval, "Trouble reading y variable.");
-          // copy the correct piece
+          rval = read_coordinate("slat", lDims[1] - 1, lDims[4] - 2, dummyVar);
+          ERRORR(rval, "Trouble reading 'slat' variable.");
+          // Copy the correct piece
           std::size_t i = 0;
           for (i = 0; i != dummyVar.size(); i++)
             jlVals[i] = dummyVar[i];
-          jlVals[i] = 90.0; // using value of i after loop exits.
+          jlVals[i] = 90.0; // Using value of i after loop exits.
         }
-        // it's in the middle
+        // It's in the middle
         else {
-          rval = _readNC->read_coordinate(jCName.c_str(), lDims[1] - 1, lDims[4] - 1, jlVals);
-          ERRORR(rval, "Trouble reading y variable.");
+          rval = read_coordinate("slat", lDims[1] - 1, lDims[4] - 1, jlVals);
+          ERRORR(rval, "Trouble reading 'slat' variable.");
         }
       }
     }
     else {
-      ERRORR(MB_FAILURE, "Couldn't find y coordinate.");
+      ERRORR(MB_FAILURE, "Couldn't find 'slat' variable.");
     }
   }
 
   // Store time coordinate values in tVals
-  if (tMin != -1) {
-    if ((vmit = varInfo.find(tName)) != varInfo.end() && (*vmit).second.varDims.size() == 1) {
-      rval = _readNC->read_coordinate(tName.c_str(), tMin, tMax, tVals);
-      ERRORR(rval, "Trouble reading time variable.");
+  if (nTimeSteps > 0) {
+    if ((vmit = varInfo.find("time")) != varInfo.end() && (*vmit).second.varDims.size() == 1) {
+      rval = read_coordinate("time", 0, nTimeSteps - 1, tVals);
+      ERRORR(rval, "Trouble reading 'time' variable.");
+    }
+    else if ((vmit = varInfo.find("t")) != varInfo.end() && (*vmit).second.varDims.size() == 1) {
+      rval = read_coordinate("t", 0, nTimeSteps - 1, tVals);
+      ERRORR(rval, "Trouble reading 't' variable.");
     }
     else {
       // If expected time variable is not available, set dummy time coordinate values to tVals
-      for (int t = tMin; t <= tMax; t++)
+      for (int t = 0; t < nTimeSteps; t++)
         tVals.push_back((double)t);
     }
   }
@@ -331,7 +318,7 @@ ErrorCode NCHelperFV::init_mesh_vals(const FileOptions& opts, EntityHandle file_
   dbgOut.tprintf(1, "%d elements, %d vertices\n", (lDims[3] - lDims[0]) * (lDims[4] - lDims[1]), (lDims[3] - lDims[0] + 1)
       * (lDims[4] - lDims[1] + 1));
 
-  // determine the entity location type of a variable
+  // Determine the entity location type of a variable
   std::map<std::string, ReadNC::VarData>::iterator mit;
   for (mit = varInfo.begin(); mit != varInfo.end(); ++mit) {
     ReadNC::VarData& vd = (*mit).second;
@@ -357,7 +344,7 @@ ErrorCode NCHelperFV::init_mesh_vals(const FileOptions& opts, EntityHandle file_
   int val_len = 0;
   for (unsigned int i = 0; i != ijdimNames.size(); i++) {
     tag_name = ijdimNames[i];
-    void * val = NULL;
+    void* val = NULL;
     if (tag_name == "__slon") {
       val = &ilVals[0];
       val_len = ilVals.size();
@@ -377,7 +364,7 @@ ErrorCode NCHelperFV::init_mesh_vals(const FileOptions& opts, EntityHandle file_
     Tag tagh = 0;
     DataType data_type;
 
-    // assume all has same data type as lon
+    // Assume all has same data type as lon
     switch (varInfo["lon"].varDataType) {
       case NC_BYTE:
       case NC_CHAR:
@@ -466,9 +453,8 @@ ErrorCode NCHelperFV::init_mesh_vals(const FileOptions& opts, EntityHandle file_
       dbgOut.tprintf(2, "Tag created for variable %s\n", tag_name.c_str());
   }
 
-  // hack: create dummy tags, if needed, for dimensions like nbnd
-  // with no corresponding variables
-  _readNC->init_dims_with_no_cvars_info();
+  // Hack: create dummy tags, if needed, for dimensions with no corresponding variables
+  init_dims_with_no_cvars_info();
 
   return MB_SUCCESS;
 }

This diff is so big that we needed to truncate the remainder.

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