1 #include "moab/Core.hpp"
2 #include "moab/Range.hpp"
3 #include "TestRunner.hpp"
4 #include "ReadHDF5.hpp"
5 #include "MBTagConventions.hpp"
6 #include "moab/FileOptions.hpp"
7
8 #ifdef MOAB_HAVE_MPI
9 #include "moab_mpi.h"
10 #endif
11
12 #include <vector>
13 #include <stdlib.h>
14 #include <iostream>
15 #include <algorithm>
16 #include <limits>
17
18 using namespace moab;
19
20 const char TEST_FILE[] = "partial.h5m";
21 #define READ_OPTS "BUFFER_SIZE=256"
22 const char ID_TAG_NAME[] = "test_id_tag";
23
24
25 static void test_read_nothing_common( bool non_existant );
26 static void test_read_nodes_common( int num_read_sets, bool blocked_coordinate_io );
27 static void test_read_handle_tag_common( bool var_len );
28
29 const int MBQUAD_INT = 20;
30 const int NUM_SETS = 10;
31 const int SET_WIDTH = (MBQUAD_INT + NUM_SETS - 1) / NUM_SETS; // ceil(MBQUAD_INT/NUM_SETS)
32 const char LOGICAL_NAME[] = "logical"; // tag storing logical (i,j) coordinates
33 const char CENTROID_NAME[] = "centroid"; // tag storing position of centroid (x,y,0)
34 //! Create a regular MBQUAD_INT^2 element quad mesh with regularly
35 //! spaced coordinates in the range [1,100]. Group elements
36 //! into 10 vertical strips MBQUAD_INT/10 elements wide. Tag elements,
37 //! vertices and/or sets with ID in [1,10] stored in ID_TAG_NAME
38 //! tag. Write new mesh to TEST_FILE.
39 void create_mesh( bool create_element_sets,
40 bool create_vertex_sets,
41 bool tag_elements_with_id,
42 bool tag_vertices_with_id,
43 const char* adj_elem_tag_name = 0,
44 bool var_len_adj_elems = false );
45 // Given a list of vertices adjacent to a quad strip, identify it as one of the
46 // NUM_SETS strips of quads written by create_mesh.
47 int identify_set( Interface& mb, const Range& verts );
48 int identify_set( Interface& mb, EntityHandle set );
49
50 static Tag check_tag( Interface& mb,
51 const char* name,
52 TagType storage,
53 DataType type,
54 int size );
55
56 enum GatherTestMode { GATHER_SETS, GATHER_CONTENTS, GATHER_NONE };
57 void test_gather_sets_common( bool contained_sets, GatherTestMode mode, bool no_parent_containing_sets = false );
58 void test_gather_sets_ranged( bool contained_sets, GatherTestMode mode, bool no_parent_containing_sets = false );
59
60
61 //! Read a set containing no entities
test_read_empty_set()62 void test_read_empty_set()
63 { test_read_nothing_common( false ); }
64
65 //! Specify ID that doesn't exist in file
test_read_non_existant_set()66 void test_read_non_existant_set()
67 { test_read_nothing_common( true ); }
68
69 //! Read in the nodes contained in a set.
test_read_one_set_nodes()70 void test_read_one_set_nodes()
71 { test_read_nodes_common(1, false); }
72
73 //! Read in the nodes contained in a set.
test_read_one_set_nodes_blocked()74 void test_read_one_set_nodes_blocked()
75 { test_read_nodes_common(1, true); }
76
77 //! Read in the elems contained in a set
78 void test_read_one_set_elems();
79
80 //! Read in the polyhedra contained in a set
81 void test_read_one_set_polyhedra();
82
83 //! Read in the sets contained in a set.
84 //! Should read all sets containing read elements or nodes
85 //! and all sets that are contained the the specified "read"
86 //! set. Test the later here.
87 void test_read_set_sets();
88
89 //! Read in the nodes contained in a sets.
test_read_two_sets_nodes()90 void test_read_two_sets_nodes()
91 { test_read_nodes_common(2,false); }
92
93 //! Read in the elems contained in a sets
94 void test_read_two_sets_elems();
95
96 //! For any set selected to be read by either explicit designation,
97 //! containing read entities, or contained in an explcitly designated
98 //! set, any child sets are also read. Check that here.
test_read_child_sets_only()99 void test_read_child_sets_only()
100 { test_gather_sets_common( false, GATHER_SETS);
101 test_gather_sets_ranged( false, GATHER_SETS); }
test_read_child_set_contents()102 void test_read_child_set_contents()
103 { test_gather_sets_common( false, GATHER_CONTENTS);
104 test_gather_sets_ranged( false, GATHER_CONTENTS); }
test_read_no_child_sets()105 void test_read_no_child_sets()
106 { test_gather_sets_common( false, GATHER_NONE);
107 test_gather_sets_ranged( false, GATHER_NONE); }
108
109 //! For any set selected to be read by either explicit designation,
110 //! containing read entities, or contained in an explcitly designated
111 //! set, any contained sets are also read. Check that here.
test_read_contained_sets_only()112 void test_read_contained_sets_only()
113 { test_gather_sets_common( true, GATHER_SETS, true);
114 test_gather_sets_ranged( true, GATHER_SETS); }
test_read_contained_set_contents()115 void test_read_contained_set_contents()
116 { test_gather_sets_common( true, GATHER_CONTENTS, true );
117 test_gather_sets_ranged( true, GATHER_CONTENTS); }
test_read_no_contained_sets()118 void test_read_no_contained_sets()
119 { test_gather_sets_common( true, GATHER_NONE, true );
120 test_gather_sets_ranged( true, GATHER_NONE); }
121
122 //! Read in the sets contained in a set.
123 //! Should read all sets containing read elements or nodes
124 //! and all sets that are contained the the specified "read"
125 //! set. Test the former here.
126 void test_read_containing_sets();
127
128 //! Test reading of explicit adjacencies
129 void test_read_adjacencies();
130
131 //! Test reading of sparse double tag data
132 void test_read_double_tag();
133
134 //! Test reading of sparse opaque tag data
135 void test_read_opaque_tag();
136
137 //! Test reading of sparse handle tag data
test_read_handle_tag()138 void test_read_handle_tag()
139 { test_read_handle_tag_common(false); }
140
141 //! Test reading of variable-length tag data
test_var_len_tag()142 void test_var_len_tag()
143 { test_read_handle_tag_common(true); }
144
145 void test_read_tagged_elems();
146
147 void test_read_tagged_nodes();
148
149 void test_read_sides();
150
151 void test_read_ids();
152
153 void test_read_partial_ids();
154
main(int argc,char * argv[])155 int main( int argc, char* argv[] )
156 {
157 #ifdef MOAB_HAVE_MPI
158 int fail = MPI_Init(&argc, &argv);
159 if (fail) return fail;
160 #endif
161
162 REGISTER_TEST(test_read_empty_set);
163 REGISTER_TEST(test_read_non_existant_set);
164 REGISTER_TEST(test_read_one_set_nodes);
165 REGISTER_TEST(test_read_one_set_nodes_blocked);
166 REGISTER_TEST(test_read_one_set_elems);
167 REGISTER_TEST(test_read_one_set_polyhedra);
168 REGISTER_TEST(test_read_set_sets);
169 REGISTER_TEST(test_read_two_sets_nodes);
170 REGISTER_TEST(test_read_two_sets_elems);
171 REGISTER_TEST(test_read_child_sets_only);
172 REGISTER_TEST(test_read_child_set_contents);
173 REGISTER_TEST(test_read_no_child_sets);
174 REGISTER_TEST(test_read_contained_sets_only);
175 REGISTER_TEST(test_read_contained_set_contents);
176 REGISTER_TEST(test_read_no_contained_sets);
177 REGISTER_TEST(test_read_containing_sets);
178 REGISTER_TEST(test_read_double_tag);
179 REGISTER_TEST(test_read_opaque_tag);
180 REGISTER_TEST(test_read_handle_tag);
181 REGISTER_TEST(test_var_len_tag);
182 REGISTER_TEST(test_read_adjacencies);
183 REGISTER_TEST(test_read_tagged_elems);
184 REGISTER_TEST(test_read_tagged_nodes);
185 REGISTER_TEST(test_read_sides);
186 REGISTER_TEST(test_read_ids);
187 REGISTER_TEST(test_read_partial_ids);
188 int result = RUN_TESTS( argc, argv );
189
190 #ifdef MOAB_HAVE_MPI
191 fail = MPI_Finalize();
192 if (fail) return fail;
193 #endif
194
195 return result;
196 }
197
test_read_nothing_common(bool non_existant)198 void test_read_nothing_common( bool non_existant )
199 {
200 ErrorCode rval;
201 Core moab;
202 Interface& mb = moab;
203
204 // create a few nodes to write to file
205 std::vector<double> coords( 3000 );
206 Range verts;
207 rval= mb.create_vertices( &coords[0], coords.size()/3, verts );
208 CHECK_ERR(rval);
209
210 // create three entity sets
211 EntityHandle sets[3];
212 rval = mb.create_meshset( MESHSET_SET, sets[0] );
213 CHECK_ERR(rval);
214 rval = mb.create_meshset( MESHSET_SET, sets[1] );
215 CHECK_ERR(rval);
216 rval = mb.create_meshset( MESHSET_ORDERED, sets[2] );
217 CHECK_ERR(rval);
218
219 // put all vertices into two of the sets
220 rval = mb.add_entities( sets[0], verts );
221 CHECK_ERR(rval);
222 rval = mb.add_entities( sets[2], verts );
223 CHECK_ERR(rval);
224
225 // tag all three sets
226 Tag id_tag;
227 rval = mb.tag_get_handle( ID_TAG_NAME, 1, MB_TYPE_INTEGER, id_tag, MB_TAG_SPARSE|MB_TAG_EXCL );
228 CHECK_ERR(rval);
229 int ids[3] = { 5, 7, 9 };
230 rval = mb.tag_set_data( id_tag, sets, 3, ids );
231 CHECK_ERR(rval);
232
233 // write mesh
234 rval = mb.write_file( TEST_FILE, "MOAB" );
235 CHECK_ERR(rval);
236 rval = mb.delete_mesh();
237 CHECK_ERR(rval);
238
239 // now read back in only the empty set
240 EntityHandle file_set;
241 int id = non_existant ? 8 : 7;
242 rval = mb.create_meshset( MESHSET_SET, file_set );
243 CHECK_ERR(rval);
244 rval = mb.load_file( TEST_FILE, &file_set, READ_OPTS, ID_TAG_NAME, &id, 1 );
245 if (non_existant) {
246 CHECK_EQUAL( MB_ENTITY_NOT_FOUND, rval );
247 return;
248 }
249 else
250 CHECK_ERR( rval );
251
252 // the file should contain exactly two sets (the specified one and the new
253 // file set, and nothing else.)
254 for (EntityType t = MBVERTEX; t < MBENTITYSET; ++t) {
255 int count = -1;
256 rval = mb.get_number_entities_by_type( 0, t, count );
257 CHECK_ERR(rval);
258 CHECK_EQUAL( 0, count );
259 }
260 Range setrange;
261 rval = mb.get_entities_by_type( 0, MBENTITYSET, setrange );
262 CHECK_ERR(rval);
263 CHECK_EQUAL( (non_existant ? 1 : 2), (int)setrange.size() );
264 CHECK( setrange.find(file_set) != setrange.end() );
265 }
266
267
vtx_coords(int set_id,int j,int num_sets,double coords[3])268 static void vtx_coords( int set_id, int j, int num_sets, double coords[3] )
269 {
270 int i = num_sets*j + set_id;
271 coords[0] = i;
272 coords[1] = i+0.25;
273 coords[2] = i+0.5;
274 }
275
test_read_nodes_common(int num_read_sets,bool blocked)276 void test_read_nodes_common( int num_read_sets, bool blocked )
277 {
278 ErrorCode rval;
279 Core moab;
280 Interface& mb = moab;
281
282 // create 1000 nodes
283 const int num_sets = 2*num_read_sets;
284 std::vector<EntityHandle> verts(1000);
285 std::vector< std::vector<EntityHandle> > set_verts(num_sets);
286 for (size_t i = 0; i < verts.size(); ++i) {
287 double coords[3];
288 int j = i % num_sets;
289 vtx_coords( j+1, set_verts[j].size(), num_sets, coords );
290 rval = mb.create_vertex( coords, verts[i] );
291 set_verts[ j ].push_back( verts[i] );
292 CHECK_ERR(rval);
293 }
294
295 // create two sets, each containing half of the nodes
296 std::vector<EntityHandle> sets(num_sets);
297 for (int i = 0; i < num_sets; ++i) {
298 rval = mb.create_meshset( MESHSET_ORDERED, sets[i] );
299 CHECK_ERR(rval);
300 rval = mb.add_entities( sets[i], &set_verts[i][0], set_verts[i].size() );
301 CHECK_ERR(rval);
302 }
303
304 // tag both sets
305 Tag id_tag;
306 rval = mb.tag_get_handle( ID_TAG_NAME, 1, MB_TYPE_INTEGER, id_tag, MB_TAG_SPARSE|MB_TAG_EXCL );
307 CHECK_ERR(rval);
308 std::vector<int> values( num_sets );
309 for (int i = 0; i < num_sets; ++i) values[i] = i+1;
310 rval = mb.tag_set_data( id_tag, &sets[0], num_sets, &values[0] );
311 CHECK_ERR(rval);
312
313 // write file
314 rval = mb.write_file( TEST_FILE, "MOAB" );
315 CHECK_ERR(rval);
316 rval = mb.delete_mesh();
317 CHECK_ERR(rval);
318
319 // now read back in only the specified number of sets
320 std::string opts(READ_OPTS);
321 if (!opts.empty())
322 opts += ';';
323 if (blocked)
324 opts += "BLOCKED_COORDINATE_IO=yes";
325 else
326 opts += "BLOCKED_COORDINATE_IO=no";
327
328 values.resize( num_read_sets );
329 for (int i = 0; i < num_read_sets; ++i) values[i] = 2*(i+1);
330 EntityHandle file_set;
331 rval = mb.create_meshset( MESHSET_SET, file_set );
332 CHECK_ERR(rval);
333 rval = mb.load_file( TEST_FILE, &file_set, opts.c_str(), ID_TAG_NAME, &values[0], num_read_sets );
334 CHECK_ERR(rval);
335
336 int count, expected = 0;
337 rval = mb.get_number_entities_by_dimension( 0, 0, count );
338 CHECK_ERR(rval);
339 for (int i = 0; i < num_sets; ++i)
340 if (i % 2)
341 expected += set_verts[i].size();
342 CHECK_EQUAL( expected, count );
343
344 Range sets2;
345 rval = mb.get_entities_by_type( 0, MBENTITYSET, sets2 );
346 CHECK_ERR(rval);
347 CHECK_EQUAL( 1+num_read_sets, (int)sets2.size() );
348 Range::iterator it = sets2.find( file_set );
349 CHECK( it != sets2.end() );
350 sets2.erase( it );
351
352 rval = mb.tag_get_handle( ID_TAG_NAME, 1, MB_TYPE_INTEGER, id_tag );
353 CHECK_ERR(rval);
354 while (!sets2.empty()) {
355 EntityHandle set = sets2.pop_front();
356 int id;
357 rval = mb.tag_get_data( id_tag, &set, 1, &id );
358 CHECK_ERR(rval);
359 CHECK( std::find(values.begin(), values.end(), id) != values.end() );
360 CHECK( id > 0 );
361 CHECK( (unsigned)id <= set_verts.size() );
362
363 std::vector<EntityHandle> verts2;
364 rval = mb.get_entities_by_handle( set, verts2 );
365 CHECK_ERR(rval);
366 CHECK_EQUAL( set_verts[id-1].size(), verts2.size() );
367
368 for (size_t i = 0; i < verts2.size(); ++i) {
369 double exp_coords[3], coords[3];
370 vtx_coords( id, i, num_sets, exp_coords );
371 rval = mb.get_coords( &verts2[i], 1, coords );
372 CHECK_ERR(rval);
373 CHECK_REAL_EQUAL( exp_coords[0], coords[0], 1e-12 );
374 CHECK_REAL_EQUAL( exp_coords[1], coords[1], 1e-12 );
375 CHECK_REAL_EQUAL( exp_coords[2], coords[2], 1e-12 );
376 }
377 }
378 }
379
380 //! Create a regular MBQUAD_INT^2 element quad mesh with regularly
381 //! spaced coordinates in the range [1,100]. Group elements
382 //! into 10 vertical strips MBQUAD_INT/10 elements wide. Tag elements,
383 //! vertices and/or sets with ID in [1,10] stored in ID_TAG_NAME
384 //! tag. Write new mesh to TEST_FILE.
create_mesh(bool create_element_sets,bool create_vertex_sets,bool tag_elements_with_id,bool tag_vertices_with_id,const char * adj_elem_tag_name,bool var_len_adj_elems)385 void create_mesh( bool create_element_sets,
386 bool create_vertex_sets,
387 bool tag_elements_with_id,
388 bool tag_vertices_with_id,
389 const char* adj_elem_tag_name,
390 bool var_len_adj_elems )
391 {
392 Core moab;
393 Interface& mb = moab;
394 ErrorCode rval;
395
396 // create tags
397 Tag logical_tag, centroid_tag, id_tag;
398 rval = mb.tag_get_handle( ID_TAG_NAME, 1, MB_TYPE_INTEGER, id_tag, MB_TAG_SPARSE|MB_TAG_EXCL );
399 CHECK_ERR(rval);
400 rval = mb.tag_get_handle( LOGICAL_NAME, 2*sizeof(int), MB_TYPE_OPAQUE, logical_tag, MB_TAG_DENSE|MB_TAG_EXCL );
401 CHECK_ERR(rval);
402 rval = mb.tag_get_handle( CENTROID_NAME, 3, MB_TYPE_DOUBLE, centroid_tag, MB_TAG_DENSE|MB_TAG_EXCL );
403 CHECK_ERR(rval);
404
405 EntityHandle sets[NUM_SETS];
406 if (create_element_sets || create_vertex_sets) {
407 for (int i = 0; i < NUM_SETS; ++i) {
408 rval = mb.create_meshset( MESHSET_ORDERED, sets[i] );
409 CHECK_ERR(rval);
410 int id = i+1;
411 rval = mb.tag_set_data( id_tag, &sets[i], 1, &id );
412 CHECK_ERR(rval);
413 }
414 }
415
416 // create elements
417 EntityHandle verts[MBQUAD_INT+1][MBQUAD_INT+1], quads[MBQUAD_INT][MBQUAD_INT];
418 for (int i = 0; i <= MBQUAD_INT; ++i) for(int j = 0; j <= MBQUAD_INT; ++j) {
419 double coords[3] = { static_cast<double>(i), static_cast<double>(j), 0 };
420 rval = mb.create_vertex( coords, verts[j][i] );
421 CHECK_ERR(rval);
422 int logical[2] = { i, j };
423 rval = mb.tag_set_data( logical_tag, &verts[j][i], 1, logical );
424 CHECK_ERR(rval);
425 rval = mb.tag_set_data( centroid_tag, &verts[j][i], 1, coords );
426 CHECK_ERR(rval);
427 int id = (i-1)/SET_WIDTH + 1; // Note: assumes SET_WIDTH > 1
428 if (tag_vertices_with_id) {
429 rval = mb.tag_set_data( id_tag, &verts[j][i], 1, &id );
430 CHECK_ERR(rval);
431 }
432 if (create_vertex_sets) {
433 rval = mb.add_entities( sets[id-1], &verts[j][i], 1 );
434 CHECK_ERR(rval);
435 // Some vertices are shared by quads in different sets.
436 // put such vertices in both sets.
437 int id2 = i/SET_WIDTH + 1;
438 if (id2 != id && id2 <= NUM_SETS) {
439 rval = mb.add_entities( sets[id2-1], &verts[j][i], 1 );
440 CHECK_ERR(rval);
441 }
442 }
443 }
444 for (int i = 0; i < MBQUAD_INT; ++i) for(int j = 0; j < MBQUAD_INT; ++j) {
445 EntityHandle conn[4] = { verts[j ][i ],
446 verts[j ][i+1],
447 verts[j+1][i+1],
448 verts[j+1][i ] };
449 rval = mb.create_element( MBQUAD, conn, 4, quads[j][i] );
450 CHECK_ERR(rval);
451 int logical[2] = { i, j };
452 rval = mb.tag_set_data( logical_tag, &quads[j][i], 1, logical );
453 CHECK_ERR(rval);
454 double centroid[3] = { i + 0.5, j + 0.5, 0 };
455 rval = mb.tag_set_data( centroid_tag, &quads[j][i], 1, centroid );
456 CHECK_ERR(rval);
457 int id = i/SET_WIDTH + 1;
458 if (tag_elements_with_id) {
459 rval = mb.tag_set_data( id_tag, &quads[j][i], 1, &id );
460 CHECK_ERR(rval);
461 }
462 if (create_element_sets) {
463 rval = mb.add_entities( sets[id-1], &quads[j][i], 1 );
464 CHECK_ERR(rval);
465 }
466 }
467
468 if (adj_elem_tag_name && !var_len_adj_elems) {
469 Tag handle_tag;
470 rval = mb.tag_get_handle( adj_elem_tag_name,
471 4,
472 MB_TYPE_HANDLE,
473 handle_tag,
474 MB_TAG_DENSE|MB_TAG_EXCL );
475 CHECK_ERR(rval);
476 for (int i = 0; i <= MBQUAD_INT; ++i) for(int j = 0; j <= MBQUAD_INT; ++j) {
477 EntityHandle val[4] = { (i > 0 && j > 0 ) ? quads[j-1][i-1] : 0,
478 (i > 0 && j < MBQUAD_INT) ? quads[j ][i-1] : 0,
479 (i < MBQUAD_INT && j < MBQUAD_INT) ? quads[j ][i ] : 0,
480 (i < MBQUAD_INT && j > 0 ) ? quads[j-1][i ] : 0 };
481 rval = mb.tag_set_data( handle_tag, &verts[j][i], 1, val );
482 CHECK_ERR(rval);
483 }
484 }
485 else if (adj_elem_tag_name && var_len_adj_elems) {
486 Tag handle_tag;
487 rval = mb.tag_get_handle( adj_elem_tag_name,
488 0, MB_TYPE_HANDLE,
489 handle_tag,
490 MB_TAG_DENSE|MB_TAG_VARLEN|MB_TAG_EXCL );
491 CHECK_ERR(rval);
492 for (int i = 0; i <= MBQUAD_INT; ++i) for(int j = 0; j <= MBQUAD_INT; ++j) {
493 EntityHandle val[4];
494 int num = 0;
495 if (i > 0 && j > 0 ) val[num++] = quads[j-1][i-1];
496 if (i > 0 && j < MBQUAD_INT) val[num++] = quads[j ][i-1];
497 if (i < MBQUAD_INT && j < MBQUAD_INT) val[num++] = quads[j ][i ];
498 if (i < MBQUAD_INT && j > 0 ) val[num++] = quads[j-1][i ];
499 const void* ptr = val;
500 rval = mb.tag_set_by_ptr( handle_tag, &verts[j][i], 1, &ptr, &num );
501 CHECK_ERR(rval);
502 }
503 }
504
505 rval = mb.write_file( TEST_FILE, "MOAB" );
506 CHECK_ERR(rval);
507 }
508
509 // Given a list of vertices adjacent to a quad strip, identify it as one of the
510 // NUM_SETS strips of quads written by create_mesh.
identify_set(Interface & mb,const Range & verts)511 int identify_set( Interface& mb, const Range& verts )
512 {
513 const int COL = SET_WIDTH+1;
514 CHECK_EQUAL( (1+MBQUAD_INT)*COL, (int)verts.size() );
515
516 // Get X range of vertices
517 int min_x = std::numeric_limits<int>::max();
518 int max_x = std::numeric_limits<int>::min();
519 for (Range::const_iterator i = verts.begin(); i != verts.end(); ++i) {
520 double coords[3];
521 ErrorCode rval = mb.get_coords( &*i, 1, coords );
522 CHECK_ERR(rval);
523 // Expect whole-valued coorindates
524 int int_x = (int)coords[0];
525 CHECK( fabs( coords[0] - (double)int_x ) < 1e-12 );
526
527 if (int_x < min_x) min_x = int_x;
528 if (int_x > max_x) max_x = int_x;
529 }
530 CHECK( max_x - min_x < COL );
531
532 // Calculate ID (return value) from coordinate range)
533 const int ID = min_x / SET_WIDTH + 1;
534
535 // Now verify that all vertices correctly form a grid
536 EntityHandle grid[MBQUAD_INT+1][COL];
537 memset( grid, 0, sizeof(grid) );
538 for (Range::const_iterator i = verts.begin(); i != verts.end(); ++i) {
539 double coords[3];
540 ErrorCode rval = mb.get_coords( &*i, 1, coords );
541 CHECK_ERR(rval);
542 // Expect whole-valued coorindates
543 int x = (int)coords[0] - (ID-1)*SET_WIDTH, y = (int)coords[1];
544 CHECK( fabs( coords[1] - (double)y ) < 1e-12 );
545 CHECK( fabs( coords[2] ) < 1e-12 );
546 CHECK( y >= 0 && y <= MBQUAD_INT );
547 CHECK_EQUAL( (EntityHandle)0, grid[y][x] );
548 grid[y][x] = *i;
549 }
550
551 return ID;
552 }
identify_set(Interface & mb,EntityHandle set)553 int identify_set( Interface& mb, EntityHandle set )
554 {
555 ErrorCode rval;
556 Range verts, elems;
557 rval = mb.get_entities_by_handle( set, elems );
558 CHECK_ERR(rval);
559 Range::iterator it = elems.upper_bound( MBVERTEX );
560 verts.merge( elems.begin(), it );
561 elems.erase( elems.begin(), it );
562 it = elems.lower_bound( MBENTITYSET );
563 elems.erase( it, elems.end() );
564 rval = mb.get_adjacencies( elems, 0, false, verts, Interface::UNION );
565 CHECK_ERR(rval);
566 return identify_set( mb, verts );
567 }
568
569 //! Read in the elems contained in a set
test_read_one_set_elems()570 void test_read_one_set_elems()
571 {
572 ErrorCode rval;
573 Core moab;
574 Interface& mb = moab;
575
576 create_mesh( true, false, false, false );
577
578 for (int id = 1; id <= NUM_SETS; ++id) {
579 rval = mb.delete_mesh();
580 CHECK_ERR(rval);
581 rval = mb.load_file( TEST_FILE, 0, READ_OPTS, ID_TAG_NAME, &id, 1 );
582 CHECK_ERR(rval);
583 Range verts;
584 rval = mb.get_entities_by_type( 0, MBVERTEX, verts );
585 int act_id = identify_set( mb, verts );
586 CHECK_EQUAL( id, act_id );
587 }
588 }
589
590 //! Read in the elems contained in a sets
test_read_two_sets_elems()591 void test_read_two_sets_elems()
592 {
593 ErrorCode rval;
594 Core moab;
595 Interface& mb = moab;
596
597 create_mesh( true, false, false, false );
598 int ids[2] = { 2, 8 };
599 EntityHandle file_set;
600 rval = mb.create_meshset( MESHSET_SET, file_set );
601 CHECK_ERR(rval);
602 rval = mb.load_file( TEST_FILE, &file_set, READ_OPTS, ID_TAG_NAME, ids, 2 );
603 CHECK_ERR(rval);
604
605 Range sets;
606 rval = mb.get_entities_by_type( 0, MBENTITYSET, sets );
607 CHECK_ERR(rval);
608 CHECK_EQUAL( 3, (int)sets.size() );
609 Range::iterator it = sets.find( file_set );
610 CHECK( it != sets.end() );
611 sets.erase( it );
612
613 int id1 = identify_set( mb, sets.front() );
614 int id2 = identify_set( mb, sets.back() );
615 if (id1 == ids[0]) {
616 CHECK_EQUAL( ids[1], id2 );
617 }
618 else {
619 CHECK_EQUAL( ids[1], id1 );
620 CHECK_EQUAL( ids[0], id2 );
621 }
622 }
623
check_tag(Interface & mb,const char * name,TagType storage,DataType type,int size)624 Tag check_tag( Interface& mb,
625 const char* name,
626 TagType storage,
627 DataType type,
628 int size )
629 {
630
631 Tag tag;
632 ErrorCode rval = mb.tag_get_handle( name, size, type, tag );
633 CHECK_ERR(rval);
634
635 TagType storage1;
636 rval = mb.tag_get_type( tag, storage1 );
637 CHECK_ERR(rval);
638 CHECK_EQUAL( storage, storage1 );
639
640 DataType type1;
641 rval = mb.tag_get_data_type( tag, type1 );
642 CHECK_ERR(rval);
643 CHECK_EQUAL( type, type1 );
644
645 int size1;
646 rval = mb.tag_get_length( tag, size1 );
647 if (size <= 0) { // variable-length tag
648 CHECK_EQUAL( MB_VARIABLE_DATA_LENGTH, rval );
649 }
650 else {
651 CHECK_ERR(rval);
652 CHECK_EQUAL( size, size1 );
653 }
654
655 return tag;
656 }
657
658 //! Test reading of sparse double tag data
test_read_double_tag()659 void test_read_double_tag()
660 {
661 ErrorCode rval;
662 Core moab;
663 Interface& mb = moab;
664
665 create_mesh( true, false, false, false );
666 int ids[2] = { 1, 4 };
667 rval = mb.load_file( TEST_FILE, 0, READ_OPTS, ID_TAG_NAME, ids, 2 );
668 CHECK_ERR(rval);
669
670 Tag tag = check_tag( mb, CENTROID_NAME, MB_TAG_DENSE, MB_TYPE_DOUBLE, 3 );
671 Range verts;
672 rval = mb.get_entities_by_type( 0, MBVERTEX, verts );
673 CHECK_ERR(rval);
674 CHECK( !verts.empty() );
675 for (Range::iterator i = verts.begin(); i != verts.end(); ++i) {
676 double coords[3], data[3];
677 rval = mb.get_coords( &*i, 1, coords );
678 CHECK_ERR(rval);
679 rval = mb.tag_get_data( tag, &*i, 1, data );
680 CHECK_ERR(rval);
681 CHECK_REAL_EQUAL( coords[0], data[0], 1e-12 );
682 CHECK_REAL_EQUAL( coords[1], data[1], 1e-12 );
683 CHECK_REAL_EQUAL( coords[2], data[2], 1e-12 );
684 }
685 }
686
687 //! Test reading of sparse opaque tag data
test_read_opaque_tag()688 void test_read_opaque_tag()
689 {
690 ErrorCode rval;
691 Core moab;
692 Interface& mb = moab;
693
694 create_mesh( true, false, false, false );
695 int ids[2] = { 1, 4 };
696 rval = mb.load_file( TEST_FILE, 0, READ_OPTS, ID_TAG_NAME, ids, 2 );
697 CHECK_ERR(rval);
698
699 Tag tag = check_tag( mb, LOGICAL_NAME, MB_TAG_DENSE, MB_TYPE_OPAQUE, 2*sizeof(int) );
700 Range verts;
701 rval = mb.get_entities_by_type( 0, MBVERTEX, verts );
702 CHECK_ERR(rval);
703 CHECK( !verts.empty() );
704 for (Range::iterator i = verts.begin(); i != verts.end(); ++i) {
705 double coords[3];
706 int data[2];
707 rval = mb.get_coords( &*i, 1, coords );
708 CHECK_ERR(rval);
709 rval = mb.tag_get_data( tag, &*i, 1, data );
710 CHECK_ERR(rval);
711 CHECK_REAL_EQUAL( coords[0], (double)data[0], 1e-12 );
712 CHECK_REAL_EQUAL( coords[1], (double)data[1], 1e-12 );
713 }
714 }
715
test_read_handle_tag_common(bool var_len)716 static void test_read_handle_tag_common( bool var_len )
717 {
718 ErrorCode rval;
719 Core moab;
720 Interface& mb = moab;
721
722 const char tag_name[] = "VTX_ADJ";
723 create_mesh( true, false, false, false, tag_name, var_len );
724 int ids[2] = { 7, 10 };
725 rval = mb.load_file( TEST_FILE, 0, READ_OPTS, ID_TAG_NAME, ids, 2 );
726 CHECK_ERR(rval);
727
728 Tag tag = check_tag( mb, tag_name, MB_TAG_DENSE, MB_TYPE_HANDLE,
729 var_len ? 0 : 4 );
730 Range verts;
731 rval = mb.get_entities_by_type( 0, MBVERTEX, verts );
732 CHECK_ERR(rval);
733 CHECK( !verts.empty() );
734 for (Range::iterator i = verts.begin(); i != verts.end(); ++i) {
735 std::vector<EntityHandle> adj, val;
736 rval = mb.get_adjacencies( &*i, 1, 2, false, adj, Interface::UNION );
737 CHECK_ERR(rval);
738 CHECK(!adj.empty());
739
740 int num;
741 const void* ptr;
742 rval = mb.tag_get_by_ptr( tag, &*i, 1, &ptr, &num );
743 CHECK_ERR(rval);
744
745 if (var_len) {
746 CHECK( num > 0 );
747 CHECK( num < 5 );
748 }
749 else {
750 CHECK_EQUAL( 4, num );
751 }
752
753 val.clear();
754 const EntityHandle* dat = (const EntityHandle*)ptr;
755 for (const EntityHandle* end = dat+num; dat != end; ++dat)
756 if (*dat)
757 val.push_back(*dat);
758
759 CHECK_EQUAL( adj.size(), val.size() );
760 std::sort( adj.begin(), adj.end() );
761 std::sort( val.begin(), val.end() );
762 CHECK( adj == val );
763 }
764 }
765
766
test_read_tagged_elems()767 void test_read_tagged_elems()
768 {
769 ErrorCode rval;
770 Core moab;
771 Interface& mb = moab;
772
773 create_mesh( false, false, true, false );
774 int id = 5;
775 rval = mb.load_file( TEST_FILE, 0, READ_OPTS, ID_TAG_NAME, &id, 1 );
776 CHECK_ERR(rval);
777
778 Range verts;
779 rval = mb.get_entities_by_type( 0, MBVERTEX, verts );
780 CHECK_ERR(rval);
781 int id2 = identify_set( mb, verts );
782 CHECK_EQUAL( id, id2 );
783
784 int elems;
785 rval = mb.get_number_entities_by_type( 0, MBQUAD, elems );
786 CHECK_ERR(rval);
787 CHECK_EQUAL( MBQUAD_INT*MBQUAD_INT/NUM_SETS, elems );
788 }
789
test_read_tagged_nodes()790 void test_read_tagged_nodes()
791 {
792 ErrorCode rval;
793 Core moab;
794 Interface& mb = moab;
795
796 create_mesh( false, false, false, true );
797 int id = 1; // NOTE: this test will only succeed for ID == 1
798 rval = mb.load_file( TEST_FILE, 0, READ_OPTS, ID_TAG_NAME, &id, 1 );
799 CHECK_ERR(rval);
800
801 Range verts;
802 rval = mb.get_entities_by_type( 0, MBVERTEX, verts );
803 CHECK_ERR(rval);
804 int id2 = identify_set( mb, verts );
805 CHECK_EQUAL( id, id2 );
806
807 int elems;
808 rval = mb.get_number_entities_by_type( 0, MBQUAD, elems );
809 CHECK_ERR(rval);
810 CHECK_EQUAL( MBQUAD_INT*MBQUAD_INT/NUM_SETS, elems );
811 }
812
813
814 //! Read in the polyhedra contained in a set
test_read_one_set_polyhedra()815 void test_read_one_set_polyhedra()
816 {
817 ErrorCode rval;
818 Core instance;
819 Interface& mb = instance;
820
821 // create a 2x2x1 block of hexes, splitting each hex face
822 // into two triangles to form an 12-sided polyhedron
823 EntityHandle verts[18], hexes[4];
824 double coords[18][3] = { {0, 0, 0},
825 {1, 0, 0},
826 {2, 0, 0},
827 {0, 1, 0},
828 {1, 1, 0},
829 {2, 1, 0},
830 {0, 0, 1},
831 {1, 0, 1},
832 {2, 0, 1},
833 {0, 1, 1},
834 {1, 1, 1},
835 {2, 1, 1},
836 {0, 0, 2},
837 {1, 0, 2},
838 {2, 0, 2},
839 {0, 1, 2},
840 {1, 1, 2},
841 {2, 1, 2} };
842 int hexconn[4][8] = { { 0, 1, 4, 3, 6, 7, 10, 9 },
843 { 1, 2, 5, 4, 7, 8, 11, 10 },
844 { 6, 7, 10, 9, 12, 13, 16, 15 },
845 { 7, 8, 11, 10, 13, 14, 17, 16 } };
846 for (int i = 0; i < 18; ++i) {
847 rval = mb.create_vertex( coords[i], verts[i] );
848 CHECK_ERR(rval);
849 }
850 for (int i = 0; i < 4; ++i) {
851 EntityHandle conn[8];
852 for (int j = 0; j < 8; ++j)
853 conn[j] = verts[hexconn[i][j]];
854 rval = mb.create_element( MBHEX, conn, 8, hexes[i] );
855 CHECK_ERR(rval);
856 }
857
858 Tag tri_tag;
859 rval = mb.tag_get_handle( "tris", 2, MB_TYPE_HANDLE, tri_tag, MB_TAG_SPARSE|MB_TAG_EXCL );
860 CHECK_ERR(rval);
861
862 std::vector<EntityHandle> quads;
863 EntityHandle tris[12], poly[4];
864 for (int i = 0; i < 4; ++i) {
865 quads.clear();
866 rval = mb.get_adjacencies( &hexes[i], 1, 2, true, quads );
867 CHECK_ERR(rval);
868 CHECK_EQUAL( 6, (int)quads.size() );
869
870 for (int j = 0; j < 6; ++j) {
871 rval = mb.tag_get_data( tri_tag, &quads[j], 1, tris + 2*j );
872 if (MB_SUCCESS == rval)
873 continue;
874 CHECK_EQUAL( MB_TAG_NOT_FOUND, rval );
875 const EntityHandle* conn;
876 int len;
877 rval = mb.get_connectivity( quads[j], conn, len );
878 CHECK_ERR(rval);
879 CHECK_EQUAL( 4, len );
880 EntityHandle tri_conn[2][3] = { { conn[0], conn[1], conn[2] },
881 { conn[2], conn[3], conn[0] } };
882 rval = mb.create_element( MBTRI, tri_conn[0], 3, tris[2*j ] ); CHECK_ERR(rval);
883 rval = mb.create_element( MBTRI, tri_conn[1], 3, tris[2*j+1] ); CHECK_ERR(rval);
884 rval = mb.tag_set_data( tri_tag, &quads[j], 1, tris + 2*j ); CHECK_ERR(rval);
885 }
886
887 rval = mb.create_element( MBPOLYHEDRON, tris, 12, poly[i] );
888 CHECK_ERR(rval);
889 }
890
891 Range all_tri;
892 rval = mb.get_entities_by_type( 0, MBTRI, all_tri );
893 CHECK_ERR(rval);
894 CHECK_EQUAL( 40, (int)all_tri.size() );
895
896 rval = mb.delete_entities( hexes, 4 ); CHECK_ERR(rval);
897 rval = mb.delete_entities( &quads[0], quads.size() ); CHECK_ERR(rval);
898
899 EntityHandle sets[2];
900 rval = mb.create_meshset( 0, sets[0] ); CHECK_ERR(rval);
901 rval = mb.add_entities( sets[0], poly, 2 ); CHECK_ERR(rval);
902 rval = mb.create_meshset( 0, sets[1] ); CHECK_ERR(rval);
903 rval = mb.add_entities( sets[1], poly+2, 2 ); CHECK_ERR(rval);
904
905 Tag id_tag;
906 rval = mb.tag_get_handle( ID_TAG_NAME, 1, MB_TYPE_INTEGER, id_tag, MB_TAG_SPARSE|MB_TAG_EXCL );
907 CHECK_ERR(rval);
908 int ids[2] = { 2, 3 };
909 rval = mb.tag_set_data( id_tag, sets, 2, ids ); CHECK_ERR(rval);
910
911 rval = mb.write_file( TEST_FILE, "MOAB" );
912 CHECK_ERR(rval);
913 rval = mb.delete_mesh();
914 CHECK_ERR(rval);
915
916 rval = mb.load_file( TEST_FILE, 0, READ_OPTS, ID_TAG_NAME, ids, 1 );
917 CHECK_ERR(rval);
918
919 Range rpoly;
920 rval = mb.get_entities_by_type( 0, MBPOLYHEDRON, rpoly );
921 CHECK_ERR(rval);
922 CHECK_EQUAL( 2, (int)rpoly.size() );
923
924 Range polyverts;
925 rval = mb.get_adjacencies( rpoly, 0, false, polyverts, Interface::UNION );
926 CHECK_ERR(rval);
927 CHECK_EQUAL( 12, (int)polyverts.size() );
928
929 for (Range::iterator it = polyverts.begin(); it != polyverts.end(); ++it) {
930 double coords2[3];
931 rval = mb.get_coords( &*it, 1, coords2 );
932 CHECK_ERR(rval);
933 CHECK( coords2[0] > -1e-12 && coords2[0]-2 < 1e-12 );
934 CHECK( coords2[1] > -1e-12 && coords2[1]-1 < 1e-12 );
935 CHECK( coords2[2] > -1e-12 && coords2[2]-1 < 1e-12 );
936 }
937 }
938
939 //! Read in the sets contained in a set.
940 //! Should read all sets containing read elements or nodes
941 //! and all sets that are contained the the specified "read"
942 //! set. Test the later here.
test_read_set_sets()943 void test_read_set_sets()
944 {
945 ErrorCode rval;
946 Core instance;
947 Interface& mb = instance;
948
949 Tag id_tag;
950 rval = mb.tag_get_handle( ID_TAG_NAME, 1, MB_TYPE_INTEGER, id_tag, MB_TAG_SPARSE|MB_TAG_EXCL );
951 CHECK_ERR(rval);
952
953 // create sets and assign an ID to each
954 const int len = 5;
955 EntityHandle set[2*len+2];
956 for (int i = 0; i < 2*len+2; ++i) {
957 rval = mb.create_meshset( MESHSET_SET, set[i] );
958 CHECK_ERR(rval);
959 int id = i + 1;
960 rval = mb.tag_set_data( id_tag, set + i, 1, &id );
961 CHECK_ERR(rval);
962 }
963
964 // make set containment as follows (values are assigned IDs):
965 int cont_ids[2][len] = { { 3, 4, 5, 9, 10 }, { 6, 7, 8, 11, 12 } };
966 for (int i = 0; i < 2; ++i) {
967 EntityHandle contents[len] = { set[cont_ids[i][0] - 1],
968 set[cont_ids[i][1] - 1],
969 set[cont_ids[i][2] - 1],
970 set[cont_ids[i][3] - 1],
971 set[cont_ids[i][4] - 1] };
972 rval = mb.add_entities( set[i], contents, len );
973 CHECK_ERR(rval);
974 }
975
976 rval = mb.write_file( TEST_FILE, "MOAB" );
977 CHECK_ERR(rval);
978
979 for (int i = 0; i < 2; ++i) {
980 rval = mb.delete_mesh();
981 CHECK_ERR(rval);
982
983 EntityHandle file;
984 rval = mb.create_meshset( MESHSET_SET, file );
985 CHECK_ERR(rval);
986 int id = i+1;
987 rval = mb.load_file( TEST_FILE, &file, READ_OPTS ";SETS=NONE", ID_TAG_NAME, &id, 1 );
988 CHECK_ERR(rval);
989
990 // check that the total number of sets read is as expected
991 Range sets;
992 rval = mb.get_entities_by_type( 0, MBENTITYSET, sets );
993 CHECK_ERR(rval);
994 Range::iterator it = sets.find( file );
995 if (it != sets.end())
996 sets.erase( it );
997 CHECK_EQUAL( len+1, (int)sets.size() );
998
999 // check that we read in the set specified by ID to the reader
1000 rval = mb.tag_get_handle( ID_TAG_NAME, 1, MB_TYPE_INTEGER, id_tag );
1001 CHECK_ERR(rval);
1002 sets.clear();
1003 const void* data[] = { &id };
1004 rval = mb.get_entities_by_type_and_tag( 0, MBENTITYSET, &id_tag, data, 1, sets );
1005 CHECK_ERR(rval);
1006 CHECK_EQUAL( 1, (int)sets.size() );
1007
1008 // check that it contains the expected sets
1009 EntityHandle owner = sets.front();
1010 sets.clear();
1011 rval = mb.get_entities_by_type( owner, MBENTITYSET, sets );
1012 CHECK_ERR(rval);
1013 CHECK_EQUAL( len, (int)sets.size() );
1014
1015 std::vector<int> expected( cont_ids[i], cont_ids[i] + len );
1016 std::vector<int> actual( len );
1017 rval = mb.tag_get_data( id_tag, sets, &actual[0] );
1018 CHECK_ERR(rval);
1019 std::sort( expected.begin(), expected.end() );
1020 std::sort( actual.begin(), actual.end() );
1021 CHECK( expected == actual );
1022 }
1023 }
1024
check_children(bool contents,GatherTestMode mode,Interface & mb,int id,Tag id_tag,EntityHandle file)1025 static void check_children( bool contents, GatherTestMode mode, Interface& mb, int id, Tag id_tag, EntityHandle file )
1026 {
1027 // Increase number of expected sets by one if contents is true because
1028 // we always read immediately contained (depth 1) sets.
1029 const int exp_num_sets = (mode == GATHER_NONE) ? 1+contents : id;
1030 const int exp_num_edges = (mode == GATHER_CONTENTS) ? id : 1;
1031
1032 ErrorCode rval;
1033 Range range;
1034 rval = mb.get_entities_by_type( 0, MBEDGE , range );
1035 CHECK_ERR(rval);
1036 CHECK_EQUAL( exp_num_edges, (int)range.size() );
1037 range.clear();
1038 rval = mb.get_entities_by_type( 0, MBENTITYSET , range );
1039 CHECK_ERR(rval);
1040 Range::iterator it = range.find( file );
1041 CHECK( it != range.end() );
1042 range.erase( it );
1043 CHECK_EQUAL( exp_num_sets, (int)range.size() );
1044
1045 EntityHandle set;
1046 const void* val[] = {&id};
1047 range.clear();
1048 rval = mb.get_entities_by_type_and_tag( 0, MBENTITYSET, &id_tag, val, 1, range );
1049 CHECK_ERR(rval);
1050 CHECK_EQUAL( 1, (int)range.size() );
1051 set = range.front();
1052
1053 if (mode == GATHER_NONE) {
1054 range.clear();
1055 rval = mb.get_entities_by_type( set, MBEDGE , range );
1056 CHECK_ERR(rval);
1057 CHECK_EQUAL( 1, (int)range.size() );
1058 return;
1059 }
1060
1061 for (int i = id; i > 0; --i) {
1062 int act_id;
1063 rval = mb.tag_get_data( id_tag, &set, 1, &act_id );
1064 CHECK_ERR(rval);
1065 CHECK_EQUAL( i, act_id );
1066
1067 range.clear();
1068 rval = mb.get_entities_by_type( set, MBEDGE, range );
1069 CHECK_ERR(rval);
1070 if (mode == GATHER_CONTENTS || i == id) {
1071 CHECK_EQUAL( 1, (int)range.size() );
1072 const EntityHandle* conn;
1073 int len;
1074 rval = mb.get_connectivity( range.front(), conn, len );
1075 CHECK_ERR(rval);
1076 CHECK_EQUAL( 2, len );
1077 double coords[3];
1078 rval = mb.get_coords( conn + 1, 1, coords );
1079 CHECK_ERR(rval);
1080 CHECK_EQUAL( i, (int)coords[0] );
1081 }
1082 else {
1083 CHECK( range.empty() );
1084 }
1085
1086 std::vector<EntityHandle> children;
1087 if (contents)
1088 rval = mb.get_entities_by_type( set, MBENTITYSET, children );
1089 else
1090 rval = mb.get_child_meshsets( set, children );
1091 CHECK_ERR(rval);
1092 if (i == 1) {
1093 CHECK( children.empty() );
1094 }
1095 else {
1096 CHECK_EQUAL( 1, (int)children.size() );
1097 set = children[0];
1098 }
1099 }
1100 }
1101
1102
1103 const char* set_read_opts[] = { "SETS", "CONTENTS", "NONE" };
test_gather_sets_common(bool contents,GatherTestMode mode,bool no_parent_containing_sets)1104 void test_gather_sets_common( bool contents, GatherTestMode mode, bool no_parent_containing_sets )
1105 {
1106 ErrorCode rval;
1107 Core instance;
1108 Interface& mb = instance;
1109
1110 Tag id_tag;
1111 rval = mb.tag_get_handle( ID_TAG_NAME, 1, MB_TYPE_INTEGER, id_tag, MB_TAG_SPARSE|MB_TAG_EXCL );
1112 CHECK_ERR(rval);
1113
1114 // Create a string of edges from [0,INT] along the X axis each 1 unit in length.
1115 // Create a set for edge edge containing the edge and make it the parent of the
1116 // set containing the previous (closer to origin) edge. Assign each set an
1117 // ID that is the X coordinate of the larger of the two vertices of the edge
1118 // contained in the set.
1119 const int INT = 64;
1120 EntityHandle verts[INT+1], edges[INT], sets[INT];
1121 double coords[] = { 0, 0, 0 };
1122 rval = mb.create_vertex( coords, verts[0] );
1123 CHECK_ERR(rval);
1124 for (int i = 0; i < INT; ++i) {
1125 const int id = i + 1;
1126 coords[0] = id;
1127 rval = mb.create_vertex( coords, verts[id] );
1128 CHECK_ERR(rval);
1129 rval = mb.create_element( MBEDGE, verts + i, 2, edges[i] );
1130 CHECK_ERR(rval);
1131 rval = mb.create_meshset( MESHSET_SET, sets[i] );
1132 CHECK_ERR(rval);
1133 rval = mb.add_entities( sets[i], edges + i, 1 );
1134 CHECK_ERR(rval);
1135 rval = mb.tag_set_data( id_tag, sets + i, 1, &id );
1136 CHECK_ERR(rval);
1137 if (i > 0) {
1138 if (contents)
1139 rval = mb.add_entities( sets[i], sets + (i-1), 1 );
1140 else
1141 rval = mb.add_child_meshset( sets[i], sets[i-1] );
1142 CHECK_ERR(rval);
1143 }
1144 }
1145
1146 // Write the data
1147 rval = mb.write_file( TEST_FILE, "MOAB" );
1148 CHECK_ERR(rval);
1149
1150 EntityHandle file;
1151 std::string opt( READ_OPTS );
1152 if (contents)
1153 opt += ";CHILDREN=NONE;SETS=";
1154 else
1155 opt += ";SETS=NONE;CHILDREN=";
1156 opt += set_read_opts[mode];
1157
1158 if (no_parent_containing_sets) opt += ";NO_SET_CONTAINING_PARENTS";
1159
1160 const int test_ids[] = { 2, 7, INT/3-1, INT/2+1, INT-3 };
1161 const int num_test_ids = sizeof(test_ids)/sizeof(int);
1162 for (int i = 0; i < num_test_ids; ++i) {
1163 CHECK (test_ids[i] <= INT);
1164
1165 rval = mb.delete_mesh();
1166 CHECK_ERR(rval);
1167
1168 rval = mb.create_meshset( MESHSET_SET, file );
1169 CHECK_ERR(rval);
1170
1171 rval = mb.load_file( TEST_FILE, 0, opt.c_str(), ID_TAG_NAME, test_ids+i, 1 );
1172 CHECK_ERR(rval);
1173 rval = mb.tag_get_handle( ID_TAG_NAME, 1, MB_TYPE_INTEGER, id_tag );
1174 CHECK_ERR(rval);
1175
1176 check_children( contents, mode, mb, test_ids[i], id_tag, file );
1177 }
1178 }
1179
1180
test_gather_sets_ranged(bool contents,GatherTestMode mode,bool no_parent_containing_sets)1181 void test_gather_sets_ranged( bool contents, GatherTestMode mode, bool no_parent_containing_sets )
1182 {
1183 ErrorCode rval;
1184 Core instance;
1185 Interface& mb = instance;
1186
1187 Range verts;
1188 Tag id_tag;
1189 rval = mb.tag_get_handle( ID_TAG_NAME, 1, MB_TYPE_INTEGER, id_tag, MB_TAG_SPARSE|MB_TAG_EXCL );
1190 CHECK_ERR(rval);
1191
1192 // create four groups of vertices, where all vertices in the same group
1193 // have the same x-coordinate
1194 const int NUM_GRP_VTX = 20;
1195 const int NUM_GRP = 4;
1196 EntityHandle sets[NUM_GRP];
1197 for (int i = 0; i < NUM_GRP; ++i) {
1198 double coords[3*NUM_GRP_VTX];
1199 for (int j = 0; j < NUM_GRP_VTX; ++j) {
1200 coords[3*j ] = i;
1201 coords[3*j+1] = j;
1202 coords[3*j+2] = 0;
1203 }
1204 rval = mb.create_vertices( coords, NUM_GRP_VTX, verts );
1205 CHECK_ERR(rval);
1206
1207 rval = mb.create_meshset( MESHSET_SET, sets[i] );
1208 CHECK_ERR(rval);
1209 rval = mb.add_entities( sets[i], verts );
1210 CHECK_ERR(rval);
1211 int id = i + 1;
1212 rval = mb.tag_set_data( id_tag, sets+i, 1, &id );
1213 CHECK_ERR(rval);
1214 }
1215
1216 // place two of the sets inside the others
1217 if (contents) {
1218 rval = mb.add_entities( sets[0], &sets[1], 1 ); CHECK_ERR(rval);
1219 rval = mb.add_entities( sets[2], &sets[3], 1 ); CHECK_ERR(rval);
1220 }
1221 else {
1222 rval = mb.add_child_meshset( sets[0], sets[1] ); CHECK_ERR(rval);
1223 rval = mb.add_child_meshset( sets[2], sets[3] ); CHECK_ERR(rval);
1224 }
1225
1226 // Write the data
1227 rval = mb.write_file( TEST_FILE, "MOAB" );
1228 CHECK_ERR(rval);
1229
1230 // Read the data
1231 std::string opt( READ_OPTS );
1232 if (contents)
1233 opt += ";CHILDREN=NONE;SETS=";
1234 else
1235 opt += ";SETS=NONE;CHILDREN=";
1236 opt += set_read_opts[mode];
1237
1238 if (no_parent_containing_sets) opt += ";NO_PARENT_CONTAINING_SETS";
1239
1240 EntityHandle file;
1241 const int read_id = 3;
1242 rval = mb.delete_mesh(); CHECK_ERR(rval);
1243 rval = mb.create_meshset( MESHSET_SET, file ); CHECK_ERR(rval);
1244 rval = mb.load_file( TEST_FILE, &file, opt.c_str(), ID_TAG_NAME, &read_id, 1 );
1245 CHECK_ERR(rval);
1246
1247 // get any sets that were read it
1248 Range read_sets;
1249 rval = mb.get_entities_by_type( file, MBENTITYSET, read_sets );
1250 CHECK_ERR(rval);
1251
1252 // count number of vertices in each group
1253 int counts[NUM_GRP];
1254 memset( counts, 0, sizeof(counts) );
1255 verts.clear();
1256 rval = mb.get_entities_by_type( 0, MBVERTEX, verts );
1257 CHECK_ERR(rval);
1258 for (Range::iterator it = verts.begin(); it != verts.end(); ++it) {
1259 double coords[3];
1260 rval = mb.get_coords( &*it, 1, coords );
1261 CHECK_ERR(rval);
1262 int i = (int)(coords[0]+1e-12);
1263 CHECK( i >= 0 && i < NUM_GRP );
1264 counts[i]++;
1265 }
1266
1267 // check expected counts
1268 CHECK_EQUAL( 0, counts[0] );
1269 CHECK_EQUAL( 0, counts[1] );
1270 CHECK_EQUAL( NUM_GRP_VTX, counts[2] );
1271 switch (mode) {
1272 case GATHER_NONE:
1273 CHECK_EQUAL( 0, counts[3] );
1274 CHECK_EQUAL( 1+contents, (int)read_sets.size() );
1275 break;
1276 case GATHER_SETS:
1277 CHECK_EQUAL( 0, counts[3] );
1278 CHECK_EQUAL( 2, (int)read_sets.size() );
1279 break;
1280 case GATHER_CONTENTS:
1281 CHECK_EQUAL( NUM_GRP_VTX, counts[3] );
1282 CHECK_EQUAL( 2, (int)read_sets.size() );
1283 break;
1284 }
1285 }
1286
check_num_verts(Interface & mb,Tag tag,int id,int num_vtx)1287 static void check_num_verts( Interface& mb, Tag tag, int id, int num_vtx )
1288 {
1289 ErrorCode rval;
1290 const void* val[] = {&id};
1291 Range range;
1292 rval = mb.get_entities_by_type_and_tag( 0, MBENTITYSET, &tag, val, 1, range );
1293 CHECK_ERR(rval);
1294 CHECK_EQUAL( 1, (int)range.size() );
1295
1296 EntityHandle set = range.front();
1297 range.clear();
1298 rval = mb.get_entities_by_type( set, MBVERTEX, range );
1299 CHECK_ERR(rval);
1300 CHECK_EQUAL( num_vtx, (int)range.size() );
1301 }
1302
1303
1304 //! Read in the sets contained in a set.
1305 //! Should read all sets containing read elements or nodes
1306 //! and all sets that are contained the the specified "read"
1307 //! set. Test the former here.
test_read_containing_sets()1308 void test_read_containing_sets()
1309 {
1310 // create mesh decomposed by elements but create
1311 // sets containing all vertices of decomposed elements
1312 // such that adjacent sets share vertices.
1313 create_mesh( false, true, false, false );
1314
1315 ErrorCode rval;
1316 Core instance;
1317 Interface& mb = instance;
1318
1319 // read some sets
1320 const int ids[] = { 1, 5, 9 };
1321 const int num_sets = sizeof(ids)/sizeof(int);
1322 rval = mb.load_file( TEST_FILE, 0, READ_OPTS, ID_TAG_NAME, ids, num_sets );
1323 CHECK_ERR(rval);
1324
1325 Tag id_tag;
1326 rval = mb.tag_get_handle( ID_TAG_NAME, 1, MB_TYPE_INTEGER, id_tag );
1327 CHECK_ERR(rval);
1328
1329 // expect all sets adjacent to the specified sets because
1330 // they share vertices.
1331 Range verts;
1332 for (int i = 0; i < num_sets; ++i) {
1333 if (ids[i] > 1)
1334 check_num_verts( mb, id_tag, ids[i]-1, MBQUAD_INT+1 );
1335 check_num_verts( mb, id_tag, ids[i], (MBQUAD_INT+1)*(SET_WIDTH+1) );
1336 if (ids[i] < NUM_SETS)
1337 check_num_verts( mb, id_tag, ids[i]+1, MBQUAD_INT+1 );
1338 }
1339 }
1340
1341 //! Test reading of explicit adjacencies
test_read_adjacencies()1342 void test_read_adjacencies()
1343 {
1344 ErrorCode rval;
1345 Core instance;
1346 Interface& mb = instance;
1347
1348 // create four hexes sharing an edge
1349 EntityHandle verts[3][3][2], hexes[2][2];
1350 for (int k = 0; k < 2; ++k) {
1351 for (int j = 0; j < 3; ++j) {
1352 for (int i = 0; i < 3; ++i) {
1353 double coords[] = { static_cast<double>(i), static_cast<double>(j), static_cast<double>(k) };
1354 rval = mb.create_vertex( coords, verts[i][j][k] );
1355 CHECK_ERR(rval);
1356 }
1357 }
1358 }
1359 for (int j = 0; j < 2; ++j) {
1360 for (int i = 0; i < 2; ++i) {
1361 EntityHandle conn[] = { verts[i ][j ][0],
1362 verts[i+1][j ][0],
1363 verts[i+1][j+1][0],
1364 verts[i ][j+1][0],
1365 verts[i ][j ][1],
1366 verts[i+1][j ][1],
1367 verts[i+1][j+1][1],
1368 verts[i ][j+1][1] };
1369 rval = mb.create_element( MBHEX, conn, 8, hexes[i][j] );
1370 CHECK_ERR(rval);
1371 }
1372 }
1373
1374 // create two duplicate edges that connect the vertices common to all four hexes
1375 EntityHandle edge_conn[2] = { verts[1][1][0], verts[1][1][1] };
1376 EntityHandle edges[2];
1377 rval = mb.create_element( MBEDGE, edge_conn, 2, edges[0] ); CHECK_ERR(rval);
1378 rval = mb.create_element( MBEDGE, edge_conn, 2, edges[1] ); CHECK_ERR(rval);
1379 // mark one edge as adjacent to the left two hexes and the
1380 // other as adjacent to the right two
1381 rval = mb.add_adjacencies( edges[0], hexes[0], 2, true ); CHECK_ERR(rval);
1382 rval = mb.add_adjacencies( edges[1], hexes[1], 2, true ); CHECK_ERR(rval);
1383 // create two sets containing the front two and the rear two
1384 // hexes, respectively.
1385 EntityHandle sets[2];
1386 rval = mb.create_meshset( MESHSET_SET, sets[0] ); CHECK_ERR(rval);
1387 rval = mb.create_meshset( MESHSET_SET, sets[1] ); CHECK_ERR(rval);
1388 EntityHandle set1[4] = { hexes[0][0], hexes[1][0], edges[0], edges[1] };
1389 EntityHandle set2[4] = { hexes[0][1], hexes[1][1], edges[0], edges[1] };
1390 rval = mb.add_entities( sets[0], set1, 4 ); CHECK_ERR(rval);
1391 rval = mb.add_entities( sets[1], set2, 4 ); CHECK_ERR(rval);
1392
1393 // assign IDs to sets
1394 Tag id_tag;
1395 rval = mb.tag_get_handle( ID_TAG_NAME, 1, MB_TYPE_INTEGER, id_tag, MB_TAG_SPARSE|MB_TAG_EXCL );
1396 CHECK_ERR(rval);
1397 int ids[2] = { 1, 2 };
1398 rval = mb.tag_set_data( id_tag, sets, 2, ids );
1399 CHECK_ERR(rval);
1400
1401 // write mesh
1402 rval = mb.write_file( TEST_FILE, "MOAB" );
1403 CHECK_ERR(rval);
1404
1405 // read mesh
1406 rval = mb.delete_mesh(); CHECK_ERR(rval);
1407 rval = mb.load_file( TEST_FILE, 0, READ_OPTS, ID_TAG_NAME, ids, 1 );
1408 CHECK_ERR(rval);
1409
1410 // expect two hexes and two edges
1411 Range range;
1412 rval = mb.get_entities_by_type( 0, MBHEX, range );
1413 CHECK_ERR(rval);
1414 CHECK_EQUAL( 2, (int)range.size() );
1415 EntityHandle h1 = range.front(), h2 = range.back();
1416 range.clear();
1417 rval = mb.get_entities_by_type( 0, MBEDGE, range );
1418 CHECK_ERR(rval);
1419 CHECK_EQUAL( 2, (int)range.size() );
1420
1421 // expecte each edge to have one of the hexes
1422 range.clear();
1423 rval = mb.get_adjacencies( &h1, 1, 1, false, range );
1424 CHECK_ERR(rval);
1425 CHECK_EQUAL( 1, (int)range.size() );
1426 EntityHandle e1 = range.front();
1427 range.clear();
1428 rval = mb.get_adjacencies( &h2, 1, 1, false, range );
1429 CHECK_ERR(rval);
1430 CHECK_EQUAL( 1, (int)range.size() );
1431 EntityHandle e2 = range.front();
1432
1433 CHECK( e1 != e2 );
1434 }
1435
1436
test_read_sides()1437 void test_read_sides()
1438 {
1439 ErrorCode rval;
1440 Core instance;
1441 Interface& mb = instance;
1442
1443 // create 4x4 grid of quads with edges
1444 const int INT = 4;
1445 EntityHandle verts[INT+1][INT+1];
1446 for (int j = 0; j <= INT; ++j) {
1447 for (int i = 0; i <= INT; ++i) {
1448 double coords[3] = { static_cast<double>(i), static_cast<double>(j), 0 };
1449 rval = mb.create_vertex( coords, verts[INT-j][i] );
1450 CHECK_ERR(rval);
1451 }
1452 }
1453 EntityHandle quads[INT][INT];
1454 for (int j = 0; j < INT; ++j) {
1455 for (int i = 0; i < INT; ++i) {
1456 EntityHandle conn[4] = { verts[INT-j][i],
1457 verts[INT-j][i+1],
1458 verts[INT-j-1][i+1],
1459 verts[INT-j-1][i] };
1460 rval = mb.create_element( MBQUAD, conn, 4, quads[INT-j-1][i] );
1461 CHECK_ERR(rval);
1462 }
1463 }
1464 Range edges;
1465 rval = mb.get_adjacencies( &quads[0][0], INT*INT, 1, true, edges, Interface::UNION );
1466 CHECK_ERR(rval);
1467 CHECK_EQUAL( 40, (int)edges.size() );
1468
1469 // group quads into two sets
1470 EntityHandle sets[2];
1471 rval = mb.create_meshset( MESHSET_SET, sets[0] ); CHECK_ERR(rval);
1472 rval = mb.create_meshset( MESHSET_SET, sets[1] ); CHECK_ERR(rval);
1473 rval = mb.add_entities( sets[0], quads[0], INT ); CHECK_ERR(rval);
1474 rval = mb.add_entities( sets[1], quads[1], INT ); CHECK_ERR(rval);
1475 rval = mb.add_entities( sets[0], quads[2], INT ); CHECK_ERR(rval);
1476 rval = mb.add_entities( sets[1], quads[3], INT ); CHECK_ERR(rval);
1477
1478 // assign IDS
1479 Tag id_tag;
1480 rval = mb.tag_get_handle( ID_TAG_NAME, 1, MB_TYPE_INTEGER, id_tag, MB_TAG_SPARSE|MB_TAG_EXCL );
1481 CHECK_ERR(rval);
1482 int ids[2] = { 4, 5 };
1483 rval = mb.tag_set_data( id_tag, sets, 2, ids );
1484 CHECK_ERR(rval);
1485
1486 // write mesh
1487 rval = mb.write_file( TEST_FILE, "MOAB" );
1488 CHECK_ERR(rval);
1489
1490 // read first set back in
1491 rval = mb.delete_mesh(); CHECK_ERR(rval);
1492 rval = mb.load_file( TEST_FILE, 0, READ_OPTS, ID_TAG_NAME, ids, 1 );
1493 CHECK_ERR(rval);
1494
1495 // check expected counts
1496 int count;
1497 rval = mb.get_number_entities_by_type( 0, MBVERTEX, count );
1498 CHECK_ERR(rval);
1499 CHECK_EQUAL( (INT+1)*INT, count );
1500 rval = mb.get_number_entities_by_type( 0, MBQUAD, count );
1501 CHECK_ERR(rval);
1502 CHECK_EQUAL( INT*INT/2, count );
1503 rval = mb.get_number_entities_by_type( 0, MBEDGE, count );
1504 CHECK_ERR(rval);
1505 CHECK_EQUAL( 2*(INT+1) + INT*INT, count );
1506
1507 // check edges adjacent to each quad
1508 Range elems;
1509 rval = mb.get_entities_by_type( 0, MBQUAD, elems );
1510 CHECK_ERR(rval);
1511 for (Range::iterator it = elems.begin(); it != elems.end(); ++it) {
1512 edges.clear();
1513 rval = mb.get_adjacencies( &*it, 1, 1, false, edges );
1514 CHECK_ERR(rval);
1515 CHECK_EQUAL( 4, (int)edges.size() );
1516 }
1517 }
1518
1519 const int expected_ids[] = { 2, 4, 6, 8, 10, 12, 14, 16, 18 };
1520 const int expected_vols[] = { 3, 7, 10 };
1521
write_id_test_file()1522 void write_id_test_file()
1523 {
1524 Core moab;
1525 Interface& mb = moab;
1526 ErrorCode rval;
1527
1528 // create 12 entity sets
1529 EntityHandle sets[12];
1530 for (int i = 0; i < 12; ++i) {
1531 rval = mb.create_meshset( MESHSET_SET, sets[i] );
1532 CHECK_ERR(rval);
1533 }
1534
1535 // create tag handles
1536 Tag id = 0, gid = 0, dim = 0;
1537 mb.tag_get_handle( ID_TAG_NAME, 1, MB_TYPE_INTEGER, id, MB_TAG_SPARSE|MB_TAG_EXCL );
1538 mb.tag_get_handle( GEOM_DIMENSION_TAG_NAME, 1, MB_TYPE_INTEGER, dim, MB_TAG_SPARSE|MB_TAG_EXCL );
1539 mb.tag_get_handle( GLOBAL_ID_TAG_NAME, 1, MB_TYPE_INTEGER, gid, MB_TAG_DENSE|MB_TAG_EXCL );
1540
1541 // set ID tag on first 10 sets
1542 rval = mb.tag_set_data( id, sets, sizeof(expected_ids)/sizeof(int), expected_ids );
1543 CHECK_ERR(rval);
1544 // set geom dim on all sets, only three of them have dim == 3
1545 int num_vol = sizeof(expected_vols)/sizeof(int);
1546 int dims[12], ids[12];
1547 int v = 0;
1548 for (int i = 0; i < 12; ++i) {
1549 dims[i] = i % 3 + 1;
1550 if (dims[i] == 3) {
1551 if (v < num_vol)
1552 ids[i] = expected_vols[v++];
1553 else
1554 ids[i] = expected_vols[0];
1555 }
1556 else
1557 ids[i] = 100;
1558 }
1559 rval = mb.tag_set_data( gid, sets, 12, ids );
1560 CHECK_ERR(rval);
1561 rval = mb.tag_set_data( dim, sets, 12, dims );
1562 CHECK_ERR(rval);
1563
1564 rval = mb.write_file( TEST_FILE, "MOAB" );
1565 CHECK_ERR(rval);
1566 }
1567
test_read_ids()1568 void test_read_ids()
1569 {
1570 write_id_test_file();
1571
1572 Core moab;
1573 ReadHDF5 reader(&moab);
1574 FileOptions opts("");
1575 ErrorCode rval;
1576 std::vector<int> values;
1577 rval = reader.read_tag_values( TEST_FILE, ID_TAG_NAME, opts, values );
1578 remove( TEST_FILE );
1579 CHECK_ERR(rval);
1580
1581 std::sort( values.begin(), values.end() );
1582 std::vector<int> expected( expected_ids, expected_ids+sizeof(expected_ids)/sizeof(int) );
1583 CHECK_EQUAL( expected, values );
1584 }
1585
test_read_partial_ids()1586 void test_read_partial_ids()
1587 {
1588 write_id_test_file();
1589
1590 const int three = 3;
1591 ReaderIface::IDTag vols = { GEOM_DIMENSION_TAG_NAME, &three, 1 };
1592 ReaderIface::SubsetList subset = { &vols, 1, 0, 0 };
1593
1594 Core moab;
1595 ReadHDF5 reader(&moab);
1596 FileOptions opts("");
1597 ErrorCode rval;
1598 std::vector<int> values;
1599 rval = reader.read_tag_values( TEST_FILE, GLOBAL_ID_TAG_NAME, opts, values, &subset );
1600 remove( TEST_FILE );
1601 CHECK_ERR(rval);
1602
1603 std::sort( values.begin(), values.end() );
1604 std::vector<int> expected( expected_ids, expected_ids+sizeof(expected_ids)/sizeof(int) );
1605 }
1606