[cgma-dev] r3108 - in cgm/trunk: . cgm_apps/cgm_cubit_acis geom geom/OCC geom/facet geom/parallel geom/virtual itaps

hongjun at mcs.anl.gov hongjun at mcs.anl.gov
Wed Aug 19 15:05:47 CDT 2009


Author: hongjun
Date: 2009-08-19 15:05:46 -0500 (Wed, 19 Aug 2009)
New Revision: 3108

Added:
   cgm/trunk/geom/parallel/AcisMemFile.hpp
   cgm/trunk/geom/parallel/CGMParallelComm.cpp
   cgm/trunk/geom/parallel/CGMParallelComm.hpp
   cgm/trunk/geom/parallel/CGMProcConfig.cpp
   cgm/trunk/geom/parallel/CGMProcConfig.hpp
   cgm/trunk/geom/parallel/FileOptions.cpp
   cgm/trunk/geom/parallel/FileOptions.hpp
   cgm/trunk/itaps/partest.cpp
Removed:
   cgm/trunk/geom/parallel/AcisMemFile.hpp
Modified:
   cgm/trunk/cgm_apps/cgm_cubit_acis/Makefile
   cgm/trunk/configure.ac
   cgm/trunk/geom/GeometryQueryEngine.hpp
   cgm/trunk/geom/GeometryQueryTool.cpp
   cgm/trunk/geom/GeometryQueryTool.hpp
   cgm/trunk/geom/OCC/OCCQueryEngine.cpp
   cgm/trunk/geom/OCC/OCCQueryEngine.hpp
   cgm/trunk/geom/facet/FacetQueryEngine.cpp
   cgm/trunk/geom/facet/FacetQueryEngine.hpp
   cgm/trunk/geom/parallel/Makefile.am
   cgm/trunk/geom/parallel/ParallelGeomTool.cpp
   cgm/trunk/geom/parallel/ParallelGeomTool.hpp
   cgm/trunk/geom/virtual/VirtualQueryEngine.cpp
   cgm/trunk/geom/virtual/VirtualQueryEngine.hpp
   cgm/trunk/itaps/CATag.hpp
   cgm/trunk/itaps/Makefile.am
   cgm/trunk/itaps/iGeom_CGMA.cc
Log:
o Parallel iGeom codes are added and modified.
o CGMParallelComm.*pp, FileOptions.*pp, ParallelGeomTool.*pp, CGMProcConfig.*pp are added in geom/parallel directory.
o Binary read and write functions are added in OCCQueryEngine.
o GeometryQueryTool, GeometryQueryEngine are modified by changing of OCCQueryEngine.
o partest is test file of parallel iGeom


Modified: cgm/trunk/cgm_apps/cgm_cubit_acis/Makefile
===================================================================
--- cgm/trunk/cgm_apps/cgm_cubit_acis/Makefile	2009-08-19 18:39:01 UTC (rev 3107)
+++ cgm/trunk/cgm_apps/cgm_cubit_acis/Makefile	2009-08-19 20:05:46 UTC (rev 3108)
@@ -1,22 +1,21 @@
 #
 # CGM_BASE_DIR: base directory below which are geom/ and util/, the cgm source
 #
-CGM_BASE_DIR = ${HOME}/cubit/CGM-10.1
+CGM_BASE_DIR = ${HOME}/lib/CGM
 #
 # CUBIT_INSTALL_DIR: the installation directory of your cubit executable, below
-# which should be bin/ and libs/ containing libcubiti19.so (in bin/) and the acis 
+# which should be bin/ containing libcubiti19.so (in bin/) and other 
 # shared libs (in libs/).
 #
-CUBIT_INSTALL_DIR = /cubit
+CUBIT_INSTALL_DIR = ${HOME}/cubit-10.2-amd64
 
-LFLAGS = -Wl,--unresolved-symbols=ignore-all -Wl,--allow-shlib-undefined -Wl,-rpath,${CUBIT_INSTALL_DIR}/bin -Wl,-rpath,${CUBIT_INSTALL_DIR}/libs
+LFLAGS = -Wl,--unresolved-symbols=ignore-all -Wl,--allow-shlib-undefined -Wl,-rpath,${CUBIT_INSTALL_DIR}/bin -Wl,-rpath,${HOME}/lib/OpenCASCADE6.3.0/lib
 
+include ${CGM_BASE_DIR}/lib/cgm.make
+
 cgm_cubit_acis_app: main_cubit_acis.o Makefile snippet.o
-	${CXX} -o cgm_cubit_acis ${LFLAGS} main_cubit_acis.o snippet.o -L${CUBIT_INSTALL_DIR}/bin -L${CUBIT_INSTALL_DIR}/libs \
-	-lcubiti19 -lacisstep -lxstep -lacisiges -lxiges -lSPAXAssemblyRep -lSPAXInterop -lSPAXAcisBase -lSPAXDefaultGeometryRep -lSPAXBase -lxacis2k -lxcore2k -lSpaAVis -lSpaAWarp -lSpaASurf -lSpaALops -lSpaABlend -lSpaACIS -lSpaBase -lcubiti19 -lacisstep -lxstep -lacisiges -lxiges -lSPAXAssemblyRep -lSPAXInterop -lSPAXAcisBase -lSPAXDefaultGeometryRep -lSPAXBase -lxacis2k -lxcore2k -lSpaAVis -lSpaAWarp -lSpaASurf -lSpaALops -lSpaABlend -lSpaACIS -lSpaBase
+	${CXX} ${CGM_INCLUDES} -o cgm_cubit_acis ${LFLAGS} main_cubit_acis.o snippet.o ${CGM_LIBS_LINK}
 
-include ${CGM_BASE_DIR}/include/config.make
-
 main_cubit_acis.o : Makefile NoAcisQueryEngine.hpp NoAcisModifyEngine.hpp
 
 mcnp_converter.o : mcnp_converter.cpp Makefile NoAcisQueryEngine.hpp NoAcisModifyEngine.hpp
@@ -25,8 +24,8 @@
 	$(CXX) ${CGM_CXXFLAGS} -g -I. ${CGM_INCLUDES} -o $@ -c $<
 
 test:
-	./cgm_cubit_acis geom.sat
+	./cgm_cubit_acis ${HOME}/source/CGM/itaps/testgeom.sat
 
 .cpp.o:
-	$(CXX) ${CGM_CXXFLAGS} -g -I. -I${CGM_BASE_DIR}/include -o $@ -c $<
+	$(CXX) ${CGM_CXXFLAGS} -g -I. ${CGM_INCLUDES} -o $@ -c $<
 

Modified: cgm/trunk/configure.ac
===================================================================
--- cgm/trunk/configure.ac	2009-08-19 18:39:01 UTC (rev 3107)
+++ cgm/trunk/configure.ac	2009-08-19 20:05:46 UTC (rev 3108)
@@ -281,7 +281,7 @@
 CUBIT_OCC_LIB=
 HAVE_OCC_DEF=
 if test "x$occ_DIR" != "xno"; then
-  OCC_LIBS="-lTKMath -lTKXSBase -lTKernel -lTKShHealing -lTKBRep -lTKG3d -lTKBO -lTKFeat -lTKFillet -lTKG2d -lTKOffset -lTKBool -lTKGeomAlgo -lTKGeomBase -lTKPrim -lTKTopAlgo -lTKHLR -lTKIGES -lTKMesh -lTKPrim -lTKSTEP209 -lTKSTEPAttr -lTKSTEPBase -lTKSTEP -lTKSTL -lTKTopAlgo -lTKXSBase -lTKLCAF"
+  OCC_LIBS="-lTKMath -lTKXSBase -lTKernel -lTKShHealing -lTKBRep -lTKG3d -lTKBO -lTKFeat -lTKFillet -lTKG2d -lTKOffset -lTKBool -lTKGeomAlgo -lTKGeomBase -lTKPrim -lTKTopAlgo -lTKHLR -lTKIGES -lTKMesh -lTKPrim -lTKSTEP209 -lTKSTEPAttr -lTKSTEPBase -lTKSTEP -lTKSTL -lTKTopAlgo -lTKXSBase -lTKLCAF -lTKBin"
   CUBIT_OCC_LIB="-lcubit_OCC"
 
   # Set OCC_INC_FLAG and OCC_LIB_FLAG based on --with-occ option

Modified: cgm/trunk/geom/GeometryQueryEngine.hpp
===================================================================
--- cgm/trunk/geom/GeometryQueryEngine.hpp	2009-08-19 18:39:01 UTC (rev 3107)
+++ cgm/trunk/geom/GeometryQueryEngine.hpp	2009-08-19 20:05:46 UTC (rev 3108)
@@ -49,6 +49,13 @@
                                    const char* file_type,
                                    const CubitString &cubit_version,
                                    const char* logfile_name = NULL ) = 0;
+
+      virtual CubitStatus export_solid_model(
+                                   DLIList<TopologyBridge*>& bridge_list,
+				   char*& p_buffer,
+				   int& n_buffer_size,
+				   bool b_export_buffer) = 0;
+
      //R CubitStatus
      //R- CUBIT_SUCCESS/CUBIT_FAILURE
      //I ref_entity_list
@@ -101,6 +108,11 @@
                                 bool import_vertices = true,
                                 bool free_surfaces = true
 					                      ) = 0;
+
+     virtual CubitStatus import_solid_model(DLIList<TopologyBridge*> &imported_entities,
+					    const char* pBuffer,
+					    const int n_buffer_size) = 0;
+       
      //R CubitStatus
      //R- CUBIT_SUCCESS/CUBIT_FAILURE
      //I file_ptr

Modified: cgm/trunk/geom/GeometryQueryTool.cpp
===================================================================
--- cgm/trunk/geom/GeometryQueryTool.cpp	2009-08-19 18:39:01 UTC (rev 3107)
+++ cgm/trunk/geom/GeometryQueryTool.cpp	2009-08-19 20:05:46 UTC (rev 3108)
@@ -507,6 +507,32 @@
   return result;
 }
 
+CubitStatus GeometryQueryTool::export_solid_model(DLIList<RefEntity*>& ref_entity_list,
+						  char*& p_buffer,
+						  int& n_buffer_size,
+						  bool b_export_buffer)
+{
+  // Get TopologyBridges from RefEntities.
+  DLIList<TopologyBridge*> bridge_list(ref_entity_list.size()), ref_ent_bridges;
+  ref_entity_list.reset();
+  for( int i = ref_entity_list.size(); i--; )
+  {
+    ref_ent_bridges.clean_out();
+    TopologyEntity* topo_ptr = dynamic_cast<TopologyEntity*>(ref_entity_list.get_and_step());
+    if( topo_ptr )
+      topo_ptr->bridge_manager()->get_bridge_list( ref_ent_bridges );
+    bridge_list += ref_ent_bridges;
+  }
+
+  bridge_list.reset();
+  GeometryQueryEngine *gqe = bridge_list.get()->get_geometry_query_engine();
+
+  CubitStatus result = gqe->export_solid_model(bridge_list, p_buffer,
+					       n_buffer_size, b_export_buffer);
+
+  return result;
+}
+
 //-------------------------------------------------------------------------
 // Purpose       : Fire a ray and see which entities it hits
 //
@@ -642,6 +668,35 @@
   return status;
 }
 
+CubitStatus GeometryQueryTool::import_solid_model(DLIList<RefEntity*> *imported_entities,
+						  const char* pBuffer,
+						  const int n_buffer_size)
+{
+  if (0 == gqeList.size()) {
+    PRINT_WARNING("No active geometry engine.\n");
+    return CUBIT_FAILURE;
+  }
+
+  // Use the default MQE to import a list of ToplogyBridges from the file.
+  gqeList.reset();
+  DLIList<TopologyBridge*> bridge_list;
+
+  CubitStatus status;
+  for (int i = 0; i < gqeList.size(); i++)
+  {
+    status = gqeList.get_and_step()->import_solid_model( bridge_list, pBuffer, n_buffer_size );
+
+    if (bridge_list.size() > 0) break;
+  }
+  if (bridge_list.size() == 0) return status;
+
+  bridge_list.reset();
+  status = construct_refentities(bridge_list, imported_entities);
+
+  // now return
+  return status;
+}
+
 CubitStatus GeometryQueryTool::construct_refentities(DLIList<TopologyBridge*> &bridge_list,
                                                      DLIList<RefEntity*> *imported_entities)
 {

Modified: cgm/trunk/geom/GeometryQueryTool.hpp
===================================================================
--- cgm/trunk/geom/GeometryQueryTool.hpp	2009-08-19 18:39:01 UTC (rev 3107)
+++ cgm/trunk/geom/GeometryQueryTool.hpp	2009-08-19 20:05:46 UTC (rev 3108)
@@ -254,6 +254,11 @@
     *
     */
 
+  CubitStatus export_solid_model(DLIList<RefEntity*>& ref_entity_list,
+				 char*& p_buffer,
+				 int& n_buffer_size,
+				 bool b_export_buffer);
+  
   CubitStatus import_solid_model(const char* file_name,
                                  const char* file_type,
                                  const char* logfile_name = NULL,
@@ -264,6 +269,7 @@
                                  CubitBoolean import_vertices = CUBIT_TRUE,
                                  CubitBoolean free_surfaces = CUBIT_TRUE,
 				 DLIList<RefEntity*> *imported_entities = NULL);
+
   /**<
    * Import all or specified entities in a solid model file.
     *  \arg file_ptr
@@ -294,6 +300,11 @@
     *  CUBIT_SUCCESS if everything goes well.
     */
 
+  // import entities in a solid model buffer
+  CubitStatus import_solid_model(DLIList<RefEntity*> *imported_entities,
+				 const char* pBuffer,
+				 const int n_buffer_size);
+
   CubitStatus construct_refentities(DLIList<TopologyBridge*> &topology_bridges,
                                     DLIList<RefEntity*> *imported_entities = NULL);
     //- given a list of TB's, construct ref entities for them; if the 2nd list pointer is

Modified: cgm/trunk/geom/OCC/OCCQueryEngine.cpp
===================================================================
--- cgm/trunk/geom/OCC/OCCQueryEngine.cpp	2009-08-19 18:39:01 UTC (rev 3107)
+++ cgm/trunk/geom/OCC/OCCQueryEngine.cpp	2009-08-19 20:05:46 UTC (rev 3108)
@@ -14,6 +14,9 @@
 //
 //-------------------------------------------------------------------------
 #include <Standard_Stream.hxx>
+//#include <Standard_SStream.hxx>
+//#include <Standard_String.hxx>
+//#include <stringbuf>
 #include "BRep_Tool.hxx"
 #include "gp_Pnt.hxx"
 #include "gp_Ax1.hxx"
@@ -24,6 +27,7 @@
 #include "BRepBuilderAPI_Transform.hxx"
 #include "BRepBuilderAPI_MakeSolid.hxx"
 #include "OCCShapeAttributeSet.hpp"
+//#include "OCCBinToolsShapeSet.hpp"
 #include "BRepBuilderAPI_MakeShell.hxx"
 #include "GProp_GProps.hxx"
 #include "BRepGProp.hxx"
@@ -110,6 +114,7 @@
 #include <BRepAdaptor_Surface.hxx>
 #include <TDataStd_Shape.hxx>
 #include <TDF_ChildIterator.hxx>
+#include <BinTools_ShapeSet.hxx>
 #include "Standard_Boolean.hxx"
 
 #include "TDF_Label.hxx"
@@ -975,6 +980,123 @@
   return CUBIT_SUCCESS;
 }
 
+CubitStatus OCCQueryEngine::export_solid_model( DLIList<TopologyBridge*>& ref_entity_list,
+						char*& p_buffer,
+						int& n_buffer_size,
+						bool b_export_buffer)
+{
+  DLIList<OCCBody*>    OCC_bodies;
+  DLIList<OCCSurface*> OCC_surfaces;
+  DLIList<OCCCurve*>   OCC_curves;
+  DLIList<OCCPoint*>   OCC_points;
+
+  DLIList<TopologyBridge*> ref_entities_handled;
+
+  int i;
+  //Collect all free entities (bodies, curves, vertices )
+  ref_entity_list.reset();
+  for(i=ref_entity_list.size(); i>0; i--)
+    {
+      TopologyBridge* ref_entity_ptr = ref_entity_list.get();
+      CubitBoolean handled = CUBIT_TRUE;
+
+      //if it is a Vertex
+      if( OCCPoint* pt = CAST_TO( ref_entity_ptr, OCCPoint) )
+	OCC_points.append( pt );
+
+      //if it is a Curve
+      else if( OCCCurve* curve = CAST_TO( ref_entity_ptr, OCCCurve) )
+	OCC_curves.append( curve );
+    
+      //if it is a surface
+      else if( OCCSurface* surf = CAST_TO( ref_entity_ptr, OCCSurface) )
+	OCC_surfaces.append( surf );
+   
+      //if it is a Body
+      else if( OCCBody* body = CAST_TO( ref_entity_ptr, OCCBody ) )
+	OCC_bodies.append( body );
+
+      else
+	handled = CUBIT_FALSE;
+
+      if( handled == CUBIT_TRUE )
+	{
+	  ref_entities_handled.append( ref_entity_ptr );
+	  ref_entity_list.change_to(NULL);
+	}
+
+      ref_entity_list.step();
+    }
+
+  ref_entity_list.remove_all_with_value(NULL);
+
+  int free_body_count = OCC_bodies.size();
+  int free_curve_count = OCC_curves.size();
+  int free_point_count = OCC_points.size();
+  int free_surface_count = OCC_surfaces.size();
+
+  //if nothing to write out...return
+  if( free_body_count == 0 && free_surface_count == 0 && 
+      free_curve_count == 0 && free_point_count == 0)
+    return CUBIT_SUCCESS;
+
+  //save the facets (geometry info )
+  CubitStatus status;
+
+  //write out topology and attributes
+  status = write_topology( p_buffer, n_buffer_size,
+			   b_export_buffer,
+			   OCC_bodies, OCC_surfaces,
+			   OCC_curves, OCC_points);
+  if( status == CUBIT_FAILURE ) return CUBIT_FAILURE;
+
+  if( free_body_count || free_surface_count || 
+      free_curve_count || free_point_count )
+    if (b_export_buffer) PRINT_INFO( "\nExported:" );
+    else PRINT_INFO( "\nSize checked:" );
+
+  int flg = 0;
+
+  if( free_body_count )
+    {
+      if( flg )PRINT_INFO( "         " );else flg=1;
+      if( free_body_count == 1 )
+         PRINT_INFO( "%4d OCC Body to buffer\n", free_body_count );
+      else
+         PRINT_INFO( "%4d OCC Bodies to buffer\n", free_body_count );
+    }
+
+  if( free_surface_count )
+    {
+      if( flg )PRINT_INFO( "         " );else flg=1;
+      if( free_surface_count == 1 )
+	PRINT_INFO( "%4d OCC Surface to buffer\n", free_surface_count );
+      else
+	PRINT_INFO( "%4d OCC Surface to buffer\n", free_surface_count );
+    }
+
+  if( free_curve_count )
+    {
+      if( flg )PRINT_INFO( "         " );else flg=1;
+      if( free_curve_count == 1 )
+	PRINT_INFO( "%4d OCC Curve to buffer\n", free_curve_count );
+      else
+	PRINT_INFO( "%4d OCC Curves to buffer\n", free_curve_count );
+    }
+
+  if( free_point_count )
+    {
+      if( flg )PRINT_INFO( "         " );else flg=1;
+      if( free_point_count == 1 )
+	PRINT_INFO( "%4d OCC Point to buffer\n", free_point_count );
+      else
+	PRINT_INFO( "%4d OCC Points to buffer\n", free_point_count );
+    }
+  PRINT_INFO( "\n" );
+
+  return CUBIT_SUCCESS;
+}
+
 //===========================================================================
 //Function Name:export_solid_model
 //Member Type:  PUBLIC
