[MOAB-dev] commit/MOAB: danwu: Added two test cases to write_nc for CAM-FV. Fixed a few NC writer bugs to make them pass.

commits-noreply at bitbucket.org commits-noreply at bitbucket.org
Mon Apr 21 17:12:11 CDT 2014


1 new commit in MOAB:

https://bitbucket.org/fathomteam/moab/commits/37fe1cefab28/
Changeset:   37fe1cefab28
Branch:      ncwriter
User:        danwu
Date:        2014-04-22 00:11:49
Summary:     Added two test cases to write_nc for CAM-FV. Fixed a few NC writer bugs to make them pass.

Affected #:  2 files

diff --git a/src/io/NCWriteHelper.cpp b/src/io/NCWriteHelper.cpp
index aa69d0f..18c8a3e 100644
--- a/src/io/NCWriteHelper.cpp
+++ b/src/io/NCWriteHelper.cpp
@@ -68,7 +68,7 @@ ErrorCode NCWriteHelper::collect_variable_data(std::vector<std::string>& var_nam
       currentVarData.has_tsteps = true;
 
     currentVarData.numLev = 1;
-    if ((std::find(currentVarData.varDims.begin(), currentVarData.varDims.end(), tDim) != currentVarData.varDims.end()))
+    if ((std::find(currentVarData.varDims.begin(), currentVarData.varDims.end(), levDim) != currentVarData.varDims.end()))
       currentVarData.numLev = nLevels;
 
     dbgOut.tprintf(2, "    for variable %s varDims.size %d \n", varname.c_str(), (int)currentVarData.varDims.size());
@@ -82,6 +82,11 @@ ErrorCode NCWriteHelper::collect_variable_data(std::vector<std::string>& var_nam
       dbgOut.tprintf(2, "    for variable %s need dimension %s with length %d\n", varname.c_str(), dimName.c_str(), dimLens[currentVarData.varDims[j]]);
     }
 
+    // Process coordinate variables later
+    if (usedCoordinates.find(varname) != usedCoordinates.end())
+      continue;
+
+    // Process non-set variables with time steps
     if (currentVarData.has_tsteps) {
       int index = 0;
       // FIXME: Should use tstep_nums (from writing options) later
@@ -106,6 +111,7 @@ ErrorCode NCWriteHelper::collect_variable_data(std::vector<std::string>& var_nam
           currentVarData.varDataType = NC_INT;
       }
     }
+    // Process set variables that are not coordinate variables
     else {
       // Get the tag with varname
       Tag tag = 0;
@@ -126,7 +132,7 @@ ErrorCode NCWriteHelper::collect_variable_data(std::vector<std::string>& var_nam
       if (MB_TYPE_INTEGER == type)
         currentVarData.varDataType = NC_INT;
 
-      assert(currentVarData.memoryHogs.size() == 0); // Nothing so far
+      assert(0 == currentVarData.memoryHogs.size()); // Nothing so far
       currentVarData.memoryHogs.push_back((void*)data);
 
       if (currentVarData.varDims.empty()) {
@@ -135,14 +141,14 @@ ErrorCode NCWriteHelper::collect_variable_data(std::vector<std::string>& var_nam
         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]]);
-        }
+        assert(1 == currentVarData.varDims.size());
+        currentVarData.writeStarts.push_back(0);
+        currentVarData.writeCounts.push_back(dimLens[currentVarData.varDims[0]]);
       }
     }
   }
 
