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