@@ -1101,7 +1223,288 @@
 
   return CUBIT_SUCCESS;
 }
+/*
+CubitStatus
+OCCQueryEngine::write_topology( //const unsigned char* p_buffer,
+			       //char* p_buffer,
+			       ofstream& os,
+				DLIList<OCCBody*> &OCC_bodies,
+				DLIList<OCCSurface*> &OCC_surfaces,
+				DLIList<OCCCurve*> &OCC_curves,
+				DLIList<OCCPoint*> &OCC_points)
+{
 
+  int i;
+  //Create a compound shape to export
+  BRep_Builder B;
+  TopoDS_Compound Co;
+  B.MakeCompound(Co);
+
+  //Add every shape to the compound
+  for (i = 0; i < OCC_bodies.size(); i++)
+    {
+      OCCBody* body = OCC_bodies.get_and_step();
+      TopoDS_CompSolid *shape = body->get_TopoDS_Shape();
+
+      if (shape == NULL) //sheet body or shell body
+      {
+         OCCSurface* surface = body->my_sheet_surface();
+         OCCShell* shell = body->shell();
+         if (surface == NULL && shell == NULL)
+         {
+           
+	   PRINT_ERROR( "Wrong body structure. Internal ERROR\n" );
+	   continue;
+         }
+         if(surface)
+           B.Add(Co,*(surface->get_TopoDS_Face())); 
+         else
+    	   B.Add(Co,*(shell->get_TopoDS_Shell()));
+         continue;
+      }
+
+      //check if this body is build backwards from lump. if so,
+      //the body and its CompSolid doesn't have bounded relationship
+      //established. In this case, each individual lump of the body 
+      // will be exported as TopoDS_Solid without a CompSolid
+      if(OCCMap->IsBound(*shape))
+	B.Add(Co, *shape);
+      else
+	{   
+	  DLIList<Lump*> lumps = body->lumps();
+	  for(int i = 0; i < lumps.size(); i++)
+	    {
+	      OCCLump *occ_lump = (OCCLump *) lumps.get_and_step();
+              TopoDS_Solid solid = *(occ_lump->get_TopoDS_Solid());
+	      B.Add(Co, solid);
+	    }
+	}
+    }
+
+  for (i = 0; i < OCC_surfaces.size(); i++)
+    {
+      TopoDS_Face *face = OCC_surfaces.get_and_step()->get_TopoDS_Face();
+      B.Add(Co, *face);
+    }
+
+  //Add standalone wires to the export BRep file
+  for (i = 0; i < WireList->size(); i++)
+    {
+      TopoDS_Wire *wire = WireList->get_and_step()->get_TopoDS_Wire();
+      B.Add(Co, *wire);
+    }
+
+  for (i = 0; i < OCC_curves.size(); i++)
+    {
+      TopoDS_Edge *edge = OCC_curves.get_and_step()->get_TopoDS_Edge();
+      B.Add(Co, *edge);
+    }
+
+  for (i = 0; i < OCC_points.size(); i++)
+    {
+      TopoDS_Vertex *vertex = OCC_points.get_and_step()->get_TopoDS_Vertex();
+      B.Add(Co, *vertex);
+    }
+ 
+  //if(strcmp(file_type, "OCC") == 0)
+  //{
+    TDF_Label label;
+    if(EXPORT_ATTRIB)
+      label = mainLabel;
+
+    if(!Write(Co, os))
+      return CUBIT_FAILURE;
+
+  return CUBIT_SUCCESS;
+}
+
+CubitStatus
+OCCQueryEngine::write_topology(
+			       std::ostringstream& os,
+				DLIList<OCCBody*> &OCC_bodies,
+				DLIList<OCCSurface*> &OCC_surfaces,
+				DLIList<OCCCurve*> &OCC_curves,
+				DLIList<OCCPoint*> &OCC_points)
+{
+
+  int i;
+  //Create a compound shape to export
+  BRep_Builder B;
+  TopoDS_Compound Co;
+  B.MakeCompound(Co);
+
+  //Add every shape to the compound
+  for (i = 0; i < OCC_bodies.size(); i++)
+    {
+      OCCBody* body = OCC_bodies.get_and_step();
+      TopoDS_CompSolid *shape = body->get_TopoDS_Shape();
+
+      if (shape == NULL) //sheet body or shell body
+      {
+         OCCSurface* surface = body->my_sheet_surface();
+         OCCShell* shell = body->shell();
+         if (surface == NULL && shell == NULL)
+         {
+           
+	   PRINT_ERROR( "Wrong body structure. Internal ERROR\n" );
+	   continue;
+         }
+         if(surface)
+           B.Add(Co,*(surface->get_TopoDS_Face())); 
+         else
+    	   B.Add(Co,*(shell->get_TopoDS_Shell()));
+         continue;
+      }
+
+      //check if this body is build backwards from lump. if so,
+      //the body and its CompSolid doesn't have bounded relationship
+      //established. In this case, each individual lump of the body 
+      // will be exported as TopoDS_Solid without a CompSolid
+      if(OCCMap->IsBound(*shape))
+	B.Add(Co, *shape);
+      else
+	{   
+	  DLIList<Lump*> lumps = body->lumps();
+	  for(int i = 0; i < lumps.size(); i++)
+	    {
+	      OCCLump *occ_lump = (OCCLump *) lumps.get_and_step();
+              TopoDS_Solid solid = *(occ_lump->get_TopoDS_Solid());
+	      B.Add(Co, solid);
+	    }
+	}
+    }
+
+  for (i = 0; i < OCC_surfaces.size(); i++)
+    {
+      TopoDS_Face *face = OCC_surfaces.get_and_step()->get_TopoDS_Face();
+      B.Add(Co, *face);
+    }
+
+  //Add standalone wires to the export BRep file
+  for (i = 0; i < WireList->size(); i++)
+    {
+      TopoDS_Wire *wire = WireList->get_and_step()->get_TopoDS_Wire();
+      B.Add(Co, *wire);
+    }
+
+  for (i = 0; i < OCC_curves.size(); i++)
+    {
+      TopoDS_Edge *edge = OCC_curves.get_and_step()->get_TopoDS_Edge();
+      B.Add(Co, *edge);
+    }
+
+  for (i = 0; i < OCC_points.size(); i++)
+    {
+      TopoDS_Vertex *vertex = OCC_points.get_and_step()->get_TopoDS_Vertex();
+      B.Add(Co, *vertex);
+    }
+ 
+  //if(strcmp(file_type, "OCC") == 0)
+  //{
+    TDF_Label label;
+    if(EXPORT_ATTRIB)
+      label = mainLabel;
+
+    if(!Write(Co, os))
+      return CUBIT_FAILURE;
+
+  return CUBIT_SUCCESS;
+}
+*/
+CubitStatus
+OCCQueryEngine::write_topology( char*& p_buffer,
+				int& n_buffer_size,
+				bool b_export_buffer,
+				DLIList<OCCBody*> &OCC_bodies,
+				DLIList<OCCSurface*> &OCC_surfaces,
+				DLIList<OCCCurve*> &OCC_curves,
+				DLIList<OCCPoint*> &OCC_points)
+{
+
+  int i;
+  //Create a compound shape to export
+  BRep_Builder B;
+  TopoDS_Compound Co;
+  B.MakeCompound(Co);
+
+  //Add every shape to the compound
+  for (i = 0; i < OCC_bodies.size(); i++)
+    {
+      OCCBody* body = OCC_bodies.get_and_step();
+      TopoDS_CompSolid *shape = body->get_TopoDS_Shape();
+
+      if (shape == NULL) //sheet body or shell body
+      {
+         OCCSurface* surface = body->my_sheet_surface();
+         OCCShell* shell = body->shell();
+         if (surface == NULL && shell == NULL)
+         {
+           
+	   PRINT_ERROR( "Wrong body structure. Internal ERROR\n" );
+	   continue;
+         }
+         if(surface)
+           B.Add(Co,*(surface->get_TopoDS_Face())); 
+         else
+    	   B.Add(Co,*(shell->get_TopoDS_Shell()));
+         continue;
+      }
+
+      //check if this body is build backwards from lump. if so,
+      //the body and its CompSolid doesn't have bounded relationship
+      //established. In this case, each individual lump of the body 
+      // will be exported as TopoDS_Solid without a CompSolid
+      if(OCCMap->IsBound(*shape))
+	B.Add(Co, *shape);
+      else
+	{   
+	  DLIList<Lump*> lumps = body->lumps();
+	  for(int i = 0; i < lumps.size(); i++)
+	    {
+	      OCCLump *occ_lump = (OCCLump *) lumps.get_and_step();
+              TopoDS_Solid solid = *(occ_lump->get_TopoDS_Solid());
+	      B.Add(Co, solid);
+	    }
+	}
+    }
+
+  for (i = 0; i < OCC_surfaces.size(); i++)
+    {
+      TopoDS_Face *face = OCC_surfaces.get_and_step()->get_TopoDS_Face();
+      B.Add(Co, *face);
+    }
+
+  //Add standalone wires to the export BRep file
+  for (i = 0; i < WireList->size(); i++)
+    {
+      TopoDS_Wire *wire = WireList->get_and_step()->get_TopoDS_Wire();
+      B.Add(Co, *wire);
+    }
+
+  for (i = 0; i < OCC_curves.size(); i++)
+    {
+      TopoDS_Edge *edge = OCC_curves.get_and_step()->get_TopoDS_Edge();
+      B.Add(Co, *edge);
+    }
+
+  for (i = 0; i < OCC_points.size(); i++)
+    {
+      TopoDS_Vertex *vertex = OCC_points.get_and_step()->get_TopoDS_Vertex();
+      B.Add(Co, *vertex);
+    }
+ 
+  //if(strcmp(file_type, "OCC") == 0)
+  //{
+    TDF_Label label;
+    if(EXPORT_ATTRIB)
+      label = mainLabel;
+
+    if(!Write(Co, p_buffer, n_buffer_size, b_export_buffer))
+      return CUBIT_FAILURE;
+
+  return CUBIT_SUCCESS;
+}
+
 CubitBoolean OCCQueryEngine::Write(const TopoDS_Shape& Sh,
                                    const Standard_CString File,
                                    TDF_Label label) 
@@ -1129,7 +1532,200 @@
 
   return isGood;
 }
+/*
+CubitBoolean OCCQueryEngine::Write(const TopoDS_Shape& Sh,
+				   //const unsigned char* pbuffer,
+				   //streambuf* rpsbuf)
+				   //char* pbuffer,
+				   //TDF_Label label) 
+				   std::ofstream& os)
+{
+  os.open("test.txt", std::ios::out);
+  std::filebuf* pbuf_os = os.rdbuf();
+  if (!pbuf_os->is_open()) return Standard_False;
+  
+  CubitBoolean isGood = (os.good() && !os.eof());
+  if (!isGood) return isGood;
 
+  long os_size1 = pbuf_os->pubseekoff(0, std::ios_base::end, std::ios::out);
+  std::cout << "size os1 = " << os_size1 << std::endl;
+  
+  BinTools_ShapeSet SS;
+  SS.Add(Sh);
+  isGood = os.good();
+  SS.Write(os);
+  isGood = os.good();
+ 
+  //std::streamsize size = pbuf->in_avail();
+  long os_size = pbuf_os->pubseekoff(0, std::ios_base::end, std::ios::out);
+  std::cout << "size os2 = " << os_size << std::endl;
+  
+  char* buffer = new char[os_size];
+  //os.write(buffer, os_size);
+  //pbuf_os->sputn(buffer, os_size);
+
+  //memcpy(buffer, pbuf_os, os_size);
+  
+  return CUBIT_TRUE;
+}
+
+CubitBoolean OCCQueryEngine::Write(const TopoDS_Shape& Sh,
+				   std::ostringstream& os)
+{
+
+  CubitBoolean isGood = (os.good() && !os.eof());
+  if (!isGood) return isGood;
+
+  std::stringbuf* pbuf = os.rdbuf();
+  std::streamsize ssize = pbuf->in_avail(); 
+  long size = pbuf->pubseekoff(0, std::ios_base::end, std::ios::out);
+  std::cout << "size os1 = " << size << " " << ssize << std::endl;
+  
+  BinTools_ShapeSet SS;
+  SS.Add(Sh);
+  isGood = os.good();
+  SS.Write(os);
+  isGood = os.good();
+ 
+  ssize = pbuf->in_avail();
+  size = pbuf->pubseekoff(0, std::ios_base::end, std::ios::out);
+  std::cout << "size os2 = " << size << " " << ssize << std::endl;
+
+  char* buffer = new char[size];
+  //os.write(buffer, os_size);
+  pbuf->sputn(buffer, size);
+
+  std::istringstream is;
+  pbuf = is.rdbuf();
+
+  ssize = pbuf->in_avail();
+  size = pbuf->pubseekoff(0, std::ios_base::end, std::ios::in);
+  std::cout << "size io1 = " << size << " " << ssize << std::endl;
+
+  //is.tie(&os);
+  //is.read(buffer, size1);
+  pbuf->pubseekpos(0, std::ios::in);
+  pbuf->sgetn(buffer, size);
+
+  ssize = pbuf->in_avail();
+  size = is.rdbuf()->pubseekoff(0, std::ios_base::end, std::ios::in);
+  std::cout << "size io2 = " << size << " " << ssize << std::endl;
+
+  pbuf->pubsetbuf(buffer, size);
+
+  ssize = pbuf->in_avail();
+  size = is.rdbuf()->pubseekoff(0, std::ios_base::end, std::ios::in);
+  std::cout << "size io3 = " << size << " " << ssize << std::endl;
+
+  BinTools_ShapeSet SS2;
+  SS2.Read(is);
+  int nShape = SS2.NbShapes();
+  std::cout << "nShpae = %d" << nShape << std::endl;
+
+  
+  // test
+  std::ostringstream oss("test");
+  pbuf = oss.rdbuf();
+  ssize = pbuf->in_avail();
+  size = pbuf->pubseekoff(0, std::ios_base::end, std::ios::out);
+  std::cout << "test size os1 = " << size << " " << ssize << std::endl;
+
+  char* tbuffer = new char[size];
+  //pbuf->sputn(tbuffer, size);
+  ssize = pbuf->sgetn(tbuffer, size);
+
+  std::istringstream iss;
+  pbuf = iss.rdbuf();
+
+  //ssize = pbuf->in_avail();
+  size = pbuf->pubseekoff(0, std::ios_base::end, std::ios::in);
+  std::cout << "test size io1 = " << size << " " << ssize << std::endl;
+
+  //is.tie(&os);
+  //is.read(buffer, size1);
+  pbuf->pubseekpos(0, std::ios::in);
+  //pbuf->sgetn(tbuffer, size);
+  //ssize = pbuf->sputn(tbuffer, size);
+  pbuf->pubsetbuf(tbuffer, size);
+
+  //ssize = pbuf->in_avail();
+  size = iss.rdbuf()->pubseekoff(0, std::ios_base::end, std::ios::in);
+  std::cout << "test size io2 = " << size << " " << ssize << std::endl;
+
+  pbuf->pubsetbuf(tbuffer, size);
+
+  ssize = pbuf->in_avail();
+  size = iss.rdbuf()->pubseekoff(0, std::ios_base::end, std::ios::in);
+  std::cout << "test size io3 = " << size << " " << ssize << std::endl;
+
+  // 
+  std::stringstream ssos("test2");
+  ssize = ssos.rdbuf()->in_avail();
+  size = ssos.rdbuf()->pubseekoff(0, std::ios_base::end, std::ios::in);
+  std::cout << "test size os4 = " << size << " " << ssize << std::endl;
+  std::string mystr = ssos.rdbuf()->str();
+  std::stringstream ssis(mystr);
+  ssize = ssis.rdbuf()->in_avail();
+  size = ssis.rdbuf()->pubseekoff(0, std::ios_base::end, std::ios::in);
+  std::cout << "test size is4 = " << size << " " << ssize << std::endl;
+
+  std::stringbuf sbos;
+  std::stringbuf sbis;
+  std::iostream tos(&sbos);
+  std::iostream tis(&sbis);
+  BinTools_ShapeSet tSS1;
+  tSS1.Add(Sh);
+  isGood = tos.good();
+  std::cout << "isGood=" << isGood << std::endl;
+  tSS1.Write(tos);
+  isGood = tos.good();
+  std::cout << "isGood=" << isGood << std::endl;
+  size = tos.rdbuf()->pubseekoff(0, std::ios_base::end, std::ios::out);
+  std::cout << "test fos size = " << size << std::endl;
+  char* tbuffer1 = new char[size];
+  tos.read(tbuffer1, size);
+
+  tis.write(tbuffer1, size);
+  BinTools_ShapeSet tSS2;
+  tSS2.Read(tis);
+  isGood = tis.good();
+  std::cout << "isGood=" << isGood << std::endl;
+  nShape = tSS2.NbShapes();
+  std::cout << "test nShpae = " << nShape << std::endl;
+
+  return CUBIT_TRUE;
+}
+*/
+CubitBoolean OCCQueryEngine::Write(const TopoDS_Shape& Sh,
+				   char*& pBuffer,
+				   int& n_buffer_size,
+				   bool b_write_buffer)
+{
+  std::stringbuf sb;
+  std::iostream os(&sb);
+  BinTools_ShapeSet SS;
+
+  SS.Add(Sh);
+  CubitBoolean isGood = os.good();
+  //std::cout << "isGood=" << isGood << std::endl;
+  if (!isGood) return isGood;
+  SS.Write(os);
+  isGood = os.good();
+  //std::cout << "isGood=" << isGood << std::endl;
+  if (!isGood) return isGood;
+
+  n_buffer_size = os.rdbuf()->pubseekoff(0, std::ios_base::end, std::ios::out);
+  //std::cout << "test fos size = " << n_buffer_size 
+  //  << " nShape= " << SS.NbShapes() << std::endl;
+
+  if (b_write_buffer) {
+    //delete pBuffer;
+    //pBuffer = new char[n_buffer_size];
+    os.read(pBuffer, n_buffer_size);
+  }
+
+  return CUBIT_TRUE;
+}
                                    
 CubitBoolean OCCQueryEngine::Read(TopoDS_Shape& Sh,
                                   const Standard_CString File,
@@ -1150,7 +1746,65 @@
   SS.Read(Sh,in,nbshapes, &label);
   return CUBIT_TRUE;
 }
