[MOAB-dev] Fwd: commit/MOAB: iulian07: first pass at CGNS reader / writer

Iulian Grindeanu iulian at mcs.anl.gov
Thu Nov 21 08:33:09 CST 2013


Hello, 
I added a build with cgns on the buildbot 
http://gnep.mcs.anl.gov:8010/builders/moab-cgns 
Buildbot still runs on ubuntu 10.04, on gnep; 
this build uses a gnep-built cgns library, which is located here: 
/homes/fathom/3rdparty/cgns/cgns314 

On my machine (ubuntu 12.04), I have tested with this cgns 
/homes/fathom/3rdparty/cgns 

It works for me, but not for Rajeev. There are still some quirks related to hdf5 library not linked correctly. 

So far, all these cgns builds are static. This reader/writer works in serial, and it is a work done by Carlos Breviglieri and Junior Junqueira. Thank you! 

Best regards, 
Iulian 

----- Forwarded Message -----

From: commits-noreply at bitbucket.org 
To: moab-dev at mcs.anl.gov 
Sent: Wednesday, November 20, 2013 10:40:20 AM 
Subject: [MOAB-dev] commit/MOAB: iulian07: first pass at CGNS reader / writer 

1 new commit in MOAB: 

https://bitbucket.org/fathomteam/moab/commits/6cccf6afd097/ 
Changeset: 6cccf6afd097 
Branch: master 
User: iulian07 
Date: 2013-11-20 17:39:28 
Summary: first pass at CGNS reader / writer 

integrate contributions from Carlos Breviglieri and Junior 
Junqueira 

Affected #: 14 files 

diff --git a/Makefile.am b/Makefile.am 
index 1c91622..b8c3c9e 100644 
--- a/Makefile.am 
+++ b/Makefile.am 
@@ -48,7 +48,7 @@ install-data-hook: 
echo -n "SET(MOAB_LIBRARIES \"" >> $(DESTDIR)$(cfgdir)/MOABConfig.cmake 
# next line: get the post-substitution set of link commands, then filter out leading 
# and trailing spaces, then terminate with close-quote and close-paren 
- echo -n "@EXPORT_LDFLAGS@ -L$(MOAB_LIBDIR) -lMOAB @LIBS@ @PNETCDF_LIBS@ @NETCDF_LIBS@ @HDF5_LIBS@ @CCMIO_LIBS@ @CGM_LIBS@" | \ 
+ echo -n "@EXPORT_LDFLAGS@ -L$(libdir) -lMOAB @LIBS@ @PNETCDF_LIBS@ @NETCDF_LIBS@ @CGNS_LIBS@ @HDF5_LIBS@ @CCMIO_LIBS@ @CGM_LIBS@" | \ 
sed -e 's/^ *//;s/ *$$/\")\n/' >> $(DESTDIR)$(cfgdir)/MOABConfig.cmake 

# Generate a file to be installed in $libdir containing the configuration 

diff --git a/MeshFiles/unittest/io/2d_naca0012.cgns b/MeshFiles/unittest/io/2d_naca0012.cgns 
new file mode 100644 
index 0000000..4ce0452 
Binary files /dev/null and b/MeshFiles/unittest/io/2d_naca0012.cgns differ 

diff --git a/MeshFiles/unittest/io/Makefile.am b/MeshFiles/unittest/io/Makefile.am 
index fb8a265..b4077d0 100644 
--- a/MeshFiles/unittest/io/Makefile.am 
+++ b/MeshFiles/unittest/io/Makefile.am 
@@ -19,6 +19,7 @@ EXTRA_DIST = HommeMapping.nc \ 
test.unv \ 
sample.stl \ 
three.smf \ 
- mpasx1.642.t.2.nc 
+ mpasx1.642.t.2.nc \ 
+ 2d_naca0012.cgns 



diff --git a/config/cgns.m4 b/config/cgns.m4 
new file mode 100644 
index 0000000..16b19e3 
--- /dev/null 
+++ b/config/cgns.m4 
@@ -0,0 +1,92 @@ 
+####################################################################################### 
+# Check for CGNS library 
+# Sets HAVE_CGNS to 'yes' or 'no' 
+# If HAVE_CGNS == yes, then exports: 
+# CGNS_CPPFLAGS 
+# CGNS_LDFLAGS 
+# CGNS_LIBS 
+####################################################################################### 
+AC_DEFUN([FATHOM_CHECK_CGNS],[ 
+ 
+AC_MSG_CHECKING([if CGNS support is enabled]) 
+AC_ARG_WITH(cgns, 
+[AC_HELP_STRING([--with-cgns<:@=DIR@:>@], [Specify CGNS library to use for CGNS file format]) 
+AC_HELP_STRING([--without-cgns], [Disable support for CGNS file format])], 
+[CGNS_ARG=$withval 
+DISTCHECK_CONFIGURE_FLAGS="$DISTCHECK_CONFIGURE_FLAGS --with-cgns=\"${withval}\"" 
+] 
+, [CGNS_ARG=]) 
+if test "xno" != "x$CGNS_ARG"; then 
+ AC_MSG_RESULT([yes]) 
+else 
+ AC_MSG_RESULT([no]) 
+fi 
+ 
+ # if CGNS support is not disabled 
+HAVE_CGNS=no 
+if test "xno" != "x$CGNS_ARG"; then 
+ HAVE_CGNS=yes 
+ 
+ # if a path is specified, update LIBS and INCLUDES accordingly 
+ if test "xyes" != "x$CGNS_ARG" && test "x" != "x$CGNS_ARG"; then 
+ if test -d "${CGNS_ARG}/lib"; then 
+ CGNS_LDFLAGS="-L${CGNS_ARG}/lib" 
+ elif test -d "${CGNS_ARG}"; then 
+ CGNS_LDFLAGS="-L${CGNS_ARG}" 
+ else 
+ AC_MSG_ERROR("$CGNS_ARG is not a directory.") 
+ fi 
+ if test -d "${CGNS_ARG}/include"; then 
+ CGNS_CPPFLAGS="-I${CGNS_ARG}/include" 
+ elif test -d "${CGNS_ARG}/inc"; then 
+ CGNS_CPPFLAGS="-I${CGNS_ARG}/inc" 
+ else 
+ CGNS_CPPFLAGS="-I${CGNS_ARG}" 
+ fi 
+ fi 
+ 
+ old_CPPFLAGS="$CPPFLAGS" 
+ CPPFLAGS="$CGNS_CPPFLAGS $CPPFLAGS" 
+ old_LDFLAGS="$LDFLAGS" 
+ LDFLAGS="$CGNS_LDFLAGS $HDF5_LDFLAGS $LDFLAGS" 
+ 
+ # Check for C library 
+ AC_LANG_PUSH([C]) 
+ 
+ AC_CHECK_HEADER([cgnslib.h], [], 
+ [AC_MSG_WARN([[CGNS header not found.]]); HAVE_CGNS=no] ) 
+ 
+ # Check if cgns is usable by itself 
+ AC_CHECK_LIB( [cgns], [cg_open], [CGNS_LIBS="-lcgns"], [ 
+ # Check if cgns is usable with HDF5 
+ unset ac_cv_lib_cgns 
+ unset ac_cv_lib_cgns_cg_open 
+ # If we haven't already looked for HDF5 libraries, again now incase 
+ # they're in the CGNS lib directory. 
+ FATHOM_DETECT_HDF5_LIBS 
+ LDFLAGS="$LDFLAGS $HDF5_LDFLAGS" 
+ AC_CHECK_LIB( [cgns], [cg_open], [CGNS_LIBS="-lcgns -lhdf5_hl"], [ 
+ # Try one more time with HDF5 and libcurl 
+ unset ac_cv_lib_cgns 
+ unset ac_cv_lib_cgns_cg_open 
+ AC_CHECK_LIB( [cgns], [cg_open], [CGNS_LIBS="-lcgns -lhdf5_hl -lcurl"], 
+ [HAVE_CGNS=no], [-lhdf5_hl $HDF5_LIBS -lcurl] )], 
+ [-lhdf5_hl $HDF5_LIBS] )], 
+ ) 
+ 
+ CPPFLAGS="$old_CPPFLAGS" 
+ LDFLAGS="$old_LDFLAGS" 
+ AC_LANG_POP([C]) 
+ 
+ if test "x$HAVE_CGNS" = "xno"; then 
+ if test "x$CGNS_ARG" != "x"; then 
+ AC_MSG_ERROR("CGNS not found or not working") 
+ else 
+ AC_MSG_WARN("CGNS support disabled") 
+ fi 
+ CGNS_CPPFLAGS= 
+ CGNS_LDFLAGS= 
+ fi 
+fi 
+ 
+]) # FATHOM_HAVE_CGNS 

diff --git a/configure.ac b/configure.ac 
index bdc225b..ea22a5e 100644 
--- a/configure.ac 
+++ b/configure.ac 
@@ -446,6 +446,22 @@ AM_CPPFLAGS="$PNETCDF_CPPFLAGS $AM_CPPFLAGS" 
EXPORT_LDFLAGS="$PNETCDF_LDFLAGS $EXPORT_LDFLAGS" 
AC_SUBST(PNETCDF_LIBS) 

+################################################################################ 
+# CGNS OPTIONS 
+################################################################################ 
+ 
+old_LDFLAGS="$LDFLAGS" 
+LDFLAGS="$LDFLAGS $HDF5_LDFLAGS" 
+FATHOM_CHECK_CGNS 
+LDFLAGS="$old_LDFLAGS" 
+if test "xno" != "x$HAVE_CGNS"; then 
+ AM_CPPFLAGS="$AM_CPPFLAGS -DCGNS_FILE" 
+fi 
+AM_CONDITIONAL(CGNS_FILE, [test "xno" != "x$HAVE_CGNS"]) 
+AM_CPPFLAGS="$CGNS_CPPFLAGS $AM_CPPFLAGS" 
+EXPORT_LDFLAGS="$CGNS_LDFLAGS $EXPORT_LDFLAGS" 
+AC_SUBST(CGNS_LIBS) 
+ 

################################################################################# 
# Documentation 

diff --git a/moab.make.in b/moab.make.in 
index 45f80de..4519175 100644 
--- a/moab.make.in 
+++ b/moab.make.in 
@@ -16,7 +16,7 @@ MOAB_FFLAGS = @FFLAGS@ 
MOAB_FCFLAGS = @FCFLAGS@ 
MOAB_LDFLAGS = @EXPORT_LDFLAGS@ 

