[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