+                                   
+CubitBoolean OCCQueryEngine::Read(TopoDS_Shape& Sh,
+				  const char* pBuffer,
+				  const int n_buffer_size)
+{
+  std::stringbuf sb;
+  std::iostream is(&sb);
+  is.write(pBuffer, n_buffer_size);
+  /*
+  BinTools_ShapeSet SS;
+  SS.Read(is);
+  CubitBoolean isGood = is.good();
+  std::cout << "isGood=" << isGood << std::endl;
+  int nShape = SS.NbShapes();
+  std::cout << "test nShpae = " << nShape << std::endl;
+  if (!nShape) return CUBIT_FALSE;
+  //Sh = SS.TopoDS_Shape();
+  //SS.Read(Sh, is, nShape);
+  */
+  //TDF_Label label;
+  //CubitBoolean print_results = false;
+  //OCCBinToolsShapeSet SS;
+  BinTools_ShapeSet SS;
+  SS.Read(is);
+  int nbshapes = SS.NbShapes();
+  if (!nbshapes) return CUBIT_FALSE;
+  
+  //TopoDS_Shape fs = SS.Shape(1);
+  //TopoDS_Shape ls = SS.Shape(nbshapes);
+  /* for (int i = 1; i <= nbshapes; i++) {
+    TopoDS_Shape s = SS.Shape(i);
+    std::cout << "shape type" << i << "=" << s.ShapeType() << std::endl;
+    }*/
+  
+  //SS.Read(Sh, is, nbshapes);
+  Sh = SS.Shape(nbshapes);
+  
+  //is.seekg (0, std::ios::beg);
+  //do {
+  //SS.Read(Sh, is, nbshapes);
+    //if (!Sh.IsNull()) {
+      //AddShapes(S,SS);
+      //break;
+    //}
+  //} while(!Sh.IsNull());
+  
+  /*
+  BRep_Builder B;
+  TopoDS_Compound Co;
+  B.MakeCompound(Co);
+  for (int i = 1; i <= nShape; i++) {
+    B.Add(Co, SS.Shape(i));
+  }
 
+  Sh = Co;
+  */
+  return CUBIT_TRUE;
+}
+
 CubitStatus
 OCCQueryEngine::import_temp_geom_file(FILE* file_ptr,
                                       const char* file_name,
@@ -1224,6 +1878,18 @@
   return CUBIT_SUCCESS;
 }
 
+CubitStatus OCCQueryEngine::import_solid_model(DLIList<TopologyBridge*> &imported_entities,
+					       const char* pBuffer,
+					       const int n_buffer_size)
+{
+  TopoDS_Shape *aShape = new TopoDS_Shape;
+  Standard_Boolean result = Read(*aShape, pBuffer, n_buffer_size);
+  if (result==0) return CUBIT_FAILURE;
+  
+  imported_entities = populate_topology_bridge(*aShape);
+  return CUBIT_SUCCESS;
+}
+
 //===========================================================================
 //Function Name:populate_topology_bridge
 //Member Type:  PUBLIC

Modified: cgm/trunk/geom/OCC/OCCQueryEngine.hpp
===================================================================
--- cgm/trunk/geom/OCC/OCCQueryEngine.hpp	2009-08-19 18:39:01 UTC (rev 3107)
+++ cgm/trunk/geom/OCC/OCCQueryEngine.hpp	2009-08-19 20:05:46 UTC (rev 3108)
@@ -231,6 +231,12 @@
                                           const CubitString &cubit_version,
                                           const char* logfile_name = NULL );
 
+  // write shapes to buffer as binary format
+  virtual CubitStatus export_solid_model( DLIList<TopologyBridge*>& ref_entity_list,
+					  char*& p_buffer,
+					  int& n_buffer_size,
+					  bool b_export_buffer);
+  
   virtual CubitStatus save_temp_geom_file( DLIList<TopologyBridge*>& ref_entity_list,
                                           const char *file_name,
                                           const CubitString &cubit_version,
@@ -254,6 +260,10 @@
                                          CubitBoolean import_vertices = CUBIT_TRUE,
                                          CubitBoolean free_surfaces = CUBIT_TRUE );
 
+  virtual CubitStatus import_solid_model(DLIList<TopologyBridge*> &imported_entities,
+					 const char* pBuffer,
+					 const int n_buffer_size);
+    
   CubitStatus unhook_BodySM_from_OCC( BodySM* bodysm)const;
   CubitStatus unhook_Surface_from_OCC( Surface* surface) const;
   CubitStatus unhook_Curve_from_OCC( Curve* curve) const;
@@ -387,15 +397,32 @@
                               DLIList<OCCCurve*> &facet_curves,
                               DLIList<OCCPoint*> &facet_points );
 
+  CubitStatus write_topology( char*& p_buffer,
+			      int& n_buffer_size,
+			      bool b_export_buffer,
+			      DLIList<OCCBody*> &OCC_bodies,
+			      DLIList<OCCSurface*> &OCC_surfaces,
+			      DLIList<OCCCurve*> &OCC_curves,
+			      DLIList<OCCPoint*> &OCC_points);
+  
   CubitBoolean Write(const TopoDS_Shape& Sh,
                      const Standard_CString File,
                      TDF_Label label);
 
+  CubitBoolean Write(const TopoDS_Shape& Sh,
+		     char*& p_buffer,
+		     int& n_buffer_size,
+		     bool b_export_buffer);
+  
   CubitBoolean Read(TopoDS_Shape& Sh,
                     const Standard_CString File,
                     TDF_Label label,
                     bool print_results);
 
+  CubitBoolean Read(TopoDS_Shape& Sh,
+		    const char* pBuffer,
+		    const int n_buffer_size);
+
   static OCCQueryEngine* instance_;
     //- static pointer to unique instance of this class
 

Modified: cgm/trunk/geom/facet/FacetQueryEngine.cpp
===================================================================
--- cgm/trunk/geom/facet/FacetQueryEngine.cpp	2009-08-19 18:39:01 UTC (rev 3107)
+++ cgm/trunk/geom/facet/FacetQueryEngine.cpp	2009-08-19 20:05:46 UTC (rev 3108)
@@ -849,6 +849,14 @@
   return CUBIT_SUCCESS;
 }
 
+CubitStatus FacetQueryEngine::export_solid_model( DLIList<TopologyBridge*>& bridge_list,
+						  char*& p_buffer,
+						  int& n_buffer_size,
+						  bool b_export_buffer)
+{
+  return CUBIT_FAILURE;
+}
+
 CubitStatus
 FacetQueryEngine::gather_all_facet_entities( DLIList<FacetBody*> &facet_bodies,
                                              DLIList<FacetLump*> &facet_lumps,
@@ -1790,13 +1798,13 @@
     PRINT_ERROR("Trouble reading in file type for MBG\n");
     return CUBIT_FAILURE;
   }
-
+  
   if( strncmp( fileType, "MESH_BASED_GEOMETRY", 19 ) )
   {
     PRINT_ERROR("Not MESH_BASED_GEOMETRY file type\n");
     return CUBIT_FAILURE;
   }
-
+  
   // read in the endian value
   NCubitFile::CIOWrapper file_reader(file_ptr, 19, 0);
 
@@ -1838,6 +1846,12 @@
   return CUBIT_SUCCESS;
 }
 
+CubitStatus FacetQueryEngine::import_solid_model(DLIList<TopologyBridge*> &imported_entities,
+						 const char* pBuffer,
+						 const int n_buffer_size)
+{
+  return CUBIT_FAILURE;
+}
 
 //===============================================================================
 // Function   : restore_facets

Modified: cgm/trunk/geom/facet/FacetQueryEngine.hpp
===================================================================
--- cgm/trunk/geom/facet/FacetQueryEngine.hpp	2009-08-19 18:39:01 UTC (rev 3107)
+++ cgm/trunk/geom/facet/FacetQueryEngine.hpp	2009-08-19 20:05:46 UTC (rev 3108)
@@ -270,6 +270,11 @@
                                           const CubitString &cubit_version,
                                           const char* logfile_name = NULL );
 
+  virtual CubitStatus export_solid_model( DLIList<TopologyBridge*>& bridge_list,
+					  char*& p_buffer,
+					  int& n_buffer_size,
+					  bool b_export_buffer);
+
   virtual CubitStatus save_temp_geom_file( DLIList<TopologyBridge*>& ref_entity_list,
                                           const char *file_name,
                                           const CubitString &cubit_version,
@@ -292,7 +297,11 @@
                                          CubitBoolean import_curves = CUBIT_TRUE,
                                          CubitBoolean import_vertices = CUBIT_TRUE,
                                          CubitBoolean free_surfaces = CUBIT_TRUE );
