[MOAB-dev] r2549 - MOAB/trunk

kraftche at mcs.anl.gov kraftche at mcs.anl.gov
Wed Jan 14 17:40:24 CST 2009


Author: kraftche
Date: 2009-01-14 17:40:24 -0600 (Wed, 14 Jan 2009)
New Revision: 2549

Added:
   MOAB/trunk/ho_test.cub
Removed:
   MOAB/trunk/hex27.cub
   MOAB/trunk/quad9.cub
Modified:
   MOAB/trunk/cub_file_test.cc
Log:
write better tests for higher-order elements from cub file that can be done for any element type and add tests for other cubit-supported higher-order elements

Modified: MOAB/trunk/cub_file_test.cc
===================================================================
--- MOAB/trunk/cub_file_test.cc	2009-01-14 23:39:12 UTC (rev 2548)
+++ MOAB/trunk/cub_file_test.cc	2009-01-14 23:40:24 UTC (rev 2549)
@@ -7,7 +7,7 @@
 #include <math.h>
 #include <algorithm>
 
-/**\brief Input test file.
+/**\brief Input test file: test.cub
  * Cubit 10.2 file.
  * File contains:
  * Two merged 10x10x10 bricks sharing a single surface (surface 6).
@@ -67,20 +67,45 @@
  * |.         |.         |/
  * 4----------1----------9
 */
