[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