-private:
+
+ virtual CubitStatus import_solid_model(DLIList<TopologyBridge*> &imported_entities,
+					const char* pBuffer,
+					const int n_buffer_size);
+    private:
   CubitStatus import_solid_model(FILE *file_ptr,
                                  const char* /*file_type*/,
                                  DLIList<TopologyBridge*> &imported_entities,

Deleted: cgm/trunk/geom/parallel/AcisMemFile.hpp
===================================================================
--- cgm/trunk/geom/parallel/AcisMemFile.hpp	2009-08-19 18:39:01 UTC (rev 3107)
+++ cgm/trunk/geom/parallel/AcisMemFile.hpp	2009-08-19 20:05:46 UTC (rev 3108)
@@ -1,144 +0,0 @@
-#ifndef ACISMEMFILE
-#define ACISMEMFILE
-
-//---------------------------------------------------------------------
-// Define the AcisMemFile class for doing ACIS save and restore to a memory
-// buffer.  This file is intended as an example of how to create a new
-// ACIS FileInterface object.
-//
-// This class is used to store ACIS-specific geometry in a memory file;
-// generic memory file functions are implemented in CGMMemFile; ACIS-specific
-// functions for gathering ACIS geometry and putting it in a memory buffer
-// is implemented in AcisMemFile and in the ACIS BinaryFile class.
-//
-// There is also a FileSizeComputer class.  This can be used to determine
-// how many bytes a list of entities will use when saved.
-//---------------------------------------------------------------------
-
-#if CUBIT_ACIS_VERSION < 1100
-#include "kernel/kernutil/fileio/binfile.hxx"
-#else
-#include "binfile.hxx"
-#endif
-#include "CGMMemFile.hpp"
-#include "DLIList.hpp"
-
-class AcisQueryEngine;
-class RefEntity;
-class ENTITY_LIST;
-//---------------------------------------------------------------------
-
-class AcisMemFile : public BinaryFile,
-                    public CGMMemFile
-{
-
-public:
-
-  AcisMemFile(AcisQueryEngine *aqe) {acisQueryEngine = aqe;};
-    //- (empty) constructor
-
-  virtual ~AcisMemFile() {};
-    //- (empty) destructor
-
-  virtual FilePosition set_mark();
-    //- The methods for positioning the file pointer must also be
-    //- implemented for each derived class.  These are not normally
-    //- used.
-
-  virtual FilePosition goto_mark(FilePosition);
-    //- The methods for positioning the file pointer must also be
-    //- implemented for each derived class.  These are not normally
-    //- used.
-
-  size_t BytesWritten() { return (size_t)m_currentPosition; }
-    //- Get the number of bytes written
-
-protected:
-
-  CubitStatus read_refentity_list(DLIList<RefEntity*> &ref_entity_list);
-    //- read a RefEntity list from the buffer into ref_entity_list; relies on engine-
-    //- specific implementation
-
-  CubitStatus write_refentity_list(DLIList<RefEntity*> &ref_entity_list);
-    //- write a RefEntity list to the buffer from ref_entity_list; relies on engine-
-    //- specific implementation
-  CubitStatus append_refentity_list(DLIList<RefEntity*> &ref_entity_list,
-                                    int &buffer_size);
-
-  CubitStatus get_refentity_list(DLIList<RefEntity*> &ref_entity_list);
-
-  virtual int get_refentity_list_size(DLIList<RefEntity*> ref_entity_list);
-  //- get a the size of entities
-
-  virtual size_t read(void* buf, size_t length, logical swap);
-    //- ACIS-dependent function to read data from a buffer
-
-  virtual void write(const void* data, size_t len, logical swap);
-    //- ACIS-dependent function to write data to a buffer
-
-private:
-  size_t write_memory_buffer(ENTITY_LIST &entity_list);
-    //- write ACIS entity list to memory buffer
-
-  size_t append_memory_buffer(ENTITY_LIST &entity_list,
-                              int &buffer_size);
-
-  //unsigned char* get_memory_buffer(ENTITY_LIST &entity_list);
-  
-  int get_memory_buffer_size(ENTITY_LIST entity_list);
-    //- get a the size of entities in memory buffer
-  
-  size_t read_memory_buffer(ENTITY_LIST &entity_list);
-    // read ACIS entity list from memory buffer
-  size_t scatter_memory_buffer(ENTITY_LIST &entity_list,
-                                          int *buffer_sizes);
-  AcisQueryEngine *acisQueryEngine;
-    //- for convenience
-  
-};
-
-//---------------------------------------------------------------------
-// This class can be used to compute how many bytes will be required
-// to save a list of entities in binary format.  The following example
-// shows how it can be used:
-//
-// ENTITY_LIST elist;
-// ... add entities you want saved to the list
-// FileSizeComputer fsc;
-// outcome result = api_save_entity_list_file(&fsc, elist);
-// if(result.ok()) {
-//    unsigned long bytesNeeded = sc.GetSize();
-// }
-
-class FileSizeComputer : public BinaryFile {
-
-private:
-  size_t m_bytesNeeded;
-  int num_writes; // number of calls to write function
-  
-protected:
-
-    // These are the virtual methods which actually do the reading
-    // and writing of the data.
-
-    // Read doesn't really do anything.
-  virtual size_t read(void* buf, size_t length, logical swap);
-  virtual void write(const void* data, size_t len, logical swap);
-
-public:
-
-    // The methods for positioning the file pointer must also be
-    // implemented for each derived class.  These do not do
-    // anything in this class
-  virtual FilePosition set_mark();
-  virtual FilePosition goto_mark(FilePosition);
-
-public:
-  FileSizeComputer();
-  virtual ~FileSizeComputer();
-  size_t GetSize();
-  int GetWrites();
-};
-
-//---------------------------------------------------------------------
-#endif

Added: cgm/trunk/geom/parallel/AcisMemFile.hpp
===================================================================
--- cgm/trunk/geom/parallel/AcisMemFile.hpp	                        (rev 0)
+++ cgm/trunk/geom/parallel/AcisMemFile.hpp	2009-08-19 20:05:46 UTC (rev 3108)
@@ -0,0 +1,144 @@
+#ifndef ACISMEMFILE
+#define ACISMEMFILE
+
+//---------------------------------------------------------------------
+// Define the AcisMemFile class for doing ACIS save and restore to a memory
+// buffer.  This file is intended as an example of how to create a new
+// ACIS FileInterface object.
+//
+// This class is used to store ACIS-specific geometry in a memory file;
+// generic memory file functions are implemented in CGMMemFile; ACIS-specific
+// functions for gathering ACIS geometry and putting it in a memory buffer
+// is implemented in AcisMemFile and in the ACIS BinaryFile class.
+//
+// There is also a FileSizeComputer class.  This can be used to determine
+// how many bytes a list of entities will use when saved.
+//---------------------------------------------------------------------
+
+#if CUBIT_ACIS_VERSION < 1100
+#include "kernel/kernutil/fileio/binfile.hxx"
+#else
+#include "binfile.hxx"
+#endif
+#include "CGMMemFile.hpp"
+#include "DLIList.hpp"
+
+class AcisQueryEngine;
+class RefEntity;
+class ENTITY_LIST;
+//---------------------------------------------------------------------
+
+class AcisMemFile : public BinaryFile,
+                    public CGMMemFile
+{
+
+public:
+
+  AcisMemFile(AcisQueryEngine *aqe) {acisQueryEngine = aqe;};
+    //- (empty) constructor
+
+  virtual ~AcisMemFile() {};
+    //- (empty) destructor
+
+  virtual FilePosition set_mark();
+    //- The methods for positioning the file pointer must also be
+    //- implemented for each derived class.  These are not normally
+    //- used.
+
+  virtual FilePosition goto_mark(FilePosition);
+    //- The methods for positioning the file pointer must also be
+    //- implemented for each derived class.  These are not normally
+    //- used.
+
+  size_t BytesWritten() { return (size_t)m_currentPosition; }
+    //- Get the number of bytes written
+
+protected:
+
+  CubitStatus read_refentity_list(DLIList<RefEntity*> &ref_entity_list);
+    //- read a RefEntity list from the buffer into ref_entity_list; relies on engine-
+    //- specific implementation
+
+  CubitStatus write_refentity_list(DLIList<RefEntity*> &ref_entity_list);
+    //- write a RefEntity list to the buffer from ref_entity_list; relies on engine-
+    //- specific implementation
+  CubitStatus append_refentity_list(DLIList<RefEntity*> &ref_entity_list,
+                                    int &buffer_size);
+
+  CubitStatus get_refentity_list(DLIList<RefEntity*> &ref_entity_list);
+
+  virtual int get_refentity_list_size(DLIList<RefEntity*> ref_entity_list);
+  //- get a the size of entities
+
+  virtual size_t read(void* buf, size_t length, logical swap);
+    //- ACIS-dependent function to read data from a buffer
+
+  virtual void write(const void* data, size_t len, logical swap);
+    //- ACIS-dependent function to write data to a buffer
+
+private:
+  size_t write_memory_buffer(ENTITY_LIST &entity_list);
+    //- write ACIS entity list to memory buffer
+
+  size_t append_memory_buffer(ENTITY_LIST &entity_list,
+                              int &buffer_size);
+
+  //unsigned char* get_memory_buffer(ENTITY_LIST &entity_list);
+  
+  int get_memory_buffer_size(ENTITY_LIST entity_list);
+    //- get a the size of entities in memory buffer
+  
+  size_t read_memory_buffer(ENTITY_LIST &entity_list);
+    // read ACIS entity list from memory buffer
+  size_t scatter_memory_buffer(ENTITY_LIST &entity_list,
+                                          int *buffer_sizes);
+  AcisQueryEngine *acisQueryEngine;
+    //- for convenience
+  
+};
+
+//---------------------------------------------------------------------
+// This class can be used to compute how many bytes will be required
+// to save a list of entities in binary format.  The following example
+// shows how it can be used:
+//
+// ENTITY_LIST elist;
+// ... add entities you want saved to the list
+// FileSizeComputer fsc;
+// outcome result = api_save_entity_list_file(&fsc, elist);
+// if(result.ok()) {
+//    unsigned long bytesNeeded = sc.GetSize();
+// }
+
+class FileSizeComputer : public BinaryFile {
+
+private:
+  size_t m_bytesNeeded;
+  int num_writes; // number of calls to write function
+  
+protected:
+
+    // These are the virtual methods which actually do the reading
+    // and writing of the data.
+
+    // Read doesn't really do anything.
+  virtual size_t read(void* buf, size_t length, logical swap);
+  virtual void write(const void* data, size_t len, logical swap);
+
+public:
+
+    // The methods for positioning the file pointer must also be
+    // implemented for each derived class.  These do not do
+    // anything in this class
+  virtual FilePosition set_mark();
+  virtual FilePosition goto_mark(FilePosition);
+
+public:
+  FileSizeComputer();
+  virtual ~FileSizeComputer();
+  size_t GetSize();
+  int GetWrites();
+};
+
+//---------------------------------------------------------------------
+#endif


Property changes on: cgm/trunk/geom/parallel/AcisMemFile.hpp
___________________________________________________________________
Added: svn:executable
   + *

Added: cgm/trunk/geom/parallel/CGMParallelComm.cpp
===================================================================
--- cgm/trunk/geom/parallel/CGMParallelComm.cpp	                        (rev 0)
+++ cgm/trunk/geom/parallel/CGMParallelComm.cpp	2009-08-19 20:05:46 UTC (rev 3108)
@@ -0,0 +1,421 @@
+#include "CGMParallelComm.hpp"
+//#include "CubitAttrib.hpp"
+//#include "OCCQueryEngine.hpp"
+#include "TopologyEntity.hpp"
+#include "GeometryQueryEngine.hpp"
+#include "RefEntity.hpp"
+
+//#include <iostream>
+#include <sstream>
+
+#ifdef USE_MPI
+#include "mpi.h"
+#endif
+
+#define INITIAL_BUFF_SIZE 1024
+#define RRA(a) if (CUBIT_SUCCESS != result) {	\
+    std::string tmp_str;			\
+    tmp_str.append("\n"); tmp_str.append(a);	\
+    PRINT_ERROR(tmp_str.c_str());		\
+    return result;}
+
+CGMParallelComm::CGMParallelComm(CGMTagManager *impl,
+				 MPI_Comm comm, int* id )
+  : cgmImpl(impl), procConfig(comm)
+{
+  myBuffer.resize(INITIAL_BUFF_SIZE);
+  
+  int flag = 1;
+  int retval = MPI_Initialized(&flag);
+  if (MPI_SUCCESS != retval || !flag) {
+    int argc = 0;
+    char **argv = NULL;
+    
+    // mpi not initialized yet - initialize here
+    retval = MPI_Init(&argc, &argv);
+  }
+  
+  pcommID = add_pcomm(this);
+  if (id)
+    *id = pcommID;
+
+  m_pBuffer = NULL;
+  m_nBufferSize = 0;
+  m_currentPosition = 0;
+}
+
+CGMParallelComm::CGMParallelComm(CGMTagManager *impl,
+				 std::vector<unsigned char> &tmp_buff, 
+				 MPI_Comm comm,
+				 int* id) 
+  : cgmImpl(impl), procConfig(comm)
+{
+  myBuffer.swap(tmp_buff);
+  int flag = 1;
+  int retval = MPI_Initialized(&flag);
+  if (MPI_SUCCESS != retval || !flag) {
+    int argc = 0;
+    char **argv = NULL;
+    
+    // mpi not initialized yet - initialize here
+    retval = MPI_Init(&argc, &argv);
+  }
+
+  pcommID = add_pcomm(this);
+  if (id)
+    *id = pcommID;
+
+  m_pBuffer = NULL;
+  m_nBufferSize = 0;
+  m_currentPosition = 0;
+}
+
+CGMParallelComm::~CGMParallelComm() 
+{
+  remove_pcomm(this);
+  delete m_pBuffer;
+}
+
+int CGMParallelComm::add_pcomm(CGMParallelComm *pc) 
+{
+  // add this pcomm to instance tag
+  std::vector<CGMParallelComm *> pc_array;
+  pc_array = cgmImpl->get_pc_array();
+  pc_array.push_back(pc);
+
+  return pc_array.size() - 1;
+}
+
+void CGMParallelComm::remove_pcomm(CGMParallelComm *pc) 
+{
+  // remove this pcomm from instance tag
+  std::vector<CGMParallelComm *> pc_array;
+  pc_array = cgmImpl->get_pc_array();
+
+  std::vector<CGMParallelComm*>::iterator pc_it = 
+    std::find(pc_array.begin(), pc_array.end(), pc);
+  assert(pc_it != pc_array.end());
+  pc_array.erase(pc_it);
+}
+
+//! get the indexed pcomm object from the interface
+CGMParallelComm *CGMParallelComm::get_pcomm(CGMTagManager *impl,
+					    const int index) 
+{  
+  std::vector<CGMParallelComm *> pc_array;
+  pc_array = impl->get_pc_array();
+
+  if (pc_array.size() < (unsigned int) (index + 1)) return NULL;
+  else return pc_array[index];
+}
+
+CubitStatus CGMParallelComm::get_all_pcomm(CGMTagManager *impl,
+					   std::vector<CGMParallelComm*>& list )
+{
+  list = impl->get_pc_array();
+  return CUBIT_SUCCESS;
+}
+  
+
+//! get the indexed pcomm object from the interface
+CGMParallelComm *CGMParallelComm::get_pcomm(CGMTagManager *impl,
+					    //MBEntityHandle prtn,
+					    const MPI_Comm* comm ) 
+{
+  //MBErrorCode rval;
+  CGMParallelComm* result = 0;
+  
+  //MBTag prtn_tag;
+  //rval = impl->tag_create( PARTITIONING_PCOMM_TAG_NAME, 
+  //                       sizeof(int),
+  //                       MB_TAG_SPARSE,
+  //                       MB_TYPE_INTEGER,
+  //                       prtn_tag,
+  //                       0, true );
+  //if (MB_SUCCESS != rval)
+  //return 0;
+  
+  int pcomm_id;
+  //rval = impl->tag_get_data( prtn_tag, &prtn, 1, &pcomm_id );
+  //if (MB_SUCCESS == rval) {
+    result= get_pcomm(impl, 
+		      pcomm_id );
+    //}
+    /*
+  else if (MB_TAG_NOT_FOUND == rval && comm) {
+    result = new MBParallelComm( impl, *comm, &pcomm_id );
+    if (!result)
+      return 0;
+    result->set_partitioning( prtn );
+    
+    rval = impl->tag_set_data( prtn_tag, &prtn, 1, &pcomm_id );
+    if (MB_SUCCESS != rval) {
+      delete result;
+      result = 0;
+    }
+    }*/
+  
+  return result;
+}
+
+CubitStatus CGMParallelComm::bcast_buffer(const unsigned int from_proc) 
+{
+  //- broadcasts the buffer contained in this object
+
+  if ((int)procConfig.proc_rank() == from_proc) {
+    PRINT_DEBUG_100("Broadcasting buffer size from %d.\n", from_proc);
+    MPI_Bcast(&m_nBufferSize, 1, MPI_INT, from_proc, MPI_COMM_WORLD);
+    PRINT_DEBUG_100("Broadcasting buffer from %d, %d bytes.\n", from_proc,
+		    m_nBufferSize);
+    MPI_Bcast(m_pBuffer, m_nBufferSize, MPI_BYTE, from_proc, 
+              MPI_COMM_WORLD);
+  }
+  else {
+    int this_size;
+    PRINT_DEBUG_100("Broadcasting buffer size from proc %d.\n",
+		    procConfig.proc_rank());
+    MPI_Bcast(&this_size, 1, MPI_INT, from_proc, 
+              MPI_COMM_WORLD);
+    PRINT_DEBUG_100("Processor %d: received size of %d.\n", procConfig.proc_rank(), this_size);
+    check_size(this_size);
+    PRINT_DEBUG_100("Broadcasting buffer from proc %d, %d bytes.\n", 
+                    procConfig.proc_rank(), this_size);
+    MPI_Bcast(m_pBuffer, this_size, MPI_BYTE, from_proc, 
+              MPI_COMM_WORLD);
+  }
+ 
+  return CUBIT_SUCCESS;
+}
+
+CubitStatus CGMParallelComm::broadcast_entities(const unsigned int from_proc,
+						DLIList<RefEntity*> &ref_entity_list)
+{
+#ifndef USE_MPI
+  return CUBIT_FAILURE;
+#else
+  CubitStatus result = CUBIT_SUCCESS;
+
+  if ((int)procConfig.proc_rank() == from_proc) {
+    int nBufferSize = 0;
+    result = write_buffer(ref_entity_list, m_pBuffer, nBufferSize, false);
+    RRA("Failed to write ref entity list to buffer.");
+
+    result = check_size(nBufferSize);
+    RRA("Failed to write ref entity list to buffer.");
+
+    result = write_buffer(ref_entity_list, m_pBuffer, nBufferSize, true);
+    //m_currentPosition = m_nBufferSize;
+    RRA("Failed to write ref entity list to buffer.");
+  }
+  
+  result = bcast_buffer(from_proc);
+  RRA("Failed to broadcast buffer to processors.");
+  
+  if ((int)procConfig.proc_rank() != from_proc) {
+    result = read_buffer(ref_entity_list, m_pBuffer, m_nBufferSize);
+    RRA("Failed to read ref entity list from buffer.");
+  }
+  
+  return CUBIT_SUCCESS;
+#endif
+}
+
+// scatter exact amount of geometry information to each processors
+CubitStatus CGMParallelComm::scatter_entities(const unsigned int from_proc,
+					      DLIList<RefEntity*> &ref_entity_list)
+{
+#ifndef USE_MPI
+  return CUBIT_FAILURE;
+#else
+  CubitStatus result = CUBIT_SUCCESS;
+  CubitStatus status;
+  double tScatter;
+  int mySendCount;
+  int nEntity;
+  DLIList<RefEntity*> temp_list, temp_ref_list;
+
+  int nProcs = procConfig.proc_size();
+  int *sendCounts = new int[nProcs];
+  int *displacements = new int[nProcs];
+  int nBarEntity;
+  int restEntity;
+  int nEndEntity;
+  displacements[0] = 0;
+
+  if (procConfig.proc_rank() == from_proc) {
+    int curPosition = 0;
+    nEntity = ref_entity_list.size();
+    nBarEntity = nEntity/nProcs;
+    restEntity = nEntity%nProcs;
+    nEndEntity = nBarEntity + restEntity;
+    
+    ref_entity_list.reset();
+    int sum = 0;
+
+    // make temporary lists to contain geometry information for each processors
+    for (int i = 0; i < nProcs; i++) {
+      if (i == from_proc) {
+	ref_entity_list.step(nBarEntity);
+	if (i < restEntity) ref_entity_list.step();
+	sendCounts[i] = 0;
+      }
+      else {
+	for ( int j = 0; j < nBarEntity; j++) {
+	  RefEntity* body_ptr = ref_entity_list.get_and_step();
+	  temp_list.append(body_ptr);
+	}
+	
+	if (i < restEntity) {
+	  RefEntity* body_ptr = ref_entity_list.get_and_step();
+	  temp_list.append(body_ptr);
+	}
+	
+	//sendCounts[i] = get_ref_list_buffer_size(temp_list);
+	result = write_buffer(temp_list, m_pBuffer, sendCounts[i], false);
+	RRA("Failed to write ref entity list to buffer.");
+	
+	sum += sendCounts[i];
+	temp_list.clean_out();
+      }
+    }
+
+    // check the size of the buffer and resize if necessary
+    check_size(sum);
+    
+    // now append the real information
+    ref_entity_list.reset();
+    for (int i = 0; i < nProcs; i++) {
+      if (i == from_proc) {
+	ref_entity_list.step(nBarEntity);
+	if (i < restEntity) ref_entity_list.step();
+      }
+      else {
+	for ( int j = 0; j < nBarEntity; j++) {
+	  temp_list.append(ref_entity_list.get_and_step());
+	}
+	
+	if (i < restEntity) {
+	  temp_list.append(ref_entity_list.get_and_step());
+	}
+	
+	append_to_buffer(temp_list, sendCounts[i]);
+	temp_list.clean_out();
+      }
+    }
+  }
+
+  // broadcast buffer size array
+  PRINT_DEBUG_100("Broadcasting buffer size array from master.\n");
+  MPI_Bcast(sendCounts, nProcs, MPI_INT, from_proc, MPI_COMM_WORLD);
+  
+  for (int i = 1; i < nProcs; i++) {
+    displacements[i] = displacements[i-1] + sendCounts[i-1];
+  }
+  
+  mySendCount = sendCounts[procConfig.proc_rank()];
+
+  if (procConfig.proc_rank() != from_proc) check_size(mySendCount);
+
+  PRINT_DEBUG_100("Scattering buffer from master.\n");
+
+  // scatter geometry
+  MPI_Scatterv(m_pBuffer, sendCounts, displacements, MPI_BYTE, m_pBuffer, 
+	       mySendCount, MPI_BYTE, from_proc, MPI_COMM_WORLD);
+
+  if (procConfig.proc_rank() != from_proc) {
+    result = read_buffer(ref_entity_list, m_pBuffer, mySendCount);
+    RRA("Failed to read ref entity list from buffer.");
+  }
+
+  return CUBIT_SUCCESS;
+#endif
+}
+/*
+CubitStatus CGMParallelComm::write_buffer(DLIList<RefEntity*> &ref_entity_list,
+					 std::ofstream& os)
+{
+#ifndef USE_MPI
+  return CUBIT_FAILURE;
+#else
+  //ofstream os;
+  //CubitStatus result = GeometryQueryTool::instance()->export_solid_model(ref_entity_list, p_buffer);
+  CubitStatus result = GeometryQueryTool::instance()->export_solid_model(ref_entity_list, os);
+  RRA("Failed to compute buffer size in broadcast_entities.");
+  
+  return CUBIT_SUCCESS;
+#endif
+}
+
+CubitStatus CGMParallelComm::write_buffer(DLIList<RefEntity*> &ref_entity_list,
+					 std::ostringstream& os)
+{
+#ifndef USE_MPI
+  return CUBIT_FAILURE;
+#else
+  CubitStatus result = GeometryQueryTool::instance()->export_solid_model(ref_entity_list, os);
+  RRA("Failed to compute buffer size in broadcast_entities.");
+  
+  return CUBIT_SUCCESS;
+#endif
+}
+*/
+CubitStatus CGMParallelComm::write_buffer(DLIList<RefEntity*> &ref_entity_list,
+					  char* pBuffer,
+					  int& n_buffer_size,
+					  bool b_write_buffer)
+{
+#ifndef USE_MPI
+  return CUBIT_FAILURE;
+#else
+  CubitStatus result = GeometryQueryTool::instance()->export_solid_model(ref_entity_list, pBuffer,
+									 n_buffer_size, b_write_buffer);
+  RRA("Failed to write ref entities to buffer.");
+  
+  if (b_write_buffer) m_currentPosition += n_buffer_size;
+  return CUBIT_SUCCESS;
+#endif
+}
+
+CubitStatus CGMParallelComm::read_buffer(DLIList<RefEntity*> &ref_entity_list,
+					 const char* pBuffer,
+					 const int n_buffer_size)
+{
+#ifndef USE_MPI
+  return CUBIT_FAILURE;
+#else
+  CubitStatus result = GeometryQueryTool::instance()->import_solid_model(&ref_entity_list, pBuffer,
+									 n_buffer_size);
+  RRA("Failed to read ref entities from buffer.");
+  
+  return CUBIT_SUCCESS;
+#endif
+}
+
+CubitStatus CGMParallelComm::check_size(int& target_size, const CubitBoolean keep) 
+{
+  PRINT_DEBUG_100("Checking buffer size on proc %d, target size %d.\n", 
+                  procConfig.proc_rank(), target_size);
+
+  if (m_nBufferSize < target_size) {
+    PRINT_DEBUG_100("Increasing buffer size on proc %d.\n", procConfig.proc_rank());
+    void *temp_buffer = malloc(target_size);
+    if (keep && 0 != m_currentPosition) memcpy(temp_buffer, m_pBuffer, m_currentPosition);
+    delete m_pBuffer;
+    m_pBuffer = (char *) temp_buffer;
+    m_nBufferSize = target_size;
+  }
+
+  return CUBIT_SUCCESS;
+}
+
+CubitStatus CGMParallelComm::append_to_buffer(DLIList<RefEntity*> &ref_entity_list,
+					      int add_size) 
+{
+  if (m_currentPosition + add_size > m_nBufferSize) return CUBIT_FAILURE;
+  CubitStatus result = write_buffer(ref_entity_list, m_pBuffer + m_currentPosition, add_size, true);
+  RRA("Failed to append ref entity list to buffer.");
+  
+  //m_currentPosition += add_size;
+
+  return CUBIT_SUCCESS;
+}

