1 #include "TestUtil.hpp"
2 #include "moab/Core.hpp"
3 #include "MBTagConventions.hpp"
4 #include "moab/CN.hpp"
5 #include "moab/Range.hpp"
6 #include "ReadNCDF.hpp"
7 #include "moab/FileOptions.hpp"
8 #define IS_BUILDING_MB
9 #include "ExoIIUtil.hpp"
10 #include <math.h>
11 #include <algorithm>
12
13 using namespace moab;
14
15 /* Input test file: ho_test.g
16 *
17 * File is expected to contain at least one block for every
18 * supported higher-order element type. The coordinates of
19 * every higher-order node are expected to be the mean of the
20 * adjacent corner vertices of the element.
21 */
22 #ifdef MESHDIR
23 static const char ho_file[] = STRINGIFY(MESHDIR) "/io/ho_test.g";
24 static const char file_one[] = STRINGIFY(MESHDIR) "/mbtest1.g";
25 static const char alt_file[] = STRINGIFY(MESHDIR) "/io/hex_2x2x2_ss.exo";
26 static const char polyg[] = STRINGIFY(MESHDIR) "/io/poly8-10.vtk";
27 static const char polyh[] = STRINGIFY(MESHDIR) "/io/polyhedra.vtk";
28 static const char rpolyg[] = STRINGIFY(MESHDIR)"/io/polyg.exo";
29 static const char rpolyh[] = STRINGIFY(MESHDIR) "/io/polyh.exo";
30 #else
31 static const char ho_file[] = "ho_test.g";
32 static const char file_one[] = "mbtest1.g";
33 static const char alt_file[] = "hex_2x2x2_ss.exo";
34 static const char polyg[] = "poly8-10.vtk";
35 static const char polyh[] = "polyhedra.vtk";
36 static const char rpolyg[] = "polyg.exo";
37 static const char rpolyh[] = "polyh.exo";
38 #endif
39
40 void read_file( Interface& moab,
41 const char* input_file );
42
43 // Check that element has expected higher-order nodes
44 // and that each higher-order node is at the center
45 // of the sub-entity it is on.
46 void check_ho_element( Interface& moab,
47 EntityHandle entity,
48 int mid_nodes[4] );
49
50 void test_read_side( int sideset_id,
51 EntityType sideset_type,
52 int sideset_nodes_per_elem,
53 bool shell_side = false );
54
55 // Validate elements of specified type.
56 // Looks for a block containing the specified entity type
57 // and with the specified mid-node flags set in its
58 // HAS_MID_NODES_TAG.
59 void test_ho_elements( EntityType type, int num_nodes );
60
61 // Tests originally in MBTest.cpp
62 void mb_vertex_coordinate_test();
63 void mb_bar_connectivity_test();
64 void mb_tri_connectivity_test();
65 void mb_quad_connectivity_test();
66 void mb_hex_connectivity_test();
67 void mb_tet_connectivity_test();
68 void mb_write_mesh_test();
69
70 void test_types();
71
test_tri6()72 void test_tri6 () { test_ho_elements(MBTRI, 6); }
test_tri7()73 void test_tri7 () { test_ho_elements(MBTRI, 7); }
74
test_quad5()75 void test_quad5() { test_ho_elements(MBQUAD, 5); }
test_quad8()76 void test_quad8() { test_ho_elements(MBQUAD, 8); }
test_quad9()77 void test_quad9() { test_ho_elements(MBQUAD, 9); }
78
test_tet8()79 void test_tet8 () { test_ho_elements(MBTET, 8); }
test_tet10()80 void test_tet10() { test_ho_elements(MBTET, 10); }
test_tet14()81 void test_tet14() { test_ho_elements(MBTET, 14); }
82
test_hex9()83 void test_hex9 () { test_ho_elements(MBHEX, 9); }
test_hex20()84 void test_hex20() { test_ho_elements(MBHEX, 20); }
test_hex27()85 void test_hex27() { test_ho_elements(MBHEX, 27); }
86
test_read_tri6_side()87 void test_read_tri6_side() { test_read_side( 1, MBEDGE, 3 ); } // sideset 1
test_read_shell_side()88 void test_read_shell_side() { test_read_side( 3, MBQUAD, 9, true ); } // sideset 3
test_read_shell_edge()89 void test_read_shell_edge() { test_read_side( 4, MBEDGE, 3 ); } // sideset 4
test_read_hex20_side()90 void test_read_hex20_side() { test_read_side( 2, MBQUAD, 8 ); } // sideset 2
91
92 void test_read_block_ids();
93 void test_read_sideset_ids();
94 void test_read_nodeset_ids();
95 void test_write_polygons();
96 void test_write_polyhedra();
97 void test_read_polygons();
98 void test_read_polyhedra();
99
100 void test_read_alternate_coord_format();
101
main()102 int main()
103 {
104 int result = 0;
105
106 result += RUN_TEST(mb_vertex_coordinate_test);
107 result += RUN_TEST(mb_bar_connectivity_test);
108 result += RUN_TEST(mb_tri_connectivity_test);
109 result += RUN_TEST(mb_quad_connectivity_test);
110 result += RUN_TEST(mb_hex_connectivity_test);
111 result += RUN_TEST(mb_tet_connectivity_test);
112 result += RUN_TEST(mb_write_mesh_test);
113
114 result += RUN_TEST(test_types);
115
116 result += RUN_TEST(test_tri6 );
117 result += RUN_TEST(test_tri7 );
118 result += RUN_TEST(test_quad5);
119 result += RUN_TEST(test_quad8);
120 result += RUN_TEST(test_quad9);
121 result += RUN_TEST(test_tet8 );
122 result += RUN_TEST(test_tet10);
123 result += RUN_TEST(test_tet14);
124 result += RUN_TEST(test_hex9 );
125 result += RUN_TEST(test_hex20);
126 result += RUN_TEST(test_hex27);
127
128 result += RUN_TEST(test_read_tri6_side );
129 result += RUN_TEST(test_read_shell_side);
130 result += RUN_TEST(test_read_shell_edge);
131 result += RUN_TEST(test_read_hex20_side);
132
133 result += RUN_TEST(test_read_block_ids );
134 result += RUN_TEST(test_read_sideset_ids);
135 result += RUN_TEST(test_read_nodeset_ids);
136
137 result += RUN_TEST(test_read_alternate_coord_format);
138
139 result += RUN_TEST(test_write_polygons);
140 result += RUN_TEST(test_write_polyhedra);
141 result += RUN_TEST(test_read_polygons);
142 result += RUN_TEST(test_read_polyhedra);
143
144 return result;
145 }
146
load_file_one(Interface * iface)147 void load_file_one( Interface* iface )
148 {
149 ErrorCode error = iface->load_mesh( file_one );
150 if (MB_SUCCESS != error) {
151 std::cout << "Failed to load input file: " << file_one << std::endl;
152 std::string error_reason;
153 iface->get_last_error(error_reason);
154 std::cout << error_reason << std::endl;
155 }
156 CHECK_ERR(error);
157 }
158
159 /*!
160 @test
161 Vertex Coordinates
162 @li Get coordinates of vertex 1 correctly
163 @li Get coordinates of vertex 8 correctly
164 @li Get coordinates of vertex 6 correctly
165 */
mb_vertex_coordinate_test()166 void mb_vertex_coordinate_test()
167 {
168 double coords[3];
169 EntityHandle handle;
170 ErrorCode error;
171 int err;
172
173 Core moab;
174 Interface* MB = &moab;
175 load_file_one( MB );
176
177 // coordinate 2 should be {1.5, -1.5, 3.5}
178
179 handle = CREATE_HANDLE(MBVERTEX, 2, err);
180 error = MB->get_coords(&handle, 1, coords );
181 CHECK_ERR(error);
182 const double exp2[] = { 1.5, -1.5, 3.5 };
183 CHECK_ARRAYS_EQUAL( exp2, 3, coords, 3 );
184
185
186 // coordinate 9 should be {1, -2, 3.5}
187 handle = CREATE_HANDLE(MBVERTEX, 9, err);
188 error = MB->get_coords(&handle, 1, coords );
189 CHECK_ERR(error);
190 const double exp9[] = { 1, -2, 3.5 };
191 CHECK_ARRAYS_EQUAL( exp9, 3, coords, 3 );
192
193 // coordinate 7 should be {0.5, -2, 3.5}
194 handle = CREATE_HANDLE(MBVERTEX, 7, err);
195 error = MB->get_coords(&handle, 1, coords);
196 CHECK_ERR(error);
197 const double exp7[] = {0.5, -2, 3.5};
198 CHECK_ARRAYS_EQUAL( exp7, 3, coords, 3 );
199
200 int node_count = 0;
201 error = MB->get_number_entities_by_type( 0, MBVERTEX, node_count );
202 CHECK_ERR(error);
203 // Number of vertices (node_count) should be 83 assuming no gaps in the handle space
204 CHECK_EQUAL( 47, node_count );
205 }
206
207
208 /*!
209 @test
210 MB Bar Element Connectivity Test
211 @li Get coordinates for 2 node bar elements
212 */
213
mb_bar_connectivity_test()214 void mb_bar_connectivity_test()
215 {
216 Core moab;
217 Interface* MB = &moab;
218 load_file_one( MB );
219
220 std::vector<EntityHandle> conn;
221 Range bars;
222
223 ErrorCode error = MB->get_entities_by_type(0, MBEDGE, bars);
224 CHECK_ERR(error);
225
226 // get the connectivity of the second bar
227 EntityHandle handle = *(++bars.begin());
228
229 error = MB->get_connectivity(&handle, 1, conn);
230 CHECK_ERR(error);
231
232 CHECK_EQUAL( (size_t)2, conn.size() );
233
234 // from ncdump the connectivity of bar 2 (0 based) is
235 // 14, 13
236 CHECK_EQUAL( (EntityHandle)14, conn[0] );
237 CHECK_EQUAL( (EntityHandle)13, conn[1] );
238
239 // Now try getting the connectivity of one of the vertices for fun.
240 // just return the vertex in the connectivity
241 handle = conn[0];
242 error = MB->get_connectivity(&handle, 1, conn);
243 CHECK_EQUAL( MB_FAILURE, error );
244 }
245
mb_tri_connectivity_test()246 void mb_tri_connectivity_test()
247 {
248 Core moab;
249 Interface* MB = &moab;
250 load_file_one( MB );
251
252 std::vector<EntityHandle> conn;
253 Range tris;
254 ErrorCode error = MB->get_entities_by_type(0, MBTRI, tris);
255 CHECK_ERR(error);
256
257 // get the connectivity of the second tri
258 EntityHandle handle = *(++tris.begin());
259
260 error = MB->get_connectivity(&handle, 1, conn);
261 CHECK_ERR(error);
262
263 CHECK_EQUAL( (size_t)3, conn.size() );
264
265 // from ncdump the connectivity of tri 2 (0 based) is
266 // 45, 37, 38
267
268 CHECK_EQUAL( (EntityHandle)45, conn[0] );
269 CHECK_EQUAL( (EntityHandle)37, conn[1] );
270 CHECK_EQUAL( (EntityHandle)38, conn[2] );
271 }
272
mb_quad_connectivity_test()273 void mb_quad_connectivity_test()
274 {
275 Core moab;
276 Interface* MB = &moab;
277 load_file_one( MB );
278
279 std::vector<EntityHandle> conn;
280 Range quads;
281
282 ErrorCode error = MB->get_entities_by_type(0, MBQUAD, quads);
283 CHECK_ERR(error);
284
285 // get the connectivity of the second quad
286 EntityHandle handle = *(++quads.begin());
287
288 error = MB->get_connectivity(&handle, 1, conn);
289 CHECK_ERR(error);
290
291 CHECK_EQUAL( (size_t)4, conn.size() );
292
293 // from ncdump the connectivity of quad 2 (0 based) is
294 // 20, 11, 12, 26,
295
296 CHECK_EQUAL( (EntityHandle)20, conn[0] );
297 CHECK_EQUAL( (EntityHandle)11, conn[1] );
298 CHECK_EQUAL( (EntityHandle)12, conn[2] );
299 CHECK_EQUAL( (EntityHandle)26, conn[3] );
300 }
301
mb_hex_connectivity_test()302 void mb_hex_connectivity_test()
303 {
304 Core moab;
305 Interface* MB = &moab;
306 load_file_one( MB );
307
308 std::vector<EntityHandle> conn;
309 Range hexes;
310
311 ErrorCode error = MB->get_entities_by_type(0, MBHEX, hexes);
312 CHECK_ERR(error);
313
314 // get the connectivity of the second hex
315 EntityHandle handle = *(++hexes.begin());
316
317 error = MB->get_connectivity(&handle, 1, conn);
318 CHECK_ERR(error);
319
320 CHECK_EQUAL( (size_t)8, conn.size() );
321
322 // from ncdump the connectivity of hex 1 (0 based) is
323 //19, 13, 16, 23, 21, 14, 18, 27
324
325 CHECK_EQUAL( (EntityHandle)19, conn[0] );
326 CHECK_EQUAL( (EntityHandle)13, conn[1] );
327 CHECK_EQUAL( (EntityHandle)16, conn[2] );
328 CHECK_EQUAL( (EntityHandle)23, conn[3] );
329 CHECK_EQUAL( (EntityHandle)21, conn[4] );
330 CHECK_EQUAL( (EntityHandle)14, conn[5] );
331 CHECK_EQUAL( (EntityHandle)18, conn[6] );
332 CHECK_EQUAL( (EntityHandle)27, conn[7] );
333 }
334
mb_tet_connectivity_test()335 void mb_tet_connectivity_test()
336 {
337 Core moab;
338 Interface* MB = &moab;
339 load_file_one( MB );
340
341 std::vector<EntityHandle> conn;
342 Range tets;
343 ErrorCode error = MB->get_entities_by_type(0, MBTET, tets);
344 CHECK_ERR(error);
345
346 // get the connectivity of the second tet
347 EntityHandle handle = *(++tets.begin());
348
349 error = MB->get_connectivity(&handle, 1, conn);
350 CHECK_ERR(error);
351
352 CHECK_EQUAL( (size_t)4, conn.size() );
353
354 // from ncdump the connectivity of tet 2 (0 based) is:
355 // 35, 34, 32, 43
356
357 CHECK_EQUAL( (EntityHandle)35, conn[0] );
358 CHECK_EQUAL( (EntityHandle)34, conn[1] );
359 CHECK_EQUAL( (EntityHandle)32, conn[2] );
360 CHECK_EQUAL( (EntityHandle)43, conn[3] );
361 }
362
mb_write_mesh_test()363 void mb_write_mesh_test()
364 {
365 Core moab;
366 Interface* MB = &moab;
367 load_file_one( MB );
368 ErrorCode result;
369
370 std::string file_name = "mb_write.g";
371
372 // no need to get lists, write out the whole mesh
373 result = MB->write_mesh(file_name.c_str());
374 CHECK_ERR(result);
375
376 //---------The following tests outputting meshsets that are in meshsets of blocks ---/
377
378 //lets create a block meshset and put some entities and meshsets into it
379 EntityHandle block_ms;
380 result = MB->create_meshset(MESHSET_ORDERED | MESHSET_TRACK_OWNER, block_ms );
381 CHECK_ERR(result);
382
383 //make another meshset to put quads in, so SHELLs can be written out
384 EntityHandle block_of_shells;
385 result = MB->create_meshset(MESHSET_ORDERED | MESHSET_TRACK_OWNER, block_of_shells);
386 CHECK_ERR(result);
387
388 //tag the meshset so it's a block, with id 100
389 int id = 100;
390 Tag tag_handle;
391 const int negone = -1;
392 result = MB->tag_get_handle( MATERIAL_SET_TAG_NAME, 1, MB_TYPE_INTEGER, tag_handle, 0, &negone) ;
393 CHECK_ERR(result);
394 result = MB->tag_set_data( tag_handle, &block_ms, 1, &id ) ;
395 CHECK_ERR(result);
396 id = 101;
397 result = MB->tag_set_data( tag_handle, &block_of_shells, 1, &id ) ;
398 CHECK_ERR(result);
399
400 // set dimension tag on this to ensure shells get output; reuse id variable
401 result = MB->tag_get_handle( GEOM_DIMENSION_TAG_NAME, 1, MB_TYPE_INTEGER, tag_handle, 0, &negone) ;
402 CHECK_ERR(result);
403 id = 3;
404 result = MB->tag_set_data( tag_handle, &block_of_shells, 1, &id ) ;
405 CHECK_ERR(result);
406
407 //get some entities (tets)
408 Range temp_range;
409 result = MB->get_entities_by_type(0, MBHEX, temp_range ) ;
410 CHECK_ERR(result);
411
412 Range::iterator iter, end_iter;
413 iter = temp_range.begin();
414 end_iter = temp_range.end();
415
416 //add evens to 'block_ms'
417 std::vector<EntityHandle> temp_vec;
418 for(; iter != end_iter; ++iter)
419 {
420 if( ID_FROM_HANDLE( *iter ) % 2 == 0 )
421 temp_vec.push_back( *iter );
422 }
423 result = MB->add_entities( block_ms, &temp_vec[0], temp_vec.size());
424 CHECK_ERR(result);
425
426
427 //make another meshset
428 EntityHandle ms_of_block_ms;
429 result = MB->create_meshset(MESHSET_ORDERED | MESHSET_TRACK_OWNER, ms_of_block_ms);
430 CHECK_ERR(result);
431
432 //add some entities to it
433 temp_vec.clear();
434 iter = temp_range.begin();
435 for(; iter != end_iter; ++iter)
436 {
437 if( ID_FROM_HANDLE( *iter ) % 2 ) //add all odds
438 temp_vec.push_back( *iter );
439 }
440 result = MB->add_entities( ms_of_block_ms, &temp_vec[0], temp_vec.size() );
441 CHECK_ERR(result);
442
443 //add the other meshset to the block's meshset
444 result = MB->add_entities( block_ms, &ms_of_block_ms, 1);
445 CHECK_ERR(result);
446
447
448 //---------------testing sidesets----------------/
449
450 //lets create a sideset meshset and put some entities and meshsets into it
451 EntityHandle sideset_ms;
452 result = MB->create_meshset(MESHSET_ORDERED | MESHSET_TRACK_OWNER, sideset_ms );
453 CHECK_ERR(result);
454
455 //tag the meshset so it's a sideset, with id 104
456 id = 104;
457 result = MB->tag_get_handle( NEUMANN_SET_TAG_NAME, 1, MB_TYPE_INTEGER, tag_handle, 0, &negone) ;
458 CHECK_ERR(result);
459
460 result = MB->tag_set_data( tag_handle, &sideset_ms, 1, &id ) ;
461 CHECK_ERR(result);
462
463 //get some entities (tris)
464 temp_range.clear();
465 result = MB->get_entities_by_type(0, MBQUAD, temp_range ) ;
466 CHECK_ERR(result);
467
468 iter = temp_range.begin();
469 end_iter = temp_range.end();
470
471 //add evens to 'sideset_ms'
472 temp_vec.clear();
473 for(; iter != end_iter; ++iter)
474 {
475 if( ID_FROM_HANDLE( *iter ) % 2 == 0 )
476 temp_vec.push_back( *iter );
477 }
478 result = MB->add_entities( sideset_ms, &temp_vec[0], temp_vec.size() );
479 CHECK_ERR(result);
480
481 //make another meshset
482 EntityHandle ms_of_sideset_ms;
483 result = MB->create_meshset(MESHSET_ORDERED | MESHSET_TRACK_OWNER, ms_of_sideset_ms);
484 CHECK_ERR(result);
485
486 //add some entities to it
487 temp_vec.clear();
488 iter = temp_range.begin();
489 for(; iter != end_iter; ++iter)
490 {
491 if( ID_FROM_HANDLE( *iter ) % 2 ) //add all odds
492 temp_vec.push_back( *iter );
493 }
494 result = MB->add_entities( ms_of_sideset_ms, &temp_vec[0], temp_vec.size() );
495 CHECK_ERR(result);
496
497 //add the other meshset to the sideset's meshset
498 result = MB->add_entities( sideset_ms, &ms_of_sideset_ms, 1);
499 CHECK_ERR(result);
500
501 //---------test sense on meshsets (reverse/foward)-------//
502
503 //get all quads whose x-coord = 2.5 and put them into a meshset_a
504 EntityHandle meshset_a;
505 result = MB->create_meshset(MESHSET_ORDERED | MESHSET_TRACK_OWNER, meshset_a );
506 CHECK_ERR(result);
507
508 temp_range.clear();
509 result = MB->get_entities_by_type(0, MBQUAD, temp_range ) ;
510 CHECK_ERR(result);
511
512 std::vector<EntityHandle> nodes1, entity_vec;
513 std::copy(temp_range.begin(), temp_range.end(), std::back_inserter(entity_vec));
514 result = MB->get_connectivity(&entity_vec[0], entity_vec.size(), nodes1);
515 CHECK_ERR(result);
516 assert( nodes1.size() == 4 * temp_range.size() );
517 temp_vec.clear();
518 std::vector<double> coords(3*nodes1.size());
519 result = MB->get_coords(&nodes1[0], nodes1.size(), &coords[0]);
520 CHECK_ERR(result);
521
522 unsigned int k = 0;
523 for(Range::iterator it = temp_range.begin(); it != temp_range.end(); ++it) {
524 if( coords[12*k] == 2.5 && coords[12*k+3] == 2.5 &&
525 coords[12*k+6] == 2.5 && coords[12*k+9] == 2.5 )
526 temp_vec.push_back(*it);
527 k++;
528 }
529 result = MB->add_entities( meshset_a, (temp_vec.empty())?NULL:&temp_vec[0], temp_vec.size() );
530 CHECK_ERR(result);
531 result = MB->add_entities( block_of_shells, (temp_vec.empty())?NULL:&temp_vec[0], temp_vec.size());
532 CHECK_ERR(result);
533
534 //put these quads into a different meshset_b and tag them with a reverse sense tag
535 EntityHandle meshset_b;
536 result = MB->create_meshset(MESHSET_ORDERED | MESHSET_TRACK_OWNER, meshset_b );
537 CHECK_ERR(result);
538
539 result = MB->add_entities( meshset_b, &meshset_a, 1);
540 CHECK_ERR(result);
541
542
543 result = MB->tag_get_handle( "SENSE", 1, MB_TYPE_INTEGER, tag_handle, MB_TAG_SPARSE|MB_TAG_CREAT );
544 CHECK_ERR(result);
545
546 int reverse_value = -1;
547 result = MB->tag_set_data( tag_handle, &meshset_b, 1, &reverse_value ) ;
548 CHECK_ERR(result);
549
550
551 //get some random quad, whose x-coord != 2.5, and put it into a different meshset_c
552 //and tag it with a reverse sense tag
553
554 iter = temp_range.begin();
555 end_iter = temp_range.end();
556
557 temp_vec.clear();
558 for(; iter != end_iter; ++iter)
559 {
560 std::vector<EntityHandle> nodes;
561 result = MB->get_connectivity( &(*iter), 1, nodes );
562 CHECK_ERR(result);
563
564 bool not_equal_2_5 = true;
565 for(unsigned int ku=0; ku<nodes.size(); ku++ )
566 {
567 double coords2[3] = {0};
568
569 result = MB->get_coords( &(nodes[ku]), 1, coords2 );
570 CHECK_ERR(result);
571
572 if( coords2[0] == 2.5 )
573 {
574 not_equal_2_5 = false;
575 break;
576 }
577 }
578
579 if( not_equal_2_5 && nodes.size()> 0)
580 {
581 temp_vec.push_back( *iter );
582 break;
583 }
584 }
585
586 EntityHandle meshset_c;
587 MB->create_meshset(MESHSET_ORDERED | MESHSET_TRACK_OWNER, meshset_c );
588
589
590 result = MB->tag_get_handle( "SENSE", 1, MB_TYPE_INTEGER, tag_handle );
591 CHECK_ERR(result);
592
593 reverse_value = -1;
594 result = MB->tag_set_data( tag_handle, &meshset_c, 1, &reverse_value ) ;
595 CHECK_ERR(result);
596
597 MB->add_entities( meshset_c, &temp_vec[0], temp_vec.size() );
598 MB->add_entities( block_of_shells, &temp_vec[0], temp_vec.size());
599
600
601 //create another meshset_abc, adding meshset_a, meshset_b, meshset_c
602 EntityHandle meshset_abc;
603 MB->create_meshset(MESHSET_ORDERED | MESHSET_TRACK_OWNER, meshset_abc );
604
605 temp_vec.clear();
606 temp_vec.push_back( meshset_a );
607 temp_vec.push_back( meshset_b );
608 temp_vec.push_back( meshset_c );
609
610 MB->add_entities( meshset_abc, &temp_vec[0], temp_vec.size());
611
612
613 //tag it so it's a sideset
614 id = 444;
615 result = MB->tag_get_handle( "NEUMANN_SET", 1, MB_TYPE_INTEGER, tag_handle, 0, &negone) ;
616 CHECK_ERR(result);
617
618 result = MB->tag_set_data( tag_handle, &meshset_abc, 1, &id ) ;
619 CHECK_ERR(result);
620
621
622
623 //---------------do nodesets now -----------------//
624
625
626 //lets create a nodeset meshset and put some entities and meshsets into it
627 EntityHandle nodeset_ms;
628 MB->create_meshset(MESHSET_ORDERED | MESHSET_TRACK_OWNER, nodeset_ms );
629
630 //tag the meshset so it's a nodeset, with id 119
631 id = 119;
632 result = MB->tag_get_handle( DIRICHLET_SET_TAG_NAME, 1, MB_TYPE_INTEGER, tag_handle, 0, &negone) ;
633 CHECK_ERR(result);
634
635 result = MB->tag_set_data( tag_handle, &nodeset_ms, 1, &id ) ;
636 CHECK_ERR(result);
637
638 //get all Quads
639 temp_range.clear();
640 result = MB->get_entities_by_type(0, MBQUAD, temp_range ) ;
641 CHECK_ERR(result);
642
643
644 //get all the nodes of the tris
645 Range nodes_of_quads;
646 iter = temp_range.begin();
647 end_iter = temp_range.end();
648
649
650 for(; iter != end_iter; ++iter)
651 {
652 std::vector<EntityHandle> nodes;
653 result = MB->get_connectivity( &(*iter), 1, nodes);
654 CHECK_ERR(result);
655
656 for(unsigned int ku=0; ku<nodes.size(); ku++ )
657 nodes_of_quads.insert( nodes[ku] );
658
659 }
660
661 iter = nodes_of_quads.begin();
662 end_iter = nodes_of_quads.end();
663
664 //add evens to 'nodeset_ms'
665 temp_vec.clear();
666 for(; iter != end_iter; ++iter)
667 {
668 if( ID_FROM_HANDLE( *iter ) % 2 == 0 )
669 temp_vec.push_back( *iter );
670 }
671 MB->add_entities( nodeset_ms, &temp_vec[0], temp_vec.size() );
672
673
674 //make another meshset
675 EntityHandle ms_of_nodeset_ms;
676 MB->create_meshset(MESHSET_ORDERED | MESHSET_TRACK_OWNER, ms_of_nodeset_ms);
677
678 //add some entities to it
679 temp_vec.clear();
680 iter = nodes_of_quads.begin();
681 end_iter = nodes_of_quads.end();
682 for(; iter != end_iter; ++iter)
683 {
684 if( ID_FROM_HANDLE( *iter ) % 2 ) //add all odds
685 temp_vec.push_back( *iter );
686 }
687 MB->add_entities( ms_of_nodeset_ms, &temp_vec[0], temp_vec.size() );
688
689 //add the other meshset to the nodeset's meshset
690 MB->add_entities( nodeset_ms, &ms_of_nodeset_ms, 1);
691
692
693 // no need to get lists, write out the whole mesh
694 file_name = "mb_write2.g";
695 std::vector<EntityHandle> output_list;
696 output_list.push_back( block_ms );
697 output_list.push_back( sideset_ms );
698 output_list.push_back( meshset_abc );
699 output_list.push_back( nodeset_ms );
700 output_list.push_back( block_of_shells );
701 result = MB->write_mesh(file_name.c_str(), &output_list[0], output_list.size());
702 CHECK_ERR(result);
703 }
704
705
706 struct TestType {
707 EntityType moab_type;
708 ExoIIElementType exo_type;
709 int num_nodes;
710 std::string name;
711 };
712
check_type(const TestType & type)713 void check_type( const TestType& type )
714 {
715 int has_mid_nodes[4];
716 CN::HasMidNodes( type.moab_type, type.num_nodes, has_mid_nodes );
717
718 CHECK_EQUAL( type.moab_type, ExoIIUtil::ExoIIElementMBEntity[type.exo_type] );
719 CHECK_EQUAL( type.name, std::string( ExoIIUtil::ElementTypeNames[type.exo_type] ) );
720 CHECK_EQUAL( type.num_nodes, ExoIIUtil::VerticesPerElement[type.exo_type] );
721 switch (CN::Dimension(type.moab_type)) {
722 case 3: CHECK_EQUAL( has_mid_nodes[3], ExoIIUtil::HasMidNodes[type.exo_type][3] );
723 case 2: CHECK_EQUAL( has_mid_nodes[2], ExoIIUtil::HasMidNodes[type.exo_type][2] );
724 case 1: CHECK_EQUAL( has_mid_nodes[1], ExoIIUtil::HasMidNodes[type.exo_type][1] );
725 }
726
727 Core moab;
728 ExoIIUtil tool(&moab);
729 CHECK_EQUAL( type.exo_type, tool.element_name_to_type( type.name.c_str() ) );
730 CHECK_EQUAL( type.name, std::string(tool.element_type_name( type.exo_type ) ) );
731 }
732
test_types()733 void test_types()
734 {
735 const TestType types[] = {
736 { MBVERTEX, EXOII_SPHERE, 1, "SPHERE" },
737 { MBEDGE, EXOII_SPRING, 1, "SPRING" },
738 { MBEDGE, EXOII_BAR, 2, "BAR" },
739 { MBEDGE, EXOII_BAR2, 2, "BAR2" },
740 { MBEDGE, EXOII_BAR3, 3, "BAR3" },
741 { MBEDGE, EXOII_BEAM, 2, "BEAM" },
742 { MBEDGE, EXOII_BEAM2, 2, "BEAM2" },
743 { MBEDGE, EXOII_BEAM3, 3, "BEAM3" },
744 { MBEDGE, EXOII_TRUSS, 2, "TRUSS" },
745 { MBEDGE, EXOII_TRUSS2, 2, "TRUSS2" },
746 { MBEDGE, EXOII_TRUSS3, 3, "TRUSS3" },
747 { MBTRI, EXOII_TRI, 3, "TRI" },
748 { MBTRI, EXOII_TRI3, 3, "TRI3" },
749 { MBTRI, EXOII_TRI6, 6, "TRI6" },
750 { MBTRI, EXOII_TRI7, 7, "TRI7" },
751 { MBQUAD, EXOII_QUAD, 4, "QUAD" },
752 { MBQUAD, EXOII_QUAD4, 4, "QUAD4" },
753 { MBQUAD, EXOII_QUAD5, 5, "QUAD5" },
754 { MBQUAD, EXOII_QUAD8, 8, "QUAD8" },
755 { MBQUAD, EXOII_QUAD9, 9, "QUAD9" },
756 { MBQUAD, EXOII_SHELL, 4, "SHELL" },
757 { MBQUAD, EXOII_SHELL4, 4, "SHELL4" },
758 { MBQUAD, EXOII_SHELL5, 5, "SHELL5" },
759 { MBQUAD, EXOII_SHELL8, 8, "SHELL8" },
760 { MBQUAD, EXOII_SHELL9, 9, "SHELL9" },
761 { MBTET, EXOII_TETRA, 4, "TETRA" },
762 { MBTET, EXOII_TETRA4, 4, "TETRA4" },
763 { MBTET, EXOII_TET4, 4, "TET4" },
764 { MBTET, EXOII_TETRA8, 8, "TETRA8" },
765 { MBTET, EXOII_TETRA10, 10, "TETRA10" },
766 { MBTET, EXOII_TETRA14, 14, "TETRA14" },
767 { MBPYRAMID, EXOII_PYRAMID, 5, "PYRAMID" },
768 { MBPYRAMID, EXOII_PYRAMID5, 5, "PYRAMID5" },
769 { MBPYRAMID, EXOII_PYRAMID10, 10, "PYRAMID10" },
770 { MBPYRAMID, EXOII_PYRAMID13, 13, "PYRAMID13" },
771 { MBPYRAMID, EXOII_PYRAMID18, 18, "PYRAMID18" },
772 { MBPRISM, EXOII_WEDGE, 6, "WEDGE" },
773 { MBKNIFE, EXOII_KNIFE, 7, "KNIFE" },
774 { MBHEX, EXOII_HEX, 8, "HEX" },
775 { MBHEX, EXOII_HEX8, 8, "HEX8" },
776 { MBHEX, EXOII_HEX9, 9, "HEX9" },
777 { MBHEX, EXOII_HEX20, 20, "HEX20" },
778 { MBHEX, EXOII_HEX27, 27, "HEX27" },
779 { MBHEX, EXOII_HEXSHELL, 12, "HEXSHELL" } };
780 const int num_types = sizeof(types)/sizeof(types[0]);
781 for (int i = 0; i < num_types; ++i)
782 check_type( types[i] );
783 }
784
read_file(Interface & moab,const char * input_file)785 void read_file( Interface& moab,
786 const char* input_file )
787 {
788 ErrorCode rval = moab.load_file( input_file );
789 CHECK_ERR(rval);
790 }
791
write_and_read(Interface & write_mb,Interface & read_mb,EntityHandle block=0)792 void write_and_read( Interface& write_mb,
793 Interface& read_mb,
794 EntityHandle block = 0 )
795 {
796 const char* tmp_file = "exodus_test_tmp.g";
797 ErrorCode rval;
798
799 EntityHandle* write_set_list = █
800 int write_set_list_len = 0;//(block != 0);
801 rval = write_mb.write_file( tmp_file, "EXODUS", 0,
802 write_set_list, write_set_list_len );
803 if (MB_SUCCESS != rval)
804 remove(tmp_file);
805 CHECK_ERR(rval);
806
807 rval = read_mb.load_file( tmp_file );
808 remove( tmp_file );
809 CHECK_ERR(rval);
810 }
811
check_ho_elements(Interface & moab,EntityHandle block,EntityType type,int mid_nodes[4])812 void check_ho_elements( Interface& moab,
813 EntityHandle block,
814 EntityType type,
815 int mid_nodes[4] )
816 {
817 ErrorCode rval;
818 Range elems;
819 rval = moab.get_entities_by_handle( block, elems, (type != MBENTITYSET ? true : false));
820 CHECK_ERR(rval);
821 CHECK(!elems.empty());
822 CHECK(elems.all_of_type(type));
823 for (Range::const_iterator i = elems.begin(); i != elems.end(); ++i)
824 check_ho_element( moab, *i, mid_nodes );
825 }
826
827 // Check that element has expected higher-order nodes
828 // and that each higher-order node is at the center
829 // of the sub-entity it is on.
check_ho_element(Interface & moab,EntityHandle entity,int mid_nodes[4])830 void check_ho_element( Interface& moab,
831 EntityHandle entity,
832 int mid_nodes[4] )
833 {
834 // get element info
835 const EntityType type = TYPE_FROM_HANDLE(entity);
836 const EntityHandle* conn;
837 int conn_len;
838 ErrorCode rval = moab.get_connectivity( entity, conn, conn_len );
839 CHECK_ERR(rval);
840 std::vector<double> coords(3*conn_len);
841 rval = moab.get_coords( conn, conn_len, &coords[0] );
842 CHECK_ERR(rval);
843
844 // calculate and verify expected number of mid nodes
845 int num_nodes = CN::VerticesPerEntity(type);
846 for (int d = 1; d <= CN::Dimension(type); ++d)
847 if (mid_nodes[d])
848 num_nodes += CN::NumSubEntities(type, d);
849 CHECK_EQUAL( num_nodes, conn_len );
850
851 // verify that each higher-order node is at the center
852 // of its respective sub-entity.
853 for (int i = CN::VerticesPerEntity(type); i < num_nodes; ++i) {
854 // get sub-entity owning ho-node
855 int sub_dim, sub_num;
856 CN::HONodeParent( type, num_nodes, i, sub_dim, sub_num );
857 // get corner vertex indices
858 int sub_conn[8], num_sub;
859 if (sub_dim < CN::Dimension(type)) {
860 CN::SubEntityVertexIndices( type, sub_dim, sub_num, sub_conn );
861 EntityType sub_type = CN::SubEntityType( type, sub_dim, sub_num );
862 num_sub = CN::VerticesPerEntity( sub_type );
863 }
864 else {
865 num_sub = CN::VerticesPerEntity(type);
866 for (int j = 0; j < num_sub; ++j)
867 sub_conn[j] = j;
868 }
869 // calculate mean of corner vertices
870 double mean[3] = {0,0,0};
871 for (int j = 0; j < num_sub; ++j) {
872 int co = 3*sub_conn[j];
873 mean[0] += coords[co ];
874 mean[1] += coords[co+1];
875 mean[2] += coords[co+2];
876 }
877 mean[0] /= num_sub;
878 mean[1] /= num_sub;
879 mean[2] /= num_sub;
880 // verify that higher-order node is at expected location
881 CHECK_REAL_EQUAL( mean[0], coords[3*i ], 1e-6 );
882 CHECK_REAL_EQUAL( mean[1], coords[3*i+1], 1e-6 );
883 CHECK_REAL_EQUAL( mean[2], coords[3*i+2], 1e-6 );
884 }
885 }
886
887
find_block(Interface & mb,EntityType type,const int has_mid_nodes[4])888 EntityHandle find_block( Interface& mb, EntityType type, const int has_mid_nodes[4] )
889 {
890
891 ErrorCode rval;
892 Tag ho_tag, block_tag;
893 const int negone = -1;
894 rval = mb.tag_get_handle( MATERIAL_SET_TAG_NAME, 1, MB_TYPE_INTEGER, block_tag, 0, &negone);
895 CHECK_ERR(rval);
896 const int mids[] = {-1, -1, -1, -1};
897 rval = mb.tag_get_handle( HAS_MID_NODES_TAG_NAME, 4, MB_TYPE_INTEGER, ho_tag, 0, mids);
898 CHECK_ERR(rval);
899
900 // get material sets with expected higher-order nodes
901 Range blocks;
902 Tag tags[2] = {ho_tag, block_tag};
903 const void* vals[2] = {has_mid_nodes, NULL};
904 rval = mb.get_entities_by_type_and_tag( 0, MBENTITYSET, tags, vals, 2, blocks );
905 CHECK_ERR(rval);
906
907 for (Range::iterator i = blocks.begin(); i != blocks.end(); ++i) {
908 int n;
909 rval = mb.get_number_entities_by_type( *i, type, n );
910 CHECK_ERR(rval);
911 if (n > 0)
912 return *i;
913 }
914
915 CHECK(false); // no block matching element type description
916 return 0;
917 }
918
find_sideset(Interface & mb,int sideset_id,EntityType)919 EntityHandle find_sideset( Interface& mb,
920 int sideset_id,
921 EntityType /*side_type*/ )
922 {
923 ErrorCode rval;
924 Tag ss_tag;
925 const int negone = -1;
926 rval = mb.tag_get_handle( NEUMANN_SET_TAG_NAME, 1, MB_TYPE_INTEGER, ss_tag, 0, &negone);
927 CHECK_ERR(rval);
928
929 const void* tag_vals[] = { &sideset_id };
930 Range side_sets;
931 rval = mb.get_entities_by_type_and_tag( 0, MBENTITYSET, &ss_tag, tag_vals, 1, side_sets );
932 CHECK_ERR(rval);
933 CHECK_EQUAL( 1, (int)side_sets.size() );
934 return side_sets.front();
935 }
936
937 // Validate elements of specified type.
938 // Looks for a block containing the specified entity type
939 // and with the specified mid-node flags set in its
940 // HAS_MID_NODES_TAG.
test_ho_elements(EntityType type,int num_nodes)941 void test_ho_elements( EntityType type, int num_nodes )
942 {
943 Core mb_impl1, mb_impl2;
944 Interface &mb1 = mb_impl1, &mb2 = mb_impl2;
945 int ho_flags[4];
946 CN::HasMidNodes( type, num_nodes, ho_flags );
947
948 // read file
949 read_file( mb1, ho_file );
950 // test element connectivity order
951 EntityHandle block = find_block( mb1, type, ho_flags );
952 CHECK(block != 0);
953 check_ho_elements( mb1, block, type, ho_flags );
954
955 // write block and read it back in
956 write_and_read( mb1, mb2, block );
957 // test element connectivity order on re-read data
958 block = find_block( mb2, type, ho_flags );
959 CHECK(block != 0);
960 check_ho_elements( mb2, block, type, ho_flags );
961 }
962
test_read_side(int id,EntityType sideset_type,int sideset_nodes_per_elem,bool shell_side)963 void test_read_side( int id,
964 EntityType sideset_type,
965 int sideset_nodes_per_elem,
966 bool shell_side )
967 {
968 // read test file
969 Core mb_impl;
970 Interface& moab = mb_impl;
971 read_file( moab, ho_file );
972
973 // get side set
974 EntityHandle set = find_sideset( moab, id, sideset_type );
975 CHECK(set != 0);
976
977 // check expected element connectivity
978 int ho_flags[4];
979 CN::HasMidNodes( sideset_type, sideset_nodes_per_elem, ho_flags );
980 check_ho_elements( moab, set, sideset_type, ho_flags );
981
982 if (shell_side)
983 return;
984
985 // check that each element is on the boundary of the mesh
986 Range elems;
987 ErrorCode rval = mb_impl.get_entities_by_handle( set, elems );
988 CHECK_ERR(rval);
989
990 int dim = CN::Dimension( sideset_type );
991 for (Range::iterator i= elems.begin(); i != elems.end(); ++i) {
992 Range adj;
993 rval = mb_impl.get_adjacencies( &*i, 1, dim+1, false, adj, Interface::UNION );
994 CHECK_ERR(rval);
995 CHECK_EQUAL( 1, (int)adj.size() );
996 }
997
998 }
999
test_read_ids_common(const char * file_name,const char * tag_name,const int * expected_vals,int num_expected)1000 void test_read_ids_common( const char* file_name,
1001 const char* tag_name,
1002 const int* expected_vals,
1003 int num_expected )
1004 {
1005 Core mb;
1006 ReadNCDF reader(&mb);
1007
1008 FileOptions opts("");
1009 std::vector<int> values;
1010 ErrorCode rval = reader.read_tag_values( file_name, tag_name, opts, values );
1011 CHECK_ERR(rval);
1012
1013 std::vector<int> expected( expected_vals, expected_vals+num_expected );
1014 std::sort( values.begin(), values.end() );
1015 std::sort( expected.begin(), expected.end() );
1016 CHECK_EQUAL( expected, values );
1017 }
1018
test_read_block_ids()1019 void test_read_block_ids() {
1020 const int expected[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 };
1021 test_read_ids_common( ho_file, MATERIAL_SET_TAG_NAME, expected, sizeof(expected)/sizeof(expected[0]) );
1022 }
1023
test_read_sideset_ids()1024 void test_read_sideset_ids() {
1025 const int expected[] = { 1, 2, 3, 4 };
1026 test_read_ids_common( ho_file, NEUMANN_SET_TAG_NAME, expected, sizeof(expected)/sizeof(expected[0]) );
1027 }
1028
test_read_nodeset_ids()1029 void test_read_nodeset_ids() {
1030 test_read_ids_common( ho_file, DIRICHLET_SET_TAG_NAME, 0, 0 );
1031 }
1032
test_read_alternate_coord_format()1033 void test_read_alternate_coord_format()
1034 {
1035 Core moab;
1036 Interface& mb = moab;
1037 ErrorCode rval = mb.load_file( alt_file );
1038 CHECK_ERR(rval);
1039
1040 const double exp[] = { 0, 0, 0,
1041 1, 0, 0,
1042 1, 1, 0,
1043 0, 1, 0,
1044 0, 0, 1,
1045 1, 0, 1,
1046 1, 1, 1,
1047 0, 1, 1 };
1048
1049 Range hexes;
1050 rval = mb.get_entities_by_type( 0, MBHEX, hexes );
1051 CHECK_ERR(rval);
1052 CHECK_EQUAL( (size_t)1, hexes.size() );
1053 EntityHandle hex = hexes.front();
1054 const EntityHandle* conn;
1055 int len;
1056 rval = mb.get_connectivity( hex, conn, len );
1057 CHECK_ERR(rval);
1058 CHECK_EQUAL(8, len);
1059 double act[3*8];
1060 rval = mb.get_coords( conn, len, act );
1061 CHECK_ERR(rval);
1062 CHECK_ARRAYS_EQUAL( exp, 3*8, act, 3*8 );
1063 }
test_write_polygons()1064 void test_write_polygons()
1065 {
1066 Core moab;
1067 Interface& mb = moab;
1068 ErrorCode rval = mb.load_file( polyg );
1069 CHECK_ERR(rval);
1070 rval = mb.write_file("polyg.exo");
1071 CHECK_ERR(rval);
1072 }
1073
test_write_polyhedra()1074 void test_write_polyhedra()
1075 {
1076 Core moab;
1077 Interface& mb = moab;
1078 ErrorCode rval = mb.load_file( polyh );
1079 CHECK_ERR(rval);
1080 rval = mb.write_file("polyh.exo");
1081 CHECK_ERR(rval);
1082 }
test_read_polygons()1083 void test_read_polygons()
1084 {
1085 Core moab;
1086 Interface& mb = moab;
1087 ErrorCode rval = mb.load_file( rpolyg );
1088 CHECK_ERR(rval);
1089 }
test_read_polyhedra()1090 void test_read_polyhedra()
1091 {
1092 Core moab;
1093 Interface& mb = moab;
1094 ErrorCode rval = mb.load_file( rpolyh );
1095 CHECK_ERR(rval);
1096 }
1097