-MOAB_LIBS_LINK = ${MOAB_LDFLAGS} -L${MOAB_LIBDIR} -lMOAB @LIBS@ @PNETCDF_LIBS@ @NETCDF_LIBS@ @HDF5_LIBS@ @CCMIO_LIBS@ @CGM_LIBS@ @ZOLTAN_LIBS@ 
+MOAB_LIBS_LINK = ${MOAB_LDFLAGS} -L${MOAB_LIBDIR} -lMOAB @LIBS@ @PNETCDF_LIBS@ @NETCDF_LIBS@ @CGNS_LIBS@ @HDF5_LIBS@ @CCMIO_LIBS@ @CGM_LIBS@ @ZOLTAN_LIBS@ 

MOAB_CXX = @CXX@ 
MOAB_CC = @CC@ 

diff --git a/src/ReaderWriterSet.cpp b/src/ReaderWriterSet.cpp 
index 8185b34..5015a7f 100644 
--- a/src/ReaderWriterSet.cpp 
+++ b/src/ReaderWriterSet.cpp 
@@ -1,16 +1,16 @@ 
/** 
* 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 "moab/Core.hpp" 
@@ -54,11 +54,16 @@ 
#endif 

// 2nd include of ReadNC in case we have pnetcdf and not netcdf 
-#ifdef PNETCDF_FILE 
+#ifdef PNETCDF_FILE 
# include "ReadNC.hpp" 
# include "ReadGCRM.hpp" 
#endif 

+#ifdef CGNS_FILE 
+# include "ReadCGNS.hpp" 
+# include "WriteCGNS.hpp" 
+#endif 
+ 
#ifdef CCMIO_FILE 
# include "ReadCCMIO.hpp" 
# include "WriteCCMIO.hpp" 
@@ -83,15 +88,15 @@ 
namespace moab { 

ReaderWriterSet::ReaderWriterSet( Core* mdb, Error* handler ) 
- : mbCore( mdb ), mbError( handler ) 
+ : mbCore( mdb ), mbError( handler ) 
{ 
#ifdef HDF5_FILE 
const char* hdf5_sufxs[] = { "h5m", "mhdf", NULL }; 
#ifdef HDF5_PARALLEL 
- register_factory( ReadHDF5::factory, WriteHDF5Parallel::factory, 
+ register_factory( ReadHDF5::factory, WriteHDF5Parallel::factory, 
"MOAB native (HDF5)", hdf5_sufxs, "MOAB" ); 
#else 
- register_factory( ReadHDF5::factory, WriteHDF5::factory, 
+ register_factory( ReadHDF5::factory, WriteHDF5::factory, 
"MOAB native (HDF5)", hdf5_sufxs, "MOAB" ); 
#endif 
#endif 
@@ -103,21 +108,26 @@ ReaderWriterSet::ReaderWriterSet( Core* mdb, Error* handler ) 
register_factory( ReadNC::factory, NULL, "Climate NC", "nc", "NC" ); 
#endif 

+#ifdef CGNS_FILE 
+ const char* cgns_sufxs[] = { "cgns", NULL }; 
+ register_factory( ReadCGNS::factory, WriteCGNS::factory, "CGNS", cgns_sufxs, "CGNS" ); 
+#endif 
+ 
register_factory( ReadIDEAS::factory, NULL, "IDEAS format", "unv", "UNV" ); 
- 
+ 
register_factory( ReadMCNP5::factory, NULL, "MCNP5 format", "meshtal", "MESHTAL" ); 
- 
+ 
const char* nastran_sufxs[] = { "nas", "bdf", NULL }; 
register_factory( ReadNASTRAN::factory, NULL, "NASTRAN format", nastran_sufxs, "NAS" ); 

register_factory( ReadABAQUS::factory, NULL, "ABAQUS INP mesh format", "abq", "Abaqus mesh" ); 
- 
+ 
register_factory( ReadVtk::factory, WriteVtk::factory, "Kitware VTK", "vtk", "VTK" ); 
- 
+ 
register_factory( ReadSms::factory, NULL, "RPI SMS", "sms", "SMS" ); 
- 
+ 
register_factory( Tqdcfr::factory, NULL, "Cubit", "cub", "CUBIT" ); 
- 
+ 
register_factory( ReadSmf::factory, WriteSmf::factory , "QSlim format", "smf", "SMF"); 

#ifdef CGM 
@@ -131,27 +141,27 @@ ReaderWriterSet::ReaderWriterSet( Core* mdb, Error* handler ) 
register_factory( ReadCGM::factory, NULL, "IGES B-Rep exchange", iges_sufxs, "IGES"); 
#endif 

-#ifdef NETCDF_FILE 
+#ifdef NETCDF_FILE 
register_factory( NULL, WriteSLAC::factory, "SLAC", "slac", "SLAC" ); 
#endif 

-#ifdef CCMIO_FILE 
+#ifdef CCMIO_FILE 
const char* ccmio_sufxs[] = { "ccm", "ccmg", NULL }; 
register_factory( ReadCCMIO::factory, WriteCCMIO::factory, "CCMIO files", ccmio_sufxs, "CCMIO"); 
#endif 

-#ifdef DAMSEL_FILE 
+#ifdef DAMSEL_FILE 
const char* damsel_sufxs[] = { "h5", NULL }; 
register_factory( ReadDamsel::factory, WriteDamsel::factory, "Damsel files", damsel_sufxs, "DAMSEL"); 
#endif 

register_factory( NULL, WriteGMV::factory, "GMV", "gmv", "GMV" ); 
- 
+ 
register_factory( NULL, WriteAns::factory, "Ansys", "ans", "ANSYS" ); 
- 
+ 
const char* gmsh_sufxs[] = { "msh", "gmsh", NULL }; 
register_factory( ReadGmsh::factory, WriteGmsh::factory, "Gmsh mesh file", gmsh_sufxs, "GMSH" ); 
- 
+ 
register_factory( ReadSTL::factory, WriteSTL::factory, "Stereo Lithography File (STL)", "stl", "STL" ); 

const char* tetgen_sufxs[] = { "node", "ele", "face", "edge", NULL }; 
@@ -178,7 +188,7 @@ ErrorCode ReaderWriterSet::register_factory( reader_factory_t reader, 
{ 
if (!reader && !writer) 
return MB_FAILURE; 
- 
+ 
// check for duplicate names 
iterator h = handler_by_name( name ); 
if (h != end()) { 
@@ -186,7 +196,7 @@ ErrorCode ReaderWriterSet::register_factory( reader_factory_t reader, 
name ); 
return MB_FAILURE; 
} 
- 
+ 
// count extensions and check for duplicates 
const char* const* iter; 
for (iter = extensions; *iter; ++iter) 
@@ -206,7 +216,7 @@ ErrorCode ReaderWriterSet::register_factory( reader_factory_t reader, 
} 
handlerList.push_back( Handler(reader, writer, name, description, extensions, iter - extensions) ); 
return MB_SUCCESS; 
-} 
+} 

ErrorCode ReaderWriterSet::register_factory( reader_factory_t reader, 
writer_factory_t writer, 
@@ -218,8 +228,8 @@ ErrorCode ReaderWriterSet::register_factory( reader_factory_t reader, 
return register_factory( reader, writer, description, extensions, name ); 
} 

- 
-ReaderIface* ReaderWriterSet::get_file_extension_reader( 
+ 
+ReaderIface* ReaderWriterSet::get_file_extension_reader( 
const std::string& filename ) const 
{ 
std::string ext = extension_from_filename( filename ); 
@@ -227,7 +237,7 @@ ReaderIface* ReaderWriterSet::get_file_extension_reader( 
return handler == end() ? NULL : handler->make_reader(mbCore); 
} 

-WriterIface* ReaderWriterSet::get_file_extension_writer( 
+WriterIface* ReaderWriterSet::get_file_extension_writer( 
const std::string& filename ) const 
{ 
std::string ext = extension_from_filename( filename ); 
@@ -235,7 +245,7 @@ WriterIface* ReaderWriterSet::get_file_extension_writer( 
return handler == end() ? NULL : handler->make_writer(mbCore); 
} 

-std::string ReaderWriterSet::extension_from_filename( 
+std::string ReaderWriterSet::extension_from_filename( 
const std::string& filename ) 
{ 
std::string::size_type idx = filename.find_last_of( "." ); 
@@ -245,11 +255,11 @@ std::string ReaderWriterSet::extension_from_filename( 
return filename.substr( idx + 1 ); 
} 

-ReaderWriterSet::Handler::Handler( reader_factory_t read_f, 
+ReaderWriterSet::Handler::Handler( reader_factory_t read_f, 
writer_factory_t write_f, 
const char* nm, 
- const char* desc, 
- const char* const* ext, 
+ const char* desc, 
+ const char* const* ext, 
int num_ext ) 
: mReader(read_f), mWriter(write_f), mName(nm), mDescription(desc), mExtensions(num_ext) 
{ 
@@ -261,45 +271,45 @@ ReaderWriterSet::Handler::Handler( reader_factory_t read_f, 
#define strcasecmp(A,B) _stricmp( A, B ) 
#endif 

-ReaderWriterSet::iterator 
+ReaderWriterSet::iterator 
ReaderWriterSet::handler_from_extension( const std::string& ext, 
bool with_reader, 
bool with_writer ) const 
{ 
iterator iter; 
std::vector<std::string>::const_iterator siter; 
- 
+ 
// try case-sensitive compare 
for (iter = begin(); iter != end(); ++iter) 
{ 
if ((with_reader && !iter->have_reader()) || 
(with_writer && !iter->have_writer())) 
continue; 
- 
+ 
for (siter = iter->mExtensions.begin(); siter != iter->mExtensions.end(); ++siter) 
if (*siter == ext) 
return iter; 
} 
- 
+ 
// try case-insensitive compare 
for (iter = begin(); iter != end(); ++iter) 
{ 
if ((with_reader && !iter->have_reader()) || 
(with_writer && !iter->have_writer())) 
continue; 
- 
+ 
for (siter = iter->mExtensions.begin(); siter != iter->mExtensions.end(); ++siter) 
if (0 == strcasecmp( siter->c_str(), ext.c_str() )) 
return iter; 
} 
- 
+ 
return end(); 
} 

-bool ReaderWriterSet::Handler::reads_extension(const char *ext) const 
+bool ReaderWriterSet::Handler::reads_extension(const char *ext) const 
{ 
if (!have_reader()) return false; 
- 
+ 
std::vector<std::string>::const_iterator siter; 
for (siter = mExtensions.begin(); siter != mExtensions.end(); ++siter) 
if (!(*siter).compare(ext)) return true; 
@@ -308,10 +318,10 @@ bool ReaderWriterSet::Handler::reads_extension(const char *ext) const 
return false; 
} 

-bool ReaderWriterSet::Handler::writes_extension(const char *ext) const 
+bool ReaderWriterSet::Handler::writes_extension(const char *ext) const 
{ 
if (!have_writer()) return false; 
- 
+ 
std::vector<std::string>::const_iterator siter; 
for (siter = mExtensions.begin(); siter != mExtensions.end(); ++siter) 
if (!(*siter).compare(ext)) return true; 
@@ -335,7 +345,7 @@ bool ReaderWriterSet::Handler::operator==( const char* nm ) const 
return false; 
return *nm == '\0'; 
} 
- 
+ 
} // namespace moab 



diff --git a/src/io/Makefile.am b/src/io/Makefile.am 
index 60caa48..09fe3d3 100644 
--- a/src/io/Makefile.am 
+++ b/src/io/Makefile.am 
@@ -7,7 +7,7 @@ endif 

# Things to build 
noinst_LTLIBRARIES = libmoabio.la 
-libmoabio_la_LIBADD = $(NETCDF_LIBS) $(PNETCDF_LIBS) $(HDF5_LIBS) 
+libmoabio_la_LIBADD = $(NETCDF_LIBS) $(PNETCDF_LIBS) $(CGNS_LIBS) $(HDF5_LIBS) 

AM_CPPFLAGS += -DIS_BUILDING_MB \ 
-I.. -I$(srcdir)/.. -I$(srcdir)/../parallel 
@@ -43,6 +43,13 @@ if ENABLE_mbzoltan 
AM_CPPFLAGS += -I$(srcdir)/../../tools/mbzoltan $(ZOLTAN_INC_FLAGS) 
endif 

+if CGNS_FILE 
+ MOAB_CGNS_SRCS = ReadCGNS.cpp ReadCGNS.hpp \ 
+ WriteCGNS.cpp WriteCGNS.hpp 
+else 
+ MOAB_CGNS_SRCS = 
+endif 
+ 
if HDF5_FILE 
libmoabio_la_LIBADD += mhdf/libmhdf.la 
MOAB_HDF5_SRCS = HDF5Common.cpp \ 
@@ -139,6 +146,7 @@ libmoabio_la_SOURCES = \ 
WriteVtk.cpp \ 
WriteVtk.hpp \ 
$(MOAB_NETCDF_SRCS) \ 
+ $(MOAB_CGNS_SRCS) \ 
$(MOAB_HDF5_SRCS) \ 
$(MOAB_CCMIO_SRCS) \ 
$(MOAB_DAMSEL_SRCS) \ 

diff --git a/src/io/ReadCGNS.cpp b/src/io/ReadCGNS.cpp 
new file mode 100644 
index 0000000..d8f77e8 
--- /dev/null 
+++ b/src/io/ReadCGNS.cpp 
@@ -0,0 +1,613 @@ 
+/** 
+ * \class ReadCGNS 
+ * \brief Template for writing a new reader in MOAB 
+ * 
+ */ 
+ 
+#include "ReadCGNS.hpp" 
+#include "Internals.hpp" 
+#include "moab/Interface.hpp" 
+#include "moab/ReadUtilIface.hpp" 
+#include "moab/Range.hpp" 
+#include "moab/FileOptions.hpp" 
+#include "MBTagConventions.hpp" 
+#include "MBParallelConventions.h" 
+#include "moab/CN.hpp" 
+ 
+#include <cstdio> 
+#include <assert.h> 
+#include <errno.h> 
+#include <map> 
+#include <set> 
+ 
+#include <iostream> 
+#include <cmath> 
+ 
+namespace moab 
+{ 
+ 
+ReaderIface* ReadCGNS::factory(Interface* iface) 
+{ 
+ return new ReadCGNS(iface); 
+} 
+ 
+ReadCGNS::ReadCGNS(Interface* impl) 
+ : mbImpl(impl) 
+{ 
+ mbImpl->query_interface(readMeshIface); 
+} 
+ 
+ReadCGNS::~ReadCGNS() 
+{ 
+ if (readMeshIface) { 
+ mbImpl->release_interface(readMeshIface); 
+ readMeshIface = 0; 
+ } 
+} 
+ 
+ 
+ErrorCode ReadCGNS::read_tag_values(const char* /* file_name */, 
+ const char* /* tag_name */, 
+ const FileOptions& /* opts */, 
+ std::vector<int>& /* tag_values_out */, 
+ const SubsetList* /* subset_list */) 
+{ 
+ return MB_NOT_IMPLEMENTED; 
+} 
+ 
+ 
+ErrorCode ReadCGNS::load_file(const char* filename, 
+ const EntityHandle * /*file_set*/, 
+ const FileOptions& opts, 
+ const ReaderIface::SubsetList* subset_list, 
+ const Tag* file_id_tag) 
+{ 
+ 
+ int num_material_sets = 0; 
+ const int* material_set_list = 0; 
+ 
+ if (subset_list) { 
+ if (subset_list->tag_list_length > 1 && 
+ !strcmp(subset_list->tag_list[0].tag_name, MATERIAL_SET_TAG_NAME)) { 
+ readMeshIface->report_error("CGNS supports subset read only by material ID."); 
+ return MB_UNSUPPORTED_OPERATION; 
+ } 
+ material_set_list = subset_list->tag_list[0].tag_values; 
+ num_material_sets = subset_list->tag_list[0].num_tag_values; 
+ } 
+ 
+ 
+ ErrorCode result; 
+ 
+ geomSets.clear(); 
+ result = mbImpl->tag_get_handle(GLOBAL_ID_TAG_NAME, 1, MB_TYPE_INTEGER, 
+ globalId, MB_TAG_DENSE | MB_TAG_CREAT, 0); 
+ if (MB_SUCCESS != result) 
+ return result; 
+ 
+ // Create set for more convienient check for material set ids 
+ std::set<int> blocks; 
+ for (const int* mat_set_end = material_set_list + num_material_sets; 
+ material_set_list != mat_set_end; ++material_set_list) 
+ blocks.insert(*material_set_list); 
+ 
+ // Map of ID->handle for nodes 
+ std::map<long, EntityHandle> node_id_map; 
+ 
+ 
+ // save filename to member variable so we don't need to pass as an argument 
+ // to called functions 
+ fileName = filename; 
+ 
+ // process options; see src/FileOptions.hpp for API for FileOptions class, and doc/metadata_info.doc for 
+ // a description of various options used by some of the readers in MOAB 
+ result = process_options(opts); 
+ if (MB_SUCCESS != result) { 
+ readMeshIface->report_error("%s: problem reading options\n", fileName); 
+ return result; 
+ } 
+ 
+ // Open file 
+ int filePtr = 0; 
+ 
+ cg_open(filename, CG_MODE_READ, &filePtr); 
+ 
+ if (filePtr <= 0) { 
+ readMeshIface->report_error("%s: fopen returned error.\n", fileName); 
+ return MB_FILE_DOES_NOT_EXIST; 
+ } 
+ 
+ // read number of verts, elements, sets 
+ long num_verts = 0, num_elems = 0, num_sets = 0; 
+ int num_bases = 0, num_zones = 0, num_sections = 0; 
+ 
+ char zoneName[128]; 
+ cgsize_t size[3]; 
+ 
+ mesh_dim = 3; // default to 3D 
+ 
+ // Read number of bases; 
+ cg_nbases(filePtr, &num_bases); 
+ 
+ if (num_bases > 1) { 
+ readMeshIface->report_error("%s: support for number of bases > 1 not implemented.\n", fileName); 
+ return MB_NOT_IMPLEMENTED; 
+ } 
+ 
+ for (int indexBase = 1; indexBase <= num_bases; ++indexBase) { 
+ 
+ // Get the number of zones/blocks in current base. 
+ cg_nzones(filePtr, indexBase, &num_zones); 
+ 
+ if (num_zones > 1) { 
+ readMeshIface->report_error("%s: support for number of zones > 1 not implemented.\n", fileName); 
+ return MB_NOT_IMPLEMENTED; 
+ } 
+ 
+ for (int indexZone = 1; indexZone <= num_zones; ++indexZone) { 
+ 
+ // get zone name and size. 
+ cg_zone_read(filePtr, indexBase, indexZone, zoneName, size); 
+ 
+ // Read number of sections/Parts in current zone. 
+ cg_nsections(filePtr, indexBase, indexZone, &num_sections); 
+ 
+ num_verts = size[0]; 
+ num_elems = size[1]; 
+ num_sets = num_sections; 
+ 
+ 
+ std::cout << "\nnumber of nodes = " << num_verts; 
+ std::cout << "\nnumber of elems = " << num_elems; 
+ std::cout << "\nnumber of parts = " << num_sets << std::endl; 
+ 
+ 
+ 
+ // ////////////////////////////////// 
+ // Read Nodes 
+ 
+ // allocate nodes; these are allocated in one shot, get contiguous handles starting with start_handle, 
+ // and the reader is passed back double*'s pointing to MOAB's native storage for vertex coordinates 
+ // for those verts 
+ std::vector<double*> coord_arrays; 
+ EntityHandle handle = 0; 
+ result = readMeshIface->get_node_coords(3, num_verts, MB_START_ID, handle, coord_arrays); 
+ if (MB_SUCCESS != result) { 
+ readMeshIface->report_error("%s: Trouble reading vertices\n", fileName); 
+ return result; 
+ } 
+ 
+ 
+ // fill in vertex coordinate arrays 
+ cgsize_t beginPos = 1, endPos = num_verts; 
+ 
+ 
+ // Read nodes coordinates. 
+ cg_coord_read(filePtr, indexBase, indexZone, "CoordinateX", 
+ RealDouble, &beginPos, &endPos, coord_arrays[0]); 
+ cg_coord_read(filePtr, indexBase, indexZone, "CoordinateY", 
+ RealDouble, &beginPos, &endPos, coord_arrays[1]); 
+ cg_coord_read(filePtr, indexBase, indexZone, "CoordinateZ", 
+ RealDouble, &beginPos, &endPos, coord_arrays[2]); 
+ 
+ // CGNS seems to always include the Z component, even if the mesh is 2D. 
+ // Check if Z is zero and determine mesh dimension. 
+ // Also create the node_id_map data. 
+ double sumZcoord = 0.0; 
+ double eps = 1.0e-12; 
+ for (long i = 0; i < num_verts; ++i, ++handle) { 
+ 
+ int index = i + 1; 
+ 
+ node_id_map.insert(std::pair<long, EntityHandle>(index, handle)).second; 
+ 
+ sumZcoord += *(coord_arrays[2] + i); 
+ } 
+ if (std::abs(sumZcoord) <= eps) mesh_dim = 2; 
+ 
+ 
+ // create reverse map from handle to id 
+ std::vector<int> ids(num_verts); 
+ std::vector<int>::iterator id_iter = ids.begin(); 
+ std::vector<EntityHandle> handles(num_verts); 
+ std::vector<EntityHandle>::iterator h_iter = handles.begin(); 
+ for (std::map<long, EntityHandle>::iterator i = node_id_map.begin(); 
+ i != node_id_map.end(); ++i, ++id_iter, ++h_iter) { 
+ *id_iter = i->first; 
+ * h_iter = i->second; 
+ } 
+ // store IDs in tags 
+ result = mbImpl->tag_set_data(globalId, &handles[0], num_verts, &ids[0]); 
+ if (MB_SUCCESS != result) 
+ return result; 
+ if (file_id_tag) { 
+ result = mbImpl->tag_set_data(*file_id_tag, &handles[0], num_verts, &ids[0]); 
+ if (MB_SUCCESS != result) 
+ return result; 
+ } 
+ ids.clear(); 
+ handles.clear(); 
+ 
+ 
+ 
+ // ////////////////////////////////// 
+ // Read elements data 
+ 
+ EntityType ent_type; 
+ 
+ long section_offset = 0; 
+ 
+ // Define which mesh parts are volume families. 
+ // mesh parts with volumeID[X] = 0 are boundary parts. 
+ std::vector<int> volumeID(num_sections, 0); 
+ 
+ 
+ for (int section = 0; section < num_sections; ++section) { 
+ 
+ ElementType_t elemsType; 
+ int iparent_flag, nbndry; 
+ char sectionName[128]; 
+ int verts_per_elem; 
+ 
+ int cgSection = section + 1; 
+ 
+ cg_section_read(filePtr, indexBase, indexZone, cgSection, sectionName, 
+ &elemsType, &beginPos, &endPos, &nbndry, &iparent_flag); 
+ 
+ size_t section_size = endPos - beginPos + 1; 
+ 
+ 
+ // Read element description in current section 
+ 
+ switch (elemsType) { 
+ case BAR_2: 
+ ent_type = MBEDGE; 
+ verts_per_elem = 2; 
+ break; 
+ case TRI_3: 
+ ent_type = MBTRI; 
+ verts_per_elem = 3; 
+ if (mesh_dim == 2) volumeID[section] = 1; 
+ break; 
+ case QUAD_4: 
+ ent_type = MBQUAD; 
+ verts_per_elem = 4; 
+ if (mesh_dim == 2) volumeID[section] = 1; 
+ break; 
+ case TETRA_4: 
+ ent_type = MBTET; 
+ verts_per_elem = 4; 
+ if (mesh_dim == 3) volumeID[section] = 1; 
+ break; 
+ case PYRA_5: 
+ ent_type = MBPYRAMID; 
+ verts_per_elem = 5; 
+ if (mesh_dim == 3) volumeID[section] = 1; 
+ break; 
+ case PENTA_6: 
+ ent_type = MBPRISM; 
+ verts_per_elem = 6; 
+ if (mesh_dim == 3) volumeID[section] = 1; 
+ break; 
+ case HEXA_8: 
+ ent_type = MBHEX; 
+ verts_per_elem = 8; 
+ if (mesh_dim == 3) volumeID[section] = 1; 
+ break; 
+ case MIXED: 
+ ent_type = MBMAXTYPE; 
+ verts_per_elem = 0; 
+ break; 
+ default: 
+ readMeshIface->report_error("%s: Trouble determining element type.\n", fileName); 
+ return MB_INDEX_OUT_OF_RANGE; 
+ break; 
+ } 
+ 
+ if (elemsType == TETRA_4 || elemsType == PYRA_5 || elemsType == PENTA_6 || elemsType == HEXA_8 || 
+ elemsType == TRI_3 || elemsType == QUAD_4 || ((elemsType == BAR_2) && mesh_dim == 2)) { 
+ 
+ // read connectivity into conn_array directly 
+ 
+ cgsize_t iparentdata; 
+ cgsize_t connDataSize; 
+ 
+ // get number of entries on the connectivity list for this section 
+ cg_ElementDataSize(filePtr, indexBase, indexZone, cgSection, &connDataSize); 
+ 
+ // need a temporary vector to later cast to conn_array. 
+ std::vector<cgsize_t> elemNodes(connDataSize); 
+ 
+ cg_elements_read(filePtr, indexBase, indexZone, cgSection, &elemNodes[0], &iparentdata); 
+ 
+ // ////////////////////////////////// 
+ // Create elements, sets and tags 
+ 
+ create_elements(sectionName, file_id_tag, 
+ ent_type, verts_per_elem, section_offset, section_size , elemNodes); 
+ 
+ 
+ } // homogeneous mesh type 
+ 
+ else if (elemsType == MIXED) { 
+ 
+ // We must first sort all elements connectivities into continuous vectors 
+ 
+ cgsize_t connDataSize; 
+ cgsize_t iparentdata; 
+ 
+ cg_ElementDataSize(filePtr, indexBase, indexZone, cgSection, &connDataSize); 
+ 
+ std::vector< cgsize_t > elemNodes(connDataSize); 
+ 
+ cg_elements_read(filePtr, indexBase, indexZone, cgSection, &elemNodes[0], &iparentdata); 
+ 
+ std::vector<cgsize_t> elemsConn_EDGE; 
+ std::vector<cgsize_t> elemsConn_TRI, elemsConn_QUAD; 
+ std::vector<cgsize_t> elemsConn_TET, elemsConn_PYRA, elemsConn_PRISM, elemsConn_HEX; 
+ cgsize_t count_EDGE, count_TRI, count_QUAD; 
+ cgsize_t count_TET, count_PYRA, count_PRISM, count_HEX; 
+ 
+ 
+ // First, get elements count for current section 
+ 
+ count_EDGE = count_TRI = count_QUAD = 0; 
+ count_TET = count_PYRA = count_PRISM = count_HEX = 0; 
+ 
+ int connIndex = 0; 
+ for (int i = beginPos; i <= endPos; i++) { 
+ 
+ elemsType = ElementType_t(elemNodes[connIndex]); 
+ 
+ // get current cell node count. 
+ cg_npe(elemsType, &verts_per_elem); 
+ 
+ switch (elemsType) { 
+ case BAR_2: 
+ count_EDGE += 1; 
+ break; 
+ case TRI_3: 
+ count_TRI += 1; 
+ break; 
+ case QUAD_4: 
+ count_QUAD += 1; 
+ break; 
+ case TETRA_4: 
+ count_TET += 1; 
+ break; 
+ case PYRA_5: 
+ count_PYRA += 1; 
+ break; 
+ case PENTA_6: 
+ count_PRISM += 1; 
+ break; 
+ case HEXA_8: 
+ count_HEX += 1; 
+ break; 
+ default: 
+ readMeshIface->report_error("%s: Trouble determining element type.\n", fileName); 
+ return MB_INDEX_OUT_OF_RANGE; 
+ break; 
+ } 
+ 
+ connIndex += (verts_per_elem + 1); // add one to skip next element descriptor 
+ 
+ } 
+ 
+ if (count_EDGE > 0) elemsConn_EDGE.resize(count_EDGE * 2); 
+ if (count_TRI > 0) elemsConn_TRI.resize(count_TRI * 3); 
+ if (count_QUAD > 0) elemsConn_QUAD.resize(count_QUAD * 4); 
+ if (count_TET > 0) elemsConn_TET.resize(count_TET * 4); 
+ if (count_PYRA > 0) elemsConn_PYRA.resize(count_PYRA * 5); 
+ if (count_PRISM > 0) elemsConn_PRISM.resize(count_PRISM * 6); 
+ if (count_HEX > 0) elemsConn_HEX.resize(count_HEX * 8); 
+ 
+ // grab mixed section elements connectivity 
+ 
+ int idx_edge, idx_tri, idx_quad; 
+ int idx_tet, idx_pyra, idx_prism, idx_hex; 
+ idx_edge = idx_tri = idx_quad = 0; 
+ idx_tet = idx_pyra = idx_prism = idx_hex = 0; 
+ 
+ 
+ connIndex = 0; 
+ for (int i = beginPos; i <= endPos; i++) { 
+ 
+ elemsType = ElementType_t(elemNodes[connIndex]); 
+ 
+ // get current cell node count. 
+ cg_npe(elemsType, &verts_per_elem); 
+ 
+ switch (elemsType) { 
+ case BAR_2: 
+ for (int j = 0; j < 2; ++j) elemsConn_EDGE[idx_edge + j] = elemNodes[connIndex + j + 1]; 
+ idx_edge += 2; 
+ break; 
+ case TRI_3: 
+ for (int j = 0; j < 3; ++j) elemsConn_TRI[idx_tri + j] = elemNodes[connIndex + j + 1]; 
+ idx_tri += 3; 
+ break; 
+ case QUAD_4: 
+ for (int j = 0; j < 4; ++j) elemsConn_QUAD[idx_quad + j] = elemNodes[connIndex + j + 1]; 
+ idx_quad += 4; 
+ break; 
+ case TETRA_4: 
+ for (int j = 0; j < 4; ++j) elemsConn_TET[idx_tet + j] = elemNodes[connIndex + j + 1]; 
+ idx_tet += 4; 
+ break; 
+ case PYRA_5: 
+ for (int j = 0; j < 5; ++j) elemsConn_PYRA[idx_pyra + j] = elemNodes[connIndex + j + 1]; 
+ idx_pyra += 5; 
+ break; 
+ case PENTA_6: 
+ for (int j = 0; j < 6; ++j) elemsConn_PRISM[idx_prism + j] = elemNodes[connIndex + j + 1]; 
+ idx_prism += 6; 
+ break; 
+ case HEXA_8: 
+ for (int j = 0; j < 8; ++j) elemsConn_HEX[idx_hex + j] = elemNodes[connIndex + j + 1]; 
+ idx_hex += 8; 
+ break; 
+ default: 
+ readMeshIface->report_error("%s: Trouble determining element type.\n", fileName); 
+ return MB_INDEX_OUT_OF_RANGE; 
+ break; 
+ } 
+ 
+ connIndex += (verts_per_elem + 1); // add one to skip next element descriptor 
+ 
+ } 
+ 
+ 
+ // ////////////////////////////////// 
+ // Create elements, sets and tags 
+ 
+ if (count_EDGE > 0) 
+ create_elements(sectionName, file_id_tag, MBEDGE, 2, section_offset, count_EDGE, elemsConn_EDGE); 
+ 
+ if (count_TRI > 0) 
+ create_elements(sectionName, file_id_tag, MBTRI, 3, section_offset, count_TRI, elemsConn_TRI); 
+ 
+ if (count_QUAD > 0) 
+ create_elements(sectionName, file_id_tag, MBQUAD, 4, section_offset, count_QUAD, elemsConn_QUAD); 
+ 
+ if (count_TET > 0) 
+ create_elements(sectionName, file_id_tag, MBTET, 4, section_offset, count_TET, elemsConn_TET); 
+ 
+ if (count_PYRA > 0) 
+ create_elements(sectionName, file_id_tag, MBPYRAMID, 5, section_offset, count_PYRA, elemsConn_PYRA); 
+ 
+ if (count_PRISM > 0) 
+ create_elements(sectionName, file_id_tag, MBPRISM, 6, section_offset, count_PRISM, elemsConn_PRISM); 
+ 
+ if (count_HEX > 0) 
+ create_elements(sectionName, file_id_tag, MBHEX, 8, section_offset, count_HEX, elemsConn_HEX); 
+ 
+ } // mixed mesh type 
+ 
+ } // num_sections 
+ 
+ cg_close(filePtr); 
+ 
+ return result; 
+ 
+ } // indexZone for 
+ 
+ } // indexBase for 
+ 
+ return MB_SUCCESS; 
+ 
+} 
+ 
+ErrorCode ReadCGNS::create_elements(char *sectionName, 
+ const Tag *file_id_tag, 
+ const EntityType &ent_type, 
+ const int& verts_per_elem, 
+ long &section_offset, 
+ int elems_count, 
+ const std::vector<cgsize_t>& elemsConn) 
+{ 
+ 
+ ErrorCode result; 
+ 
+ // Create the element sequence; passes back a pointer to the internal storage for connectivity and the 
+ // starting entity handle 
+ EntityHandle* conn_array; 
+ EntityHandle handle = 0; 
+ 
+ result = readMeshIface->get_element_connect(elems_count, verts_per_elem, ent_type, 1, handle, conn_array); 
+ 
+ if (MB_SUCCESS != result) { 
+ readMeshIface->report_error("%s: Trouble reading elements\n", fileName); 
+ return result; 
+ } 
+ 
+ memcpy(conn_array, &elemsConn[0], elemsConn.size() * sizeof(EntityHandle)); 
+ 
+ // notify MOAB of the new elements 
+ result = readMeshIface->update_adjacencies(handle, elems_count, verts_per_elem, conn_array); 
+ if (MB_SUCCESS != result) return result; 
+ 
+ 
+ // ////////////////////////////////// 
+ // Create sets and tags 
+ 
+ Range elements(handle, handle + elems_count - 1); 
+ 
+ // Store element IDs 
+ 
+ std::vector<int> id_list(elems_count); 
+ 
+ // add 1 to offset id to 1-based numbering 
+ for (cgsize_t i = 0; i < elems_count; ++i) id_list[i] = i + 1 + section_offset; 
+ section_offset += elems_count; 
+ 
+ create_sets(sectionName, file_id_tag, ent_type, elements, id_list, 0); 
+ 
+ return MB_SUCCESS; 
+ 
+} 
+ 
+ 
+ErrorCode ReadCGNS::create_sets(char *sectionName, 
+ const Tag *file_id_tag, 
+ EntityType /*element_type*/, 
+ const Range& elements, 
+ const std::vector<int>& set_ids, 
+ int /*set_type*/) 
+{ 
+ 
+ ErrorCode result; 
+ 
+ result = mbImpl->tag_set_data(globalId, elements, &set_ids[0]); 
+ if (MB_SUCCESS != result) return result; 
+ 
+ if (file_id_tag) { 
+ result = mbImpl->tag_set_data(*file_id_tag, elements, &set_ids[0]); 
+ if (MB_SUCCESS != result) return result; 
+ } 
+ 
+ result = MB_SUCCESS; 
+ EntityHandle set_handle; 
+ 
+ Tag tag_handle; 
+ 
+ const char* setName = sectionName; 
+ 
+ mbImpl->tag_get_handle(setName, 1, MB_TYPE_INTEGER, tag_handle, MB_TAG_SPARSE | MB_TAG_CREAT); 
+ 
+ // create set 
+ result = mbImpl->create_meshset(MESHSET_SET, set_handle); 
+ if (MB_SUCCESS != result) { 
+ readMeshIface->report_error("%s: Trouble creating set.\n", fileName); 
+ return result; 
+ } 
+ 
+// // add dummy values to current set 
+// std::vector<int> tags(set_ids.size(), 1); 
+// result = mbImpl->tag_set_data(tag_handle, elements, &tags[0]); 
+// if (MB_SUCCESS != result) return result; 
+ 
+ // add them to the set 
+ result = mbImpl->add_entities(set_handle, elements); 
+ if (MB_SUCCESS != result) { 
+ readMeshIface->report_error("%s: Trouble putting entities in set.\n", fileName); 
+ return result; 
+ } 
+ 
+ return MB_SUCCESS; 
+ 
+} 
+ 
+ 
+ErrorCode ReadCGNS::process_options(const FileOptions & opts) 
+{ 
+ // mark all options seen, to avoid compile warning on unused variable 
+ opts.mark_all_seen(); 
+ 
+ return MB_SUCCESS; 
+} 
+ 
+ 
+} // namespace moab 
+ 
+ 

