MOAB: Mesh Oriented datABase  (version 5.5.0)
h5sets_test.cpp
Go to the documentation of this file.
1 #include "moab/Core.hpp"
2 #include "moab/Range.hpp"
3 #include "TestUtil.hpp"
4 
5 #ifdef MOAB_HAVE_MPI
6 #include "moab_mpi.h"
7 #endif
8 
9 #include <algorithm>
10 #include <iostream>
11 #include <sstream>
12 #include <cstdlib>
13 #include <cmath>
14 
15 using namespace moab;
16 
17 const char filename[] = "sets.h5m";
18 bool keep_file = false;
19 
20 void read_write_file( Interface& output, Interface& input, EntityHandle* input_set = 0 )
21 {
22  ErrorCode rval;
23  rval = output.write_file( filename, 0, "DEBUG_BINIO" );CHECK_ERR( rval );
24  if( input_set )
25  {
26  rval = input.create_meshset( MESHSET_SET, *input_set );CHECK_ERR( rval );
27  }
28  rval = input.load_file( filename, input_set );
29  if( !keep_file ) remove( filename );CHECK_ERR( rval );
30 }
31 
33 {
34  Core moab;
35  Interface& mb = moab;
36  ErrorCode rval;
37  Range verts;
38 
39  const int num_vtx = 40;
40  std::vector< double > coords( 3 * num_vtx, 0.0 );
41  rval = mb.create_vertices( &coords[0], num_vtx, verts );CHECK_ERR( rval );
42  CHECK_EQUAL( num_vtx, (int)verts.size() );
43 
44  EntityHandle set;
45  rval = mb.create_meshset( MESHSET_SET, set );CHECK_ERR( rval );
46  rval = mb.add_entities( set, verts );CHECK_ERR( rval );
47 
48  std::vector< EntityHandle > dead_verts;
49  for( int i = num_vtx / 4; i < num_vtx; i += num_vtx / 4 )
50  {
51  Range::iterator j = verts.begin();
52  j += i;
53  dead_verts.push_back( *j );
54  }
55  rval = mb.delete_entities( &dead_verts[0], dead_verts.size() );CHECK_ERR( rval );
56 
57  Core moab2;
58  Interface& mb2 = moab2;
59  EntityHandle file_set;
60  read_write_file( mb, mb2, &file_set );
61  Range sets;
62  rval = mb2.get_entities_by_type( 0, MBENTITYSET, sets );CHECK_ERR( rval );
63  CHECK_EQUAL( 2, (int)sets.size() );
64  EntityHandle other_set = sets.front() == file_set ? sets.back() : sets.front();
65 
66  int num_vtx2 = -5;
67  rval = mb2.get_number_entities_by_type( other_set, MBVERTEX, num_vtx2 );CHECK_ERR( rval );
68  CHECK_EQUAL( (int)( num_vtx - dead_verts.size() ), num_vtx2 );
69 }
70 
72 {
73  Core moab;
74  Interface& mb = moab;
75  ErrorCode rval;
76  Range verts;
77 
78  const int num_vtx = 40;
79  std::vector< double > coords( 3 * num_vtx, 0.0 );
80  rval = mb.create_vertices( &coords[0], num_vtx, verts );CHECK_ERR( rval );
81  CHECK_EQUAL( num_vtx, (int)verts.size() );
82 
83  EntityHandle set;
84  rval = mb.create_meshset( MESHSET_ORDERED, set );CHECK_ERR( rval );
85  rval = mb.add_entities( set, verts );CHECK_ERR( rval );
86 
87  std::vector< EntityHandle > dead_verts;
88  for( int i = num_vtx / 4; i < num_vtx; i += num_vtx / 4 )
89  {
90  Range::iterator j = verts.begin();
91  j += i;
92  dead_verts.push_back( *j );
93  }
94  rval = mb.delete_entities( &dead_verts[0], dead_verts.size() );CHECK_ERR( rval );
95 
96  Core moab2;
97  Interface& mb2 = moab2;
98  EntityHandle file_set;
99  read_write_file( mb, mb2, &file_set );
100  Range sets;
101  rval = mb2.get_entities_by_type( 0, MBENTITYSET, sets );CHECK_ERR( rval );
102  CHECK_EQUAL( 2, (int)sets.size() );
103  EntityHandle other_set = sets.front() == file_set ? sets.back() : sets.front();
104 
105  std::vector< EntityHandle > list;
106  rval = mb2.get_entities_by_handle( other_set, list );CHECK_ERR( rval );
107  CHECK_EQUAL( verts.size() - dead_verts.size(), list.size() );
108 }
109 
111 {
112  ErrorCode rval;
113  Core moab;
114  double vtxcoords[] = { 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0 };
115  Range verts;
116  rval = moab.create_vertices( vtxcoords, 3, verts );CHECK_ERR( rval );
117  CHECK_EQUAL( 3, (int)verts.size() );
118 
119  EntityHandle tri;
120  EntityHandle conn[3];
121  std::copy( verts.begin(), verts.end(), conn );
122  rval = moab.create_element( MBTRI, conn, 3, tri );CHECK_ERR( rval );
123 
124  EntityHandle set;
125  rval = moab.create_meshset( MESHSET_ORDERED, set );CHECK_ERR( rval );
126  rval = moab.add_entities( set, &tri, 1 );CHECK_ERR( rval );
127 
128  EntityHandle file;
129  read_write_file( moab, moab, &file );
130 
131  int count;
132  rval = moab.get_number_entities_by_type( 0, MBVERTEX, count );CHECK_ERR( rval );
133  CHECK_EQUAL( 6, count );
134  rval = moab.get_number_entities_by_type( file, MBVERTEX, count );CHECK_ERR( rval );
135  CHECK_EQUAL( 3, count );
136 
137  rval = moab.get_number_entities_by_type( 0, MBTRI, count );CHECK_ERR( rval );
138  CHECK_EQUAL( 2, count );
139  rval = moab.get_number_entities_by_type( file, MBTRI, count );CHECK_ERR( rval );
140  CHECK_EQUAL( 1, count );
141 
142  rval = moab.get_number_entities_by_type( 0, MBENTITYSET, count );CHECK_ERR( rval );
143  CHECK_EQUAL( 3, count );
144  rval = moab.get_number_entities_by_type( file, MBENTITYSET, count );CHECK_ERR( rval );
145  CHECK_EQUAL( 1, count );
146 }
147 
149 {
150  ErrorCode rval;
151  Core moab;
152  double vtxcoords[] = { 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0 };
153  Range verts;
154  rval = moab.create_vertices( vtxcoords, 3, verts );CHECK_ERR( rval );
155  CHECK_EQUAL( 3, (int)verts.size() );
156 
157  EntityHandle tri;
158  EntityHandle conn[3];
159  std::copy( verts.begin(), verts.end(), conn );
160  rval = moab.create_element( MBTRI, conn, 3, tri );CHECK_ERR( rval );
161 
162  EntityHandle set;
163  rval = moab.create_meshset( MESHSET_ORDERED, set );CHECK_ERR( rval );
164  rval = moab.add_entities( set, &tri, 1 );CHECK_ERR( rval );
165 
166  rval = moab.write_file( filename );CHECK_ERR( rval );
167 
168  moab.delete_mesh();
169 
170  rval = moab.load_file( filename, 0, "STORE_SETS_FILEIDS;" );CHECK_ERR( rval );
171 
172  Tag setFileIdTag;
173 
174  rval = moab.tag_get_handle( "__FILE_ID_FOR_SETS", setFileIdTag );CHECK_ERR( rval );
175  CHECK( setFileIdTag );
176 
177  Range sets;
178  rval = moab.get_entities_by_type( 0, MBENTITYSET, sets );CHECK_ERR( rval );
179 
180  std::vector< long > vals( sets.size() );
181  rval = moab.tag_get_data( setFileIdTag, sets, &vals[0] );CHECK_ERR( rval );
182 
183  CHECK_EQUAL( 5, (int)vals[0] );
184  if( !keep_file ) remove( filename );
185 
186  return;
187 }
188 
189 int coords_by_idx( int idx, double coords[][3] )
190 {
191  coords[0][0] = idx;
192  coords[0][1] = 0;
193  coords[0][2] = 0;
194  coords[1][0] = 0;
195  coords[1][1] = idx;
196  coords[1][2] = 0;
197  coords[2][0] = 0;
198  coords[2][1] = 0;
199  coords[2][2] = idx;
200  coords[3][0] = 3.14 * idx;
201  coords[3][1] = 1;
202  coords[3][2] = 1;
203  coords[4][0] = 1;
204  coords[4][1] = 3.14 * idx;
205  coords[4][2] = 1;
206  coords[5][0] = 1;
207  coords[5][1] = 1;
208  coords[5][2] = 3.14 * idx;
209  return idx % 5 + 1;
210 }
211 
212 void recursive_build_tree( int max_depth, Interface& mb, Tag tag, EntityHandle p, int depth, int& idx )
213 {
214  ErrorCode rval = mb.tag_set_data( tag, &p, 1, &idx );CHECK_ERR( rval );
215 
216  Range verts;
217  double coords[6][3];
218  int num_vtx = coords_by_idx( idx, coords );
219  rval = mb.create_vertices( &coords[0][0], num_vtx, verts );
220  rval = mb.add_entities( p, verts );
221  ++idx;
222  if( depth == max_depth ) return;
223 
224  EntityHandle l, r;
225  rval = mb.create_meshset( MESHSET_SET, l );CHECK_ERR( rval );
226  rval = mb.create_meshset( MESHSET_SET, r );CHECK_ERR( rval );
227  rval = mb.add_parent_child( p, l );CHECK_ERR( rval );
228  rval = mb.add_parent_child( p, r );CHECK_ERR( rval );
229 
230  recursive_build_tree( max_depth, mb, tag, l, depth + 1, idx );
231  recursive_build_tree( max_depth, mb, tag, r, depth + 1, idx );
232 }
233 
234 void recursive_check_tree( int max_depth, Interface& mb, Tag tag, EntityHandle p, int depth, int& idx )
235 {
236  int id;
237  ErrorCode rval = mb.tag_get_data( tag, &p, 1, &id );CHECK_ERR( rval );
238  CHECK_EQUAL( idx, id );
239 
240  Range verts;
241  double coords[6][3];
242  int num_vtx = coords_by_idx( idx, coords );
243  rval = mb.get_entities_by_handle( p, verts );
244  CHECK( verts.all_of_type( MBVERTEX ) );
245  CHECK_EQUAL( num_vtx, (int)verts.size() );
246  double coords2[6][3];
247  rval = mb.get_coords( verts, &coords2[0][0] );
248  std::vector< bool > match( 6, true );
249  for( int i = 0; i < num_vtx; ++i )
250  {
251  match[i] = false;
252  for( int j = 0; j < num_vtx; ++j )
253  {
254  if( !match[j] )
255  {
256  double d[3] = { coords[i][0] - coords2[j][0], coords[i][1] - coords2[j][1],
257  coords[i][2] - coords2[j][2] };
258  double ds = d[0] * d[0] + d[1] * d[1] + d[2] * d[2];
259  if( ds < 1e-12 )
260  {
261  match[j] = true;
262  break;
263  }
264  }
265  }
266  }
267  CHECK( match[0] );
268  CHECK( match[1] );
269  CHECK( match[2] );
270  CHECK( match[3] );
271  CHECK( match[4] );
272  CHECK( match[5] );
273 
274  ++idx;
275 
276  std::vector< EntityHandle > children, parents;
277 
278  rval = mb.get_child_meshsets( p, children );CHECK_ERR( rval );
279  if( depth == max_depth )
280  {
281  CHECK_EQUAL( (size_t)0, children.size() );
282  return;
283  }
284 
285  CHECK_EQUAL( (size_t)2, children.size() );
286  EntityHandle l = children.front();
287  EntityHandle r = children.back();
288 
289  parents.clear();
290  rval = mb.get_parent_meshsets( l, parents );CHECK_ERR( rval );
291  CHECK_EQUAL( (size_t)1, parents.size() );
292  CHECK_EQUAL( p, parents.front() );
293  parents.clear();
294  rval = mb.get_parent_meshsets( r, parents );CHECK_ERR( rval );
295  CHECK_EQUAL( (size_t)1, parents.size() );
296  CHECK_EQUAL( p, parents.front() );
297 
298  recursive_check_tree( max_depth, mb, tag, l, depth + 1, idx );
299  recursive_check_tree( max_depth, mb, tag, r, depth + 1, idx );
300 }
301 
302 void test_tree( int max_depth )
303 {
304  ErrorCode rval;
305  Core moab;
306  Interface& mb = moab;
307  EntityHandle root;
308 
309  // create tag in which to store number for each tree node,
310  // in depth-first in-order search order.
311  Tag tag;
312  rval = mb.tag_get_handle( "GLOBAL_ID", 1, MB_TYPE_INTEGER, tag );CHECK_ERR( rval );
313 
314  // create a binary tree to a depth of 20 (about 1 million nodes)
315  rval = mb.create_meshset( MESHSET_SET, root );CHECK_ERR( rval );
316  int idx = 1;
317  recursive_build_tree( max_depth, mb, tag, root, 1, idx );
318  const int last_idx = idx;
319  std::cerr << "Created binary tree containing " << last_idx << " nodes." << std::endl;
320 
321  std::ostringstream str;
322  str << "tree-" << max_depth << ".h5m";
323 
324  // write file and read back in
325  rval = mb.write_file( str.str().c_str(), 0, "BUFFER_SIZE=1024;DEBUG_BINIO" );CHECK_ERR( rval );
326  mb.delete_mesh();
327  rval = mb.load_file( str.str().c_str() );
328  if( !keep_file ) remove( str.str().c_str() );CHECK_ERR( rval );
329 
330  // get tree root
331  rval = mb.tag_get_handle( "GLOBAL_ID", 1, MB_TYPE_INTEGER, tag );CHECK_ERR( rval );
332  Range roots;
333  idx = 1;
334  const void* vals[] = { &idx };
335  rval = mb.get_entities_by_type_and_tag( 0, MBENTITYSET, &tag, vals, 1, roots );
336  CHECK_EQUAL( (size_t)1, roots.size() );
337  root = roots.front();
338 
339  // check that tree is as we expect it
340  idx = 1;
341  recursive_check_tree( max_depth, mb, tag, root, 1, idx );
342  CHECK_EQUAL( last_idx, idx );
343 }
344 
346 {
347  int max_depth = 8;
348  const char* str = getenv( "MAX_DEPTH" );
349  if( str )
350  {
351  max_depth = atoi( str );
352  CHECK( max_depth > 0 );
353  }
354  test_tree( max_depth );
355 }
356 
358 {
359  test_tree( 20 );
360 }
361 
363 
364 void test_set_flags();
365 
366 int main( int argc, char* argv[] )
367 {
368 #ifdef MOAB_HAVE_MPI
369  int fail = MPI_Init( &argc, &argv );
370  if( fail ) return fail;
371 #endif
372 
373  bool do_big_tree_test = false;
374  for( int i = 1; i < argc; ++i )
375  {
376  if( std::string( argv[i] ) == "-k" )
377  keep_file = true;
378  else if( std::string( argv[i] ) == "-b" )
379  do_big_tree_test = true;
380  else
381  {
382  std::cerr << "Usage: " << argv[0] << " [-k] [-b]" << std::endl;
383  return 1;
384  }
385  }
386 
387  int exitval = 0;
390  exitval += RUN_TEST( test_file_set );
391  exitval += RUN_TEST( test_small_tree );
392  exitval += RUN_TEST( test_set_flags );
393  exitval += RUN_TEST( regression_mmiller_8_2010 );
394  exitval += RUN_TEST( test_sets_fileids );
395  if( do_big_tree_test )
396  {
397  exitval += RUN_TEST( test_big_tree );
398  }
399 
400 #ifdef MOAB_HAVE_MPI
401  fail = MPI_Finalize();
402  if( fail ) return fail;
403 #endif
404 
405  return exitval;
406 }
407 
408 // NOTE: this test makes some assuptions about handles:
409 // mainly that they will be assigned sequentially
410 // in the same order as defined in the file and
411 // beginning with ID 1
413 {
414  Core moab;
415  Interface& mb = moab;
416 
417  const size_t num_vtx = 171;
418  const size_t num_pri = 12;
419  const size_t num_pyr = 8;
420  const size_t num_hex = 100;
421  const size_t num_set = 25;
422 
423  mb.load_file( std::string( TestDir + "unittest/h5file/rocket_ents_in_assm.h5m" ).c_str() );
424 
425  /* Dump of set contents from input file:
426  1r: 172, 4,
427  2r: 192, 4, 204, 4, 216, 4, 228, 4, 240, 4, 252, 4, 264, 4, 276, 4,
428  3r: 288, 4,
429  4 : 181, 183, 185, 187,
430  5r: 176, 5, 182, 1, 184, 1, 186, 1, 188, 4, 196, 8, 208, 8, 220, 8, 232, 8, 244, 8, 256, 8,
431  268, 8, 280, 8, 6r: 172, 4, 192, 4, 204, 4, 216, 4, 228, 4, 240, 4, 252, 4, 264, 4, 276, 4, 288,
432  4, 7r: 176, 4, 188, 4, 196, 8, 208, 8, 220, 8, 232, 8, 244, 8, 8r: 180, 8, 256, 8, 268, 8, 280,
433  8, 9r: 172, 120, 301, 1, 309, 1, 10r: 176, 4, 188, 100, 302, 1, 308, 1, 11r: 176, 4, 188, 52,
434  303, 1, 12r: 176, 4, 188, 4, 304, 4, 13 : 177, 189, 14 : 178, 190, 15 : 179, 191, 16 : 17r: 240,
435  48, 18r: 172, 4, 180, 8, 288, 4, 310, 1, 312, 1, 19r: 180, 8, 288, 4, 311, 1, 20r: 180, 8, 21r:
436  172, 4, 313, 4, 22 : 173, 23 : 174, 24 : 175, 25 : 176, 188
437  */
438 
439  // check expected handles
440 
441  const EntityHandle VTX1 = CREATE_HANDLE( MBVERTEX, 1 );
442  Range range, expected;
443  mb.get_entities_by_type( 0, MBVERTEX, range );
444  CHECK_EQUAL( num_vtx, range.size() );
445  expected.insert( VTX1, VTX1 + num_vtx - 1 );
446  CHECK_EQUAL( expected, range );
447 
448  const EntityHandle PRI1 = CREATE_HANDLE( MBPRISM, 1 );
449  range.clear();
450  expected.clear();
451  mb.get_entities_by_type( 0, MBPRISM, range );
452  CHECK_EQUAL( num_pri, range.size() );
453  expected.insert( PRI1, PRI1 + num_pri - 1 );
454  CHECK_EQUAL( expected, range );
455 
456  const EntityHandle PYR1 = CREATE_HANDLE( MBPYRAMID, 1 );
457  range.clear();
458  expected.clear();
459  mb.get_entities_by_type( 0, MBPYRAMID, range );
460  CHECK_EQUAL( num_pyr, range.size() );
461  expected.insert( PYR1, PYR1 + num_pyr - 1 );
462  CHECK_EQUAL( expected, range );
463 
464  const EntityHandle HEX1 = CREATE_HANDLE( MBHEX, 1 );
465  range.clear();
466  expected.clear();
467  mb.get_entities_by_type( 0, MBHEX, range );
468  CHECK_EQUAL( num_hex, range.size() );
469  expected.insert( HEX1, HEX1 + num_hex - 1 );
470  CHECK_EQUAL( expected, range );
471 
472  const EntityHandle SET1 = CREATE_HANDLE( MBENTITYSET, 1 );
473  range.clear();
474  expected.clear();
475  mb.get_entities_by_type( 0, MBENTITYSET, range );
476  CHECK_EQUAL( num_set, range.size() );
477  expected.insert( SET1, SET1 + num_set - 1 );
478  CHECK_EQUAL( expected, range );
479 
480  // Check set contents
481 
482  // Set 1: Pyramids 1 to 4
483  range.clear();
484  mb.get_entities_by_handle( SET1, range );
485  expected.clear();
486  expected.insert( PYR1 + 0, PYR1 + 3 );
487  CHECK_EQUAL( expected, range );
488 
489  // Skip sets 2 through 8 because they're long and complicated and
490  // I doubt I could code up the content lists explicitly from the
491  // dump of the HDF5 file w/out many mistakes
492 
493  // Set 9: Pyramids 1 to 8, Prism 1 to 12, Hex 1 to 100, and Sets 10 and 18
494  range.clear();
495  mb.get_entities_by_handle( SET1 + 8, range );
496  expected.clear();
497  expected.insert( PYR1 + 0, PYR1 + 7 );
498  expected.insert( PRI1 + 0, PRI1 + 11 );
499  expected.insert( HEX1 + 0, HEX1 + 99 );
500  expected.insert( SET1 + 9 );
501  expected.insert( SET1 + 17 );
502  CHECK_EQUAL( expected, range );
503 
504  // Set 10: Pyramids 5 to 8, Prism 9 to 12, Hex 1 to 96, and Sets 11 and 17
505  range.clear();
506  mb.get_entities_by_handle( SET1 + 9, range );
507  expected.clear();
508  expected.insert( PYR1 + 4, PYR1 + 7 );
509  expected.insert( PRI1 + 8, PRI1 + 11 );
510  expected.insert( HEX1 + 0, HEX1 + 95 );
511  expected.insert( SET1 + 10 );
512  expected.insert( SET1 + 16 );
513  CHECK_EQUAL( expected, range );
514 
515  // Set 11: Pyramids 5 to 8, Prism 9 to 12, Hex 1 to 48, and Set 12
516  range.clear();
517  mb.get_entities_by_handle( SET1 + 10, range );
518  expected.clear();
519  expected.insert( PYR1 + 4, PYR1 + 7 );
520  expected.insert( PRI1 + 8, PRI1 + 11 );
521  expected.insert( HEX1 + 0, HEX1 + 47 );
522  expected.insert( SET1 + 11 );
523  CHECK_EQUAL( expected, range );
524 
525  // Set 12: Pyramids 5 to 8, Prism 9 to 12, and Sets 13 to 16
526  range.clear();
527  mb.get_entities_by_handle( SET1 + 11, range );
528  expected.clear();
529  expected.insert( PYR1 + 4, PYR1 + 7 );
530  expected.insert( PRI1 + 8, PRI1 + 11 );
531  expected.insert( SET1 + 12, SET1 + 15 );
532  CHECK_EQUAL( expected, range );
533 
534  // Set 13: Pyramids 6 and Prism 10
535  range.clear();
536  mb.get_entities_by_handle( SET1 + 12, range );
537  expected.clear();
538  expected.insert( PYR1 + 5 );
539  expected.insert( PRI1 + 9 );
540  CHECK_EQUAL( expected, range );
541 
542  // Set 14: Pyramids 7 and Prism 11
543  range.clear();
544  mb.get_entities_by_handle( SET1 + 13, range );
545  expected.clear();
546  expected.insert( PYR1 + 6 );
547  expected.insert( PRI1 + 10 );
548  CHECK_EQUAL( expected, range );
549 
550  // Set 15: Pyramids 8 and Prism 12
551  range.clear();
552  mb.get_entities_by_handle( SET1 + 14, range );
553  expected.clear();
554  expected.insert( PYR1 + 7 );
555  expected.insert( PRI1 + 11 );
556  CHECK_EQUAL( expected, range );
557 
558  // Set 16: Empty
559  range.clear();
560  mb.get_entities_by_handle( SET1 + 15, range );
561  expected.clear();
562  CHECK_EQUAL( expected, range );
563 
564  // Set 17: Hex 49 to 96
565  range.clear();
566  mb.get_entities_by_handle( SET1 + 16, range );
567  expected.clear();
568  expected.insert( HEX1 + 48, HEX1 + 95 );
569  CHECK_EQUAL( expected, range );
570 
571  // Set 18: Pyramids 1 to 4, Prism 1 to 8, Hex 97 to 100, and Sets 19 and 21
572  range.clear();
573  mb.get_entities_by_handle( SET1 + 17, range );
574  expected.clear();
575  expected.insert( PYR1 + 0, PYR1 + 3 );
576  expected.insert( PRI1 + 0, PRI1 + 7 );
577  expected.insert( HEX1 + 96, HEX1 + 99 );
578  expected.insert( SET1 + 18 );
579  expected.insert( SET1 + 20 );
580  CHECK_EQUAL( expected, range );
581 
582  // Set 19: Prism 1 to 8, Hex 97 to 100, and Set 20
583  range.clear();
584  mb.get_entities_by_handle( SET1 + 18, range );
585  expected.clear();
586  expected.insert( PRI1 + 0, PRI1 + 7 );
587  expected.insert( HEX1 + 96, HEX1 + 99 );
588  expected.insert( SET1 + 19 );
589  CHECK_EQUAL( expected, range );
590 
591  // Set 20: Prism 1 to 8
592  range.clear();
593  mb.get_entities_by_handle( SET1 + 19, range );
594  expected.clear();
595  expected.insert( PRI1 + 0, PRI1 + 7 );
596  CHECK_EQUAL( expected, range );
597 
598  // Set 21: Pyramids 1 to 4, and Sets 22 to 25
599  range.clear();
600  mb.get_entities_by_handle( SET1 + 20, range );
601  expected.clear();
602  expected.insert( PYR1 + 0, PYR1 + 3 );
603  expected.insert( SET1 + 21, SET1 + 24 );
604  CHECK_EQUAL( expected, range );
605 
606  // Set 22: Pyramid 2
607  range.clear();
608  mb.get_entities_by_handle( SET1 + 21, range );
609  expected.clear();
610  expected.insert( PYR1 + 1 );
611  CHECK_EQUAL( expected, range );
612 
613  // Set 23: Pyramid 3
614  range.clear();
615  mb.get_entities_by_handle( SET1 + 22, range );
616  expected.clear();
617  expected.insert( PYR1 + 2 );
618  CHECK_EQUAL( expected, range );
619 
620  // Set 24: Pyramid 4
621  range.clear();
622  mb.get_entities_by_handle( SET1 + 23, range );
623  expected.clear();
624  expected.insert( PYR1 + 3 );
625  CHECK_EQUAL( expected, range );
626 
627  // Set 25: Pyramid 5 and Prism 9
628  range.clear();
629  mb.get_entities_by_handle( SET1 + 24, range );
630  expected.clear();
631  expected.insert( PYR1 + 4 );
632  expected.insert( PRI1 + 8 );
633  CHECK_EQUAL( expected, range );
634 }
635 
636 // Test to reproduce bug reported by brandom smith on 2011-3-7
637 // and test other possible issues with the somewhat inconsistant
638 // meshset creation flags. Bug was fixed in SVN revision 4548.
640 {
641  const char filename2[] = "test_set_flags.h5m";
642  ErrorCode rval;
643  Core core;
644  Interface& mb = core;
645 
646  // create a bunch of vertices so we have something to put in sets
647  const int nverts = 20;
648  double coords[3 * nverts] = { 0.0 };
649  Range verts;
650  rval = mb.create_vertices( coords, nverts, verts );CHECK_ERR( rval );
651 
652  // Assign IDs to things so that we can identify them in the
653  // data we read back in.
654  Tag tag;
655  rval = mb.tag_get_handle( "GLOBAL_ID", 1, MB_TYPE_INTEGER, tag );CHECK_ERR( rval );
656  int ids[nverts];
657  for( int i = 0; i < nverts; ++i )
658  ids[i] = i + 1;
659  rval = mb.tag_set_data( tag, verts, ids );CHECK_ERR( rval );
660 
661  // define two lists of vertex ids corresponding to the
662  // vertices that we are going to put into different sets
663  const int set_verts1[] = { 1, 2, 3, 4, 8, 13, 14, 15 };
664  const int set_verts2[] = { 3, 9, 10, 11, 12, 13, 14, 15, 16, 17 };
665  const int num_verts1 = sizeof( set_verts1 ) / sizeof( set_verts1[0] );
666  const int num_verts2 = sizeof( set_verts1 ) / sizeof( set_verts1[0] );
667 
668  // convert to handle lists
669  EntityHandle set_handles1[num_verts1], set_handles2[num_verts2];
670  for( int i = 0; i < num_verts1; ++i )
671  set_handles1[i] = *( verts.begin() + set_verts1[i] - 1 );
672  for( int i = 0; i < num_verts2; ++i )
673  set_handles2[i] = *( verts.begin() + set_verts2[i] - 1 );
674 
675  // now create some sets with different flag combinations
676  EntityHandle sets[6];
677  rval = mb.create_meshset( 0, sets[0] );
678  rval = mb.create_meshset( MESHSET_TRACK_OWNER, sets[1] );
679  rval = mb.create_meshset( MESHSET_SET, sets[2] );
680  rval = mb.create_meshset( MESHSET_SET | MESHSET_TRACK_OWNER, sets[3] );
681  rval = mb.create_meshset( MESHSET_ORDERED, sets[4] );
682  rval = mb.create_meshset( MESHSET_ORDERED | MESHSET_TRACK_OWNER, sets[5] );
683 
684  // assign IDs to sets so that we can identify them later
685  rval = mb.tag_set_data( tag, sets, 6, ids );CHECK_ERR( rval );
686  // add entities to sets
687  rval = mb.add_entities( sets[0], set_handles1, num_verts1 );CHECK_ERR( rval );
688  rval = mb.add_entities( sets[1], set_handles2, num_verts2 );CHECK_ERR( rval );
689  rval = mb.add_entities( sets[2], set_handles1, num_verts1 );CHECK_ERR( rval );
690  rval = mb.add_entities( sets[3], set_handles2, num_verts2 );CHECK_ERR( rval );
691  rval = mb.add_entities( sets[4], set_handles1, num_verts1 );CHECK_ERR( rval );
692  rval = mb.add_entities( sets[5], set_handles2, num_verts2 );CHECK_ERR( rval );
693 
694  // now write the file and read it back in
695  rval = mb.write_file( filename2, 0, "BUFFER_SIZE=1024;DEBUG_BINIO" );CHECK_ERR( rval );
696  mb.delete_mesh();
697  rval = mb.load_file( filename2 );
698  if( !keep_file ) remove( filename2 );CHECK_ERR( rval );
699  rval = mb.tag_get_handle( "GLOBAL_ID", 1, MB_TYPE_INTEGER, tag );CHECK_ERR( rval );
700 
701  // find our sets
702  Range tmp;
703  for( int i = 0; i < 6; ++i )
704  {
705  int id = i + 1;
706  tmp.clear();
707  const void* vals[] = { &id };
708  rval = mb.get_entities_by_type_and_tag( 0, MBENTITYSET, &tag, vals, 1, tmp );CHECK_ERR( rval );
709  CHECK_EQUAL( 1u, (unsigned)tmp.size() );
710  sets[i] = tmp.front();
711  }
712 
713  // check that sets have correct flags
714  unsigned opts;
715  rval = mb.get_meshset_options( sets[0], opts );CHECK_ERR( rval );
716  CHECK_EQUAL( 0u, opts );
717  rval = mb.get_meshset_options( sets[1], opts );CHECK_ERR( rval );
718  CHECK_EQUAL( (unsigned)MESHSET_TRACK_OWNER, opts );
719  rval = mb.get_meshset_options( sets[2], opts );CHECK_ERR( rval );
720  CHECK_EQUAL( (unsigned)MESHSET_SET, opts );
721  rval = mb.get_meshset_options( sets[3], opts );CHECK_ERR( rval );
722  CHECK_EQUAL( (unsigned)( MESHSET_SET | MESHSET_TRACK_OWNER ), opts );
723  rval = mb.get_meshset_options( sets[4], opts );CHECK_ERR( rval );
724  CHECK_EQUAL( (unsigned)MESHSET_ORDERED, opts );
725  rval = mb.get_meshset_options( sets[5], opts );CHECK_ERR( rval );
726  CHECK_EQUAL( (unsigned)( MESHSET_ORDERED | MESHSET_TRACK_OWNER ), opts );
727 
728  // check that sets have correct contents
729  int set_ids1[num_verts1], set_ids2[num_verts2];
730 
731  tmp.clear();
732  rval = mb.get_entities_by_handle( sets[0], tmp );CHECK_ERR( rval );
733  CHECK_EQUAL( num_verts1, (int)tmp.size() );
734  rval = mb.tag_get_data( tag, tmp, set_ids1 );CHECK_ERR( rval );
735  std::sort( set_ids1, set_ids1 + num_verts1 );
736  CHECK_ARRAYS_EQUAL( set_verts1, num_verts1, set_ids1, num_verts1 );
737 
738  tmp.clear();
739  rval = mb.get_entities_by_handle( sets[1], tmp );CHECK_ERR( rval );
740  CHECK_EQUAL( num_verts2, (int)tmp.size() );
741  rval = mb.tag_get_data( tag, tmp, set_ids2 );CHECK_ERR( rval );
742  std::sort( set_ids2, set_ids2 + num_verts2 );
743  CHECK_ARRAYS_EQUAL( set_verts2, num_verts2, set_ids2, num_verts2 );
744 
745  tmp.clear();
746  rval = mb.get_entities_by_handle( sets[2], tmp );CHECK_ERR( rval );
747  CHECK_EQUAL( num_verts1, (int)tmp.size() );
748  rval = mb.tag_get_data( tag, tmp, set_ids1 );CHECK_ERR( rval );
749  std::sort( set_ids1, set_ids1 + num_verts1 );
750  CHECK_ARRAYS_EQUAL( set_verts1, num_verts1, set_ids1, num_verts1 );
751 
752  tmp.clear();
753  rval = mb.get_entities_by_handle( sets[3], tmp );CHECK_ERR( rval );
754  CHECK_EQUAL( num_verts2, (int)tmp.size() );
755  rval = mb.tag_get_data( tag, tmp, set_ids2 );CHECK_ERR( rval );
756  std::sort( set_ids2, set_ids2 + num_verts2 );
757  CHECK_ARRAYS_EQUAL( set_verts2, num_verts2, set_ids2, num_verts2 );
758 
759  tmp.clear();
760  rval = mb.get_entities_by_handle( sets[4], tmp );CHECK_ERR( rval );
761  CHECK_EQUAL( num_verts1, (int)tmp.size() );
762  rval = mb.tag_get_data( tag, tmp, set_ids1 );CHECK_ERR( rval );
763  std::sort( set_ids1, set_ids1 + num_verts1 );
764  CHECK_ARRAYS_EQUAL( set_verts1, num_verts1, set_ids1, num_verts1 );
765 
766  tmp.clear();
767  rval = mb.get_entities_by_handle( sets[5], tmp );CHECK_ERR( rval );
768  CHECK_EQUAL( num_verts2, (int)tmp.size() );
769  rval = mb.tag_get_data( tag, tmp, set_ids2 );CHECK_ERR( rval );
770  std::sort( set_ids2, set_ids2 + num_verts2 );
771  CHECK_ARRAYS_EQUAL( set_verts2, num_verts2, set_ids2, num_verts2 );
772 }