+
+/* Input test file: ho_test.cub
+ * 
+ * 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 input_file_1[] = STRINGIFY(SRCDIR) "/test.cub";
-static const char quad9_file[] = STRINGIFY(SRCDIR) "/quad9.cub";
-static const char hex27_file[] = STRINGIFY(SRCDIR) "/hex27.cub";
+static const char ho_file[] = STRINGIFY(SRCDIR) "/ho_test.cub";
 #else
 static const char input_file_1[] = "test.cub";
-static const char quad9_file[] = "quad9.cub";
-static const char hex27_file[] = "hex27.cub";
+static const char ho_file[] = "ho_test.cub";
 #endif
 
 void read_file( MBInterface& moab, 
                 const char* input_file,
                 MBEntityHandle* file_set = 0 );
 
+
+// Check that adjacent lower-order entities have
+// higher-order nodes consitent with input entity.
+void check_adj_ho_nodes( MBInterface& moab,
+                         MBEntityHandle entity );
+
+// 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_vertices();
 
 void test_edges();
@@ -101,16 +126,21 @@
 
 void test_file_set();
 
-void test_quad9();
+void test_tri6 () { test_ho_elements(MBTRI, 6); }
+void test_tri7 () { test_ho_elements(MBTRI, 7); }
 
-void test_hex27();
+void test_quad5() { test_ho_elements(MBQUAD, 6); }
+void test_quad8() { test_ho_elements(MBQUAD, 8); }
+void test_quad9() { test_ho_elements(MBQUAD, 9); }
 
-// Check that adjacent lower-order entities have
-// higher-order nodes consitent with input entities.
-void check_adj_ho_nodes( MBInterface& moab,
-                         const MBEntityHandle* entities,
-                         int num_entities );
+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;
@@ -125,8 +155,17 @@
   result += RUN_TEST(test_side_sets);
   result += RUN_TEST(test_node_sets);
   result += RUN_TEST(test_file_set);
-  result += RUN_TEST(test_hex27);
+  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;
 }
@@ -804,193 +843,6 @@
   CHECK( exp == act );
 }
 
-static int q9_idx_from_coord( double coord )
-{
-    // 10x10 element grid has 21 vertices in each direction,
-    // equally spaced in [-5,5].
-  return (int)round( 2*coord + 10 );
-}
-
-void test_quad9()
-{
-  MBErrorCode rval;
-  MBCore mb_impl;
-  MBInterface& mb = mb_impl;
-  read_file( mb, quad9_file );
-  
-    // we're expecting a 10x10 element grid in the xy plane.
-  MBEntityHandle verts[21][21], quads[10][10];
-  memset( verts, 0, sizeof(verts) );
-  memset( quads, 0, sizeof(quads) );
-  
-    // get all quads
-  MBRange range;
-  rval = mb.get_entities_by_type( 0, MBQUAD, range );
-  CHECK_ERR(rval);
-  CHECK_EQUAL( (size_t)(10*10), range.size() );
-  
-    // for each quad
-  for (MBRange::iterator i = range.begin(); i != range.end(); ++i) {
-      // get connectivity
-    const MBEntityHandle* conn = 0;
-    int conn_len = 0;
-    rval = mb.get_connectivity( *i, conn, conn_len, false );
-    CHECK_ERR(rval);
-    CHECK_EQUAL( 9, conn_len );
-    
-      // translate connectivity to indices into vertex grid
-    double coords[3*9];
-    rval = mb.get_coords( conn, 9, coords ); CHECK_ERR(rval);
-    int x[9], y[9];
-    for (int j = 0; j < 9; ++j) {
-      x[j] = q9_idx_from_coord( coords[3*j] );
-      y[j] = q9_idx_from_coord( coords[3*j+1] );
-      CHECK_REAL_EQUAL( 0.0, coords[3*j+2], 1e-12 );
-      CHECK( 0 <= x[j] && x[j] <= 20 );
-      CHECK( 0 <= y[j] && y[j] <= 20 );
-    }
-    
-      // calculate element location from mid-node location
-    int ex = (x[8]-1)/2;
-    int ey = (y[8]-1)/2;
-    CHECK_EQUAL( (MBEntityHandle)0, quads[ex][ey] );
-    quads[ex][ey] = *i;
-    
-      // check each vertex
-    bool seen[3][3] = { {false, false, false},
-                        {false, false, false},
-                        {false, false, false} };
-    for (int j = 0; j < 9; ++j) {
-        // check for duplicate vertices
-      if (verts[x[j]][y[j]] == 0)
-        verts[x[j]][y[j]] = conn[j];
-      else {
-        CHECK_EQUAL( verts[x[j]][y[j]], conn[j] );
-      }
-        // check that vertices have correct coordinates
-      int sx = x[j] - x[8] + 1;
-      int sy = y[j] - y[8] + 1;
-      CHECK( 0 <= sx && sx <= 2 );
-      CHECK( 0 <= sy && sy <= 2 );
-      seen[sx][sy] = true;
-    }
-    
-    CHECK( seen[0][0] );
-    CHECK( seen[0][1] );
-    CHECK( seen[0][2] );
-    CHECK( seen[1][0] );
-    CHECK( seen[1][1] );
-    CHECK( seen[1][2] );
-    CHECK( seen[2][0] );
-    CHECK( seen[2][1] );
-    CHECK( seen[2][2] );
-  }
-  
-    // check that we saw all the elements and vertices we expected to
-  for (int i = 0; i < 21; ++i)
-    for (int j = 0; j < 21; ++j)
-      CHECK( verts[i][j] != 0 );
-  for (int i = 0; i < 10; ++i)
-    for (int j = 0; j < 10; ++j)
-      CHECK( quads[i][j] != 0 );
-        
-  check_adj_ho_nodes( mb, &quads[0][0], 10*10 );
-}
-
-
-static int h27_idx_from_coord( double coord )
-{
-    // 2x2 element grid has 7 vertices in each direction,
-    // equally spaced in [-1,1].
-  return (int)round( 2*coord + 2 );
-}
-
-void test_hex27()
-{
-  MBErrorCode rval;
-  MBCore mb_impl;
-  MBInterface& mb = mb_impl;
-  read_file( mb, hex27_file );
-  
-    // we're expecting a 2x2x2 element grid
-  MBEntityHandle verts[5][5][5], hexes[2][2][2];
-  memset( verts, 0, sizeof(verts) );
-  memset( hexes, 0, sizeof(hexes) );
-  
-    // get all hexes
-  MBRange range;
-  rval = mb.get_entities_by_type( 0, MBHEX, range );
-  CHECK_ERR(rval);
-  CHECK_EQUAL( (size_t)(2*2*2), range.size() );
-  
-    // for each quad
-  for (MBRange::iterator i = range.begin(); i != range.end(); ++i) {
-      // get connectivity
-    const MBEntityHandle* conn = 0;
-    int conn_len = 0;
-    rval = mb.get_connectivity( *i, conn, conn_len, false );
-    CHECK_ERR(rval);
-    CHECK_EQUAL( 27, conn_len );
-    
-      // translate connectivity to indices into vertex grid
-    double coords[3*27];
-    rval = mb.get_coords( conn, 27, coords ); CHECK_ERR(rval);
-    int x[27], y[27], z[27];
-    for (int j = 0; j < 27; ++j) {
-      x[j] = h27_idx_from_coord( coords[3*j] );
-      y[j] = h27_idx_from_coord( coords[3*j+1] );
-      z[j] = h27_idx_from_coord( coords[3*j+2] );
-      CHECK( 0 <= x[j] && x[j] <= 4 );
-      CHECK( 0 <= y[j] && y[j] <= 4 );
-      CHECK( 0 <= z[j] && z[j] <= 4 );
-    }
-    
-      // calculate element location from mid-node location
-    int ex = (x[26]-1)/2;
-    int ey = (y[26]-1)/2;
-    int ez = (z[26]-1)/2;
-    CHECK_EQUAL( (MBEntityHandle)0, hexes[ex][ey][ez] );
-    hexes[ex][ey][ez] = *i;
-    
-      // check each vertex
-    bool seen[3][3][3];
-    std::fill( &seen[0][0][0], &seen[0][0][0] + 3*3*3, false );
-    for (int j = 0; j < 27; ++j) {
-        // check for duplicate vertices
-      if (verts[x[j]][y[j]][z[j]] == 0)
-        verts[x[j]][y[j]][z[j]] = conn[j];
-      else {
-        CHECK_EQUAL( verts[x[j]][y[j]][z[j]], conn[j] );
-      }
-        // check that vertices have correct coordinates
-      int sx = x[j] - x[26] + 1;
-      int sy = y[j] - y[26] + 1;
-      int sz = z[j] - z[26] + 1;
-      CHECK( 0 <= sx && sx <= 2 );
-      CHECK( 0 <= sy && sy <= 2 );
-      CHECK( 0 <= sz && sz <= 2 );
-      seen[sx][sy][sz] = true;
-    }
-    
-    for (int k = 0; k < 3; ++k) 
-      for (int l = 0; l < 3; ++l)
-        for (int m = 0; m < 3; ++m)
-          CHECK( seen[k][l][m] );
-  }
-  
-    // check that we saw all the elements and vertices we expected to
-  for (int i = 0; i < 5; ++i)
-    for (int j = 0; j < 5; ++j)
-      for (int k = 0; k < 5; ++k)
-        CHECK( verts[i][j][k] != 0 );
-  for (int i = 0; i < 2; ++i)
-    for (int j = 0; j < 2; ++j)
-      for (int k = 0; k < 2; ++k)
-        CHECK( hexes[i][j][k] != 0 );
-        
-  check_adj_ho_nodes( mb, &hexes[0][0][0], 2*2*2 );
-}
-
 static MBEntityHandle find_side( MBInterface& moab, 
                                  MBEntityHandle entity,
                                  int side_dim,
@@ -1050,14 +902,12 @@
       
   
 void check_adj_ho_nodes( MBInterface& moab,
-                         const MBEntityHandle* entities,
-                         int num_entities )
+                         MBEntityHandle entity )
 {
-  for (int i = 0; i < num_entities; ++i) {
-    MBEntityType type = TYPE_FROM_HANDLE(entities[i]);
+    MBEntityType type = TYPE_FROM_HANDLE(entity);
     const MBEntityHandle* conn;
     int conn_len;
-    MBErrorCode rval = moab.get_connectivity( entities[i], conn, conn_len );
+    MBErrorCode rval = moab.get_connectivity( entity, conn, conn_len );
     CHECK_ERR(rval);
     
     int ho[4];
@@ -1067,7 +917,7 @@
         continue;
         
       for (int j = 0; j < MBCN::NumSubEntities( type, dim ); ++j) {
-        MBEntityHandle side = find_side( moab, entities[i], dim, j );
+        MBEntityHandle side = find_side( moab, entity, dim, j );
         if (!side)
           continue;
         
@@ -1081,6 +931,107 @@
         CHECK_EQUAL( side_conn[side_idx], conn[this_idx] );
       }
     }
+}
+
+// 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 );
   }
 }
 
+// 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_impl;
+  MBInterface& mb = mb_impl;
+  MBEntityHandle set;
+  read_file( mb, ho_file, &set );
+
+  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;
+  int ho_flags[4];
+  MBCN::HasMidNodes( type, num_nodes, ho_flags );
+  MBTag tags[2] = {ho_tag, block_tag};
+  void* vals[2] = {ho_flags, NULL};
+  rval = mb.get_entities_by_type_and_tag( 0, MBENTITYSET, tags, vals, 2, blocks );
+  CHECK_ERR(rval);
+  
+  MBRange::iterator i;
+  MBRange entities;
+  for (i = blocks.begin(); i != blocks.end(); ++i) {
+    rval = mb.get_entities_by_type( *i, type, entities, true );
+    CHECK_ERR(rval);
+  }
+    // test file should contain all types of HO entities
+  CHECK(!entities.empty());
+    // test ho node positions -- expect to be at center of adj corners
+  for (i = entities.begin(); i != entities.end(); ++i)
+    check_ho_element( mb, *i, ho_flags );
+    // test ho node handles consistent with adjacent entities
+  for (i = entities.begin(); i != entities.end(); ++i)
+    check_adj_ho_nodes( mb, *i );
+}

Deleted: MOAB/trunk/hex27.cub
===================================================================
(Binary files differ)

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


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

Deleted: MOAB/trunk/quad9.cub
===================================================================
(Binary files differ)




More information about the moab-dev mailing list