![]() |
Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
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
00018 #include
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 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::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,
00222 iMeshP_PartHandle set1,
00223 iBase_EntitySetHandle set2,
00224 int type,
00225 int topo,
00226 Range& result,
00227 int* err )
00228 {
00229 ErrorCode rval;
00230
00231 if( !set1 )
00232 {
00233 rval = get_entities( MOABI, itaps_cast< EntityHandle >( set2 ), type, topo, result );CHKERR( rval, "Invalid Part handle" );
00234 }
00235 else if( !set2 )
00236 {
00237 rval = get_entities( MOABI, itaps_cast< EntityHandle >( set1 ), type, topo, result );CHKERR( rval, "Invalid set handle" );
00238 }
00239 else
00240 {
00241 Range r1, r2;
00242 rval = get_entities( MOABI, itaps_cast< EntityHandle >( set1 ), type, topo, r1 );CHKERR( rval, "Invalid Part handle" );
00243 rval = get_entities( MOABI, itaps_cast< EntityHandle >( set2 ), type, topo, r2 );CHKERR( rval, "Invalid set handle" );
00244 result.merge( intersect( r1, r2 ) );
00245 }
00246
00247 RETURN( iBase_SUCCESS );
00248 }
00249
00250 /********************* Iterators **************************/
00251
00252 static ErrorCode get_boundary_entities( ParallelComm* pcomm,
00253 EntityHandle part_handle,
00254 int entity_type,
00255 int entity_topology,
00256 int adj_part_id,
00257 Range& entities_out )
00258 {
00259 int* adj_part_id_ptr = ( adj_part_id == iMeshP_ALL_PARTS ) ? 0 : &adj_part_id;
00260
00261 Range iface_sets;
00262 ErrorCode rval = pcomm->get_interface_sets( part_handle, iface_sets, adj_part_id_ptr );
00263 if( MB_SUCCESS != rval ) return rval;
00264
00265 for( Range::iterator i = iface_sets.begin(); i != iface_sets.end(); ++i )
00266 {
00267 rval = get_entities( pcomm->get_moab(), *i, entity_type, entity_topology, entities_out );
00268 if( MB_SUCCESS != rval ) return rval;
00269 }
00270
00271 return MB_SUCCESS;
00272 }
00273
00274 class PartBoundaryIter : public MBRangeIter
00275 {
00276 private:
00277 ParallelComm* pComm;
00278 int adjPart;
00279
00280 public:
00281 inline PartBoundaryIter( ParallelComm* pcomm,
00282 EntityHandle part_handle,
00283 iBase_EntityType entity_type,
00284 iMesh_EntityTopology entity_topology,
00285 int adj_part_id,
00286 int array_sz )
00287 : MBRangeIter( entity_type, entity_topology, part_handle, array_sz ), pComm( pcomm ), adjPart( adj_part_id )
00288 {
00289 }
00290
00291 virtual ErrorCode reset( Interface* )
00292 {
00293 iterData.clear();
00294 ErrorCode result = get_boundary_entities( pComm, entSet, entType, entTopo, adjPart, iterData );
00295 iterPos = iterData.begin();
00296 return result;
00297 }
00298 };
00299
00300 template < class Container >
00301 class SetIntersectIter : public MBIter< Container >
00302 {
00303 private:
00304 EntityHandle otherSet;
00305
00306 public:
00307 SetIntersectIter( iBase_EntityType type,
00308 iMesh_EntityTopology topology,
00309 EntityHandle set,
00310 EntityHandle other_set,
00311 int array_sz )
00312 : MBIter< Container >( type, topology, set, array_sz ), otherSet( other_set )
00313 {
00314 }
00315 virtual ~SetIntersectIter() {}
00316
00317 inline ErrorCode intersect_with_set( Interface* mb, Range& range )
00318 {
00319 Range tmp;
00320 ErrorCode result;
00321 result = mb->get_entities_by_handle( otherSet, tmp );
00322 range = intersect( range, tmp );
00323 return result;
00324 }
00325
00326 inline ErrorCode intersect_with_set( Interface* mb, std::vector< EntityHandle >& list )
00327 {
00328 size_t w = 0;
00329 for( size_t r = 0; r < list.size(); ++r )
00330 {
00331 if( mb->contains_entities( otherSet, &list[r], 1 ) ) list[w++] = list[r];
00332 }
00333 list.resize( w );
00334 return MB_SUCCESS;
00335 }
00336
00337 virtual ErrorCode reset( Interface* mb )
00338 {
00339 ErrorCode result = MBIter< Container >::reset( mb );
00340 if( MB_SUCCESS != result ) return result;
00341
00342 result = intersect_with_set( mb, MBIter< Container >::iterData );
00343 MBIter< Container >::iterPos = MBIter< Container >::iterData.begin();
00344 return result;
00345 }
00346 };
00347
00348 /********************* iMeshP API **************************/
00349
00350 #ifdef __cplusplus
00351 extern "C" {
00352 #endif
00353
00354 void iMeshP_createPartitionAll( iMesh_Instance instance,
00355 /*in*/ MPI_Comm communicator,
00356 /*out*/ iMeshP_PartitionHandle* partition_handle,
00357 int* err )
00358 {
00359 *partition_handle = 0;
00360
00361 Tag prtn_tag;
00362 ErrorCode rval = MOABI->tag_get_handle( PARALLEL_PARTITIONING_TAG_NAME, 1, MB_TYPE_INTEGER, prtn_tag,
00363 MB_TAG_SPARSE | MB_TAG_CREAT );CHKERR( rval, "tag creation failed" );
00364
00365 EntityHandle handle;
00366 rval = MOABI->create_meshset( MESHSET_SET, handle );CHKERR( rval, "set creation failed" );
00367 ParallelComm* pcomm = ParallelComm::get_pcomm( MOABI, handle, &communicator );
00368 if( !pcomm )
00369 {
00370 MOABI->delete_entities( &handle, 1 );
00371 RETURN( iBase_FAILURE );
00372 }
00373
00374 // set the value of pcomm id, to the partitioning tag, although this is not used
00375 // we just need the tag to be set
00376 int pid = pcomm->get_id();
00377 rval = MOABI->tag_set_data( prtn_tag, &handle, 1, &pid );CHKERR( rval, "tag creation failed" );
00378
00379 *partition_handle = itaps_cast< iMeshP_PartitionHandle >( handle );
00380 RETURN( iBase_SUCCESS );
00381 }
00382
00383 void iMeshP_destroyPartitionAll( iMesh_Instance instance, iMeshP_PartitionHandle partition_handle, int* err )
00384 {
00385 ParallelComm* pcomm = PCOMM;
00386 if( pcomm ) delete pcomm;
00387 EntityHandle handle = itaps_cast< EntityHandle >( partition_handle );
00388 ErrorCode rval = MOABI->delete_entities( &handle, 1 );CHKERR( rval, "entity deletion failed" );
00389 RETURN( iBase_SUCCESS );
00390 }
00391
00392 void iMeshP_getPartIdFromPartHandle( iMesh_Instance instance,
00393 const iMeshP_PartitionHandle partition_handle,
00394 const iMeshP_PartHandle part_handle,
00395 iMeshP_Part* part_id,
00396 int* err )
00397 {
00398 int junk1 = 1, junk2;
00399 iMeshP_getPartIdsFromPartHandlesArr( instance, partition_handle, &part_handle, 1, &part_id, &junk1, &junk2, err );
00400 }
00401
00402 void iMeshP_getPartHandleFromPartId( iMesh_Instance instance,
00403 const iMeshP_PartitionHandle partition_handle,
00404 iMeshP_Part part_id,
00405 iMeshP_PartHandle* part_handle,
00406 int* err )
00407 {
00408 int junk1 = 1, junk2;
00409 iMeshP_getPartHandlesFromPartsIdsArr( instance, partition_handle, &part_id, 1, &part_handle, &junk1, &junk2, err );
00410 }
00411
00412 void iMeshP_getPartIdsFromPartHandlesArr( iMesh_Instance instance,
00413 const iMeshP_PartitionHandle partition_handle,
00414 const iMeshP_PartHandle* part_handles,
00415 const int part_handles_size,
00416 iMeshP_Part** part_ids,
00417 int* part_ids_allocated,
00418 int* part_ids_size,
00419 int* err )
00420 {
00421 ErrorCode rval;
00422 ParallelComm* pcomm = PCOMM;
00423 ALLOC_CHECK_ARRAY( part_ids, part_handles_size );
00424 for( int i = 0; i < part_handles_size; ++i )
00425 {
00426 int id;
00427 rval = pcomm->get_part_id( itaps_cast< EntityHandle >( part_handles[i] ), id );
00428 ( *part_ids )[i] = id;CHKERR( rval, "error getting part id" );
00429 }
00430 KEEP_ARRAY( part_ids );
00431 RETURN( iBase_SUCCESS );
00432 }
00433
00434 void iMeshP_getPartHandlesFromPartsIdsArr( iMesh_Instance instance,
00435 const iMeshP_PartitionHandle partition_handle,
00436 const iMeshP_Part* part_ids,
00437 const int part_ids_size,
00438 iMeshP_PartHandle** part_handles,
00439 int* part_handles_allocated,
00440 int* part_handles_size,
00441 int* err )
00442 {
00443 ErrorCode rval;
00444 ParallelComm* pcomm = PCOMM;
00445 ALLOC_CHECK_ARRAY( part_handles, part_ids_size );
00446 for( int i = 0; i < part_ids_size; ++i )
00447 {
00448 EntityHandle handle;
00449 rval = pcomm->get_part_handle( part_ids[i], handle );CHKERR( rval, "error getting part handle" );
00450 ( *part_handles )[i] = itaps_cast< iMeshP_PartHandle >( handle );
00451 }
00452 KEEP_ARRAY( part_handles );
00453 RETURN( iBase_SUCCESS );
00454 }
00455
00456 void iMeshP_getPartitionComm( iMesh_Instance instance,
00457 iMeshP_PartitionHandle partition_handle,
00458 MPI_Comm* communicator_out,
00459 int* err )
00460 {
00461 ParallelComm* pcomm = PCOMM;
00462 if( !pcomm ) RETURN( iBase_FAILURE );
00463 *communicator_out = pcomm->proc_config().proc_comm();
00464 RETURN( iBase_SUCCESS );
00465 }
00466
00467 void iMeshP_syncPartitionAll( iMesh_Instance instance, iMeshP_PartitionHandle partition_handle, int* err )
00468 {
00469 ParallelComm* pcomm = PCOMM;
00470 if( !pcomm ) ERROR( iBase_FAILURE, "No PComm" );
00471 ErrorCode rval = pcomm->collective_sync_partition();CHKERR( rval, "collective sync failed" );
00472 RETURN( iBase_SUCCESS );
00473 }
00474
00475 void iMeshP_getNumPartitions( iMesh_Instance instance, int* num_partitions_out, int* err )
00476 {
00477 std::vector< ParallelComm* > pcomms;
00478 ErrorCode rval = ParallelComm::get_all_pcomm( MOABI, pcomms );CHKERR( rval, "Internal error retreiving PComms" );
00479
00480 std::vector< ParallelComm* >::iterator i;
00481 *num_partitions_out = 0;
00482 for( i = pcomms.begin(); i != pcomms.end(); ++i )
00483 if( ( *i )->get_partitioning() ) ( *num_partitions_out )++;
00484
00485 RETURN( iBase_SUCCESS );
00486 }
00487
00488 void iMeshP_getPartitions( iMesh_Instance instance,
00489 iMeshP_PartitionHandle** partition_handle,
00490 int* partition_handle_allocated,
00491 int* partition_handle_size,
00492 int* err )
00493 {
00494 std::vector< ParallelComm* > pcomms;
00495 ErrorCode rval = ParallelComm::get_all_pcomm( MOABI, pcomms );CHKERR( rval, "Internal error retreiving PComms" );
00496
00497 std::vector< ParallelComm* >::iterator i;
00498 int count = 0;
00499 for( i = pcomms.begin(); i != pcomms.end(); ++i )
00500 if( ( *i )->get_partitioning() ) ++count;
00501 ALLOC_CHECK_ARRAY_NOFAIL( partition_handle, count );
00502
00503 *partition_handle_size = 0;
00504 for( i = pcomms.begin(); i != pcomms.end(); ++i )
00505 if( ( *i )->get_partitioning() )
00506 ( *partition_handle )[( *partition_handle_size )++] =
00507 itaps_cast< iMeshP_PartitionHandle >( ( *i )->get_partitioning() );
00508
00509 RETURN( iBase_SUCCESS );
00510 }
00511
00512 void iMeshP_getNumGlobalParts( iMesh_Instance instance,
00513 const iMeshP_PartitionHandle partition_handle,
00514 int* num_global_part,
00515 int* err )
00516 {
00517 ParallelComm* pcomm = PCOMM;
00518 if( !pcomm ) ERROR( iBase_FAILURE, "No PComm" );
00519
00520 ErrorCode rval = pcomm->get_global_part_count( *num_global_part );CHKERR( rval, "PComm::get_global_part_count failed" );
00521 RETURN( iBase_SUCCESS );
00522 }
00523
00524 void iMeshP_getNumLocalParts( iMesh_Instance instance,
00525 const iMeshP_PartitionHandle partition_handle,
00526 int* num_local_part,
00527 int* err )
00528 {
00529 ParallelComm* pcomm = PCOMM;
00530 if( !pcomm ) ERROR( iBase_FAILURE, "No PComm" );
00531
00532 *num_local_part = pcomm->partition_sets().size();
00533 RETURN( iBase_SUCCESS );
00534 }
00535
00536 void iMeshP_getLocalParts( iMesh_Instance instance,
00537 const iMeshP_PartitionHandle partition_handle,
00538 iMeshP_PartHandle** part_handles,
00539 int* part_handles_allocated,
00540 int* part_handles_size,
00541 int* err )
00542 {
00543 ParallelComm* pcomm = PCOMM;
00544 if( !pcomm ) ERROR( iBase_FAILURE, "No PComm" );
00545
00546 RANGE_TO_ITAPS_ARRAY( pcomm->partition_sets(), part_handles );
00547 RETURN( iBase_SUCCESS );
00548 }
00549
00550 void iMeshP_getRankOfPart( iMesh_Instance instance,
00551 const iMeshP_PartitionHandle partition_handle,
00552 const iMeshP_Part part_id,
00553 int* rank,
00554 int* err )
00555 {
00556 int junk1 = 1, junk2 = 1;
00557 iMeshP_getRankOfPartArr( instance, partition_handle, &part_id, 1, &rank, &junk1, &junk2, err );
00558 }
00559
00560 void iMeshP_getRankOfPartArr( iMesh_Instance instance,
00561 const iMeshP_PartitionHandle partition_handle,
00562 const iMeshP_Part* part_ids,
00563 const int part_ids_size,
00564 int** rank,
00565 int* rank_allocated,
00566 int* rank_size,
00567 int* err )
00568 {
00569 ParallelComm* pcomm = PCOMM;
00570 if( !pcomm ) ERROR( iBase_FAILURE, "No PComm" );
00571
00572 ALLOC_CHECK_ARRAY( rank, part_ids_size );
00573 ErrorCode rval = MB_SUCCESS;
00574 for( int i = 0; i < part_ids_size; ++i )
00575 {
00576 rval = pcomm->get_part_owner( part_ids[i], ( *rank )[i] );CHKERR( rval, "PComm::get_part_owner failed" );
00577 }
00578 KEEP_ARRAY( rank );
00579 RETURN( iBase_SUCCESS );
00580 }
00581
00582 void iMeshP_getNumOfTypeAll( iMesh_Instance instance,
00583 const iMeshP_PartitionHandle partition_handle,
00584 const iBase_EntitySetHandle entity_set_handle,
00585 const int entity_type,
00586 int* num_type,
00587 int* err )
00588 {
00589 ParallelComm* pcomm = PCOMM;
00590 if( !pcomm ) ERROR( iBase_FAILURE, "No PComm" );
00591
00592 Range entities;
00593 ErrorCode rval = get_entities( MOABI, itaps_cast< EntityHandle >( entity_set_handle ), entity_type,
00594 iMesh_ALL_TOPOLOGIES, entities );
00595 int count = 0;
00596 if( MB_SUCCESS == rval ) rval = count_owned( pcomm, entities, count );
00597
00598 int vals[2] = { count, rval }, sums[2];
00599 int ierr = MPI_Allreduce( vals, sums, 2, MPI_INT, MPI_SUM, pcomm->proc_config().proc_comm() );
00600 assert( iBase_SUCCESS == 0 );
00601 if( ierr || sums[1] ) RETURN( iBase_FAILURE );
00602
00603 *num_type = sums[0];
00604 RETURN( iBase_SUCCESS );
00605 }
00606
00607 void iMeshP_getNumOfTopoAll( iMesh_Instance instance,
00608 const iMeshP_PartitionHandle partition_handle,
00609 const iBase_EntitySetHandle entity_set_handle,
00610 const int entity_topology,
00611 int* num_topo,
00612 int* err )
00613 {
00614 ParallelComm* pcomm = PCOMM;
00615 if( !pcomm ) ERROR( iBase_FAILURE, "No PComm" );
00616
00617 Range entities;
00618 ErrorCode rval = get_entities( MOABI, itaps_cast< EntityHandle >( entity_set_handle ), iBase_ALL_TYPES,
00619 entity_topology, entities );
00620 int count = 0;
00621 if( MB_SUCCESS == rval ) rval = count_owned( pcomm, entities, count );
00622
00623 int vals[2] = { count, rval }, sums[2];
00624 int ierr = MPI_Allreduce( vals, sums, 2, MPI_INT, MPI_SUM, pcomm->proc_config().proc_comm() );
00625 assert( iBase_SUCCESS == 0 );
00626 if( ierr || sums[1] ) RETURN( iBase_FAILURE );
00627
00628 *num_topo = sums[0];
00629 RETURN( iBase_SUCCESS );
00630 }
00631
00632 void iMeshP_createPart( iMesh_Instance instance,
00633 iMeshP_PartitionHandle partition_handle,
00634 iMeshP_PartHandle* part_handle,
00635 int* err )
00636 {
00637 ParallelComm* pcomm = PCOMM;
00638 if( !pcomm ) ERROR( iBase_FAILURE, "No PComm" );
00639
00640 EntityHandle h;
00641 ErrorCode rval = pcomm->create_part( h );CHKERR( rval, "Part creation failed" );
00642 *part_handle = itaps_cast< iMeshP_PartHandle >( h );
00643 RETURN( iBase_SUCCESS );
00644 }
00645
00646 void iMeshP_destroyPart( iMesh_Instance instance,
00647 iMeshP_PartitionHandle partition_handle,
00648 iMeshP_PartHandle part_handle,
00649 int* err )
00650 {
00651 ParallelComm* pcomm = PCOMM;
00652 if( !pcomm ) ERROR( iBase_FAILURE, "No PComm" );
00653
00654 ErrorCode rval = pcomm->destroy_part( itaps_cast< EntityHandle >( part_handle ) );CHKERR( rval, "Part destruction failed" );
00655 RETURN( iBase_SUCCESS );
00656 }
00657
00658 void iMeshP_getNumPartNbors( iMesh_Instance instance,
00659 iMeshP_PartitionHandle partition_handle,
00660 iMeshP_PartHandle part_handle,
00661 int entity_type,
00662 int* num_part_nbors,
00663 int* err )
00664 {
00665 int junk1 = 1, junk2 = 1;
00666 iMeshP_getNumPartNborsArr( instance, partition_handle, &part_handle, 1, entity_type, &num_part_nbors, &junk1,
00667 &junk2, err );
00668 }
00669
00670 void iMeshP_getNumPartNborsArr( iMesh_Instance instance,
00671 const iMeshP_PartitionHandle partition_handle,
00672 const iMeshP_PartHandle* part_handles,
00673 const int part_handles_size,
00674 int /*entity_type*/,
00675 int** num_part_nbors,
00676 int* num_part_nbors_allocated,
00677 int* num_part_nbors_size,
00678 int* err )
00679 {
00680 ParallelComm* pcomm = PCOMM;
00681 if( !pcomm ) ERROR( iBase_FAILURE, "No PComm" );
00682
00683 ALLOC_CHECK_ARRAY( num_part_nbors, part_handles_size );
00684
00685 int n, neighbors[MAX_SHARING_PROCS];
00686 ErrorCode rval;
00687 for( int i = 0; i < part_handles_size; ++i )
00688 {
00689 EntityHandle h = itaps_cast< EntityHandle >( part_handles[i] );
00690 rval = pcomm->get_part_neighbor_ids( h, neighbors, n );CHKERR( rval, "error getting neighbor ids" );
00691 ( *num_part_nbors )[i] = n;
00692 }
00693
00694 KEEP_ARRAY( num_part_nbors );
00695 RETURN( iBase_SUCCESS );
00696 }
00697
00698 void iMeshP_getPartNbors( iMesh_Instance instance,
00699 const iMeshP_PartitionHandle partition_handle,
00700 const iMeshP_PartHandle part_handle,
00701 int entity_type,
00702 int* num_part_nbors,
00703 iMeshP_Part** nbor_part_ids,
00704 int* nbor_part_ids_allocated,
00705 int* nbor_part_ids_size,
00706 int* err )
00707 {
00708 int junk1 = 1, junk2 = 1;
00709 iMeshP_getPartNborsArr( instance, partition_handle, &part_handle, 1, entity_type, &num_part_nbors, &junk1, &junk2,
00710 nbor_part_ids, nbor_part_ids_allocated, nbor_part_ids_size, err );
00711 }
00712
00713 void iMeshP_getPartNborsArr( iMesh_Instance instance,
00714 const iMeshP_PartitionHandle partition_handle,
00715 const iMeshP_PartHandle* part_handles,
00716 const int part_handles_size,
00717 int /*entity_type*/,
00718 int** num_part_nbors,
00719 int* num_part_nbors_allocated,
00720 int* num_part_nbors_size,
00721 iMeshP_Part** nbor_part_ids,
00722 int* nbor_part_ids_allocated,
00723 int* nbor_part_ids_size,
00724 int* err )
00725 {
00726 ParallelComm* pcomm = PCOMM;
00727 if( !pcomm ) ERROR( iBase_FAILURE, "No PComm" );
00728
00729 ALLOC_CHECK_ARRAY( num_part_nbors, part_handles_size );
00730
00731 std::vector< int > all_neighbors;
00732 int n, pnbor[MAX_SHARING_PROCS];
00733 ErrorCode rval;
00734 for( int i = 0; i < part_handles_size; ++i )
00735 {
00736 EntityHandle h = itaps_cast< EntityHandle >( part_handles[i] );
00737 rval = pcomm->get_part_neighbor_ids( h, pnbor, n );CHKERR( rval, "error getting neighbor ids" );
00738 ( *num_part_nbors )[i] = n;
00739 std::copy( pnbor, pnbor + n, std::back_inserter( all_neighbors ) );
00740 }
00741
00742 ALLOC_CHECK_ARRAY_NOFAIL( nbor_part_ids, all_neighbors.size() );
00743 memcpy( *nbor_part_ids, &all_neighbors[0], sizeof( int ) * all_neighbors.size() );
00744
00745 KEEP_ARRAY( num_part_nbors );
00746 RETURN( iBase_SUCCESS );
00747 }
00748
00749 void iMeshP_getNumPartBdryEnts( iMesh_Instance instance,
00750 const iMeshP_PartitionHandle partition_handle,
00751 const iMeshP_PartHandle part_handle,
00752 const int entity_type,
00753 const int entity_topology,
00754 const iMeshP_Part target_part_id,
00755 int* num_entities,
00756 int* err )
00757 {
00758 Range entities;
00759 ErrorCode rval = get_boundary_entities( PCOMM, itaps_cast< EntityHandle >( part_handle ), entity_type,
00760 entity_topology, target_part_id, entities );CHKERR( rval, "failed to get boundary entities" );
00761 *num_entities = entities.size();
00762 RETURN( iBase_SUCCESS );
00763 }
00764
00765 void iMeshP_getPartBdryEnts( iMesh_Instance instance,
00766 const iMeshP_PartitionHandle partition_handle,
00767 const iMeshP_PartHandle part_handle,
00768 const int entity_type,
00769 const int entity_topology,
00770 const iMeshP_Part target_part_id,
00771 iBase_EntityHandle** entity_handles,
00772 int* entity_handles_allocated,
00773 int* entity_handles_size,
00774 int* err )
00775 {
00776 Range entities;
00777 ErrorCode rval = get_boundary_entities( PCOMM, itaps_cast< EntityHandle >( part_handle ), entity_type,
00778 entity_topology, target_part_id, entities );CHKERR( rval, "failed to get boundary entities" );
00779 RANGE_TO_ITAPS_ARRAY( entities, entity_handles );
00780 RETURN( iBase_SUCCESS );
00781 }
00782
00783 void iMeshP_initPartBdryEntIter( iMesh_Instance instance,
00784 const iMeshP_PartitionHandle partition_handle,
00785 const iMeshP_PartHandle part_handle,
00786 const int entity_type,
00787 const int entity_topology,
00788 const iMeshP_Part nbor_part_id,
00789 iBase_EntityIterator* entity_iterator,
00790 int* err )
00791 {
00792 iMeshP_initPartBdryEntArrIter( instance, partition_handle, part_handle, entity_type, entity_topology, 1,
00793 nbor_part_id, reinterpret_cast< iBase_EntityArrIterator* >( entity_iterator ), err );
00794 }
00795
00796 void iMeshP_initPartBdryEntArrIter( iMesh_Instance instance,
00797 const iMeshP_PartitionHandle partition_handle,
00798 const iMeshP_PartHandle part_handle,
00799 const int entity_type,
00800 const int entity_topology,
00801 const int array_size,
00802 const iMeshP_Part nbor_part_id,
00803 iBase_EntityArrIterator* entity_iterator,
00804 int* err )
00805 {
00806 *entity_iterator =
00807 new PartBoundaryIter( PCOMM, itaps_cast< EntityHandle >( part_handle ), (iBase_EntityType)entity_type,
00808 (iMesh_EntityTopology)entity_topology, nbor_part_id, array_size );
00809 ErrorCode result = ( *entity_iterator )->reset( MOABI );
00810 if( MB_SUCCESS != result ) delete *entity_iterator;CHKERR( result, "iMesh_initEntArrIter: ERROR getting entities of proper type or topology." );
00811 RETURN( iBase_SUCCESS );
00812 }
00813
00814 void iMeshP_getNumOfType( iMesh_Instance instance,
00815 const iMeshP_PartitionHandle,
00816 const iMeshP_PartHandle part_handle,
00817 const iBase_EntitySetHandle entity_set_handle,
00818 const int entity_type,
00819 int* num_type,
00820 int* err )
00821 {
00822 Range r;
00823 set_intersection_query( instance, part_handle, entity_set_handle, entity_type, iMesh_ALL_TOPOLOGIES, r, err );
00824 *num_type = r.size();
00825 }
00826
00827 void iMeshP_getNumOfTopo( iMesh_Instance instance,
00828 const iMeshP_PartitionHandle /*partition_handle*/,
00829 const iMeshP_PartHandle part_handle,
00830 const iBase_EntitySetHandle entity_set_handle,
00831 const int entity_topology,
00832 int* num_topo,
00833 int* err )
00834 {
00835 Range r;
00836 set_intersection_query( instance, part_handle, entity_set_handle, iBase_ALL_TYPES, entity_topology, r, err );
00837 *num_topo = r.size();
00838 }
00839
00840 void iMeshP_getAdjEntIndices( iMesh_Instance instance,
00841 iMeshP_PartitionHandle partition,
00842 iMeshP_PartHandle part,
00843 iBase_EntitySetHandle entity_set_handle,
00844 int entity_type_requestor,
00845 int entity_topology_requestor,
00846 int entity_type_requested,
00847 iBase_EntityHandle** entity_handles,
00848 int* entity_handles_allocated,
00849 int* entity_handles_size,
00850 iBase_EntityHandle** adj_entity_handles,
00851 int* adj_entity_handles_allocated,
00852 int* adj_entity_handles_size,
00853 int** adj_entity_indices,
00854 int* adj_entity_indices_allocated,
00855 int* adj_entity_indices_size,
00856 int** offset,
00857 int* offset_allocated,
00858 int* offset_size,
00859 int* err )
00860 {
00861 const int allocated_entity_handles = ( *entity_handles_allocated == 0 );
00862 const int allocated_indices = ( *adj_entity_indices_allocated == 0 );
00863 const int allocated_offset = ( *offset_allocated == 0 );
00864
00865 // get source entities
00866 iMeshP_getEntities( instance, partition, part, entity_set_handle, entity_type_requestor, entity_topology_requestor,
00867 entity_handles, entity_handles_allocated, entity_handles_size, err );
00868 if( iBase_SUCCESS != *err ) return;
00869
00870 // get adjacencies
00871 iBase_EntityHandle* all_adj_handles = 0;
00872 int size = 0, alloc = 0;
00873 iMesh_getEntArrAdj( instance, *entity_handles, *entity_handles_size, entity_type_requested, &all_adj_handles,
00874 &alloc, &size, offset, offset_allocated, offset_size, err );
00875 if( *err != iBase_SUCCESS )
00876 {
00877 if( allocated_entity_handles )
00878 {
00879 free( *entity_handles );
00880 *entity_handles = 0;
00881 *entity_handles_allocated = 0;
00882 }
00883 return;
00884 }
00885
00886 // allocate or check size of adj_entity_indices
00887 *adj_entity_indices_size = size;
00888 if( allocated_indices )
00889 {
00890 *adj_entity_indices = (int*)malloc( sizeof( iBase_EntityHandle ) * size );
00891 if( !*adj_entity_indices )
00892 *err = iBase_MEMORY_ALLOCATION_FAILED;
00893 else
00894 *adj_entity_indices_allocated = size;
00895 }
00896 else if( *adj_entity_indices_allocated < size )
00897 {
00898 *err = iBase_BAD_ARRAY_DIMENSION;
00899 }
00900 if( iBase_SUCCESS != *err )
00901 {
00902 free( all_adj_handles );
00903 if( allocated_entity_handles )
00904 {
00905 free( *entity_handles );
00906 *entity_handles = 0;
00907 *entity_handles_allocated = 0;
00908 }
00909 if( allocated_offset )
00910 {
00911 free( *offset );
00912 *offset = 0;
00913 *offset_allocated = 0;
00914 }
00915 return;
00916 }
00917
00918 // Now create an array of unique sorted handles from all_adj_handles.
00919 // We need to create a copy because we still need all_adj_handles. We
00920 // will eventually need to copy the resulting unique list into
00921 // adj_entity_handles, so if adj_entity_handles is already allocated and
00922 // of sufficient size, use it rather than allocating another temporary.
00923 iBase_EntityHandle* unique_adj = 0;
00924 if( *adj_entity_handles_allocated >= size )
00925 {
00926 unique_adj = *adj_entity_handles;
00927 }
00928 else
00929 {
00930 unique_adj = (iBase_EntityHandle*)malloc( sizeof( iBase_EntityHandle ) * size );
00931 }
00932 std::copy( all_adj_handles, all_adj_handles + size, unique_adj );
00933 std::sort( unique_adj, unique_adj + size );
00934 *adj_entity_handles_size = std::unique( unique_adj, unique_adj + size ) - unique_adj;
00935
00936 // If we created a temporary array for unique_adj rather than using
00937 // already allocated space in adj_entity_handles, allocate adj_entity_handles
00938 // and copy the unique handle list into it
00939 if( *adj_entity_handles != unique_adj )
00940 {
00941 if( !*adj_entity_handles_allocated )
00942 {
00943 *adj_entity_handles =
00944 (iBase_EntityHandle*)malloc( sizeof( iBase_EntityHandle ) * *adj_entity_handles_size );
00945 if( !*adj_entity_handles )
00946 *err = iBase_MEMORY_ALLOCATION_FAILED;
00947 else
00948 *adj_entity_handles_allocated = *adj_entity_handles_size;
00949 }
00950 else if( *adj_entity_handles_allocated < *adj_entity_handles_size )
00951 *err = iBase_BAD_ARRAY_DIMENSION;
00952 if( iBase_SUCCESS != *err )
00953 {
00954 free( unique_adj );
00955 free( all_adj_handles );
00956 if( allocated_entity_handles )
00957 {
00958 free( *entity_handles );
00959 *entity_handles = 0;
00960 *entity_handles_allocated = 0;
00961 }
00962 if( allocated_offset )
00963 {
00964 free( *offset );
00965 *offset = 0;
00966 *offset_allocated = 0;
00967 }
00968 if( allocated_indices )
00969 {
00970 free( *adj_entity_indices );
00971 *adj_entity_indices = 0;
00972 *adj_entity_indices_allocated = 0;
00973 }
00974 return;
00975 }
00976
00977 std::copy( unique_adj, unique_adj + *adj_entity_handles_size, *adj_entity_handles );
00978 free( unique_adj );
00979 unique_adj = *adj_entity_handles;
00980 }
00981
00982 // convert from adjacency list to indices into unique_adj
00983 for( int i = 0; i < *adj_entity_indices_size; ++i )
00984 ( *adj_entity_indices )[i] =
00985 std::lower_bound( unique_adj, unique_adj + *adj_entity_handles_size, all_adj_handles[i] ) - unique_adj;
00986 free( all_adj_handles );
00987 }
00988
00989 void iMeshP_getEntities( iMesh_Instance instance,
00990 const iMeshP_PartitionHandle,
00991 const iMeshP_PartHandle part_handle,
00992 const iBase_EntitySetHandle entity_set_handle,
00993 const int entity_type,
00994 const int entity_topology,
00995 iBase_EntityHandle** entity_handles,
00996 int* entity_handles_allocated,
00997 int* entity_handles_size,
00998 int* err )
00999 {
01000 Range r;
01001 set_intersection_query( instance, part_handle, entity_set_handle, entity_type, entity_topology, r, err );
01002 if( iBase_SUCCESS != *err ) return;
01003
01004 RANGE_TO_ITAPS_ARRAY( r, entity_handles );
01005 RETURN( iBase_SUCCESS );
01006 }
01007
01008 void iMeshP_getAdjEntities( iMesh_Instance instance,
01009 const iMeshP_PartitionHandle /*partition_handle*/,
01010 const iMeshP_PartHandle part_handle,
01011 const iBase_EntitySetHandle entity_set_handle,
01012 const int entity_type_requestor,
01013 const int entity_topology_requestor,
01014 const int entity_type_requested,
01015 iBase_EntityHandle** adj_entity_handles,
01016 int* adj_entity_handles_allocated,
01017 int* adj_entity_handles_size,
01018 int** offset,
01019 int* offset_allocated,
01020 int* offset_size,
01021 int** in_entity_set,
01022 int* in_entity_set_allocated,
01023 int* in_entity_set_size,
01024 int* err )
01025 {
01026 ErrorCode rval;
01027 Range r;
01028 set_intersection_query( instance, part_handle, entity_set_handle, entity_type_requestor, entity_topology_requestor,
01029 r, err );
01030 if( iBase_SUCCESS != *err ) return;
01031
01032 // count adjacencies
01033 std::vector< EntityHandle > tmp_storage;
01034 int num_adj = 0;
01035 int num_conn;
01036 const EntityHandle* conn_ptr;
01037 for( Range::iterator i = r.begin(); i != r.end(); ++i )
01038 {
01039 if( entity_type_requested || TYPE_FROM_HANDLE( *i ) == MBPOLYHEDRON )
01040 {
01041 tmp_storage.clear();
01042 rval = MOABI->get_adjacencies( &*i, 1, entity_type_requested, false, tmp_storage );CHKERR( rval, "get_adjacencies failed" );
01043 num_adj += tmp_storage.size();
01044 }
01045 else
01046 {
01047 rval = MOABI->get_connectivity( *i, conn_ptr, num_conn, false, &tmp_storage );CHKERR( rval, "get_connectivity failed" );
01048 num_adj += num_conn;
01049 }
01050 }
01051
01052 // get adjacencies
01053 ALLOC_CHECK_ARRAY( adj_entity_handles, num_adj );
01054 ALLOC_CHECK_ARRAY( offset, r.size() );
01055 int arr_pos = 0;
01056 int* offset_iter = *offset;
01057 for( Range::iterator i = r.begin(); i != r.end(); ++i )
01058 {
01059 *offset_iter = arr_pos;
01060 ++offset_iter;
01061
01062 tmp_storage.clear();
01063 rval = MOABI->get_adjacencies( &*i, 1, entity_type_requested, false, tmp_storage );CHKERR( rval, "get_adjacencies failed" );
01064 for( std::vector< EntityHandle >::iterator j = tmp_storage.begin(); j != tmp_storage.end(); ++j )
01065 {
01066 ( *adj_entity_handles )[arr_pos] = itaps_cast< iBase_EntityHandle >( *j );
01067 ++arr_pos;
01068 }
01069 }
01070
01071 // get in_entity_set
01072 iMesh_isEntArrContained( instance, entity_set_handle, *adj_entity_handles, *adj_entity_handles_size, in_entity_set,
01073 in_entity_set_allocated, in_entity_set_size, err );
01074
01075 if( iBase_SUCCESS == *err )
01076 {
01077 KEEP_ARRAY( adj_entity_handles );
01078 KEEP_ARRAY( offset );
01079 }
01080 }
01081
01082 void iMeshP_initEntIter( iMesh_Instance instance,
01083 const iMeshP_PartitionHandle partition_handle,
01084 const iMeshP_PartHandle part_handle,
01085 const iBase_EntitySetHandle entity_set_handle,
01086 const int requested_entity_type,
01087 const int requested_entity_topology,
01088 iBase_EntityIterator* entity_iterator,
01089 int* err )
01090 {
01091 iMeshP_initEntArrIter( instance, partition_handle, part_handle, entity_set_handle, requested_entity_type,
01092 requested_entity_topology, 1,
01093 reinterpret_cast< iBase_EntityArrIterator* >( entity_iterator ), err );
01094 }
01095
01096 void iMeshP_initEntArrIter( iMesh_Instance instance,
01097 const iMeshP_PartitionHandle /*partition_handle*/,
01098 const iMeshP_PartHandle part_handle,
01099 const iBase_EntitySetHandle entity_set_handle,
01100 const int requested_entity_type,
01101 const int requested_entity_topology,
01102 const int requested_array_size,
01103 iBase_EntityArrIterator* entArr_iterator,
01104 int* err )
01105 {
01106 if( !entity_set_handle || entity_set_handle == part_handle )
01107 {
01108 iMesh_initEntArrIter( instance, part_handle, requested_entity_type, requested_entity_topology,
01109 requested_array_size,
01110 0, // TODO: update this function for "resilient" arg
01111 entArr_iterator, err );
01112 }
01113 else
01114 {
01115 unsigned flags;
01116 ErrorCode result = MOABI->get_meshset_options( itaps_cast< EntityHandle >( entity_set_handle ), flags );CHKERR( result, "Invalid entity set handle" );
01117 if( flags & MESHSET_ORDERED )
01118 *entArr_iterator = new SetIntersectIter< std::vector< EntityHandle > >(
01119 (iBase_EntityType)requested_entity_type, (iMesh_EntityTopology)requested_entity_topology,
01120 itaps_cast< EntityHandle >( entity_set_handle ), itaps_cast< EntityHandle >( part_handle ),
01121 requested_array_size );
01122 else
01123 *entArr_iterator =
01124 new SetIntersectIter< Range >( (iBase_EntityType)requested_entity_type,
01125 (iMesh_EntityTopology)requested_entity_topology,
01126 itaps_cast< EntityHandle >( entity_set_handle ),
01127 itaps_cast< EntityHandle >( part_handle ), requested_array_size );
01128 result = ( *entArr_iterator )->reset( MOABI );
01129 if( MB_SUCCESS != result ) delete *entArr_iterator;CHKERR( result, "iMesh_initEntArrIter: ERROR getting entities of proper type or topology." );
01130 RETURN( iBase_SUCCESS );
01131 }
01132 }
01133
01134 void iMeshP_getEntOwnerPart( iMesh_Instance instance,
01135 const iMeshP_PartitionHandle partition_handle,
01136 const iBase_EntityHandle entity_handle,
01137 iMeshP_Part* part_id,
01138 int* err )
01139 {
01140 int junk1 = 1, junk2 = 1;
01141 iMeshP_getEntOwnerPartArr( instance, partition_handle, &entity_handle, 1, &part_id, &junk1, &junk2, err );
01142 }
01143
01144 void iMeshP_getEntOwnerPartArr( iMesh_Instance instance,
01145 const iMeshP_PartitionHandle partition_handle,
01146 const iBase_EntityHandle* entity_handles,
01147 const int entity_handles_size,
01148 iMeshP_Part** part_ids,
01149 int* part_ids_allocated,
01150 int* part_ids_size,
01151 int* err )
01152 {
01153 ParallelComm* pcomm = PCOMM;
01154 if( !pcomm ) ERROR( iBase_FAILURE, "No PComm" );
01155
01156 int id;
01157 ALLOC_CHECK_ARRAY( part_ids, entity_handles_size );
01158 ErrorCode rval = MB_SUCCESS;
01159 for( int i = 0; i < entity_handles_size; ++i )
01160 {
01161 EntityHandle h = itaps_cast< EntityHandle >( entity_handles[i] );
01162 rval = pcomm->get_owning_part( h, id );
01163 ( *part_ids )[i] = id;CHKERR( rval, "Failet get part owner" );
01164 }
01165 KEEP_ARRAY( part_ids );
01166 RETURN( iBase_SUCCESS );
01167 }
01168
01169 void iMeshP_isEntOwner( iMesh_Instance instance,
01170 const iMeshP_PartitionHandle partition_handle,
01171 const iMeshP_PartHandle part_handle,
01172 const iBase_EntityHandle entity_handle,
01173 int* is_owner,
01174 int* err )
01175 {
01176 int junk1 = 1, junk2 = 1;
01177 iMeshP_isEntOwnerArr( instance, partition_handle, part_handle, &entity_handle, 1, &is_owner, &junk1, &junk2, err );
01178 }
01179
01180 void iMeshP_isEntOwnerArr( iMesh_Instance instance,
01181 const iMeshP_PartitionHandle partition_handle,
01182 const iMeshP_PartHandle part_handle,
01183 const iBase_EntityHandle* entity_handles,
01184 const int entity_handles_size,
01185 int** is_owner,
01186 int* is_owner_allocated,
01187 int* is_owner_size,
01188 int* err )
01189 {
01190 ErrorCode rval;
01191 ParallelComm* pcomm = PCOMM;
01192 if( !pcomm ) ERROR( iBase_FAILURE, "No PComm" );
01193
01194 int id;
01195 rval = pcomm->get_part_id( itaps_cast< EntityHandle >( part_handle ), id );CHKERR( rval, "error getting part id" );
01196
01197 ALLOC_CHECK_ARRAY( is_owner, entity_handles_size );
01198 *is_owner_size = entity_handles_size;
01199
01200 int owner;
01201 for( int i = 0; i < entity_handles_size; ++i )
01202 {
01203 rval = pcomm->get_owner( itaps_cast< EntityHandle >( entity_handles[i] ), owner );CHKERR( rval, "error getting owner" );
01204 ( *is_owner )[i] = ( owner == id );
01205 }
01206
01207 KEEP_ARRAY( is_owner );
01208 RETURN( iBase_SUCCESS );
01209 }
01210
01211 void iMeshP_getEntStatus( iMesh_Instance instance,
01212 /*in*/ const iMeshP_PartitionHandle partition_handle,
01213 /*in*/ const iMeshP_PartHandle part_handle,
01214 /*in*/ const iBase_EntityHandle entity_handle,
01215 /*out*/ int* par_status, // Values=INTERNAL,BOUNDARY,GHOST
01216 int* err )
01217 {
01218 int junk1 = 1, junk2 = 1;
01219 iMeshP_getEntStatusArr( instance, partition_handle, part_handle, &entity_handle, 1, &par_status, &junk1, &junk2,
01220 err );
01221 }
01222
01223 void iMeshP_getEntStatusArr( iMesh_Instance instance,
01224 /*in*/ const iMeshP_PartitionHandle partition_handle,
01225 /*in*/ const iMeshP_PartHandle /*part_handle*/,
01226 /*in*/ const iBase_EntityHandle* entity_handles,
01227 /*in*/ const int entity_handles_size,
01228 /*inout*/ int** par_status, // Values=INTERNAL,BOUNDARY,GHOST
01229 /*inout*/ int* par_status_allocated,
01230 /*inout*/ int* par_status_size,
01231 int* err )
01232 {
01233 ParallelComm* pcomm = PCOMM;
01234 if( !pcomm ) ERROR( iBase_FAILURE, "No PComm" );
01235
01236 std::vector< unsigned char > pstatus( entity_handles_size );
01237 ErrorCode result = MOABI->tag_get_data( pcomm->pstatus_tag(), itaps_cast< const EntityHandle* >( entity_handles ),
01238 entity_handles_size, &pstatus[0] );CHKERR( result, "error getting pstatus_tag" );
01239
01240 ALLOC_CHECK_ARRAY( par_status, entity_handles_size );
01241 for( int i = 0; i < entity_handles_size; i++ )
01242 {
01243 if( !pstatus[i] )
01244 ( *par_status )[i] = iMeshP_INTERNAL;
01245 else if( pstatus[i] & PSTATUS_GHOST )
01246 ( *par_status )[i] = iMeshP_GHOST;
01247 else if( pstatus[i] & PSTATUS_INTERFACE )
01248 ( *par_status )[i] = iMeshP_BOUNDARY;
01249 }
01250
01251 KEEP_ARRAY( par_status );
01252 RETURN( iBase_SUCCESS );
01253 }
01254
01255 void iMeshP_getNumCopies( iMesh_Instance instance,
01256 const iMeshP_PartitionHandle partition_handle,
01257 const iBase_EntityHandle entity_handle,
01258 int* num_copies_ent,
01259 int* err )
01260 {
01261 ParallelComm* pcomm = PCOMM;
01262 if( !pcomm ) ERROR( iBase_FAILURE, "No PComm" );
01263
01264 int ids[MAX_SHARING_PROCS];
01265 ErrorCode rval = pcomm->get_sharing_parts( itaps_cast< EntityHandle >( entity_handle ), ids, *num_copies_ent );CHKERR( rval, "ParallelComm::get_sharing_parts failed" );
01266 RETURN( iBase_SUCCESS );
01267 }
01268
01269 void iMeshP_getCopyParts( iMesh_Instance instance,
01270 const iMeshP_PartitionHandle partition_handle,
01271 const iBase_EntityHandle entity_handle,
01272 iMeshP_Part** part_ids,
01273 int* part_ids_allocated,
01274 int* part_ids_size,
01275 int* err )
01276 {
01277 ParallelComm* pcomm = PCOMM;
01278 if( !pcomm ) ERROR( iBase_FAILURE, "No PComm" );
01279
01280 int ids[MAX_SHARING_PROCS], num_ids;
01281 ErrorCode rval = pcomm->get_sharing_parts( itaps_cast< EntityHandle >( entity_handle ), ids, num_ids );CHKERR( rval, "ParallelComm::get_sharing_parts failed" );
01282 ALLOC_CHECK_ARRAY_NOFAIL( part_ids, num_ids );
01283 std::copy( ids, ids + num_ids, *part_ids );
01284 RETURN( iBase_SUCCESS );
01285 }
01286
01287 void iMeshP_getCopies( iMesh_Instance instance,
01288 const iMeshP_PartitionHandle partition_handle,
01289 const iBase_EntityHandle entity_handle,
01290 iMeshP_Part** part_ids,
01291 int* part_ids_allocated,
01292 int* part_ids_size,
01293 iBase_EntityHandle** copies_entity_handles,
01294 int* copies_entity_handles_allocated,
01295 int* copies_entity_handles_size,
01296 int* err )
01297 {
01298 ParallelComm* pcomm = PCOMM;
01299 if( !pcomm ) ERROR( iBase_FAILURE, "No PComm" );
01300
01301 int ids[MAX_SHARING_PROCS], num_ids;
01302 EntityHandle handles[MAX_SHARING_PROCS];
01303 ErrorCode rval = pcomm->get_sharing_parts( itaps_cast< EntityHandle >( entity_handle ), ids, num_ids, handles );CHKERR( rval, "ParallelComm::get_sharing_parts failed" );
01304 ALLOC_CHECK_ARRAY_NOFAIL( part_ids, num_ids );
01305 ALLOC_CHECK_ARRAY_NOFAIL( copies_entity_handles, num_ids );
01306 for( int i = 0; i < num_ids; ++i )
01307 {
01308 ( *part_ids )[i] = ids[i];
01309 ( *copies_entity_handles )[i] = itaps_cast< iBase_EntityHandle >( handles[i] );
01310 }
01311 RETURN( iBase_SUCCESS );
01312 }
01313
01314 void iMeshP_getCopyOnPart( iMesh_Instance instance,
01315 const iMeshP_PartitionHandle partition_handle,
01316 const iBase_EntityHandle entity_handle,
01317 const iMeshP_Part part_id,
01318 iBase_EntityHandle* copy_entity_handle,
01319 int* err )
01320 {
01321 ParallelComm* pcomm = PCOMM;
01322 if( !pcomm ) ERROR( iBase_FAILURE, "No PComm" );
01323
01324 int ids[MAX_SHARING_PROCS], num_ids;
01325 EntityHandle handles[MAX_SHARING_PROCS];
01326 ErrorCode rval = pcomm->get_sharing_parts( itaps_cast< EntityHandle >( entity_handle ), ids, num_ids, handles );CHKERR( rval, "ParallelComm::get_sharing_parts failed" );
01327 int idx = std::find( ids, ids + num_ids, part_id ) - ids;
01328 if( idx == num_ids ) RETURN( iBase_FAILURE );
01329
01330 *copy_entity_handle = itaps_cast< iBase_EntityHandle >( handles[idx] );
01331 RETURN( iBase_SUCCESS );
01332 }
01333
01334 void iMeshP_getOwnerCopy( iMesh_Instance instance,
01335 const iMeshP_PartitionHandle partition_handle,
01336 const iBase_EntityHandle entity_handle,
01337 iMeshP_Part* owner_part_id,
01338 iBase_EntityHandle* owner_entity_handle,
01339 int* err )
01340 {
01341 ParallelComm* pcomm = PCOMM;
01342 if( !pcomm ) ERROR( iBase_FAILURE, "No PComm" );
01343
01344 int id;
01345 EntityHandle h;
01346 ErrorCode rval = pcomm->get_owning_part( itaps_cast< EntityHandle >( entity_handle ), id, &h );CHKERR( rval, "Failed to get owner" );
01347 *owner_part_id = id;
01348 *owner_entity_handle = itaps_cast< iBase_EntityHandle >( h );
01349 RETURN( iBase_SUCCESS );
01350 }
01351
01352 void iMeshP_waitForAnyRequest( iMesh_Instance instance,
01353 iMeshP_PartitionHandle,
01354 iMeshP_RequestHandle*,
01355 int,
01356 int*,
01357 int* err )
01358 {
01359 FIXME;
01360 RETURN( iBase_NOT_SUPPORTED );
01361 }
01362
01363 void iMeshP_waitForAllRequests( iMesh_Instance instance, iMeshP_PartitionHandle, iMeshP_RequestHandle*, int, int* err )
01364 {
01365 FIXME;
01366 RETURN( iBase_NOT_SUPPORTED );
01367 }
01368
01369 void iMeshP_waitForRequestEnt( iMesh_Instance instance,
01370 const iMeshP_PartitionHandle,
01371 iMeshP_RequestHandle,
01372 iBase_EntityHandle**,
01373 int*,
01374 int*,
01375 int* err )
01376 {
01377 FIXME;
01378 RETURN( iBase_NOT_SUPPORTED );
01379 }
01380
01381 void iMeshP_testRequest( iMesh_Instance instance, const iMeshP_PartitionHandle, iMeshP_RequestHandle, int*, int* err )
01382 {
01383 FIXME;
01384 RETURN( iBase_NOT_SUPPORTED );
01385 }
01386
01387 void iMeshP_pollForRequests( iMesh_Instance instance,
01388 iMeshP_PartitionHandle,
01389 iMeshP_RequestHandle**,
01390 int*,
01391 int*,
01392 int* err )
01393 {
01394 FIXME;
01395 RETURN( iBase_NOT_SUPPORTED );
01396 }
01397
01398 void iMeshP_exchEntArrToPartsAll( iMesh_Instance instance,
01399 const iMeshP_PartitionHandle partition_handle,
01400 const iBase_EntityHandle* entity_handles,
01401 const int entity_handles_size,
01402 const iMeshP_Part* target_part_ids,
01403 int command_code,
01404 int update_ghost,
01405 iMeshP_RequestHandle* /*request*/,
01406 int* err )
01407 {
01408 if( command_code == 1 )
01409 {
01410 std::cerr << "Entity migration option is not supported." << std::endl;
01411 RETURN( iBase_NOT_SUPPORTED );
01412 }
01413
01414 if( update_ghost == 1 )
01415 {
01416 std::cerr << "Gost update option is not supported." << std::endl;
01417 RETURN( iBase_NOT_SUPPORTED );
01418 }
01419
01420 // make exchange entity and processor list
01421 ErrorCode rval;
01422 ParallelComm* pcomm = PCOMM;
01423 std::vector< unsigned int > exchange_procs;
01424 std::vector< Range* > exchange_ents;
01425
01426 for( int i = 0; i < entity_handles_size; i++ )
01427 {
01428 int ind = -1;
01429 // iMeshP_Part target_p = target_part_ids[i];
01430 int target_p;
01431 rval = pcomm->get_part_owner( target_part_ids[i], target_p );CHKERR( rval, "ParallelComm::get_part_owner failed" );
01432
01433 std::vector< unsigned int >::iterator vit = std::find( exchange_procs.begin(), exchange_procs.end(), target_p );
01434 if( vit == exchange_procs.end() )
01435 {
01436 ind = exchange_procs.size();
01437 exchange_procs.push_back( target_p );
01438 exchange_ents.push_back( new Range );
01439 }
01440 else
01441 ind = vit - exchange_procs.begin();
01442
01443 exchange_ents[ind]->insert( itaps_cast< EntityHandle >( entity_handles[i] ) );
01444 }
01445
01446 std::vector< MPI_Request > recv_ent_reqs, recv_remoteh_reqs;
01447 rval = pcomm->exchange_owned_meshs( exchange_procs, exchange_ents, recv_ent_reqs, recv_remoteh_reqs, true );CHKERR( rval, "ParallelComm::exchange_owned_meshs failed" );
01448
01449 // delete exchange list
01450 std::vector< Range* >::iterator vit;
01451 for( vit = exchange_ents.begin(); vit != exchange_ents.end(); ++vit )
01452 delete( *vit );
01453
01454 RETURN( iBase_SUCCESS );
01455 }
01456
01457 void iMeshP_migrateEntity( iMesh_Instance instance,
01458 const iMeshP_PartitionHandle,
01459 const iMeshP_PartHandle,
01460 const iBase_EntityHandle,
01461 iMeshP_RequestHandle*,
01462 int* err )
01463 {
01464 FIXME;
01465 RETURN( iBase_NOT_SUPPORTED );
01466 }
01467
01468 void iMeshP_updateVtxCoords( iMesh_Instance instance, const iMeshP_PartitionHandle, const iBase_EntityHandle, int* err )
01469 {
01470 FIXME;
01471 RETURN( iBase_NOT_SUPPORTED );
01472 }
01473
01474 void iMeshP_replaceOnPartBdry( iMesh_Instance instance,
01475 const iMeshP_PartitionHandle,
01476 const iBase_EntityHandle*,
01477 const int,
01478 const iBase_EntityHandle*,
01479 const int,
01480 const int*,
01481 const int,
01482 int* err )
01483 {
01484 FIXME;
01485 RETURN( iBase_NOT_SUPPORTED );
01486 }
01487
01488 void iMeshP_addGhostOf( iMesh_Instance instance,
01489 const iMeshP_PartitionHandle,
01490 const iMeshP_Part,
01491 const iBase_EntityHandle,
01492 iMeshP_RequestHandle*,
01493 int* err )
01494 {
01495 FIXME;
01496 RETURN( iBase_NOT_SUPPORTED );
01497 }
01498
01499 void iMeshP_rmvGhostOf( iMesh_Instance instance,
01500 const iMeshP_PartitionHandle,
01501 const iMeshP_Part,
01502 const iBase_EntityHandle,
01503 int* err )
01504 {
01505 FIXME;
01506 RETURN( iBase_NOT_SUPPORTED );
01507 }
01508
01509 void iMeshP_syncMeshAll( iMesh_Instance instance, const iMeshP_PartitionHandle partition_handle, int* err )
01510 {
01511 ParallelComm* pcomm = PCOMM;
01512 ErrorCode rval = pcomm->resolve_shared_ents( itaps_cast< EntityHandle >( partition_handle ), -1, -1 );CHKERR( rval, "update failed" );
01513 RETURN( iBase_SUCCESS );
01514 }
01515
01516 void iMeshP_pushTags( iMesh_Instance instance,
01517 const iMeshP_PartitionHandle partition_handle,
01518 iBase_TagHandle source_tag,
01519 iBase_TagHandle dest_tag,
01520 int entity_type,
01521 int entity_topo,
01522 int* err )
01523 {
01524 ParallelComm* pcomm = PCOMM;
01525 DimensionPair types;
01526 if( entity_topo != iMesh_ALL_TOPOLOGIES )
01527 types.first = types.second = mb_topology_table[entity_topo];
01528 else if( entity_type != iBase_ALL_TYPES )
01529 // types = CN::TypeDimensionMap[entity_type];
01530 types = CN::getDimPair( entity_type );
01531 else
01532 {
01533 types.first = MBVERTEX;
01534 types.second = MBENTITYSET;
01535 --types.second;
01536 }
01537
01538 std::vector< Tag > src_tags( 1, itaps_cast< Tag >( source_tag ) );
01539 std::vector< Tag > dst_tags( 1, itaps_cast< Tag >( dest_tag ) );
01540
01541 ErrorCode rval;
01542 Range entities;
01543 for( EntityType t = types.first; t <= types.second; ++t )
01544 {
01545 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" );
01546 }
01547
01548 rval = pcomm->exchange_tags( src_tags, dst_tags, entities );CHKERR( rval, "tag data communication failed" );
01549 RETURN( iBase_SUCCESS );
01550 }
01551
01552 void iMeshP_pushTagsEnt( iMesh_Instance instance,
01553 const iMeshP_PartitionHandle partition_handle,
01554 iBase_TagHandle source_tag,
01555 iBase_TagHandle dest_tag,
01556 const iBase_EntityHandle* entities,
01557 int entities_size,
01558 int* err )
01559 {
01560
01561 Range range;
01562 const EntityHandle* ents = itaps_cast< const EntityHandle* >( entities );
01563 std::copy( ents, ents + entities_size, range_inserter( range ) );
01564
01565 std::vector< Tag > src_tags( 1, itaps_cast< Tag >( source_tag ) );
01566 std::vector< Tag > dst_tags( 1, itaps_cast< Tag >( dest_tag ) );
01567 ParallelComm* pcomm = PCOMM;
01568 ErrorCode rval = pcomm->exchange_tags( src_tags, dst_tags, range );CHKERR( rval, "tag data communication failed" );
01569 RETURN( iBase_SUCCESS );
01570 }
01571
01572 void iMeshP_iPushTags( iMesh_Instance instance,
01573 const iMeshP_PartitionHandle,
01574 iBase_TagHandle,
01575 iBase_TagHandle,
01576 int,
01577 int,
01578 iMeshP_RequestHandle*,
01579 int* err )
01580 {
01581 FIXME;
01582 RETURN( iBase_NOT_SUPPORTED );
01583 }
01584
01585 void iMeshP_iPushTagsEnt( iMesh_Instance instance,
01586 const iMeshP_PartitionHandle,
01587 iBase_TagHandle,
01588 iBase_TagHandle,
01589 const iBase_EntityHandle*,
01590 int,
01591 iMeshP_RequestHandle*,
01592 int* err )
01593 {
01594 FIXME;
01595 RETURN( iBase_NOT_SUPPORTED );
01596 }
01597
01598 void iMeshP_createGhostEntsAll( iMesh_Instance instance,
01599 iMeshP_PartitionHandle partition_handle,
01600 int ghost_dim,
01601 int bridge_dim,
01602 int num_layers,
01603 int include_copies,
01604 int* err )
01605 {
01606 if( include_copies )
01607 {
01608 FIXME;
01609 RETURN( iBase_NOT_SUPPORTED );
01610 }
01611
01612 ParallelComm* pcomm = PCOMM;
01613 ErrorCode rval;
01614 if( iBase_ALL_TYPES == ghost_dim ) ghost_dim = -1;
01615 rval = pcomm->exchange_ghost_cells( ghost_dim, bridge_dim, num_layers, 0, true );CHKERR( rval, "ghost exchange failed" );
01616 RETURN( iBase_SUCCESS );
01617 }
01618
01619 void iMeshP_deleteGhostEntsAll( iMesh_Instance instance, iMeshP_PartitionHandle, int* err )
01620 {
01621 FIXME;
01622 RETURN( iBase_NOT_SUPPORTED );
01623 }
01624
01625 void iMeshP_ghostEntInfo( const iMesh_Instance instance,
01626 const iMeshP_PartitionHandle,
01627 int*,
01628 int*,
01629 int**,
01630 int**,
01631 int**,
01632 int* err )
01633 {
01634 FIXME;
01635 RETURN( iBase_NOT_SUPPORTED );
01636 }
01637
01638 // append the specified option if it isn't already there; returns whether this
01639 // function actually appended it or not
01640 static bool append_option( std::string& opt, const char* option, const char* default_value = 0 )
01641 {
01642 std::string::size_type i;
01643
01644 const char sep = ' ';
01645
01646 if( strchr( option, sep ) || ( default_value && strchr( default_value, sep ) ) )
01647 {
01648 // options can't have a separator in them; XXX work around this
01649 return false; // iBase_INVALID_ARGUMENT;
01650 }
01651
01652 // search for the required option
01653 std::string search( &sep, 1 );
01654 search += option;
01655 const std::string::size_type sl = search.length();
01656 i = opt.find( search );
01657 while( i != std::string::npos )
01658 {
01659 std::string::size_type end = i + sl;
01660 if( end == opt.size() || opt[end] == sep || opt[end] == '=' ) break;
01661 i = end;
01662 }
01663
01664 // if string already contained the option, just return
01665 if( i != std::string::npos ) return false;
01666
01667 opt += search;
01668 if( default_value )
01669 {
01670 opt += "=";
01671 opt += default_value;
01672 }
01673
01674 return true;
01675 }
01676
01677 void iMeshP_loadAll( iMesh_Instance instance,
01678 const iMeshP_PartitionHandle partition,
01679 const iBase_EntitySetHandle entity_set_handle,
01680 const char* name,
01681 const char* options,
01682 int* err,
01683 int name_len,
01684 int options_len )
01685 {
01686 ErrorCode rval;
01687
01688 // create partition set if user didn't give us one.
01689 EntityHandle partitioning;
01690 if( partition )
01691 {
01692 partitioning = itaps_cast< EntityHandle >( partition );
01693 }
01694 else
01695 {
01696 rval = MOABI->create_meshset( MESHSET_SET, partitioning );CHKERR( rval, "failed to create meshset" );
01697 }
01698
01699 // get ParallelComm for partition
01700 MPI_Comm default_comm = MPI_COMM_WORLD;
01701 ParallelComm* pcomm = ParallelComm::get_pcomm( MOABI, partitioning, &default_comm );
01702 if( !pcomm )
01703 {
01704 RETURN( iBase_FAILURE );
01705 }
01706
01707 // add necessary values to options string
01708 std::string opt = std::string( options, options + options_len );
01709
01710 if( append_option( opt, "moab:PARALLEL" ) )
01711 {
01712 // only append these other ones if the parallel option wasn't there originally
01713 append_option( opt, "moab:PARTITION_DISTRIBUTE" );
01714 append_option( opt, "moab:PARALLEL_RESOLVE_SHARED_ENTS" );
01715 std::ostringstream id;
01716 id << pcomm->get_id();
01717 append_option( opt, "moab:PCOMM", id.str().c_str() );
01718 }
01719
01720 // load the file
01721 iMesh_load( instance, entity_set_handle, name, opt.c_str(), err, name_len, opt.length() );
01722 if( *err ) return;
01723
01724 rval = pcomm->collective_sync_partition();CHKERR( rval, "collective sync failed" );
01725 RETURN( iBase_SUCCESS );
01726 }
01727
01728 void iMeshP_saveAll( iMesh_Instance instance,
01729 const iMeshP_PartitionHandle partition,
01730 const iBase_EntitySetHandle entity_set_handle,
01731 const char* name,
01732 const char* options,
01733 int* err,
01734 const int name_len,
01735 int options_len )
01736 {
01737 EntityHandle set;
01738 set = entity_set_handle ? itaps_cast< EntityHandle >( entity_set_handle ) : itaps_cast< EntityHandle >( partition );
01739 iMesh_save( instance, itaps_cast< iBase_EntitySetHandle >( set ), name, options, err, name_len, options_len );
01740 }
01741
01742 // Map from processes to parts:
01743 // Given a partition handle and a process rank,
01744 // return the part handles owned by the process.
01745 // COMMUNICATION: None++.
01746 void iMeshP_getPartsOnRank( iMesh_Instance instance,
01747 const iMeshP_PartitionHandle partition_handle,
01748 /*in*/ const int /*rank*/,
01749 /*inout*/ iMeshP_PartHandle** part_handles,
01750 /*inout*/ int* part_handles_allocated,
01751 /*out*/ int* part_handles_size,
01752 int* err )
01753 {
01754 EntityHandle p = itaps_cast< EntityHandle >( partition_handle );
01755 ParallelComm* pc = ParallelComm::get_pcomm( MOABI, p );
01756 if( !pc ) RETURN( iBase_ERROR_MAP[MB_FAILURE] );
01757
01758 Range part_sets;
01759
01760 ALLOC_CHECK_ARRAY_NOFAIL( part_handles, pc->partition_sets().size() );
01761 Range::iterator rit;
01762 int i;
01763 for( i = 0, rit = pc->partition_sets().begin(); rit != pc->partition_sets().end(); ++rit, i++ )
01764 ( *part_handles )[i] = itaps_cast< iMeshP_PartHandle >( *rit );
01765
01766 RETURN( iBase_SUCCESS );
01767 }
01768
01769 void iMeshP_getPartsArrOnRank( iMesh_Instance instance,
01770 const iMeshP_PartitionHandle partition_handle,
01771 /*in*/ const int* rank,
01772 /*in*/ const int rank_size,
01773 /*inout*/ iMeshP_PartHandle** part_handles,
01774 /*inout*/ int* part_handles_allocated,
01775 /*out*/ int* part_handles_size,
01776 int* err )
01777 {
01778 EntityHandle p = itaps_cast< EntityHandle >( partition_handle );
01779 ParallelComm* pc = ParallelComm::get_pcomm( MOABI, p );
01780 if( !pc ) RETURN( iBase_ERROR_MAP[MB_FAILURE] );
01781
01782 if( rank[0] != (int)pc->proc_config().proc_rank() || rank_size > 1 )
01783 {
01784 RETURN( iBase_ERROR_MAP[MB_NOT_IMPLEMENTED] );
01785 }
01786
01787 iMeshP_getPartsOnRank( instance, partition_handle, rank[0], part_handles, part_handles_allocated, part_handles_size,
01788 err );
01789 }
01790
01791 /** \brief Assign a global id space to entities
01792 * Assign a global id space to entities and vertices, and optionally intermediate-dimension entities
01793 *
01794 * COMMUNICATION: Collective.
01795 */
01796 void iMeshP_assignGlobalIds( iMesh_Instance instance,
01797 const iMeshP_PartitionHandle partition,
01798 const iBase_EntitySetHandle this_set,
01799 const int dimension,
01800 const int start_id,
01801 const int largest_dim_only,
01802 const int parallel,
01803 const int owned_only,
01804 int* err )
01805 {
01806 ErrorCode rval;
01807
01808 // get partition set
01809 EntityHandle partitionset = itaps_cast< EntityHandle >( partition );
01810 if( !partitionset )
01811 {
01812 rval = MB_FAILURE;CHKERR( rval, "failed to get partition set" );
01813 }
01814
01815 EntityHandle this_mb_set = itaps_cast< EntityHandle >( this_set );
01816
01817 // get ParallelComm for partition
01818 MPI_Comm default_comm;
01819 ParallelComm* pcomm = ParallelComm::get_pcomm( MOABI, partitionset, &default_comm );
01820 if( !pcomm )
01821 {
01822 RETURN( iBase_FAILURE );
01823 }
01824
01825 rval = pcomm->assign_global_ids( this_mb_set, dimension, start_id, largest_dim_only, parallel, owned_only );
01826
01827 RETURN( rval );
01828 }
01829
01830 void iMeshP_getCommunicator( iMesh_Instance instance, int* fcomm, MPI_Comm* ccomm, int* err )
01831 {
01832 *ccomm = MPI_Comm_f2c( *fcomm );
01833 RETURN( iBase_SUCCESS );
01834 }
01835
01836 #ifdef __cplusplus
01837 } // extern "C"
01838 #endif