+  // Process coordinate variables
   // Check that for used coordinates we have found the tags
   for (std::set<std::string>::iterator setIt = usedCoordinates.begin();
       setIt != usedCoordinates.end(); ++setIt) {
@@ -212,6 +218,9 @@ ErrorCode NCWriteHelper::init_file(std::vector<std::string>& var_names)
   std::map<std::string, WriteNC::AttData>& globalAtts = _writeNC->globalAtts;
   DebugOutput& dbgOut = _writeNC->dbgOut;
 
+  int tDim_in_dimNames = tDim;
+  int levDim_in_dimNames = levDim;
+
   // 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();
@@ -236,6 +245,12 @@ ErrorCode NCWriteHelper::init_file(std::vector<std::string>& var_names)
 
     dbgOut.tprintf(2, "    for coordName %s dim id is %d \n", coordName.c_str(), (int)varCoordData.varDims[0]);
 
+    // Update tDim and levDim to actual dimension id
+    if (coordName == dimNames[tDim_in_dimNames])
+      tDim = varCoordData.varDims[0];
+    else if (coordName == dimNames[levDim_in_dimNames])
+      levDim = 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,
@@ -261,6 +276,10 @@ ErrorCode NCWriteHelper::init_file(std::vector<std::string>& var_names)
     if (vit == varInfo.end())
       ERRORR(MB_FAILURE, "Can't find variable requested.");
 
+    // Skip coordinate variables
+    if (usedCoordinates.find(var_names[i]) != usedCoordinates.end())
+      continue;
+
     WriteNC::VarData& variableData = vit->second;
     int numDims = (int)variableData.varDims.size();
     // The index is for dimNames; we need to find out the actual dimension id (from above)

diff --git a/test/io/write_nc.cpp b/test/io/write_nc.cpp
index 6f2c9af..6a1b0be 100644
--- a/test/io/write_nc.cpp
+++ b/test/io/write_nc.cpp
@@ -6,10 +6,12 @@ using namespace moab;
 
 #ifdef MESHDIR
 static const char example_eul[] = STRINGIFY(MESHDIR) "/io/camEul26x48x96.t3.nc";
+static const char example_fv[] = STRINGIFY(MESHDIR) "/io/fv26x46x72.t.3.nc";
 static const char example_homme[] = STRINGIFY(MESHDIR) "/io/homme26x3458.t.3.nc";
 static const char example_homme_mapping[] = STRINGIFY(MESHDIR) "/io/HommeMapping.nc";
 #else
 static const char example_eul[] = "/io/camEul26x48x96.t3.nc";
+static const char example_fv[] = "/io/fv26x46x72.t.3.nc";
 static const char example_homme[] = "/io/homme26x3458.t.3.nc";
 static const char example_homme_mapping[] = "/io/HommeMapping.nc";
 #endif
@@ -23,11 +25,16 @@ static const char example_homme_mapping[] = "/io/HommeMapping.nc";
 void test_eul_read_write_T();
 void test_eul_check_T();
 
+// CAM-FV
+void test_fv_read_write_T();
+void test_fv_check_T();
+
 // CAM-SE (HOMME)
 void test_homme_read_write_T();
 void test_homme_check_T();
 
 void get_eul_read_options(std::string& opts);
+void get_fv_read_options(std::string& opts);
 void get_homme_read_options(std::string& opts);
 
 int main(int argc, char* argv[])
@@ -44,6 +51,8 @@ int main(int argc, char* argv[])
 
   result += RUN_TEST(test_eul_read_write_T);
   result += RUN_TEST(test_eul_check_T);
+  result += RUN_TEST(test_fv_read_write_T);
+  result += RUN_TEST(test_fv_check_T);
   result += RUN_TEST(test_homme_read_write_T);
   result += RUN_TEST(test_homme_check_T);
 
@@ -194,6 +203,122 @@ void test_eul_check_T()
   }
 }
 