Added: cgm/trunk/geom/parallel/CGMParallelComm.hpp
===================================================================
--- cgm/trunk/geom/parallel/CGMParallelComm.hpp	                        (rev 0)
+++ cgm/trunk/geom/parallel/CGMParallelComm.hpp	2009-08-19 20:05:46 UTC (rev 3108)
@@ -0,0 +1,225 @@
+/**
+ * \class CGMParallelComm
+ * \brief Parallel communications in CGM
+ * \author Hong-Jun Kim, copied from MBParallelComm.hpp
+ *
+ *  This class implements methods to communicate geometry between processors
+ *
+ */
+
+#ifndef CGM_PARALLEL_COMM_HPP
+#define CGM_PARALLEL_COMM_HPP
+
+//#include "CGMForward.hpp"
+#include "GeometryQueryTool.hpp"
+//#include "CGMRange.hpp"
+#include "CGMProcConfig.hpp"
+#include "CATag.hpp"
+#include <map>
+#include <set>
+#include <vector>
+#include "math.h"
+
+#ifdef SEEK_SET
+#  define SEEK_SET_OLD SEEK_SET
+#  undef SEEK_SET
+#endif
+#ifdef SEEK_CUR
+#  define SEEK_CUR_OLD SEEK_CUR
+#  undef SEEK_CUR
+#endif
+#ifdef SEEK_END
+#  define SEEK_END_OLD SEEK_END
+#  undef SEEK_END
+#endif
+#include "mpi.h"
+#ifdef SEEK_SET_OLD
+#  undef SEEK_SET
+#  define SEEK_SET SEEK_SET_OLD
+#  undef SEEK_SET_OLD
+#endif
+#ifdef SEEK_CUR_OLD
+#  undef SEEK_CUR
+#  define SEEK_CUR SEEK_CUR_OLD
+#  undef SEEK_CUR_OLD
+#endif
+#ifdef SEEK_END_OLD
+#  undef SEEK_END
+#  define SEEK_END SEEK_END_OLD
+#  undef SEEK_END_OLD
+#endif
+
+
+extern "C" {
+  struct tuple_list;
+}
+
+//class TagServer;
+//class SequenceManager;
+//template <typename KeyType, typename ValType, ValType NullVal> class RangeMap;
+//typedef RangeMap<CGMEntityHandle, CGMEntityHandle, 0> HandleMap;
+
+#define MAX_SHARING_PROCS 64
+
+class CGMParallelComm 
+{
+public:
+
+    //! constructor
+  CGMParallelComm(CGMTagManager *impl,
+		  MPI_Comm comm = MPI_COMM_WORLD,
+		  int* pcomm_id_out = 0);
+  
+  //! constructor taking buffer, for testing
+  CGMParallelComm(CGMTagManager *impl,
+		  std::vector<unsigned char> &tmp_buff,
+		  MPI_Comm comm = MPI_COMM_WORLD,
+		  int* pcomm_id_out = 0);
+  
+    //! Get ID used to reference this PCOMM instance
+  int get_id() const { return pcommID; }
+
+    //! get the indexed pcomm object from the interface
+  static CGMParallelComm *get_pcomm(CGMTagManager *impl,
+				    const int index);
+  
+    //! Get CGMParallelComm instance associated with partition handle
+    //! Will create CGMParallelComm instance if a) one does not already
+    //! exist and b) a valid value for MPI_Comm is passed.
+  static CGMParallelComm *get_pcomm(CGMTagManager *impl,
+                                    //CGMEntityHandle partitioning,
+                                    const MPI_Comm* comm = 0 );
+
+  static CubitStatus get_all_pcomm(CGMTagManager *impl,
+				   std::vector<CGMParallelComm*>& list );
+  
+  //! destructor
+  ~CGMParallelComm();
+  
+  //static unsigned char PROC_SHARED, PROC_OWNER;
+  /*
+    //! assign a global id space, for largest-dimension or all entities (and
+    //! in either case for vertices too)
+  CGMErrorCode assign_global_ids(CGMEntityHandle this_set,
+                                const int dimension,
+                                const int start_id = 1,
+                                const bool largest_dim_only = true,
+                                const bool parallel = true);
+
+    //! check for global ids; based only on tag handle being there or not;
+    //! if it's not there, create them for the specified dimensions
+  CGMErrorCode check_global_ids(CGMEntityHandle this_set,
+                               const int dimension, 
+                               const int start_id = 1,
+                               const bool largest_dim_only = true,
+                               const bool parallel = true);
+  */
+	
+  //! return partition ref entity list
+  DLIList<RefEntity*> &partition_surf_list() {return partitioningSurfList;}
+  const DLIList<RefEntity*> &partition_surf_list() const {return partitioningSurfList;}
+  DLIList<RefEntity*> &partition_body_list() {return partitioningBodyList;}
+  const DLIList<RefEntity*> &partition_body_list() const {return partitioningBodyList;}
+
+  //! Get proc config for this communication object
+  const CGMProcConfig &proc_config() const {return procConfig;}
+  
+  //! Get proc config for this communication object
+  CGMProcConfig &proc_config() {return procConfig;}
+
+  CubitStatus broadcast_entities(const unsigned int from_proc,
+				 DLIList<RefEntity*> &ref_entity_list);
+
+  CubitStatus scatter_entities(const unsigned int from_proc,
+			       DLIList<RefEntity*> &ref_entity_list);
+  /*
+  CubitStatus write_buffer(DLIList<RefEntity*> &ref_entity_list,
+			  //const unsigned char* p_buffer);
+			  //char* p_buffer);
+			  std::ofstream& os);
+
+  CubitStatus write_buffer(DLIList<RefEntity*> &ref_entity_list,
+			  std::ostringstream& os);
+  */
+  CubitStatus write_buffer(DLIList<RefEntity*> &ref_entity_list,
+			  char* pBuffer,
+			  int& n_buffer_size,
+			  bool b_export_buffer);
+
+  CubitStatus read_buffer(DLIList<RefEntity*> &ref_entity_list,
+			    const char* pBuffer,
+			    const int n_buffer_size);
+    
+  CubitStatus bcast_buffer(const unsigned int from_proc);
+
+  CubitStatus append_to_buffer(DLIList<RefEntity*> &ref_entity_list,
+			       int add_size);
+  
+private:  
+
+    //! add a pc to the iface instance tag PARALLEL_COMM
+  int add_pcomm(CGMParallelComm *pc);
+  
+    //! remove a pc from the iface instance tag PARALLEL_COMM
+  void remove_pcomm(CGMParallelComm *pc);
+
+  CubitStatus check_size(int& target_size, const CubitBoolean keep = CUBIT_FALSE);
+  
+    //! CGM query tool interface associated with this writer
+  GeometryQueryTool *gqt;
+
+    //! CGM tag manager interface associated with this writer
+  CGMTagManager *cgmImpl;
+
+    //! Proc config object, keeps info on parallel stuff
+  CGMProcConfig procConfig;
+
+    //! Tag server, so we can get more info about tags
+  //TagServer *tagServer;
+
+    //! Sequence manager, to get more efficient access to entities
+  //SequenceManager *sequenceManager;
+  
+  
+    //! data buffer used to communicate
+  std::vector<unsigned char> myBuffer;
+
+  char* m_pBuffer;
+  
+  int m_nBufferSize;
+  
+  int m_currentPosition;
+
+  //std::ofstream mOfstream;
+
+    //! more data buffers, proc-specific
+  //std::vector<unsigned char> ownerRBuffs[MAX_SHARING_PROCS],
+  //ownerSBuffs[MAX_SHARING_PROCS], ghostRBuffs[MAX_SHARING_PROCS],
+  // ghostSBuffs[MAX_SHARING_PROCS];
+
+    //! request objects, may be used if store_remote_handles is used
+  //MPI_Request sendReqs[2*MAX_SHARING_PROCS];
+
+    //! processor rank for each buffer index
+  //std::vector<int> buffProcs;
+
+    //! the partition, interface sets for this comm'n instance
+  //CGMRange partitionSets, interfaceSets;
+  
+    //! local entities ghosted to other procs
+  //std::map<unsigned int, CGMRange> ghostedEnts;
+  
+    //! tags used to save sharing procs and handles
+  //CGMTag sharedpTag, sharedpsTag, sharedhTag, sharedhsTag, pstatusTag, 
+  //ifaceSetsTag, partitionTag;
+    
+  //int globalPartCount; //!< Cache of global part count
+  
+  //CGMEntityHandle partitioningSet; //!< entity set containing all parts
+  DLIList<RefEntity*> partitioningSurfList; // ref entity list containing all parts
+  DLIList<RefEntity*> partitioningBodyList; // ref entity list containing all parts
+  
+  int pcommID;
+};
+
+#endif

Added: cgm/trunk/geom/parallel/CGMProcConfig.cpp
===================================================================
--- cgm/trunk/geom/parallel/CGMProcConfig.cpp	                        (rev 0)
+++ cgm/trunk/geom/parallel/CGMProcConfig.cpp	2009-08-19 20:05:46 UTC (rev 3108)
@@ -0,0 +1,23 @@
+#include "CGMProcConfig.hpp"
+
+//! Constructor
+CGMProcConfig::CGMProcConfig(MPI_Comm proc_comm) 
+  : procComm(proc_comm),
+    crystalInit(false)
+{
+#ifdef USE_MPI
+  int rank, size;
+  MPI_Comm_rank(procComm, &rank); 
+  procRank = (unsigned int) rank;
+  MPI_Comm_size(procComm, &size); 
+  procSize = (unsigned int) size;
+#else
+  procRank = 0;
+  procSize = 1;
+#endif
+}
+
+CGMProcConfig::~CGMProcConfig() 
+{
+}
+

Added: cgm/trunk/geom/parallel/CGMProcConfig.hpp
===================================================================
--- cgm/trunk/geom/parallel/CGMProcConfig.hpp	                        (rev 0)
+++ cgm/trunk/geom/parallel/CGMProcConfig.hpp	2009-08-19 20:05:46 UTC (rev 3108)
@@ -0,0 +1,89 @@
+#ifndef CGM_PROC_CONFIG_HPP
+#define CGM_PROC_CONFIG_HPP
+
+//#include "MBTypes.h"
+//#include "MBRange.hpp"
+
+//class MBInterface;
+
+
+#ifdef USE_MPI
+/* MPICH2 will fail if SEEK_* macros are defined
+ * because they are also C++ enums. Undefine them
+ * when including mpi.h and then redefine them
+ * for sanity.
+ */
+
+#  ifdef SEEK_SET
+#    define CGM_SEEK_SET SEEK_SET
+#    define CGM_SEEK_CUR SEEK_CUR
+#    define CGM_SEEK_END SEEK_END
+#    undef SEEK_SET
+#    undef SEEK_CUR
+#    undef SEEK_END
+#  endif
+#include "mpi.h"
+
+#  ifdef CGM_SEEK_SET
+#    define SEEK_SET CGM_SEEK_SET
+#    define SEEK_CUR CGM_SEEK_CUR
+#    define SEEK_END CGM_SEEK_END
+#    undef CGM_SEEK_SET
+#    undef CGM_SEEK_CUR
+#    undef CGM_SEEK_END
+#  endif
+//extern "C" 
+//{
+  //#include "types.h"
+  //#include "errmem.h"
+//#include "crystal.h"
+//}
+#else
+typedef int MPI_Comm;
+#define MPI_COMM_WORLD 0
+//typedef void* crystal_data;
+#endif
+
+/**\brief Multi-CPU information for parallel CGM */
+class CGMProcConfig {
+public:
+
+  CGMProcConfig(MPI_Comm proc_comm = MPI_COMM_WORLD);
+  
+  ~CGMProcConfig();
+  
+    //! Get the current processor number
+  unsigned proc_rank() const 
+    { return procRank; }
+      
+    //! Get the number of processors
+  unsigned proc_size() const 
+    { return procSize; }
+      
+    //! get a crystal router for this parallel job
+  //crystal_data *crystal_router(bool construct_if_missing = true);
+
+    //! get/set the communicator for this proc config
+  const MPI_Comm proc_comm() const {return procComm;}
+  void proc_comm(MPI_Comm this_comm) {procComm = this_comm;}
+  
+private:
+
+    //! MPI communicator set for this instance
+  MPI_Comm procComm;
+
+    //! rank of this processor
+  unsigned procRank;
+  
+    //! number of processors
+  unsigned procSize;
+
+    //! whether the crystal router's been initialized or not
+  bool crystalInit;
+  
+    //! crystal router for this parallel job
+  //crystal_data crystalData;
+  
+};
+
+#endif

Added: cgm/trunk/geom/parallel/FileOptions.cpp
===================================================================
--- cgm/trunk/geom/parallel/FileOptions.cpp	                        (rev 0)
+++ cgm/trunk/geom/parallel/FileOptions.cpp	2009-08-19 20:05:46 UTC (rev 3108)
@@ -0,0 +1,463 @@
+/**\file FileOptions.cpp
+ *\ copied from MOAB
+ *\date 2009-06-11
+ */
+
+#include "FileOptions.hpp"
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+
+const char DEFAULT_SEPARATOR = ';';
+
+static inline bool strempty( const char* s ) { return !*s; }
+
+FileOptions::FileOptions( const char* str )
+  : mData(0)
+{
+    // if option string is null, just return
+  if (!str)
+    return;
+  
+    // check if alternate separator is specified
+  char separator[2] = { DEFAULT_SEPARATOR, '\0' };
+  if (*str == DEFAULT_SEPARATOR) {
+    ++str;
+    if (strempty(str))
+      return;
+    separator[0] = *str;
+    ++str;
+  }
+  
+    // don't bother allocating copy of input string if
+    // input string is empty.
+  if (!strempty(str))
+  {
+       // tokenize at separator character
+    mData = strdup( str );
+    for (char* i = strtok( mData, separator ); i; i = strtok( 0, separator )) 
+      if (!strempty(i)) // skip empty strings
+        mOptions.push_back( i );
+  }
+}
+
+FileOptions::FileOptions( const FileOptions& copy ) :
+  mData(0), mOptions( copy.mOptions.size() )
+{
+  if (!copy.mOptions.empty()) {
+    const char* last = copy.mOptions.back();
+    const char* endptr = last + strlen(last) + 1;
+    size_t len = endptr - copy.mData;
+    mData = (char*)malloc( len );
+    memcpy( mData, copy.mData, len );
+    for (size_t i = 0; i < mOptions.size(); ++i)
+      mOptions[i] = mData + (copy.mOptions[i] - copy.mData);
+  }
+}
+
+FileOptions& FileOptions::operator=( const FileOptions& copy )
+{
+  free( mData );
+  mData = 0;
+  mOptions.resize( copy.mOptions.size() );
+
+  if (!copy.mOptions.empty()) {
+    const char* last = copy.mOptions.back();
+    const char* endptr = last + strlen(last) + 1;
+    size_t len = endptr - copy.mData;
+    mData = (char*)malloc( len );
+    memcpy( mData, copy.mData, len );
+    for (size_t i = 0; i < mOptions.size(); ++i)
+      mOptions[i] = mData + (copy.mOptions[i] - copy.mData);
+  }
+    
+  return *this;
+}
+
+FileOptions::~FileOptions()
+{
+  free( mData );
+}
+
+FOErrorCode FileOptions::get_null_option( const char* name ) const
+{
+  const char* s;
+  FOErrorCode rval = get_option( name, s );
+  if (FO_SUCCESS != rval)
+    return rval;
+  return strempty(s) ? FO_SUCCESS : FO_TYPE_OUT_OF_RANGE;
+}
+
+FOErrorCode FileOptions::get_int_option( const char* name, int& value ) const
+{
+  const char* s;
+  FOErrorCode rval = get_option( name, s );
+  if (FO_SUCCESS != rval)
+    return rval;
+  
+    // empty string
+  if (strempty(s))
+    return FO_TYPE_OUT_OF_RANGE;
+  
+    // parse value
+  char* endptr;
+  long int pval = strtol( s, &endptr, 0 );
+  if (!strempty(endptr)) // syntax error
+    return FO_TYPE_OUT_OF_RANGE;
+  
+    // check for overflow (parsing long int, returning int)
+  value = pval;
+  if (pval != (long int)value)
+    return FO_TYPE_OUT_OF_RANGE;
+  
+  return FO_SUCCESS;
+}
+
+FOErrorCode FileOptions::get_ints_option( const char* name, 
+                                          std::vector<int>& values) const
+{
+  const char* s;
+  FOErrorCode rval = get_option( name, s );
+  if (FO_SUCCESS != rval)
+    return rval;
+  
+    // empty string
+  if (strempty(s))
+    return FO_TYPE_OUT_OF_RANGE;
+  
+    // parse values
+  while (!strempty(s)) {
+    char* endptr;
+    long int sval = strtol( s, &endptr, 0 );
+
+#define EATSPACE(a) while ((!strncmp(a, " ", 1) ||	\
+			    !strncmp(a, ",", 1)) && !strempty(a)) a++;
+    //EATSPACE(endptr);
+
+    while ((!strncmp(endptr, " ", 1) ||
+	    !strncmp(endptr, ",", 1)) && !strempty(endptr)) {
+      endptr++;
+    }
+
+    long int eval = sval;
+    if (!strcmp(endptr, "-")) {
+      endptr++;
+      s = endptr;
+      eval = strtol(s, &endptr, 0);
+      EATSPACE(endptr);
+    }
+  
+      // check for overflow (parsing long int, returning int)
+    int value = sval;
+    if (sval != (long int)value)
+      return FO_TYPE_OUT_OF_RANGE;
+    value = eval;
+    if (eval != (long int)value)
+      return FO_TYPE_OUT_OF_RANGE;
+  
+    for (int i = sval; i <= eval; i++)
+      values.push_back(i);
+
+    s = endptr;
+  }
+  
+  return FO_SUCCESS;
+}
+
+FOErrorCode FileOptions::get_real_option ( const char* name, double& value ) const
+{
+  const char* s;
+  FOErrorCode rval = get_option( name, s );
+  if (FO_SUCCESS != rval)
+    return rval;
+  
+    // empty string
+  if (strempty(s))
+    return FO_TYPE_OUT_OF_RANGE;
+  
+    // parse value
+  char* endptr;
+  value = strtod( s, &endptr );
+  if (!strempty(endptr)) // syntax error
+    return FO_TYPE_OUT_OF_RANGE;
+  
+  return FO_SUCCESS;
+}
+
+FOErrorCode FileOptions::get_str_option( const char* name, std::string& value ) const
+{
+  const char* s;
+  FOErrorCode rval = get_option( name, s );
+  if (FO_SUCCESS != rval)
+    return rval;
+  if (strempty(s))
+    return FO_TYPE_OUT_OF_RANGE;
+  value = s;
+  return FO_SUCCESS;
+}
+
+FOErrorCode FileOptions::get_option( const char* name, std::string& value ) const
+{
+  const char* s;
+  FOErrorCode rval = get_option( name, s );
+  if (FO_SUCCESS != rval)
+    return rval;
+  
+  value = s;
+  return FO_SUCCESS;
+}  
+
+FOErrorCode FileOptions::get_option( const char* name, const char*& value ) const
+{
+  std::vector<const char*>::const_iterator i;
+  for (i = mOptions.begin(); i != mOptions.end(); ++i) {
+    const char* opt = *i;
+    if (compare( name, opt )) {
+      value = opt + strlen(name);
+        // if compare returned true, next char after option
+        // name must be either the null char or an equals symbol.
+      if (*value == '=') 
+        ++value;
+        
+      return FO_SUCCESS;
+    }
+  }
+  
+  return FO_ENTITY_NOT_FOUND;
+}
+
+FOErrorCode FileOptions::match_option( const char* name, 
+                                       const char* value ) const
+{
+  int idx;
+  const char* array[] = { value, NULL };
+  return match_option( name, array, idx );
+}
+
+FOErrorCode FileOptions::match_option( const char* name, 
+                                       const char* const* values, 
+                                       int& index ) const
+{
+  const char* optval;
+  FOErrorCode rval = get_option( name, optval );
+  if (FO_SUCCESS != rval)
+    return rval;
+  
+  for (index = 0; values[index]; ++index)
+    if (compare( optval, values[index] ))
+      return FO_SUCCESS;
+  
+  index = -1;
+  return FO_FAILURE;
+}
+
+
+bool FileOptions::compare( const char* name, const char* option )
+{
+  while (!strempty(name) && toupper(*name) == toupper(*option)) {
+    ++name;
+    ++option;
+  }
+   // match if name matched option for length of name,
+   // and option either matched entirely or matches up to
+   // and equals sign.
+  return strempty(name) && (strempty(option) || *option == '=');
+}
+
+void FileOptions::get_options( std::vector<std::string>& list ) const
+{
+  list.clear();
+  list.resize( mOptions.size() );
+  std::copy( mOptions.begin(), mOptions.end(), list.begin() );
+}
+
+#ifdef TEST
+
+#include <iostream>
+
+#define CHECK(A) \
+  if (FO_SUCCESS != (A)) { \
+    std::cerr << "Failure at line " << __LINE__ << ": error code " << (A) << std::endl; \
+    return 1; \
+  }
+
+#define EQUAL(A,B) \
+  if (A != B) { \
+    std::cerr << "Failure at line " << __LINE__ << ": expected " << (B) << " but got " << (A) << std::endl; \
+    return 2; \
+  }
+
+int main()
+{
+  FileOptions tool( "INT1=1;NUL1;STR1=ABC;DBL1=1.0;dbl2=2.0;DBL3=3.0;INT2=2;nul2;NUL3;INT3=3;str2=once upon a time;str3==fubar=;;" );
+
+  std::string s;
+  int i;
+  double d;
+  FOErrorCodeyy rval;
+  
+    // test basic get_option method without deleting entry
+  rval = tool.get_option( "STR1", s );
+  CHECK(rval);
+  EQUAL( s, "ABC" );
+  
+    // test basic get_option method again, this time deleting the entry
+  rval = tool.get_option( "STR1", s );
+  CHECK(rval);
+  EQUAL( s, "ABC" );
+  
+    // test basig get_option method with a null option
+  rval = tool.get_option( "NUL2", s );
+  CHECK( rval );
+  EQUAL( s.empty(), true );
+
+  
+    // test null option
+  rval = tool.get_null_option( "nul1" );
+  CHECK( rval );
+  
+    // try null option method on non-null value
+  rval = tool.get_null_option( "INT1" ) ;
+  EQUAL( rval, FO_TYPE_OUT_OF_RANGE) ;
+  
+
+    // test integer option
+  rval = tool.get_int_option( "int1", i );
+  CHECK( rval );
+  EQUAL( i, 1 );
+  
+  rval = tool.get_int_option( "int2", i );
+  CHECK( rval );
+  EQUAL( i, 2 );
+  
+    // test integer option on non-integer value
+  rval = tool.get_int_option( "dbl2", i );
+  EQUAL( rval, FO_TYPE_OUT_OF_RANGE );
+  
+    // test integer option on null value
+  rval = tool.get_int_option( "NUL3", i);
+  EQUAL( rval, FO_TYPE_OUT_OF_RANGE );
+  
+    // test double option
+  rval = tool.get_real_option( "dbl1", d );
+  CHECK( rval );
+  EQUAL( d, 1.0 );
+  
+  rval = tool.get_real_option( "dbl2", d );
+  CHECK( rval );
+  EQUAL( d, 2.0 );
+  
+  rval = tool.get_real_option( "int3", d );
+  CHECK( rval );
+  EQUAL( d, 3.0 );
+  
+    // test real option on non-real value
+  rval = tool.get_real_option( "str2", d );
+  EQUAL( rval, FO_TYPE_OUT_OF_RANGE );
+  
+  
+    // test real option on null value
+  rval = tool.get_real_option( "NUL3", d );
+  EQUAL( rval, FO_TYPE_OUT_OF_RANGE );
+  
+    // test get a simple string option
+  rval = tool.get_str_option( "DBL3", s );
+  CHECK( rval );
+  EQUAL( s, "3.0" );
+  
+    // test get a string with spaces
+  rval = tool.get_str_option("STR2", s );
+  CHECK( rval );
+  EQUAL( s, "once upon a time" );
+  
+    // try to get a string value for a null option
+  rval = tool.get_str_option( "nul3", s );
+  EQUAL( rval, FO_TYPE_OUT_OF_RANGE );
+  
+    // test options using generic get_option method
+    
+  rval = tool.get_option( "NUL3", s );
+  CHECK( rval );
+  EQUAL( s.empty(), true );
+  
+  rval = tool.get_option( "STR3", s );
+  CHECK( rval );
+  EQUAL( s, "=fubar=" );
+  
+    // test size of options string
+  unsigned l = tool.size();
+  EQUAL( l, 12u );
+  
+  
+    // test alternate separator
+  
+  FileOptions tool2( ";+OPT1=ABC+OPT2=" );
+  l = tool2.size();
+  EQUAL( l, 2 );
+  
+  rval = tool2.get_option( "opt1", s );
+  CHECK( rval );
+  EQUAL( s, "ABC" );
+  
+  rval = tool2.get_option( "opt2", s );
+  CHECK( rval );
+  bool e = s.empty();
+  EQUAL( e, true );
+  
+  l = tool2.size();
+  EQUAL( l, 2 );
+  
+    
+    // test empty options string
+    
+  FileOptions tool3( ";;;;" );
+  e = tool3.empty();
+  EQUAL( e, true );
+  l = tool3.size();
+  EQUAL( l, 0 );
+  
+  FileOptions tool4(NULL);
+  e = tool4.empty();
+  EQUAL( e, true );
+  l = tool4.size();
+  EQUAL( l, 0 );
+  
+  FileOptions tool5(";+");
+  e = tool5.empty();
+  EQUAL( e, true );
+  l = tool5.size();
+  EQUAL( l, 0 );
+  
+    // test copy constructor
+  
+  FileOptions tool6( tool2 );
+  
+  rval = tool6.get_option( "opt1", s );
+  CHECK( rval );
+  EQUAL( s, "ABC" );
+  
+  rval = tool6.get_option( "opt2", s );
+  CHECK( rval );
+  e = s.empty();
+  EQUAL( e, true );
+  
+  l = tool6.size();
+  EQUAL( l, 2 );
+  
+  FileOptions tool7( tool5 );
+  e = tool7.empty();
+  EQUAL( e, true );
+  l = tool7.size();
+  EQUAL( l, 0 );
+  
+    // test assignment operator
+  
+  FileOptions tool8( tool2 );
+  tool8 = tool;
+  EQUAL( tool8.size(), tool.size() );
+    
+  return 0;
+}
+
+#endif

