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

commits-noreply at bitbucket.org commits-noreply at bitbucket.org
Wed Nov 20 10:40:20 CST 2013


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.


More information about the moab-dev mailing list