moab
iMeshP_MOAB.cpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines