[MOAB-dev] r2562 - in MOAB/trunk: . test

kraftche at mcs.anl.gov kraftche at mcs.anl.gov
Tue Jan 20 16:44:09 CST 2009


Author: kraftche
Date: 2009-01-20 16:44:09 -0600 (Tue, 20 Jan 2009)
New Revision: 2562

Added:
   MOAB/trunk/exodus_test.cc
   MOAB/trunk/test/ho_test.g
Log:
add unit tests for reading/writing higher-order elements fomr Exodus/Genesis files

Added: MOAB/trunk/exodus_test.cc
===================================================================
--- MOAB/trunk/exodus_test.cc	                        (rev 0)
+++ MOAB/trunk/exodus_test.cc	2009-01-20 22:44:09 UTC (rev 2562)
@@ -0,0 +1,240 @@
+#include "TestUtil.hpp"
+#include "MBCore.hpp"
+#include "MBTagConventions.hpp"
+#include "MBCN.hpp"
+#include "ReadNCDF.hpp"
+#include "WriteNCDF.hpp"
+#include "FileOptions.hpp"
+#include <math.h>
+#include <algorithm>
+
+/* Input test file: ho_test.g
+ * 
+ * File is expected to contain at least one block for every
+ * supported higher-order element type.  The coordinates of
+ * every higher-order node are expected to be the mean of the
+ * adjacent corner vertices of the element.
+ */
+#ifdef SRCDIR
+static const char ho_file[] = STRINGIFY(SRCDIR) "/test/ho_test.g";
+#else
+static const char ho_file[] = "test/ho_test.g";
+#endif
+
+void read_file( MBInterface& moab, 
+                const char* input_file );
+
+// Check that element has expected higher-order nodes
+// and that each higher-order node is at the center
+// of the sub-entity it is on.
+void check_ho_element( MBInterface& moab, 
+                       MBEntityHandle entity,
+                       int mid_nodes[4] );
+
+// Validate elements of specified type.
+// Looks for a block containing the specified entity type
+// and with the specified mid-node flags set in its
+// HAS_MID_NODES_TAG.
+void test_ho_elements( MBEntityType type, int num_nodes );
+
+void test_tri6 () { test_ho_elements(MBTRI, 6); }
+void test_tri7 () { test_ho_elements(MBTRI, 7); }
+
+void test_quad5() { test_ho_elements(MBQUAD, 6); }
+void test_quad8() { test_ho_elements(MBQUAD, 8); }
+void test_quad9() { test_ho_elements(MBQUAD, 9); }
+
+void test_tet8 () { test_ho_elements(MBTET,  8); }
+void test_tet10() { test_ho_elements(MBTET, 10); }
+void test_tet14() { test_ho_elements(MBTET, 14); }
+
+void test_hex9 () { test_ho_elements(MBHEX,  9); }
+void test_hex20() { test_ho_elements(MBHEX, 20); }
+void test_hex27() { test_ho_elements(MBHEX, 27); }
+
+int main()
+{
+  int result = 0;
+  
+  result += RUN_TEST(test_tri6 );
+  result += RUN_TEST(test_tri7 );
+  result += RUN_TEST(test_quad5);
+  result += RUN_TEST(test_quad8);
+  result += RUN_TEST(test_quad9);
+  result += RUN_TEST(test_tet8 );
+  result += RUN_TEST(test_tet10);
+  result += RUN_TEST(test_tet14);
+  result += RUN_TEST(test_hex9 );
+  result += RUN_TEST(test_hex20);
+  result += RUN_TEST(test_hex27);
+  
+  return result;
+}
+
+void read_file( MBInterface& moab, 
+                const char* input_file )
+{
+  MBErrorCode rval;
+  MBEntityHandle set;
+  ReadNCDF reader( &moab );
+  FileOptions opts("");
+  rval = reader.load_file( input_file, set, opts, 0, 0 );
+  CHECK_ERR(rval);
+}
+
+void write_and_read( MBInterface& write_mb,
+                     MBInterface& read_mb,
+                     MBEntityHandle block = 0 )
+{
+  const char* tmp_file = "exodus_test_tmp.g";
+  MBErrorCode rval;
+  MBEntityHandle set;
+  ReadNCDF reader( &read_mb );
+  WriteNCDF writer( &write_mb );
+  FileOptions opts("");
+  
+  MBEntityHandle* write_set_list = &block;
+  int write_set_list_len = 0;//(block != 0);
+  std::vector<std::string> qa_records;
+  rval = writer.write_file( tmp_file, true, opts, 
+                            write_set_list, write_set_list_len,
+                            qa_records, 3 );
+  if (MB_SUCCESS != rval) 
+    remove(tmp_file);
+  CHECK_ERR(rval);
+  
+  rval = reader.load_file( tmp_file, set, opts, 0, 0 );
+  remove( tmp_file );
+  CHECK_ERR(rval);
+}
+
+void check_ho_elements( MBInterface& moab, 
+                        MBEntityHandle block,
+                        MBEntityType type,
+                        int mid_nodes[4] )
+{
+  MBErrorCode rval;
+  MBRange elems;
+  rval = moab.get_entities_by_handle( block, elems );
+  CHECK_ERR(rval);
+  CHECK(!elems.empty());
+  CHECK(elems.all_of_type(type));
+  for (MBRange::const_iterator i = elems.begin(); i != elems.end(); ++i)
+    check_ho_element( moab, *i, mid_nodes );
+}
+
+// Check that element has expected higher-order nodes
+// and that each higher-order node is at the center
+// of the sub-entity it is on.
+void check_ho_element( MBInterface& moab, 
+                       MBEntityHandle entity,
+                       int mid_nodes[4] )
+{
+    // get element info
+  const MBEntityType type = TYPE_FROM_HANDLE(entity);
+  const MBEntityHandle* conn;
+  int conn_len;
+  MBErrorCode rval = moab.get_connectivity( entity, conn, conn_len );
+  CHECK_ERR(rval);
+  std::vector<double> coords(3*conn_len);
+  rval = moab.get_coords( conn, conn_len, &coords[0] );
+  CHECK_ERR(rval);
+  
+    // calculate and verify expected number of mid nodes
+  int num_nodes = MBCN::VerticesPerEntity(type);
+  for (int d = 1; d <= MBCN::Dimension(type); ++d)
+    if (mid_nodes[d])
+      num_nodes += MBCN::NumSubEntities(type, d);
+  CHECK_EQUAL( num_nodes, conn_len );
+  
+    // verify that each higher-order node is at the center
+    // of its respective sub-entity.
+  for (int i = MBCN::VerticesPerEntity(type); i < num_nodes; ++i) {
+      // get sub-entity owning ho-node  
+    int sub_dim, sub_num;
+    MBCN::HONodeParent( type, num_nodes, i, sub_dim, sub_num );
+      // get corner vertex indices
+    int sub_conn[8], num_sub;
+    if (sub_dim < MBCN::Dimension(type)) {
+      MBCN::SubEntityVertexIndices( type, sub_dim, sub_num, sub_conn );
+      MBEntityType sub_type = MBCN::SubEntityType( type, sub_dim, sub_num );
+      num_sub = MBCN::VerticesPerEntity( sub_type );
+    }
+    else {
+      num_sub = MBCN::VerticesPerEntity(type);
+      for (int j = 0; j < num_sub; ++j)
+        sub_conn[j] = j;
+    }
+      // calculate mean of corner vertices
+    double mean[3] = {0,0,0};
+    for (int j = 0; j < num_sub; ++j) {
+      int co = 3*sub_conn[j];
+      mean[0] += coords[co  ];
+      mean[1] += coords[co+1];
+      mean[2] += coords[co+2];
+    }
+    mean[0] /= num_sub;
+    mean[1] /= num_sub;
+    mean[2] /= num_sub;
+      // verify that higher-order node is at expected location
+    CHECK_REAL_EQUAL( mean[0], coords[3*i  ], 1e-6 );
+    CHECK_REAL_EQUAL( mean[1], coords[3*i+1], 1e-6 );
+    CHECK_REAL_EQUAL( mean[2], coords[3*i+2], 1e-6 );
+  }
+}
+
+
+MBEntityHandle find_block( MBInterface& mb, MBEntityType type, const int has_mid_nodes[4] )
+{
+
+  MBErrorCode rval;
+  MBTag ho_tag, block_tag;
+  rval = mb.tag_get_handle( MATERIAL_SET_TAG_NAME, block_tag );
+  CHECK_ERR(rval);
+  rval = mb.tag_get_handle( HAS_MID_NODES_TAG_NAME, ho_tag );
+  CHECK_ERR(rval);
+  
+  // get material sets with expected higher-order nodes
+  MBRange blocks;
+  MBTag tags[2] = {ho_tag, block_tag};
+  const void* vals[2] = {has_mid_nodes, NULL};
+  rval = mb.get_entities_by_type_and_tag( 0, MBENTITYSET, tags, vals, 2, blocks );
+  CHECK_ERR(rval);
+  
+  for (MBRange::iterator i = blocks.begin(); i != blocks.end(); ++i) {
+    int n;
+    rval = mb.get_number_entities_by_type( *i, type, n );
+    CHECK_ERR(rval);
+    if (n > 0)
+      return *i;
+  }
+  
+  CHECK(false); // no block matching element type description
+  return 0;
+}
+
+// Validate elements of specified type.
+// Looks for a block containing the specified entity type
+// and with the specified mid-node flags set in its
+// HAS_MID_NODES_TAG.
+void test_ho_elements( MBEntityType type, int num_nodes )
+{
+  MBCore mb_impl1, mb_impl2;
+  MBInterface &mb1 = mb_impl1, &mb2 = mb_impl2;
+  int ho_flags[4];
+  MBCN::HasMidNodes( type, num_nodes, ho_flags );
+
+    // read file 
+  read_file( mb1, ho_file );
+    // test element connectivity order
+  MBEntityHandle block = find_block( mb1, type, ho_flags );
+  CHECK(block != 0);
+  check_ho_elements( mb1, block, type, ho_flags );
+  
+    // write block and read it back in
+  write_and_read( mb1, mb2, block );
+    // test element connectivity order on re-read data
+  block = find_block( mb2, type, ho_flags );
+  CHECK(block != 0);
+  check_ho_elements( mb2, block, type, ho_flags );
+}

Added: MOAB/trunk/test/ho_test.g
===================================================================
(Binary files differ)


Property changes on: MOAB/trunk/test/ho_test.g
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream




More information about the moab-dev mailing list