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 <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, 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