diff --git a/src/io/ReadCGNS.hpp b/src/io/ReadCGNS.hpp 
new file mode 100644 
index 0000000..c0e25c6 
--- /dev/null 
+++ b/src/io/ReadCGNS.hpp 
@@ -0,0 +1,88 @@ 
+#ifndef READ_CGNS_HPP 
+#define READ_CGNS_HPP 
+ 
+#include "moab/ReaderIface.hpp" 
+#include "moab/Range.hpp" 
+ 
+#include "cgnslib.h" 
+ 
+namespace moab 
+{ 
+ 
+class ReadUtilIface; 
+class Interface; 
+ 
+/** 
+ * \brief Export CGNS files. 
+ * \author Carlos Breviglieri, Carlos Junqueira Junior 
+ */ 
+ 
+class ReadCGNS : public ReaderIface 
+{ 
+ 
+public: 
+ 
+ //! factory method 
+ static ReaderIface* factory(Interface*); 
+ 
+ ErrorCode load_file(const char* file_name, 
+ const EntityHandle* file_set, 
+ const FileOptions& opts, 
+ const SubsetList* subset_list = 0, 
+ const Tag* file_id_tag = 0); 
+ 
+ ErrorCode read_tag_values(const char* file_name, 
+ const char* tag_name, 
+ const FileOptions& opts, 
+ std::vector<int>& tag_values_out, 
+ const SubsetList* subset_list = 0); 
+ 
+ //! Constructor 
+ ReadCGNS(Interface* impl = NULL); 
+ 
+ //! Destructor 
+ virtual ~ReadCGNS(); 
+ 
+private: 
+ 
+ ErrorCode create_elements(char *sectionName, 
+ const Tag* file_id_tag, 
+ const EntityType& ent_type, 
+ const int& verts_per_elem, 
+ long& section_offset, 
+ int elems_count, 
+ const std::vector<cgsize_t>& elemsConn); 
+ 
+ ErrorCode create_sets(char* sectionName, 
+ const Tag* file_id_tag, 
+ EntityType element_type, 
+ const Range& elements, 
+ const std::vector<int>& set_ids, 
+ int set_type); 
+ 
+ ErrorCode create_geometric_topology(); 
+ 
+ /** \brief Process options passed into the reader 
+ * \param opts Options passed into this read 
+ */ 
+ ErrorCode process_options(const FileOptions &opts); 
+ 
+ const char *fileName; 
+ 
+ short mesh_dim; 
+ 
+ ReadUtilIface* readMeshIface; 
+ 
+ //! interface instance 
+ Interface* mbImpl; 
+ 
+ Tag globalId; 
+ Tag boundary; 
+ Range geomSets; 
+ 
+}; 
+ 
+} // namespace moab 
+ 
+#endif 
+ 

