1 #include "moab/Core.hpp"
2 #include "moab/ReorderTool.hpp"
3 #include "TestUtil.hpp"
4
5 using namespace moab;
6
7 // some tag names
8 const char GLOBAL_ID_NAME[] = "GLOBAL_ID"; /* global ID assigned to each vtx and quad */
9 const char SET_IDS_NAME[] = "SET_IDS"; /* global IDs of entities in each set */
10 const char SET_HANDLES_NAME[] = "SET_HANDLES"; /* handles of entities in each set */
11 const char CONN_IDS_NAME[] = "CONN_IDS"; /* global IDs of vertices in each quad */
12 const char CONN_NAME[] = "CONN_HANDLES"; /* handles of vertices in each quad */
13 const char VAR_INTS_NAME[] = "VAR_LEN_INTS"; /* variable length tag on nodes */
14 const char BIT_NAME[] = "TEST_BIT_TAG";
15 const int ENTS_PER_SET = 6;
16 const int BITS_PER_TAG = 2;
17
18 Core* mbcore = 0;
19 Interface* mb = 0;
20 Tag order_tag = 0;
21
22 const size_t INTERVALS = 6;
23
24 /* values for variable-length tag data */
tag_vals_from_gid(int global_id,std::vector<int> & values)25 void tag_vals_from_gid( int global_id, std::vector<int>& values )
26 {
27 int i = global_id / (INTERVALS+1);
28 int j = global_id % (INTERVALS+1);
29 int n = global_id % 5 + 1;
30 int vals[]= { i, j, n, i+j, j-2*i };
31 values.resize(n);
32 std::copy( vals, vals+n, values.begin() );
33 }
34
bits_from_gid(int global_id)35 unsigned char bits_from_gid( int global_id )
36 {
37 return global_id % (1<<BITS_PER_TAG);
38 }
39
order_from_gid(int global_id)40 unsigned char order_from_gid( int global_id )
41 {
42 return global_id % 3;
43 }
44
coords_from_gid(int global_id,double coords[3])45 void coords_from_gid( int global_id, double coords[3] )
46 {
47 int i = global_id / (INTERVALS+1);
48 int j = global_id % (INTERVALS+1);
49 coords[0] = i;
50 coords[1] = j;
51 coords[2] = 0.1*(i+j);
52 }
53
54 void build_mesh();
55 void check_order_by_sets_and_adj();
56 void call_reorder();
57 void check_order();
58 void check_node_coords();
59 void check_quad_conn();
60 void check_set_meshset();
61 void check_list_meshset();
62 void check_big_meshset();
63 void check_handle_tag();
64 void check_varlen_tag();
65 void check_bit_tag();
66
main()67 int main()
68 {
69 // Define global MOAB instance for use by all tests
70 Core mcore;
71 mbcore = &mcore;
72 mb = &mcore;
73
74 // if this fails, don't bother with anything else
75 if (RUN_TEST(build_mesh))
76 return 1;
77
78 // this test needs be be run before reordering the mesh
79 int errors = 0;
80 errors += RUN_TEST(check_order_by_sets_and_adj);
81
82 // if reorder returned failure, don't bother doing anything else
83 int tmp = RUN_TEST(call_reorder);
84 if (tmp)
85 return tmp+errors;
86
87 // test the core stuff
88 errors += RUN_TEST(check_order);
89 errors += RUN_TEST(check_node_coords);
90 errors += RUN_TEST(check_quad_conn);
91 errors += RUN_TEST(check_set_meshset);
92 errors += RUN_TEST(check_list_meshset);
93 errors += RUN_TEST(check_big_meshset);
94 errors += RUN_TEST(check_handle_tag);
95 errors += RUN_TEST(check_varlen_tag);
96 errors += RUN_TEST(check_bit_tag);
97 return errors;
98 }
99
build_mesh()100 void build_mesh( )
101 {
102 const unsigned dense = MB_TAG_CREAT|MB_TAG_DENSE;
103 const unsigned sparse = MB_TAG_CREAT|MB_TAG_SPARSE;
104
105 ErrorCode rval;
106
107 // get/create various tags
108 Tag gid;
109 rval = mb->tag_get_handle( GLOBAL_ID_NAME, 1, MB_TYPE_INTEGER, gid, dense );
110 CHECK_ERR(rval);
111
112 Tag conn_ids;
113 rval = mb->tag_get_handle( CONN_IDS_NAME, 4, MB_TYPE_INTEGER, conn_ids, dense );
114 CHECK_ERR(rval);
115
116 Tag conn_handles;
117 rval = mb->tag_get_handle( CONN_NAME, 4, MB_TYPE_HANDLE, conn_handles, dense );
118 CHECK_ERR(rval);
119
120 Tag set_ids;
121 rval = mb->tag_get_handle( SET_IDS_NAME, ENTS_PER_SET, MB_TYPE_INTEGER, set_ids, sparse );
122 CHECK_ERR(rval);
123
124 Tag set_handles;
125 rval = mb->tag_get_handle( SET_HANDLES_NAME, ENTS_PER_SET, MB_TYPE_HANDLE, set_handles, sparse );
126 CHECK_ERR(rval);
127
128 Tag var_data;
129 rval = mb->tag_get_handle( VAR_INTS_NAME, 0, MB_TYPE_INTEGER, var_data, dense|MB_TAG_VARLEN );
130 CHECK_ERR(rval);
131
132 Tag bit_data;
133 rval = mb->tag_get_handle( BIT_NAME, BITS_PER_TAG, MB_TYPE_BIT, bit_data, MB_TAG_CREAT );
134 CHECK_ERR(rval);
135
136 rval = mb->tag_get_handle( "ORDER", 1, MB_TYPE_INTEGER, order_tag, dense );
137 CHECK_ERR(rval);
138
139 // create and tag vertices
140 std::vector<int> values;
141 EntityHandle nodes[(INTERVALS+1)*(INTERVALS+1)];
142 for (size_t i = 0; i <= INTERVALS; ++i) {
143 for (size_t j = 0; j <= INTERVALS; ++j) {
144 size_t idx = i*(INTERVALS+1) + j;
145 double coords[3];
146 coords_from_gid(idx, coords);
147 rval = mb->create_vertex( coords, nodes[idx] );
148 CHECK_ERR(rval);
149
150 int tagval = idx;
151 rval = mb->tag_set_data( gid, nodes+idx, 1, &tagval );
152 CHECK_ERR(rval);
153
154 tag_vals_from_gid( idx, values );
155 const void* ptr = &values[0];
156 const int size = values.size();
157 rval = mb->tag_set_by_ptr( var_data, nodes+idx, 1, &ptr, &size );
158 CHECK_ERR(rval);
159
160 unsigned char bits = bits_from_gid( idx );
161 rval = mb->tag_set_data( bit_data, nodes+idx, 1, &bits );
162 CHECK_ERR(rval);
163
164 int group = order_from_gid( idx );
165 rval = mb->tag_set_data( order_tag, nodes+idx, 1, &group );
166 CHECK_ERR(rval);
167 }
168 }
169
170 // create and tag elements
171 EntityHandle quads[INTERVALS*INTERVALS];
172 for (size_t i = 0; i < INTERVALS; ++i) {
173 for (size_t j = 0; j < INTERVALS; ++j) {
174 size_t idx = i * INTERVALS + j;
175 size_t n0 = i * (INTERVALS+1) + j;
176 size_t n1 = (i+1) * (INTERVALS+1) + j;
177 size_t n2 = (i+1) * (INTERVALS+1) + j + 1;
178 size_t n3 = i * (INTERVALS+1) + j + 1;
179 EntityHandle conn[4] = { nodes[n0], nodes[n1], nodes[n2], nodes[n3] };
180 EntityHandle h;
181 rval = mb->create_element( MBQUAD, conn, 4, h );
182 CHECK_ERR(rval);
183
184 int tagval = idx;
185 rval = mb->tag_set_data( gid, &h, 1, &tagval );
186 CHECK_ERR(rval);
187
188 int ids[4] = { static_cast<int>(n0), static_cast<int>(n1),
189 static_cast<int>(n2), static_cast<int>(n3) };
190 rval = mb->tag_set_data( conn_ids, &h, 1, ids );
191 CHECK_ERR(rval);
192
193 rval = mb->tag_set_data( conn_handles, &h, 1, conn );
194 CHECK_ERR(rval);
195
196 int group = order_from_gid( idx );
197 rval = mb->tag_set_data( order_tag, &h, 1, &group );
198 CHECK_ERR(rval);
199
200 quads[idx] = h;
201 }
202 }
203
204 // create a few sets
205 for (int i = 0; i < 2; ++i) {
206 EntityHandle* from = 0;
207 size_t count;
208 unsigned flag;
209 if (i) {
210 from = nodes;
211 count = (INTERVALS+1)*(INTERVALS+1);
212 flag = MESHSET_SET;
213 }
214 else {
215 from = quads;
216 count = INTERVALS*INTERVALS;
217 flag = MESHSET_ORDERED;
218 }
219
220 EntityHandle h;
221 rval = mb->create_meshset( flag|MESHSET_TRACK_OWNER, h );
222 CHECK_ERR(rval);
223
224 EntityHandle ents[ENTS_PER_SET];
225 int gids[ENTS_PER_SET];
226 for (int j = 0; j < ENTS_PER_SET; ++j) {
227 int idx = j+2;
228 idx = (idx*idx)%count;
229 ents[j] = from[idx];
230 gids[j] = idx;
231 }
232
233 rval = mb->add_entities( h, ents, ENTS_PER_SET );
234 CHECK_ERR(rval);
235
236 rval = mb->tag_set_data( set_ids, &h, 1, gids );
237 CHECK_ERR(rval);
238
239 rval = mb->tag_set_data( set_handles, &h, 1, ents );
240 CHECK_ERR(rval);
241 }
242
243 // create a set containing all vertices
244 EntityHandle allverts;
245 rval = mb->create_meshset( MESHSET_SET, allverts );
246 CHECK_ERR(rval);
247 rval = mb->add_entities( allverts, nodes, (INTERVALS+1)*(INTERVALS+1) );
248 CHECK_ERR(rval);
249 }
250
call_reorder()251 void call_reorder()
252 {
253 // do reorder
254 ReorderTool tool(mbcore);
255 Tag mapping;
256 ErrorCode rval = tool.handle_order_from_int_tag( order_tag, -1, mapping );
257 CHECK_ERR(rval);
258 rval = tool.reorder_entities( mapping );
259 CHECK_ERR(rval);
260 }
261
check_order(EntityType type)262 void check_order( EntityType type )
263 {
264 ErrorCode rval;
265
266 Tag gid;
267 rval = mb->tag_get_handle( GLOBAL_ID_NAME, 1, MB_TYPE_INTEGER, gid );
268 CHECK_ERR(rval);
269
270 Range ents;
271 rval = mb->get_entities_by_type( 0, type, ents );
272 CHECK_ERR(rval);
273
274 std::vector<int> ids(ents.size());
275 rval = mb->tag_get_data( gid, ents, &ids[0] );
276 CHECK_ERR(rval);
277
278 for (size_t i = 1; i < ids.size(); ++i) {
279 CHECK( order_from_gid(ids[i-1]) <= order_from_gid( ids[i] ) );
280 }
281 }
282
check_order_by_sets_and_adj()283 void check_order_by_sets_and_adj()
284 {
285 ErrorCode rval;
286
287 std::vector<EntityHandle> quads;
288 rval = mb->get_entities_by_dimension( 0, 2, quads );
289 CHECK_ERR(rval);
290 CHECK(!quads.empty());
291
292 // group quads by the ordering assigned in build_mesh()
293 std::map<int,Range> groups;
294 std::vector<int> group_ids(quads.size());
295 rval = mb->tag_get_data( order_tag, &quads[0], quads.size(), &group_ids[0] );
296 CHECK_ERR(rval);
297 for (size_t i = 0; i < quads.size(); ++i)
298 groups[group_ids[i]].insert(quads[i]);
299
300 // create sets from groups
301 Range sets;
302 for (std::map<int,Range>::iterator i = groups.begin(); i != groups.end(); ++i) {
303 EntityHandle h;
304 rval = mb->create_meshset( MESHSET_SET, h );
305 CHECK_ERR(rval);
306 rval = mb->add_entities( h, i->second );
307 CHECK_ERR(rval);
308 sets.insert( h );
309 }
310
311 // Get ordering assigned by set containment
312 Tag neworder = 0;
313 ReorderTool tool(mbcore);
314 rval = tool.handle_order_from_sets_and_adj( sets, neworder );
315 CHECK_ERR(rval);
316
317 // check that new quad handles are clustered as expected
318 std::vector< std::pair<EntityHandle,EntityHandle> > ranges;
319 for (std::map<int,Range>::iterator i = groups.begin(); i != groups.end(); ++i) {
320 std::vector<EntityHandle> newh(i->second.size());
321 rval = mb->tag_get_data( neworder, i->second, &newh[0] );
322 CHECK_ERR(rval);
323 std::sort(newh.begin(), newh.end());
324 CHECK(newh[0] > 0); // zero implies some quad got left out of the reordering
325 std::pair<EntityHandle,EntityHandle> p(newh[0], newh[newh.size()-1]);
326 ranges.push_back(p);
327 }
328 std::sort( ranges.begin(), ranges.end() );
329 for (size_t i = 1; i < ranges.size(); ++i) {
330 CHECK( ranges[i-1].second < ranges[i].first );
331 }
332
333 // group vertices as we expect handles to be grouped
334 std::map< std::vector<int>, Range > vtxgroups;
335 Range verts;
336 rval = mb->get_entities_by_type( 0, MBVERTEX, verts );
337 CHECK_ERR(rval);
338 for (Range::iterator i = verts.begin(); i != verts.end(); ++i) {
339 Range adj;
340 rval = mb->get_adjacencies( &*i, 1, 2, false, adj );
341 CHECK_ERR(rval);
342 std::vector<int> ids(adj.size());
343 rval = mb->tag_get_data( order_tag, adj, &ids[0] );
344 CHECK_ERR(rval);
345 std::sort( ids.begin(), ids.end() );
346 ids.erase( std::unique( ids.begin(), ids.end() ), ids.end() );
347 vtxgroups[ids].insert( *i );
348 }
349
350 // check that new vertex handles are clustered as expected
351 ranges.clear();
352 std::map< std::vector<int>, Range >::iterator j;
353 for (j = vtxgroups.begin(); j != vtxgroups.end(); ++j) {
354 std::vector<EntityHandle> newh(j->second.size());
355 rval = mb->tag_get_data( neworder, j->second, &newh[0] );
356 CHECK_ERR(rval);
357 std::sort(newh.begin(), newh.end());
358 CHECK(newh[0] > 0); // zero implies some quad got left out of the reordering
359 std::pair<EntityHandle,EntityHandle> p(newh[0], newh[newh.size()-1]);
360 ranges.push_back(p);
361 }
362 std::sort( ranges.begin(), ranges.end() );
363 for (size_t i = 1; i < ranges.size(); ++i) {
364 CHECK( ranges[i-1].second < ranges[i].first );
365 }
366 }
367
368
check_order()369 void check_order()
370 {
371 check_order( MBVERTEX );
372 check_order( MBQUAD );
373 }
374
375
check_node_coords()376 void check_node_coords()
377 {
378 ErrorCode rval;
379
380 Tag gid;
381 rval = mb->tag_get_handle( GLOBAL_ID_NAME, 1, MB_TYPE_INTEGER, gid );
382 CHECK_ERR(rval);
383
384 Range verts;
385 rval = mb->get_entities_by_type( 0, MBVERTEX, verts );
386 CHECK_ERR(rval);
387
388 std::vector<int> ids(verts.size());
389 rval = mb->tag_get_data( gid, verts, &ids[0] );
390 CHECK_ERR(rval);
391
392 std::vector<double> coords(3*verts.size());
393 rval = mb->get_coords( verts, &coords[0] );
394 CHECK_ERR(rval);
395
396 std::vector<double> expected(3*verts.size());
397 for (size_t i = 0; i < ids.size(); ++i)
398 coords_from_gid( ids[i], &expected[3*i] );
399
400 CHECK_EQUAL( expected, coords );
401 }
402
403
check_quad_conn()404 void check_quad_conn()
405 {
406 ErrorCode rval;
407
408 Tag gid;
409 rval = mb->tag_get_handle( GLOBAL_ID_NAME, 1, MB_TYPE_INTEGER, gid );
410 CHECK_ERR(rval);
411
412 Tag conn_ids;
413 rval = mb->tag_get_handle( CONN_IDS_NAME, 4, MB_TYPE_INTEGER, conn_ids );
414 CHECK_ERR(rval);
415
416 std::vector<EntityHandle> quads;
417 rval = mb->get_entities_by_type( 0, MBQUAD, quads );
418 CHECK_ERR(rval);
419
420 std::vector<EntityHandle> conn;
421 rval = mb->get_connectivity( &quads[0], quads.size(), conn, true );
422 CHECK_ERR(rval);
423
424 CHECK_EQUAL( 4*quads.size(), conn.size() );
425 std::vector<int> exp_ids(4*quads.size()), act_ids(4*quads.size());
426 rval = mb->tag_get_data( conn_ids, &quads[0], quads.size(), &exp_ids[0] );
427 CHECK_ERR(rval);
428 rval = mb->tag_get_data( gid, &conn[0], conn.size(), &act_ids[0] );
429 CHECK_ERR(rval);
430
431 CHECK_EQUAL( exp_ids, act_ids );
432 }
433
check_meshset_common(bool ordered)434 void check_meshset_common( bool ordered )
435 {
436 ErrorCode rval;
437
438 Tag set_ids;
439 rval = mb->tag_get_handle( SET_IDS_NAME, ENTS_PER_SET, MB_TYPE_INTEGER, set_ids );
440 CHECK_ERR(rval);
441
442 Tag gid;
443 rval = mb->tag_get_handle( GLOBAL_ID_NAME, 1, MB_TYPE_INTEGER, gid );
444 CHECK_ERR(rval);
445
446 Range sets;
447 rval = mb->get_entities_by_type_and_tag( 0, MBENTITYSET, &set_ids, 0, 1, sets );
448 CHECK_ERR(rval);
449 CHECK(!sets.empty());
450
451 EntityHandle set = 0;
452 unsigned flags;
453 for (Range::iterator it = sets.begin(); it != sets.end(); ++it) {
454 rval = mb->get_meshset_options( *it, flags );
455 CHECK_ERR(rval);
456 if (( ordered && (flags & MESHSET_ORDERED)) ||
457 (!ordered && !(flags & MESHSET_ORDERED))) {
458 set = *it;
459 break;
460 }
461 }
462 CHECK(0 != set);
463
464 std::vector<EntityHandle> ents;
465 rval = mb->get_entities_by_handle( set, ents );
466 CHECK_ERR(rval);
467 CHECK_EQUAL( ENTS_PER_SET,(int)ents.size() );
468
469 int exp[ENTS_PER_SET], act[ENTS_PER_SET];
470 rval = mb->tag_get_data( set_ids, &set, 1, exp );
471 CHECK_ERR(rval);
472 rval = mb->tag_get_data( gid, &ents[0], ENTS_PER_SET, act );
473 CHECK_ERR(rval);
474
475 if (!ordered) {
476 std::sort( exp, exp+ENTS_PER_SET );
477 std::sort( act, act+ENTS_PER_SET );
478 }
479
480 CHECK_ARRAYS_EQUAL( exp, ENTS_PER_SET, act, ENTS_PER_SET );
481
482 if (!(flags & MESHSET_TRACK_OWNER))
483 return;
484
485 for (int i = 0; i < ENTS_PER_SET; ++i) {
486 std::vector<EntityHandle> adj;
487 rval = mb->get_adjacencies( &ents[i], 1, 4, false, adj );
488 CHECK_ERR(rval);
489 CHECK( std::find(adj.begin(), adj.end(), set) != adj.end() );
490 }
491 }
492
check_set_meshset()493 void check_set_meshset()
494 {
495 check_meshset_common(false);
496 }
497
check_list_meshset()498 void check_list_meshset()
499 {
500 check_meshset_common(true);
501 }
502
check_big_meshset()503 void check_big_meshset()
504 {
505 // Mesh should have a single set that contains all the vertices.
506 // Find it.
507 Range sets;
508 ErrorCode rval = mb->get_entities_by_type( 0, MBENTITYSET, sets );
509 CHECK_ERR(rval);
510
511 Range verts;
512 rval = mb->get_entities_by_type( 0, MBVERTEX, verts );
513 CHECK_ERR(rval);
514
515 bool found = false;
516 for (Range::iterator it = sets.begin(); it != sets.end(); ++it) {
517 Range ents;
518 rval = mb->get_entities_by_handle( *it, ents );
519 CHECK_ERR(rval);
520 if (ents == verts) {
521 found = true;
522 break;
523 }
524 }
525 CHECK(found);
526 }
527
528
check_handle_tag()529 void check_handle_tag()
530 {
531 Range::iterator it;
532 ErrorCode rval;
533
534 // first check tag on sets, for which the values should have been
535 // updated according to the reordering
536
537 Tag set_handles;
538 rval = mb->tag_get_handle( SET_HANDLES_NAME, ENTS_PER_SET, MB_TYPE_HANDLE, set_handles );
539 CHECK_ERR(rval);
540
541 Range sets;
542 rval = mb->get_entities_by_type_and_tag( 0, MBENTITYSET, &set_handles, 0, 1, sets );
543 CHECK_ERR(rval);
544 CHECK(!sets.empty());
545
546 for (it = sets.begin(); it != sets.end(); ++it) {
547 std::vector<EntityHandle> ents;
548 rval = mb->get_entities_by_handle( *it, ents );
549 CHECK_ERR(rval);
550
551 std::vector<EntityHandle> handles(ENTS_PER_SET);
552 rval = mb->tag_get_data( set_handles, &*it, 1, &handles[0] );
553 CHECK_ERR(rval);
554
555 unsigned flags;
556 rval = mb->get_meshset_options( *it, flags );
557 CHECK_ERR(rval);
558 if (!(flags & MESHSET_ORDERED))
559 std::sort( handles.begin(), handles.end() );
560
561 CHECK_EQUAL( ents, handles );
562 }
563
564 // Now check handle tag on quads. This tag need to both be re-ordered
565 // and have the contained handles updated.
566
567 Tag conn_handles;
568 rval = mb->tag_get_handle( CONN_NAME, 4, MB_TYPE_HANDLE, conn_handles );
569 CHECK_ERR(rval);
570
571 std::vector<EntityHandle> quads;
572 rval = mb->get_entities_by_type( 0, MBQUAD, quads );
573 CHECK_ERR(rval);
574
575 std::vector<EntityHandle> conn;
576 rval = mb->get_connectivity( &quads[0], quads.size(), conn, true );
577 CHECK_ERR(rval);
578
579 std::vector<EntityHandle> tagvals(4*quads.size());
580 rval = mb->tag_get_data( conn_handles, &quads[0], quads.size(), &tagvals[0] );
581 CHECK_ERR(rval);
582
583 CHECK_EQUAL( conn, tagvals );
584 }
585
check_varlen_tag()586 void check_varlen_tag()
587 {
588 ErrorCode rval;
589
590 Tag gid;
591 rval = mb->tag_get_handle( GLOBAL_ID_NAME, 1, MB_TYPE_INTEGER, gid );
592 CHECK_ERR(rval);
593
594 Tag var_data;
595 rval = mb->tag_get_handle( VAR_INTS_NAME, 0, MB_TYPE_INTEGER, var_data );
596 CHECK_ERR(rval);
597
598 Range verts;
599 rval = mb->get_entities_by_type( 0, MBVERTEX, verts );
600 CHECK_ERR(rval);
601
602 std::vector<int> gids(verts.size());
603 rval = mb->tag_get_data( gid, verts, &gids[0] );
604 CHECK_ERR(rval);
605
606 std::vector<const void*> ptrs(verts.size());
607 std::vector<int> sizes(verts.size());
608 rval = mb->tag_get_by_ptr( var_data, verts, &ptrs[0], &sizes[0] );
609 CHECK_ERR(rval);
610
611 for (size_t i = 0; i < gids.size(); ++i) {
612 std::vector<int> exp;
613 tag_vals_from_gid( gids[i], exp );
614 CHECK_ARRAYS_EQUAL( &exp[0], exp.size(), (const int*)ptrs[i], sizes[i] );
615 }
616 }
617
618
check_bit_tag()619 void check_bit_tag()
620 {
621 ErrorCode rval;
622
623 Tag gid;
624 rval = mb->tag_get_handle( GLOBAL_ID_NAME, 1, MB_TYPE_INTEGER, gid );
625 CHECK_ERR(rval);
626
627 Tag bit_data;
628 rval = mb->tag_get_handle( BIT_NAME, BITS_PER_TAG, MB_TYPE_BIT, bit_data );
629 CHECK_ERR(rval);
630
631 Range verts;
632 rval = mb->get_entities_by_type( 0, MBVERTEX, verts );
633 CHECK_ERR(rval);
634
635 std::vector<int> gids(verts.size());
636 rval = mb->tag_get_data( gid, verts, &gids[0] );
637 CHECK_ERR(rval);
638
639 std::vector<unsigned char> exp(gids.size()), act(gids.size());
640 for (size_t i = 0; i < exp.size(); ++i)
641 exp[i] = bits_from_gid( gids[i] );
642
643 rval = mb->tag_get_data( bit_data, verts, &act[0] );
644 CHECK_ERR(rval);
645
646 CHECK_EQUAL( exp, act );
647 }
648