1 #include "moab/MOABConfig.h"
2 #include "iMeshP_extensions.h"
3 #include "iMesh_MOAB.hpp"
4 #include "moab/Core.hpp"
5 #include "moab/Range.hpp"
6 #include "moab/CN.hpp"
7 #include "moab/MeshTopoUtil.hpp"
8 #include "moab/FileOptions.hpp"
9 #include "moab/ParallelComm.hpp"
10 #include "MBParallelConventions.h"
11 #include "MBIter.hpp"
12
13 #define IS_BUILDING_MB
14 #include "Internals.hpp"
15 #undef IS_BUILDING_MB
16
17 #include <assert.h>
18 #include <sstream>
19
20 #ifdef MOAB_HAVE_MPI
21 #include "moab_mpi.h"
22 #endif
23
24 using namespace moab;
25
26
27 /********************* Error Handling **************************/
28
29 #define FIXME printf("Warning: function has incomplete implementation: %s\n", __func__ )
30
31
32
33 /******** Type-safe casting between MOAB and ITAPS types *********/
34
35 #ifndef MOAB_TEMPLATE_FUNC_SPECIALIZATION
36 // if no template specialization, disable some type checking
37 template <typename T, typename S> inline
itaps_cast(S handle)38 T itaps_cast( S handle )
39 {
40 assert(sizeof(S) >= sizeof(T));
41 return reinterpret_cast<T>(handle);
42 }
43 #else
44
45 // basic template method : only works to cast to equivalent types (no-op)
46 template <typename T, typename S> inline
itaps_cast(S h)47 T itaps_cast( S h )
48 { return h; }
49 // verify size and do reinterpret cast
itaps_cast_internal_(EntityHandle h)50 template <typename T> inline T itaps_cast_internal_( EntityHandle h )
51 {
52 assert(sizeof(T) >= sizeof(EntityHandle));
53 return reinterpret_cast<T>(h);
54 }
55 // verify size and do reinterpret cast
itaps_cast_ptr_(T * h)56 template <typename T> inline EntityHandle* itaps_cast_ptr_( T* h )
57 {
58 assert(sizeof(T) == sizeof(EntityHandle));
59 return reinterpret_cast<EntityHandle*>(h);
60 }
61 // verify size and do reinterpret cast
itaps_cast_const_ptr_(const T * h)62 template <typename T> inline const EntityHandle* itaps_cast_const_ptr_( const T* h )
63 {
64 assert(sizeof(T) == sizeof(EntityHandle));
65 return reinterpret_cast<const EntityHandle*>(h);
66 }
67 // verify set-type handle before cast
itaps_set_cast_(EntityHandle h)68 template <typename T> inline T itaps_set_cast_( EntityHandle h )
69 {
70 assert(TYPE_FROM_HANDLE(h) == MBENTITYSET);
71 return itaps_cast_internal_<T>(h);
72 }
73
74 // define conversion routines between itaps handle and EntityHandle types
75 #define DECLARE_ALLOWED_ITAPS_CONVERSION( ITAPS_HANDLE_TYPE ) \
76 template <> inline \
77 ITAPS_HANDLE_TYPE \
78 itaps_cast<ITAPS_HANDLE_TYPE,EntityHandle>( EntityHandle h ) \
79 { return itaps_cast_internal_<ITAPS_HANDLE_TYPE>(h); } \
80 \
81 template <> inline \
82 EntityHandle \
83 itaps_cast<EntityHandle,ITAPS_HANDLE_TYPE>( ITAPS_HANDLE_TYPE handle ) \
84 { return reinterpret_cast<EntityHandle>(handle); } \
85 \
86 template <> inline \
87 EntityHandle* \
88 itaps_cast<EntityHandle*,ITAPS_HANDLE_TYPE*>( ITAPS_HANDLE_TYPE* ptr ) \
89 { return itaps_cast_ptr_(ptr); } \
90 \
91 template <> inline \
92 const EntityHandle* \
93 itaps_cast<const EntityHandle*,const ITAPS_HANDLE_TYPE*>( const ITAPS_HANDLE_TYPE* ptr ) \
94 { return itaps_cast_const_ptr_(ptr); }
95
96
97 // define conversion routines between itaps handle and EntityHandle types
98 // but limit to EntityHandle for MBENTITYSET type.
99 #define DECLARE_ALLOWED_ITAPS_SET_CONVERSION( ITAPS_HANDLE_TYPE ) \
100 template <> inline \
101 ITAPS_HANDLE_TYPE \
102 itaps_cast<ITAPS_HANDLE_TYPE,EntityHandle>( EntityHandle h ) \
103 { return itaps_set_cast_<ITAPS_HANDLE_TYPE>(h); } \
104 \
105 template <> inline \
106 EntityHandle \
107 itaps_cast<EntityHandle,ITAPS_HANDLE_TYPE>( ITAPS_HANDLE_TYPE handle ) \
108 { return reinterpret_cast<EntityHandle>(handle); } \
109 \
110 template <> inline \
111 EntityHandle* \
112 itaps_cast<EntityHandle*,ITAPS_HANDLE_TYPE*>( ITAPS_HANDLE_TYPE* ptr ) \
113 { return itaps_cast_ptr_(ptr); } \
114 \
115 template <> inline \
116 const EntityHandle* \
117 itaps_cast<const EntityHandle*,const ITAPS_HANDLE_TYPE*>( const ITAPS_HANDLE_TYPE* ptr ) \
118 { return itaps_cast_const_ptr_(ptr); }
119
120 DECLARE_ALLOWED_ITAPS_SET_CONVERSION( iMeshP_PartitionHandle )
121 //DECLARE_ALLOWED_ITAPS_SET_CONVERSION( iMeshP_PartHandle )
DECLARE_ALLOWED_ITAPS_SET_CONVERSION(iBase_EntitySetHandle)122 DECLARE_ALLOWED_ITAPS_SET_CONVERSION( iBase_EntitySetHandle )
123 DECLARE_ALLOWED_ITAPS_CONVERSION( iBase_EntityHandle )
124
125
126 template <> inline
127 Tag itaps_cast<Tag,iBase_TagHandle>( iBase_TagHandle h )
128 { return reinterpret_cast<Tag>(h); }
129 template <> inline
itaps_cast(Tag h)130 iBase_TagHandle itaps_cast<iBase_TagHandle,Tag>( Tag h )
131 { return reinterpret_cast<iBase_TagHandle>(h); }
132
133
134 #endif
135
136 #define PCOMM ParallelComm::get_pcomm( MOABI, itaps_cast<EntityHandle>(partition_handle) )
137
138 /*** static function implemented in iMesh_MOAB.cpp ***/
139
140 // Need a different function name for Tag because (currently)
141 // both Tag and iBase_EntityHandle are void**.
itaps_tag_cast(Tag t)142 iBase_TagHandle itaps_tag_cast( Tag t )
143 {
144 assert(sizeof(iBase_TagHandle) >= sizeof(Tag));
145 return reinterpret_cast<iBase_TagHandle>(t);
146 }
147
148 /********************* ITAPS arrays **************************/
149
150 // Handle returning Range in ITAPS array (do ALLOCATE_ARRAY and copy).
151 #define RANGE_TO_ITAPS_ARRAY( RANGE, NAME ) do { \
152 ALLOC_CHECK_ARRAY_NOFAIL( NAME, (RANGE).size() ); \
153 std::copy( (RANGE).begin(), (RANGE).end(), itaps_cast<EntityHandle*>(*(NAME)) ); \
154 } while (false)
155
156
get_entities(Interface * iface,EntityHandle set,int type,int topology,Range & entities)157 static inline ErrorCode get_entities( Interface* iface,
158 EntityHandle set,
159 int type, int topology,
160 Range& entities )
161 {
162 if (topology != iMesh_ALL_TOPOLOGIES)
163 return iface->get_entities_by_type( set, mb_topology_table[topology], entities );
164 else if (type != iBase_ALL_TYPES)
165 return iface->get_entities_by_dimension( set, type, entities );
166 else
167 return iface->get_entities_by_handle( set, entities );
168 }
169
170 /*
171 static inline ErrorCode remove_not_owned( ParallelComm* pcomm, Range& ents )
172 {
173 ErrorCode rval;
174
175 std::vector<unsigned char> pstatus(ents.size());
176 rval = pcomm->get_moab()->tag_get_data(pcomm->pstatus_tag(), ents, &pstatus[0]);
177 if (MB_SUCCESS != rval)
178 return rval;
179
180 Range::iterator i = ents.begin();
181 std::vector<unsigned char>::const_iterator j;
182 for (j = pstatus.begin(); j != pstatus.end(); ++j) {
183 if (*j & PSTATUS_NOT_OWNED)
184 i = ents.erase( i );
185 else
186 ++i;
187 }
188
189 return MB_SUCCESS;
190 }
191 */
192
count_owned(ParallelComm * pcomm,const Range & ents,int & n)193 static inline ErrorCode count_owned( ParallelComm* pcomm, const Range& ents, int& n )
194 {
195 ErrorCode rval;
196 n = 0;
197
198 std::vector<unsigned char> pstatus(ents.size());
199 rval = pcomm->get_moab()->tag_get_data(pcomm->pstatus_tag(), ents, &pstatus[0]);
200 if (MB_SUCCESS != rval)
201 return rval;
202
203 std::vector<unsigned char>::const_iterator j;
204 for (j = pstatus.begin(); j != pstatus.end(); ++j)
205 if (!(*j & PSTATUS_NOT_OWNED))
206 ++n;
207
208 return MB_SUCCESS;
209 }
210
set_intersection_query(iMesh_Instance instance,iMeshP_PartHandle set1,iBase_EntitySetHandle set2,int type,int topo,Range & result,int * err)211 static void set_intersection_query( iMesh_Instance instance,
212 iMeshP_PartHandle set1,
213 iBase_EntitySetHandle set2,
214 int type,
215 int topo,
216 Range& result,
217 int* err )
218 {
219 ErrorCode rval;
220
221 if (!set1) {
222 rval = get_entities( MOABI, itaps_cast<EntityHandle>(set2), type, topo, result );
223 CHKERR(rval,"Invalid Part handle");
224 }
225 else if (!set2) {
226 rval = get_entities( MOABI, itaps_cast<EntityHandle>(set1), type, topo, result );
227 CHKERR(rval,"Invalid set handle");
228 }
229 else {
230 Range r1, r2;
231 rval = get_entities( MOABI, itaps_cast<EntityHandle>(set1), type, topo, r1 );
232 CHKERR(rval,"Invalid Part handle");
233 rval = get_entities( MOABI, itaps_cast<EntityHandle>(set2), type, topo, r2 );
234 CHKERR(rval,"Invalid set handle");
235 result.merge( intersect( r1, r2) );
236 }
237
238 RETURN (iBase_SUCCESS);
239 }
240
241 /********************* Iterators **************************/
242
get_boundary_entities(ParallelComm * pcomm,EntityHandle part_handle,int entity_type,int entity_topology,int adj_part_id,Range & entities_out)243 static ErrorCode get_boundary_entities( ParallelComm* pcomm,
244 EntityHandle part_handle,
245 int entity_type,
246 int entity_topology,
247 int adj_part_id,
248 Range& entities_out)
249 {
250 int* adj_part_id_ptr = (adj_part_id == iMeshP_ALL_PARTS) ? 0 : &adj_part_id;
251
252 Range iface_sets;
253 ErrorCode rval = pcomm->get_interface_sets( part_handle, iface_sets, adj_part_id_ptr );
254 if (MB_SUCCESS != rval)
255 return rval;
256
257 for (Range::iterator i = iface_sets.begin(); i != iface_sets.end(); ++i) {
258 rval = get_entities( pcomm->get_moab(), *i, entity_type, entity_topology, entities_out );
259 if (MB_SUCCESS != rval)
260 return rval;
261 }
262
263 return MB_SUCCESS;
264 }
265
266 class PartBoundaryIter : public MBRangeIter
267 {
268 private:
269 ParallelComm* pComm;
270 int adjPart;
271 public:
PartBoundaryIter(ParallelComm * pcomm,EntityHandle part_handle,iBase_EntityType entity_type,iMesh_EntityTopology entity_topology,int adj_part_id,int array_sz)272 inline PartBoundaryIter( ParallelComm* pcomm,
273 EntityHandle part_handle,
274 iBase_EntityType entity_type,
275 iMesh_EntityTopology entity_topology,
276 int adj_part_id,
277 int array_sz )
278 : MBRangeIter( entity_type, entity_topology,
279 part_handle, array_sz ),
280 pComm(pcomm), adjPart(adj_part_id)
281 {}
282
reset(Interface *)283 virtual ErrorCode reset( Interface* ) {
284 iterData.clear();
285 ErrorCode result = get_boundary_entities( pComm, entSet, entType, entTopo,
286 adjPart, iterData );
287 iterPos = iterData.begin();
288 return result;
289 }
290 };
291
292 template <class Container>
293 class SetIntersectIter : public MBIter<Container>
294 {
295 private:
296 EntityHandle otherSet;
297 public:
SetIntersectIter(iBase_EntityType type,iMesh_EntityTopology topology,EntityHandle set,EntityHandle other_set,int array_sz)298 SetIntersectIter( iBase_EntityType type,
299 iMesh_EntityTopology topology,
300 EntityHandle set,
301 EntityHandle other_set,
302 int array_sz )
303 : MBIter<Container>( type, topology, set, array_sz ),
304 otherSet( other_set )
305 {}
~SetIntersectIter()306 virtual ~SetIntersectIter() {}
307
intersect_with_set(Interface * mb,Range & range)308 inline ErrorCode intersect_with_set( Interface* mb, Range& range )
309 {
310 Range tmp;
311 ErrorCode result;
312 result = mb->get_entities_by_handle( otherSet, tmp );
313 range = intersect( range, tmp );
314 return result;
315 }
316
intersect_with_set(Interface * mb,std::vector<EntityHandle> & list)317 inline ErrorCode intersect_with_set( Interface* mb, std::vector<EntityHandle>& list )
318 {
319 size_t w = 0;
320 for (size_t r = 0; r < list.size(); ++r) {
321 if (mb->contains_entities( otherSet, &list[r], 1))
322 list[w++] = list[r];
323 }
324 list.resize(w);
325 return MB_SUCCESS;
326 }
327
reset(Interface * mb)328 virtual ErrorCode reset(Interface* mb)
329 {
330 ErrorCode result = MBIter<Container>::reset(mb);
331 if (MB_SUCCESS != result)
332 return result;
333
334 result = intersect_with_set( mb, MBIter<Container>::iterData );
335 MBIter<Container>::iterPos = MBIter<Container>::iterData.begin();
336 return result;
337 }
338 };
339
340
341
342 /********************* iMeshP API **************************/
343
344 #ifdef __cplusplus
345 extern "C" {
346 #endif
347
iMeshP_createPartitionAll(iMesh_Instance instance,MPI_Comm communicator,iMeshP_PartitionHandle * partition_handle,int * err)348 void iMeshP_createPartitionAll( iMesh_Instance instance,
349 /*in*/ MPI_Comm communicator,
350 /*out*/ iMeshP_PartitionHandle *partition_handle,
351 int *err )
352 {
353 *partition_handle = 0;
354
355 Tag prtn_tag;
356 ErrorCode rval = MOABI->tag_get_handle( PARALLEL_PARTITIONING_TAG_NAME,
357 1, MB_TYPE_INTEGER,
358 prtn_tag,
359 MB_TAG_SPARSE|MB_TAG_CREAT );
360 CHKERR(rval,"tag creation failed");
361
362 EntityHandle handle;
363 rval = MOABI->create_meshset( MESHSET_SET, handle ); CHKERR(rval,"set creation failed");
364 ParallelComm* pcomm = ParallelComm::get_pcomm( MOABI, handle, &communicator );
365 if (!pcomm) {
366 MOABI->delete_entities( &handle, 1 );
367 RETURN(iBase_FAILURE);
368 }
369
370 // set the value of pcomm id, to the partitioning tag, although this is not used
371 // we just need the tag to be set
372 int pid = pcomm->get_id();
373 rval = MOABI->tag_set_data(prtn_tag, &handle, 1, &pid);
374 CHKERR(rval,"tag creation failed");
375
376 *partition_handle = itaps_cast<iMeshP_PartitionHandle>(handle);
377 RETURN (iBase_SUCCESS);
378 }
379
iMeshP_destroyPartitionAll(iMesh_Instance instance,iMeshP_PartitionHandle partition_handle,int * err)380 void iMeshP_destroyPartitionAll( iMesh_Instance instance,
381 iMeshP_PartitionHandle partition_handle,
382 int *err)
383 {
384 ParallelComm* pcomm = PCOMM;
385 if (pcomm)
386 delete pcomm;
387 EntityHandle handle = itaps_cast<EntityHandle>(partition_handle);
388 ErrorCode rval = MOABI->delete_entities( &handle, 1 ); CHKERR(rval,"entity deletion failed");
389 RETURN (iBase_SUCCESS);
390 }
391
iMeshP_getPartIdFromPartHandle(iMesh_Instance instance,const iMeshP_PartitionHandle partition_handle,const iMeshP_PartHandle part_handle,iMeshP_Part * part_id,int * err)392 void iMeshP_getPartIdFromPartHandle( iMesh_Instance instance,
393 const iMeshP_PartitionHandle partition_handle,
394 const iMeshP_PartHandle part_handle,
395 iMeshP_Part *part_id,
396 int *err )
397 {
398 int junk1 = 1, junk2;
399 iMeshP_getPartIdsFromPartHandlesArr( instance, partition_handle, &part_handle, 1,
400 &part_id, &junk1, &junk2, err );
401 }
402
iMeshP_getPartHandleFromPartId(iMesh_Instance instance,const iMeshP_PartitionHandle partition_handle,iMeshP_Part part_id,iMeshP_PartHandle * part_handle,int * err)403 void iMeshP_getPartHandleFromPartId( iMesh_Instance instance,
404 const iMeshP_PartitionHandle partition_handle,
405 iMeshP_Part part_id,
406 iMeshP_PartHandle *part_handle,
407 int *err )
408 {
409 int junk1 = 1, junk2;
410 iMeshP_getPartHandlesFromPartsIdsArr( instance, partition_handle, &part_id, 1,
411 &part_handle, &junk1, &junk2, err );
412 }
413
iMeshP_getPartIdsFromPartHandlesArr(iMesh_Instance instance,const iMeshP_PartitionHandle partition_handle,const iMeshP_PartHandle * part_handles,const int part_handles_size,iMeshP_Part ** part_ids,int * part_ids_allocated,int * part_ids_size,int * err)414 void iMeshP_getPartIdsFromPartHandlesArr(
415 iMesh_Instance instance,
416 const iMeshP_PartitionHandle partition_handle,
417 const iMeshP_PartHandle *part_handles,
418 const int part_handles_size,
419 iMeshP_Part **part_ids,
420 int *part_ids_allocated,
421 int *part_ids_size,
422 int *err)
423 {
424 ErrorCode rval;
425 ParallelComm* pcomm = PCOMM;
426 ALLOC_CHECK_ARRAY( part_ids, part_handles_size );
427 for (int i = 0; i < part_handles_size; ++i) {
428 int id;
429 rval = pcomm->get_part_id( itaps_cast<EntityHandle>(part_handles[i]), id );
430 (*part_ids)[i] = id;
431 CHKERR(rval,"error getting part id");
432 }
433 KEEP_ARRAY(part_ids);
434 RETURN(iBase_SUCCESS);
435 }
436
iMeshP_getPartHandlesFromPartsIdsArr(iMesh_Instance instance,const iMeshP_PartitionHandle partition_handle,const iMeshP_Part * part_ids,const int part_ids_size,iMeshP_PartHandle ** part_handles,int * part_handles_allocated,int * part_handles_size,int * err)437 void iMeshP_getPartHandlesFromPartsIdsArr(
438 iMesh_Instance instance,
439 const iMeshP_PartitionHandle partition_handle,
440 const iMeshP_Part *part_ids,
441 const int part_ids_size,
442 iMeshP_PartHandle **part_handles,
443 int *part_handles_allocated,
444 int *part_handles_size,
445 int *err)
446 {
447 ErrorCode rval;
448 ParallelComm* pcomm = PCOMM;
449 ALLOC_CHECK_ARRAY( part_handles, part_ids_size );
450 for (int i = 0; i < part_ids_size; ++i) {
451 EntityHandle handle;
452 rval = pcomm->get_part_handle( part_ids[i], handle );
453 CHKERR(rval,"error getting part handle");
454 (*part_handles)[i] = itaps_cast<iMeshP_PartHandle>(handle);
455 }
456 KEEP_ARRAY(part_handles);
457 RETURN(iBase_SUCCESS);
458 }
459
iMeshP_getPartitionComm(iMesh_Instance instance,iMeshP_PartitionHandle partition_handle,MPI_Comm * communicator_out,int * err)460 void iMeshP_getPartitionComm( iMesh_Instance instance,
461 iMeshP_PartitionHandle partition_handle,
462 MPI_Comm* communicator_out,
463 int* err )
464 {
465 ParallelComm* pcomm = PCOMM;
466 if (!pcomm)
467 RETURN (iBase_FAILURE);
468 *communicator_out = pcomm->proc_config().proc_comm();
469 RETURN (iBase_SUCCESS);
470 }
471
iMeshP_syncPartitionAll(iMesh_Instance instance,iMeshP_PartitionHandle partition_handle,int * err)472 void iMeshP_syncPartitionAll( iMesh_Instance instance,
473 iMeshP_PartitionHandle partition_handle,
474 int* err )
475 {
476 ParallelComm* pcomm = PCOMM;
477 if (!pcomm)
478 ERROR (iBase_FAILURE,"No PComm");
479 ErrorCode rval = pcomm->collective_sync_partition();
480 CHKERR(rval,"collective sync failed");
481 RETURN(iBase_SUCCESS);
482 }
483
iMeshP_getNumPartitions(iMesh_Instance instance,int * num_partitions_out,int * err)484 void iMeshP_getNumPartitions( iMesh_Instance instance,
485 int* num_partitions_out,
486 int* err )
487 {
488 std::vector<ParallelComm*> pcomms;
489 ErrorCode rval = ParallelComm::get_all_pcomm( MOABI, pcomms );
490 CHKERR(rval,"Internal error retreiving PComms");
491
492 std::vector<ParallelComm*>::iterator i;
493 *num_partitions_out = 0;
494 for (i = pcomms.begin(); i != pcomms.end(); ++i)
495 if ((*i)->get_partitioning())
496 (*num_partitions_out)++;
497
498 RETURN (iBase_SUCCESS );
499 }
500
iMeshP_getPartitions(iMesh_Instance instance,iMeshP_PartitionHandle ** partition_handle,int * partition_handle_allocated,int * partition_handle_size,int * err)501 void iMeshP_getPartitions( iMesh_Instance instance,
502 iMeshP_PartitionHandle **partition_handle,
503 int *partition_handle_allocated,
504 int *partition_handle_size,
505 int *err )
506 {
507 std::vector<ParallelComm*> pcomms;
508 ErrorCode rval = ParallelComm::get_all_pcomm( MOABI, pcomms );
509 CHKERR(rval,"Internal error retreiving PComms");
510
511 std::vector<ParallelComm*>::iterator i;
512 int count = 0;
513 for (i = pcomms.begin(); i != pcomms.end(); ++i)
514 if ((*i)->get_partitioning())
515 ++count;
516 ALLOC_CHECK_ARRAY_NOFAIL( partition_handle, count );
517
518 *partition_handle_size = 0;
519 for (i = pcomms.begin(); i != pcomms.end(); ++i)
520 if ((*i)->get_partitioning())
521 (*partition_handle)[(*partition_handle_size)++]
522 = itaps_cast<iMeshP_PartitionHandle>((*i)->get_partitioning());
523
524 RETURN (iBase_SUCCESS );
525 }
526
iMeshP_getNumGlobalParts(iMesh_Instance instance,const iMeshP_PartitionHandle partition_handle,int * num_global_part,int * err)527 void iMeshP_getNumGlobalParts( iMesh_Instance instance,
528 const iMeshP_PartitionHandle partition_handle,
529 int *num_global_part,
530 int *err )
531 {
532 ParallelComm* pcomm = PCOMM;
533 if (!pcomm)
534 ERROR (iBase_FAILURE,"No PComm");
535
536 ErrorCode rval = pcomm->get_global_part_count( *num_global_part );
537 CHKERR (rval,"PComm::get_global_part_count failed");
538 RETURN(iBase_SUCCESS);
539 }
540
iMeshP_getNumLocalParts(iMesh_Instance instance,const iMeshP_PartitionHandle partition_handle,int * num_local_part,int * err)541 void iMeshP_getNumLocalParts(iMesh_Instance instance,
542 const iMeshP_PartitionHandle partition_handle,
543 int *num_local_part,
544 int *err)
545 {
546 ParallelComm* pcomm = PCOMM;
547 if (!pcomm)
548 ERROR (iBase_FAILURE,"No PComm");
549
550 *num_local_part = pcomm->partition_sets().size();
551 RETURN (iBase_SUCCESS);
552 }
553
iMeshP_getLocalParts(iMesh_Instance instance,const iMeshP_PartitionHandle partition_handle,iMeshP_PartHandle ** part_handles,int * part_handles_allocated,int * part_handles_size,int * err)554 void iMeshP_getLocalParts( iMesh_Instance instance,
555 const iMeshP_PartitionHandle partition_handle,
556 iMeshP_PartHandle **part_handles,
557 int *part_handles_allocated,
558 int *part_handles_size,
559 int *err )
560 {
561 ParallelComm* pcomm = PCOMM;
562 if (!pcomm)
563 ERROR (iBase_FAILURE,"No PComm");
564
565 RANGE_TO_ITAPS_ARRAY( pcomm->partition_sets(), part_handles );
566 RETURN (iBase_SUCCESS);
567 }
568
iMeshP_getRankOfPart(iMesh_Instance instance,const iMeshP_PartitionHandle partition_handle,const iMeshP_Part part_id,int * rank,int * err)569 void iMeshP_getRankOfPart( iMesh_Instance instance,
570 const iMeshP_PartitionHandle partition_handle,
571 const iMeshP_Part part_id,
572 int *rank,
573 int *err )
574 {
575 int junk1 = 1, junk2 = 1;
576 iMeshP_getRankOfPartArr( instance, partition_handle, &part_id,
577 1, &rank, &junk1, &junk2, err );
578 }
579
iMeshP_getRankOfPartArr(iMesh_Instance instance,const iMeshP_PartitionHandle partition_handle,const iMeshP_Part * part_ids,const int part_ids_size,int ** rank,int * rank_allocated,int * rank_size,int * err)580 void iMeshP_getRankOfPartArr( iMesh_Instance instance,
581 const iMeshP_PartitionHandle partition_handle,
582 const iMeshP_Part *part_ids,
583 const int part_ids_size,
584 int **rank,
585 int *rank_allocated,
586 int *rank_size,
587 int *err )
588 {
589 ParallelComm* pcomm = PCOMM;
590 if (!pcomm)
591 ERROR (iBase_FAILURE,"No PComm");
592
593 ALLOC_CHECK_ARRAY( rank, part_ids_size );
594 ErrorCode rval = MB_SUCCESS;
595 for (int i = 0; i < part_ids_size; ++i) {
596 rval = pcomm->get_part_owner( part_ids[i], (*rank)[i] );
597 CHKERR(rval,"PComm::get_part_owner failed");
598 }
599 KEEP_ARRAY(rank);
600 RETURN(iBase_SUCCESS);
601 }
602
iMeshP_getNumOfTypeAll(iMesh_Instance instance,const iMeshP_PartitionHandle partition_handle,const iBase_EntitySetHandle entity_set_handle,const int entity_type,int * num_type,int * err)603 void iMeshP_getNumOfTypeAll( iMesh_Instance instance,
604 const iMeshP_PartitionHandle partition_handle,
605 const iBase_EntitySetHandle entity_set_handle,
606 const int entity_type,
607 int *num_type,
608 int *err )
609 {
610 ParallelComm* pcomm = PCOMM;
611 if (!pcomm)
612 ERROR (iBase_FAILURE,"No PComm");
613
614 Range entities;
615 ErrorCode rval = get_entities( MOABI,
616 itaps_cast<EntityHandle>(entity_set_handle),
617 entity_type,
618 iMesh_ALL_TOPOLOGIES,
619 entities );
620 int count = 0;
621 if (MB_SUCCESS == rval)
622 rval = count_owned( pcomm, entities, count );
623
624 int vals[2] = { count, rval }, sums[2];
625 int ierr = MPI_Allreduce( vals, sums, 2, MPI_INT, MPI_SUM, pcomm->proc_config().proc_comm() );
626 assert(iBase_SUCCESS == 0);
627 if (ierr || sums[1])
628 RETURN (iBase_FAILURE);
629
630 *num_type = sums[0];
631 RETURN (iBase_SUCCESS);
632 }
633
iMeshP_getNumOfTopoAll(iMesh_Instance instance,const iMeshP_PartitionHandle partition_handle,const iBase_EntitySetHandle entity_set_handle,const int entity_topology,int * num_topo,int * err)634 void iMeshP_getNumOfTopoAll( iMesh_Instance instance,
635 const iMeshP_PartitionHandle partition_handle,
636 const iBase_EntitySetHandle entity_set_handle,
637 const int entity_topology,
638 int *num_topo,
639 int *err )
640 {
641 ParallelComm* pcomm = PCOMM;
642 if (!pcomm)
643 ERROR (iBase_FAILURE,"No PComm");
644
645 Range entities;
646 ErrorCode rval = get_entities( MOABI,
647 itaps_cast<EntityHandle>(entity_set_handle),
648 iBase_ALL_TYPES,
649 entity_topology,
650 entities );
651 int count = 0;
652 if (MB_SUCCESS == rval)
653 rval = count_owned( pcomm, entities, count );
654
655 int vals[2] = { count, rval }, sums[2];
656 int ierr = MPI_Allreduce( vals, sums, 2, MPI_INT, MPI_SUM, pcomm->proc_config().proc_comm() );
657 assert(iBase_SUCCESS == 0);
658 if (ierr || sums[1])
659 RETURN (iBase_FAILURE);
660
661 *num_topo = sums[0];
662 RETURN (iBase_SUCCESS);
663 }
664
iMeshP_createPart(iMesh_Instance instance,iMeshP_PartitionHandle partition_handle,iMeshP_PartHandle * part_handle,int * err)665 void iMeshP_createPart( iMesh_Instance instance,
666 iMeshP_PartitionHandle partition_handle,
667 iMeshP_PartHandle *part_handle,
668 int *err )
669 {
670 ParallelComm* pcomm = PCOMM;
671 if (!pcomm)
672 ERROR (iBase_FAILURE,"No PComm");
673
674 EntityHandle h;
675 ErrorCode rval = pcomm->create_part( h );
676 CHKERR(rval,"Part creation failed");
677 *part_handle = itaps_cast<iMeshP_PartHandle>(h);
678 RETURN (iBase_SUCCESS);
679 }
680
iMeshP_destroyPart(iMesh_Instance instance,iMeshP_PartitionHandle partition_handle,iMeshP_PartHandle part_handle,int * err)681 void iMeshP_destroyPart( iMesh_Instance instance,
682 iMeshP_PartitionHandle partition_handle,
683 iMeshP_PartHandle part_handle,
684 int *err )
685 {
686 ParallelComm* pcomm = PCOMM;
687 if (!pcomm)
688 ERROR (iBase_FAILURE,"No PComm");
689
690 ErrorCode rval = pcomm->destroy_part( itaps_cast<EntityHandle>(part_handle) );
691 CHKERR(rval,"Part destruction failed");
692 RETURN(iBase_SUCCESS);
693 }
694
iMeshP_getNumPartNbors(iMesh_Instance instance,iMeshP_PartitionHandle partition_handle,iMeshP_PartHandle part_handle,int entity_type,int * num_part_nbors,int * err)695 void iMeshP_getNumPartNbors( iMesh_Instance instance,
696 iMeshP_PartitionHandle partition_handle,
697 iMeshP_PartHandle part_handle,
698 int entity_type,
699 int *num_part_nbors,
700 int *err )
701 {
702 int junk1 = 1, junk2 = 1;
703 iMeshP_getNumPartNborsArr( instance, partition_handle,
704 &part_handle, 1, entity_type,
705 &num_part_nbors, &junk1, &junk2,
706 err );
707 }
708
iMeshP_getNumPartNborsArr(iMesh_Instance instance,const iMeshP_PartitionHandle partition_handle,const iMeshP_PartHandle * part_handles,const int part_handles_size,int,int ** num_part_nbors,int * num_part_nbors_allocated,int * num_part_nbors_size,int * err)709 void iMeshP_getNumPartNborsArr( iMesh_Instance instance,
710 const iMeshP_PartitionHandle partition_handle,
711 const iMeshP_PartHandle *part_handles,
712 const int part_handles_size,
713 int /*entity_type*/,
714 int **num_part_nbors,
715 int *num_part_nbors_allocated,
716 int *num_part_nbors_size,
717 int *err )
718 {
719 ParallelComm* pcomm = PCOMM;
720 if (!pcomm)
721 ERROR (iBase_FAILURE,"No PComm");
722
723 ALLOC_CHECK_ARRAY( num_part_nbors, part_handles_size );
724
725 int n, neighbors[MAX_SHARING_PROCS];
726 ErrorCode rval;
727 for (int i = 0; i < part_handles_size; ++i) {
728 EntityHandle h = itaps_cast<EntityHandle>(part_handles[i]);
729 rval = pcomm->get_part_neighbor_ids( h, neighbors, n );
730 CHKERR(rval,"error getting neighbor ids");
731 (*num_part_nbors)[i] = n;
732 }
733
734 KEEP_ARRAY(num_part_nbors);
735 RETURN(iBase_SUCCESS);
736 }
737
738
iMeshP_getPartNbors(iMesh_Instance instance,const iMeshP_PartitionHandle partition_handle,const iMeshP_PartHandle part_handle,int entity_type,int * num_part_nbors,iMeshP_Part ** nbor_part_ids,int * nbor_part_ids_allocated,int * nbor_part_ids_size,int * err)739 void iMeshP_getPartNbors( iMesh_Instance instance,
740 const iMeshP_PartitionHandle partition_handle,
741 const iMeshP_PartHandle part_handle,
742 int entity_type,
743 int *num_part_nbors,
744 iMeshP_Part **nbor_part_ids,
745 int *nbor_part_ids_allocated,
746 int *nbor_part_ids_size,
747 int *err )
748 {
749 int junk1 = 1, junk2 = 1;
750 iMeshP_getPartNborsArr( instance, partition_handle,
751 &part_handle, 1, entity_type,
752 &num_part_nbors, &junk1, &junk2,
753 nbor_part_ids, nbor_part_ids_allocated,
754 nbor_part_ids_size, err );
755 }
756
iMeshP_getPartNborsArr(iMesh_Instance instance,const iMeshP_PartitionHandle partition_handle,const iMeshP_PartHandle * part_handles,const int part_handles_size,int,int ** num_part_nbors,int * num_part_nbors_allocated,int * num_part_nbors_size,iMeshP_Part ** nbor_part_ids,int * nbor_part_ids_allocated,int * nbor_part_ids_size,int * err)757 void iMeshP_getPartNborsArr( iMesh_Instance instance,
758 const iMeshP_PartitionHandle partition_handle,
759 const iMeshP_PartHandle *part_handles,
760 const int part_handles_size,
761 int /*entity_type*/,
762 int **num_part_nbors,
763 int *num_part_nbors_allocated,
764 int *num_part_nbors_size,
765 iMeshP_Part **nbor_part_ids,
766 int *nbor_part_ids_allocated,
767 int *nbor_part_ids_size,
768 int *err )
769 {
770 ParallelComm* pcomm = PCOMM;
771 if (!pcomm)
772 ERROR (iBase_FAILURE,"No PComm");
773
774 ALLOC_CHECK_ARRAY( num_part_nbors, part_handles_size );
775
776 std::vector<int> all_neighbors;
777 int n, pnbor[MAX_SHARING_PROCS];
778 ErrorCode rval;
779 for (int i = 0; i < part_handles_size; ++i) {
780 EntityHandle h = itaps_cast<EntityHandle>(part_handles[i]);
781 rval = pcomm->get_part_neighbor_ids( h, pnbor, n );
782 CHKERR(rval,"error getting neighbor ids");
783 (*num_part_nbors)[i] = n;
784 std::copy( pnbor, pnbor+n, std::back_inserter(all_neighbors) );
785 }
786
787 ALLOC_CHECK_ARRAY_NOFAIL( nbor_part_ids, all_neighbors.size() );
788 memcpy( *nbor_part_ids, &all_neighbors[0], sizeof(int)*all_neighbors.size() );
789
790 KEEP_ARRAY(num_part_nbors);
791 RETURN(iBase_SUCCESS);
792 }
793
iMeshP_getNumPartBdryEnts(iMesh_Instance instance,const iMeshP_PartitionHandle partition_handle,const iMeshP_PartHandle part_handle,const int entity_type,const int entity_topology,const iMeshP_Part target_part_id,int * num_entities,int * err)794 void iMeshP_getNumPartBdryEnts( iMesh_Instance instance,
795 const iMeshP_PartitionHandle partition_handle,
796 const iMeshP_PartHandle part_handle,
797 const int entity_type,
798 const int entity_topology,
799 const iMeshP_Part target_part_id,
800 int *num_entities,
801 int *err )
802 {
803 Range entities;
804 ErrorCode rval = get_boundary_entities( PCOMM,
805 itaps_cast<EntityHandle>(part_handle),
806 entity_type,
807 entity_topology,
808 target_part_id,
809 entities );
810 CHKERR(rval,"failed to get boundary entities");
811 *num_entities = entities.size();
812 RETURN(iBase_SUCCESS);
813 }
814
iMeshP_getPartBdryEnts(iMesh_Instance instance,const iMeshP_PartitionHandle partition_handle,const iMeshP_PartHandle part_handle,const int entity_type,const int entity_topology,const iMeshP_Part target_part_id,iBase_EntityHandle ** entity_handles,int * entity_handles_allocated,int * entity_handles_size,int * err)815 void iMeshP_getPartBdryEnts( iMesh_Instance instance,
816 const iMeshP_PartitionHandle partition_handle,
817 const iMeshP_PartHandle part_handle,
818 const int entity_type,
819 const int entity_topology,
820 const iMeshP_Part target_part_id,
821 iBase_EntityHandle **entity_handles,
822 int *entity_handles_allocated,
823 int *entity_handles_size,
824 int *err )
825 {
826 Range entities;
827 ErrorCode rval = get_boundary_entities( PCOMM,
828 itaps_cast<EntityHandle>(part_handle),
829 entity_type,
830 entity_topology,
831 target_part_id,
832 entities );
833 CHKERR(rval,"failed to get boundary entities");
834 RANGE_TO_ITAPS_ARRAY( entities, entity_handles );
835 RETURN(iBase_SUCCESS);
836 }
837
iMeshP_initPartBdryEntIter(iMesh_Instance instance,const iMeshP_PartitionHandle partition_handle,const iMeshP_PartHandle part_handle,const int entity_type,const int entity_topology,const iMeshP_Part nbor_part_id,iBase_EntityIterator * entity_iterator,int * err)838 void iMeshP_initPartBdryEntIter( iMesh_Instance instance,
839 const iMeshP_PartitionHandle partition_handle,
840 const iMeshP_PartHandle part_handle,
841 const int entity_type,
842 const int entity_topology,
843 const iMeshP_Part nbor_part_id,
844 iBase_EntityIterator* entity_iterator,
845 int* err )
846 {
847 iMeshP_initPartBdryEntArrIter( instance,
848 partition_handle,
849 part_handle,
850 entity_type,
851 entity_topology,
852 1,
853 nbor_part_id,
854 reinterpret_cast<iBase_EntityArrIterator*>(entity_iterator),
855 err );
856 }
857
iMeshP_initPartBdryEntArrIter(iMesh_Instance instance,const iMeshP_PartitionHandle partition_handle,const iMeshP_PartHandle part_handle,const int entity_type,const int entity_topology,const int array_size,const iMeshP_Part nbor_part_id,iBase_EntityArrIterator * entity_iterator,int * err)858 void iMeshP_initPartBdryEntArrIter( iMesh_Instance instance,
859 const iMeshP_PartitionHandle partition_handle,
860 const iMeshP_PartHandle part_handle,
861 const int entity_type,
862 const int entity_topology,
863 const int array_size,
864 const iMeshP_Part nbor_part_id,
865 iBase_EntityArrIterator* entity_iterator,
866 int* err )
867 {
868 *entity_iterator = new PartBoundaryIter( PCOMM,
869 itaps_cast<EntityHandle>(part_handle),
870 (iBase_EntityType)entity_type,
871 (iMesh_EntityTopology)entity_topology,
872 nbor_part_id,
873 array_size );
874 ErrorCode result = (*entity_iterator)->reset( MOABI );
875 if (MB_SUCCESS != result)
876 delete *entity_iterator;
877 CHKERR(result, "iMesh_initEntArrIter: ERROR getting entities of proper type or topology." );
878 RETURN(iBase_SUCCESS);
879 }
880
881
882
iMeshP_getNumOfType(iMesh_Instance instance,const iMeshP_PartitionHandle,const iMeshP_PartHandle part_handle,const iBase_EntitySetHandle entity_set_handle,const int entity_type,int * num_type,int * err)883 void iMeshP_getNumOfType( iMesh_Instance instance,
884 const iMeshP_PartitionHandle ,
885 const iMeshP_PartHandle part_handle,
886 const iBase_EntitySetHandle entity_set_handle,
887 const int entity_type,
888 int *num_type,
889 int *err )
890 {
891 Range r;
892 set_intersection_query( instance, part_handle, entity_set_handle,
893 entity_type, iMesh_ALL_TOPOLOGIES, r, err );
894 *num_type = r.size();
895 }
896
iMeshP_getNumOfTopo(iMesh_Instance instance,const iMeshP_PartitionHandle,const iMeshP_PartHandle part_handle,const iBase_EntitySetHandle entity_set_handle,const int entity_topology,int * num_topo,int * err)897 void iMeshP_getNumOfTopo( iMesh_Instance instance,
898 const iMeshP_PartitionHandle /*partition_handle*/,
899 const iMeshP_PartHandle part_handle,
900 const iBase_EntitySetHandle entity_set_handle,
901 const int entity_topology,
902 int *num_topo,
903 int *err )
904 {
905 Range r;
906 set_intersection_query( instance, part_handle, entity_set_handle,
907 iBase_ALL_TYPES, entity_topology, r, err );
908 *num_topo = r.size();
909 }
910
iMeshP_getAdjEntIndices(iMesh_Instance instance,iMeshP_PartitionHandle partition,iMeshP_PartHandle part,iBase_EntitySetHandle entity_set_handle,int entity_type_requestor,int entity_topology_requestor,int entity_type_requested,iBase_EntityHandle ** entity_handles,int * entity_handles_allocated,int * entity_handles_size,iBase_EntityHandle ** adj_entity_handles,int * adj_entity_handles_allocated,int * adj_entity_handles_size,int ** adj_entity_indices,int * adj_entity_indices_allocated,int * adj_entity_indices_size,int ** offset,int * offset_allocated,int * offset_size,int * err)911 void iMeshP_getAdjEntIndices(iMesh_Instance instance,
912 iMeshP_PartitionHandle partition,
913 iMeshP_PartHandle part,
914 iBase_EntitySetHandle entity_set_handle,
915 int entity_type_requestor,
916 int entity_topology_requestor,
917 int entity_type_requested,
918 iBase_EntityHandle** entity_handles,
919 int* entity_handles_allocated,
920 int* entity_handles_size,
921 iBase_EntityHandle** adj_entity_handles,
922 int* adj_entity_handles_allocated,
923 int* adj_entity_handles_size,
924 int** adj_entity_indices,
925 int* adj_entity_indices_allocated,
926 int* adj_entity_indices_size,
927 int** offset,
928 int* offset_allocated,
929 int* offset_size,
930 int *err)
931 {
932 const int allocated_entity_handles = (*entity_handles_allocated == 0);
933 const int allocated_indices = (*adj_entity_indices_allocated == 0);
934 const int allocated_offset = (*offset_allocated == 0);
935
936 // get source entities
937 iMeshP_getEntities( instance,
938 partition, part,
939 entity_set_handle,
940 entity_type_requestor,
941 entity_topology_requestor,
942 entity_handles,
943 entity_handles_allocated,
944 entity_handles_size,
945 err );
946 if (iBase_SUCCESS != *err)
947 return;
948
949 // get adjacencies
950 iBase_EntityHandle* all_adj_handles = 0;
951 int size = 0, alloc = 0;
952 iMesh_getEntArrAdj( instance,
953 *entity_handles, *entity_handles_size,
954 entity_type_requested,
955 &all_adj_handles, &alloc, &size,
956 offset, offset_allocated, offset_size,
957 err );
958 if (*err != iBase_SUCCESS) {
959 if (allocated_entity_handles) {
960 free( *entity_handles );
961 *entity_handles = 0;
962 *entity_handles_allocated = 0;
963 }
964 return;
965 }
966
967 // allocate or check size of adj_entity_indices
968 *adj_entity_indices_size = size;
969 if (allocated_indices) {
970 *adj_entity_indices = (int*)malloc(sizeof(iBase_EntityHandle)*size);
971 if (!*adj_entity_indices)
972 *err = iBase_MEMORY_ALLOCATION_FAILED;
973 else
974 *adj_entity_indices_allocated = size;
975 }
976 else if (*adj_entity_indices_allocated < size) {
977 *err = iBase_BAD_ARRAY_DIMENSION;
978 }
979 if (iBase_SUCCESS != *err) {
980 free( all_adj_handles );
981 if (allocated_entity_handles) {
982 free( *entity_handles );
983 *entity_handles = 0;
984 *entity_handles_allocated = 0;
985 }
986 if (allocated_offset) {
987 free( *offset );
988 *offset = 0;
989 *offset_allocated = 0;
990 }
991 return;
992 }
993
994 // Now create an array of unique sorted handles from all_adj_handles.
995 // We need to create a copy because we still need all_adj_handles. We
996 // will eventually need to copy the resulting unique list into
997 // adj_entity_handles, so if adj_entity_handles is already allocated and
998 // of sufficient size, use it rather than allocating another temporary.
999 iBase_EntityHandle* unique_adj = 0;
1000 if (*adj_entity_handles_allocated >= size) {
1001 unique_adj = *adj_entity_handles;
1002 }
1003 else {
1004 unique_adj = (iBase_EntityHandle*)malloc(sizeof(iBase_EntityHandle) * size);
1005 }
1006 std::copy( all_adj_handles, all_adj_handles+size, unique_adj );
1007 std::sort( unique_adj, unique_adj + size );
1008 *adj_entity_handles_size = std::unique( unique_adj, unique_adj + size ) - unique_adj;
1009
1010 // If we created a temporary array for unique_adj rather than using
1011 // already allocated space in adj_entity_handles, allocate adj_entity_handles
1012 // and copy the unique handle list into it
1013 if (*adj_entity_handles != unique_adj) {
1014 if (!*adj_entity_handles_allocated) {
1015 *adj_entity_handles = (iBase_EntityHandle*)malloc(
1016 sizeof(iBase_EntityHandle) * *adj_entity_handles_size);
1017 if (!*adj_entity_handles)
1018 *err = iBase_MEMORY_ALLOCATION_FAILED;
1019 else
1020 *adj_entity_handles_allocated = *adj_entity_handles_size;
1021 }
1022 else if (*adj_entity_handles_allocated < *adj_entity_handles_size)
1023 *err = iBase_BAD_ARRAY_DIMENSION;
1024 if (iBase_SUCCESS != *err) {
1025 free( unique_adj );
1026 free( all_adj_handles );
1027 if (allocated_entity_handles) {
1028 free( *entity_handles );
1029 *entity_handles = 0;
1030 *entity_handles_allocated = 0;
1031 }
1032 if (allocated_offset) {
1033 free( *offset );
1034 *offset = 0;
1035 *offset_allocated = 0;
1036 }
1037 if (allocated_indices) {
1038 free( *adj_entity_indices );
1039 *adj_entity_indices = 0;
1040 *adj_entity_indices_allocated = 0;
1041 }
1042 return;
1043 }
1044
1045 std::copy( unique_adj, unique_adj + *adj_entity_handles_size, *adj_entity_handles );
1046 free( unique_adj );
1047 unique_adj = *adj_entity_handles;
1048 }
1049
1050 // convert from adjacency list to indices into unique_adj
1051 for (int i = 0; i < *adj_entity_indices_size; ++i)
1052 (*adj_entity_indices)[i] = std::lower_bound( unique_adj,
1053 unique_adj + *adj_entity_handles_size, all_adj_handles[i] ) - unique_adj;
1054 free( all_adj_handles );
1055 }
1056
iMeshP_getEntities(iMesh_Instance instance,const iMeshP_PartitionHandle,const iMeshP_PartHandle part_handle,const iBase_EntitySetHandle entity_set_handle,const int entity_type,const int entity_topology,iBase_EntityHandle ** entity_handles,int * entity_handles_allocated,int * entity_handles_size,int * err)1057 void iMeshP_getEntities( iMesh_Instance instance,
1058 const iMeshP_PartitionHandle ,
1059 const iMeshP_PartHandle part_handle,
1060 const iBase_EntitySetHandle entity_set_handle,
1061 const int entity_type,
1062 const int entity_topology,
1063 iBase_EntityHandle** entity_handles,
1064 int* entity_handles_allocated,
1065 int* entity_handles_size,
1066 int *err )
1067 {
1068 Range r;
1069 set_intersection_query( instance, part_handle, entity_set_handle,
1070 entity_type, entity_topology, r, err );
1071 if (iBase_SUCCESS != *err)
1072 return;
1073
1074 RANGE_TO_ITAPS_ARRAY( r, entity_handles );
1075 RETURN(iBase_SUCCESS);
1076 }
1077
iMeshP_getAdjEntities(iMesh_Instance instance,const iMeshP_PartitionHandle,const iMeshP_PartHandle part_handle,const iBase_EntitySetHandle entity_set_handle,const int entity_type_requestor,const int entity_topology_requestor,const int entity_type_requested,iBase_EntityHandle ** adj_entity_handles,int * adj_entity_handles_allocated,int * adj_entity_handles_size,int ** offset,int * offset_allocated,int * offset_size,int ** in_entity_set,int * in_entity_set_allocated,int * in_entity_set_size,int * err)1078 void iMeshP_getAdjEntities( iMesh_Instance instance,
1079 const iMeshP_PartitionHandle /*partition_handle*/,
1080 const iMeshP_PartHandle part_handle,
1081 const iBase_EntitySetHandle entity_set_handle,
1082 const int entity_type_requestor,
1083 const int entity_topology_requestor,
1084 const int entity_type_requested,
1085 iBase_EntityHandle** adj_entity_handles,
1086 int* adj_entity_handles_allocated,
1087 int* adj_entity_handles_size,
1088 int** offset,
1089 int* offset_allocated,
1090 int* offset_size,
1091 int** in_entity_set,
1092 int* in_entity_set_allocated,
1093 int* in_entity_set_size,
1094 int *err )
1095 {
1096 ErrorCode rval;
1097 Range r;
1098 set_intersection_query( instance, part_handle, entity_set_handle,
1099 entity_type_requestor, entity_topology_requestor,
1100 r, err );
1101 if (iBase_SUCCESS != *err)
1102 return;
1103
1104 // count adjacencies
1105 std::vector<EntityHandle> tmp_storage;
1106 int num_adj = 0;
1107 int num_conn;
1108 const EntityHandle* conn_ptr;
1109 for (Range::iterator i = r.begin(); i != r.end(); ++i) {
1110 if (entity_type_requested || TYPE_FROM_HANDLE(*i) == MBPOLYHEDRON) {
1111 tmp_storage.clear();
1112 rval = MOABI->get_adjacencies( &*i, 1, entity_type_requested, false, tmp_storage );
1113 CHKERR(rval,"get_adjacencies failed");
1114 num_adj += tmp_storage.size();
1115 }
1116 else {
1117 rval = MOABI->get_connectivity( *i, conn_ptr, num_conn, false, &tmp_storage );
1118 CHKERR(rval,"get_connectivity failed");
1119 num_adj += num_conn;
1120 }
1121 }
1122
1123 // get adjacencies
1124 ALLOC_CHECK_ARRAY( adj_entity_handles, num_adj );
1125 ALLOC_CHECK_ARRAY( offset, r.size() );
1126 int arr_pos = 0;
1127 int* offset_iter = *offset;
1128 for (Range::iterator i = r.begin(); i != r.end(); ++i) {
1129 *offset_iter = arr_pos;
1130 ++offset_iter;
1131
1132 tmp_storage.clear();
1133 rval = MOABI->get_adjacencies( &*i, 1, entity_type_requested, false, tmp_storage );
1134 CHKERR(rval,"get_adjacencies failed");
1135 for (std::vector<EntityHandle>::iterator j = tmp_storage.begin(); j != tmp_storage.end(); ++j) {
1136 (*adj_entity_handles)[arr_pos] = itaps_cast<iBase_EntityHandle>(*j);
1137 ++arr_pos;
1138 }
1139 }
1140
1141 // get in_entity_set
1142 iMesh_isEntArrContained( instance,
1143 entity_set_handle,
1144 *adj_entity_handles,
1145 *adj_entity_handles_size,
1146 in_entity_set,
1147 in_entity_set_allocated,
1148 in_entity_set_size,
1149 err );
1150
1151 if (iBase_SUCCESS == *err) {
1152 KEEP_ARRAY(adj_entity_handles);
1153 KEEP_ARRAY(offset);
1154 }
1155 }
1156
iMeshP_initEntIter(iMesh_Instance instance,const iMeshP_PartitionHandle partition_handle,const iMeshP_PartHandle part_handle,const iBase_EntitySetHandle entity_set_handle,const int requested_entity_type,const int requested_entity_topology,iBase_EntityIterator * entity_iterator,int * err)1157 void iMeshP_initEntIter( iMesh_Instance instance,
1158 const iMeshP_PartitionHandle partition_handle,
1159 const iMeshP_PartHandle part_handle,
1160 const iBase_EntitySetHandle entity_set_handle,
1161 const int requested_entity_type,
1162 const int requested_entity_topology,
1163 iBase_EntityIterator* entity_iterator,
1164 int *err )
1165 {
1166 iMeshP_initEntArrIter( instance,
1167 partition_handle,
1168 part_handle,
1169 entity_set_handle,
1170 requested_entity_type,
1171 requested_entity_topology,
1172 1,
1173 reinterpret_cast<iBase_EntityArrIterator*>(entity_iterator),
1174 err );
1175 }
1176
iMeshP_initEntArrIter(iMesh_Instance instance,const iMeshP_PartitionHandle,const iMeshP_PartHandle part_handle,const iBase_EntitySetHandle entity_set_handle,const int requested_entity_type,const int requested_entity_topology,const int requested_array_size,iBase_EntityArrIterator * entArr_iterator,int * err)1177 void iMeshP_initEntArrIter( iMesh_Instance instance,
1178 const iMeshP_PartitionHandle /*partition_handle*/,
1179 const iMeshP_PartHandle part_handle,
1180 const iBase_EntitySetHandle entity_set_handle,
1181 const int requested_entity_type,
1182 const int requested_entity_topology,
1183 const int requested_array_size,
1184 iBase_EntityArrIterator* entArr_iterator,
1185 int *err )
1186 {
1187 if (!entity_set_handle || entity_set_handle == part_handle) {
1188 iMesh_initEntArrIter( instance,
1189 part_handle,
1190 requested_entity_type,
1191 requested_entity_topology,
1192 requested_array_size,
1193 0, // TODO: update this function for "resilient" arg
1194 entArr_iterator,
1195 err );
1196 }
1197 else {
1198 unsigned flags;
1199 ErrorCode result = MOABI->get_meshset_options( itaps_cast<EntityHandle>(entity_set_handle), flags );
1200 CHKERR(result,"Invalid entity set handle");
1201 if (flags & MESHSET_ORDERED)
1202 *entArr_iterator = new SetIntersectIter< std::vector<EntityHandle> >
1203 ( (iBase_EntityType)requested_entity_type,
1204 (iMesh_EntityTopology)requested_entity_topology,
1205 itaps_cast<EntityHandle>(entity_set_handle),
1206 itaps_cast<EntityHandle>(part_handle),
1207 requested_array_size );
1208 else
1209 *entArr_iterator = new SetIntersectIter< Range >
1210 ( (iBase_EntityType)requested_entity_type,
1211 (iMesh_EntityTopology)requested_entity_topology,
1212 itaps_cast<EntityHandle>(entity_set_handle),
1213 itaps_cast<EntityHandle>(part_handle),
1214 requested_array_size );
1215 result = (*entArr_iterator)->reset( MOABI );
1216 if (MB_SUCCESS != result)
1217 delete *entArr_iterator;
1218 CHKERR(result, "iMesh_initEntArrIter: ERROR getting entities of proper type or topology." );
1219 RETURN(iBase_SUCCESS);
1220 }
1221 }
1222
iMeshP_getEntOwnerPart(iMesh_Instance instance,const iMeshP_PartitionHandle partition_handle,const iBase_EntityHandle entity_handle,iMeshP_Part * part_id,int * err)1223 void iMeshP_getEntOwnerPart( iMesh_Instance instance,
1224 const iMeshP_PartitionHandle partition_handle,
1225 const iBase_EntityHandle entity_handle,
1226 iMeshP_Part *part_id,
1227 int* err )
1228 {
1229 int junk1 = 1, junk2 = 1;
1230 iMeshP_getEntOwnerPartArr( instance, partition_handle, &entity_handle, 1,
1231 &part_id, &junk1, &junk2, err );
1232 }
1233
iMeshP_getEntOwnerPartArr(iMesh_Instance instance,const iMeshP_PartitionHandle partition_handle,const iBase_EntityHandle * entity_handles,const int entity_handles_size,iMeshP_Part ** part_ids,int * part_ids_allocated,int * part_ids_size,int * err)1234 void iMeshP_getEntOwnerPartArr( iMesh_Instance instance,
1235 const iMeshP_PartitionHandle partition_handle,
1236 const iBase_EntityHandle *entity_handles,
1237 const int entity_handles_size,
1238 iMeshP_Part **part_ids,
1239 int *part_ids_allocated,
1240 int *part_ids_size,
1241 int* err )
1242 {
1243 ParallelComm* pcomm = PCOMM;
1244 if (!pcomm)
1245 ERROR (iBase_FAILURE,"No PComm");
1246
1247 int id;
1248 ALLOC_CHECK_ARRAY( part_ids, entity_handles_size );
1249 ErrorCode rval = MB_SUCCESS;
1250 for (int i = 0; i < entity_handles_size; ++i) {
1251 EntityHandle h = itaps_cast<EntityHandle>(entity_handles[i]);
1252 rval = pcomm->get_owning_part( h, id );
1253 (*part_ids)[i] = id;
1254 CHKERR(rval,"Failet get part owner");
1255 }
1256 KEEP_ARRAY(part_ids);
1257 RETURN(iBase_SUCCESS);
1258 }
1259
iMeshP_isEntOwner(iMesh_Instance instance,const iMeshP_PartitionHandle partition_handle,const iMeshP_PartHandle part_handle,const iBase_EntityHandle entity_handle,int * is_owner,int * err)1260 void iMeshP_isEntOwner( iMesh_Instance instance,
1261 const iMeshP_PartitionHandle partition_handle,
1262 const iMeshP_PartHandle part_handle,
1263 const iBase_EntityHandle entity_handle,
1264 int* is_owner,
1265 int *err )
1266 {
1267 int junk1 = 1, junk2 = 1;
1268 iMeshP_isEntOwnerArr( instance, partition_handle,
1269 part_handle, &entity_handle, 1,
1270 &is_owner, &junk1, &junk2,
1271 err );
1272 }
1273
iMeshP_isEntOwnerArr(iMesh_Instance instance,const iMeshP_PartitionHandle partition_handle,const iMeshP_PartHandle part_handle,const iBase_EntityHandle * entity_handles,const int entity_handles_size,int ** is_owner,int * is_owner_allocated,int * is_owner_size,int * err)1274 void iMeshP_isEntOwnerArr( iMesh_Instance instance,
1275 const iMeshP_PartitionHandle partition_handle,
1276 const iMeshP_PartHandle part_handle,
1277 const iBase_EntityHandle *entity_handles,
1278 const int entity_handles_size,
1279 int** is_owner,
1280 int* is_owner_allocated,
1281 int* is_owner_size,
1282 int *err )
1283 {
1284 ErrorCode rval;
1285 ParallelComm* pcomm = PCOMM;
1286 if (!pcomm)
1287 ERROR (iBase_FAILURE,"No PComm");
1288
1289 int id;
1290 rval = pcomm->get_part_id( itaps_cast<EntityHandle>(part_handle), id );
1291 CHKERR(rval,"error getting part id");
1292
1293 ALLOC_CHECK_ARRAY( is_owner, entity_handles_size );
1294 *is_owner_size = entity_handles_size;
1295
1296 int owner;
1297 for (int i = 0; i < entity_handles_size; ++i) {
1298 rval = pcomm->get_owner( itaps_cast<EntityHandle>(entity_handles[i]), owner );
1299 CHKERR(rval,"error getting owner");
1300 (*is_owner)[i] = (owner == id);
1301 }
1302
1303 KEEP_ARRAY(is_owner);
1304 RETURN(iBase_SUCCESS);
1305 }
1306
iMeshP_getEntStatus(iMesh_Instance instance,const iMeshP_PartitionHandle partition_handle,const iMeshP_PartHandle part_handle,const iBase_EntityHandle entity_handle,int * par_status,int * err)1307 void iMeshP_getEntStatus(iMesh_Instance instance,
1308 /*in*/ const iMeshP_PartitionHandle partition_handle,
1309 /*in*/ const iMeshP_PartHandle part_handle,
1310 /*in*/ const iBase_EntityHandle entity_handle,
1311 /*out*/ int* par_status, // Values=INTERNAL,BOUNDARY,GHOST
1312 int *err)
1313 {
1314 int junk1 = 1, junk2 = 1;
1315 iMeshP_getEntStatusArr( instance, partition_handle,
1316 part_handle, &entity_handle, 1,
1317 &par_status, &junk1, &junk2,
1318 err );
1319 }
1320
iMeshP_getEntStatusArr(iMesh_Instance instance,const iMeshP_PartitionHandle partition_handle,const iMeshP_PartHandle,const iBase_EntityHandle * entity_handles,const int entity_handles_size,int ** par_status,int * par_status_allocated,int * par_status_size,int * err)1321 void iMeshP_getEntStatusArr(iMesh_Instance instance,
1322 /*in*/ const iMeshP_PartitionHandle partition_handle,
1323 /*in*/ const iMeshP_PartHandle /*part_handle*/,
1324 /*in*/ const iBase_EntityHandle *entity_handles,
1325 /*in*/ const int entity_handles_size,
1326 /*inout*/ int** par_status, // Values=INTERNAL,BOUNDARY,GHOST
1327 /*inout*/ int* par_status_allocated,
1328 /*inout*/ int* par_status_size,
1329 int *err)
1330 {
1331 ParallelComm* pcomm = PCOMM;
1332 if (!pcomm)
1333 ERROR (iBase_FAILURE,"No PComm");
1334
1335 std::vector<unsigned char> pstatus(entity_handles_size);
1336 ErrorCode result = MOABI->tag_get_data(pcomm->pstatus_tag(),
1337 itaps_cast<const EntityHandle*>(entity_handles),
1338 entity_handles_size,
1339 &pstatus[0]);
1340 CHKERR(result,"error getting pstatus_tag");
1341
1342 ALLOC_CHECK_ARRAY( par_status, entity_handles_size );
1343 for (int i = 0; i < entity_handles_size; i++) {
1344 if (!pstatus[i])
1345 (*par_status)[i] = iMeshP_INTERNAL;
1346 else if (pstatus[i] & PSTATUS_GHOST)
1347 (*par_status)[i] = iMeshP_GHOST;
1348 else if (pstatus[i] & PSTATUS_INTERFACE)
1349 (*par_status)[i] = iMeshP_BOUNDARY;
1350 }
1351
1352 KEEP_ARRAY(par_status);
1353 RETURN(iBase_SUCCESS);
1354 }
1355
iMeshP_getNumCopies(iMesh_Instance instance,const iMeshP_PartitionHandle partition_handle,const iBase_EntityHandle entity_handle,int * num_copies_ent,int * err)1356 void iMeshP_getNumCopies( iMesh_Instance instance,
1357 const iMeshP_PartitionHandle partition_handle,
1358 const iBase_EntityHandle entity_handle,
1359 int *num_copies_ent,
1360 int *err )
1361 {
1362 ParallelComm* pcomm = PCOMM;
1363 if (!pcomm)
1364 ERROR (iBase_FAILURE,"No PComm");
1365
1366 int ids[MAX_SHARING_PROCS];
1367 ErrorCode rval = pcomm->get_sharing_parts(
1368 itaps_cast<EntityHandle>(entity_handle),
1369 ids, *num_copies_ent );
1370 CHKERR(rval,"ParallelComm::get_sharing_parts failed");
1371 RETURN(iBase_SUCCESS);
1372 }
1373
iMeshP_getCopyParts(iMesh_Instance instance,const iMeshP_PartitionHandle partition_handle,const iBase_EntityHandle entity_handle,iMeshP_Part ** part_ids,int * part_ids_allocated,int * part_ids_size,int * err)1374 void iMeshP_getCopyParts( iMesh_Instance instance,
1375 const iMeshP_PartitionHandle partition_handle,
1376 const iBase_EntityHandle entity_handle,
1377 iMeshP_Part **part_ids,
1378 int *part_ids_allocated,
1379 int *part_ids_size,
1380 int *err )
1381 {
1382 ParallelComm* pcomm = PCOMM;
1383 if (!pcomm)
1384 ERROR (iBase_FAILURE,"No PComm");
1385
1386 int ids[MAX_SHARING_PROCS], num_ids;
1387 ErrorCode rval = pcomm->get_sharing_parts(
1388 itaps_cast<EntityHandle>(entity_handle),
1389 ids, num_ids );
1390 CHKERR(rval,"ParallelComm::get_sharing_parts failed");
1391 ALLOC_CHECK_ARRAY_NOFAIL( part_ids, num_ids );
1392 std::copy( ids, ids+num_ids, *part_ids );
1393 RETURN (iBase_SUCCESS);
1394 }
1395
1396
1397
iMeshP_getCopies(iMesh_Instance instance,const iMeshP_PartitionHandle partition_handle,const iBase_EntityHandle entity_handle,iMeshP_Part ** part_ids,int * part_ids_allocated,int * part_ids_size,iBase_EntityHandle ** copies_entity_handles,int * copies_entity_handles_allocated,int * copies_entity_handles_size,int * err)1398 void iMeshP_getCopies( iMesh_Instance instance,
1399 const iMeshP_PartitionHandle partition_handle,
1400 const iBase_EntityHandle entity_handle,
1401 iMeshP_Part **part_ids,
1402 int *part_ids_allocated,
1403 int *part_ids_size,
1404 iBase_EntityHandle **copies_entity_handles,
1405 int *copies_entity_handles_allocated,
1406 int *copies_entity_handles_size,
1407 int *err )
1408 {
1409 ParallelComm* pcomm = PCOMM;
1410 if (!pcomm)
1411 ERROR (iBase_FAILURE,"No PComm");
1412
1413 int ids[MAX_SHARING_PROCS], num_ids;
1414 EntityHandle handles[MAX_SHARING_PROCS];
1415 ErrorCode rval = pcomm->get_sharing_parts(
1416 itaps_cast<EntityHandle>(entity_handle),
1417 ids, num_ids, handles );
1418 CHKERR(rval,"ParallelComm::get_sharing_parts failed");
1419 ALLOC_CHECK_ARRAY_NOFAIL( part_ids, num_ids );
1420 ALLOC_CHECK_ARRAY_NOFAIL( copies_entity_handles, num_ids );
1421 for (int i = 0; i < num_ids; ++i) {
1422 (*part_ids)[i] = ids[i];
1423 (*copies_entity_handles)[i] = itaps_cast<iBase_EntityHandle>(handles[i]);
1424 }
1425 RETURN (iBase_SUCCESS);
1426 }
1427
iMeshP_getCopyOnPart(iMesh_Instance instance,const iMeshP_PartitionHandle partition_handle,const iBase_EntityHandle entity_handle,const iMeshP_Part part_id,iBase_EntityHandle * copy_entity_handle,int * err)1428 void iMeshP_getCopyOnPart( iMesh_Instance instance,
1429 const iMeshP_PartitionHandle partition_handle,
1430 const iBase_EntityHandle entity_handle,
1431 const iMeshP_Part part_id,
1432 iBase_EntityHandle* copy_entity_handle,
1433 int *err )
1434 {
1435 ParallelComm* pcomm = PCOMM;
1436 if (!pcomm)
1437 ERROR (iBase_FAILURE,"No PComm");
1438
1439 int ids[MAX_SHARING_PROCS], num_ids;
1440 EntityHandle handles[MAX_SHARING_PROCS];
1441 ErrorCode rval = pcomm->get_sharing_parts(
1442 itaps_cast<EntityHandle>(entity_handle),
1443 ids, num_ids, handles );
1444 CHKERR(rval,"ParallelComm::get_sharing_parts failed");
1445 int idx = std::find( ids, ids+num_ids, part_id ) - ids;
1446 if (idx == num_ids)
1447 RETURN (iBase_FAILURE);
1448
1449 *copy_entity_handle = itaps_cast<iBase_EntityHandle>(handles[idx]);
1450 RETURN (iBase_SUCCESS);
1451 }
1452
1453
iMeshP_getOwnerCopy(iMesh_Instance instance,const iMeshP_PartitionHandle partition_handle,const iBase_EntityHandle entity_handle,iMeshP_Part * owner_part_id,iBase_EntityHandle * owner_entity_handle,int * err)1454 void iMeshP_getOwnerCopy( iMesh_Instance instance,
1455 const iMeshP_PartitionHandle partition_handle,
1456 const iBase_EntityHandle entity_handle,
1457 iMeshP_Part *owner_part_id,
1458 iBase_EntityHandle *owner_entity_handle,
1459 int *err )
1460 {
1461 ParallelComm* pcomm = PCOMM;
1462 if (!pcomm)
1463 ERROR (iBase_FAILURE,"No PComm");
1464
1465 int id;
1466 EntityHandle h;
1467 ErrorCode rval = pcomm->get_owning_part(
1468 itaps_cast<EntityHandle>(entity_handle),
1469 id, &h );
1470 CHKERR(rval,"Failed to get owner");
1471 *owner_part_id = id;
1472 *owner_entity_handle = itaps_cast<iBase_EntityHandle>(h);
1473 RETURN(iBase_SUCCESS);
1474 }
1475
iMeshP_waitForAnyRequest(iMesh_Instance instance,iMeshP_PartitionHandle,iMeshP_RequestHandle *,int,int *,int * err)1476 void iMeshP_waitForAnyRequest( iMesh_Instance instance,
1477 iMeshP_PartitionHandle ,
1478 iMeshP_RequestHandle *,
1479 int ,
1480 int* ,
1481 int* err)
1482 { FIXME; RETURN(iBase_NOT_SUPPORTED); }
1483
iMeshP_waitForAllRequests(iMesh_Instance instance,iMeshP_PartitionHandle,iMeshP_RequestHandle *,int,int * err)1484 void iMeshP_waitForAllRequests( iMesh_Instance instance,
1485 iMeshP_PartitionHandle ,
1486 iMeshP_RequestHandle *,
1487 int ,
1488 int *err)
1489 { FIXME; RETURN(iBase_NOT_SUPPORTED); }
1490
iMeshP_waitForRequestEnt(iMesh_Instance instance,const iMeshP_PartitionHandle,iMeshP_RequestHandle,iBase_EntityHandle **,int *,int *,int * err)1491 void iMeshP_waitForRequestEnt(
1492 iMesh_Instance instance,
1493 const iMeshP_PartitionHandle ,
1494 iMeshP_RequestHandle ,
1495 iBase_EntityHandle **,
1496 int *,
1497 int *,
1498 int *err)
1499 { FIXME; RETURN(iBase_NOT_SUPPORTED); }
1500
iMeshP_testRequest(iMesh_Instance instance,const iMeshP_PartitionHandle,iMeshP_RequestHandle,int *,int * err)1501 void iMeshP_testRequest( iMesh_Instance instance,
1502 const iMeshP_PartitionHandle ,
1503 iMeshP_RequestHandle ,
1504 int *,
1505 int *err)
1506 { FIXME; RETURN(iBase_NOT_SUPPORTED); }
1507
iMeshP_pollForRequests(iMesh_Instance instance,iMeshP_PartitionHandle,iMeshP_RequestHandle **,int *,int *,int * err)1508 void iMeshP_pollForRequests( iMesh_Instance instance,
1509 iMeshP_PartitionHandle ,
1510 iMeshP_RequestHandle **,
1511 int *,
1512 int *,
1513 int *err)
1514 { FIXME; RETURN(iBase_NOT_SUPPORTED); }
1515
iMeshP_exchEntArrToPartsAll(iMesh_Instance instance,const iMeshP_PartitionHandle partition_handle,const iBase_EntityHandle * entity_handles,const int entity_handles_size,const iMeshP_Part * target_part_ids,int command_code,int update_ghost,iMeshP_RequestHandle *,int * err)1516 void iMeshP_exchEntArrToPartsAll( iMesh_Instance instance,
1517 const iMeshP_PartitionHandle partition_handle,
1518 const iBase_EntityHandle *entity_handles,
1519 const int entity_handles_size,
1520 const iMeshP_Part *target_part_ids,
1521 int command_code,
1522 int update_ghost,
1523 iMeshP_RequestHandle */*request*/,
1524 int *err )
1525 {
1526 if (command_code == 1) {
1527 std::cerr << "Entity migration option is not supported." << std::endl;
1528 RETURN(iBase_NOT_SUPPORTED);
1529 }
1530
1531 if (update_ghost == 1) {
1532 std::cerr << "Gost update option is not supported." << std::endl;
1533 RETURN(iBase_NOT_SUPPORTED);
1534 }
1535
1536 // make exchange entity and processor list
1537 ErrorCode rval;
1538 ParallelComm* pcomm = PCOMM;
1539 std::vector<unsigned int> exchange_procs;
1540 std::vector< Range* > exchange_ents;
1541
1542 for (int i = 0; i < entity_handles_size; i++) {
1543 int ind = -1;
1544 //iMeshP_Part target_p = target_part_ids[i];
1545 int target_p;
1546 rval = pcomm->get_part_owner(target_part_ids[i], target_p);
1547 CHKERR(rval,"ParallelComm::get_part_owner failed");
1548
1549 std::vector<unsigned int>::iterator vit =
1550 std::find(exchange_procs.begin(), exchange_procs.end(), target_p);
1551 if (vit == exchange_procs.end()) {
1552 ind = exchange_procs.size();
1553 exchange_procs.push_back(target_p);
1554 exchange_ents.push_back(new Range);
1555 }
1556 else ind = vit - exchange_procs.begin();
1557
1558 exchange_ents[ind]->insert(itaps_cast<EntityHandle>(entity_handles[i]));
1559 }
1560
1561 std::vector<MPI_Request> recv_ent_reqs, recv_remoteh_reqs;
1562 rval = pcomm->exchange_owned_meshs(exchange_procs, exchange_ents,
1563 recv_ent_reqs, recv_remoteh_reqs,
1564 true);
1565 CHKERR(rval,"ParallelComm::exchange_owned_meshs failed");
1566
1567 // delete exchange list
1568 std::vector<Range*>::iterator vit;
1569 for (vit = exchange_ents.begin(); vit != exchange_ents.end(); ++vit)
1570 delete (*vit);
1571
1572 RETURN (iBase_SUCCESS);
1573 }
1574
iMeshP_migrateEntity(iMesh_Instance instance,const iMeshP_PartitionHandle,const iMeshP_PartHandle,const iBase_EntityHandle,iMeshP_RequestHandle *,int * err)1575 void iMeshP_migrateEntity( iMesh_Instance instance,
1576 const iMeshP_PartitionHandle ,
1577 const iMeshP_PartHandle ,
1578 const iBase_EntityHandle ,
1579 iMeshP_RequestHandle *,
1580 int *err )
1581 { FIXME; RETURN(iBase_NOT_SUPPORTED); }
1582
iMeshP_updateVtxCoords(iMesh_Instance instance,const iMeshP_PartitionHandle,const iBase_EntityHandle,int * err)1583 void iMeshP_updateVtxCoords( iMesh_Instance instance,
1584 const iMeshP_PartitionHandle ,
1585 const iBase_EntityHandle ,
1586 int *err )
1587 { FIXME; RETURN(iBase_NOT_SUPPORTED); }
1588
iMeshP_replaceOnPartBdry(iMesh_Instance instance,const iMeshP_PartitionHandle,const iBase_EntityHandle *,const int,const iBase_EntityHandle *,const int,const int *,const int,int * err)1589 void iMeshP_replaceOnPartBdry( iMesh_Instance instance,
1590 const iMeshP_PartitionHandle ,
1591 const iBase_EntityHandle *,
1592 const int ,
1593 const iBase_EntityHandle *,
1594 const int ,
1595 const int *,
1596 const int ,
1597 int *err)
1598 { FIXME; RETURN(iBase_NOT_SUPPORTED); }
1599
iMeshP_addGhostOf(iMesh_Instance instance,const iMeshP_PartitionHandle,const iMeshP_Part,const iBase_EntityHandle,iMeshP_RequestHandle *,int * err)1600 void iMeshP_addGhostOf( iMesh_Instance instance,
1601 const iMeshP_PartitionHandle ,
1602 const iMeshP_Part ,
1603 const iBase_EntityHandle ,
1604 iMeshP_RequestHandle *,
1605 int *err)
1606 { FIXME; RETURN(iBase_NOT_SUPPORTED); }
1607
iMeshP_rmvGhostOf(iMesh_Instance instance,const iMeshP_PartitionHandle,const iMeshP_Part,const iBase_EntityHandle,int * err)1608 void iMeshP_rmvGhostOf( iMesh_Instance instance,
1609 const iMeshP_PartitionHandle ,
1610 const iMeshP_Part ,
1611 const iBase_EntityHandle ,
1612 int *err )
1613 { FIXME; RETURN(iBase_NOT_SUPPORTED); }
1614
iMeshP_syncMeshAll(iMesh_Instance instance,const iMeshP_PartitionHandle partition_handle,int * err)1615 void iMeshP_syncMeshAll( iMesh_Instance instance,
1616 const iMeshP_PartitionHandle partition_handle,
1617 int *err )
1618 {
1619 ParallelComm* pcomm = PCOMM;
1620 ErrorCode rval = pcomm->resolve_shared_ents(itaps_cast<EntityHandle>(partition_handle), -1, -1);
1621 CHKERR(rval,"update failed");
1622 RETURN (iBase_SUCCESS);
1623 }
1624
iMeshP_pushTags(iMesh_Instance instance,const iMeshP_PartitionHandle partition_handle,iBase_TagHandle source_tag,iBase_TagHandle dest_tag,int entity_type,int entity_topo,int * err)1625 void iMeshP_pushTags( iMesh_Instance instance,
1626 const iMeshP_PartitionHandle partition_handle,
1627 iBase_TagHandle source_tag,
1628 iBase_TagHandle dest_tag,
1629 int entity_type,
1630 int entity_topo,
1631 int *err )
1632 {
1633 ParallelComm* pcomm = PCOMM;
1634 DimensionPair types;
1635 if (entity_topo != iMesh_ALL_TOPOLOGIES)
1636 types.first = types.second = mb_topology_table[entity_topo];
1637 else if (entity_type != iBase_ALL_TYPES)
1638 types = CN::TypeDimensionMap[entity_type];
1639 else {
1640 types.first = MBVERTEX;
1641 types.second = MBENTITYSET;
1642 --types.second;
1643 }
1644
1645 std::vector<Tag> src_tags(1, itaps_cast<Tag>(source_tag));
1646 std::vector<Tag> dst_tags(1, itaps_cast<Tag>(dest_tag));
1647
1648 ErrorCode rval;
1649 Range entities;
1650 for (EntityType t = types.first; t <= types.second; ++t) {
1651 rval = MOABI->get_entities_by_type_and_tag( 0, t, &src_tags[0], 0, 1,
1652 entities, Interface::UNION );
1653 CHKERR(rval,"error getting entities to push");
1654 }
1655
1656 rval = pcomm->exchange_tags( src_tags, dst_tags, entities );
1657 CHKERR(rval,"tag data communication failed");
1658 RETURN (iBase_SUCCESS);
1659 }
1660
iMeshP_pushTagsEnt(iMesh_Instance instance,const iMeshP_PartitionHandle partition_handle,iBase_TagHandle source_tag,iBase_TagHandle dest_tag,const iBase_EntityHandle * entities,int entities_size,int * err)1661 void iMeshP_pushTagsEnt( iMesh_Instance instance,
1662 const iMeshP_PartitionHandle partition_handle,
1663 iBase_TagHandle source_tag,
1664 iBase_TagHandle dest_tag,
1665 const iBase_EntityHandle *entities,
1666 int entities_size,
1667 int *err )
1668 {
1669
1670 Range range;
1671 const EntityHandle* ents = itaps_cast<const EntityHandle*>(entities);
1672 std::copy( ents, ents+entities_size, range_inserter(range) );
1673
1674 std::vector<Tag> src_tags(1, itaps_cast<Tag>(source_tag));
1675 std::vector<Tag> dst_tags(1, itaps_cast<Tag>(dest_tag));
1676 ParallelComm* pcomm = PCOMM;
1677 ErrorCode rval = pcomm->exchange_tags( src_tags, dst_tags, range );
1678 CHKERR(rval,"tag data communication failed");
1679 RETURN (iBase_SUCCESS);
1680 }
1681
iMeshP_iPushTags(iMesh_Instance instance,const iMeshP_PartitionHandle,iBase_TagHandle,iBase_TagHandle,int,int,iMeshP_RequestHandle *,int * err)1682 void iMeshP_iPushTags( iMesh_Instance instance,
1683 const iMeshP_PartitionHandle ,
1684 iBase_TagHandle ,
1685 iBase_TagHandle ,
1686 int ,
1687 int ,
1688 iMeshP_RequestHandle *,
1689 int *err )
1690 { FIXME; RETURN(iBase_NOT_SUPPORTED); }
1691
iMeshP_iPushTagsEnt(iMesh_Instance instance,const iMeshP_PartitionHandle,iBase_TagHandle,iBase_TagHandle,const iBase_EntityHandle *,int,iMeshP_RequestHandle *,int * err)1692 void iMeshP_iPushTagsEnt( iMesh_Instance instance,
1693 const iMeshP_PartitionHandle ,
1694 iBase_TagHandle ,
1695 iBase_TagHandle ,
1696 const iBase_EntityHandle *,
1697 int ,
1698 iMeshP_RequestHandle *,
1699 int *err )
1700 { FIXME; RETURN(iBase_NOT_SUPPORTED); }
1701
iMeshP_createGhostEntsAll(iMesh_Instance instance,iMeshP_PartitionHandle partition_handle,int ghost_dim,int bridge_dim,int num_layers,int include_copies,int * err)1702 void iMeshP_createGhostEntsAll( iMesh_Instance instance,
1703 iMeshP_PartitionHandle partition_handle,
1704 int ghost_dim,
1705 int bridge_dim,
1706 int num_layers,
1707 int include_copies,
1708 int *err )
1709 {
1710 if (include_copies) {
1711 FIXME; RETURN(iBase_NOT_SUPPORTED);
1712 }
1713
1714 ParallelComm* pcomm = PCOMM;
1715 ErrorCode rval;
1716 if (iBase_ALL_TYPES == ghost_dim) ghost_dim = -1;
1717 rval = pcomm->exchange_ghost_cells( ghost_dim, bridge_dim, num_layers, 0, true );
1718 CHKERR(rval,"ghost exchange failed");
1719 RETURN(iBase_SUCCESS);
1720 }
1721
iMeshP_deleteGhostEntsAll(iMesh_Instance instance,iMeshP_PartitionHandle,int * err)1722 void iMeshP_deleteGhostEntsAll( iMesh_Instance instance,
1723 iMeshP_PartitionHandle ,
1724 int *err )
1725 { FIXME; RETURN(iBase_NOT_SUPPORTED); }
1726
iMeshP_ghostEntInfo(const iMesh_Instance instance,const iMeshP_PartitionHandle,int *,int *,int **,int **,int **,int * err)1727 void iMeshP_ghostEntInfo( const iMesh_Instance instance,
1728 const iMeshP_PartitionHandle ,
1729 int *,
1730 int *,
1731 int **,
1732 int **,
1733 int **,
1734 int *err )
1735 { FIXME; RETURN(iBase_NOT_SUPPORTED); }
1736
1737 // append the specified option if it isn't already there; returns whether this
1738 // function actually appended it or not
append_option(std::string & opt,const char * option,const char * default_value=0)1739 static bool append_option( std::string& opt,
1740 const char* option,
1741 const char* default_value = 0 )
1742 {
1743 std::string::size_type i;
1744
1745 const char sep = ' ';
1746
1747 if (strchr(option,sep) || (default_value && strchr(default_value,sep))) {
1748 // options can't have a separator in them; XXX work around this
1749 return iBase_INVALID_ARGUMENT;
1750 }
1751
1752 // search for the required option
1753 std::string search(&sep,1);
1754 search += option;
1755 const std::string::size_type sl = search.length();
1756 i = opt.find( search );
1757 while (i != std::string::npos) {
1758 std::string::size_type end = i + sl;
1759 if (end == opt.size() || opt[end] == sep || opt[end] == '=')
1760 break;
1761 i = end;
1762 }
1763
1764 // if string already contained the option, just return
1765 if (i != std::string::npos) return false;
1766
1767 opt += search;
1768 if (default_value) {
1769 opt += "=";
1770 opt += default_value;
1771 }
1772
1773 return true;
1774 }
1775
iMeshP_loadAll(iMesh_Instance instance,const iMeshP_PartitionHandle partition,const iBase_EntitySetHandle entity_set_handle,const char * name,const char * options,int * err,int name_len,int options_len)1776 void iMeshP_loadAll( iMesh_Instance instance,
1777 const iMeshP_PartitionHandle partition,
1778 const iBase_EntitySetHandle entity_set_handle,
1779 const char *name,
1780 const char *options,
1781 int *err,
1782 int name_len,
1783 int options_len )
1784 {
1785 ErrorCode rval;
1786
1787 // create partition set if user didn't give us one.
1788 EntityHandle partitioning;
1789 if (partition) {
1790 partitioning = itaps_cast<EntityHandle>(partition);
1791 }
1792 else {
1793 rval = MOABI->create_meshset( MESHSET_SET, partitioning );
1794 CHKERR(rval,"failed to create meshset");
1795 }
1796
1797 // get ParallelComm for partition
1798 MPI_Comm default_comm = MPI_COMM_WORLD;
1799 ParallelComm* pcomm = ParallelComm::get_pcomm( MOABI, partitioning, &default_comm );
1800 if (!pcomm) {
1801 RETURN (iBase_FAILURE);
1802 }
1803
1804 // add necessary values to options string
1805 std::string opt = std::string(options, options+options_len);
1806
1807 if (append_option( opt, "moab:PARALLEL" )) {
1808 // only append these other ones if the parallel option wasn't there originally
1809 append_option( opt, "moab:PARTITION_DISTRIBUTE" );
1810 append_option( opt, "moab:PARALLEL_RESOLVE_SHARED_ENTS" );
1811 std::ostringstream id;
1812 id << pcomm->get_id();
1813 append_option( opt, "moab:PCOMM", id.str().c_str() );
1814 }
1815
1816 // load the file
1817 iMesh_load( instance, entity_set_handle, name, opt.c_str(), err, name_len, opt.length() );
1818 if (*err) return;
1819
1820 rval = pcomm->collective_sync_partition();
1821 CHKERR(rval,"collective sync failed");
1822 RETURN(iBase_SUCCESS);
1823 }
1824
iMeshP_saveAll(iMesh_Instance instance,const iMeshP_PartitionHandle partition,const iBase_EntitySetHandle entity_set_handle,const char * name,const char * options,int * err,const int name_len,int options_len)1825 void iMeshP_saveAll( iMesh_Instance instance,
1826 const iMeshP_PartitionHandle partition,
1827 const iBase_EntitySetHandle entity_set_handle,
1828 const char *name,
1829 const char *options,
1830 int *err,
1831 const int name_len,
1832 int options_len )
1833 {
1834 EntityHandle set;
1835 set = entity_set_handle ? itaps_cast<EntityHandle>(entity_set_handle)
1836 : itaps_cast<EntityHandle>(partition);
1837 iMesh_save( instance, itaps_cast<iBase_EntitySetHandle>(set),
1838 name, options, err, name_len, options_len );
1839
1840 }
1841
1842
1843
1844
1845 // Map from processes to parts:
1846 // Given a partition handle and a process rank,
1847 // return the part handles owned by the process.
1848 // COMMUNICATION: None++.
iMeshP_getPartsOnRank(iMesh_Instance instance,const iMeshP_PartitionHandle partition_handle,const int,iMeshP_PartHandle ** part_handles,int * part_handles_allocated,int * part_handles_size,int * err)1849 void iMeshP_getPartsOnRank(iMesh_Instance instance,
1850 const iMeshP_PartitionHandle partition_handle,
1851 /*in*/ const int /*rank*/,
1852 /*inout*/ iMeshP_PartHandle **part_handles,
1853 /*inout*/ int *part_handles_allocated,
1854 /*out*/ int *part_handles_size,
1855 int *err)
1856 {
1857 EntityHandle p = itaps_cast<EntityHandle>(partition_handle);
1858 ParallelComm *pc = ParallelComm::get_pcomm(MOABI, p);
1859 if (!pc) RETURN(iBase_ERROR_MAP[MB_FAILURE]);
1860
1861 Range part_sets;
1862
1863 ALLOC_CHECK_ARRAY_NOFAIL( part_handles, pc->partition_sets().size() );
1864 Range::iterator rit;
1865 int i;
1866 for (i = 0, rit = pc->partition_sets().begin();
1867 rit != pc->partition_sets().end(); ++rit, i++)
1868 (*part_handles)[i] = itaps_cast<iMeshP_PartHandle>(*rit);
1869
1870 RETURN(iBase_SUCCESS);
1871 }
1872
iMeshP_getPartsArrOnRank(iMesh_Instance instance,const iMeshP_PartitionHandle partition_handle,const int * rank,const int rank_size,iMeshP_PartHandle ** part_handles,int * part_handles_allocated,int * part_handles_size,int * err)1873 void iMeshP_getPartsArrOnRank(iMesh_Instance instance,
1874 const iMeshP_PartitionHandle partition_handle,
1875 /*in*/ const int *rank,
1876 /*in*/ const int rank_size,
1877 /*inout*/ iMeshP_PartHandle **part_handles,
1878 /*inout*/ int *part_handles_allocated,
1879 /*out*/ int *part_handles_size,
1880 int *err)
1881 {
1882 EntityHandle p = itaps_cast<EntityHandle>(partition_handle);
1883 ParallelComm *pc = ParallelComm::get_pcomm(MOABI, p);
1884 if (!pc) RETURN(iBase_ERROR_MAP[MB_FAILURE]);
1885
1886 if (rank[0] != (int)pc->proc_config().proc_rank() || rank_size > 1) {
1887 RETURN(iBase_ERROR_MAP[MB_NOT_IMPLEMENTED]);
1888 }
1889
1890 iMeshP_getPartsOnRank(instance, partition_handle, rank[0],
1891 part_handles, part_handles_allocated, part_handles_size,
1892 err);
1893 }
1894
1895 /** \brief Assign a global id space to entities
1896 * Assign a global id space to entities and vertices, and optionally intermediate-dimension entities
1897 *
1898 * COMMUNICATION: Collective.
1899 */
iMeshP_assignGlobalIds(iMesh_Instance instance,const iMeshP_PartitionHandle partition,const iBase_EntitySetHandle this_set,const int dimension,const int start_id,const int largest_dim_only,const int parallel,const int owned_only,int * err)1900 void iMeshP_assignGlobalIds(
1901 iMesh_Instance instance,
1902 const iMeshP_PartitionHandle partition,
1903 const iBase_EntitySetHandle this_set,
1904 const int dimension,
1905 const int start_id,
1906 const int largest_dim_only,
1907 const int parallel,
1908 const int owned_only,
1909 int *err)
1910 {
1911 ErrorCode rval;
1912
1913 // get partition set
1914 EntityHandle partitionset = itaps_cast<EntityHandle>(partition);
1915 if (!partitionset) {
1916 rval = MB_FAILURE;
1917 CHKERR(rval,"failed to get partition set");
1918 }
1919
1920 EntityHandle this_mb_set = itaps_cast<EntityHandle>(this_set);
1921
1922 // get ParallelComm for partition
1923 MPI_Comm default_comm;
1924 ParallelComm* pcomm = ParallelComm::get_pcomm( MOABI, partitionset, &default_comm );
1925 if (!pcomm) {
1926 RETURN (iBase_FAILURE);
1927 }
1928
1929 rval = pcomm->assign_global_ids(this_mb_set, dimension, start_id, largest_dim_only, parallel, owned_only);
1930
1931 RETURN(rval);
1932 }
1933
iMeshP_getCommunicator(iMesh_Instance instance,int * fcomm,MPI_Comm * ccomm,int * err)1934 void iMeshP_getCommunicator(
1935 iMesh_Instance instance,
1936 int *fcomm,
1937 MPI_Comm *ccomm,
1938 int *err)
1939 {
1940 *ccomm = MPI_Comm_f2c(*fcomm);
1941 RETURN(iBase_SUCCESS);
1942 }
1943
1944 #ifdef __cplusplus
1945 } // extern "C"
1946 #endif
1947