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