Added: cgm/trunk/geom/parallel/FileOptions.hpp
===================================================================
--- cgm/trunk/geom/parallel/FileOptions.hpp	                        (rev 0)
+++ cgm/trunk/geom/parallel/FileOptions.hpp	2009-08-19 20:05:46 UTC (rev 3108)
@@ -0,0 +1,165 @@
+/**\file FileOptions.hpp
+ *\copied from MOAB
+ *\date 2009-06-11
+ */
+
+#ifndef FILE_OPTIONS_HPP
+#define FILE_OPTIONS_HPP
+
+#include <string>
+#include <vector>
+#include "CubitDefines.h"
+
+/* file option type */
+enum FOErrorCode
+{
+  FO_SUCCESS = 0,
+  FO_TYPE_OUT_OF_RANGE,
+  FO_ENTITY_NOT_FOUND,
+  FO_FAILURE
+};
+
+/**\brief Parse options string passed to file IO routines
+ *
+ * This is a utility class used by file-IO-related code to 
+ * parse the options string passed to ParallelMeshTool::load_file
+ */
+class FileOptions {
+public:
+
+  /*\param options_string The concatenation of a list of 
+   *          options, separated either by the default separator
+   *          (semicolon) with a custom separator specified at
+   *          the beginning of the string (semicolon followed by
+   *          destired separator character.)
+   */
+  FileOptions( const char* option_string );
+  
+  FileOptions( const FileOptions& copy );
+  FileOptions& operator=( const FileOptions& copy );
+  
+  ~FileOptions();
+  
+  /**\brief Check for option with no value 
+   *
+   * Check for an option w/out a value.
+   *\param name The option name
+   *\return - CUBIT_SUCCESS if option is found
+   *        - CUBIT_TYPE_OUT_OF_RANGE if options is found, but has value
+   *        - CUBIT_ENTITY_NOT_FOUND if option is not found.
+   */
+  FOErrorCode get_null_option( const char* name ) const;
+  
+  /**\brief Check for option with an integer value.
+   *
+   * Check for an option with an integer value
+   *\param name The option name
+   *\param value Output. The value.
+   *\return - CUBIT_SUCCESS if option is found
+   *        - CUBIT_TYPE_OUT_OF_RANGE if options is found, but does not have an integer value
+   *        - CUBIT_ENTITY_NOT_FOUND if option is not found.
+   */
+  FOErrorCode get_int_option( const char* name, int& value ) const;
+  
+  /**\brief Check for option with a double value.
+   *
+   * Check for an option with a double value
+   *\param name The option name
+   *\param value Output. The value.
+   *\return - CUBIT_SUCCESS if option is found
+   *        - CUBIT_TYPE_OUT_OF_RANGE if options is found, but does not have a double value
+   *        - CUBIT_ENTITY_NOT_FOUND if option is not found.
+   */
+  FOErrorCode get_real_option( const char* name, double& value ) const;
+  
+  /**\brief Check for option with any value.
+   *
+   * Check for an option with any value.
+   *\param name The option name
+   *\param value Output. The value.
+   *\return - CUBIT_SUCCESS if option is found
+   *        - CUBIT_TYPE_OUT_OF_RANGE if options is found, but does not have a value
+   *        - CUBIT_ENTITY_NOT_FOUND if option is not found.
+   */
+  FOErrorCode get_str_option( const char* name, std::string& value ) const;
+  
+  /**\brief Check for option 
+   *
+   * Check for an option
+   *\param name The option name
+   *\param value The option value, or an empty string if no value.
+   *\return CUBIT_SUCCESS or CUBIT_ENTITY_NOT_FOUND
+   */
+  FOErrorCode get_option( const char* name, std::string& value ) const;
+  
+  /**\brief Check the string value of an option
+   *
+   * Check which of a list of possible values a string option contains.
+   *\param name The option name
+   *\param values A NULL-terminated array of C-style strings enumerating
+   *              the possible option values.
+   *\param index  Output: The index into <code>values</code> for the
+   *              option value.
+   *\return CUBIT_SUCCESS if matched name and value.
+   *        CUBIT_ENTITY_NOT_FOUND if the option was not specified
+   *        CUBIT_FAILURE if the option value is not in the input <code>values</code> array.
+   */
+  FOErrorCode match_option( const char* name, const char* const* values, int& index ) const;
+  
+  /**\brief Check if an option matches a string value
+   *
+   * Check if the value for an option is the passed string.
+   *\param name The option name
+   *\param value The expected value.
+   *\return CUBIT_SUCCESS if matched name and value.
+   *        CUBIT_ENTITY_NOT_FOUND if the option was not specified
+   *        CUBIT_FAILURE if the option value doesn't match the passed string/
+   */
+  FOErrorCode match_option( const char* name, const char* value ) const;
+  
+  /**\brief Check for option for which the value is a list of ints
+   *
+   * Check for an option which is an int list.  The value is expected to
+   * be a comma-separated list of int ranges, where an int range can be 
+   * either a single integer value or a range of integer values separated
+   * by a dash ('-').
+   *
+   *\param name The option name
+   *\param values Output. The list of integer values.
+   *\return - CUBIT_SUCCESS if option is found
+   *        - CUBIT_TYPE_OUT_OF_RANGE if options is found, but does not contain an ID list
+   *        - CUBIT_ENTITY_NOT_FOUND if option is not found.
+   */
+  FOErrorCode get_ints_option( const char* name, std::vector<int>& values) const;
+  
+  /** number of options */
+  inline unsigned size() const 
+    { return mOptions.size(); }
+  
+  /** true if no options */
+  inline bool empty() const 
+    { return mOptions.empty(); }
+  
+  /** Get list of options */
+  void get_options( std::vector<std::string>& list ) const;
+  
+private:
+  
+  /**\brief Check for option 
+   *
+   * Check for an option
+   *\param name The option name
+   *\param value The option value, or an empty string if no value.
+   *\return CUBIT_SUCCESS or CUBIT_ENTITY_NOT_FOUND
+   */
+  FOErrorCode get_option( const char* name, const char*& value) const;
+
+  char* mData;
+  std::vector<const char*> mOptions;
+
+    /** Case-insensitive compare of name with option value. */
+  static bool compare( const char* name, const char* option );
+};
+
+#endif
+

Modified: cgm/trunk/geom/parallel/Makefile.am
===================================================================
--- cgm/trunk/geom/parallel/Makefile.am	2009-08-19 18:39:01 UTC (rev 3107)
+++ cgm/trunk/geom/parallel/Makefile.am	2009-08-19 20:05:46 UTC (rev 3108)
@@ -1,17 +1,28 @@
 # Don't require GNU-standard files (Changelog, README, etc.)
 AUTOMAKE_OPTIONS = foreign
 
+
 # Override default defines with the ones we want from the configure script
-# Override default defines with the ones we want from the configure script
-DEFS = $(TEMPLATE_DEFS_INCLUDED) \
-       $(LITTLE_ENDIAN) $(ACIS_STEP_TRANSLATOR) $(ACIS_IGES_TRANSLATOR) \
-       -DCUBIT_ACIS_VERSION=$(ACIS_VERSION) -DACIS_VERSION=$(ACIS_VERSION) \
-       -D$(ACIS_PLATFORM)
+if build_OCC
+#  DEFS = $(TEMPLATE_DEFS_INCLUDED) $(HAVE_OCC_DEF)
+   DEFS += $(HAVE_OCC_DEF)
+else
+   DEFS = $(TEMPLATE_DEFS_INCLUDED) \
+         $(LITTLE_ENDIAN) $(ACIS_STEP_TRANSLATOR) $(ACIS_IGES_TRANSLATOR) \
+         -DCUBIT_ACIS_VERSION=$(ACIS_VERSION) -DACIS_VERSION=$(ACIS_VERSION) \
+         -D$(ACIS_PLATFORM)
+#   DEFS += $(ACIS_STEP_TRANSLATOR) $(ACIS_IGES_TRANSLATOR) \
+         -DCUBIT_ACIS_VERSION=$(ACIS_VERSION) -DACIS_VERSION=$(ACIS_VERSION) \
+         -D$(ACIS_PLATFORM)
+endif
 
+# because "ISO C++ does not support ‘long long"
+CXXFLAGS += -Wno-long-long
+
 INCLUDES = -I$(top_srcdir)/util \
            -I$(top_srcdir)/geom \
            -I$(top_srcdir)/geom/ACIS \
-           -I$(ACIS_DIR)/include \
+	   -I$(ACIS_DIR)/include \
            $(MPI_INCLUDE)
 
 # The name of the library to build
@@ -25,21 +36,17 @@
 
 # The non-template sources
 libcubit_parallel_la_SOURCES = \
-    AcisMemFile.cpp \
-    CABodies.cpp \
-    CGMMemFile.cpp \
-    ParallelGeomTool.cpp \
-    ProcData.cpp \
-    TDParallel.cpp
+    CGMProcConfig.cpp \
+    CGMParallelComm.cpp \
+    FileOptions.cpp \
+    ParallelGeomTool.cpp
 
 # The non-template headers
 # If any of these do not need to be installed, move them
 # to the _SOURCES list above.
 libcubit_parallel_la_include_HEADERS = \
-    AcisMemFile.hpp \
-    CABodies.cpp \
-    CGMMemFile.hpp \
-    ParallelGeomTool.hpp \
-    ProcData.hpp \
-    TDParallel.hpp
+    CGMProcConfig.hpp \
+    CGMParallelComm.hpp \
+    FileOptions.hpp \
+    ParallelGeomTool.hpp
 

Modified: cgm/trunk/geom/parallel/ParallelGeomTool.cpp
===================================================================
--- cgm/trunk/geom/parallel/ParallelGeomTool.cpp	2009-08-19 18:39:01 UTC (rev 3107)
+++ cgm/trunk/geom/parallel/ParallelGeomTool.cpp	2009-08-19 20:05:46 UTC (rev 3108)
@@ -1,51 +1,539 @@
+#include <cstdio>
+
+#include "CubitString.hpp"
+#include "CubitMessage.hpp"
+#include "DLList.hpp"
+#include "RefEntity.hpp"
+#include "CubitEntity.hpp"
+#include "CastTo.hpp"
+#include "CubitUtil.hpp"
+
+#include "TopologyBridge.hpp"
+#include "GeometryQueryTool.hpp"
 #include "ParallelGeomTool.hpp"
-#include "AcisMemFile.hpp"
-#include "AcisQueryEngine.hpp"
-#include "TSTTG_CGM.h"
-#include "ProcData.hpp"
+#include "CGMParallelConventions.h"
+#include "CATag.hpp"
+#include "CGMParallelComm.hpp"
 
-ParallelGeomTool *ParallelGeomTool::instance_ = NULL;
+const bool debug = true;
 
-int ParallelGeomTool::load_parallel(TSTTG_Instance geom,
-                                    const char *name, 
-                                    int par_load_option) 
+enum CGMParallelActions {PA_READ=0, PA_BROADCAST, PA_DELETE_NONLOCAL,
+			 PA_SCATTER,
+			 PA_CHECK_GIDS_SERIAL, PA_GET_ENTS, 
+			 PA_RESOLVE_SHARED_ENTS,
+			 PA_EXCHANGE_GHOSTS};
+
+enum CGMPartitionActions {PT_GEOM_DIM=0, PT_PAR_PART};
+
+const char *CGMParallelActionsNames[] = {
+  "PARALLEL READ",
+  "PARALLEL BROADCAST", 
+  "PARALLEL DELETE NONLOCAL",
+  "PARALLEL SCATTER",
+  "PARALLEL CHECK_GIDS_SERIAL",
+  "PARALLEL GET_FILESET_ENTS",
+  "PARALLEL RESOLVE_SHARED_ENTS",
+  "PARALLEL EXCHANGE_GHOSTS"
+};
+
+const char* ParallelGeomTool::CGMparallelOptsNames[] = { "NONE", "READ", "READ_DELETE", "BCAST", 
+							 "BCAST_DELETE", "SCATTER", "SCATTER_DELETE",
+							 "READ_PARALLEL", "FORMAT", "", 0 };
+
+const char* ParallelGeomTool::CGMpartitionOptsNames[] = { "NONE", "GEOM_DIMENSION",
+							  "PARARELL_PARTITION", "", 0 };
+
+//ParallelGeomTool *ParallelGeomTool::instance_ = NULL;
+
+ParallelGeomTool::ParallelGeomTool(CGMTagManager* impl, CGMParallelComm *pc)
+  : cgmImpl(impl), myPcomm(pc) 
 {
-    // declare an acismemfile object
-  AcisMemFile amf(AcisQueryEngine::instance());
+  if (!myPcomm) {
+    myPcomm = CGMParallelComm::get_pcomm(impl, 0);
+    if (NULL == myPcomm) myPcomm = new CGMParallelComm(cgmImpl);
+  }
+  //gqt = GeometryQueryTool::instfance();
+}
 