+// We also write coordinate variables slat and slon to the output file, so that
+// it can be recognized by NC reader later in test_fv_check_T()
+void test_fv_read_write_T()
+{
+  int procs = 1;
+#ifdef USE_MPI
+  MPI_Comm_size(MPI_COMM_WORLD, &procs);
+#endif
+
+  Core moab;
+  Interface& mb = moab;
+
+  std::string read_opts;
+  get_fv_read_options(read_opts);
+
+  EntityHandle set;
+  ErrorCode rval = mb.create_meshset(MESHSET_SET, set);
+  CHECK_ERR(rval);
+
+  // Load non-set variable T, and the mesh
+  read_opts += ";DEBUG_IO=0;VARIABLE=T";
+  rval = mb.load_file(example_fv, &set, read_opts.c_str());
+  CHECK_ERR(rval);
+
+  // Write variables T, slat and slon
+  std::string write_opts;
+  write_opts = std::string(";;VARIABLE=T,slat,slon;DEBUG_IO=0");
+#ifdef USE_MPI
+  // Use parallel options
+  write_opts += std::string(";PARALLEL=WRITE_PART");
+#endif
+  if (procs > 1)
+    rval = mb.write_file("test_par_fv_T.nc", 0, write_opts.c_str(), &set, 1);
+  else
+    rval = mb.write_file("test_fv_T.nc", 0, write_opts.c_str(), &set, 1);
+}
+
+// Check non-set variable T on some quads
+void test_fv_check_T()
+{
+  int rank = 0;
+  int procs = 1;
+#ifdef USE_MPI
+  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+  MPI_Comm_size(MPI_COMM_WORLD, &procs);
+#endif
+
+  Core moab;
+  Interface& mb = moab;
+
+  std::string read_opts;
+  get_eul_read_options(read_opts);
+
+  EntityHandle set;
+  ErrorCode rval = mb.create_meshset(MESHSET_SET, set);
+  CHECK_ERR(rval);
+
+  // Load non-set variable T and the mesh
+  read_opts += ";VARIABLE=T";
+  if (procs > 1)
+    rval = mb.load_file("test_par_fv_T.nc", &set, read_opts.c_str());
+  else
+    rval = mb.load_file("test_fv_T.nc", &set, read_opts.c_str());
+  CHECK_ERR(rval);
+
+  // Get tag T0
+  Tag Ttag0;
+  rval = mb.tag_get_handle("T0", 26, MB_TYPE_DOUBLE, Ttag0);
+  CHECK_ERR(rval);
+
+  double eps = 0.0001;
+  double val[8 * 26];
+
+  if (1 == procs) {
+    Range global_quads;
+    rval = mb.get_entities_by_type(0, MBQUAD, global_quads);
+    CHECK_ERR(rval);
+    CHECK_EQUAL((size_t)3312, global_quads.size());
+
+    EntityHandle gloabl_quad_ents[] = {global_quads[0], global_quads[1619], global_quads[1656], global_quads[3275],
+                                       global_quads[36], global_quads[1655], global_quads[1692], global_quads[3311]};
+    rval = mb.tag_get_data(Ttag0, &gloabl_quad_ents[0], 8, val);
+
+    CHECK_REAL_EQUAL(253.6048, val[0 * 26], eps); // First global quad
+    CHECK_REAL_EQUAL(232.2170, val[1 * 26], eps); // 1620th global quad
+    CHECK_REAL_EQUAL(232.7454, val[2 * 26], eps); // 1657th global quad
+    CHECK_REAL_EQUAL(210.2581, val[3 * 26], eps); // 3276th global quad
+    CHECK_REAL_EQUAL(253.6048, val[4 * 26], eps); // 37th global quad
+    CHECK_REAL_EQUAL(232.9553, val[5 * 26], eps); // 1656th global quad
+    CHECK_REAL_EQUAL(232.1704, val[6 * 26], eps); // 1693th global quad
+    CHECK_REAL_EQUAL(210.2581, val[7 * 26], eps); // Last global quad
+  }
+  else if (2 == procs) {
+    Range local_quads;
+    rval = mb.get_entities_by_type(0, MBQUAD, local_quads);
+    CHECK_ERR(rval);
+    CHECK_EQUAL((size_t)1656, local_quads.size());
+
+    EntityHandle local_quad_ents[] = {local_quads[0], local_quads[827], local_quads[828], local_quads[1655]};
+    rval = mb.tag_get_data(Ttag0, &local_quad_ents[0], 4, val);
+
+    if (0 == rank) {
+      CHECK_REAL_EQUAL(253.6048, val[0 * 26], eps); // First local quad, first global quad
+      CHECK_REAL_EQUAL(232.2170, val[1 * 26], eps); // Median local quad, 1620th global quad
+      CHECK_REAL_EQUAL(232.7454, val[2 * 26], eps); // Median local quad, 1657th global quad
+      CHECK_REAL_EQUAL(210.2581, val[3 * 26], eps); // Last local quad, 3276th global quad
+    }
+    else if (1 == rank) {
+      CHECK_REAL_EQUAL(253.6048, val[0 * 26], eps); // First local quad, 37th global quad
+      CHECK_REAL_EQUAL(232.9553, val[1 * 26], eps); // Median local quad, 1656th global quad
+      CHECK_REAL_EQUAL(232.1704, val[2 * 26], eps); // Median local quad, 1693th global quad
+      CHECK_REAL_EQUAL(210.2581, val[3 * 26], eps); // Last local quad, last global quad
+    }
+  }
+}
+
 // We also read and write set variables lat and lon, which are required to create the mesh
 // In test_homme_check_T(), we need to load the output file with mesh
 void test_homme_read_write_T()
@@ -329,6 +454,16 @@ void get_eul_read_options(std::string& opts)
 #endif
 }
 
+void get_fv_read_options(std::string& opts)
+{
+#ifdef USE_MPI
+  // Use parallel options
+  opts = ";;PARALLEL=READ_PART;PARTITION_METHOD=SQIJ";
+#else
+  opts = ";;";
+#endif
+}
+
 void get_homme_read_options(std::string& opts)
 {
 #ifdef USE_MPI

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