MOAB: Mesh Oriented datABase
(version 5.3.1)
|
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