-  DLIList<RefEntity*> ref_ents, ref_ents_master;
+CubitStatus ParallelGeomTool::load_file(const char *file_name,
+					const char *options,
+					const char* set_tag_name,
+					const int* set_tag_values,
+					int num_set_tag_values) 
+{
+  FileOptions opts(options);
 
-    // if I'm the master, load the file and get the entities
-  int result;
-  if (ProcData::instance()->is_master()) {
-    result = TSTTG_load(geom, name, NULL, 0);
-    if (TSTTB_SUCCESS != result) return result;
+  // Get parallel settings
+  int parallel_mode;
+  FOErrorCode result = opts.match_option("PARALLEL", CGMparallelOptsNames, 
+					 parallel_mode);
+  if (FO_FAILURE == result) {
+    PRINT_ERROR( "Unexpected value for 'PARALLEL' option\n" );
+    return CUBIT_FAILURE;
+  }
+  else if (FO_ENTITY_NOT_FOUND == result) {
+    parallel_mode = 0;
+  }
 
-      // get all the volumes
-    TSTTG_EntityHandle *ents = NULL;
-    int ents_alloc = 0, ents_size;
-    result = TSTTG_getEntities(geom, 0, TSTTG_REGION, 
-                               &ents, &ents_alloc, &ents_size);
-    if (TSTTB_SUCCESS != result) return result;
+  bool distrib = false;
+  bool surf_partition = false;
+  bool body_partition = false;
+  std::string partition_tag_name;
+  std::vector<int> partition_tag_vals;
 
-      // make this the storage for the ent list
-    ref_ents.copy_from((RefEntity**)ents, ents_size);
+  // Get partition tag value(s), if any, and whether they're to be
+  result = opts.get_ints_option("PARTITION_VAL", partition_tag_vals);
+
+  // Get partition setting
+  result = opts.get_option("PARTITION", partition_tag_name);
+
+  if (FO_ENTITY_NOT_FOUND == result || partition_tag_name.empty()) {
+    partition_tag_name = PARALLEL_PARTITION_TAG_NAME;
+    distrib = true;
   }
+  else {
+    if (partition_tag_name == "GEOM_DIMENSION") {
+      int geom_dim = 0;
+      for (std::vector<int>::iterator pit = partition_tag_vals.begin(); 
+	   pit != partition_tag_vals.end(); pit++) {
+	geom_dim = *pit;
+	if (geom_dim == 2) surf_partition = true; // body & surface distribution
+	else if (geom_dim == 3) body_partition = true; // body only distribution
+      }
+      if (!surf_partition && !body_partition) {
+	PRINT_ERROR("Geometry dimension %d is not supported.\n", geom_dim);
+	return CUBIT_FAILURE;
+      }
+    }
+    else if (partition_tag_name == "PARALLEL_PARTITION") {
+    }
 
-    // now communicate the entities
-  if (BCAST == par_load_option) {
-      // broadcast
-    result = amf.bcast_entity_list(ref_ents);
+    // distributed or assigned
+    result = opts.get_null_option("PARTITION_DISTRIBUTE");
+    if (FO_SUCCESS == result) {
+      distrib = true;
+      body_partition = true;
+    }
   }
-  else if (BCAST_AND_DELETE == par_load_option) {
-      // bcast and delete
-    result = amf.bcast_and_delete_entity_list(ref_ents, ref_ents_master);
+
+  // get MPI IO processor rank
+  int reader_rank;
+  result = opts.get_int_option("MPI_IO_RANK", reader_rank);
+  if (FO_ENTITY_NOT_FOUND == result)
+    reader_rank = 0;
+  else if (FO_SUCCESS != result) {
+    PRINT_ERROR( "Unexpected value for 'MPI_IO_RANK' option\n" );
+    return CUBIT_FAILURE;
   }
-  else if (SCATTER == par_load_option) {
-      // scatter
-    result = amf.scatter_entity_list(ref_ents);
+
+  // now that we've parsed all the parallel options, make an instruction
+  // queue
+  std::vector<int> pa_vec;
+  bool is_reader = (reader_rank == (int) myPcomm->proc_config().proc_rank());
+  
+  switch (parallel_mode) {
+
+  case POPT_READ:
+    pa_vec.push_back(PA_READ);
+    //pa_vec.push_back(PA_CHECK_GIDS_SERIAL);
+    pa_vec.push_back(PA_GET_ENTS);
+    break;
+  
+  case POPT_DEFAULT:
+  case POPT_READ_DELETE:
+    pa_vec.push_back(PA_READ);
+    //pa_vec.push_back(PA_CHECK_GIDS_SERIAL);
+    pa_vec.push_back(PA_GET_ENTS);
+    pa_vec.push_back(PA_DELETE_NONLOCAL);
+    break;
+
+  case POPT_BCAST:
+    if (is_reader) {
+      pa_vec.push_back(PA_READ);
+      //pa_vec.push_back(PA_CHECK_GIDS_SERIAL);
+      pa_vec.push_back(PA_GET_ENTS);
+    }
+    pa_vec.push_back(PA_BROADCAST);
+    if (!is_reader) pa_vec.push_back(PA_GET_ENTS);
+    break;
+    
+  case POPT_BCAST_DELETE:
+    if (is_reader) {
+      pa_vec.push_back(PA_READ);
+      //pa_vec.push_back(PA_CHECK_GIDS_SERIAL);
+      pa_vec.push_back(PA_GET_ENTS);
+    }
+    pa_vec.push_back(PA_BROADCAST);
+    //if (!is_reader) pa_vec.push_back(PA_GET_FILESET_ENTS);
+    pa_vec.push_back(PA_DELETE_NONLOCAL);
+    break;
+    
+  case PORT_SCATTER:
+    if (is_reader) {
+      pa_vec.push_back(PA_READ);
+      //pa_vec.push_back(PA_CHECK_GIDS_SERIAL);
+      pa_vec.push_back(PA_GET_ENTS);
+    }
+    pa_vec.push_back(PA_SCATTER);
+    if (!is_reader) pa_vec.push_back(PA_GET_ENTS);
+    break;
+      
+  case PORT_SCATTER_DELETE:
+    if (is_reader) {
+      pa_vec.push_back(PA_READ);
+      //pa_vec.push_back(PA_CHECK_GIDS_SERIAL);
+      pa_vec.push_back(PA_GET_ENTS);
+    }
+    pa_vec.push_back(PA_SCATTER);
+    if (is_reader) pa_vec.push_back(PA_DELETE_NONLOCAL);
+    else pa_vec.push_back(PA_GET_ENTS);
+    break;
+  
+  case POPT_FORMAT:
+    PRINT_ERROR( "Access to format-specific parallel read not implemented.\n");
+    return CUBIT_FAILURE;
+
+  case POPT_READ_PARALLEL:
+    PRINT_ERROR( "Partitioning for PARALLEL=READ_PARALLEL not supported yet.\n");
+    return CUBIT_FAILURE;
+
+  default:
+    return CUBIT_FAILURE;
   }
+
+  return load_file(file_name, parallel_mode, 
+                   partition_tag_name,
+                   partition_tag_vals, distrib, pa_vec, opts,
+                   set_tag_name, set_tag_values,
+		   num_set_tag_values,
+                   reader_rank, surf_partition, body_partition
+		   );
+}
+
+CubitStatus ParallelGeomTool::load_file(const char *file_name,
+                        		int parallel_mode, 
+                        		std::string &partition_tag_name, 
+					std::vector<int> &partition_tag_vals, 
+					bool distrib,
+					std::vector<int> &pa_vec,
+					const FileOptions &opts,
+					const char* set_tag_name,
+					const int* set_tag_values,
+					const int num_set_tag_values,
+					const int reader_rank,
+					const bool surf_partition,
+					const bool body_partition
+					)
+{
+  // check file type
+  CubitString file_type;
+  //if (strstr(file_name, ".sab")) file_type = "ACIS_SAB";
+  //else if (strstr(file_name, ".sat")) file_type = "ACIS_SAT";
+  if (strstr(file_name, ".stp")) file_type = "STEP";
+  else if (strstr(file_name, ".igs")) file_type = "IGES";
+  else if (strstr(file_name, ".occ") || strstr(file_name, ".brep")) file_type = "OCC";
+  else {
+    PRINT_ERROR("File type not known for file %s; skipping.\n", file_name);
+    return CUBIT_FAILURE;
+  }
   
-  return result;
+  // do the work by options
+  bool i_read = false;
+  std::vector<int>::iterator vit;
+  int i;
+  DLIList<RefEntity*> surf_entity_list, body_entity_list;
+  for (i = 1, vit = pa_vec.begin(); vit != pa_vec.end(); vit++, i++) {
+    CubitStatus tmp_result = CUBIT_SUCCESS;
+    switch (*vit) {
+//==================
+    case PA_READ:
+      i_read = true;
+      double tStart, tEnd;
+
+      if (debug) {
+	std::cout << "Reading file " << file_name << std::endl;
+	tStart = MPI_Wtime();
+      }
+      tmp_result = GeometryQueryTool::instance()->import_solid_model(file_name, file_type.c_str());
+
+      if (CUBIT_SUCCESS != tmp_result) {
+	PRINT_ERROR("Reading file %s failed.\n", file_name);
+	return CUBIT_FAILURE;
+      }
+      else if (debug) {
+	tEnd = MPI_Wtime();
+	PRINT_INFO("Read time in proc %d is %f.\n", myPcomm->proc_config().proc_size(),
+		   tEnd - tStart);
+	PRINT_INFO("Read done.\n");
+      }
+      
+      break;
+
+//==================
+    case PA_GET_ENTS:
+      if (debug) std::cout << "Getting entities." << std::endl;
+      
+      // get entities
+      if (body_partition) {
+	tmp_result = GeometryQueryTool::instance()->ref_entity_list("body", body_entity_list, CUBIT_FALSE);
+	
+	if (CUBIT_SUCCESS != tmp_result) {
+	  PRINT_ERROR("Getting body entities failed.\n");
+	  return CUBIT_FAILURE;
+	}
+      }
+      if (surf_partition) {
+	tmp_result = GeometryQueryTool::instance()->ref_entity_list("surface", surf_entity_list, CUBIT_FALSE);
+	
+	if (CUBIT_SUCCESS != tmp_result) {
+	  PRINT_ERROR("Getting surf entities failed.\n");
+	  return CUBIT_FAILURE;
+	}
+      }
+      if (debug) PRINT_INFO("Getting entities done.\n");
+
+      break;
+      
+//==================     
+    case PA_DELETE_NONLOCAL:
+      if (debug) {
+	PRINT_INFO("Deleting nonlocal entities.\n");
+	tStart = MPI_Wtime();
+      }
+     
+      tmp_result = delete_nonlocal_entities(partition_tag_name, 
+					    partition_tag_vals,
+					    surf_entity_list,
+					    body_entity_list,
+					    distrib);
+     
+      if (CUBIT_SUCCESS != tmp_result) {
+	PRINT_ERROR("Delete failed.\n");
+	return CUBIT_FAILURE;
+      }
+      else if (debug) {
+	tEnd = MPI_Wtime();
+	PRINT_INFO("Delete done.\n");
+	PRINT_INFO("Delete time in proc %d is %f.\n", myPcomm->proc_config().proc_size(),
+		   tEnd - tStart);
+      }
+      break;
+
+//==================      
+    case PA_BROADCAST:
+      // do the actual broadcast; if single-processor, ignore error
+      if (myPcomm->proc_config().proc_size() > 1) {
+	if (body_partition) {
+	  if (debug) {
+	    PRINT_INFO("Broadcasting body entities.\n");
+	    tStart = MPI_Wtime();
+	  }
+
+	  tmp_result = myPcomm->broadcast_entities(reader_rank, body_entity_list);
+	  
+	  if (CUBIT_SUCCESS != tmp_result) {
+	    PRINT_ERROR("Broadcasting body entities failed.\n");
+	    return CUBIT_FAILURE;
+	  }
+	  else if (debug) {
+	    tEnd = MPI_Wtime();
+	    PRINT_INFO("Bcast bodies done.\n");
+	    PRINT_INFO("Broadcast bodies time in proc %d is %f.\n", myPcomm->proc_config().proc_size(),
+		       tEnd - tStart);
+	  }
+	}
+	if (surf_partition) {
+	  if (debug) {
+	    PRINT_INFO("Broadcasting surface entities.\n");
+	    tStart = MPI_Wtime();
+	  }
+	  tmp_result = myPcomm->broadcast_entities(reader_rank, surf_entity_list);
+	  
+	  if (CUBIT_SUCCESS != tmp_result) {
+	    PRINT_ERROR("Broadcasting surface entities failed.\n");
+	    return CUBIT_FAILURE;
+	  }
+	  else if (debug) {
+	    tEnd = MPI_Wtime();
+	    PRINT_INFO("Bcast surface done.\n");
+	    PRINT_INFO("Broadcast surfaces time in proc %d is %f.\n", myPcomm->proc_config().proc_size(),
+		       tEnd - tStart);
+	  }
+	}
+      }
+      
+      break;
+
+//==================      
+    case PA_SCATTER:
+      // do the actual scatter
+      if (myPcomm->proc_config().proc_size() > 1) {
+	if (body_partition) {
+	  if (debug) {
+	    PRINT_INFO("Scattering body entities.\n");
+	    tStart = MPI_Wtime();
+	  }
+	  tmp_result = myPcomm->scatter_entities(reader_rank, body_entity_list);
+	  
+	  if (CUBIT_SUCCESS != tmp_result) {
+	    PRINT_ERROR("Scattering body entities failed.\n");
+	    return CUBIT_FAILURE;
+	  }
+	  else if (debug) {
+	    tEnd = MPI_Wtime();
+	    PRINT_INFO("Scatter bodies done.\n");
+	    PRINT_INFO("Scatter bodies time in proc %d is %f.\n", myPcomm->proc_config().proc_size(),
+		       tEnd - tStart);
+	  }
+	}
+	if (surf_partition) {
+	  if (debug) {
+	    PRINT_INFO("Scattering surface entities.\n");
+	    tStart = MPI_Wtime();
+	  }
+	  tmp_result = myPcomm->scatter_entities(reader_rank, surf_entity_list);
+	  
+	  if (CUBIT_SUCCESS != tmp_result) {
+	    PRINT_ERROR("Scattering surf entities failed.\n");
+	    return CUBIT_FAILURE;
+	  }
+	  else if (debug) {
+	    tEnd = MPI_Wtime();
+	    PRINT_INFO("Scatter surfaces done;\n");
+	    PRINT_INFO("Scatter surfaces time in proc %d is %f.\n", myPcomm->proc_config().proc_size(),
+		       tEnd - tStart);
+	  }
+	}
+      }
+      if (debug) PRINT_INFO("Scatter done.\n");
+      
+      break;
+
+//==================    
+    default:
+      return CUBIT_FAILURE;
+    }
+  }
+
+  return CUBIT_SUCCESS;
 }
 
+CubitStatus ParallelGeomTool::delete_nonlocal_entities(std::string &ptag_name,
+						       std::vector<int> &ptag_vals,
+						       DLIList<RefEntity*> surf_entity_list,
+						       DLIList<RefEntity*> body_entity_list,
+						       const bool distribute)
+{
+  unsigned int i;
+  CubitStatus result;
+  int proc_sz = myPcomm->proc_config().proc_size();
+  int proc_rk = myPcomm->proc_config().proc_rank();
+  
+  if (distribute) { // Round-Robin
+    // for now, require that number of partition sets be greater
+    // than number of procs
+    if (body_entity_list.size() < proc_sz &&
+	surf_entity_list.size() < proc_sz) {
+      result = CUBIT_FAILURE;
+      PRINT_ERROR("Number of procs greater than number of partitions.");
+      return CUBIT_FAILURE;
+    }
+    
+    // delete unneeded surf entities
+    unsigned int tot_entity = surf_entity_list.size();
+    unsigned int n_entity = tot_entity / proc_sz;
+    unsigned int n_entity_leftover = tot_entity % proc_sz;
+    unsigned int begin_entity = 0;
+
+    if (proc_rk < (int) n_entity_leftover) {
+      n_entity++;
+      begin_entity = n_entity * proc_rk;
+    }
+    else
+      begin_entity = proc_rk * n_entity + n_entity_leftover;
+
+    DLIList<RefEntity*> tmp_entity_list, delete_surf_list, delete_body_list;
+    unsigned int end_entity = begin_entity + n_entity;
+    for (i = 0; i < tot_entity; i++) {
+      if (i >= begin_entity && i < end_entity) tmp_entity_list.append(surf_entity_list[i]);
+      else {
+	delete_surf_list.append(surf_entity_list[i]);
+	//GeometryQueryTool::instance()->delete_RefEntity(surf_entity_list[i]);
+      }
+    }
+    
+    // change partition surf ref entity list
+    myPcomm->partition_surf_list().clean_out();
+    myPcomm->partition_surf_list() += tmp_entity_list;
+
+    // delete unneeded body entities
+    tot_entity = body_entity_list.size();
+    n_entity = tot_entity / proc_sz;
+    n_entity_leftover = tot_entity % proc_sz;
+
+    if (proc_rk < (int) n_entity_leftover) {
+      n_entity++;
+      begin_entity = n_entity * proc_rk;
+    }
+    else
+      begin_entity = proc_rk * n_entity + n_entity_leftover;
+
+    end_entity = begin_entity + n_entity;
+    for (i = 0; i < tot_entity; i++) {
+      if (i >= begin_entity && i < end_entity) tmp_entity_list.append(body_entity_list[i]);
+      else {
+	delete_body_list.append(body_entity_list[i]);
+	//GeometryQueryTool::instance()->delete_RefEntity(body_entity_list[i]);
+      }
+    }
+
+    char pre_surf[100], pre_body[100];
+    DLIList<CubitEntity*> tmp_surf_list, tmp_body_list;
+    if (debug) {
+      CAST_LIST_TO_PARENT(delete_surf_list, tmp_surf_list);
+      sprintf( pre_surf, "Deleted %d Surfaces: ", tmp_surf_list.size() );
+      CAST_LIST_TO_PARENT(delete_body_list, tmp_body_list);
+      sprintf( pre_body, "Deleted %d Bodies: ", tmp_body_list.size() );
+      CubitUtil::list_entity_ids( pre_surf, tmp_surf_list );
+    }
+
+    unsigned int nDelete = delete_surf_list.size();
+    for (i = 0; i < nDelete; i++) {
+      GeometryQueryTool::instance()->delete_RefEntity(surf_entity_list[i]);
+    }
+    
+    if (debug) CubitUtil::list_entity_ids( pre_body, tmp_body_list );
+    
+    nDelete = delete_body_list.size();
+    for (i = 0; i < nDelete; i++) {
+      GeometryQueryTool::instance()->delete_RefEntity(body_entity_list[i]);
+    }
+
+    // change partition surf ref entity list
+    myPcomm->partition_body_list().clean_out();
+    myPcomm->partition_body_list() += tmp_entity_list;
+  }
+  else {
+    myPcomm->partition_surf_list().clean_out();
+    myPcomm->partition_surf_list() += surf_entity_list;
+    myPcomm->partition_body_list().clean_out();
+    myPcomm->partition_body_list() += body_entity_list;
+  }
+       
+  if (debug) {
+    /*
+    surf_entity_list.clean_out();
+    GeometryQueryTool::instance()->ref_entity_list("surface", surf_entity_list, CUBIT_FALSE);
+    body_entity_list.clean_out();
+    GeometryQueryTool::instance()->ref_entity_list("body", body_entity_list, CUBIT_FALSE);
+    std::cerr << "My partition surf/body ref entity list size1: "
+    << surf_entity_list.size() << " "
+	      << body_entity_list.size() << std::endl;*/
+
+    std::cerr << "My partition surf/body ref entity list size: "
+	      << myPcomm->partition_surf_list().size() << " "
+	      << myPcomm->partition_body_list().size() << std::endl;
+  }    
+  
+  return CUBIT_SUCCESS;
+}

Modified: cgm/trunk/geom/parallel/ParallelGeomTool.hpp
===================================================================
--- cgm/trunk/geom/parallel/ParallelGeomTool.hpp	2009-08-19 18:39:01 UTC (rev 3107)
+++ cgm/trunk/geom/parallel/ParallelGeomTool.hpp	2009-08-19 20:05:46 UTC (rev 3108)
@@ -1,32 +1,88 @@
 #ifndef PARALLELGEOMTOOL_HPP
 #define PARALLELGEOMTOOL_HPP
 
-#include "TSTTG_CGM.h"
+#include <vector>
+#include "CubitDefines.h"
+#include "CGMParallelComm.hpp"
+//#include "ProcData.hpp"
+#include "FileOptions.hpp"
+//#include "CATag.hpp"
+//#include "CGMParallelComm.hpp"
 
+//class CGMTagManager;
+//class CGMParallelComm;
+
 class ParallelGeomTool 
 {
 public:
-  static ParallelGeomTool *instance();
 
+  ParallelGeomTool(CGMTagManager* impl = NULL, CGMParallelComm *pc = NULL);
+
+  //static ParallelGeomTool *instance();
+
   enum ParallelLoadOption {BCAST, BCAST_AND_DELETE, SCATTER};
   
-    // load geometry to parallel processors, using ParallelLoadOption
-    // to determine how 
-  int load_parallel(TSTTG_Instance geom,
-                    const char *name, 
-                    int par_load_option);
+  // load a file
+  CubitStatus load_file(const char *file_names, const char *options,
+			const char* set_tag_name = 0,
+			const int* set_tag_values = 0,
+			int num_set_tag_values = 0);
   
+  CubitStatus load_file(const char *file_name,
+                        int parallel_mode, 
+                        std::string &partition_tag_name, 
+                        std::vector<int> &partition_tag_vals, 
+                        bool distrib,
+                        std::vector<int> &pa_vec,
+                        const FileOptions &opts,
+                        const char* set_tag_name,
+                        const int* set_tag_values,
+                        const int num_set_tag_values,
+                        const int reader_rank,
+			const bool surf_partition,
+			const bool body_partition);
+  
+  static const char *CGMparallelOptsNames[];
+
+  static const char *CGMpartitionOptsNames[];
+  
+  enum CGMParallelOpts {POPT_NONE=0, POPT_READ, POPT_READ_DELETE, POPT_BCAST,
+			POPT_BCAST_DELETE, PORT_SCATTER,
+			PORT_SCATTER_DELETE, POPT_READ_PARALLEL,
+			POPT_FORMAT, POPT_DEFAULT};
+
 private:
-  ParallelGeomTool() {}
 
-  static ParallelGeomTool *instance_;
+  // surf ref entity list to be partitioned
+  DLIList<RefEntity*> msurf_entity_list;
+
+  // body ref entity list to be partitioned
+  DLIList<RefEntity*> mbody_entity_list;
+
+  CubitStatus delete_nonlocal_entities(std::string &ptag_name,
+                                       std::vector<int> &ptag_vals,
+				       DLIList<RefEntity*> surf_entity_list,
+				       DLIList<RefEntity*> body_entity_list,
+				       bool distribute);
+  
+  //CubitStatus delete_nonlocal_entities(MBEntityHandle file_set);
+
+
+  //static ParallelGeomTool *instance_;
+
+  CGMTagManager *cgmImpl;
+
+  // each reader can keep track of its own pcomm
+  CGMParallelComm *myPcomm;
+
+  //GeometryQueryTool *gqt;
 };
 
-  
+/*
 inline ParallelGeomTool *ParallelGeomTool::instance()
 {
   if (!instance_) instance_ = new ParallelGeomTool();
   return instance_;
-}
+  }*/
 
 #endif

Modified: cgm/trunk/geom/virtual/VirtualQueryEngine.cpp
===================================================================
--- cgm/trunk/geom/virtual/VirtualQueryEngine.cpp	2009-08-19 18:39:01 UTC (rev 3107)
+++ cgm/trunk/geom/virtual/VirtualQueryEngine.cpp	2009-08-19 20:05:46 UTC (rev 3108)
@@ -1526,6 +1526,14 @@
   return CUBIT_FAILURE;
 }
 
+CubitStatus VirtualQueryEngine::export_solid_model( DLIList<TopologyBridge*>& bridge_list,
+						    char*& p_Buffer,
+						    int& n_buffer_size,
+						    bool b_export_buffer)
+{
+  return CUBIT_FAILURE;
+}
+
 CubitStatus VirtualQueryEngine::save_temp_geom_file( DLIList<TopologyBridge*>& ,
                                         const char* ,
                                         const CubitString &,
@@ -1560,6 +1568,16 @@
   return CUBIT_FAILURE;
 }
 
+CubitStatus VirtualQueryEngine::import_solid_model(DLIList<TopologyBridge*> &imported_entities,
+						   const char* pBuffer,
+						   const int n_buffer_size)
+{
+  PRINT_INFO("VirtualQueryEngine::import_solid_model\n");
+  
+  default_error_message( "import_solid_model()");
+  return CUBIT_FAILURE;
+}
+
 void VirtualQueryEngine::delete_solid_model_entities(DLIList<BodySM*>& list) const
 {
   for ( int i = list.size(); i--; )

Modified: cgm/trunk/geom/virtual/VirtualQueryEngine.hpp
===================================================================
--- cgm/trunk/geom/virtual/VirtualQueryEngine.hpp	2009-08-19 18:39:01 UTC (rev 3107)
+++ cgm/trunk/geom/virtual/VirtualQueryEngine.hpp	2009-08-19 20:05:46 UTC (rev 3108)
@@ -357,6 +357,11 @@
                                           const CubitString &cubit_version,
                                           const char* logfile_name = NULL );
 
+  virtual CubitStatus export_solid_model( DLIList<TopologyBridge*>& bridge_list,
+					  char*& p_buffer,
+					  int& n_buffer_size,
+					  bool b_export_buffer);
+  
   virtual CubitStatus save_temp_geom_file(DLIList<TopologyBridge*>& bridge_list,
                                           const char *file_name,
                                           const CubitString &cubit_version,
@@ -381,6 +386,10 @@
                              CubitBoolean import_vertices = CUBIT_TRUE,
                              CubitBoolean free_surfaces = CUBIT_TRUE );
 
+  virtual CubitStatus import_solid_model(DLIList<TopologyBridge*> &imported_entities,
+					 const char* pBuffer,
+					 const int n_buffer_size);
+
   virtual void delete_solid_model_entities(DLIList<BodySM*>&) const;
   virtual CubitStatus delete_solid_model_entities( BodySM* body_ptr ) const;
   virtual CubitStatus delete_solid_model_entities(Surface* surf_ptr ) const;

Modified: cgm/trunk/itaps/CATag.hpp
===================================================================
--- cgm/trunk/itaps/CATag.hpp	2009-08-19 18:39:01 UTC (rev 3107)
+++ cgm/trunk/itaps/CATag.hpp	2009-08-19 20:05:46 UTC (rev 3108)
@@ -42,6 +42,7 @@
 class RefEntity;
 class RefGroup;
 class CATag;
+class CGMParallelComm;
 
 class CGMTagManager 
 {
@@ -116,6 +117,8 @@
     return static_instance;
   }
 
+  inline std::vector<CGMParallelComm*>& get_pc_array() { return pc_array; }
+
 private:
   CGMTagManager();
 
@@ -129,6 +132,9 @@
   static const char *CATag_NAME_INTERNAL;
   RefGroup *interfaceGroup;
 
+  // list of parallel comm
+  std::vector<CGMParallelComm*> pc_array;
+
   bool getPresetTagData(const RefEntity *entity, const long tag_num, 
                         char *tag_value, int &tag_size);
 

Modified: cgm/trunk/itaps/Makefile.am
===================================================================
--- cgm/trunk/itaps/Makefile.am	2009-08-19 18:39:01 UTC (rev 3107)
+++ cgm/trunk/itaps/Makefile.am	2009-08-19 20:05:46 UTC (rev 3108)
@@ -3,6 +3,10 @@
 
 DEFS = $(TEMPLATE_DEFS_INCLUDED) $(HAVE_ACIS_DEF) $(HAVE_OCC_DEF)
 
+# because "ISO C++ does not support ‘long long"
+CXXFLAGS += -Wno-long-long
+#CXXFLAGS = -Wall -pipe -pedantic -g -DDEBUG -Wno-long-long -DUSE_MPI
+
 if USE_BABEL
   SIDL_DIR = SIDL
 else
@@ -20,6 +24,9 @@
 if build_OCC
   TESTS += testgeom_occ
 endif
+if build_parallel
+  TESTS += partest testgeomParallel
+endif
 
 
 SUBDIRS = . $(SIDL_DIR)
@@ -67,6 +74,19 @@
 chaman_CPPFLAGS = $(CPPFLAGS) -DSRCDIR=$(srcdir)
 chaman_LDFLAGS = $(CGM_EXT_LTFLAGS) $(CGM_EXT_LDFLAGS)
 
+if build_parallel
+  partest_SOURCES = partest.cpp
+  partest_LDADD = $(testgeom_LDADD)
+  partest_CPPFLAGS = $(testgeom_CPPFLAGS) -DFORCE_OCC
+  partest_LDFLAGS = $(testgeom_LDFLAGS)
+  testgeomParallel_SOURCES = testgeomParallel.cpp
+  testgeomParallel_LDADD = $(testgeom_LDADD)
+  testgeomParallel_CPPFLAGS = $(testgeom_CPPFLAGS) -DFORCE_OCC
+  testgeomParallel_LDFLAGS = $(testgeom_LDFLAGS)
+  INCLUDES += -I$(top_srcdir)/geom/parallel
+endif
+
+
 # Automake doesn't seem to have a directory defined for
 # platform-dependent data (or include) files. So put 
 # in $(libdir).  Define a $(cfgdir) to get around automake's

Modified: cgm/trunk/itaps/iGeom_CGMA.cc
===================================================================
--- cgm/trunk/itaps/iGeom_CGMA.cc	2009-08-19 18:39:01 UTC (rev 3107)
+++ cgm/trunk/itaps/iGeom_CGMA.cc	2009-08-19 20:05:46 UTC (rev 3108)
@@ -314,32 +314,19 @@
   std::string file_name( name, name_len );
   name = file_name.c_str();
   
-    // process options
+  // check if work in parallel
   bool parallel = false;
-  int par_load_option = -1;
-  std::vector<std::string> opts;
-  tokenize( std::string(options, options_size), opts );
-  for (size_t i = 0; i < opts.size(); ++i) {
-    if (opts[i] == "PARALLEL" 
-     || opts[i] == "parallel")
-      parallel = true;
-    
-    if (opts[i] == "GEOM_BCAST" 
-     || opts[i] == "geom_bcast");
-      par_load_option = 0;
-    
-    if (opts[i] == "GEOM_BCAST_AND_DELETE" 
-     || opts[i] == "geom_bcast_and_delete")
-      par_load_option = 1;
-    
-    if (opts[i] == "GEOM_SCATTER" 
-     || opts[i] == "geom_scatter")
-      par_load_option = 2;
-  }
+  FileOptions opts(options);
+  std::string parallel_opt;
+  FOErrorCode rval = opts.get_option("PARALLEL", parallel_opt);
+  if (FO_SUCCESS == rval) parallel = true;
 
+  // parallel
   if (parallel) {
 #ifdef USE_MPI
-    CubitStatus status = ParallelGeomTool::instance()->load_parallel(name, par_load_option);
+    //CubitStatus status = ParallelGeomTool::instance()->load_file(name, options);
+    ParallelGeomTool pgt(reinterpret_cast<CGMTagManager*> (instance), NULL);
+    CubitStatus status = pgt.load_file(name, options);
     if (CUBIT_SUCCESS != status) {
       ERROR(iBase_FAILURE, "Trouble loading geometry file in parallel.");
     }
@@ -347,27 +334,28 @@
     ERROR(iBase_NOT_SUPPORTED, "Parallel not enabled in this version.");
 #endif    
   }
-  
-  iBase_ErrorType result;
-  CubitStatus status = CUBIT_SUCCESS;
-
-  if (strstr(name, ".cub") != NULL) {
-    iGeom_load_cub_geometry(name, err);
-    if (iBase_SUCCESS != *err) {
-      return;
-    }
-  }
   else {
-    if (strstr(name, ".brep") != NULL || strstr(name, ".occ") != NULL)
-      status = gqt->read_geometry_file(name, NULL, "OCC");
-    else
-      status = gqt->read_geometry_file(name);
-    if (CUBIT_SUCCESS != status) {
-      ERROR(iBase_FILE_NOT_FOUND, "Trouble loading geometry file.");
+    CubitStatus status = CUBIT_SUCCESS;
+    
+    if (strstr(name, ".cub") != NULL) {
+      iGeom_load_cub_geometry(name, err);
+      if (iBase_SUCCESS != *err) {
+	return;
+      }
     }
+    else {
+      if (strstr(name, ".brep") != NULL || strstr(name, ".occ") != NULL)
+	status = gqt->read_geometry_file(name, NULL, "OCC");
+      else
+	status = gqt->read_geometry_file(name);
+      if (CUBIT_SUCCESS != status) {
+	ERROR(iBase_FILE_NOT_FOUND, "Trouble loading geometry file.");
+      }
+    }
   }
-  
+
     // now process uncaught/unregistered attributes
+  iBase_ErrorType result;
   result = process_attribs(instance);
 
   RETURN(result);
@@ -5882,7 +5870,8 @@
   if (NULL == cubfile) RETURN(iBase_FILE_NOT_FOUND);
 
     // first get the length
-  int result = fseek(cubfile, 0, SEEK_END);
+  //int result = fseek(cubfile, 0, SEEK_END);
+  int result = fseek(cubfile, 0, 2);
   if (result) {
     ERROR(iBase_FAILURE, "Couldn't seek to end of .cub file.");
   }
@@ -5896,7 +5885,8 @@
   }
   
     // get the model header
-  result = fseek(cubfile, 4, SEEK_SET);
+  //result = fseek(cubfile, 4, SEEK_SET);
+  result = fseek(cubfile, 4, 0);
   if (result) {
     ERROR(iBase_FAILURE, "Seek failed reading cub file header.");
   }
@@ -5916,7 +5906,8 @@
     ERROR(iBase_FAILURE, "Reading model table will go past end of file.");
   }
     
-  result = fseek(cubfile, model_table_offset, SEEK_SET);
+  //result = fseek(cubfile, model_table_offset, SEEK_SET);
+  result = fseek(cubfile, model_table_offset, 0);
   if (result) {
     ERROR(iBase_FAILURE, "Seek failed seeking to model table.");
   }

Added: cgm/trunk/itaps/partest.cpp
===================================================================
--- cgm/trunk/itaps/partest.cpp	                        (rev 0)
+++ cgm/trunk/itaps/partest.cpp	2009-08-19 20:05:46 UTC (rev 3108)
@@ -0,0 +1,88 @@
+// Test parallel iGeom
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+
+#  ifdef SEEK_SET
+#    define PTEST_SEEK_SET SEEK_SET
+#    define PTEST_SEEK_CUR SEEK_CUR
+#    define PTEST_SEEK_END SEEK_END
+#    undef SEEK_SET
+#    undef SEEK_CUR
+#    undef SEEK_END
+#  endif
+#include "mpi.h"
+#  ifdef PTEST_SEEK_SET
+#    define SEEK_SET PTEST_SEEK_SET
+#    define SEEK_CUR PTEST_SEEK_CUR
+#    define SEEK_END PTEST_SEEK_END
+#    undef PTEST_SEEK_SET
+#    undef PTEST_SEEK_CUR
+#    undef PTEST_SEEK_END
+#  endif
+
+#include "iGeom.h"
+
+#define IGEOM_ASSERT(ierr) if (ierr!=0) printf("igeom assert\n");
+#define IGEOM_NULL 0
+
+int main(int argc, char* argv[]){
+  int rank, size;
+  MPI_Init(&argc, &argv);
+  MPI_Comm_rank( MPI_COMM_WORLD, &rank );
+  MPI_Comm_size( MPI_COMM_WORLD, &size );
+  printf("Hello\n");
+
+  iGeom_Instance igeom;
+  int ierr;
+  igeom = IGEOM_NULL;
+  iGeom_newGeom("PARALLEL", &igeom, &ierr, 8);
+  IGEOM_ASSERT(ierr);
+ 
+  // check command line arg
+  const char* filename = 0;
+  int nMethod = 1;
+  std::string options;
+  
+  if (argc == 3) {
+    filename = argv[1];
+    nMethod = atoi(argv[2]);
+  }
+  else {
+    if (rank == 0) printf("Usage: %s [<filename>] [<send_methond>]\n", argv[0]);
+    if (argc != 1 || argc != 2) return 1;
+    if (rank == 0) {
+      printf("  No file specified.  Defaulting to: %s\n", "Moto.brep");
+      printf("  No send method specified.  Defaulting to: read_delete\n");
+    }
+    filename = "../../../test_files/Moto.brep";
+  }
+  
+  // set geometry send method
+  if (nMethod == 0) options += "PARALLEL=READ;";
+  else if (nMethod == 1) options += "PARALLEL=READ_DELETE;";
+  else if (nMethod == 2) options += "PARALLEL=BCAST;";
+  else if (nMethod == 3) options += "PARALLEL=BCAST_DELETE;";
+  else if (nMethod == 4) options += "PARALLEL=SCATTER;";
+  else if (nMethod == 5) options += "PARALLEL=SCATTER_DELETE;";
+  else if (nMethod == 6) options += "PARALLEL=READ_PARALLEL;";
+  else {
+    printf("Send method %d is not supported. Defaulting to: read_delete\n", nMethod);
+    options = "READ_DELETE;";
+  }
+
+  // do body partitioning with round robin distribution
+  options += "PARTITION=GEOM_DIMENSION;PARTITION_VAL=3;PARTITION_DISTRIBUTE;";
+
+  double tStart = MPI_Wtime();
+  iGeom_load(igeom, filename, options.c_str(), &ierr, strlen(filename), options.length());
+	    
+  MPI_Barrier(MPI_COMM_WORLD); 
+  double tEnd = MPI_Wtime();
+
+  IGEOM_ASSERT(ierr);
+  
+  printf("Done. Geometry load time is %f\n", tEnd - tStart);
+  MPI_Finalize();
+}



More information about the cgma-dev mailing list