[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