MOAB: Mesh Oriented datABase  (version 5.3.0)
iMeshP_MOAB.cpp
Go to the documentation of this file.
00001 #include "moab/MOABConfig.h"
00002 #include "iMeshP_extensions.h"
00003 #include "iMesh_MOAB.hpp"
00004 #include "moab/Core.hpp"
00005 #include "moab/Range.hpp"
00006 #include "moab/CN.hpp"
00007 #include "moab/MeshTopoUtil.hpp"
00008 #include "moab/FileOptions.hpp"
00009 #include "moab/ParallelComm.hpp"
00010 #include "MBParallelConventions.h"
00011 #include "MBIter.hpp"
00012 
00013 #define IS_BUILDING_MB
00014 #include "Internals.hpp"
00015 #undef IS_BUILDING_MB
00016 
00017 #include <cassert>
00018 #include <sstream>
00019 
00020 #ifdef MOAB_HAVE_MPI
00021 #include "moab_mpi.h"
00022 #endif
00023 
00024 using namespace moab;
00025 
00026 /********************* Error Handling **************************/
00027 
00028 #define FIXME printf( "Warning: function has incomplete implementation: %s\n", __func__ )
00029 
00030 /******** Type-safe casting between MOAB and ITAPS types *********/
00031 
00032 #ifndef MOAB_TEMPLATE_FUNC_SPECIALIZATION
00033 // if no template specialization, disable some type checking
00034 template < typename T, typename S >
00035 inline T itaps_cast( S handle )
00036 {
00037     assert( sizeof( S ) >= sizeof( T ) );
00038     return reinterpret_cast< T >( handle );
00039 }
00040 #else
00041 
00042 // basic template method : only works to cast to equivalent types (no-op)
00043 template < typename T, typename S >
00044 inline T itaps_cast( S h )
00045 {
00046     return h;
00047 }
00048 // verify size and do reinterpret cast
00049 template < typename T >
00050 inline T itaps_cast_internal_( EntityHandle h )
00051 {
00052     assert( sizeof( T ) >= sizeof( EntityHandle ) );
00053     return reinterpret_cast< T >( h );
00054 }
00055 // verify size and do reinterpret cast
00056 template < typename T >
00057 inline EntityHandle* itaps_cast_ptr_( T* h )
00058 {
00059     assert( sizeof( T ) == sizeof( EntityHandle ) );
00060     return reinterpret_cast< EntityHandle* >( h );
00061 }
00062 // verify size and do reinterpret cast
00063 template < typename T >
00064 inline const EntityHandle* itaps_cast_const_ptr_( const T* h )
00065 {
00066     assert( sizeof( T ) == sizeof( EntityHandle ) );
00067     return reinterpret_cast< const EntityHandle* >( h );
00068 }
00069 // verify set-type handle before cast
00070 template < typename T >
00071 inline T itaps_set_cast_( EntityHandle h )
00072 {
00073     assert( TYPE_FROM_HANDLE( h ) == MBENTITYSET );
00074     return itaps_cast_internal_< T >( h );
00075 }
00076 
00077 // define conversion routines between itaps handle and EntityHandle types
00078 #define DECLARE_ALLOWED_ITAPS_CONVERSION( ITAPS_HANDLE_TYPE )                                       \
00079     template <>                                                                                     \
00080     inline ITAPS_HANDLE_TYPE itaps_cast< ITAPS_HANDLE_TYPE, EntityHandle >( EntityHandle h )        \
00081     {                                                                                               \
00082         return itaps_cast_internal_< ITAPS_HANDLE_TYPE >( h );                                      \
00083     }                                                                                               \
00084                                                                                                     \
00085     template <>                                                                                     \
00086     inline EntityHandle itaps_cast< EntityHandle, ITAPS_HANDLE_TYPE >( ITAPS_HANDLE_TYPE handle )   \
00087     {                                                                                               \
00088         return reinterpret_cast< EntityHandle >( handle );                                          \
00089     }                                                                                               \
00090                                                                                                     \
00091     template <>                                                                                     \
00092     inline EntityHandle* itaps_cast< EntityHandle*, ITAPS_HANDLE_TYPE* >( ITAPS_HANDLE_TYPE * ptr ) \
00093     {                                                                                               \
00094         return itaps_cast_ptr_( ptr );                                                              \
00095     }                                                                                               \
00096                                                                                                     \
00097     template <>                                                                                     \
00098     inline const EntityHandle* itaps_cast< const EntityHandle*, const ITAPS_HANDLE_TYPE* >(         \
00099         const ITAPS_HANDLE_TYPE* ptr )                                                              \
00100     {                                                                                               \
00101         return itaps_cast_const_ptr_( ptr );                                                        \
00102     }
00103 
00104 // define conversion routines between itaps handle and EntityHandle types
00105 // but limit to EntityHandle for MBENTITYSET type.
00106 #define DECLARE_ALLOWED_ITAPS_SET_CONVERSION( ITAPS_HANDLE_TYPE )                                   \
00107     template <>                                                                                     \
00108     inline ITAPS_HANDLE_TYPE itaps_cast< ITAPS_HANDLE_TYPE, EntityHandle >( EntityHandle h )        \
00109     {                                                                                               \
00110         return itaps_set_cast_< ITAPS_HANDLE_TYPE >( h );                                           \
00111     }                                                                                               \
00112                                                                                                     \
00113     template <>                                                                                     \
00114     inline EntityHandle itaps_cast< EntityHandle, ITAPS_HANDLE_TYPE >( ITAPS_HANDLE_TYPE handle )   \
00115     {                                                                                               \
00116         return reinterpret_cast< EntityHandle >( handle );                                          \
00117     }                                                                                               \
00118                                                                                                     \
00119     template <>                                                                                     \
00120     inline EntityHandle* itaps_cast< EntityHandle*, ITAPS_HANDLE_TYPE* >( ITAPS_HANDLE_TYPE * ptr ) \
00121     {                                                                                               \
00122         return itaps_cast_ptr_( ptr );                                                              \
00123     }                                                                                               \
00124                                                                                                     \
00125     template <>                                                                                     \
00126     inline const EntityHandle* itaps_cast< const EntityHandle*, const ITAPS_HANDLE_TYPE* >(         \
00127         const ITAPS_HANDLE_TYPE* ptr )                                                              \
00128     {                                                                                               \
00129         return itaps_cast_const_ptr_( ptr );                                                        \
00130     }
00131 
00132 DECLARE_ALLOWED_ITAPS_SET_CONVERSION( iMeshP_PartitionHandle )
00133 // DECLARE_ALLOWED_ITAPS_SET_CONVERSION( iMeshP_PartHandle )
00134 DECLARE_ALLOWED_ITAPS_SET_CONVERSION( iBase_EntitySetHandle )
00135 DECLARE_ALLOWED_ITAPS_CONVERSION( iBase_EntityHandle )
00136 
00137 template <>
00138 inline Tag itaps_cast< Tag, iBase_TagHandle >( iBase_TagHandle h )
00139 {
00140     return reinterpret_cast< Tag >( h );
00141 }
00142 template <>
00143 inline iBase_TagHandle itaps_cast< iBase_TagHandle, Tag >( Tag h )
00144 {
00145     return reinterpret_cast< iBase_TagHandle >( h );
00146 }
00147 
00148 #endif
00149 
00150 #define PCOMM ParallelComm::get_pcomm( MOABI, itaps_cast< EntityHandle >( partition_handle ) )
00151 
00152 /*** static function implemented in iMesh_MOAB.cpp ***/
00153 
00154 // Need a different function name for Tag because (currently)
00155 // both Tag and iBase_EntityHandle are void**.
00156 iBase_TagHandle itaps_tag_cast( Tag t )
00157 {
00158     assert( sizeof( iBase_TagHandle ) >= sizeof( Tag ) );
00159     return reinterpret_cast< iBase_TagHandle >( t );
00160 }
00161 
00162 /********************* ITAPS arrays **************************/
00163 
00164 // Handle returning Range in ITAPS array (do ALLOCATE_ARRAY and copy).
00165 #define RANGE_TO_ITAPS_ARRAY( RANGE, NAME )                                                        \
00166     do                                                                                             \
00167     {                                                                                              \
00168         ALLOC_CHECK_ARRAY_NOFAIL( NAME, ( RANGE ).size() );                                        \
00169         std::copy( ( RANGE ).begin(), ( RANGE ).end(), itaps_cast< EntityHandle* >( *( NAME ) ) ); \
00170     } while( false )
00171 
00172 static inline ErrorCode get_entities( Interface* iface, EntityHandle set, int type, int topology, Range& entities )
00173 {
00174     if( topology != iMesh_ALL_TOPOLOGIES )
00175         return iface->get_entities_by_type( set, mb_topology_table[topology], entities );
00176     else if( type != iBase_ALL_TYPES )
00177         return iface->get_entities_by_dimension( set, type, entities );
00178     else
00179         return iface->get_entities_by_handle( set, entities );
00180 }
00181 
00182 /*
00183 static inline ErrorCode remove_not_owned( ParallelComm* pcomm, Range& ents )
00184 {
00185   ErrorCode rval;
00186 
00187   std::vector<unsigned char> pstatus(ents.size());
00188   rval = pcomm->get_moab()->tag_get_data(pcomm->pstatus_tag(), ents, &pstatus[0]);
00189   if (MB_SUCCESS != rval)
00190     return rval;
00191 
00192   Range::iterator i = ents.begin();
00193   std::vector<unsigned char>::const_iterator j;
00194   for (j = pstatus.begin(); j != pstatus.end(); ++j) {
00195     if (*j & PSTATUS_NOT_OWNED)
00196       i = ents.erase( i );
00197     else
00198       ++i;
00199   }
00200 
00201   return MB_SUCCESS;
00202 }
00203 */
00204 
00205 static inline ErrorCode count_owned( ParallelComm* pcomm, const Range& ents, int& n )
00206 {
00207     ErrorCode rval;
00208     n = 0;
00209 
00210     std::vector< unsigned char > pstatus( ents.size() );
00211     rval = pcomm->get_moab()->tag_get_data( pcomm->pstatus_tag(), ents, &pstatus[0] );
00212     if( MB_SUCCESS != rval ) return rval;
00213 
00214     std::vector< unsigned char >::const_iterator j;
00215     for( j = pstatus.begin(); j != pstatus.end(); ++j )
00216         if( !( *j & PSTATUS_NOT_OWNED ) ) ++n;
00217 
00218     return MB_SUCCESS;
00219 }
00220 
00221 static void set_intersection_query( iMesh_Instance instance, iMeshP_PartHandle set1, iBase_EntitySetHandle set2,
00222                                     int type, int topo, Range& result, int* err )
00223 {
00224     ErrorCode rval;
00225 
00226     if( !set1 )
00227     {
00228         rval = get_entities( MOABI, itaps_cast< EntityHandle >( set2 ), type, topo, result );CHKERR( rval, "Invalid Part handle" );
00229     }
00230     else if( !set2 )
00231     {
00232         rval = get_entities( MOABI, itaps_cast< EntityHandle >( set1 ), type, topo, result );CHKERR( rval, "Invalid set handle" );
00233     }
00234     else
00235     {
00236         Range r1, r2;
00237         rval = get_entities( MOABI, itaps_cast< EntityHandle >( set1 ), type, topo, r1 );CHKERR( rval, "Invalid Part handle" );
00238         rval = get_entities( MOABI, itaps_cast< EntityHandle >( set2 ), type, topo, r2 );CHKERR( rval, "Invalid set handle" );
00239         result.merge( intersect( r1, r2 ) );
00240     }
00241 
00242     RETURN( iBase_SUCCESS );
00243 }
00244 
00245 /********************* Iterators **************************/
00246 
00247 static ErrorCode get_boundary_entities( ParallelComm* pcomm, EntityHandle part_handle, int entity_type,
00248                                         int entity_topology, int adj_part_id, Range& entities_out )
00249 {
00250     int* adj_part_id_ptr = ( adj_part_id == iMeshP_ALL_PARTS ) ? 0 : &adj_part_id;
00251 
00252     Range iface_sets;
00253     ErrorCode rval = pcomm->get_interface_sets( part_handle, iface_sets, adj_part_id_ptr );
00254     if( MB_SUCCESS != rval ) return rval;
00255 
00256     for( Range::iterator i = iface_sets.begin(); i != iface_sets.end(); ++i )
00257     {
00258         rval = get_entities( pcomm->get_moab(), *i, entity_type, entity_topology, entities_out );
00259         if( MB_SUCCESS != rval ) return rval;
00260     }
00261 
00262     return MB_SUCCESS;
00263 }
00264 
00265 class PartBoundaryIter : public MBRangeIter
00266 {
00267   private:
00268     ParallelComm* pComm;
00269     int adjPart;
00270 
00271   public:
00272     inline PartBoundaryIter( ParallelComm* pcomm, EntityHandle part_handle, iBase_EntityType entity_type,
00273                              iMesh_EntityTopology entity_topology, int adj_part_id, int array_sz )
00274         : MBRangeIter( entity_type, entity_topology, part_handle, array_sz ), pComm( pcomm ), adjPart( adj_part_id )
00275     {
00276     }
00277 
00278     virtual ErrorCode reset( Interface* )
00279     {
00280         iterData.clear();
00281         ErrorCode result = get_boundary_entities( pComm, entSet, entType, entTopo, adjPart, iterData );
00282         iterPos          = iterData.begin();
00283         return result;
00284     }
00285 };
00286 
00287 template < class Container >
00288 class SetIntersectIter : public MBIter< Container >
00289 {
00290   private:
00291     EntityHandle otherSet;
00292 
00293   public:
00294     SetIntersectIter( iBase_EntityType type, iMesh_EntityTopology topology, EntityHandle set, EntityHandle other_set,
00295                       int array_sz )
00296         : MBIter< Container >( type, topology, set, array_sz ), otherSet( other_set )
00297     {
00298     }
00299     virtual ~SetIntersectIter() {}
00300 
00301     inline ErrorCode intersect_with_set( Interface* mb, Range& range )
00302     {
00303         Range tmp;
00304         ErrorCode result;
00305         result = mb->get_entities_by_handle( otherSet, tmp );
00306         range  = intersect( range, tmp );
00307         return result;
00308     }
00309 
00310     inline ErrorCode intersect_with_set( Interface* mb, std::vector< EntityHandle >& list )
00311     {
00312         size_t w = 0;
00313         for( size_t r = 0; r < list.size(); ++r )
00314         {
00315             if( mb->contains_entities( otherSet, &list[r], 1 ) ) list[w++] = list[r];
00316         }
00317         list.resize( w );
00318         return MB_SUCCESS;
00319     }
00320 
00321     virtual ErrorCode reset( Interface* mb )
00322     {
00323         ErrorCode result = MBIter< Container >::reset( mb );
00324         if( MB_SUCCESS != result ) return result;
00325 
00326         result                       = intersect_with_set( mb, MBIter< Container >::iterData );
00327         MBIter< Container >::iterPos = MBIter< Container >::iterData.begin();
00328         return result;
00329     }
00330 };
00331 
00332 /********************* iMeshP API **************************/
00333 
00334 #ifdef __cplusplus
00335 extern "C" {
00336 #endif
00337 
00338 void iMeshP_createPartitionAll( iMesh_Instance instance,
00339                                 /*in*/ MPI_Comm communicator,
00340                                 /*out*/ iMeshP_PartitionHandle* partition_handle, int* err )
00341 {
00342     *partition_handle = 0;
00343 
00344     Tag prtn_tag;
00345     ErrorCode rval = MOABI->tag_get_handle( PARALLEL_PARTITIONING_TAG_NAME, 1, MB_TYPE_INTEGER, prtn_tag,
00346                                             MB_TAG_SPARSE | MB_TAG_CREAT );CHKERR( rval, "tag creation failed" );
00347 
00348     EntityHandle handle;
00349     rval = MOABI->create_meshset( MESHSET_SET, handle );CHKERR( rval, "set creation failed" );
00350     ParallelComm* pcomm = ParallelComm::get_pcomm( MOABI, handle, &communicator );
00351     if( !pcomm )
00352     {
00353         MOABI->delete_entities( &handle, 1 );
00354         RETURN( iBase_FAILURE );
00355     }
00356 
00357     // set the value of pcomm id, to the partitioning tag, although this is not used
00358     // we just need the tag to be set
00359     int pid = pcomm->get_id();
00360     rval    = MOABI->tag_set_data( prtn_tag, &handle, 1, &pid );CHKERR( rval, "tag creation failed" );
00361 
00362     *partition_handle = itaps_cast< iMeshP_PartitionHandle >( handle );
00363     RETURN( iBase_SUCCESS );
00364 }
00365 
00366 void iMeshP_destroyPartitionAll( iMesh_Instance instance, iMeshP_PartitionHandle partition_handle, int* err )
00367 {
00368     ParallelComm* pcomm = PCOMM;
00369     if( pcomm ) delete pcomm;
00370     EntityHandle handle = itaps_cast< EntityHandle >( partition_handle );
00371     ErrorCode rval      = MOABI->delete_entities( &handle, 1 );CHKERR( rval, "entity deletion failed" );
00372     RETURN( iBase_SUCCESS );
00373 }
00374 
00375 void iMeshP_getPartIdFromPartHandle( iMesh_Instance instance, const iMeshP_PartitionHandle partition_handle,
00376                                      const iMeshP_PartHandle part_handle, iMeshP_Part* part_id, int* err )
00377 {
00378     int junk1 = 1, junk2;
00379     iMeshP_getPartIdsFromPartHandlesArr( instance, partition_handle, &part_handle, 1, &part_id, &junk1, &junk2, err );
00380 }
00381 
00382 void iMeshP_getPartHandleFromPartId( iMesh_Instance instance, const iMeshP_PartitionHandle partition_handle,
00383                                      iMeshP_Part part_id, iMeshP_PartHandle* part_handle, int* err )
00384 {
00385     int junk1 = 1, junk2;
00386     iMeshP_getPartHandlesFromPartsIdsArr( instance, partition_handle, &part_id, 1, &part_handle, &junk1, &junk2, err );
00387 }
00388 
00389 void iMeshP_getPartIdsFromPartHandlesArr( iMesh_Instance instance, const iMeshP_PartitionHandle partition_handle,
00390                                           const iMeshP_PartHandle* part_handles, const int part_handles_size,
00391                                           iMeshP_Part** part_ids, int* part_ids_allocated, int* part_ids_size,
00392                                           int* err )
00393 {
00394     ErrorCode rval;
00395     ParallelComm* pcomm = PCOMM;
00396     ALLOC_CHECK_ARRAY( part_ids, part_handles_size );
00397     for( int i = 0; i < part_handles_size; ++i )
00398     {
00399         int id;
00400         rval             = pcomm->get_part_id( itaps_cast< EntityHandle >( part_handles[i] ), id );
00401         ( *part_ids )[i] = id;CHKERR( rval, "error getting part id" );
00402     }
00403     KEEP_ARRAY( part_ids );
00404     RETURN( iBase_SUCCESS );
00405 }
00406 
00407 void iMeshP_getPartHandlesFromPartsIdsArr( iMesh_Instance instance, const iMeshP_PartitionHandle partition_handle,
00408                                            const iMeshP_Part* part_ids, const int part_ids_size,
00409                                            iMeshP_PartHandle** part_handles, int* part_handles_allocated,
00410                                            int* part_handles_size, int* err )
00411 {
00412     ErrorCode rval;
00413     ParallelComm* pcomm = PCOMM;
00414     ALLOC_CHECK_ARRAY( part_handles, part_ids_size );
00415     for( int i = 0; i < part_ids_size; ++i )
00416     {
00417         EntityHandle handle;
00418         rval = pcomm->get_part_handle( part_ids[i], handle );CHKERR( rval, "error getting part handle" );
00419         ( *part_handles )[i] = itaps_cast< iMeshP_PartHandle >( handle );
00420     }
00421     KEEP_ARRAY( part_handles );
00422     RETURN( iBase_SUCCESS );
00423 }
00424 
00425 void iMeshP_getPartitionComm( iMesh_Instance instance, iMeshP_PartitionHandle partition_handle,
00426                               MPI_Comm* communicator_out, int* err )
00427 {
00428     ParallelComm* pcomm = PCOMM;
00429     if( !pcomm ) RETURN( iBase_FAILURE );
00430     *communicator_out = pcomm->proc_config().proc_comm();
00431     RETURN( iBase_SUCCESS );
00432 }
00433 
00434 void iMeshP_syncPartitionAll( iMesh_Instance instance, iMeshP_PartitionHandle partition_handle, int* err )
00435 {
00436     ParallelComm* pcomm = PCOMM;
00437     if( !pcomm ) ERROR( iBase_FAILURE, "No PComm" );
00438     ErrorCode rval = pcomm->collective_sync_partition();CHKERR( rval, "collective sync failed" );
00439     RETURN( iBase_SUCCESS );
00440 }
00441 
00442 void iMeshP_getNumPartitions( iMesh_Instance instance, int* num_partitions_out, int* err )
00443 {
00444     std::vector< ParallelComm* > pcomms;
00445     ErrorCode rval = ParallelComm::get_all_pcomm( MOABI, pcomms );CHKERR( rval, "Internal error retreiving PComms" );
00446 
00447     std::vector< ParallelComm* >::iterator i;
00448     *num_partitions_out = 0;
00449     for( i = pcomms.begin(); i != pcomms.end(); ++i )
00450         if( ( *i )->get_partitioning() ) ( *num_partitions_out )++;
00451 
00452     RETURN( iBase_SUCCESS );
00453 }
00454 
00455 void iMeshP_getPartitions( iMesh_Instance instance, iMeshP_PartitionHandle** partition_handle,
00456                            int* partition_handle_allocated, int* partition_handle_size, int* err )
00457 {
00458     std::vector< ParallelComm* > pcomms;
00459     ErrorCode rval = ParallelComm::get_all_pcomm( MOABI, pcomms );CHKERR( rval, "Internal error retreiving PComms" );
00460 
00461     std::vector< ParallelComm* >::iterator i;
00462     int count = 0;
00463     for( i = pcomms.begin(); i != pcomms.end(); ++i )
00464         if( ( *i )->get_partitioning() ) ++count;
00465     ALLOC_CHECK_ARRAY_NOFAIL( partition_handle, count );
00466 
00467     *partition_handle_size = 0;
00468     for( i = pcomms.begin(); i != pcomms.end(); ++i )
00469         if( ( *i )->get_partitioning() )
00470             ( *partition_handle )[( *partition_handle_size )++] =
00471                 itaps_cast< iMeshP_PartitionHandle >( ( *i )->get_partitioning() );
00472 
00473     RETURN( iBase_SUCCESS );
00474 }
00475 
00476 void iMeshP_getNumGlobalParts( iMesh_Instance instance, const iMeshP_PartitionHandle partition_handle,
00477                                int* num_global_part, int* err )
00478 {
00479     ParallelComm* pcomm = PCOMM;
00480     if( !pcomm ) ERROR( iBase_FAILURE, "No PComm" );
00481 
00482     ErrorCode rval = pcomm->get_global_part_count( *num_global_part );CHKERR( rval, "PComm::get_global_part_count failed" );
00483     RETURN( iBase_SUCCESS );
00484 }
00485 
00486 void iMeshP_getNumLocalParts( iMesh_Instance instance, const iMeshP_PartitionHandle partition_handle,
00487                               int* num_local_part, int* err )
00488 {
00489     ParallelComm* pcomm = PCOMM;
00490     if( !pcomm ) ERROR( iBase_FAILURE, "No PComm" );
00491 
00492     *num_local_part = pcomm->partition_sets().size();
00493     RETURN( iBase_SUCCESS );
00494 }
00495 
00496 void iMeshP_getLocalParts( iMesh_Instance instance, const iMeshP_PartitionHandle partition_handle,
00497                            iMeshP_PartHandle** part_handles, int* part_handles_allocated, int* part_handles_size,
00498                            int* err )
00499 {
00500     ParallelComm* pcomm = PCOMM;
00501     if( !pcomm ) ERROR( iBase_FAILURE, "No PComm" );
00502 
00503     RANGE_TO_ITAPS_ARRAY( pcomm->partition_sets(), part_handles );
00504     RETURN( iBase_SUCCESS );
00505 }
00506 
00507 void iMeshP_getRankOfPart( iMesh_Instance instance, const iMeshP_PartitionHandle partition_handle,
00508                            const iMeshP_Part part_id, int* rank, int* err )
00509 {
00510     int junk1 = 1, junk2 = 1;
00511     iMeshP_getRankOfPartArr( instance, partition_handle, &part_id, 1, &rank, &junk1, &junk2, err );
00512 }
00513 
00514 void iMeshP_getRankOfPartArr( iMesh_Instance instance, const iMeshP_PartitionHandle partition_handle,
00515                               const iMeshP_Part* part_ids, const int part_ids_size, int** rank, int* rank_allocated,
00516                               int* rank_size, int* err )
00517 {
00518     ParallelComm* pcomm = PCOMM;
00519     if( !pcomm ) ERROR( iBase_FAILURE, "No PComm" );
00520 
00521     ALLOC_CHECK_ARRAY( rank, part_ids_size );
00522     ErrorCode rval = MB_SUCCESS;
00523     for( int i = 0; i < part_ids_size; ++i )
00524     {
00525         rval = pcomm->get_part_owner( part_ids[i], ( *rank )[i] );CHKERR( rval, "PComm::get_part_owner failed" );
00526     }
00527     KEEP_ARRAY( rank );
00528     RETURN( iBase_SUCCESS );
00529 }
00530 
00531 void iMeshP_getNumOfTypeAll( iMesh_Instance instance, const iMeshP_PartitionHandle partition_handle,
00532                              const iBase_EntitySetHandle entity_set_handle, const int entity_type, int* num_type,
00533                              int* err )
00534 {
00535     ParallelComm* pcomm = PCOMM;
00536     if( !pcomm ) ERROR( iBase_FAILURE, "No PComm" );
00537 
00538     Range entities;
00539     ErrorCode rval = get_entities( MOABI, itaps_cast< EntityHandle >( entity_set_handle ), entity_type,
00540                                    iMesh_ALL_TOPOLOGIES, entities );
00541     int count      = 0;
00542     if( MB_SUCCESS == rval ) rval = count_owned( pcomm, entities, count );
00543 
00544     int vals[2] = { count, rval }, sums[2];
00545     int ierr    = MPI_Allreduce( vals, sums, 2, MPI_INT, MPI_SUM, pcomm->proc_config().proc_comm() );
00546     assert( iBase_SUCCESS == 0 );
00547     if( ierr || sums[1] ) RETURN( iBase_FAILURE );
00548 
00549     *num_type = sums[0];
00550     RETURN( iBase_SUCCESS );
00551 }
00552 
00553 void iMeshP_getNumOfTopoAll( iMesh_Instance instance, const iMeshP_PartitionHandle partition_handle,
00554                              const iBase_EntitySetHandle entity_set_handle, const int entity_topology, int* num_topo,
00555                              int* err )
00556 {
00557     ParallelComm* pcomm = PCOMM;
00558     if( !pcomm ) ERROR( iBase_FAILURE, "No PComm" );
00559 
00560     Range entities;
00561     ErrorCode rval = get_entities( MOABI, itaps_cast< EntityHandle >( entity_set_handle ), iBase_ALL_TYPES,
00562                                    entity_topology, entities );
00563     int count      = 0;
00564     if( MB_SUCCESS == rval ) rval = count_owned( pcomm, entities, count );
00565 
00566     int vals[2] = { count, rval }, sums[2];
00567     int ierr    = MPI_Allreduce( vals, sums, 2, MPI_INT, MPI_SUM, pcomm->proc_config().proc_comm() );
00568     assert( iBase_SUCCESS == 0 );
00569     if( ierr || sums[1] ) RETURN( iBase_FAILURE );
00570 
00571     *num_topo = sums[0];
00572     RETURN( iBase_SUCCESS );
00573 }
00574 
00575 void iMeshP_createPart( iMesh_Instance instance, iMeshP_PartitionHandle partition_handle,
00576                         iMeshP_PartHandle* part_handle, int* err )
00577 {
00578     ParallelComm* pcomm = PCOMM;
00579     if( !pcomm ) ERROR( iBase_FAILURE, "No PComm" );
00580 
00581     EntityHandle h;
00582     ErrorCode rval = pcomm->create_part( h );CHKERR( rval, "Part creation failed" );
00583     *part_handle = itaps_cast< iMeshP_PartHandle >( h );
00584     RETURN( iBase_SUCCESS );
00585 }
00586 
00587 void iMeshP_destroyPart( iMesh_Instance instance, iMeshP_PartitionHandle partition_handle,
00588                          iMeshP_PartHandle part_handle, int* err )
00589 {
00590     ParallelComm* pcomm = PCOMM;
00591     if( !pcomm ) ERROR( iBase_FAILURE, "No PComm" );
00592 
00593     ErrorCode rval = pcomm->destroy_part( itaps_cast< EntityHandle >( part_handle ) );CHKERR( rval, "Part destruction failed" );
00594     RETURN( iBase_SUCCESS );
00595 }
00596 
00597 void iMeshP_getNumPartNbors( iMesh_Instance instance, iMeshP_PartitionHandle partition_handle,
00598                              iMeshP_PartHandle part_handle, int entity_type, int* num_part_nbors, int* err )
00599 {
00600     int junk1 = 1, junk2 = 1;
00601     iMeshP_getNumPartNborsArr( instance, partition_handle, &part_handle, 1, entity_type, &num_part_nbors, &junk1,
00602                                &junk2, err );
00603 }
00604 
00605 void iMeshP_getNumPartNborsArr( iMesh_Instance instance, const iMeshP_PartitionHandle partition_handle,
00606                                 const iMeshP_PartHandle* part_handles, const int part_handles_size, int /*entity_type*/,
00607                                 int** num_part_nbors, int* num_part_nbors_allocated, int* num_part_nbors_size,
00608                                 int* err )
00609 {
00610     ParallelComm* pcomm = PCOMM;
00611     if( !pcomm ) ERROR( iBase_FAILURE, "No PComm" );
00612 
00613     ALLOC_CHECK_ARRAY( num_part_nbors, part_handles_size );
00614 
00615     int n, neighbors[MAX_SHARING_PROCS];
00616     ErrorCode rval;
00617     for( int i = 0; i < part_handles_size; ++i )
00618     {
00619         EntityHandle h = itaps_cast< EntityHandle >( part_handles[i] );
00620         rval           = pcomm->get_part_neighbor_ids( h, neighbors, n );CHKERR( rval, "error getting neighbor ids" );
00621         ( *num_part_nbors )[i] = n;
00622     }
00623 
00624     KEEP_ARRAY( num_part_nbors );
00625     RETURN( iBase_SUCCESS );
00626 }
00627 
00628 void iMeshP_getPartNbors( iMesh_Instance instance, const iMeshP_PartitionHandle partition_handle,
00629                           const iMeshP_PartHandle part_handle, int entity_type, int* num_part_nbors,
00630                           iMeshP_Part** nbor_part_ids, int* nbor_part_ids_allocated, int* nbor_part_ids_size, int* err )
00631 {
00632     int junk1 = 1, junk2 = 1;
00633     iMeshP_getPartNborsArr( instance, partition_handle, &part_handle, 1, entity_type, &num_part_nbors, &junk1, &junk2,
00634                             nbor_part_ids, nbor_part_ids_allocated, nbor_part_ids_size, err );
00635 }
00636 
00637 void iMeshP_getPartNborsArr( iMesh_Instance instance, const iMeshP_PartitionHandle partition_handle,
00638                              const iMeshP_PartHandle* part_handles, const int part_handles_size, int /*entity_type*/,
00639                              int** num_part_nbors, int* num_part_nbors_allocated, int* num_part_nbors_size,
00640                              iMeshP_Part** nbor_part_ids, int* nbor_part_ids_allocated, int* nbor_part_ids_size,
00641                              int* err )
00642 {
00643     ParallelComm* pcomm = PCOMM;
00644     if( !pcomm ) ERROR( iBase_FAILURE, "No PComm" );
00645 
00646     ALLOC_CHECK_ARRAY( num_part_nbors, part_handles_size );
00647 
00648     std::vector< int > all_neighbors;
00649     int n, pnbor[MAX_SHARING_PROCS];
00650     ErrorCode rval;
00651     for( int i = 0; i < part_handles_size; ++i )
00652     {
00653         EntityHandle h = itaps_cast< EntityHandle >( part_handles[i] );
00654         rval           = pcomm->get_part_neighbor_ids( h, pnbor, n );CHKERR( rval, "error getting neighbor ids" );
00655         ( *num_part_nbors )[i] = n;
00656         std::copy( pnbor, pnbor + n, std::back_inserter( all_neighbors ) );
00657     }
00658 
00659     ALLOC_CHECK_ARRAY_NOFAIL( nbor_part_ids, all_neighbors.size() );
00660     memcpy( *nbor_part_ids, &all_neighbors[0], sizeof( int ) * all_neighbors.size() );
00661 
00662     KEEP_ARRAY( num_part_nbors );
00663     RETURN( iBase_SUCCESS );
00664 }
00665 
00666 void iMeshP_getNumPartBdryEnts( iMesh_Instance instance, const iMeshP_PartitionHandle partition_handle,
00667                                 const iMeshP_PartHandle part_handle, const int entity_type, const int entity_topology,
00668                                 const iMeshP_Part target_part_id, int* num_entities, int* err )
00669 {
00670     Range entities;
00671     ErrorCode rval = get_boundary_entities( PCOMM, itaps_cast< EntityHandle >( part_handle ), entity_type,
00672                                             entity_topology, target_part_id, entities );CHKERR( rval, "failed to get boundary entities" );
00673     *num_entities = entities.size();
00674     RETURN( iBase_SUCCESS );
00675 }
00676 
00677 void iMeshP_getPartBdryEnts( iMesh_Instance instance, const iMeshP_PartitionHandle partition_handle,
00678                              const iMeshP_PartHandle part_handle, const int entity_type, const int entity_topology,
00679                              const iMeshP_Part target_part_id, iBase_EntityHandle** entity_handles,
00680                              int* entity_handles_allocated, int* entity_handles_size, int* err )
00681 {
00682     Range entities;
00683     ErrorCode rval = get_boundary_entities( PCOMM, itaps_cast< EntityHandle >( part_handle ), entity_type,
00684                                             entity_topology, target_part_id, entities );CHKERR( rval, "failed to get boundary entities" );
00685     RANGE_TO_ITAPS_ARRAY( entities, entity_handles );
00686     RETURN( iBase_SUCCESS );
00687 }
00688 
00689 void iMeshP_initPartBdryEntIter( iMesh_Instance instance, const iMeshP_PartitionHandle partition_handle,
00690                                  const iMeshP_PartHandle part_handle, const int entity_type, const int entity_topology,
00691                                  const iMeshP_Part nbor_part_id, iBase_EntityIterator* entity_iterator, int* err )
00692 {
00693     iMeshP_initPartBdryEntArrIter( instance, partition_handle, part_handle, entity_type, entity_topology, 1,
00694                                    nbor_part_id, reinterpret_cast< iBase_EntityArrIterator* >( entity_iterator ), err );
00695 }
00696 
00697 void iMeshP_initPartBdryEntArrIter( iMesh_Instance instance, const iMeshP_PartitionHandle partition_handle,
00698                                     const iMeshP_PartHandle part_handle, const int entity_type,
00699                                     const int entity_topology, const int array_size, const iMeshP_Part nbor_part_id,
00700                                     iBase_EntityArrIterator* entity_iterator, int* err )
00701 {
00702     *entity_iterator =
00703         new PartBoundaryIter( PCOMM, itaps_cast< EntityHandle >( part_handle ), (iBase_EntityType)entity_type,
00704                               (iMesh_EntityTopology)entity_topology, nbor_part_id, array_size );
00705     ErrorCode result = ( *entity_iterator )->reset( MOABI );
00706     if( MB_SUCCESS != result ) delete *entity_iterator;CHKERR( result, "iMesh_initEntArrIter: ERROR getting entities of proper type or topology." );
00707     RETURN( iBase_SUCCESS );
00708 }
00709 
00710 void iMeshP_getNumOfType( iMesh_Instance instance, const iMeshP_PartitionHandle, const iMeshP_PartHandle part_handle,
00711                           const iBase_EntitySetHandle entity_set_handle, const int entity_type, int* num_type,
00712                           int* err )
00713 {
00714     Range r;
00715     set_intersection_query( instance, part_handle, entity_set_handle, entity_type, iMesh_ALL_TOPOLOGIES, r, err );
00716     *num_type = r.size();
00717 }
00718 
00719 void iMeshP_getNumOfTopo( iMesh_Instance instance, const iMeshP_PartitionHandle /*partition_handle*/,
00720                           const iMeshP_PartHandle part_handle, const iBase_EntitySetHandle entity_set_handle,
00721                           const int entity_topology, int* num_topo, int* err )
00722 {
00723     Range r;
00724     set_intersection_query( instance, part_handle, entity_set_handle, iBase_ALL_TYPES, entity_topology, r, err );
00725     *num_topo = r.size();
00726 }
00727 
00728 void iMeshP_getAdjEntIndices( iMesh_Instance instance, iMeshP_PartitionHandle partition, iMeshP_PartHandle part,
00729                               iBase_EntitySetHandle entity_set_handle, int entity_type_requestor,
00730                               int entity_topology_requestor, int entity_type_requested,
00731                               iBase_EntityHandle** entity_handles, int* entity_handles_allocated,
00732                               int* entity_handles_size, iBase_EntityHandle** adj_entity_handles,
00733                               int* adj_entity_handles_allocated, int* adj_entity_handles_size, int** adj_entity_indices,
00734                               int* adj_entity_indices_allocated, int* adj_entity_indices_size, int** offset,
00735                               int* offset_allocated, int* offset_size, int* err )
00736 {
00737     const int allocated_entity_handles = ( *entity_handles_allocated == 0 );
00738     const int allocated_indices        = ( *adj_entity_indices_allocated == 0 );
00739     const int allocated_offset         = ( *offset_allocated == 0 );
00740 
00741     // get source entities
00742     iMeshP_getEntities( instance, partition, part, entity_set_handle, entity_type_requestor, entity_topology_requestor,
00743                         entity_handles, entity_handles_allocated, entity_handles_size, err );
00744     if( iBase_SUCCESS != *err ) return;
00745 
00746     // get adjacencies
00747     iBase_EntityHandle* all_adj_handles = 0;
00748     int size = 0, alloc = 0;
00749     iMesh_getEntArrAdj( instance, *entity_handles, *entity_handles_size, entity_type_requested, &all_adj_handles,
00750                         &alloc, &size, offset, offset_allocated, offset_size, err );
00751     if( *err != iBase_SUCCESS )
00752     {
00753         if( allocated_entity_handles )
00754         {
00755             free( *entity_handles );
00756             *entity_handles           = 0;
00757             *entity_handles_allocated = 0;
00758         }
00759         return;
00760     }
00761 
00762     // allocate or check size of adj_entity_indices
00763     *adj_entity_indices_size = size;
00764     if( allocated_indices )
00765     {
00766         *adj_entity_indices = (int*)malloc( sizeof( iBase_EntityHandle ) * size );
00767         if( !*adj_entity_indices )
00768             *err = iBase_MEMORY_ALLOCATION_FAILED;
00769         else
00770             *adj_entity_indices_allocated = size;
00771     }
00772     else if( *adj_entity_indices_allocated < size )
00773     {
00774         *err = iBase_BAD_ARRAY_DIMENSION;
00775     }
00776     if( iBase_SUCCESS != *err )
00777     {
00778         free( all_adj_handles );
00779         if( allocated_entity_handles )
00780         {
00781             free( *entity_handles );
00782             *entity_handles           = 0;
00783             *entity_handles_allocated = 0;
00784         }
00785         if( allocated_offset )
00786         {
00787             free( *offset );
00788             *offset           = 0;
00789             *offset_allocated = 0;
00790         }
00791         return;
00792     }
00793 
00794     // Now create an array of unique sorted handles from all_adj_handles.
00795     // We need to create a copy because we still need all_adj_handles.  We
00796     // will eventually need to copy the resulting unique list into
00797     // adj_entity_handles, so if adj_entity_handles is already allocated and
00798     // of sufficient size, use it rather than allocating another temporary.
00799     iBase_EntityHandle* unique_adj = 0;
00800     if( *adj_entity_handles_allocated >= size ) { unique_adj = *adj_entity_handles; }
00801     else
00802     {
00803         unique_adj = (iBase_EntityHandle*)malloc( sizeof( iBase_EntityHandle ) * size );
00804     }
00805     std::copy( all_adj_handles, all_adj_handles + size, unique_adj );
00806     std::sort( unique_adj, unique_adj + size );
00807     *adj_entity_handles_size = std::unique( unique_adj, unique_adj + size ) - unique_adj;
00808 
00809     // If we created a temporary array for unique_adj rather than using
00810     // already allocated space in adj_entity_handles, allocate adj_entity_handles
00811     // and copy the unique handle list into it
00812     if( *adj_entity_handles != unique_adj )
00813     {
00814         if( !*adj_entity_handles_allocated )
00815         {
00816             *adj_entity_handles =
00817                 (iBase_EntityHandle*)malloc( sizeof( iBase_EntityHandle ) * *adj_entity_handles_size );
00818             if( !*adj_entity_handles )
00819                 *err = iBase_MEMORY_ALLOCATION_FAILED;
00820             else
00821                 *adj_entity_handles_allocated = *adj_entity_handles_size;
00822         }
00823         else if( *adj_entity_handles_allocated < *adj_entity_handles_size )
00824             *err = iBase_BAD_ARRAY_DIMENSION;
00825         if( iBase_SUCCESS != *err )
00826         {
00827             free( unique_adj );
00828             free( all_adj_handles );
00829             if( allocated_entity_handles )
00830             {
00831                 free( *entity_handles );
00832                 *entity_handles           = 0;
00833                 *entity_handles_allocated = 0;
00834             }
00835             if( allocated_offset )
00836             {
00837                 free( *offset );
00838                 *offset           = 0;
00839                 *offset_allocated = 0;
00840             }
00841             if( allocated_indices )
00842             {
00843                 free( *adj_entity_indices );
00844                 *adj_entity_indices           = 0;
00845                 *adj_entity_indices_allocated = 0;
00846             }
00847             return;
00848         }
00849 
00850         std::copy( unique_adj, unique_adj + *adj_entity_handles_size, *adj_entity_handles );
00851         free( unique_adj );
00852         unique_adj = *adj_entity_handles;
00853     }
00854 
00855     // convert from adjacency list to indices into unique_adj
00856     for( int i = 0; i < *adj_entity_indices_size; ++i )
00857         ( *adj_entity_indices )[i] =
00858             std::lower_bound( unique_adj, unique_adj + *adj_entity_handles_size, all_adj_handles[i] ) - unique_adj;
00859     free( all_adj_handles );
00860 }
00861 
00862 void iMeshP_getEntities( iMesh_Instance instance, const iMeshP_PartitionHandle, const iMeshP_PartHandle part_handle,
00863                          const iBase_EntitySetHandle entity_set_handle, const int entity_type,
00864                          const int entity_topology, iBase_EntityHandle** entity_handles, int* entity_handles_allocated,
00865                          int* entity_handles_size, int* err )
00866 {
00867     Range r;
00868     set_intersection_query( instance, part_handle, entity_set_handle, entity_type, entity_topology, r, err );
00869     if( iBase_SUCCESS != *err ) return;
00870 
00871     RANGE_TO_ITAPS_ARRAY( r, entity_handles );
00872     RETURN( iBase_SUCCESS );
00873 }
00874 
00875 void iMeshP_getAdjEntities( iMesh_Instance instance, const iMeshP_PartitionHandle /*partition_handle*/,
00876                             const iMeshP_PartHandle part_handle, const iBase_EntitySetHandle entity_set_handle,
00877                             const int entity_type_requestor, const int entity_topology_requestor,
00878                             const int entity_type_requested, iBase_EntityHandle** adj_entity_handles,
00879                             int* adj_entity_handles_allocated, int* adj_entity_handles_size, int** offset,
00880                             int* offset_allocated, int* offset_size, int** in_entity_set, int* in_entity_set_allocated,
00881                             int* in_entity_set_size, int* err )
00882 {
00883     ErrorCode rval;
00884     Range r;
00885     set_intersection_query( instance, part_handle, entity_set_handle, entity_type_requestor, entity_topology_requestor,
00886                             r, err );
00887     if( iBase_SUCCESS != *err ) return;
00888 
00889     // count adjacencies
00890     std::vector< EntityHandle > tmp_storage;
00891     int num_adj = 0;
00892     int num_conn;
00893     const EntityHandle* conn_ptr;
00894     for( Range::iterator i = r.begin(); i != r.end(); ++i )
00895     {
00896         if( entity_type_requested || TYPE_FROM_HANDLE( *i ) == MBPOLYHEDRON )
00897         {
00898             tmp_storage.clear();
00899             rval = MOABI->get_adjacencies( &*i, 1, entity_type_requested, false, tmp_storage );CHKERR( rval, "get_adjacencies failed" );
00900             num_adj += tmp_storage.size();
00901         }
00902         else
00903         {
00904             rval = MOABI->get_connectivity( *i, conn_ptr, num_conn, false, &tmp_storage );CHKERR( rval, "get_connectivity failed" );
00905             num_adj += num_conn;
00906         }
00907     }
00908 
00909     // get adjacencies
00910     ALLOC_CHECK_ARRAY( adj_entity_handles, num_adj );
00911     ALLOC_CHECK_ARRAY( offset, r.size() );
00912     int arr_pos      = 0;
00913     int* offset_iter = *offset;
00914     for( Range::iterator i = r.begin(); i != r.end(); ++i )
00915     {
00916         *offset_iter = arr_pos;
00917         ++offset_iter;
00918 
00919         tmp_storage.clear();
00920         rval = MOABI->get_adjacencies( &*i, 1, entity_type_requested, false, tmp_storage );CHKERR( rval, "get_adjacencies failed" );
00921         for( std::vector< EntityHandle >::iterator j = tmp_storage.begin(); j != tmp_storage.end(); ++j )
00922         {
00923             ( *adj_entity_handles )[arr_pos] = itaps_cast< iBase_EntityHandle >( *j );
00924             ++arr_pos;
00925         }
00926     }
00927 
00928     // get in_entity_set
00929     iMesh_isEntArrContained( instance, entity_set_handle, *adj_entity_handles, *adj_entity_handles_size, in_entity_set,
00930                              in_entity_set_allocated, in_entity_set_size, err );
00931 
00932     if( iBase_SUCCESS == *err )
00933     {
00934         KEEP_ARRAY( adj_entity_handles );
00935         KEEP_ARRAY( offset );
00936     }
00937 }
00938 
00939 void iMeshP_initEntIter( iMesh_Instance instance, const iMeshP_PartitionHandle partition_handle,
00940                          const iMeshP_PartHandle part_handle, const iBase_EntitySetHandle entity_set_handle,
00941                          const int requested_entity_type, const int requested_entity_topology,
00942                          iBase_EntityIterator* entity_iterator, int* err )
00943 {
00944     iMeshP_initEntArrIter( instance, partition_handle, part_handle, entity_set_handle, requested_entity_type,
00945                            requested_entity_topology, 1,
00946                            reinterpret_cast< iBase_EntityArrIterator* >( entity_iterator ), err );
00947 }
00948 
00949 void iMeshP_initEntArrIter( iMesh_Instance instance, const iMeshP_PartitionHandle /*partition_handle*/,
00950                             const iMeshP_PartHandle part_handle, const iBase_EntitySetHandle entity_set_handle,
00951                             const int requested_entity_type, const int requested_entity_topology,
00952                             const int requested_array_size, iBase_EntityArrIterator* entArr_iterator, int* err )
00953 {
00954     if( !entity_set_handle || entity_set_handle == part_handle )
00955     {
00956         iMesh_initEntArrIter( instance, part_handle, requested_entity_type, requested_entity_topology,
00957                               requested_array_size,
00958                               0,  // TODO: update this function for "resilient" arg
00959                               entArr_iterator, err );
00960     }
00961     else
00962     {
00963         unsigned flags;
00964         ErrorCode result = MOABI->get_meshset_options( itaps_cast< EntityHandle >( entity_set_handle ), flags );CHKERR( result, "Invalid entity set handle" );
00965         if( flags & MESHSET_ORDERED )
00966             *entArr_iterator = new SetIntersectIter< std::vector< EntityHandle > >(
00967                 (iBase_EntityType)requested_entity_type, (iMesh_EntityTopology)requested_entity_topology,
00968                 itaps_cast< EntityHandle >( entity_set_handle ), itaps_cast< EntityHandle >( part_handle ),
00969                 requested_array_size );
00970         else
00971             *entArr_iterator =
00972                 new SetIntersectIter< Range >( (iBase_EntityType)requested_entity_type,
00973                                                (iMesh_EntityTopology)requested_entity_topology,
00974                                                itaps_cast< EntityHandle >( entity_set_handle ),
00975                                                itaps_cast< EntityHandle >( part_handle ), requested_array_size );
00976         result = ( *entArr_iterator )->reset( MOABI );
00977         if( MB_SUCCESS != result ) delete *entArr_iterator;CHKERR( result, "iMesh_initEntArrIter: ERROR getting entities of proper type or topology." );
00978         RETURN( iBase_SUCCESS );
00979     }
00980 }
00981 
00982 void iMeshP_getEntOwnerPart( iMesh_Instance instance, const iMeshP_PartitionHandle partition_handle,
00983                              const iBase_EntityHandle entity_handle, iMeshP_Part* part_id, int* err )
00984 {
00985     int junk1 = 1, junk2 = 1;
00986     iMeshP_getEntOwnerPartArr( instance, partition_handle, &entity_handle, 1, &part_id, &junk1, &junk2, err );
00987 }
00988 
00989 void iMeshP_getEntOwnerPartArr( iMesh_Instance instance, const iMeshP_PartitionHandle partition_handle,
00990                                 const iBase_EntityHandle* entity_handles, const int entity_handles_size,
00991                                 iMeshP_Part** part_ids, int* part_ids_allocated, int* part_ids_size, int* err )
00992 {
00993     ParallelComm* pcomm = PCOMM;
00994     if( !pcomm ) ERROR( iBase_FAILURE, "No PComm" );
00995 
00996     int id;
00997     ALLOC_CHECK_ARRAY( part_ids, entity_handles_size );
00998     ErrorCode rval = MB_SUCCESS;
00999     for( int i = 0; i < entity_handles_size; ++i )
01000     {
01001         EntityHandle h   = itaps_cast< EntityHandle >( entity_handles[i] );
01002         rval             = pcomm->get_owning_part( h, id );
01003         ( *part_ids )[i] = id;CHKERR( rval, "Failet get part owner" );
01004     }
01005     KEEP_ARRAY( part_ids );
01006     RETURN( iBase_SUCCESS );
01007 }
01008 
01009 void iMeshP_isEntOwner( iMesh_Instance instance, const iMeshP_PartitionHandle partition_handle,
01010                         const iMeshP_PartHandle part_handle, const iBase_EntityHandle entity_handle, int* is_owner,
01011                         int* err )
01012 {
01013     int junk1 = 1, junk2 = 1;
01014     iMeshP_isEntOwnerArr( instance, partition_handle, part_handle, &entity_handle, 1, &is_owner, &junk1, &junk2, err );
01015 }
01016 
01017 void iMeshP_isEntOwnerArr( iMesh_Instance instance, const iMeshP_PartitionHandle partition_handle,
01018                            const iMeshP_PartHandle part_handle, const iBase_EntityHandle* entity_handles,
01019                            const int entity_handles_size, int** is_owner, int* is_owner_allocated, int* is_owner_size,
01020                            int* err )
01021 {
01022     ErrorCode rval;
01023     ParallelComm* pcomm = PCOMM;
01024     if( !pcomm ) ERROR( iBase_FAILURE, "No PComm" );
01025 
01026     int id;
01027     rval = pcomm->get_part_id( itaps_cast< EntityHandle >( part_handle ), id );CHKERR( rval, "error getting part id" );
01028 
01029     ALLOC_CHECK_ARRAY( is_owner, entity_handles_size );
01030     *is_owner_size = entity_handles_size;
01031 
01032     int owner;
01033     for( int i = 0; i < entity_handles_size; ++i )
01034     {
01035         rval = pcomm->get_owner( itaps_cast< EntityHandle >( entity_handles[i] ), owner );CHKERR( rval, "error getting owner" );
01036         ( *is_owner )[i] = ( owner == id );
01037     }
01038 
01039     KEEP_ARRAY( is_owner );
01040     RETURN( iBase_SUCCESS );
01041 }
01042 
01043 void iMeshP_getEntStatus( iMesh_Instance instance,
01044                           /*in*/ const iMeshP_PartitionHandle partition_handle,
01045                           /*in*/ const iMeshP_PartHandle part_handle,
01046                           /*in*/ const iBase_EntityHandle entity_handle,
01047                           /*out*/ int* par_status,  // Values=INTERNAL,BOUNDARY,GHOST
01048                           int* err )
01049 {
01050     int junk1 = 1, junk2 = 1;
01051     iMeshP_getEntStatusArr( instance, partition_handle, part_handle, &entity_handle, 1, &par_status, &junk1, &junk2,
01052                             err );
01053 }
01054 
01055 void iMeshP_getEntStatusArr( iMesh_Instance instance,
01056                              /*in*/ const iMeshP_PartitionHandle partition_handle,
01057                              /*in*/ const iMeshP_PartHandle /*part_handle*/,
01058                              /*in*/ const iBase_EntityHandle* entity_handles,
01059                              /*in*/ const int entity_handles_size,
01060                              /*inout*/ int** par_status,  // Values=INTERNAL,BOUNDARY,GHOST
01061                              /*inout*/ int* par_status_allocated,
01062                              /*inout*/ int* par_status_size, int* err )
01063 {
01064     ParallelComm* pcomm = PCOMM;
01065     if( !pcomm ) ERROR( iBase_FAILURE, "No PComm" );
01066 
01067     std::vector< unsigned char > pstatus( entity_handles_size );
01068     ErrorCode result = MOABI->tag_get_data( pcomm->pstatus_tag(), itaps_cast< const EntityHandle* >( entity_handles ),
01069                                             entity_handles_size, &pstatus[0] );CHKERR( result, "error getting pstatus_tag" );
01070 
01071     ALLOC_CHECK_ARRAY( par_status, entity_handles_size );
01072     for( int i = 0; i < entity_handles_size; i++ )
01073     {
01074         if( !pstatus[i] )
01075             ( *par_status )[i] = iMeshP_INTERNAL;
01076         else if( pstatus[i] & PSTATUS_GHOST )
01077             ( *par_status )[i] = iMeshP_GHOST;
01078         else if( pstatus[i] & PSTATUS_INTERFACE )
01079             ( *par_status )[i] = iMeshP_BOUNDARY;
01080     }
01081 
01082     KEEP_ARRAY( par_status );
01083     RETURN( iBase_SUCCESS );
01084 }
01085 
01086 void iMeshP_getNumCopies( iMesh_Instance instance, const iMeshP_PartitionHandle partition_handle,
01087                           const iBase_EntityHandle entity_handle, int* num_copies_ent, int* err )
01088 {
01089     ParallelComm* pcomm = PCOMM;
01090     if( !pcomm ) ERROR( iBase_FAILURE, "No PComm" );
01091 
01092     int ids[MAX_SHARING_PROCS];
01093     ErrorCode rval = pcomm->get_sharing_parts( itaps_cast< EntityHandle >( entity_handle ), ids, *num_copies_ent );CHKERR( rval, "ParallelComm::get_sharing_parts failed" );
01094     RETURN( iBase_SUCCESS );
01095 }
01096 
01097 void iMeshP_getCopyParts( iMesh_Instance instance, const iMeshP_PartitionHandle partition_handle,
01098                           const iBase_EntityHandle entity_handle, iMeshP_Part** part_ids, int* part_ids_allocated,
01099                           int* part_ids_size, int* err )
01100 {
01101     ParallelComm* pcomm = PCOMM;
01102     if( !pcomm ) ERROR( iBase_FAILURE, "No PComm" );
01103 
01104     int ids[MAX_SHARING_PROCS], num_ids;
01105     ErrorCode rval = pcomm->get_sharing_parts( itaps_cast< EntityHandle >( entity_handle ), ids, num_ids );CHKERR( rval, "ParallelComm::get_sharing_parts failed" );
01106     ALLOC_CHECK_ARRAY_NOFAIL( part_ids, num_ids );
01107     std::copy( ids, ids + num_ids, *part_ids );
01108     RETURN( iBase_SUCCESS );
01109 }
01110 
01111 void iMeshP_getCopies( iMesh_Instance instance, const iMeshP_PartitionHandle partition_handle,
01112                        const iBase_EntityHandle entity_handle, iMeshP_Part** part_ids, int* part_ids_allocated,
01113                        int* part_ids_size, iBase_EntityHandle** copies_entity_handles,
01114                        int* copies_entity_handles_allocated, int* copies_entity_handles_size, int* err )
01115 {
01116     ParallelComm* pcomm = PCOMM;
01117     if( !pcomm ) ERROR( iBase_FAILURE, "No PComm" );
01118 
01119     int ids[MAX_SHARING_PROCS], num_ids;
01120     EntityHandle handles[MAX_SHARING_PROCS];
01121     ErrorCode rval = pcomm->get_sharing_parts( itaps_cast< EntityHandle >( entity_handle ), ids, num_ids, handles );CHKERR( rval, "ParallelComm::get_sharing_parts failed" );
01122     ALLOC_CHECK_ARRAY_NOFAIL( part_ids, num_ids );
01123     ALLOC_CHECK_ARRAY_NOFAIL( copies_entity_handles, num_ids );
01124     for( int i = 0; i < num_ids; ++i )
01125     {
01126         ( *part_ids )[i]              = ids[i];
01127         ( *copies_entity_handles )[i] = itaps_cast< iBase_EntityHandle >( handles[i] );
01128     }
01129     RETURN( iBase_SUCCESS );
01130 }
01131 
01132 void iMeshP_getCopyOnPart( iMesh_Instance instance, const iMeshP_PartitionHandle partition_handle,
01133                            const iBase_EntityHandle entity_handle, const iMeshP_Part part_id,
01134                            iBase_EntityHandle* copy_entity_handle, int* err )
01135 {
01136     ParallelComm* pcomm = PCOMM;
01137     if( !pcomm ) ERROR( iBase_FAILURE, "No PComm" );
01138 
01139     int ids[MAX_SHARING_PROCS], num_ids;
01140     EntityHandle handles[MAX_SHARING_PROCS];
01141     ErrorCode rval = pcomm->get_sharing_parts( itaps_cast< EntityHandle >( entity_handle ), ids, num_ids, handles );CHKERR( rval, "ParallelComm::get_sharing_parts failed" );
01142     int idx = std::find( ids, ids + num_ids, part_id ) - ids;
01143     if( idx == num_ids ) RETURN( iBase_FAILURE );
01144 
01145     *copy_entity_handle = itaps_cast< iBase_EntityHandle >( handles[idx] );
01146     RETURN( iBase_SUCCESS );
01147 }
01148 
01149 void iMeshP_getOwnerCopy( iMesh_Instance instance, const iMeshP_PartitionHandle partition_handle,
01150                           const iBase_EntityHandle entity_handle, iMeshP_Part* owner_part_id,
01151                           iBase_EntityHandle* owner_entity_handle, int* err )
01152 {
01153     ParallelComm* pcomm = PCOMM;
01154     if( !pcomm ) ERROR( iBase_FAILURE, "No PComm" );
01155 
01156     int id;
01157     EntityHandle h;
01158     ErrorCode rval = pcomm->get_owning_part( itaps_cast< EntityHandle >( entity_handle ), id, &h );CHKERR( rval, "Failed to get owner" );
01159     *owner_part_id       = id;
01160     *owner_entity_handle = itaps_cast< iBase_EntityHandle >( h );
01161     RETURN( iBase_SUCCESS );
01162 }
01163 
01164 void iMeshP_waitForAnyRequest( iMesh_Instance instance, iMeshP_PartitionHandle, iMeshP_RequestHandle*, int, int*,
01165                                int* err )
01166 {
01167     FIXME;
01168     RETURN( iBase_NOT_SUPPORTED );
01169 }
01170 
01171 void iMeshP_waitForAllRequests( iMesh_Instance instance, iMeshP_PartitionHandle, iMeshP_RequestHandle*, int, int* err )
01172 {
01173     FIXME;
01174     RETURN( iBase_NOT_SUPPORTED );
01175 }
01176 
01177 void iMeshP_waitForRequestEnt( iMesh_Instance instance, const iMeshP_PartitionHandle, iMeshP_RequestHandle,
01178                                iBase_EntityHandle**, int*, int*, int* err )
01179 {
01180     FIXME;
01181     RETURN( iBase_NOT_SUPPORTED );
01182 }
01183 
01184 void iMeshP_testRequest( iMesh_Instance instance, const iMeshP_PartitionHandle, iMeshP_RequestHandle, int*, int* err )
01185 {
01186     FIXME;
01187     RETURN( iBase_NOT_SUPPORTED );
01188 }
01189 
01190 void iMeshP_pollForRequests( iMesh_Instance instance, iMeshP_PartitionHandle, iMeshP_RequestHandle**, int*, int*,
01191                              int* err )
01192 {
01193     FIXME;
01194     RETURN( iBase_NOT_SUPPORTED );
01195 }
01196 
01197 void iMeshP_exchEntArrToPartsAll( iMesh_Instance instance, const iMeshP_PartitionHandle partition_handle,
01198                                   const iBase_EntityHandle* entity_handles, const int entity_handles_size,
01199                                   const iMeshP_Part* target_part_ids, int command_code, int update_ghost,
01200                                   iMeshP_RequestHandle* /*request*/, int* err )
01201 {
01202     if( command_code == 1 )
01203     {
01204         std::cerr << "Entity migration option is not supported." << std::endl;
01205         RETURN( iBase_NOT_SUPPORTED );
01206     }
01207 
01208     if( update_ghost == 1 )
01209     {
01210         std::cerr << "Gost update option is not supported." << std::endl;
01211         RETURN( iBase_NOT_SUPPORTED );
01212     }
01213 
01214     // make exchange entity and processor list
01215     ErrorCode rval;
01216     ParallelComm* pcomm = PCOMM;
01217     std::vector< unsigned int > exchange_procs;
01218     std::vector< Range* > exchange_ents;
01219 
01220     for( int i = 0; i < entity_handles_size; i++ )
01221     {
01222         int ind = -1;
01223         // iMeshP_Part target_p = target_part_ids[i];
01224         int target_p;
01225         rval = pcomm->get_part_owner( target_part_ids[i], target_p );CHKERR( rval, "ParallelComm::get_part_owner failed" );
01226 
01227         std::vector< unsigned int >::iterator vit = std::find( exchange_procs.begin(), exchange_procs.end(), target_p );
01228         if( vit == exchange_procs.end() )
01229         {
01230             ind = exchange_procs.size();
01231             exchange_procs.push_back( target_p );
01232             exchange_ents.push_back( new Range );
01233         }
01234         else
01235             ind = vit - exchange_procs.begin();
01236 
01237         exchange_ents[ind]->insert( itaps_cast< EntityHandle >( entity_handles[i] ) );
01238     }
01239 
01240     std::vector< MPI_Request > recv_ent_reqs, recv_remoteh_reqs;
01241     rval = pcomm->exchange_owned_meshs( exchange_procs, exchange_ents, recv_ent_reqs, recv_remoteh_reqs, true );CHKERR( rval, "ParallelComm::exchange_owned_meshs failed" );
01242 
01243     // delete exchange list
01244     std::vector< Range* >::iterator vit;
01245     for( vit = exchange_ents.begin(); vit != exchange_ents.end(); ++vit )
01246         delete( *vit );
01247 
01248     RETURN( iBase_SUCCESS );
01249 }
01250 
01251 void iMeshP_migrateEntity( iMesh_Instance instance, const iMeshP_PartitionHandle, const iMeshP_PartHandle,
01252                            const iBase_EntityHandle, iMeshP_RequestHandle*, int* err )
01253 {
01254     FIXME;
01255     RETURN( iBase_NOT_SUPPORTED );
01256 }
01257 
01258 void iMeshP_updateVtxCoords( iMesh_Instance instance, const iMeshP_PartitionHandle, const iBase_EntityHandle, int* err )
01259 {
01260     FIXME;
01261     RETURN( iBase_NOT_SUPPORTED );
01262 }
01263 
01264 void iMeshP_replaceOnPartBdry( iMesh_Instance instance, const iMeshP_PartitionHandle, const iBase_EntityHandle*,
01265                                const int, const iBase_EntityHandle*, const int, const int*, const int, int* err )
01266 {
01267     FIXME;
01268     RETURN( iBase_NOT_SUPPORTED );
01269 }
01270 
01271 void iMeshP_addGhostOf( iMesh_Instance instance, const iMeshP_PartitionHandle, const iMeshP_Part,
01272                         const iBase_EntityHandle, iMeshP_RequestHandle*, int* err )
01273 {
01274     FIXME;
01275     RETURN( iBase_NOT_SUPPORTED );
01276 }
01277 
01278 void iMeshP_rmvGhostOf( iMesh_Instance instance, const iMeshP_PartitionHandle, const iMeshP_Part,
01279                         const iBase_EntityHandle, int* err )
01280 {
01281     FIXME;
01282     RETURN( iBase_NOT_SUPPORTED );
01283 }
01284 
01285 void iMeshP_syncMeshAll( iMesh_Instance instance, const iMeshP_PartitionHandle partition_handle, int* err )
01286 {
01287     ParallelComm* pcomm = PCOMM;
01288     ErrorCode rval      = pcomm->resolve_shared_ents( itaps_cast< EntityHandle >( partition_handle ), -1, -1 );CHKERR( rval, "update failed" );
01289     RETURN( iBase_SUCCESS );
01290 }
01291 
01292 void iMeshP_pushTags( iMesh_Instance instance, const iMeshP_PartitionHandle partition_handle,
01293                       iBase_TagHandle source_tag, iBase_TagHandle dest_tag, int entity_type, int entity_topo, int* err )
01294 {
01295     ParallelComm* pcomm = PCOMM;
01296     DimensionPair types;
01297     if( entity_topo != iMesh_ALL_TOPOLOGIES )
01298         types.first = types.second = mb_topology_table[entity_topo];
01299     else if( entity_type != iBase_ALL_TYPES )
01300         // types = CN::TypeDimensionMap[entity_type];
01301         types = CN::getDimPair( entity_type );
01302     else
01303     {
01304         types.first  = MBVERTEX;
01305         types.second = MBENTITYSET;
01306         --types.second;
01307     }
01308 
01309     std::vector< Tag > src_tags( 1, itaps_cast< Tag >( source_tag ) );
01310     std::vector< Tag > dst_tags( 1, itaps_cast< Tag >( dest_tag ) );
01311 
01312     ErrorCode rval;
01313     Range entities;
01314     for( EntityType t = types.first; t <= types.second; ++t )
01315     {
01316         rval = MOABI->get_entities_by_type_and_tag( 0, t, &src_tags[0], 0, 1, entities, Interface::UNION );CHKERR( rval, "error getting entities to push" );
01317     }
01318 
01319     rval = pcomm->exchange_tags( src_tags, dst_tags, entities );CHKERR( rval, "tag data communication failed" );
01320     RETURN( iBase_SUCCESS );
01321 }
01322 
01323 void iMeshP_pushTagsEnt( iMesh_Instance instance, const iMeshP_PartitionHandle partition_handle,
01324                          iBase_TagHandle source_tag, iBase_TagHandle dest_tag, const iBase_EntityHandle* entities,
01325                          int entities_size, int* err )
01326 {
01327 
01328     Range range;
01329     const EntityHandle* ents = itaps_cast< const EntityHandle* >( entities );
01330     std::copy( ents, ents + entities_size, range_inserter( range ) );
01331 
01332     std::vector< Tag > src_tags( 1, itaps_cast< Tag >( source_tag ) );
01333     std::vector< Tag > dst_tags( 1, itaps_cast< Tag >( dest_tag ) );
01334     ParallelComm* pcomm = PCOMM;
01335     ErrorCode rval      = pcomm->exchange_tags( src_tags, dst_tags, range );CHKERR( rval, "tag data communication failed" );
01336     RETURN( iBase_SUCCESS );
01337 }
01338 
01339 void iMeshP_iPushTags( iMesh_Instance instance, const iMeshP_PartitionHandle, iBase_TagHandle, iBase_TagHandle, int,
01340                        int, iMeshP_RequestHandle*, int* err )
01341 {
01342     FIXME;
01343     RETURN( iBase_NOT_SUPPORTED );
01344 }
01345 
01346 void iMeshP_iPushTagsEnt( iMesh_Instance instance, const iMeshP_PartitionHandle, iBase_TagHandle, iBase_TagHandle,
01347                           const iBase_EntityHandle*, int, iMeshP_RequestHandle*, int* err )
01348 {
01349     FIXME;
01350     RETURN( iBase_NOT_SUPPORTED );
01351 }
01352 
01353 void iMeshP_createGhostEntsAll( iMesh_Instance instance, iMeshP_PartitionHandle partition_handle, int ghost_dim,
01354                                 int bridge_dim, int num_layers, int include_copies, int* err )
01355 {
01356     if( include_copies )
01357     {
01358         FIXME;
01359         RETURN( iBase_NOT_SUPPORTED );
01360     }
01361 
01362     ParallelComm* pcomm = PCOMM;
01363     ErrorCode rval;
01364     if( iBase_ALL_TYPES == ghost_dim ) ghost_dim = -1;
01365     rval = pcomm->exchange_ghost_cells( ghost_dim, bridge_dim, num_layers, 0, true );CHKERR( rval, "ghost exchange failed" );
01366     RETURN( iBase_SUCCESS );
01367 }
01368 
01369 void iMeshP_deleteGhostEntsAll( iMesh_Instance instance, iMeshP_PartitionHandle, int* err )
01370 {
01371     FIXME;
01372     RETURN( iBase_NOT_SUPPORTED );
01373 }
01374 
01375 void iMeshP_ghostEntInfo( const iMesh_Instance instance, const iMeshP_PartitionHandle, int*, int*, int**, int**, int**,
01376                           int* err )
01377 {
01378     FIXME;
01379     RETURN( iBase_NOT_SUPPORTED );
01380 }
01381 
01382 // append the specified option if it isn't already there; returns whether this
01383 // function actually appended it or not
01384 static bool append_option( std::string& opt, const char* option, const char* default_value = 0 )
01385 {
01386     std::string::size_type i;
01387 
01388     const char sep = ' ';
01389 
01390     if( strchr( option, sep ) || ( default_value && strchr( default_value, sep ) ) )
01391     {
01392         // options can't have a separator in them; XXX work around this
01393         return iBase_INVALID_ARGUMENT;
01394     }
01395 
01396     // search for the required option
01397     std::string search( &sep, 1 );
01398     search += option;
01399     const std::string::size_type sl = search.length();
01400     i                               = opt.find( search );
01401     while( i != std::string::npos )
01402     {
01403         std::string::size_type end = i + sl;
01404         if( end == opt.size() || opt[end] == sep || opt[end] == '=' ) break;
01405         i = end;
01406     }
01407 
01408     // if string already contained the option, just return
01409     if( i != std::string::npos ) return false;
01410 
01411     opt += search;
01412     if( default_value )
01413     {
01414         opt += "=";
01415         opt += default_value;
01416     }
01417 
01418     return true;
01419 }
01420 
01421 void iMeshP_loadAll( iMesh_Instance instance, const iMeshP_PartitionHandle partition,
01422                      const iBase_EntitySetHandle entity_set_handle, const char* name, const char* options, int* err,
01423                      int name_len, int options_len )
01424 {
01425     ErrorCode rval;
01426 
01427     // create partition set if user didn't give us one.
01428     EntityHandle partitioning;
01429     if( partition ) { partitioning = itaps_cast< EntityHandle >( partition ); }
01430     else
01431     {
01432         rval = MOABI->create_meshset( MESHSET_SET, partitioning );CHKERR( rval, "failed to create meshset" );
01433     }
01434 
01435     // get ParallelComm for partition
01436     MPI_Comm default_comm = MPI_COMM_WORLD;
01437     ParallelComm* pcomm   = ParallelComm::get_pcomm( MOABI, partitioning, &default_comm );
01438     if( !pcomm ) { RETURN( iBase_FAILURE ); }
01439 
01440     // add necessary values to options string
01441     std::string opt = std::string( options, options + options_len );
01442 
01443     if( append_option( opt, "moab:PARALLEL" ) )
01444     {
01445         // only append these other ones if the parallel option wasn't there originally
01446         append_option( opt, "moab:PARTITION_DISTRIBUTE" );
01447         append_option( opt, "moab:PARALLEL_RESOLVE_SHARED_ENTS" );
01448         std::ostringstream id;
01449         id << pcomm->get_id();
01450         append_option( opt, "moab:PCOMM", id.str().c_str() );
01451     }
01452 
01453     // load the file
01454     iMesh_load( instance, entity_set_handle, name, opt.c_str(), err, name_len, opt.length() );
01455     if( *err ) return;
01456 
01457     rval = pcomm->collective_sync_partition();CHKERR( rval, "collective sync failed" );
01458     RETURN( iBase_SUCCESS );
01459 }
01460 
01461 void iMeshP_saveAll( iMesh_Instance instance, const iMeshP_PartitionHandle partition,
01462                      const iBase_EntitySetHandle entity_set_handle, const char* name, const char* options, int* err,
01463                      const int name_len, int options_len )
01464 {
01465     EntityHandle set;
01466     set = entity_set_handle ? itaps_cast< EntityHandle >( entity_set_handle ) : itaps_cast< EntityHandle >( partition );
01467     iMesh_save( instance, itaps_cast< iBase_EntitySetHandle >( set ), name, options, err, name_len, options_len );
01468 }
01469 
01470 //  Map from processes to parts:
01471 //  Given a partition handle and a process rank,
01472 //  return the part handles owned by the process.
01473 //  COMMUNICATION:  None++.
01474 void iMeshP_getPartsOnRank( iMesh_Instance instance, const iMeshP_PartitionHandle partition_handle,
01475                             /*in*/ const int /*rank*/,
01476                             /*inout*/ iMeshP_PartHandle** part_handles,
01477                             /*inout*/ int* part_handles_allocated,
01478                             /*out*/ int* part_handles_size, int* err )
01479 {
01480     EntityHandle p   = itaps_cast< EntityHandle >( partition_handle );
01481     ParallelComm* pc = ParallelComm::get_pcomm( MOABI, p );
01482     if( !pc ) RETURN( iBase_ERROR_MAP[MB_FAILURE] );
01483 
01484     Range part_sets;
01485 
01486     ALLOC_CHECK_ARRAY_NOFAIL( part_handles, pc->partition_sets().size() );
01487     Range::iterator rit;
01488     int i;
01489     for( i = 0, rit = pc->partition_sets().begin(); rit != pc->partition_sets().end(); ++rit, i++ )
01490         ( *part_handles )[i] = itaps_cast< iMeshP_PartHandle >( *rit );
01491 
01492     RETURN( iBase_SUCCESS );
01493 }
01494 
01495 void iMeshP_getPartsArrOnRank( iMesh_Instance instance, const iMeshP_PartitionHandle partition_handle,
01496                                /*in*/ const int* rank,
01497                                /*in*/ const int rank_size,
01498                                /*inout*/ iMeshP_PartHandle** part_handles,
01499                                /*inout*/ int* part_handles_allocated,
01500                                /*out*/ int* part_handles_size, int* err )
01501 {
01502     EntityHandle p   = itaps_cast< EntityHandle >( partition_handle );
01503     ParallelComm* pc = ParallelComm::get_pcomm( MOABI, p );
01504     if( !pc ) RETURN( iBase_ERROR_MAP[MB_FAILURE] );
01505 
01506     if( rank[0] != (int)pc->proc_config().proc_rank() || rank_size > 1 )
01507     {
01508         RETURN( iBase_ERROR_MAP[MB_NOT_IMPLEMENTED] );
01509     }
01510 
01511     iMeshP_getPartsOnRank( instance, partition_handle, rank[0], part_handles, part_handles_allocated, part_handles_size,
01512                            err );
01513 }
01514 
01515 /** \brief Assign a global id space to entities
01516  * Assign a global id space to entities and vertices, and optionally intermediate-dimension entities
01517  *
01518  *  COMMUNICATION:  Collective.
01519  */
01520 void iMeshP_assignGlobalIds( iMesh_Instance instance, const iMeshP_PartitionHandle partition,
01521                              const iBase_EntitySetHandle this_set, const int dimension, const int start_id,
01522                              const int largest_dim_only, const int parallel, const int owned_only, int* err )
01523 {
01524     ErrorCode rval;
01525 
01526     // get partition set
01527     EntityHandle partitionset = itaps_cast< EntityHandle >( partition );
01528     if( !partitionset )
01529     {
01530         rval = MB_FAILURE;CHKERR( rval, "failed to get partition set" );
01531     }
01532 
01533     EntityHandle this_mb_set = itaps_cast< EntityHandle >( this_set );
01534 
01535     // get ParallelComm for partition
01536     MPI_Comm default_comm;
01537     ParallelComm* pcomm = ParallelComm::get_pcomm( MOABI, partitionset, &default_comm );
01538     if( !pcomm ) { RETURN( iBase_FAILURE ); }
01539 
01540     rval = pcomm->assign_global_ids( this_mb_set, dimension, start_id, largest_dim_only, parallel, owned_only );
01541 
01542     RETURN( rval );
01543 }
01544 
01545 void iMeshP_getCommunicator( iMesh_Instance instance, int* fcomm, MPI_Comm* ccomm, int* err )
01546 {
01547     *ccomm = MPI_Comm_f2c( *fcomm );
01548     RETURN( iBase_SUCCESS );
01549 }
01550 
01551 #ifdef __cplusplus
01552 }  // extern "C"
01553 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines