MOAB: Mesh Oriented datABase  (version 5.5.0)
pcomm_unit.cpp
Go to the documentation of this file.
1 #include "moab/ParallelComm.hpp"
3 #include "MBTagConventions.hpp"
4 #include "moab/Core.hpp"
5 #include "moab/MeshTopoUtil.hpp"
6 #include "ReadParallel.hpp"
7 #include "moab/FileOptions.hpp"
8 #include "TestUtil.hpp"
9 #include <algorithm>
10 #include <vector>
11 #include <set>
12 #include <sstream>
13 
14 using namespace moab;
15 
16 #ifdef MOAB_HAVE_MPI
17 #include "moab_mpi.h"
18 #else
19 #define MPI_COMM_WORLD 0
20 #endif
21 
22 /** Test pack/unpack of vertices */
23 void test_pack_vertices();
24 /** Test pack/unpack of elements */
25 void test_pack_elements();
26 /** Test pack/unpack of higher-order elements */
28 /** Test pack/unpack of polygons & polyhedra */
29 void test_pack_poly();
30 /** Test pack/unpack of entity sets */
32 /** Test pack/unpack of entity sets including implicit packing of set contents */
34 /** Test pack/unpack of entity sets containing entity sets */
36 /** Test pack/unpack of set parent/child relations */
38 /** Test pack/unpack tag values*/
42 /** Test pack/unpack tag values*/
44 /** Test pack/unpack of variable length tag values*/
46 /** Test pack/unpack tag values*/
48 /** Test pack/unpack of shared entities in 2d*/
50 /** Test pack/unpack of shared entities in 3d*/
52 /** Test filter_pstatus function*/
53 void test_filter_pstatus();
54 /** Test creating a new ParallelComm instance in addition to an existing one*/
56 
57 int rank = 0;
58 
59 int main( int argc, char* argv[] )
60 {
61 #ifdef MOAB_HAVE_MPI
62  MPI_Init( &argc, &argv );
63  MPI_Comm_rank( MPI_COMM_WORLD, &rank );
64 #endif
65 
66  int num_err = 0;
67  num_err += RUN_TEST( test_pack_vertices );
68  num_err += RUN_TEST( test_pack_elements );
69  num_err += RUN_TEST( test_pack_higher_order );
70  num_err += RUN_TEST( test_pack_poly );
71  num_err += RUN_TEST( test_pack_sets_simple );
72  num_err += RUN_TEST( test_pack_set_contents );
73  num_err += RUN_TEST( test_pack_sets_of_sets );
75  num_err += RUN_TEST( test_pack_tag_data_sparse );
76  num_err += RUN_TEST( test_pack_tag_data_dense );
78  // num_err += RUN_TEST( test_pack_bit_tag_data );
80  num_err += RUN_TEST( test_pack_tag_handle_data );
83  num_err += RUN_TEST( test_filter_pstatus );
84  num_err += RUN_TEST( test_new_pcomm_instance );
85 
86 #ifdef MOAB_HAVE_MPI
87  MPI_Finalize();
88 #endif
89  return num_err;
90 }
91 
92 /* Utility method: pack mesh data, clear moab instance, and unpack */
94 {
95  ErrorCode rval;
96  if( entities.empty() )
97  {
98  rval = moab.get_entities_by_handle( 0, entities );CHECK_ERR( rval );
99  }
100 
101  ParallelComm* pcomm = new ParallelComm( &moab, MPI_COMM_WORLD );
102 
103  // get the necessary vertices too
104  Range tmp_range = entities.subset_by_type( MBENTITYSET );
105  entities = subtract( entities, tmp_range );
106  rval = moab.get_adjacencies( entities, 0, false, entities, Interface::UNION );CHECK_ERR( rval );
107  entities.merge( tmp_range );
108 
110  buff.reset_ptr( sizeof( int ) );
111  rval = pcomm->pack_buffer( entities, false, true, false, -1, &buff );CHECK_ERR( rval );
112  buff.set_stored_size();
113 
114  delete pcomm;
115  moab.~Core();
116 
117  new( &moab ) Core();
118  pcomm = new ParallelComm( &moab, MPI_COMM_WORLD );
119 
120  entities.clear();
121  std::vector< std::vector< EntityHandle > > L1hloc, L1hrem;
122  std::vector< std::vector< int > > L1p;
123  std::vector< EntityHandle > L2hloc, L2hrem;
124  std::vector< unsigned int > L2p;
125  buff.reset_ptr( sizeof( int ) );
126  std::vector< EntityHandle > entities_vec( entities.size() );
127  std::copy( entities.begin(), entities.end(), entities_vec.begin() );
128  rval = pcomm->unpack_buffer( buff.buff_ptr, false, -1, -1, L1hloc, L1hrem, L1p, L2hloc, L2hrem, L2p, entities_vec );CHECK_ERR( rval );
129  std::copy( entities_vec.begin(), entities_vec.end(), range_inserter( entities ) );
130 
131  delete pcomm;
132 }
134 {
135  Range empty;
136  pack_unpack_noremoteh( moab, empty );
137 }
138 
139 /* Utility method -- check expected sizes */
141  int num_vtx,
142  int num_edge,
143  int num_tri,
144  int num_quad,
145  int num_polygon,
146  int num_tet,
147  int num_pyr,
148  int num_wedge,
149  int num_knife,
150  int num_hex,
151  int num_polyhedron )
152 {
153  int count;
154  ErrorCode rval;
155 
156  rval = moab.get_number_entities_by_type( 0, MBVERTEX, count );CHECK_ERR( rval );
157  CHECK_EQUAL( num_vtx, count );
158 
159  rval = moab.get_number_entities_by_type( 0, MBEDGE, count );CHECK_ERR( rval );
160  CHECK_EQUAL( num_edge, count );
161 
162  rval = moab.get_number_entities_by_type( 0, MBTRI, count );CHECK_ERR( rval );
163  CHECK_EQUAL( num_tri, count );
164 
165  rval = moab.get_number_entities_by_type( 0, MBQUAD, count );CHECK_ERR( rval );
166  CHECK_EQUAL( num_quad, count );
167 
168  rval = moab.get_number_entities_by_type( 0, MBPOLYGON, count );CHECK_ERR( rval );
169  CHECK_EQUAL( num_polygon, count );
170 
171  rval = moab.get_number_entities_by_type( 0, MBTET, count );CHECK_ERR( rval );
172  CHECK_EQUAL( num_tet, count );
173 
174  rval = moab.get_number_entities_by_type( 0, MBPYRAMID, count );CHECK_ERR( rval );
175  CHECK_EQUAL( num_pyr, count );
176 
177  rval = moab.get_number_entities_by_type( 0, MBPRISM, count );CHECK_ERR( rval );
178  CHECK_EQUAL( num_wedge, count );
179 
180  rval = moab.get_number_entities_by_type( 0, MBKNIFE, count );CHECK_ERR( rval );
181  CHECK_EQUAL( num_knife, count );
182 
183  rval = moab.get_number_entities_by_type( 0, MBHEX, count );CHECK_ERR( rval );
184  CHECK_EQUAL( num_hex, count );
185 
186  rval = moab.get_number_entities_by_type( 0, MBPOLYHEDRON, count );CHECK_ERR( rval );
187  CHECK_EQUAL( num_polyhedron, count );
188 }
189 
190 /* Create a simple mesh for use in tests */
191 void create_simple_grid( Interface& moab, unsigned x, unsigned y, unsigned z );
192 void create_simple_grid( Interface& moab, unsigned xyz = 3 )
193 {
194  create_simple_grid( moab, xyz, xyz, xyz );
195 }
196 void create_simple_grid( Interface& moab, unsigned x, unsigned y, unsigned z )
197 {
198  ErrorCode rval;
199  EntityHandle* verts = new EntityHandle[x * y * z];
200  for( unsigned k = 0; k < z; ++k )
201  for( unsigned j = 0; j < y; ++j )
202  for( unsigned i = 0; i < x; ++i )
203  {
204  const double coords[3] = { static_cast< double >( i ), static_cast< double >( j ),
205  static_cast< double >( k ) };
206  rval = moab.create_vertex( coords, verts[x * y * k + x * j + i] );CHECK_ERR( rval );
207  }
208 
209  EntityHandle* elems = new EntityHandle[( x - 1 ) * ( y - 1 ) * ( z - 1 )];
210  for( unsigned k = 0; k < ( z - 1 ); ++k )
211  for( unsigned j = 0; j < ( y - 1 ); ++j )
212  for( unsigned i = 0; i < ( x - 1 ); ++i )
213  {
214  const size_t idx = (size_t)i + (size_t)j * x + (size_t)k * x * y;
215  const EntityHandle conn[8] = {
216  verts[idx], verts[idx + 1], verts[idx + x + 1], verts[idx + x],
217  verts[idx + x * y], verts[idx + x * y + 1], verts[idx + x * y + x + 1], verts[idx + x * y + x] };
218  rval = moab.create_element( MBHEX, conn, 8, elems[( x - 1 ) * ( y - 1 ) * k + ( x - 1 ) * j + i] );CHECK_ERR( rval );
219  }
220  delete[] verts;
221  delete[] elems;
222 }
223 
224 ErrorCode create_patch( Interface* moab, Range& verts, Range& quads, unsigned int n, double* xyz, int* gids )
225 {
226  // create vertices/quads in square array
227  ErrorCode result = moab->create_vertices( xyz, n * n, verts );
228  if( MB_SUCCESS != result ) return result;
229  std::vector< EntityHandle > connect;
230  for( unsigned int j = 0; j < n - 1; j++ )
231  {
232  for( unsigned int i = 0; i < n - 1; i++ )
233  {
234  connect.push_back( verts[n * j + i] );
235  connect.push_back( verts[n * j + i + 1] );
236  connect.push_back( verts[n * ( j + 1 ) + i + 1] );
237  connect.push_back( verts[n * ( j + 1 ) + i] );
238  }
239  }
240 
241  unsigned int nquads = ( n - 1 ) * ( n - 1 );
242  for( unsigned int i = 0; i < nquads; i++ )
243  {
244  EntityHandle dum_quad;
245  result = moab->create_element( MBQUAD, &connect[4 * i], 4, dum_quad );
246  if( MB_SUCCESS != result ) return result;
247  quads.insert( dum_quad );
248  }
249 
250  // global ids
251  Tag gid_tag = moab->globalId_tag();
252  result = moab->tag_set_data( gid_tag, verts, gids );
253  if( MB_SUCCESS != result ) return result;
254 
255  return result;
256 }
257 
259 {
260  //
261  // P2______
262  // /__/__/ /|P1
263  // y: /__/__/ /||
264  // 1 _____ ||/ _____ 1
265  // | | | |/|-1 | | |
266  // .5 |__|__| ||/ |__|__| .5
267  // |P0| | |/-.5 |P3| |
268  // 0 |__|__| z:0 |__|__| 0
269  // x:-1 -.5 0 0 .5 1
270  //
271  // nodes: P2
272  // 18 16 14 P1
273  // 17 15 13 14
274  // 6 7 8 13 12
275  // 8 11 10
276  // 6 7 8 5 9 8 23 24 P3
277  // 3 4 5 2 5 21 22
278  // P0 0 1 2 2 19 20
279 
280  int gids[] = {
281  0, 1, 2, 3, 4, 5, 6, 7, 8, // P0
282  2, 9, 10, 5, 11, 12, 8, 13, 14, // P1
283  6, 7, 8, 17, 15, 13, 18, 16, 14, // P2
284  2, 19, 20, 5, 21, 22, 8, 23, 24 // P3
285  };
286  double xyz[] = {
287  -1.0, 0.0, 0.0, -0.5, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.5, 0.0, -0.5, 0.5, 0.0, 0.0, 0.5, 0.0,
288  -1.0, 1.0, 0.0, -0.5, 1.0, 0.0, 0.0, 1.0, 0.0, // n0-8
289  0.0, 0.0, -0.5, 0.0, 0.0, -1.0, 0.0, 0.5, -0.5, 0.0, 0.5, -1.0, 0.0, 1.0, -0.5, 0.0, 1.0, -1.0, // n9-14
290  -0.5, 1.0, -0.5, -0.5, 1.0, -1.0, -1.0, 1.0, -0.5, -1.0, 1.0, -1.0, // n15-18
291  0.5, 0.0, 0.0, 1.0, 0.0, 0.0, 0.5, 0.5, 0.0, 1.0, 0.5, 0.0, 0.5, 1.0, 0.0, 1.0, 1.0, 0.0, // n19-24
292  };
293  double xyztmp[27];
294 
295  // create the test mesh above
296  for( unsigned int i = 0; i < 4; i++ )
297  {
298  for( unsigned int j = 0; j < 9; j++ )
299  {
300  xyztmp[3 * j] = xyz[3 * gids[9 * i + j]];
301  xyztmp[3 * j + 1] = xyz[3 * gids[9 * i + j] + 1];
302  xyztmp[3 * j + 2] = xyz[3 * gids[9 * i + j] + 2];
303  }
304 
305  create_patch( pc[i]->get_moab(), verts[i], quads[i], 3, xyztmp, &gids[9 * i] );
306  }
307 
308  ErrorCode rval = ParallelComm::resolve_shared_ents( pc, 4, 0, 2 );CHECK_ERR( rval );
309 
310  return rval;
311 }
312 
314 {
315  //
316  // 4 _____ _____
317  // | | | | | |
318  // 3|__|__| |__|__| GIDS HANDLES
319  // |P1| | |P2| |
320  // |__|__| |__|__| 20 21 22 22 23 24 7 8 9 7 8 9
321  // 2 ___________ 15 16 17 17 18 19 4 5 6 4 5 6
322  // | | | | | 10 11 12 12 13 14 1 2 3 1 2 3
323  // / 1|__|__|__|__|
324  // | | |P0| | | 10 11 12 13 14 10 11 12 13 14
325  // J 0|__|__|__|__| 5 6 7 8 9 5 6 7 8 9
326  // I-> 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4
327  //
328  // P3 - k = 2..4
329 
330  // create structured meshes
331  // ijkmin[p][ijk], ijkmax[p][ijk]
332 #define P 4
333  int ijkmin[P][3] = { { 0, 0, 0 }, { 0, 2, 0 }, { 2, 2, 0 }, { 0, 0, 2 } };
334  int ijkmax[P][3] = { { 4, 2, 2 }, { 2, 4, 2 }, { 4, 4, 2 }, { 4, 4, 4 } };
335 
336  int nijk[P][3];
337  int NIJK[3] = { 0, 0, 0 };
338 #define INDEXG( i, j, k ) ( (k)*NIJK[1] * NIJK[0] + (j)*NIJK[0] + ( i ) )
339 #define INDEXL( i, j, k ) \
340  ( ( (k)-ijkmin[p][2] ) * nijk[p][1] * nijk[p][0] + ( (j)-ijkmin[p][1] ) * nijk[p][0] + ( (i)-ijkmin[p][0] ) )
341 
342  int p, i, j, k;
343  for( p = 0; p < P; p++ )
344  {
345  for( i = 0; i < 3; i++ )
346  {
347  nijk[p][i] = ijkmax[p][i] - ijkmin[p][i] + 1;
348  NIJK[i] = std::max( NIJK[i], nijk[p][i] );
349  }
350  }
351 
352  std::vector< int > gids;
353  std::vector< double > xyz;
354  ErrorCode rval;
355  Tag gid_tag;
356 
357  for( p = 0; p < P; p++ )
358  {
359  gid_tag = pc[p]->get_moab()->globalId_tag();
360 
361  // make vertices
362  int nverts = nijk[p][0] * nijk[p][1] * nijk[p][2];
363  xyz.resize( 3 * nverts );
364  gids.resize( nverts );
365 
366  // set vertex gids
367  int nv = 0;
368  for( k = ijkmin[p][2]; k <= ijkmax[p][2]; k++ )
369  for( j = ijkmin[p][1]; j <= ijkmax[p][1]; j++ )
370  for( i = ijkmin[p][0]; i <= ijkmax[p][0]; i++ )
371  {
372  // xyz
373  xyz[3 * nv] = i;
374  xyz[3 * nv + 1] = j;
375  xyz[3 * nv + 2] = k;
376 
377  // gid
378  gids[nv++] = INDEXG( i, j, k );
379  }
380 
381  rval = pc[p]->get_moab()->create_vertices( &xyz[0], nverts, verts[p] );CHECK_ERR( rval );
382 
383  rval = pc[p]->get_moab()->tag_set_data( gid_tag, verts[p], &gids[0] );
384  if( MB_SUCCESS != rval ) return rval;
385 
386  // make elements
387  nv = 0;
388  EntityHandle connect[8], dum_hex;
389  for( k = ijkmin[p][2]; k < ijkmax[p][2]; k++ )
390  for( j = ijkmin[p][1]; j < ijkmax[p][1]; j++ )
391  for( i = ijkmin[p][0]; i < ijkmax[p][0]; i++ )
392  {
393  // gid
394  connect[0] = verts[p][INDEXL( i, j, k )];
395  connect[1] = verts[p][INDEXL( i + 1, j, k )];
396  connect[2] = verts[p][INDEXL( i + 1, j + 1, k )];
397  connect[3] = verts[p][INDEXL( i, j + 1, k )];
398  connect[4] = verts[p][INDEXL( i, j, k + 1 )];
399  connect[5] = verts[p][INDEXL( i + 1, j, k + 1 )];
400  connect[6] = verts[p][INDEXL( i + 1, j + 1, k + 1 )];
401  connect[7] = verts[p][INDEXL( i, j + 1, k + 1 )];
402  rval = pc[p]->get_moab()->create_element( MBHEX, connect, 8, dum_hex );
403  hexes[p].insert( dum_hex );
404  gids[nv++] = INDEXG( i, j, k );
405  }
406  rval = pc[p]->get_moab()->tag_set_data( gid_tag, hexes[p], &gids[0] );
407  if( MB_SUCCESS != rval ) return rval;
408 
409  std::ostringstream fname;
410  fname << "tmp" << p << "." << rank << ".h5m";
411  rval = pc[p]->get_moab()->write_file( fname.str().c_str() );
412  if( MB_SUCCESS != rval ) return rval;
413  }
414  rval = ParallelComm::resolve_shared_ents( pc, 4, 0, 3 );CHECK_ERR( rval );
415  return rval;
416 }
417 
419 {
420  Core moab;
421  ErrorCode rval;
422  Range verts;
423 
424  const size_t num_verts = 4;
425  const double coords[3 * num_verts] = { -0.5, -1. / 3, 0.0, 0.5, -1. / 3, 0.0,
426  0.0, 2. / 3, 0.0, 0.0, 0.0, 0.745356 };
427 
428  rval = moab.create_vertices( coords, num_verts, verts );CHECK_ERR( rval );
429 
430  pack_unpack_noremoteh( moab, verts );
431  CHECK_EQUAL( num_verts, verts.size() );
432 
433  double coords2[3 * num_verts];
434  rval = moab.get_coords( verts, coords2 );CHECK_ERR( rval );
435 
436  std::vector< bool > seen( num_verts, false );
437  for( unsigned i = 0; i < num_verts; ++i )
438  {
439  unsigned j;
440  for( j = 0; j < num_verts; ++j )
441  if( coords[3 * j] == coords2[3 * i] && coords[3 * j + 1] == coords2[3 * i + 1] &&
442  coords[3 * j + 2] == coords2[3 * i + 2] )
443  break;
444  CHECK( j < num_verts );
445  CHECK( !seen[j] );
446  seen[j] = true;
447  }
448 }
449 
451 {
452  Core moab;
453  ErrorCode rval;
454  Range elems;
455 
456  // define some vertices
457  const size_t num_verts = 12;
458  EntityHandle verts[num_verts];
459  const double hex_corners[3 * num_verts] = { -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 0, 1, -1, 0,
460  1, 1, 0, -1, 1, 0, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1 };
461  for( size_t i = 0; i < num_verts; ++i )
462  {
463  rval = moab.create_vertex( hex_corners + 3 * i, verts[i] );CHECK_ERR( rval );
464  }
465 
466  // define two adjacent hexes
467  const size_t num_hex = 2;
468  EntityHandle hexes[num_hex];
469  rval = moab.create_element( MBHEX, verts, 8, hexes[0] );CHECK_ERR( rval );
470  elems.insert( hexes[0] );
471  rval = moab.create_element( MBHEX, verts + 4, 8, hexes[1] );CHECK_ERR( rval );
472  elems.insert( hexes[1] );
473 
474  // define a single quad on the adjacent sides of the hexes
475  const size_t num_quad = 1;
476  EntityHandle quad;
477  rval = moab.create_element( MBQUAD, verts + 4, 4, quad );CHECK_ERR( rval );
478  elems.insert( quad );
479 
480  // define a decomposition of the first hex into 5 tets
481  const size_t num_tet = 5;
482  EntityHandle tets[num_tet];
483  EntityHandle tet_conn[num_tet][4] = { { verts[0], verts[1], verts[3], verts[4] },
484  { verts[1], verts[2], verts[3], verts[6] },
485  { verts[1], verts[3], verts[4], verts[6] },
486  { verts[4], verts[6], verts[5], verts[1] },
487  { verts[7], verts[6], verts[4], verts[3] } };
488  rval = moab.create_element( MBTET, tet_conn[0], 4, tets[0] );CHECK_ERR( rval );
489  elems.insert( tets[0] );
490  rval = moab.create_element( MBTET, tet_conn[1], 4, tets[1] );CHECK_ERR( rval );
491  elems.insert( tets[1] );
492  rval = moab.create_element( MBTET, tet_conn[2], 4, tets[2] );CHECK_ERR( rval );
493  elems.insert( tets[2] );
494  rval = moab.create_element( MBTET, tet_conn[3], 4, tets[3] );CHECK_ERR( rval );
495  elems.insert( tets[3] );
496  rval = moab.create_element( MBTET, tet_conn[4], 4, tets[4] );CHECK_ERR( rval );
497  elems.insert( tets[4] );
498 
499  // define the 4 shared faces of the above tets as tris
500  // (the faces of the 3rd tet)
501  const size_t num_tri = 4;
502  EntityHandle tris[num_tri];
503  EntityHandle tri_conn[num_tri][3] = { { verts[3], verts[1], verts[4] },
504  { verts[1], verts[6], verts[4] },
505  { verts[1], verts[3], verts[6] },
506  { verts[3], verts[4], verts[6] } };
507  rval = moab.create_element( MBTRI, tri_conn[0], 3, tris[0] );CHECK_ERR( rval );
508  elems.insert( tris[0] );
509  rval = moab.create_element( MBTRI, tri_conn[1], 3, tris[1] );CHECK_ERR( rval );
510  elems.insert( tris[1] );
511  rval = moab.create_element( MBTRI, tri_conn[2], 3, tris[2] );CHECK_ERR( rval );
512  elems.insert( tris[2] );
513  rval = moab.create_element( MBTRI, tri_conn[3], 3, tris[3] );CHECK_ERR( rval );
514  elems.insert( tris[3] );
515 
516  // define a decomposition of the second hex into two wedges
517  const size_t num_wedge = 2;
518  EntityHandle wedges[num_wedge];
519  EntityHandle wedge_conn[num_wedge][6] = { { verts[4], verts[5], verts[7], verts[8], verts[9], verts[11] },
520  { verts[5], verts[6], verts[7], verts[9], verts[10], verts[11] } };
521  rval = moab.create_element( MBPRISM, wedge_conn[0], 6, wedges[0] );CHECK_ERR( rval );
522  elems.insert( wedges[0] );
523  rval = moab.create_element( MBPRISM, wedge_conn[1], 6, wedges[1] );CHECK_ERR( rval );
524  elems.insert( wedges[1] );
525 
526  // define a pyramid
527  EntityHandle pyr;
528  rval = moab.create_element( MBPYRAMID, verts, 5, pyr );CHECK_ERR( rval );
529  elems.insert( pyr );
530 
531  // pack and unpack mesh
532  pack_unpack_noremoteh( moab, elems );
533 
534  // check_counts
535  check_sizes( moab, num_verts, 0, num_tri, num_quad, 0, num_tet, 1, num_wedge, 0, num_hex, 0 );
536 
537  // get connectivity for two hexes and a quad
538  Range range;
539  const EntityHandle *conn1, *conn2, *conn3;
540  int len1, len2, len3;
541  rval = moab.get_entities_by_type( 0, MBHEX, range );CHECK_ERR( rval );
542  CHECK_EQUAL( num_hex, range.size() );
543  rval = moab.get_connectivity( range.front(), conn1, len1, true );CHECK_ERR( rval );
544  CHECK_EQUAL( 8, len1 );
545  rval = moab.get_connectivity( range.back(), conn2, len2, true );CHECK_ERR( rval );
546  CHECK_EQUAL( 8, len2 );
547  range.clear();
548  rval = moab.get_entities_by_type( 0, MBQUAD, range );CHECK_ERR( rval );
549  CHECK_EQUAL( num_quad, range.size() );
550  rval = moab.get_connectivity( range.front(), conn3, len3, true );CHECK_ERR( rval );
551  CHECK_EQUAL( 4, len3 );
552 
553  // Check if hexes are reversed
554  if( conn1[0] == conn2[4] )
555  {
556  std::swap( conn1, conn2 );
557  }
558 
559  // Check consistant connectivity between hexes
560  CHECK_EQUAL( conn1[4], conn2[0] );
561  CHECK_EQUAL( conn1[5], conn2[1] );
562  CHECK_EQUAL( conn1[6], conn2[2] );
563  CHECK_EQUAL( conn1[7], conn2[3] );
564  // Check connectivity of quad on shared face
565  CHECK_EQUAL( conn1[4], conn3[0] );
566  CHECK_EQUAL( conn1[5], conn3[1] );
567  CHECK_EQUAL( conn1[6], conn3[2] );
568  CHECK_EQUAL( conn1[7], conn3[3] );
569  // Check coordinates
570  const EntityHandle combined[12] = { conn1[0], conn1[1], conn1[2], conn1[3], conn3[0], conn3[1],
571  conn3[2], conn3[3], conn2[4], conn2[5], conn2[6], conn2[7] };
572  double coords[36];
573  rval = moab.get_coords( combined, 12, coords );CHECK_ERR( rval );
574  for( int i = 0; i < 36; ++i )
575  {
576  CHECK_REAL_EQUAL( hex_corners[i], coords[i], 1e-12 );
577  }
578 }
579 
581 {
582  Core moab;
583  ErrorCode rval;
584  Range elems;
585 
586  // define coordinates for a pyramid decomposed
587  // into two 10-node tets
588  const size_t num_vert = 14;
589  const double coords[3 * num_vert] = { -1, -1, 0, 0, -1, 0, 1, -1, 0, 1, 0, 0, 1, 1,
590  0, 0, 1, 0, -1, 1, 0, -1, 0, 0, 0, 0, 0, 0,
591  0, 1, -.5, -.5, .5, .5, -.5, .5, .5, .5, .5, -.5, .5, .5 };
592  EntityHandle verts[num_vert];
593  for( size_t i = 0; i < num_vert; ++i )
594  {
595  rval = moab.create_vertex( coords + 3 * i, verts[i] );CHECK_ERR( rval );
596  }
597 
598  // define two tets
599  const size_t num_tet = 2;
600  EntityHandle tet_conn[2][10] = {
601  { verts[0], verts[4], verts[9], verts[2], verts[8], verts[12], verts[10], verts[1], verts[3], verts[11] },
602  { verts[0], verts[9], verts[4], verts[6], verts[10], verts[12], verts[8], verts[7], verts[13], verts[5] } };
603 
604  EntityHandle tets[num_tet];
605  rval = moab.create_element( MBTET, tet_conn[0], 10, tets[0] );CHECK_ERR( rval );
606  elems.insert( tets[0] );
607  rval = moab.create_element( MBTET, tet_conn[1], 10, tets[1] );CHECK_ERR( rval );
608  elems.insert( tets[1] );
609 
610  // define interior tri face
611  const size_t num_tri = 1;
612  EntityHandle tri_conn[6] = { verts[0], verts[4], verts[9], verts[8], verts[12], verts[10] };
613  EntityHandle tri;
614  rval = moab.create_element( MBTRI, tri_conn, 6, tri );CHECK_ERR( rval );
615  elems.insert( tri );
616 
617  // pack and unpack mesh
618  pack_unpack_noremoteh( moab, elems );
619 
620  // check_counts
621  check_sizes( moab, num_vert, 0, num_tri, 0, 0, num_tet, 0, 0, 0, 0, 0 );
622 
623  // get connectivity for two tets and a tri
624  Range range;
625  const EntityHandle *conn1, *conn2, *conn3;
626  int len1, len2, len3;
627  rval = moab.get_entities_by_type( 0, MBTET, range );CHECK_ERR( rval );
628  CHECK_EQUAL( num_tet, range.size() );
629  rval = moab.get_connectivity( range.front(), conn1, len1, false );CHECK_ERR( rval );
630  CHECK_EQUAL( 10, len1 );
631  rval = moab.get_connectivity( range.back(), conn2, len2, false );CHECK_ERR( rval );
632  CHECK_EQUAL( 10, len2 );
633  range.clear();
634  rval = moab.get_entities_by_type( 0, MBTRI, range );CHECK_ERR( rval );
635  CHECK_EQUAL( num_tri, range.size() );
636  rval = moab.get_connectivity( range.front(), conn3, len3, false );CHECK_ERR( rval );
637  CHECK_EQUAL( 6, len3 );
638 
639  // The first face of one of the tets is in the
640  // same order as the tri.
641  if( conn3[1] != conn1[1] ) std::swap( conn1, conn2 );
642 
643  // check consistant connectivity for face shared by tets
644  CHECK_EQUAL( conn1[0], conn2[0] );
645  CHECK_EQUAL( conn1[1], conn2[2] );
646  CHECK_EQUAL( conn1[2], conn2[1] );
647  CHECK_EQUAL( conn1[4], conn2[6] );
648  CHECK_EQUAL( conn1[5], conn2[5] );
649  CHECK_EQUAL( conn1[6], conn2[4] );
650  // check connsistant connectivity between tet face and tri
651  CHECK_EQUAL( conn1[0], conn3[0] );
652  CHECK_EQUAL( conn1[1], conn3[1] );
653  CHECK_EQUAL( conn1[2], conn3[2] );
654  CHECK_EQUAL( conn1[4], conn3[3] );
655  CHECK_EQUAL( conn1[5], conn3[4] );
656  CHECK_EQUAL( conn1[6], conn3[5] );
657 
658  // order vertex handles corresponding to original coordinate list
659  const EntityHandle combined[num_vert] = { conn1[0], conn1[7], conn1[3], conn1[8], conn1[1], conn2[9], conn2[3],
660  conn2[7], conn1[4], conn1[2], conn1[6], conn1[9], conn1[5], conn2[8] };
661  double coords2[3 * num_vert];
662  rval = moab.get_coords( combined, num_vert, coords2 );CHECK_ERR( rval );
663 
664  // check vertex coordinates
665  for( int i = 0; i < 36; ++i )
666  {
667  CHECK_REAL_EQUAL( coords[i], coords2[i], 1e-12 );
668  }
669 }
670 
672 {
673  Core moab;
674  ErrorCode rval;
675  Range elems;
676 
677  // define a pyramid w/ a octagonal base
678  const double a = 0.5;
679  const double b = 1 + sqrt( 2.0 ) / 2.0;
680  const size_t num_vert = 9;
681  const double coords[3 * num_vert] = { -a, -b, 0, a, -b, 0, b, -a, 0, b, a, 0, a, b,
682  0, -a, b, 0, -b, a, 0, -b, -a, 0, 0, 0, 1 };
683  EntityHandle verts[num_vert];
684  for( size_t i = 0; i < num_vert; ++i )
685  {
686  rval = moab.create_vertex( coords + 3 * i, verts[i] );CHECK_ERR( rval );
687  }
688 
689  // define octagonal base
690  const size_t num_polygon = 1;
691  EntityHandle octagon;
692  rval = moab.create_element( MBPOLYGON, verts, 8, octagon );CHECK_ERR( rval );
693 
694  // define triangular sides
695  const size_t num_tri = num_vert - 1;
696  EntityHandle tri[num_tri];
697  for( size_t i = 0; i < num_tri; ++i )
698  {
699  const EntityHandle conn[3] = { verts[i], verts[( i + 1 ) % num_tri], verts[num_tri] };
700  rval = moab.create_element( MBTRI, conn, 3, tri[i] );CHECK_ERR( rval );
701  }
702 
703  // define the octagon-based pyramid
704  const size_t num_polyhedron = 1;
705  EntityHandle polyhedron;
706  EntityHandle all_faces[num_vert];
707  all_faces[0] = octagon;
708  std::copy( tri, tri + num_tri, all_faces + 1 );
709  rval = moab.create_element( MBPOLYHEDRON, all_faces, num_vert, polyhedron );CHECK_ERR( rval );
710 
711  // pack and unpack the mesh
712  elems.clear();
713  elems.insert( polyhedron );
714  elems.insert( octagon );
715  std::copy( tri, tri + num_tri, range_inserter( elems ) );
716  pack_unpack_noremoteh( moab, elems );
717 
718  // check counts
719  check_sizes( moab, num_vert, 0, num_tri, 0, num_polygon, 0, 0, 0, 0, 0, num_polyhedron );
720 
721  // get entities
722  Range range;
723  rval = moab.get_entities_by_type( 0, MBPOLYHEDRON, range );CHECK_ERR( rval );
724  CHECK_EQUAL( num_polyhedron, range.size() );
725  polyhedron = range.front();
726 
727  range.clear();
728  rval = moab.get_entities_by_type( 0, MBPOLYGON, range );CHECK_ERR( rval );
729  CHECK_EQUAL( num_polygon, range.size() );
730  octagon = range.front();
731 
732  range.clear();
733  rval = moab.get_entities_by_type( 0, MBTRI, range );CHECK_ERR( rval );
734  CHECK_EQUAL( num_tri, range.size() );
735 
736  // check coords of octagon vertices
737  const EntityHandle* oct_conn;
738  int eight = 0;
739  rval = moab.get_connectivity( octagon, oct_conn, eight );CHECK_ERR( rval );
740  CHECK_EQUAL( 8, eight );
741  double oct_coords[3 * 8];
742  rval = moab.get_coords( oct_conn, 8, oct_coords );CHECK_ERR( rval );
743  for( int i = 0; i < 3 * 8; ++i )
744  {
745  CHECK_REAL_EQUAL( coords[i], oct_coords[i], 1e-12 );
746  }
747 
748  // check faces of polyhedron
749  std::vector< EntityHandle > volconn;
750  rval = moab.get_connectivity( &polyhedron, 1, volconn );CHECK_ERR( rval );
751  CHECK_EQUAL( num_tri + 1, volconn.size() );
752  CHECK_EQUAL( volconn[0], octagon );
753  for( Range::iterator i = range.begin(); i != range.end(); ++i )
754  {
755  CHECK( std::find( volconn.begin(), volconn.end(), *i ) != volconn.end() );
756  }
757 }
758 
760 {
761  Core moab;
762  ErrorCode rval;
763  create_simple_grid( moab, 3 );
764 
765  // delete any existing sets
766  Range sets;
767  rval = moab.get_entities_by_type( 0, MBENTITYSET, sets );CHECK_ERR( rval );
768  if( !sets.empty() )
769  {
770  rval = moab.delete_entities( sets );CHECK_ERR( rval );
771  }
772 
773  // get all entities
774  Range entities;
775  rval = moab.get_entities_by_handle( 0, entities );CHECK_ERR( rval );
776  // expect 8 elements and 27 vertices
777  CHECK_EQUAL( 35, (int)entities.size() );
778  CHECK_EQUAL( 27u, entities.num_of_type( MBVERTEX ) );
779  CHECK_EQUAL( 8u, entities.num_of_type( MBHEX ) );
780 
781  // create five sets:
782  // 1) one with all the elements and vertices,
783  // 2) one with half of the elements,
784  // 3) one with the other half of the elements,
785  // 4) one with a single vertex,
786  // 5) an empty set,
787  EntityHandle all_set, half1_set, half2_set, vertex_set, empty_set;
788  const unsigned int all_opt = MESHSET_SET | MESHSET_TRACK_OWNER, half1_opt = MESHSET_SET, half2_opt = MESHSET_SET,
789  vertex_opt = MESHSET_ORDERED, empty_opt = MESHSET_ORDERED | MESHSET_TRACK_OWNER;
790  rval = moab.create_meshset( all_opt, all_set );CHECK_ERR( rval );
791  entities.insert( all_set );
792  rval = moab.create_meshset( half1_opt, half1_set );CHECK_ERR( rval );
793  entities.insert( half1_set );
794  rval = moab.create_meshset( half2_opt, half2_set );CHECK_ERR( rval );
795  entities.insert( half2_set );
796  rval = moab.create_meshset( vertex_opt, vertex_set );CHECK_ERR( rval );
797  entities.insert( vertex_set );
798  rval = moab.create_meshset( empty_opt, empty_set );CHECK_ERR( rval );
799  entities.insert( empty_set );
800 
801  Range elems, verts, half;
802  rval = moab.get_entities_by_type( 0, MBVERTEX, verts );CHECK_ERR( rval );
803  rval = moab.get_entities_by_type( 0, MBHEX, elems );CHECK_ERR( rval );
804 
805  rval = moab.add_entities( all_set, verts );CHECK_ERR( rval );
806  rval = moab.add_entities( all_set, elems );CHECK_ERR( rval );
807  half.merge( elems.begin(), elems.begin() += elems.size() / 2 );
808  rval = moab.add_entities( half1_set, half );CHECK_ERR( rval );
809  half.clear();
810  half.merge( elems.begin() += elems.size() / 2, elems.end() );
811  rval = moab.add_entities( half2_set, half );CHECK_ERR( rval );
812  EntityHandle vert = verts.front();
813  rval = moab.add_entities( vertex_set, &vert, 1 );CHECK_ERR( rval );
814 
815  // do pack and unpack
817 
818  // get entities by type
819  verts.clear();
820  rval = moab.get_entities_by_type( 0, MBVERTEX, verts );CHECK_ERR( rval );
821  elems.clear();
822  rval = moab.get_entities_by_type( 0, MBHEX, elems );CHECK_ERR( rval );
823  sets.clear();
824  rval = moab.get_entities_by_type( 0, MBENTITYSET, sets );CHECK_ERR( rval );
825 
826  CHECK_EQUAL( 27, (int)verts.size() );
827  CHECK_EQUAL( 8, (int)elems.size() );
828  CHECK_EQUAL( 5, (int)sets.size() );
829 
830  // guess which is which
831  empty_set = all_set = vertex_set = half1_set = half2_set = 0;
832  for( Range::iterator i = sets.begin(); i != sets.end(); ++i )
833  {
834  int num_vtx, num_elem;
835  rval = moab.get_number_entities_by_type( *i, MBVERTEX, num_vtx );CHECK_ERR( rval );
836  rval = moab.get_number_entities_by_type( *i, MBHEX, num_elem );CHECK_ERR( rval );
837  if( num_vtx == 0 )
838  {
839  if( num_elem == 0 )
840  {
841  CHECK_EQUAL( (EntityHandle)0, empty_set );
842  empty_set = *i;
843  }
844  else if( !half1_set )
845  {
846  half1_set = *i;
847  }
848  else
849  {
850  CHECK_EQUAL( (EntityHandle)0, half2_set );
851  half2_set = *i;
852  }
853  }
854  else if( num_vtx == 1 )
855  {
856  CHECK_EQUAL( 0, num_elem );
857  CHECK_EQUAL( (EntityHandle)0, vertex_set );
858  vertex_set = *i;
859  }
860  else
861  {
862  CHECK_EQUAL( 8, num_elem );
863  CHECK_EQUAL( 27, num_vtx );
864  CHECK_EQUAL( (EntityHandle)0, all_set );
865  all_set = *i;
866  }
867  }
868 
869  // check set options
870  unsigned opt;
871  rval = moab.get_meshset_options( all_set, opt );CHECK_ERR( rval );
872  CHECK_EQUAL( all_opt, opt );
873  rval = moab.get_meshset_options( half1_set, opt );CHECK_ERR( rval );
874  CHECK_EQUAL( half1_opt, opt );
875  rval = moab.get_meshset_options( half2_set, opt );CHECK_ERR( rval );
876  CHECK_EQUAL( half2_opt, opt );
877  rval = moab.get_meshset_options( vertex_set, opt );CHECK_ERR( rval );
878  CHECK_EQUAL( vertex_opt, opt );
879  rval = moab.get_meshset_options( empty_set, opt );CHECK_ERR( rval );
880  CHECK_EQUAL( empty_opt, opt );
881 }
882 
884 {
885  Core moab;
886  ErrorCode rval;
887  create_simple_grid( moab, 3 );
888 
889  // delete any existing sets
890  Range sets;
891  rval = moab.get_entities_by_type( 0, MBENTITYSET, sets );CHECK_ERR( rval );
892  if( !sets.empty() )
893  {
894  rval = moab.delete_entities( sets );CHECK_ERR( rval );
895  }
896 
897  // get all vertices
898  Range vertices;
899  rval = moab.get_entities_by_type( 0, MBVERTEX, vertices );CHECK_ERR( rval );
900  CHECK_EQUAL( 27, (int)vertices.size() );
901  // create meshset containing vertices
902  EntityHandle set;
903  rval = moab.create_meshset( MESHSET_SET, set );CHECK_ERR( rval );
904  rval = moab.add_entities( set, vertices );CHECK_ERR( rval );
905 
906  // pack and unpack range containing only set handle.
907  // Will fail unless we also pass in set contents explicitly
908  Range entities( vertices );
909  entities.insert( set );
911 
912  // expect single set in mesh
913  entities.clear();
914  rval = moab.get_entities_by_type( 0, MBENTITYSET, entities );CHECK_ERR( rval );
915  CHECK_EQUAL( 1, (int)entities.size() );
916  set = entities.front();
917 
918  // expect 27 vertices in mesh
919  vertices.clear();
920  rval = moab.get_entities_by_type( 0, MBVERTEX, vertices );CHECK_ERR( rval );
921  CHECK_EQUAL( 27, (int)vertices.size() );
922 
923  // expect set to contain all 27 vertices
924  vertices.clear();
925  rval = moab.get_entities_by_type( set, MBVERTEX, vertices );CHECK_ERR( rval );
926  CHECK_EQUAL( 27, (int)vertices.size() );
927 }
928 
930 {
931  Core moab;
932  ErrorCode rval;
933 
934  // delete any existing sets
935  Range sets;
936  rval = moab.get_entities_by_type( 0, MBENTITYSET, sets );CHECK_ERR( rval );
937  if( !sets.empty() )
938  {
939  rval = moab.delete_entities( sets );CHECK_ERR( rval );
940  }
941 
942  // create three sets such that set2 contains set1, and set3 contains
943  // both set1 and set2
944  EntityHandle set1, set2, set3;
945  sets.clear();
946  rval = moab.create_meshset( MESHSET_ORDERED, set1 );CHECK_ERR( rval );
947  sets.insert( set1 );
948  rval = moab.create_meshset( MESHSET_SET, set2 );CHECK_ERR( rval );
949  rval = moab.add_entities( set2, sets );CHECK_ERR( rval );
950  sets.insert( set2 );
951  rval = moab.create_meshset( MESHSET_SET, set3 );CHECK_ERR( rval );
952  rval = moab.add_entities( set3, sets );CHECK_ERR( rval );
953  sets.insert( set3 );
954 
955  // pack and unpack
956  pack_unpack_noremoteh( moab, sets );
957 
958  // get sets
959  sets.clear();
960  rval = moab.get_entities_by_type( 0, MBENTITYSET, sets );CHECK_ERR( rval );
961  CHECK_EQUAL( 3, (int)sets.size() );
962 
963  // figure out which is which
964  set1 = set2 = set3 = 0;
965  for( Range::iterator i = sets.begin(); i != sets.end(); ++i )
966  {
967  int count;
968  rval = moab.get_number_entities_by_type( *i, MBENTITYSET, count );CHECK_ERR( rval );
969  CHECK( count >= 0 && count <= 2 );
970  switch( count )
971  {
972  case 0:
973  CHECK_EQUAL( (EntityHandle)0, set1 );
974  set1 = *i;
975  break;
976  case 1:
977  CHECK_EQUAL( (EntityHandle)0, set2 );
978  set2 = *i;
979  break;
980  case 2:
981  CHECK_EQUAL( (EntityHandle)0, set3 );
982  set3 = *i;
983  break;
984  }
985  }
986 
987  // check that set2 contains set1
988  sets.clear();
989  rval = moab.get_entities_by_type( set2, MBENTITYSET, sets );CHECK_ERR( rval );
990  CHECK_EQUAL( 1, (int)sets.size() );
991  CHECK_EQUAL( set1, sets.front() );
992 
993  // check that set3 contains set1 and set2
994  sets.clear();
995  rval = moab.get_entities_by_type( set3, MBENTITYSET, sets );CHECK_ERR( rval );
996  CHECK_EQUAL( 2, (int)sets.size() );
997  if( sets.front() == set1 )
998  {
999  CHECK_EQUAL( set2, sets.back() );
1000  }
1001  else
1002  {
1003  CHECK_EQUAL( set2, sets.front() );
1004  CHECK_EQUAL( set1, sets.back() );
1005  }
1006 }
1007 
1009 {
1010  Core moab;
1011  ErrorCode rval;
1012 
1013  // delete any existing sets
1014  Range sets;
1015  rval = moab.get_entities_by_type( 0, MBENTITYSET, sets );CHECK_ERR( rval );
1016  if( !sets.empty() )
1017  {
1018  rval = moab.delete_entities( sets );CHECK_ERR( rval );
1019  }
1020 
1021  // create three sets such that set3 has a child link to
1022  // set1, set2 has a parent link to set1, and such that set3 and
1023  // set2 are parent and child, respectively.
1024  EntityHandle set1, set2, set3;
1025  sets.clear();
1026  rval = moab.create_meshset( MESHSET_ORDERED, set1 );CHECK_ERR( rval );
1027  sets.insert( set1 );
1028  rval = moab.create_meshset( MESHSET_SET, set2 );CHECK_ERR( rval );
1029  sets.insert( set2 );
1030  rval = moab.create_meshset( MESHSET_SET, set3 );CHECK_ERR( rval );
1031  sets.insert( set3 );
1032 
1033  rval = moab.add_child_meshset( set3, set1 );CHECK_ERR( rval );
1034  rval = moab.add_parent_meshset( set2, set1 );CHECK_ERR( rval );
1035  rval = moab.add_parent_child( set3, set2 );CHECK_ERR( rval );
1036 
1037  // make sure everything is valid before doing the pack/unpack
1038  int count;
1039  rval = moab.num_child_meshsets( set1, &count );
1040  CHECK( MB_SUCCESS == rval && 0 == count );
1041  rval = moab.num_child_meshsets( set2, &count );
1042  CHECK( MB_SUCCESS == rval && 0 == count );
1043  rval = moab.num_child_meshsets( set3, &count );
1044  CHECK( MB_SUCCESS == rval && 2 == count );
1045  rval = moab.num_parent_meshsets( set1, &count );
1046  CHECK( MB_SUCCESS == rval && 0 == count );
1047  rval = moab.num_parent_meshsets( set2, &count );
1048  CHECK( MB_SUCCESS == rval && 2 == count );
1049  rval = moab.num_parent_meshsets( set3, &count );
1050  CHECK( MB_SUCCESS == rval && 0 == count );
1051 
1052  // pack and unpack
1053  pack_unpack_noremoteh( moab, sets );
1054 
1055  // get sets
1056  sets.clear();
1057  rval = moab.get_entities_by_type( 0, MBENTITYSET, sets );CHECK_ERR( rval );
1058  CHECK_EQUAL( 3, (int)sets.size() );
1059 
1060  // look for a set with two child links (set3)
1061  set1 = set2 = set3 = 0;
1062  for( Range::iterator i = sets.begin(); i != sets.end(); ++i )
1063  {
1064  int mcount;
1065  rval = moab.num_child_meshsets( *i, &mcount );CHECK_ERR( rval );
1066  if( mcount == 2 )
1067  {
1068  set3 = *i;
1069  break;
1070  }
1071  }
1072  CHECK( 0 != set3 );
1073 
1074  // check set relations
1075  std::vector< EntityHandle > parents, children;
1076  rval = moab.get_child_meshsets( set3, children );CHECK_ERR( rval );
1077  CHECK_EQUAL( (std::vector< EntityHandle >::size_type)2, children.size() );
1078  set1 = children[0];
1079  set2 = children[1];
1080  rval = moab.get_parent_meshsets( set1, parents );CHECK_ERR( rval );
1081  CHECK( parents.empty() );
1082  children.clear();
1083  rval = moab.get_parent_meshsets( set1, children );CHECK_ERR( rval );
1084  CHECK( children.empty() );
1085  rval = moab.get_parent_meshsets( set2, parents );CHECK_ERR( rval );
1086  CHECK_EQUAL( (std::vector< EntityHandle >::size_type)2, parents.size() );
1087  CHECK_EQUAL( set1, parents[0] );
1088  CHECK_EQUAL( set3, parents[1] );
1089 }
1090 
1092 {
1093  Range::iterator i;
1094  int size;
1095  DataType type;
1096  TagType storage;
1097  Core moab;
1098  Interface& mb = moab;
1099  ErrorCode rval;
1100 
1101  create_simple_grid( mb, 3 );
1102  Range elems;
1103  rval = mb.get_entities_by_type( 0, MBHEX, elems );CHECK_ERR( rval );
1104  CHECK( !elems.empty() );
1105 
1106  // Define a sparse tag containing two integers. For every other element
1107  // in the mesh, set the tag value to the floor of the x and y
1108  // coordinates of the first vertex in the elements connectivity list.
1109  const char sparse_2_int_tag_name[] = "test tag 1";
1110  Tag sparse_2_int_tag;
1111  rval =
1112  mb.tag_get_handle( sparse_2_int_tag_name, 2, MB_TYPE_INTEGER, sparse_2_int_tag, MB_TAG_SPARSE | MB_TAG_CREAT );CHECK_ERR( rval );
1113  bool skip = false;
1114  for( i = elems.begin(); i != elems.end(); ++i, skip = !skip )
1115  {
1116  if( skip ) continue;
1117 
1118  const EntityHandle* conn = 0;
1119  int len;
1120  rval = mb.get_connectivity( *i, conn, len );CHECK_ERR( rval );
1121  double coords[3];
1122  rval = mb.get_coords( conn, 1, coords );CHECK_ERR( rval );
1123  const int data[2] = { (int)coords[0], (int)coords[1] };
1124  rval = mb.tag_set_data( sparse_2_int_tag, &*i, 1, data );CHECK_ERR( rval );
1125  }
1126 
1127  // pack and unpack
1128  Range ents;
1129  pack_unpack_noremoteh( moab, ents );
1130  elems.clear();
1131  rval = mb.get_entities_by_type( 0, MBHEX, elems );CHECK_ERR( rval );
1132 
1133  // check tag meta for sparse_2_int_tag
1134  rval = mb.tag_get_handle( sparse_2_int_tag_name, 2, MB_TYPE_INTEGER, sparse_2_int_tag );CHECK_ERR( rval );
1135  rval = mb.tag_get_length( sparse_2_int_tag, size );CHECK_ERR( rval );
1136  CHECK_EQUAL( 2, size );
1137  rval = mb.tag_get_type( sparse_2_int_tag, storage );CHECK_ERR( rval );
1138  CHECK_EQUAL( MB_TAG_SPARSE, storage );
1139  rval = mb.tag_get_data_type( sparse_2_int_tag, type );CHECK_ERR( rval );
1140  CHECK_EQUAL( MB_TYPE_INTEGER, type );
1141  int intdata[2];
1142  rval = mb.tag_get_default_value( sparse_2_int_tag, intdata );
1144 
1145  // check tag data for sparse_2_int_tag
1146  Range tagged;
1147  rval = mb.get_entities_by_type_and_tag( 0, MBHEX, &sparse_2_int_tag, 0, 1, tagged );CHECK_ERR( rval );
1148  CHECK_EQUAL( ( elems.size() + 1 ) / 2, tagged.size() );
1149  for( i = tagged.begin(); i != tagged.end(); ++i )
1150  {
1151  rval = mb.tag_get_data( sparse_2_int_tag, &*i, 1, intdata );CHECK_ERR( rval );
1152 
1153  const EntityHandle* conn = 0;
1154  int len;
1155  rval = mb.get_connectivity( *i, conn, len );CHECK_ERR( rval );
1156  double coords[3];
1157  rval = mb.get_coords( conn, 1, coords );CHECK_ERR( rval );
1158 
1159  CHECK_EQUAL( (int)( coords[0] ), intdata[0] );
1160  CHECK_EQUAL( (int)( coords[1] ), intdata[1] );
1161  }
1162 }
1163 
1165 {
1166  Range::iterator i;
1167  int size;
1168  DataType type;
1169  TagType storage;
1170  Core moab;
1171  Interface& mb = moab;
1172  ErrorCode rval;
1173 
1174  create_simple_grid( mb, 3 );
1175  Range verts;
1176  rval = mb.get_entities_by_type( 0, MBVERTEX, verts );CHECK_ERR( rval );
1177  CHECK( !verts.empty() );
1178 
1179  // Define a dense tag containing a single double-precision floating
1180  // point value. For each vertex, store the distance from the origin
1181  // in this tag.
1182  const char dense_1_double_tag_name[] = "test tag 2";
1183  Tag dense_1_double_tag;
1184  rval =
1185  mb.tag_get_handle( dense_1_double_tag_name, 1, MB_TYPE_DOUBLE, dense_1_double_tag, MB_TAG_DENSE | MB_TAG_EXCL );CHECK_ERR( rval );
1186  for( i = verts.begin(); i != verts.end(); ++i )
1187  {
1188  double coords[3];
1189  rval = mb.get_coords( &*i, 1, coords );CHECK_ERR( rval );
1190  double val = sqrt( coords[0] * coords[0] + coords[1] * coords[1] + coords[2] * coords[2] );
1191  rval = mb.tag_set_data( dense_1_double_tag, &*i, 1, &val );CHECK_ERR( rval );
1192  }
1193 
1194  // pack and unpack
1195  Range ents;
1196  pack_unpack_noremoteh( moab, ents );
1197  verts.clear();
1198  rval = mb.get_entities_by_type( 0, MBVERTEX, verts );CHECK_ERR( rval );
1199 
1200  // check tag meta for dense_1_double_tag
1201  rval = mb.tag_get_handle( dense_1_double_tag_name, 1, MB_TYPE_DOUBLE, dense_1_double_tag );CHECK_ERR( rval );
1202  rval = mb.tag_get_length( dense_1_double_tag, size );CHECK_ERR( rval );
1203  CHECK_EQUAL( 1, size );
1204  rval = mb.tag_get_type( dense_1_double_tag, storage );CHECK_ERR( rval );
1205  CHECK_EQUAL( MB_TAG_DENSE, storage );
1206  rval = mb.tag_get_data_type( dense_1_double_tag, type );CHECK_ERR( rval );
1207  CHECK_EQUAL( MB_TYPE_DOUBLE, type );
1208  double dval;
1209  rval = mb.tag_get_default_value( dense_1_double_tag, &dval );
1211 
1212  // check tag data for dense_1_double_tag
1213  for( i = verts.begin(); i != verts.end(); ++i )
1214  {
1215  double coords[3];
1216  rval = mb.get_coords( &*i, 1, coords );CHECK_ERR( rval );
1217 
1218  const double expected = sqrt( coords[0] * coords[0] + coords[1] * coords[1] + coords[2] * coords[2] );
1219  rval = mb.tag_get_data( dense_1_double_tag, &*i, 1, &dval );CHECK_ERR( rval );
1220  CHECK_REAL_EQUAL( expected, dval, 1e-6 );
1221  }
1222 }
1223 
1225 {
1226  Range::iterator i;
1227  int size;
1228  DataType type;
1229  TagType storage;
1230  Core moab;
1231  Interface& mb = moab;
1232  ErrorCode rval;
1233 
1234  create_simple_grid( mb, 3 );
1235  Range verts, elems, sets;
1236  rval = mb.get_entities_by_type( 0, MBVERTEX, verts );CHECK_ERR( rval );
1237  CHECK( !verts.empty() );
1238  rval = mb.get_entities_by_type( 0, MBHEX, elems );CHECK_ERR( rval );
1239  CHECK( !elems.empty() );
1240 
1241  // Define a dense, opaque tag with a default value of "DEFLT".
1242  // Set the tag on one element, one vertex,and one set to "TAGGD".
1243  const char dense_5_opaque_tag_name[] =
1244  "This is intentionally a very long tag name in an attempt to test for an arbitrary "
1245  "limitations on tag name length.";
1246  Tag dense_5_opaque_tag;
1247  rval = mb.tag_get_handle( dense_5_opaque_tag_name, 5, MB_TYPE_OPAQUE, dense_5_opaque_tag,
1248  MB_TAG_DENSE | MB_TAG_EXCL, "DEFLT" );CHECK_ERR( rval );
1249  EntityHandle set;
1250  rval = mb.create_meshset( MESHSET_SET, set );CHECK_ERR( rval );
1251  const EntityHandle handles[3] = { verts.front(), elems.front(), set };
1252  const char data[] = "TAGGDTAGGDTAGGD";
1253  rval = mb.tag_set_data( dense_5_opaque_tag, handles, 3, data );CHECK_ERR( rval );
1254 
1255  // pack and unpack
1256  Range ents;
1257  pack_unpack_noremoteh( moab, ents );
1258  elems.clear();
1259  verts.clear();
1260  sets.clear();
1261  rval = mb.get_entities_by_type( 0, MBVERTEX, verts );CHECK_ERR( rval );
1262  rval = mb.get_entities_by_type( 0, MBHEX, elems );CHECK_ERR( rval );
1263  rval = mb.get_entities_by_type( 0, MBENTITYSET, sets );CHECK_ERR( rval );
1264 
1265  // check tag meta for dense_5_opaque_tag
1266  rval = mb.tag_get_handle( dense_5_opaque_tag_name, 5, MB_TYPE_OPAQUE, dense_5_opaque_tag );CHECK_ERR( rval );
1267  rval = mb.tag_get_length( dense_5_opaque_tag, size );CHECK_ERR( rval );
1268  CHECK_EQUAL( 5, size );
1269  rval = mb.tag_get_type( dense_5_opaque_tag, storage );CHECK_ERR( rval );
1270  CHECK_EQUAL( MB_TAG_DENSE, storage );
1271  rval = mb.tag_get_data_type( dense_5_opaque_tag, type );CHECK_ERR( rval );
1272  CHECK_EQUAL( MB_TYPE_OPAQUE, type );
1273  char odata[6];
1274  odata[5] = '\0';
1275  rval = mb.tag_get_default_value( dense_5_opaque_tag, odata );CHECK_ERR( rval );
1276  CHECK_EQUAL( std::string( "DEFLT" ), std::string( odata ) );
1277 
1278  // count number of each type with tag set to non-default
1279  int vcount = 0, ecount = 0, scount = 0;
1280  for( i = verts.begin(); i != verts.end(); ++i )
1281  {
1282  rval = mb.tag_get_data( dense_5_opaque_tag, &*i, 1, odata );CHECK_ERR( rval );
1283  if( strcmp( odata, "DEFLT" ) != 0 )
1284  {
1285  CHECK_EQUAL( std::string( "TAGGD" ), std::string( odata ) );
1286  ++vcount;
1287  }
1288  }
1289  CHECK_EQUAL( 1, vcount );
1290  for( i = elems.begin(); i != elems.end(); ++i )
1291  {
1292  rval = mb.tag_get_data( dense_5_opaque_tag, &*i, 1, odata );CHECK_ERR( rval );
1293  if( strcmp( odata, "DEFLT" ) != 0 )
1294  {
1295  CHECK_EQUAL( "TAGGD", odata );
1296  ++ecount;
1297  }
1298  }
1299  CHECK_EQUAL( 1, ecount );
1300  for( i = sets.begin(); i != sets.end(); ++i )
1301  {
1302  rval = mb.tag_get_data( dense_5_opaque_tag, &*i, 1, odata );CHECK_ERR( rval );
1303  if( strcmp( odata, "DEFLT" ) != 0 )
1304  {
1305  CHECK_EQUAL( "TAGGD", odata );
1306  ++scount;
1307  }
1308  }
1309  CHECK_EQUAL( 1, scount );
1310 }
1311 
1313 {
1314  Range::iterator i;
1315  Core moab;
1316  Interface& mb = moab;
1317  ErrorCode rval;
1318 
1319  // create some mesh
1320  create_simple_grid( mb, 3 );
1321  Range verts;
1322  rval = mb.get_entities_by_type( 0, MBVERTEX, verts );CHECK_ERR( rval );
1323  CHECK( !verts.empty() );
1324 
1325  // Create a bit tag
1326  const char tag_name[] = "test bit";
1327  Tag tag;
1328  rval = mb.tag_get_handle( tag_name, 3, MB_TYPE_BIT, tag, MB_TAG_EXCL );CHECK_ERR( rval );
1329 
1330  // Set bits to 1 unless cooresponding coordinate of
1331  // vertex is zero.
1332  for( i = verts.begin(); i != verts.end(); ++i )
1333  {
1334  double coords[3];
1335  rval = mb.get_coords( &*i, 1, coords );CHECK_ERR( rval );
1336 
1337  unsigned char data = 0;
1338  for( int j = 0; j < 3; ++j )
1339  if( fabs( coords[j] ) > 1e-6 ) data |= ( 1 << j );
1340  rval = mb.tag_set_data( tag, &*i, 1, &data );CHECK_ERR( rval );
1341  }
1342 
1343  // pack and unpack
1344  Range ents;
1345  pack_unpack_noremoteh( moab, ents );
1346  verts.clear();
1347  rval = mb.get_entities_by_type( 0, MBVERTEX, verts );CHECK_ERR( rval );
1348 
1349  // check tag meta
1350  rval = mb.tag_get_handle( tag_name, 3, MB_TYPE_BIT, tag );CHECK_ERR( rval );
1351 
1352  int size;
1353  rval = mb.tag_get_length( tag, size );CHECK_ERR( rval );
1354  CHECK_EQUAL( 3, size );
1355 
1356  TagType storage;
1357  rval = mb.tag_get_type( tag, storage );CHECK_ERR( rval );
1358  CHECK_EQUAL( MB_TAG_BIT, storage );
1359 
1360  DataType type;
1361  rval = mb.tag_get_data_type( tag, type );
1362  CHECK_EQUAL( MB_TYPE_BIT, type );
1363 
1364  // check tag values
1365  for( i = verts.begin(); i != verts.end(); ++i )
1366  {
1367  double coords[3];
1368  rval = mb.get_coords( &*i, 1, coords );CHECK_ERR( rval );
1369 
1370  unsigned char expected = 0;
1371  for( int j = 0; j < 3; ++j )
1372  if( fabs( coords[j] ) > 1e-6 ) expected |= ( 1 << j );
1373 
1374  unsigned char data = (unsigned char)0xFF;
1375  rval = mb.tag_get_data( tag, &*i, 1, &data );CHECK_ERR( rval );
1376 
1377  CHECK_EQUAL( (int)expected, (int)data );
1378  }
1379 }
1380 
1382 {
1383  Range::iterator i;
1384  Core moab;
1385  Interface& mb = moab;
1386  ErrorCode rval;
1387 
1388  // create some mesh
1389  create_simple_grid( mb, 3 );
1390  Range verts;
1391  rval = mb.get_entities_by_type( 0, MBVERTEX, verts );CHECK_ERR( rval );
1392  CHECK( !verts.empty() );
1393 
1394  // create a variable-length tag
1395  const char* tag_name = "var_int_tag";
1396  const int defval_size = 5;
1397  const int default_val[defval_size] = { 0xBEEF, 0xFEED, 0xDEAD, 0xBAD, 0xBEAD };
1398  Tag tag;
1399  rval = mb.tag_get_handle( tag_name, defval_size, MB_TYPE_INTEGER, tag, MB_TAG_DENSE | MB_TAG_VARLEN | MB_TAG_EXCL,
1400  default_val );CHECK_ERR( rval );
1401 
1402  // for each vertex, store in the tag an integer between 1 and 3,
1403  // followed by the floor of the cooresponding number of vertex
1404  // coordinates, beginning with x.
1405  for( i = verts.begin(); i != verts.end(); ++i )
1406  {
1407  double coords[3];
1408  rval = mb.get_coords( &*i, 1, coords );CHECK_ERR( rval );
1409 
1410  const int num_coord = 1 + *i % 3;
1411  const int data_size = num_coord + 1;
1412  const int data[4] = { num_coord, (int)coords[0], (int)coords[1], (int)coords[2] };
1413  const void* data_ptrs[1] = { data };
1414  rval = mb.tag_set_by_ptr( tag, &*i, 1, data_ptrs, &data_size );CHECK_ERR( rval );
1415  }
1416 
1417  // pack and unpack
1419  verts.clear();
1420  rval = mb.get_entities_by_type( 0, MBVERTEX, verts );CHECK_ERR( rval );
1421 
1422  // check tag meta
1423  rval = mb.tag_get_handle( tag_name, 0, MB_TYPE_INTEGER, tag );CHECK_ERR( rval );
1424 
1425  int size;
1426  rval = mb.tag_get_length( tag, size );
1428 
1429  TagType storage;
1430  rval = mb.tag_get_type( tag, storage );CHECK_ERR( rval );
1431  CHECK_EQUAL( MB_TAG_DENSE, storage );
1432 
1433  DataType type;
1434  rval = mb.tag_get_data_type( tag, type );CHECK_ERR( rval );
1435  CHECK_EQUAL( MB_TYPE_INTEGER, type );
1436 
1437  const void* defval_ptr;
1438  rval = mb.tag_get_default_value( tag, defval_ptr, size );CHECK_ERR( rval );
1439  CHECK_EQUAL( defval_size, size );
1440  const int* defval_arr = reinterpret_cast< const int* >( defval_ptr );
1441  for( int j = 0; j < size; ++j )
1442  CHECK_EQUAL( default_val[j], defval_arr[j] );
1443 
1444  // check tag values
1445  for( i = verts.begin(); i != verts.end(); ++i )
1446  {
1447  double coords[3];
1448  rval = mb.get_coords( &*i, 1, coords );CHECK_ERR( rval );
1449 
1450  int tsize;
1451  const void* valptr;
1452  rval = mb.tag_get_by_ptr( tag, &*i, 1, &valptr, &tsize );CHECK_ERR( rval );
1453  CHECK( tsize > 1 );
1454  CHECK( tsize <= 4 );
1455 
1456  const int* valarr = reinterpret_cast< const int* >( valptr );
1457  CHECK( valarr[0] >= 1 );
1458  CHECK( valarr[0] <= 3 );
1459  for( int j = 0; j < valarr[0]; ++j )
1460  {
1461  CHECK_EQUAL( (int)( coords[j] ), valarr[j + 1] );
1462  }
1463  }
1464 }
1465 
1467 {
1468  Range::iterator i;
1469  Core moab;
1470  Interface& mb = moab;
1471  ErrorCode rval;
1472 
1473  // create some mesh
1474  create_simple_grid( mb, 3 );
1475  Range verts, elems;
1476  rval = mb.get_entities_by_type( 0, MBVERTEX, verts );CHECK_ERR( rval );
1477  CHECK( !verts.empty() );
1478  rval = mb.get_entities_by_type( 0, MBHEX, elems );CHECK_ERR( rval );
1479  CHECK( !elems.empty() );
1480 
1481  // create a tag
1482  const char* tag_name = "entity tag";
1483  EntityHandle default_val[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
1484  Tag tag;
1485  rval = mb.tag_get_handle( tag_name, 8, MB_TYPE_HANDLE, tag, MB_TAG_SPARSE | MB_TAG_EXCL, &default_val );CHECK_ERR( rval );
1486 
1487  // Store on each vertex the handles of the adjacent hexes, padded
1488  // with NULL handles.
1489  EntityHandle tagdata[8 * 8];
1490  for( i = elems.begin(); i != elems.end(); ++i )
1491  {
1492  const EntityHandle* conn;
1493  int len;
1494  rval = mb.get_connectivity( *i, conn, len );CHECK_ERR( rval );
1495  CHECK_EQUAL( 8, len );
1496 
1497  rval = mb.tag_get_data( tag, conn, len, tagdata );CHECK_ERR( rval );
1498 
1499  for( int j = 0; j < 8; ++j )
1500  {
1501  EntityHandle* vdata = tagdata + 8 * j;
1502  int idx = 0;
1503  while( vdata[idx] )
1504  {
1505  ++idx;
1506  CHECK( idx < 8 );
1507  }
1508  vdata[idx] = *i;
1509  }
1510 
1511  rval = mb.tag_set_data( tag, conn, len, tagdata );CHECK_ERR( rval );
1512  }
1513 
1514  // pack and unpack
1516  verts.clear();
1517  rval = mb.get_entities_by_type( 0, MBVERTEX, verts );CHECK_ERR( rval );
1518 
1519  // check tag meta
1520  rval = mb.tag_get_handle( tag_name, 8, MB_TYPE_HANDLE, tag );CHECK_ERR( rval );
1521 
1522  int size;
1523  rval = mb.tag_get_length( tag, size );CHECK_ERR( rval );
1524  CHECK_EQUAL( 8, size );
1525 
1526  TagType storage;
1527  rval = mb.tag_get_type( tag, storage );CHECK_ERR( rval );
1528  CHECK_EQUAL( MB_TAG_SPARSE, storage );
1529 
1530  DataType type;
1531  rval = mb.tag_get_data_type( tag, type );CHECK_ERR( rval );
1532  CHECK_EQUAL( MB_TYPE_HANDLE, type );
1533 
1534  rval = mb.tag_get_default_value( tag, tagdata );CHECK_ERR( rval );
1535  for( int j = 0; j < 8; ++j )
1536  {
1537  CHECK_EQUAL( (EntityHandle)0, tagdata[j] );
1538  }
1539 
1540  // check tag values
1541  for( i = elems.begin(); i != elems.end(); ++i )
1542  {
1543  const EntityHandle* conn;
1544  int len;
1545  rval = mb.get_connectivity( *i, conn, len );CHECK_ERR( rval );
1546  CHECK_EQUAL( 8, len );
1547 
1548  rval = mb.tag_get_data( tag, conn, len, tagdata );CHECK_ERR( rval );
1549 
1550  for( int j = 0; j < 8; ++j )
1551  {
1552  EntityHandle* vdata = tagdata + 8 * j;
1553  int idx = 0;
1554  while( vdata[idx] != *i )
1555  {
1556  ++idx;
1557  CHECK( idx < 8 );
1558  }
1559  vdata[idx] = 0;
1560  }
1561 
1562  rval = mb.tag_set_data( tag, conn, len, tagdata );CHECK_ERR( rval );
1563  }
1564 
1565  for( i = verts.begin(); i != verts.end(); ++i )
1566  {
1567  rval = mb.tag_get_data( tag, &*i, 1, tagdata );CHECK_ERR( rval );
1568  for( int j = 0; j < 8; ++j )
1569  {
1570  CHECK_EQUAL( (EntityHandle)0, tagdata[j] );
1571  }
1572  }
1573 }
1574 
1576  std::vector< EntityHandle >& ent_verts,
1577  int verts_per_entity,
1578  int dim,
1579  Range& ents )
1580 {
1581  assert( !( ent_verts.size() % verts_per_entity ) );
1582  unsigned int num_ents = ent_verts.size() / verts_per_entity;
1583  Range dum_ents;
1584  ErrorCode result;
1585  for( unsigned int i = 0; i < num_ents; i++ )
1586  {
1587  result = mb->get_adjacencies( &ent_verts[verts_per_entity * i], verts_per_entity, dim, true, dum_ents );CHECK_ERR( result );
1588  assert( dum_ents.size() == 1 );
1589  ents.merge( dum_ents );
1590  dum_ents.clear();
1591  }
1592  return MB_SUCCESS;
1593 }
1594 
1596 {
1597  Core moab[4];
1598  ParallelComm* pc[4];
1599  for( unsigned int i = 0; i < 4; i++ )
1600  {
1601  pc[i] = new ParallelComm( &moab[i], MPI_COMM_WORLD );
1602  pc[i]->set_rank( i );
1603  }
1604 
1605  Range verts[4], quads[4];
1606  ErrorCode rval = create_shared_grid_2d( pc, verts, quads );CHECK_ERR( rval );
1607 
1608  // moab[0].list_entities(0,1);
1609 
1610  // exchange interface cells
1611  rval = ParallelComm::exchange_ghost_cells( pc, 4, -1, -1, 0, 0, true );CHECK_ERR( rval );
1612 
1613  // now 1 layer of hex ghosts
1614  rval = ParallelComm::exchange_ghost_cells( pc, 4, 2, 0, 1, 0, true );CHECK_ERR( rval );
1615 
1616  // now 1 layer of hex ghosts w/ edges
1617  rval = ParallelComm::exchange_ghost_cells( pc, 4, 2, 0, 1, 1, true );CHECK_ERR( rval );
1618 
1619  for( unsigned int i = 0; i < 4; i++ )
1620  delete pc[i];
1621 }
1622 
1624 {
1625  Core moab[4];
1626  ParallelComm* pc[4];
1627  for( unsigned int i = 0; i < 4; i++ )
1628  {
1629  pc[i] = new ParallelComm( &moab[i], MPI_COMM_WORLD );
1630  pc[i]->set_rank( i );
1631  for( unsigned int j = 0; j < 4; j++ )
1632  {
1633  if( j == i )
1634  continue;
1635  else
1636  pc[i]->get_buffers( j );
1637  }
1638  }
1639 
1640  Range verts[4], hexes[4];
1641  ErrorCode rval = create_shared_grid_3d( pc, verts, hexes );CHECK_ERR( rval );
1642 
1643  // exchange interface cells
1644  rval = ParallelComm::exchange_ghost_cells( pc, 4, -1, -1, 0, 0, true );CHECK_ERR( rval );
1645 
1646  // now 1 layer of hex ghosts
1647  rval = ParallelComm::exchange_ghost_cells( pc, 4, 3, 0, 1, 0, true );CHECK_ERR( rval );
1648 
1649  // now 1 layer of hex ghosts w/ faces, edges
1650  rval = ParallelComm::exchange_ghost_cells( pc, 4, 3, 0, 1, 3, true );CHECK_ERR( rval );
1651 
1652  for( unsigned int i = 0; i < 4; i++ )
1653  delete pc[i];
1654 }
1655 
1657 {
1658  Range::iterator i;
1659  Core moab;
1660  Interface& mb = moab;
1661  ErrorCode rval;
1662 
1663  // create some mesh
1664  create_simple_grid( mb, 3 );
1665  std::vector< EntityHandle > verts;
1666  Range dum_vertsr, vertsr;
1667  rval = mb.get_entities_by_type( 0, MBVERTEX, dum_vertsr );CHECK_ERR( rval );
1668  vertsr.insert( dum_vertsr[0], dum_vertsr[8] );
1669  for( int k = 0; k < 9; k++ )
1670  verts.push_back( vertsr[k] );
1671 
1672  CHECK( !verts.empty() );
1673 
1674  ParallelComm* pcomm = new ParallelComm( &moab, MPI_COMM_WORLD );
1675 
1676  std::vector< int > procs( 70, -1 );
1677  for( int k = 0; k < 6; k++ )
1678  procs[k] = k;
1679 
1680  std::vector< unsigned char > pvals( verts.size(), 0 );
1681  // interface, owned
1682  pvals[0] = ( PSTATUS_INTERFACE | PSTATUS_SHARED ); // p0
1683  rval = moab.tag_set_data( pcomm->sharedp_tag(), &verts[0], 1, &procs[0] );CHECK_ERR( rval );
1684  // interface, not owned
1685  pvals[1] = ( PSTATUS_NOT_OWNED | PSTATUS_INTERFACE | PSTATUS_SHARED ); // p1
1686  rval = moab.tag_set_data( pcomm->sharedp_tag(), &verts[1], 1, &procs[1] );CHECK_ERR( rval );
1687  // interface, multi-shared, owned
1688  pvals[2] = ( PSTATUS_INTERFACE | PSTATUS_SHARED | PSTATUS_MULTISHARED ); // p0, p1
1689  rval = moab.tag_set_data( pcomm->sharedps_tag(), &verts[2], 1, &procs[0] );CHECK_ERR( rval );
1690  // interface, multi-shared, not owned
1692  rval = moab.tag_set_data( pcomm->sharedps_tag(), &verts[3], 1, &procs[1] );CHECK_ERR( rval );
1693  // ghost, shared
1694  pvals[4] = ( PSTATUS_GHOST | PSTATUS_SHARED | PSTATUS_NOT_OWNED ); // p2
1695  rval = moab.tag_set_data( pcomm->sharedp_tag(), &verts[4], 1, &procs[2] );CHECK_ERR( rval );
1696  // ghost, multi-shared
1697  pvals[5] = ( PSTATUS_GHOST | PSTATUS_MULTISHARED | PSTATUS_NOT_OWNED | PSTATUS_SHARED ); // p2, p3
1698  rval = moab.tag_set_data( pcomm->sharedps_tag(), &verts[5], 1, &procs[2] );CHECK_ERR( rval );
1699  // owned, shared
1700  pvals[6] = ( PSTATUS_SHARED ); // p4
1701  rval = moab.tag_set_data( pcomm->sharedp_tag(), &verts[6], 1, &procs[4] );CHECK_ERR( rval );
1702  // owned, multi-shared
1703  pvals[7] = ( PSTATUS_MULTISHARED | PSTATUS_SHARED ); // p4, p5
1704  rval = moab.tag_set_data( pcomm->sharedps_tag(), &verts[7], 1, &procs[4] );CHECK_ERR( rval );
1705  // not shared, owned
1706  pvals[8] = 0x0;
1707 
1708  rval = moab.tag_set_data( pcomm->pstatus_tag(), &verts[0], 9, &pvals[0] );CHECK_ERR( rval );
1709 
1710  Range tmp_range = vertsr;
1711 
1712  // interface ents
1713  rval = pcomm->filter_pstatus( tmp_range, PSTATUS_INTERFACE, PSTATUS_AND );CHECK_ERR( rval );
1714  CHECK( tmp_range.size() == 4 && *tmp_range.begin() == verts[0] && *tmp_range.rbegin() == verts[3] );
1715  // not interface
1716  tmp_range = vertsr;
1717  rval = pcomm->filter_pstatus( tmp_range, PSTATUS_INTERFACE, PSTATUS_NOT );CHECK_ERR( rval );
1718  CHECK( tmp_range.size() == 5 && *tmp_range.begin() == verts[4] && *tmp_range.rbegin() == verts[8] );
1719  // interface not owned
1720  tmp_range = vertsr;
1721  rval = pcomm->filter_pstatus( tmp_range, PSTATUS_INTERFACE | PSTATUS_NOT_OWNED, PSTATUS_AND );CHECK_ERR( rval );
1722  CHECK( tmp_range.size() == 2 && *tmp_range.begin() == verts[1] && *tmp_range.rbegin() == verts[3] );
1723  // ghost
1724  tmp_range = vertsr;
1725  rval = pcomm->filter_pstatus( tmp_range, PSTATUS_GHOST, PSTATUS_AND );CHECK_ERR( rval );
1726  CHECK( tmp_range.size() == 2 && *tmp_range.begin() == verts[4] && *tmp_range.rbegin() == verts[5] );
1727  // shared not multi-shared
1728  tmp_range = vertsr;
1729  rval = pcomm->filter_pstatus( tmp_range, PSTATUS_SHARED, PSTATUS_AND );CHECK_ERR( rval );
1730  rval = pcomm->filter_pstatus( tmp_range, PSTATUS_MULTISHARED, PSTATUS_NOT );CHECK_ERR( rval );
1731  CHECK( tmp_range.size() == 4 && tmp_range[0] == verts[0] && tmp_range[1] == verts[1] && tmp_range[2] == verts[4] &&
1732  tmp_range[3] == verts[6] );
1733  // shared w/ p0
1734  tmp_range = vertsr;
1735  rval = pcomm->filter_pstatus( tmp_range, PSTATUS_SHARED, PSTATUS_AND, 0 );CHECK_ERR( rval );
1736  CHECK( tmp_range.size() == 2 && tmp_range[1] == verts[2] );
1737  // shared w/ p2 && not owned
1738  tmp_range = vertsr;
1739  rval = pcomm->filter_pstatus( tmp_range, PSTATUS_SHARED | PSTATUS_NOT_OWNED, PSTATUS_AND, 2 );CHECK_ERR( rval );
1740  CHECK( tmp_range.size() == 3 && tmp_range[0] == verts[3] && tmp_range[1] == verts[4] && tmp_range[2] == verts[5] );
1741 
1742  delete pcomm;
1743 }
1744 
1746 {
1747 #if defined( MOAB_HAVE_MPI ) && defined( MOAB_HAVE_HDF5 )
1748  Core moab;
1749  Interface& mb = moab;
1750 
1751  // This parallel read will create a ParallelComm instance implicitly
1752  std::string example = TestDir + "unittest/64bricks_1khex.h5m";
1753  std::string read_options = "PARALLEL=READ_PART;PARTITION=PARALLEL_PARTITION;PARALLEL_RESOLVE_SHARED_ENTS";
1754  ErrorCode rval = mb.load_file( example.c_str(), 0, read_options.c_str() );CHECK_ERR( rval );
1755 
1756  // It is highly recommended to reuse existing ParallelComm instance with
1757  // ParallelComm::get_pcomm() Creating a new ParallelComm instance should still be allowed,
1758  // anyway
1760 
1761  // Do something with pcomm
1762  // ...
1763 
1764  delete pcomm;
1765 #endif
1766 }