diff --git a/src/io/WriteCGNS.cpp b/src/io/WriteCGNS.cpp 
new file mode 100644 
index 0000000..5e6cfe4 
--- /dev/null 
+++ b/src/io/WriteCGNS.cpp 
@@ -0,0 +1,715 @@ 
+#include "WriteCGNS.hpp" 
+#include "moab/CN.hpp" 
+#include "MBTagConventions.hpp" 
+#include "MBParallelConventions.h" 
+#include "moab/Interface.hpp" 
+#include "moab/Range.hpp" 
+#include "moab/WriteUtilIface.hpp" 
+#include "moab/FileOptions.hpp" 
+#include "GmshUtil.hpp" 
+ 
+#include <fstream> 
+#include <map> 
+#include <set> 
+ 
+#include <iostream> 
+ 
+namespace moab { 
+ 
+WriterIface *WriteCGNS::factory( Interface* iface ) 
+ { return new WriteCGNS( iface ); } 
+ 
+WriteCGNS::WriteCGNS(Interface *impl) 
+ : mbImpl(impl), VrtSize(0), EdgeSize(0), FaceSize(0), CellSize(0) 
+{ 
+ impl->query_interface(mWriteIface); 
+} 
+ 
+WriteCGNS::~WriteCGNS() 
+{ 
+ mbImpl->release_interface(mWriteIface); 
+} 
+ 
+//! writes out a file 
+ErrorCode WriteCGNS::write_file(const char *file_name, 
+ const bool overwrite, 
+ const FileOptions& /*options*/, 
+ const EntityHandle */*output_list*/, 
+ const int /*num_sets*/, 
+ const std::vector<std::string>&, 
+ const Tag*, 
+ int, 
+ int ) 
+{ 
+ ErrorCode rval; 
+ 
+ if (!overwrite){ 
+ rval = mWriteIface->check_doesnt_exist( file_name ); 
+ if (MB_SUCCESS != rval) 
+ return rval; 
+ } 
+ std::cout << "THE CGNS CONVERSION ONLY WORKS FOR ENTITIES CITED BELOW:"; 
+ std::cout << "\n -MBVERTEX\n -MBEDGE\n -MBTRI\n -MBQUAD"; 
+ std::cout << "\n -MBTET\n -MBPYRAMID\n -MBHEX\n"; 
+ 
+ // Get entities to write 
+ // Get and count vertex entities 
+ rval = get_vertex_entities ( VrtSize, Nodes ); 
+ if (rval != MB_SUCCESS){ 
+ return rval; 
+ } 
+ // Get and count edge entities 
+ rval = get_edge_entities( EdgeSize, Edges ); 
+ if (rval != MB_SUCCESS){ 
+ return rval; 
+ } 
+ // Get and count face entities 
+ rval = get_face_entities( FaceSize, Faces ); 
+ if (rval != MB_SUCCESS){ 
+ return rval; 
+ } 
+ // Get and count cell entities 
+ rval = get_cell_entities( CellSize, Cells ); 
+ if (rval != MB_SUCCESS){ 
+ return rval; 
+ } 
+ std::cout << "\nThe Number of Vertex is " << VrtSize << ".\n"; 
+ std::cout << "The Number of Edges is " << EdgeSize << ".\n"; 
+ std::cout << "The Number of Faces is " << FaceSize << ".\n"; 
+ std::cout << "The Number of Cells is " << CellSize << ".\n\n"; 
+ 
+ // save filename to member variable so we don't need to pass as an argument 
+ // to called functions 
+ fileName = file_name; 
+ std::cout << fileName << " file is a " << physdim << "-D mesh.\n"; 
+ 
+ // Open file 
+ IndexFile = 0; 
+ 
+ // open the cgns file 
+ // filename: (input) Name of the CGNS file, including path name if necessary. There is no limit on the 
+ // length of this character variable. 
+ // CG_MODE_WRITE: (input) Mode used for opening the file. The modes currently supported are CG_MODE_READ, 
+ // CG_MODE_WRITE, and CG_MODE_MODIFY. 
+ // filePtr: (output) CGNS file index number. 
+ if ( cg_open(fileName, CG_MODE_WRITE, &IndexFile) ){ 
+ std::cout << "Error opening file\n"; 
+ cg_error_exit(); 
+ } 
+ // Give a base name 
+ BaseName = "Cgns Base"; 
+ if ( cg_base_write(IndexFile,BaseName,celldim,physdim,&IndexBase) ){ 
+ std::cout << "Error creating CGNS base"; 
+ } 
+ // Give a zone name 
+ ZoneName = "Cgns Zone"; 
+ // isize array contains the total vertex size, cell size, and boundary 
+ // vertex size for the zone 
+ // Note that for unstructured zones, the index dimension is always 1 
+ isize[0] = VrtSize; // isize[0] contains the total vertex size 
+ isize[1] = CellSize; // isize[1] contains the total cell size 
+ isize[2] = 0; // isize[2] = 0 for unsorted elements 
+ // Create zone */ 
+ // ZoneType_t: Unstructured 
+ if ( cg_zone_write(IndexFile,IndexBase,ZoneName,isize,Unstructured,&IndexZone) ){ 
+ std::cout << "Error creating CGNS zone\n"; 
+ cg_error_exit(); 
+ } 
+ // Write the vertex coordinates 
+ rval = write_coord_cgns( Nodes ); 
+ if (rval != MB_SUCCESS){ 
+ return rval; 
+ } 
+ 
+ // Create a vector to hold the Tags 
+ std::vector<moab::Tag> TagHandles; 
+ // Get Tags 
+ rval = mbImpl->tag_get_tags( TagHandles ); 
+ if (rval != MB_SUCCESS){ 
+ return rval; 
+ } 
+ // Get the number of Tags in the mesh 
+ int NbTags = TagHandles.size(); 
+ std:: cout << "\nThe mesh has " << NbTags << " Tags.\n"; 
+ 
+ // Create a vector of size NbTags 
+ // Sets have informations about the entity set 
+ std::vector<SetStruct> Sets; 
+ Sets.reserve(NbTags); 
+ // Fill Sets with all information needed 
+ rval = set_tag_values( TagHandles, Edges, Faces, Cells, Sets ); 
+ if (rval != MB_SUCCESS){ 
+ std::cout << "Problem to set tag values\n"; 
+ return rval; 
+ } 
+ 
+ // Create a matrix to hold connectivity 
+ std::vector < std::vector<cgsize_t> > ConnTable; 
+ ConnTable.resize(NbTags); 
+ 
+ std::vector< int > Begin ( NbTags , 0 ); 
+ std::vector< int > End ( NbTags , 0 ); 
+ 
+ // Take the connectivity of higher dimension entities 
+ cgsize_t BeginSetsIndex = 1; 
+ cgsize_t EndSetsIndex; 
+ switch ( physdim ){ 
+ case 1: 
+ rval = get_conn_table( Edges, Begin, End, TagHandles, Sets, ConnTable ); 
+ if (rval != MB_SUCCESS){ 
+ std::cout << "Problem to fill the connectivity table for 1-D entities\n"; 
+ return rval; 
+ } 
+ for (int i = 0; i < NbTags; ++i) { 
+ if ( Sets[i].IdSet != -1 ){ 
+ const char * SectionName = Sets[i].TagName.c_str(); 
+ EndSetsIndex = BeginSetsIndex + Sets[i].NbEdges - 1; 
+ // Write the section in CGNS file 
+ if ( cg_section_write( IndexFile, IndexBase, IndexBase, SectionName, Sets[i].CGNSType, 
+ BeginSetsIndex, EndSetsIndex, 0, &ConnTable[i][0],&IndexSection) ){ 
+ std::cout << "Issue on writing connectivity - 3-D\n"; 
+ cg_error_exit(); 
+ } 
+ BeginSetsIndex = EndSetsIndex+1; 
+ } 
+ } 
+ break; 
+ case 2: 
+ rval = get_conn_table( Edges, Begin, End, TagHandles, Sets, ConnTable ); 
+ if (rval != MB_SUCCESS){ 
+ std::cout << "Problem to fill the connectivity table for 1-D entities\n"; 
+ return rval; 
+ } 
+ rval = get_conn_table( Faces, Begin, End, TagHandles, Sets, ConnTable ); 
+ if (rval != MB_SUCCESS){ 
+ std::cout << "Problem to fill the connectivity table for 2-D entities\n"; 
+ return rval; 
+ } 
+ for (int i = 0; i < NbTags; ++i) { 
+ if ( Sets[i].IdSet != -1 ){ 
+ const char * SectionName = Sets[i].TagName.c_str(); 
+ EndSetsIndex = BeginSetsIndex + Sets[i].NbEdges + Sets[i].NbFaces - 1; 
+ // Write the section in CGNS file 
+ if ( cg_section_write( IndexFile, IndexBase, IndexBase, SectionName, Sets[i].CGNSType, 
+ BeginSetsIndex, EndSetsIndex, 0, &ConnTable[i][0],&IndexSection) ){ 
+ std::cout << "Issue on writing connectivity -- 2-D\n"; 
+ cg_error_exit(); 
+ } 
+ BeginSetsIndex = EndSetsIndex+1; 
+ } 
+ } 
+ break; 
+ case 3: 
+ rval = get_conn_table( Faces, Begin, End, TagHandles, Sets, ConnTable ); 
+ if (rval != MB_SUCCESS){ 
+ std::cout << "Problem to fill the connectivity table for 2-D entities\n"; 
+ return rval; 
+ } 
+ rval = get_conn_table( Cells, Begin, End, TagHandles, Sets, ConnTable ); 
+ if (rval != MB_SUCCESS){ 
+ std::cout << "Problem to fill the connectivity table for 3-D entities\n"; 
+ return rval; 
+ } 
+ for (int i = 0; i < NbTags; ++i) { 
+ if ( Sets[i].IdSet != -1 ){ 
+ const char * SectionName = Sets[i].TagName.c_str(); 
+ EndSetsIndex = BeginSetsIndex + Sets[i].NbFaces + Sets[i].NbCells - 1; 
+ std::cout << "BeginSetsIndex = " << BeginSetsIndex << "\tEndSetsIndex = " << EndSetsIndex << "\n"; 
+ // Write the section in CGNS file 
+ if ( cg_section_write( IndexFile, IndexBase, IndexBase, SectionName, Sets[i].CGNSType, 
+ BeginSetsIndex, EndSetsIndex, 0, &ConnTable[i][0],&IndexSection) ){ 
+ std::cout << "Issue on writing connectivity -- 3-D\n"; 
+ cg_error_exit(); 
+ } 
+ BeginSetsIndex = EndSetsIndex+1; 
+ } 
+ } 
+ break; 
+ default: 
+ std::cout << "Issue on Physical dimension\n"; 
+ return MB_FAILURE; 
+ } 
+ 
+ // Close the CGNS mesh file 
+ if ( cg_close(IndexFile) ){ 
+ std::cout << "Error closing file\n"; 
+ cg_error_exit(); 
+ } 
+ // done 
+ return MB_SUCCESS; 
+} 
+ 
+// Get and count vertex entities 
+ErrorCode WriteCGNS::get_vertex_entities ( cgsize_t &VrtSize_, std::vector< moab::EntityHandle > &Nodes_) 
+{ 
+ ErrorCode rval; 
+ // Get vertex entities 
+ // The first input is 0 because one queries the entire mesh. 
+ // Retrieves all entities of dimension = 0 in "Nodes" 
+ rval = mbImpl->get_entities_by_dimension( 0, 0, Nodes_, false ); 
+ if ( Nodes.size() > 0 ){ 
+ celldim=0; 
+ physdim=0; 
+ // get the amout of vertex 
+ VrtSize_ = Nodes_.size(); 
+ } 
+ else { std::cout << "The mesh has not node points.\n"; } 
+ // done 
+ return rval; 
+} 
+ 
+// Get and count edge entities 
+ErrorCode WriteCGNS::get_edge_entities(cgsize_t &EdgeSize_, std::vector< moab::EntityHandle > &Edges_) 
+{ 
+ ErrorCode rval; 
+ // The first input is 0 because one queries the entire mesh. 
+ // Get all entities of dimension = 1 in Edges 
+ rval = mbImpl->get_entities_by_dimension( 0, 1, Edges_, false ); 
+ if ( Edges_.size() > 0 ){ 
+ celldim=1; 
+ physdim=1; 
+ // get the amout of edges 
+ EdgeSize_ = Edges_.size(); 
+ } 
+ // done 
+ return rval; 
+} 
+ 
+// Get and count face entities 
+ErrorCode WriteCGNS::get_face_entities(cgsize_t &FaceSize_, std::vector< moab::EntityHandle > &Faces_) 
+{ 
+ ErrorCode rval; 
+ // The first input is 0 because one queries the entire mesh. 
+ // Get all entities of dimension = 2 in Faces 
+ rval = mbImpl->get_entities_by_dimension( 0, 2, Faces_, false ); 
+ if ( Faces_.size() ){ 
+ celldim=2; 
+ physdim=2; 
+ // get the amout of faces 
+ FaceSize_ = Faces_.size(); 
+ } 
+ // done 
+ return rval; 
+} 
+ 
+// Get and count cell entities 
+ErrorCode WriteCGNS::get_cell_entities(cgsize_t &CellSize_, std::vector< moab::EntityHandle > &Cells_) 
+{ 
+ ErrorCode rval; 
+ // The first input is 0 because one queries the entire mesh. 
+ // Get all entities of dimension = 3 in Cell 
+ rval = mbImpl->get_entities_by_dimension( 0, 3, Cells_, false ); 
+ if ( Cells_.size() ){ 
+ celldim=3; 
+ physdim=3; 
+ // get the amout of volumes 
+ CellSize_ = Cells_.size(); 
+ } 
+ // done 
+ return rval; 
+} 
+ 
+ErrorCode WriteCGNS::write_coord_cgns(std::vector< moab::EntityHandle > &Nodes_) 
+{ 
+ ErrorCode rval; 
+ 
+ const int num_entities = (int)Nodes_.size(); 
+ 
+ // Moab works with one vector for the threee coordinates 
+ std::vector<double> Coords ( 3*num_entities ); 
+ std::vector<double>::iterator c = Coords.begin(); 
+ 
+ // CGNS uses one vector for each coordinate 
+ std::vector<double> CoordX; 
+ std::vector<double> CoordY; 
+ std::vector<double> CoordZ; 
+ 
+ // Summ the values of all coordinates to be sure if it is not zero 
+ double SumX=0; 
+ double SumY=0; 
+ double SumZ=0; 
+ 
+ // Get the moab coordinates - Coords is the output 
+ rval = mbImpl->get_coords( &Nodes_[0], num_entities, &Coords[0] ); 
+ if (MB_SUCCESS != rval){ 
+ std::cout << "Error getting coordinates from nodes.\n"; 
+ return rval; 
+ } 
+ 
+ // Reserve the size of nodes 
+ CoordX.reserve( Nodes_.size() ); 
+ CoordY.reserve( Nodes_.size() ); 
+ CoordZ.reserve( Nodes_.size() ); 
+ 
+ for (std::vector<moab::EntityHandle>::iterator i=Nodes_.begin(); i != Nodes_.end(); ++i){ 
+ CoordX.push_back(*c); // Put the X coordinate in CoordX vector 
+ SumX += abs(*c); // Sum all X coordinates 
+ ++c; // Move to Y coordinate 
+ CoordY.push_back(*c); // Put the Y coordinate in CoordY vector 
+ SumY += abs(*c); // Sum all Y coordinates 
+ ++c; // Move to Z coordinate 
+ CoordZ.push_back(*c); // Put the Z coordinate in CoordZ vector 
+ SumZ += abs(*c); // Sum all Z coordinates 
+ ++c; // Move to X coordinate 
+ } 
+ 
+ // If X coordinate is not empty then write CoordX (user must use SIDS-standard names here) 
+ if ( SumX != 0 ){ 
+ if ( cg_coord_write(IndexFile,IndexBase,IndexZone,RealDouble,"CoordinateX",&CoordX[0],&IndexCoord[0]) ){ 
+ std::cout << " Error writing X coordinates.\n"; 
+ cg_error_exit(); 
+ } 
+ } 
+ // If Y coordinate is not empty then write CoordY (user must use SIDS-standard names here) 
+ if ( SumY != 0 ){ 
+ if ( cg_coord_write(IndexFile,IndexBase,IndexZone,RealDouble,"CoordinateY",&CoordY[0],&IndexCoord[1]) ){ 
+ std::cout << " Error writing Y coordinates.\n"; 
+ cg_error_exit(); 
+ } 
+ } 
+ // If Z coordinate is not empty then write CoordZ (user must use SIDS-standard names here) 
+ if ( SumZ != 0 ){ 
+ if ( cg_coord_write(IndexFile,IndexBase,IndexZone,RealDouble,"CoordinateZ",&CoordZ[0],&IndexCoord[2]) ){ 
+ std::cout << " Error writing Z coordinates.\n"; 
+ cg_error_exit(); 
+ } 
+ } 
+ 
+ // Clear vectors 
+ Coords.clear(); 
+ CoordX.clear(); 
+ CoordY.clear(); 
+ CoordZ.clear(); 
+ 
+ // done 
+ return MB_SUCCESS; 
+} 
+ 
+ErrorCode WriteCGNS::set_tag_values( std::vector< Tag >& TagHandles, 
+ std::vector< moab::EntityHandle > &Edges_, 
+ std::vector< moab::EntityHandle > &Faces_, 
+ std::vector< moab::EntityHandle > &Cells_, 
+ std::vector< WriteCGNS::SetStruct >& Sets ) 
+{ 
+ ErrorCode rval; 
+ 
+ // Get the number of Tags in the mesh 
+ int NbTags = TagHandles.size(); 
+ 
+ // Loop over all Tags 
+ for (int i = 0; i < NbTags; ++i) { 
+ 
+ // Allocate another position in the vector of SetStruct using a default constructor 
+ Sets.push_back( SetStruct() ); 
+ 
+ // Get the Tag name 
+ rval = mbImpl->tag_get_name( TagHandles[i], Sets[i].TagName ); 
+ if (rval != MB_SUCCESS){ 
+ std::cout << "Problem to get Tag Name\n"; 
+ return rval; 
+ } 
+ std::cout << "Tag name= " << Sets[i].TagName << "\n"; 
+ 
+ // Count all entities by type and put in Sets[i].NbEntities vector 
+ rval = get_set_entities( i, TagHandles, Sets); 
+ if (rval != MB_SUCCESS ){ 
+ std::cout << "Problem to get Set entities\n"; 
+ return rval; 
+ } 
+ 
+ // Get the CGNSTYpe of the Set 
+ rval = get_cgns_type ( i, Sets ); 
+ if (rval != MB_SUCCESS ){ 
+ std::cout << "Problem to get CGNSType\n"; 
+ return rval; 
+ } 
+ std::cout << "\tSets[" << i << "].CGNSType= " << Sets[i].CGNSType << "\n"; 
+ 
+ //int Number; 
+ 
+ // Set a data index for Edges and TagHandles[i] 
+ if ( Sets[i].CGNSType == BAR_2 || Sets[i].CGNSType == TRI_3 || Sets[i].CGNSType == QUAD_4 || 
+ Sets[i].CGNSType == TETRA_4 || Sets[i].CGNSType == PYRA_5 || Sets[i].CGNSType == PENTA_6 || 
+ Sets[i].CGNSType == HEXA_8 || Sets[i].CGNSType == MIXED ){ 
+ 
+ if ( Sets[i].NbEdges > 0 && physdim < 3 ){ 
+ // Set a data index for Edges and TagHandles[i] 
+ const std::vector< int > tag_values ( Edges_.size(), i ); 
+ rval = mbImpl-> tag_set_data ( TagHandles[i], &Edges_[0], Edges_.size(), &tag_values[0] ); 
+ if (rval != MB_SUCCESS ){ 
+ std::cout << "Problem to set data for 1-D entities\n"; 
+ return rval; 
+ } 
+ } 
+ if ( Sets[i].NbFaces > 0 && physdim > 1 ){ 
+ // Set a data index for Faces and TagHandles[i] 
+ const std::vector< int > tag_values ( Faces.size(), i ); 
+ rval = mbImpl-> tag_set_data ( TagHandles[i], &Faces_[0], Faces_.size(), &tag_values[0] ); 
+ if (rval != MB_SUCCESS ){ 
+ std::cout << "Problem to set data for 2-D entities\n"; 
+ return rval; 
+ } 
+ } 
+ if ( Sets[i].NbCells > 0 && physdim > 2 ){ 
+ // Set a data index for Cells and TagHandles[i] 
+ const std::vector< int > tag_values ( Cells.size(), i ); 
+ rval = mbImpl-> tag_set_data ( TagHandles[i], &Cells_[0], Cells_.size(), &tag_values[0] ); 
+ if (rval != MB_SUCCESS ){ 
+ std::cout << "Problem to set data for 3-D entities\n"; 
+ return rval; 
+ } 
+ } 
+ // IdSet gets the Set Index indicating that it is not empty 
+ Sets[i].IdSet = i; 
+ } 
+ std::cout << "\tSets[" << i << "].IdSet = " << Sets[i].IdSet << "\n\n"; 
+ } 
+ return MB_SUCCESS; 
+} 
+ 
+// Get Entities in the set 
+ErrorCode WriteCGNS::get_set_entities(int i, std::vector< Tag >& TagHandles, 
+ std::vector< WriteCGNS::SetStruct >& Sets) 
+{ 
+ ErrorCode rval; 
+ 
+ // Get the number of MBEDGE entities 
+ // NbEntities[0] holds the number of MBEDGE in the "Sets" 
+ int Number=0; 
+ rval = mbImpl->get_number_entities_by_type_and_tag( 0, MBEDGE, &TagHandles[i], 0, 1, Number ); 
+ if (rval != MB_SUCCESS ){ 
+ std::cout << "Problem to get the number of entities by type and tag\n"; 
+ return rval; 
+ } 
+ Sets[i].NbEntities.push_back(Number); // MBEDGE == Sets[i].NbEntities[0] 
+ Sets[i].NbEdges += Number; 
+ std::cout << "\tNumber of MBEDGE = " << Number << "\n"; 
+ 
+ // Get the number of MBTRI entities 
+ // NbEntities[1] holds the number of MBTRI in the "Sets" 
+ Number=0; 
+ rval = mbImpl->get_number_entities_by_type_and_tag( 0, MBTRI, &TagHandles[i], 0, 1, Number ); 
+ if (rval != MB_SUCCESS ){ 
+ std::cout << "Problem to get the number of entities by type and tag\n"; 
+ return rval; 
+ } 
+ Sets[i].NbEntities.push_back(Number); // MBTRI == Sets[i].NbEntities[1] 
+ Sets[i].NbFaces += Number; 
+ std::cout << "\tNumber of MBTRI = " << Number << "\n"; 
+ 
+ // Get the number of MBQUAD entities 
+ // NbEntities[2] holds the number of MBQUAD in the "Sets" 
+ Number=0; 
+ rval = mbImpl->get_number_entities_by_type_and_tag( 0, MBQUAD, &TagHandles[i], 0, 1, Number ); 
+ if (rval != MB_SUCCESS ){ 
+ std::cout << "Problem to get the number of entities by type and tag\n"; 
+ return rval; 
+ } 
+ Sets[i].NbEntities.push_back(Number); // MBQUAD == Sets[i].NbEntities[2] 
+ Sets[i].NbFaces += Number; 
+ std::cout << "\tNumber of MBQUAD = " << Number << "\n"; 
+ 
+ // Get the number of MBTET entities 
+ // NbEntities[3] holds the number of MBTET in the "Sets" 
+ Number=0; 
+ rval = mbImpl->get_number_entities_by_type_and_tag( 0, MBTET, &TagHandles[i], 0, 1, Number ); 
+ if (rval != MB_SUCCESS ){ 
+ std::cout << "Problem to get the number of entities by type and tag\n"; 
+ return rval; 
+ } 
+ Sets[i].NbEntities.push_back(Number); // MBTET == Sets[i].NbEntities[3] 
+ Sets[i].NbCells += Number; 
+ std::cout << "\tNumber of MBTET = " << Number << "\n"; 
+ 
+ // Get the number of MBPYRAMID entities 
+ // NbEntities[4] holds the number of MBPYRAMID in the "Sets" 
+ Number=0; 
+ rval = mbImpl->get_number_entities_by_type_and_tag( 0, MBPYRAMID, &TagHandles[i], 0, 1, Number ); 
+ if (rval != MB_SUCCESS ){ 
+ std::cout << "Problem to get the number of entities by type and tag\n"; 
+ return rval; 
+ } 
+ Sets[i].NbEntities.push_back(Number); // MBPYRAMID == Sets[i].NbEntities[4] 
+ Sets[i].NbCells += Number; 
+ std::cout << "\tNumber of MBPYRAMID = " << Number << "\n"; 
+ 
+ // Get the number of MBPRISM entities - MBPRISM == PENTA_6 
+ // NbEntities[5] holds the number of MBPRISM in the "Sets" 
+ Number=0; 
+ rval = mbImpl->get_number_entities_by_type_and_tag( 0, MBPRISM, &TagHandles[i], 0, 1, Number ); 
+ if (rval != MB_SUCCESS ){ 
+ std::cout << "Problem to get the number of entities by type and tag\n"; 
+ return rval; 
+ } 
+ Sets[i].NbEntities.push_back(Number); // MBPRISM == Sets[i].NbEntities[5] 
+ Sets[i].NbCells += Number; 
+ std::cout << "\tNumber of MBPRISM = " << Number << "\n"; 
+ 
+ // Get the number of MBHEX entities 
+ // NbEntities[6] holds the number of MBHEX in the "Sets" 
+ Number=0; 
+ rval = mbImpl->get_number_entities_by_type_and_tag( 0, MBHEX, &TagHandles[i], 0, 1, Number ); 
+ if (rval != MB_SUCCESS ){ 
+ std::cout << "Problem to get the number of entities by type and tag\n"; 
+ return rval; 
+ } 
+ Sets[i].NbEntities.push_back(Number); // MBHEX == Sets[i].NbEntities[6] 
+ Sets[i].NbCells += Number; 
+ std::cout << "\tNumber of MBHEX = " << Number << "\n"; 
+ 
+ std::cout << "\tTotal number of Edges = " << Sets[i].NbEdges << "\n"; 
+ std::cout << "\tTotal number of Faces = " << Sets[i].NbFaces << "\n"; 
+ std::cout << "\tTotal number of Cells = " << Sets[i].NbCells << "\n"; 
+ 
+ return MB_SUCCESS; 
+} 
+ 
+// Get CGNSType 
+ErrorCode WriteCGNS::get_cgns_type ( int i, std::vector<WriteCGNS::SetStruct> &Sets ) 
+{ 
+ std::vector<int> Test; 
+ int Sum=0; 
+ 
+ // NbEntities is a vector which has the number of entities of each type 
+ // 0-MBEDGE | 1-MBTRI | 2-MBQUAD | 3-MBTET | 4-MBPYRAMID | 5-MBPRISM | 6-MBHEX 
+ // if NbEntities[i]>0 then Test[i]=1 
+ // else then Test[i]=0 
+ for ( int j=0; j< (int)Sets[i].NbEntities.size(); ++j){ 
+ if ( Sets[i].NbEntities[j] > 0 ){ 
+ Test.push_back(1); 
+ Sum++; 
+ } 
+ else { Test.push_back(0); } 
+ } 
+ 
+ // Test the Sum 
+ // if Sum > 1 then the Set is MIXED 
+ // if Sum = 0 then the Set is Homogeneous 
+ // else then the Set is empty 
+ if ( Sum>1 ){ Sets[i].CGNSType = MIXED; } 
+ else if ( Sum==1 ){ 
+ int j=0; 
+ std::cout << "Homogeneous Type\n"; 
+ while ( Sets[i].NbEntities[j] != 1 && j<(int)Sets[i].NbEntities.size() ){ ++j; } 
+ switch ( j ){ 
+ case 0 : 
+ Sets[i].CGNSType = BAR_2; 
+ break; 
+ case 1 : 
+ Sets[i].CGNSType = TRI_3; 
+ break; 
+ case 2 : 
+ Sets[i].CGNSType = QUAD_4; 
+ break; 
+ case 3 : 
+ Sets[i].CGNSType = TETRA_4; 
+ break; 
+ case 4 : 
+ Sets[i].CGNSType = PYRA_5; 
+ break; 
+ case 5 : 
+ Sets[i].CGNSType = PENTA_6; 
+ break; 
+ case 6 : 
+ Sets[i].CGNSType = HEXA_8; 
+ break; 
+ default : 
+ std::cout << "It was not possible to identify the CGNSType\n"; 
+ return MB_FAILURE; 
+ } 
+ } 
+ else { Sets[i].CGNSType = ElementTypeNull; } // NOT SURE IF THAT'S THE RIGHT WAY....... 
+ 
+ // Clear the test vector 
+ Test.clear(); 
+ 
+ return MB_SUCCESS; 
+ 
+} 
+ 
+// Fill the connectivity table 
+ErrorCode WriteCGNS::get_conn_table( std::vector< moab::EntityHandle > &Elements, 
+ std::vector< int > &Begin, 
+ std::vector< int > &End, 
+ std::vector<moab::Tag> &TagHandles, 
+ std::vector<WriteCGNS::SetStruct> &Sets, 
+ std::vector < std::vector<cgsize_t> > &ConnTable ) 
+{ 
+ ErrorCode rval; 
+ 
+// int Begin = 0; // GOT TO WORK ON THIS 
+// int End; 
+ 
+ // Get the number of Tags in the mesh 
+ int NbTags = TagHandles.size(); 
+ 
+ // Test all Elements, get their ids and connectivity 
+ // to fill ConnTable 
+ for (std::vector<moab::EntityHandle>::iterator i=Elements.begin(); i != Elements.end(); ++i){ 
+ int id; 
+ // Test all Tags 
+ for ( int j = 0; j < NbTags; ++j ){ 
+ // Test if the Tag has data 
+ if ( Sets[j].IdSet != -1 ){ 
+ // Try to get data from entity 
+ rval = mbImpl->tag_get_data( TagHandles[j], &*i, 1, &id ); 
+ if (MB_SUCCESS != rval){ 
+ return rval; 
+ } 
+ // If successful id==j 
+ if ( id == j ){ 
+ // Get the entity type of the EntityHandle wich points to Cells 
+ int num_vtx; // Number of MeshVertices in array connectivity. 
+ const EntityHandle* conn; // Array in which connectivity of entity_handle is returned. 
+ // Gets a pointer to constant connectivity data of entity_handle 
+ rval = mbImpl->get_connectivity( *i, conn, num_vtx ); 
+ if (MB_SUCCESS != rval){ 
+ return rval; 
+ } 
+ // If the Set is MIXED type 
+ // push CGNS ENUM type of the entity 
+ // before the connectivity 
+ if ( Sets[j].CGNSType == MIXED ){ 
+ ConnTable[j].push_back( moab_cgns_conv(*i) ); // moab_cgns_conv return an int which 
+ // represents the CGNS type 
+ Begin[j]++; 
+ } 
+ End[j] = Begin[j] + num_vtx; 
+ // Push conn in ConnTable in which "j" is the Set Index 
+ for (int k=Begin[j]; k<End[j]; ++k){ 
+ ConnTable[j].push_back( (cgsize_t)conn[k-Begin[j]] ); 
+ } 
+ Begin[j] = End[j]; 
+ } 
+ } 
+ } 
+ } 
+ return MB_SUCCESS; 
+} 
+ 
+// Read the Moab type and return CGNS type 
+int WriteCGNS::moab_cgns_conv(const EntityHandle handle) 
+{ 
+ EntityType MoabType = mbImpl->type_from_handle( handle ); 
+ switch ( MoabType ){ 
+ case MBEDGE : /**< Mesh Edge */ 
+ return BAR_2; 
+ case MBTRI : /**< Triangular element (including shells) */ 
+ return TRI_3; 
+ case MBQUAD : /**< Quadrilateral element (including shells) */ 
+ return QUAD_4; 
+ case MBTET : /**< Tetrahedral element */ 
+ return TETRA_4; 
+ case MBPYRAMID : /**< Pyramid element */ 
+ return PYRA_5; 
+ case MBPRISM : /**< Wedge element */ 
+ return PENTA_6; 
+ case MBHEX : /**< Hexahedral element */ 
+ return HEXA_8; 
+ default : 
+ std::cout << "It was not possible to identify the CGNSType\n"; 
+ return 0; 
+ } 
+} 
+ 
+} //namespace moab 

This diff is so big that we needed to truncate the remainder. 

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. 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mcs.anl.gov/pipermail/moab-dev/attachments/20131121/5c9efcd9/attachment-0001.html>


More information about the moab-dev mailing list