[MOAB-dev] r3178 - MOAB/trunk

kraftche at cae.wisc.edu kraftche at cae.wisc.edu
Wed Sep 30 14:06:31 CDT 2009


Author: kraftche
Date: 2009-09-30 14:06:31 -0500 (Wed, 30 Sep 2009)
New Revision: 3178

Added:
   MOAB/trunk/GmshUtil.cpp
   MOAB/trunk/GmshUtil.hpp
Modified:
   MOAB/trunk/Makefile.am
   MOAB/trunk/ReadGmsh.cpp
   MOAB/trunk/ReadGmsh.hpp
   MOAB/trunk/WriteGmsh.cpp
Log:
o Move Gmsh<=>MOAB type conversion data from ReadGmsh to GmshUtil so it
  can be shared with WriteGsm
o Add support for writing the following element types to Gmsh files:
  Quad8, Hex20, Pyr13, Pri15




Added: MOAB/trunk/GmshUtil.cpp
===================================================================
--- MOAB/trunk/GmshUtil.cpp	                        (rev 0)
+++ MOAB/trunk/GmshUtil.cpp	2009-09-30 19:06:31 UTC (rev 3178)
@@ -0,0 +1,107 @@
+/**
+ * MOAB, a Mesh-Oriented datABase, is a software component for creating,
+ * storing and accessing finite element mesh data.
+ * 
+ * Copyright 2004 Sandia Corporation.  Under the terms of Contract
+ * DE-AC04-94AL85000 with Sandia Coroporation, the U.S. Government
+ * retains certain rights in this software.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ */
+
+#include "GmshUtil.hpp"
+
+// Indexed by position in Gmsh order, containing cooresponding
+// position in MOAB order.
+const int hex_27_node_order[] =  {  
+    0,  1,  2,  3,  4,  5,  6,  7,                 // corners
+    8, 11, 12,  9, 13, 10, 14, 15, 16, 19, 17, 18, // edges
+   24, 20, 23, 21, 22, 25,                         // faces
+   26 };                                           // volume
+// Indexed by position in MOAB order, containing cooresponding
+// position in Gmsh order.
+const int pri_15_node_order[] = { 
+    0,  1,  2,  3,  4,  5,            // corners
+    6,  8,  9,  7, 10, 11, 12, 14, 13 // edges
+    };
+const int pyr_13_node_order[] = { 
+    0,  1,  2,  3,  4,                // corners
+    5,  8,  9,  6, 10,  7, 11, 12     // edges
+    };
+
+
+// List of GmshElemType structs, indexed by the VTK type number.
+const GmshElemType GmshUtil::gmshElemTypes[] = {
+      { 0,                        0, MBMAXTYPE,  0, 0 },
+      { "line",                   1, MBEDGE,     2, 0 },
+      { "triangle",               2, MBTRI,      3, 0 },
+      { "quadrangle",             3, MBQUAD,     4, 0 },
+      { "tetrahedron",            4, MBTET,      4, 0 },
+      { "hexahedron",             5, MBHEX,      8, 0 },
+      { "prism",                  6, MBPRISM,    6, 0 },
+      { "pyramid",                7, MBPYRAMID,  5, 0 },
+      { "2nd order line",         8, MBEDGE,     3, 0 },
+      { "2nd order triangle",     9, MBTRI,      6, 0 }, 
+      { "2nd order quadrangle",  10, MBQUAD,     9, 0 }, 
+      { "2nd order tetrahedron", 11, MBTET,     10, 0 }, 
+      { "2nd order hexahedron",  12, MBHEX,     27, hex_27_node_order }, 
+      { "2nd order prism",       13, MBMAXTYPE,  0, 0 }, // prism w/ mid-face nodes on quads but not tris
+      { "2nd order pyramid",     14, MBMAXTYPE,  0, 0 }, // pyramid w/ mid-face nodes on quad but not tris
+      { "point",                 15, MBMAXTYPE,  0, 0 }, // point element (0-rad sphere element?)
+      { "2nd order quadrangle",  16, MBQUAD,     8, 0 },
+      { "2nd order hexahedron",  17, MBHEX,     20, hex_27_node_order },
+      { "2nd order prism",       18, MBPRISM,   15, pri_15_node_order },
+      { "2nd order pyramid",     19, MBPYRAMID, 13, pyr_13_node_order },
+      { "3rd order triangle",    20, MBMAXTYPE,  0, 0 }, // triangle w/ 2 nodes per edge
+      { "3rd order triangle",    21, MBMAXTYPE,  0, 0 }, //   "       " "   "    "   "   and mid-face node
+      { "4th order triangle",    22, MBMAXTYPE,  0, 0 }, // triangle w/ 3 nodes per edge
+      { "4th order triangle",    23, MBMAXTYPE,  0, 0 }, //   "       " "   "    "   "   and 3 mid-face nodes
+      { "5th order triangle",    24, MBMAXTYPE,  0, 0 }, // triangle w/ 4 nodes per edge
+      { "5th order triangle",    25, MBMAXTYPE,  0, 0 }, //   "       " "   "    "   "   and 6 mid-face nodes
+      { "3rd order edge",        26, MBMAXTYPE,  0, 0 }, // 4-node edge
+      { "4th order edge",        27, MBMAXTYPE,  0, 0 }, // 5-node edge
+      { "5th order edge",        28, MBMAXTYPE,  0, 0 }, // 6-node edge
+      { "3rd order tetrahedron", 29, MBMAXTYPE,  0, 0 }, // tet w/ 2 nodes per edge and 1 per face
+      { "4th order tetrahedron", 30, MBMAXTYPE,  0, 0 }, // tet w/ 3 nodes per edge, 3 per face, and 1 mid-voluem
+      { "5th order tetrahedron", 31, MBMAXTYPE,  0, 0 }, // tet w/ 4 nodes per edge, 6 per face, and 4 mid-voluem
+      { 0,                       32, MBMAXTYPE,  0, 0 }
+    };
+
+const unsigned GmshUtil::numGmshElemType = sizeof(GmshUtil::gmshElemTypes) / sizeof(GmshUtil::gmshElemTypes[0]);
+
+// Define an array, indexed by MBEntityType and number of nodes, 
+// containing the corresponding Gmsh element type.
+#define TWENTYEIGHT_ZEROS { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+const int MAX_NODES = 28;
+const int mb_to_gmsh_type[][MAX_NODES] = {
+ // 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
+  TWENTYEIGHT_ZEROS,  // MBVERTEX
+  { 0, 0, 1, 8,26,27,28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  // MBEDGE
+  { 0, 0, 0, 2, 0, 0, 9, 0, 0,20,21, 0,22, 0, 0,23, 0, 0, 0, 0, 0,25, 0, 0, 0, 0, 0, 0 },  // MBTRI
+  { 0, 0, 0, 0, 3, 0, 0, 0,16,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  // MBQUAD
+  TWENTYEIGHT_ZEROS,  // MBPOLYGON
+  { 0, 0, 0, 0, 4, 0, 0, 0, 0, 0,11, 0, 0, 0, 0, 0, 0, 0, 0, 0,29, 0, 0, 0, 0, 0, 0, 0 },  // MBTET
+  { 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0,19,14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  // MBPYRAMID
+  { 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0,18, 0, 0,13, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  // MBWEDGE
+  TWENTYEIGHT_ZEROS,  // MBKNIFE
+  { 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,17, 0, 0, 0, 0, 0, 0,12 },  // MBHEX
+  TWENTYEIGHT_ZEROS,  // MBPOLYHEDRON
+  TWENTYEIGHT_ZEROS,  // MBENTITYSET
+  TWENTYEIGHT_ZEROS };// MBMAXTYPE
+
+int GmshUtil::get_gmsh_type( MBEntityType type, unsigned num_nodes )
+{
+  if (num_nodes >= (unsigned)MAX_NODES)
+    return -1;
+
+  int idx = mb_to_gmsh_type[type][num_nodes];
+  if (!idx)
+    return -1;
+  
+  return gmshElemTypes[idx].mb_type == MBMAXTYPE ? -1 : idx;
+}
+

Added: MOAB/trunk/GmshUtil.hpp
===================================================================
--- MOAB/trunk/GmshUtil.hpp	                        (rev 0)
+++ MOAB/trunk/GmshUtil.hpp	2009-09-30 19:06:31 UTC (rev 3178)
@@ -0,0 +1,56 @@
+/**
+ * MOAB, a Mesh-Oriented datABase, is a software component for creating,
+ * storing and accessing finite element mesh data.
+ * 
+ * Copyright 2004 Sandia Corporation.  Under the terms of Contract
+ * DE-AC04-94AL85000 with Sandia Coroporation, the U.S. Government
+ * retains certain rights in this software.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ */
+
+#ifndef GMSH_UTIL_HPP
+#define GMSH_UTIL_HPP
+
+#include "MBEntityType.h"
+
+//! Structure defining relation between MOAB and VTK element
+//! types.  VTK had different types for quadratic than linear
+//! elements, so a tuple of the MOAB type and number of
+//! elements maps to a VTK type.
+struct GmshElemType
+{
+  const char* name;      //!< String name for use in error messages
+  unsigned gmsh_type;    //!< GMsh integer type
+  MBEntityType mb_type;  //!< MOAB type
+  unsigned num_nodes;    //!< Number of nodes (0 for polygon)
+  const int* node_order; //!< Gmsh element node ordering, indexed by
+                         //!< the Gmsh node position and containing
+                         //!< the corresponding MOAB node position.
+                         //!< NOTE: This field is NULL if MOAB and Gmsh 
+                         //!< ordering is the same!
+};
+
+//! General data about GMsh files for use by read and write code.
+//! \author Jason Kraftcheck
+class GmshUtil 
+{
+
+public:
+    //! Gmsh types, indexed by Gmsh type number.
+    //! For unused Gmsh type numbers, mb_type will be MBMAXTYPE.
+  static const GmshElemType gmshElemTypes[];
+  
+    //! Length of \ref gmshElemTypes
+  static const unsigned numGmshElemType;
+  
+    //! Get the Gmsh type corresponding to a tuple of the MOAB type and number of nodes.
+    //! num_nodes is ignored for POLYGON type.  Returns -1 for unsupported types.
+  static int get_gmsh_type( MBEntityType type, unsigned num_nodes );
+};
+
+#endif

Modified: MOAB/trunk/Makefile.am
===================================================================
--- MOAB/trunk/Makefile.am	2009-09-30 17:55:13 UTC (rev 3177)
+++ MOAB/trunk/Makefile.am	2009-09-30 19:06:31 UTC (rev 3178)
@@ -122,6 +122,8 @@
   FileTokenizer.cpp \
   FileTokenizer.hpp \
   GeomTopoTool.cpp \
+  GmshUtil.cpp \
+  GmshUtil.hpp \
   HigherOrderFactory.cpp \
   HomXform.cpp \
   MBAdaptiveKDTree.cpp \

Modified: MOAB/trunk/ReadGmsh.cpp
===================================================================
--- MOAB/trunk/ReadGmsh.cpp	2009-09-30 17:55:13 UTC (rev 3177)
+++ MOAB/trunk/ReadGmsh.cpp	2009-09-30 19:06:31 UTC (rev 3178)
@@ -31,6 +31,7 @@
 #include "MBTagConventions.hpp"
 #include "MBParallelConventions.h"
 #include "MBCN.hpp"
+#include "GmshUtil.hpp"
 
 #include <errno.h>
 #include <string.h>
@@ -56,61 +57,7 @@
   }
 }
 
-// Indexed by position in Gmsh order, containing cooresponding
-// position in MOAB order.
-const int hex_27_node_order[] =  {  
-    0,  1,  2,  3,  4,  5,  6,  7,                 // corners
-    8, 11, 12,  9, 13, 10, 14, 15, 16, 19, 17, 18, // edges
-   24, 20, 23, 21, 22, 25,                         // faces
-   26 };                                           // volume
-// Indexed by position in MOAB order, containing cooresponding
-// position in Gmsh order.
-const int pri_15_node_order[] = { 
-    0,  1,  2,  3,  4,  5,            // corners
-    6,  8,  9,  7, 10, 11, 12, 14, 13 // edges
-    };
-const int pyr_13_node_order[] = { 
-    0,  1,  2,  3,  4,                // corners
-    5,  8,  9,  6, 10,  7, 11, 12     // edges
-    };
-// Type info indexed by type id used in file format.
-const ReadGmsh::ElementType typemap[] = {
-  { MBMAXTYPE, 0, 0 }, 
-  { MBEDGE,    2, 0 }, // 1
-  { MBTRI,     3, 0 }, // 2
-  { MBQUAD,    4, 0 }, // 3
-  { MBTET,     4, 0 }, // 4
-  { MBHEX,     8, 0 }, // 5
-  { MBPRISM,   6, 0 }, // 6
-  { MBPYRAMID, 5, 0 }, // 7
-  { MBEDGE,    3, 0 }, // 8
-  { MBTRI,     6, 0 }, // 9
-  { MBQUAD,    9, 0 }, // 10
-  { MBTET,    10, 0 }, // 11
-  { MBHEX,    27, hex_27_node_order },
-  { MBMAXTYPE,18, 0 }, // 13  prism w/ mid-face nodes on quads but not tris
-  { MBMAXTYPE,14, 0 }, // 14  pyramid w/ mid-face nodes on quad but not tris
-  { MBMAXTYPE, 1, 0 }, // 15  point element (0-rad sphere element?)
-  { MBQUAD,    8, 0 }, // 16
-  { MBHEX,    20, hex_27_node_order },
-  { MBPRISM,  15, pri_15_node_order },
-  { MBPYRAMID,13, pyr_13_node_order },
-  { MBMAXTYPE, 9, 0 }, // 20  triangle w/ 2 nodes per edge
-  { MBMAXTYPE,10, 0 }, // 21    "       " "   "    "   "   and mid-face node
-  { MBMAXTYPE,12, 0 }, // 22  triangle w/ 3 nodes per edge
-  { MBMAXTYPE,15, 0 }, // 23    "       " "   "    "   "   and 3 mid-face nodes
-  { MBMAXTYPE,15, 0 }, // 24  triangle w/ 4 nodes per edge
-  { MBMAXTYPE,21, 0 }, // 25    "       " "   "    "   "   and 6 mid-face nodes
-  { MBMAXTYPE, 4, 0 }, // 26  4-node edge
-  { MBMAXTYPE, 5, 0 }, // 27  5-node edge
-  { MBMAXTYPE, 6, 0 }, // 28  6-node edge
-  { MBMAXTYPE,20, 0 }, // 29  tet w/ 2 nodes per edge and 1 per face
-  { MBMAXTYPE,35, 0 }, // 30  tet w/ 3 nodes per edge, 3 per face, and 1 mid-voluem
-  { MBMAXTYPE,56, 0 }  // 31  tet w/ 4 nodes per edge, 6 per face, and 4 mid-voluem
-};
-const int max_type_int = sizeof(typemap) / sizeof(typemap[0]) - 1;
 
-
 MBErrorCode ReadGmsh::read_tag_values( const char* /* file_name */,
                                        const char* /* tag_name */,
                                        const FileOptions& /* opts */,
@@ -301,7 +248,7 @@
     // temporary, per-element data
   std::vector<int> int_data(5), tag_data(2);
   std::vector<long> tmp_conn;
-  int curr_elem_type = 0;
+  int curr_elem_type = -1;
   for (long i = 0; i < num_elem; ++i)
   {
       // Read element description
@@ -312,8 +259,8 @@
         return MB_FILE_WRITE_ERROR;
       tag_data[0] = int_data[2];
       tag_data[1] = int_data[3];
-      if (int_data[4] != typemap[int_data[1]].nodes)
-      {
+      if ((unsigned)tag_data[1] < GmshUtil::numGmshElemType &&
+           GmshUtil::gmshElemTypes[tag_data[1]].num_nodes != (unsigned)int_data[4]) {
         readMeshIface->report_error( "Invalid node count for element type at line %d\n",
                                      tokens.line_number() );
         return MB_FILE_WRITE_ERROR;
@@ -346,7 +293,7 @@
     {
       if (!id_list.empty())  // first iteration
       {
-        result = create_elements( typemap[curr_elem_type],
+        result = create_elements( GmshUtil::gmshElemTypes[curr_elem_type],
                                   id_list,
                                   mat_set_list,
                                   geom_set_list,
@@ -363,14 +310,14 @@
       part_set_list.clear();
       connectivity.clear();
       curr_elem_type = int_data[1];
-      if (curr_elem_type > max_type_int ||
-          typemap[curr_elem_type].mbtype == MBMAXTYPE)
+      if ((unsigned)curr_elem_type >= GmshUtil::numGmshElemType ||
+          GmshUtil::gmshElemTypes[curr_elem_type].mb_type == MBMAXTYPE)
       {
         readMeshIface->report_error( "Unsupported element type %d at line %d\n",
                                      curr_elem_type, tokens.line_number() );
         return MB_FILE_WRITE_ERROR;
       }
-      tmp_conn.resize( typemap[curr_elem_type].nodes );
+      tmp_conn.resize( GmshUtil::gmshElemTypes[curr_elem_type].num_nodes );
     }
     
       // Store data from element description
@@ -399,7 +346,7 @@
     // Create entity sequence for last element(s).
   if (!id_list.empty())
   {
-    result = create_elements( typemap[curr_elem_type],
+    result = create_elements( GmshUtil::gmshElemTypes[curr_elem_type],
                               id_list,
                               mat_set_list,
                               geom_set_list,
@@ -419,7 +366,7 @@
 }
 
 //! Create an element sequence
-MBErrorCode ReadGmsh::create_elements( const ElementType& type,
+MBErrorCode ReadGmsh::create_elements( const GmshElemType& type,
                                const std::vector<int>& elem_ids,
                                const std::vector<int>& matl_ids,
                                const std::vector<int>& geom_ids,
@@ -431,7 +378,7 @@
   
     // Make sure input is consistent
   const unsigned long num_elem = elem_ids.size();
-  const int node_per_elem = type.nodes;
+  const int node_per_elem = type.num_nodes;
   if (matl_ids.size() != num_elem ||
       geom_ids.size() != num_elem ||
       prtn_ids.size() != num_elem ||
@@ -441,7 +388,7 @@
     // Create the element sequence
   MBEntityHandle handle = 0;
   MBEntityHandle* conn_array;
-  result = readMeshIface->get_element_array( num_elem, node_per_elem, type.mbtype,
+  result = readMeshIface->get_element_array( num_elem, node_per_elem, type.mb_type,
                                              MB_START_ID, 
                                              handle, conn_array );
   if (MB_SUCCESS != result)
@@ -480,15 +427,15 @@
   }
   
     // Add elements to material sets
-  result = create_sets( type.mbtype, elements, matl_ids, 0 );
+  result = create_sets( type.mb_type, elements, matl_ids, 0 );
   if (MB_SUCCESS != result)
     return result;
     // Add elements to geometric sets
-  result = create_sets( type.mbtype, elements, geom_ids, 1 );
+  result = create_sets( type.mb_type, elements, geom_ids, 1 );
   if (MB_SUCCESS != result)
     return result;
     // Add elements to parallel partitions
-  result = create_sets( type.mbtype, elements, prtn_ids, 2 );
+  result = create_sets( type.mb_type, elements, prtn_ids, 2 );
   if (MB_SUCCESS != result)
     return result;
   

Modified: MOAB/trunk/ReadGmsh.hpp
===================================================================
--- MOAB/trunk/ReadGmsh.hpp	2009-09-30 17:55:13 UTC (rev 3177)
+++ MOAB/trunk/ReadGmsh.hpp	2009-09-30 19:06:31 UTC (rev 3178)
@@ -28,6 +28,7 @@
 #include "MBRange.hpp"
 
 class MBReadUtilIface;
+struct GmshElemType;
 
 // Base class for binary and ASCII readers
 class ReadGmsh : public MBReaderIface
@@ -58,12 +59,6 @@
    //! Destructor
   virtual ~ReadGmsh();
 
-  struct ElementType {
-    MBEntityType mbtype;
-    int nodes;
-    const int* node_order;
-  };
-
 private:
 
   MBErrorCode load_file_impl( const char *file_name,
@@ -71,7 +66,7 @@
                               const int num_material_sets,
                               const MBTag* file_id_tag );
   
-  MBErrorCode create_elements( const ElementType& type,
+  MBErrorCode create_elements( const GmshElemType& type,
                                const std::vector<int>& elem_ids,
                                const std::vector<int>& matl_ids,
                                const std::vector<int>& geom_ids,

Modified: MOAB/trunk/WriteGmsh.cpp
===================================================================
--- MOAB/trunk/WriteGmsh.cpp	2009-09-30 17:55:13 UTC (rev 3177)
+++ MOAB/trunk/WriteGmsh.cpp	2009-09-30 19:06:31 UTC (rev 3178)
@@ -6,6 +6,7 @@
 #include "MBRange.hpp"
 #include "MBWriteUtilIface.hpp"
 #include "FileOptions.hpp"
+#include "GmshUtil.hpp"
 
 #include <fstream>
 #include <map>
@@ -29,14 +30,7 @@
   mbImpl->release_interface("MBWriteUtilIface", mWriteIface);
 }
 
-// Type info indexed by type id used in file format.
-const int hex_27_node_order[] =  {  
-    0,  1,  2,  3,  4,  5,  6,  7,                 // corners
-    8, 11, 12,  9, 13, 10, 14, 15, 16, 19, 17, 18, // edges
-   24, 20, 23, 21, 22, 25,                         // faces
-   26 };                                           // volume
 
-
   // A structure to store per-element information.
 struct ElemInfo { 
   void set( int set, int id ) {
@@ -188,20 +182,9 @@
     rval = mbImpl->get_connectivity( *i, conn, num_vtx );
     if (MB_SUCCESS != rval)
       return rval;
-      
-    switch (type) 
-    {
-      case MBEDGE:    ei.type = num_vtx == 2 ? 1 :                      8; break;
-      case MBTRI:     ei.type = num_vtx == 3 ? 2 :                      9; break;
-      case MBQUAD:    ei.type = num_vtx == 4 ? 3 :                     10; break;
-      case MBPYRAMID: ei.type = num_vtx == 5 ? 7 :                      0; break;
-      case MBPRISM:   ei.type = num_vtx == 6 ? 6 :                      0; break;
-      case MBTET:     ei.type = num_vtx == 4 ? 4 : num_vtx == 10 ? 11 : 0; break;
-      case MBHEX:     ei.type = num_vtx == 8 ? 5 : num_vtx == 27 ? 12 : 0; break;
-      default:        ei.type = 0;
-    }
     
-    if (ei.type == 0) 
+    ei.type = GmshUtil::get_gmsh_type( type, num_vtx );
+    if (ei.type < 0) 
     {
       mWriteIface->report_error( "Gmem file format does not support element "
                                  " of type %s with %d vertices.\n",
@@ -300,12 +283,14 @@
     out << i->second.id << ' ' << i->second.type << ' ' << i->second.count;
     for (int j = 0; j < i->second.count; ++j)
       out << ' ' << i->second.sets[j];
-      
-      // special case for Hex27 - need to re-order vertices
-    if (i->second.type == 12)
+    
+    const int* order = GmshUtil::gmshElemTypes[i->second.type].node_order;
+    
+      // need to re-order vertices
+    if (order)
     {
-      for (int j = 0; j < 27; ++j)
-        out << ' ' << mbImpl->id_from_handle( conn[hex_27_node_order[j]] );
+      for (int j = 0; j < num_vtx; ++j)
+        out << ' ' << mbImpl->id_from_handle( conn[order[j]] );
     }
     else
     {  



More information about the moab-dev mailing list